Tuesday, 17 December 2024

Tim's ESP8266-01 linker

 

This is my ESP8266-01 linker.

It is an application I wrote to communicate with the ESP8266-01 via Wi-Fi from the PC.
It makes the Tim's ESP8266-01 linker act like a go-between UART and Wi-Fi.





I hope the video explains it all.
It can be downloaded from here: Tim's ESP8266-01 linker.zip

Once the ESP8266-01 is programmed, you should be able to connect it to any Microcontroller that has UART and communicate to the Microcontroller via Wi-Fi.

The Arduino code for the ESP8266-01.

/*
 File: WiFi_UART_with_RTS_CTS.ino (Place in folder with the same name)

  Using an ESP8266-01 to act as Wi-Fi / UART with Hardware handshaking.
   The hardware handshaking to be done using pins 0 and 2.
   Ther is #define HARD_HANDSHAKING
   This turns on/off hardware handshaking.

 By Tim Jackson.1960
  Give creadit where due.

 In the code you will need to enter you’re:
  "Your local network name"
  "Your local network password"
*/

#include <esp8266wifi.h>

/*
 Hard Handshaking Pins.
*/
#define RTS_PIN 0 /* GPIO0 for Request To Send (RTS) */
#define CTS_PIN 2 /* GPIO2 for Clear To Send (CTS) */

//#define HARD_HANDSHAKING /* Uncomment to enable hardware handshaking */

/*
 Wi-Fi
*/
//#define FIXED_IP /* Uncomment this if you know how to set a fixed IP address. */
/*
 The name of your local network.
 The Password.

 These are required using Station mode (STA).
*/
const char* LOCAL_SSID_STA = "Your local network name"; /* Your local network name. */
const char* LOCAL_PASSWORD_STA = "Your local network password"; /* Your local network password. */
/*
	ESP8266-01 Identification
*/
const char* HOST_NAME = "Tims ESP8266_01_154"; /* The name for the module seen on the network. */
/*
 The following IPAdresses are for use with fixed IP address mode.
 You will need to know how to reserve IP addresses on your router to use these.

 With regards IP addresses gateway and dns.
 Point these to the address of your router.
 This project is for local networks and don't need to be registered on a global server.

 Normally your router/modem will be 192.168.0.1
*/
IPAddress ip(192, 168, 0, 154);     /* Device IP address. */
IPAddress subnet(255, 255, 255, 0); /* Subnet mask (Don't change) */
IPAddress gateway(192, 168, 0, 1);  /* Gateway (router IP) */
IPAddress dns(192, 168, 0, 1);      /* DNS server (router IP) */

WiFiServer server(80); /* Set up a server on port 80 */
WiFiClient client;

String WiFi_Buffer = "";          /* Buffer to hold received Wi-Fi data */
bool WiFi_DataReceived = false;   /* Flag to indicate Wi-Fi data received */
String Serial_Buffer = "";        /* Buffer to hold received Serial data */
bool Serial_DataReceived = false; /* Flag to indicate Serial data received */

void setup() {
 /*
  Initialize UART
 
   The default Baud when using Arduino devices is 9600.
   Unless you know what you are connecting to.
   Check your connected device's UART speed.
 
 */
 Serial.begin(9600);

#if defined(HARD_HANDSHAKING)
 pinMode(RTS_PIN, OUTPUT);	/* Set RTS as output */
 pinMode(CTS_PIN, INPUT);	/* Set CTS as input */
#endif /* HARD_HANDSHAKING */
 
 /*
  Connect to Wi-Fi
  */
 WiFi.hostname(HOST_NAME);
#if defined(FIXED_IP)
 WiFi.config(ip, gateway, subnet, dns);
#endif /* FIXED_IP */
 WiFi.begin(LOCAL_SSID_STA, LOCAL_PASSWORD_STA);
 while (WiFi.status() != WL_CONNECTED) {
  delay(500);
  Serial.print(".");
 }
 
 /*
  Print the IP address to the Serial Monitor.
  Address will be allocated by local server.
 
 Serial.println("WiFi Connected! IP address: ");
 Serial.println(WiFi.localIP());
 Serial.print("ESP8266 IP Address: ");
 Serial.println(WiFi.localIP());
 
 /* Print the MAC address */
 Serial.print("MAC Address: ");
 Serial.println(WiFi.macAddress());

 Serial.print("Hostname: ");
 Serial.println(WiFi.hostname());

 server.begin();	/* Start the server */
}
 
void loop() {
 client = server.available(); /* Check for incoming clients */
 
 if (client) {
  while (client.connected()) {
   if (client.available()) {
    while (client.available()) {
     WiFi_Buffer += (char)client.read(); /* Read all available data from the client */
    }
    client.flush();           /* Clear the client buffer */
    //client.println("ok");   /* Debug */
    WiFi_DataReceived = true; /* Set the flag */
    delay(1);                 /* Slight delay */
   }

#if defined(HARD_HANDSHAKING)
   /*
    Set Ready To Send (RTS) if WiFi Data Received.
   */
   if (WiFi_DataReceived) {
    digitalWrite(RTS_PIN, LOW); /* Set RTS low to indicate Ready To Send */
   }
   else {
    digitalWrite(RTS_PIN, HIGH); /* Set RTS high otherwise */
   }
 
   /*
    Wait for attached device to be ready to receive.
     Clear To Send (CTS)
   */
   while (digitalRead(CTS_PIN)) {
   /* Waiting for CTS_PIN to go LOW. */
   }
 
   /*
    Send WiFi_Buffer, when CTS_PIN is LOW
     Clear To Send (CTS)
   */
   if (!digitalRead(CTS_PIN)) {
    if (WiFi_DataReceived) {
     Serial.print(WiFi_Buffer); /* Print received Wi-Fi data */
     WiFi_Buffer = "";          /* Clear the buffer after processing */
     WiFi_DataReceived = false; /* Reset the flag after processing the data */
    }
   }
 
   if (Serial.available()) {
    while (Serial.available()) {
     Serial_Buffer += (char)Serial.read(); /* Read all available data from the Serial */
    }
    Serial_DataReceived = true;	/* Set Serial data received flag */
    digitalWrite(RTS_PIN, LOW);	/* Set RTS low to indicate Ready To Send */
   }
 
   /*
    Send Serial data over Wi-Fi if received.
   */
   if (Serial_DataReceived) {
    client.print(Serial_Buffer); /* Send Serial data to Wi-Fi client */
    Serial_Buffer = "";          /* Clear the Serial buffer after processing */
    Serial_DataReceived = false; /* Reset the Serial data received flag */
    digitalWrite(RTS_PIN, HIGH); /* Set RTS high after sending */
   }
#else
    if (WiFi_DataReceived) {
     Serial.print(WiFi_Buffer);	/* Print received Wi-Fi data */
     WiFi_Buffer = "";		/* Clear the buffer after processing */
     WiFi_DataReceived = false;	/* Reset the flag after processing the data */
    }
 
    if (Serial.available()) {
     while (Serial.available()) {
      Serial_Buffer += (char)Serial.read(); /* Read all available data from the Serial */
     }
     Serial_DataReceived = true; /* Set Serial data received flag */
    }
 
    /*
     Send Serial data over Wi-Fi if received.
    */
     if (Serial_DataReceived) {
      client.print(Serial_Buffer); /* Send Serial data to Wi-Fi client */
      Serial_Buffer = "";          /* Clear the Serial buffer after processing */
      Serial_DataReceived = false; /* Reset the Serial data received flag */
    }

#endif /* HARD_HANDSHAKING */
   }
  }
}

Saturday, 27 April 2024

Tim's LU9685-20UC Servo Controller

 


This is a little application I made to control Servo using the new LU9685-20UC Servo Controller.





With this application, it is possible to control 32 LU9685-20CU devices, each with 16 Servo attached.
A total of 512 Servo.



Done the Pre-Set Dialog Box
Here you can store Pre-Set Positions of the Servo.






Monday, 30 October 2023

Tim's Digital Video Device Viewer

I have a cheep USB Microscope.
I think mine is just 100X.
I have seen some advertised at 1000X and 1600X.
There are many out there I believe most may have the same image sensor with just different lenses.

Finding the right software to view what is seen by the Microscope can often be hard to find, and one that does what I want it to do.

So I decided to make my own Application.


The Application can be downloaded here: Tim's New Video Device Viewer.zip
Unzip and run setup.
Updated 03/04/2024, Updated to Windows 11 screwed things up again.
The old version is called:   "Tim's Video Device Viewer"
The new version is called: "Tim's New Video Device Viewer"
 

The Camera Settings are the settings of the Device.
They are not adjustments to the image received.


It has a Take Photo button.
This saves the current image to disk.

It has Start Video button.
This starts recording video, click it again stops the recording.
The recording is a bit basic, higher resolutions tend to get the framerate wrong, I need to work this out.
I didn't really make it  for recording video though.

The path to which the Photo and video can be set.

Also I have added some overlays.
These are just some lines to make it look cool more professional haha.











Wednesday, 20 May 2020

Tim's ESP32 Cam Viewer



This is a little application I wrote, so that I could view images from my ESP 32 Cam breakout board.

 



It works with ESP32-CAM module, programmed with Arduino IDE, with ESP32 libraries installed.

I installed the Camera Web Server

I created it so that I could use it like a web cam in my videos.
Here is an example:










Friday, 15 May 2020

Tim's Serial Monitor



Some times I didn't want to load up the Arduino IDE or MS Visual Studio to view the output from one of my Arduino projects.
So I made this little Serial monitor to view the data.


I original wrote it to test and program my Bluetooth devices.
Its very handy for sending/testing commands to my Bluetooth controlled projects
(It cant handle very fast data, I'm no pro at programming, I need to learn a little more for it to cope with very fast data.)

If you want to know more. ask. 

Tim's Image Pixel Editor




This is a little application I made to edit and create Images and fonts for the small displays used by the Arduino.

Like the small Mono (Black and White) OLED 0.96 inch 128 x 64 pixels I2C connection.



I wrote this to create the binary arrays used in Arduino code to show graphics and text on the small screens.

It will also read those bit and bytes found in code.

Done a video.



Tims PCA 9685 Controller


This is a little application I made to control Servo and LED via the PCA9685 LED controller chip.

PCA9685 16x Servo Driver



With this application, it is possible to control 64 PCA9685 devices, each with 16 servo or LED attached.
A total of 1024  items (Servo/LED).

The devices need to be connected to an Arduino, communicating via I2C.
The Arduino requires the firmware installing that is included in the Tims_PCA_9685_Controller.zip
With the Application you can run scripts of pre determined positions of all the Servo/LED connected.
If you have more than one PCA9685, you can quickly switch between them.

There are some setting where you can adjust the Min, Max and Centre of each Servo.


In Tims_PCA_9685_Controller.zip  there is a little program called XLoader.
Just choose the HEX file to Upload:
Tims_PCA9685_16_LED_Servo_Controller_UNO.hex is for the Arduino UNO.
Tims_PCA9685_16_LED_Servo_Controller_NANO.hex is for the Arduino NANO.
Tims_PCA9685_16_LED_Servo_Controller_NANO_Old.hex is for the Arduino NANO with Old Bootloader.
Select which Arduino you are uploading to.
Select the port it is connected to.
Click Upload.

Here is a demonstration of controlling Servo



Here is a demonstration of controlling LED.




I have done a version 2, version 2 allows for controlling both LED and Servo on the same PCA9685 breakout board.


Also has a Pre-Set window, where you can have 20 pre-sets stored and values and re-send them at a click of a button..


This window can be resized to suit your own preferences.


The current version is: 2.0.0.11 (firm updated at 2.0.0.8)
If you install this version 2 over a previous version 2 under 2.0.0.5
you will need to load default pre-sets, the file is included in the zip.

I had to change a few things in the original pre-sets code so that; when a pre-set is sent, it also moves the sliders to the settings sent.
This is so adjustments can be made from known setups.
The file it saves settings to is just a basic rtf text file.

I am currently working on a project, that uses servo and LED, and I am altering the tool as needed to help me with the project.
If I think other things will help, I will update it.

I will add more about it if I am asked.
If you like it let me know.

I have recently found a great video showing how to use the software.


Do you have a bad PCA9685

I have done a video of three bad PCA9685 controllers I bought of eBay





Using you own application, to communicate with the Arduino:

I use Visual Basic.
I send data like this:
If OKtoSendData And SerialPort1.IsOpen Then
OKtoSendData = False
SerialPort1.Write(New Byte() {86,
BitConverter.GetBytes(Value_00)(0), BitConverter.GetBytes(Value_00)(1),
BitConverter.GetBytes(Value_01)(0), BitConverter.GetBytes(Value_01)(1),
BitConverter.GetBytes(Value_02)(0), BitConverter.GetBytes(Value_02)(1),
BitConverter.GetBytes(Value_03)(0), BitConverter.GetBytes(Value_03)(1),
BitConverter.GetBytes(Value_04)(0), BitConverter.GetBytes(Value_04)(1),
BitConverter.GetBytes(Value_05)(0), BitConverter.GetBytes(Value_05)(1),
BitConverter.GetBytes(Value_06)(0), BitConverter.GetBytes(Value_06)(1),
BitConverter.GetBytes(Value_07)(0), BitConverter.GetBytes(Value_07)(1),
BitConverter.GetBytes(Value_08)(0), BitConverter.GetBytes(Value_08)(1),
BitConverter.GetBytes(Value_09)(0), BitConverter.GetBytes(Value_09)(1),
BitConverter.GetBytes(Value_10)(0), BitConverter.GetBytes(Value_10)(1),
BitConverter.GetBytes(Value_11)(0), BitConverter.GetBytes(Value_11)(1),
BitConverter.GetBytes(Value_12)(0), BitConverter.GetBytes(Value_12)(1),
BitConverter.GetBytes(Value_13)(0), BitConverter.GetBytes(Value_13)(1),
BitConverter.GetBytes(Value_14)(0), BitConverter.GetBytes(Value_14)(1),
BitConverter.GetBytes(Value_15)(0), BitConverter.GetBytes(Value_15)(1),
13, 10
}, 0, 35)
}
Threading.Thread.Sleep(100) 'wait a little for comunication to end.
End If
The above:
86 = ASCII for V.
BitConverter splits the values(16bit) in the array(16) into two bytes(8bit).
13 = ASCII for Carriage Return.
10 = ASCII for Line Feed.

As you are only turning on or off, your values will be 0 or 4095
To change to a different PCA I send the address-64 and the frequency I want it set at.
My basic code looks like this:
If OKtoSendData And SerialPort1.IsOpen Then
OKtoSendData = False
Dim frequencyBit0 As Byte = BitConverter.GetBytes(Convert.ToInt16(My.Settings.Frequency_NumericUpDown))(0)
Dim frequencyBit1 As Byte = BitConverter.GetBytes(Convert.ToInt16(My.Settings.Frequency_NumericUpDown))(1)
My.Settings.DeviceAddress = DeviceAddress
SerialPort1.Write(New Byte() {65,
DeviceAddress,
frequencyBit0, frequencyBit1,
13, 10}, 0, 5)
End If
65 = ASCII for A.
DeviceAddress is only 1 byte as I have reduced the value by 64.
frequency needs to be split into two bytes.
13 = ASCII for Carriage Return.
10 = ASCII for Line Feed.

It has to be bytes (8 bit values) you send.
V or A followed by numbers wont work, that would just be send as text values.

So for example:
To send command to change PCA at address 64 and set frequency to 1000 Hz, would need the following:

ASCII A = 65, to let Arduino know its an address change. (ASCII for V would let Arduino know 16(32) values are coming)
Address = 64 - 64 = 0
frequency = 1000, split this 16 bit value in to 2 8 bit values, LSB and MSB.
1000 16bit binary = 0000 0011 1110 1000.
LSB = 1110 1000 = 232
MSB = 0000 0011 = 3
A carriage return and line feed. 13 and 10.

So sent would be: 65 0 232 3 13 10

Your app must send it as bytes not text.

When Arduino receives a correct command it will confirm it in normal ASCII text, also Arduino will send an "ok".
When your app. receives an "ok" from Arduino, your app. knows that it can send another command.

An example of sending values would be:
As my script shows it: V 4095 4095 0 0 0 0 0 0 0 0 0 0 0 0 0 0
as it is sent in bytes: 86 255 15 255 15 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 13 10