I am able to upload data to this LCD, but the touch buttons on this LCD are sending some signals in Low Byte which are then supposed to initiate some process in the microcontroller. Below is the code which is supposed to handle the incoming communication. It is not working. Where am I going wrong?
void Touch_Button_Activity()
{
if (Serial2.available() >= 9) // Ensure there are at least 9 bytes available
{
for (int i = 0; i < 9; i++)
{
Buffer[i] = Serial2.read();
}
// Debug: Print buffer content
Serial.print("Buffer: ");
for (int i = 0; i < 9; i++)
{
Serial.print(Buffer[i], HEX);
Serial.print(" ");
}
Serial.println();
if (Buffer[0] == 0x5A)
{
switch (Buffer[4])
{
case 0x55:
// Use the Low Byte (Buffer[8]) to determine the touch button state
switch (Buffer[8])
{
case 0:
Baseline = average;
Serial.println("Baseline set to average");
break;
case 1:
Baseline = average;
Serial.println("Baseline set to average");
break;
case 2:
Factor = average - Baseline;
Serial.println("Factor set to average - Baseline");
break;
default:
Serial.println("Unexpected value in Buffer[8]");
break;
}
break;
default:
Serial.println("No communication received from touch screen.");
break;
}
}
else
{
Serial.println("Invalid start byte in Buffer");
}
}
}
You deleted your two other threads on the same subject this is good.
double-posting is against forum-rules.
imagine any person trying to analyse what the problem is.
Any person
except that person that has had this special kind of faulty behaviour dozens of time
will start analysing
by reading your complete sketch => post your complete sketch
by reading the datasheet => provide the datasheet of this LCD
printing the received bytes to the serial monitor => post what is printed to the serial monitor as a code-section
uploading a demo-code that is well known for working for checking if hardware-wiring is OK
You are working on an informatic poject and what is needed most in an informatic project is information.
Hard to tell; what output do you get from your sketch on the Serial monitor if you input some data on the keypad? Do you get anything? Can you show us some examples of the output that's generated? Do you have a protocol description that you can post that shows what kind of data format is being sent by the module?
Also, I see there's two TX/RX pairs on the header of your UI module; are you using the correct pair? Have you also verified that the TTL/RS232 jumper on the PCB is correctly set for your application?
#include <Arduino.h>
#include <Adafruit_ADS1X15.h>
#include <cmath>
Adafruit_ADS1115 ads; /* Use this for the 16-bit version */
const int numReadings = 100; // Number of readings to average
int readings[numReadings]; // Array to store readings
int readIndex = 0; // Index for current reading
int total = 0; // Running total of readings
int average = 0; // Moving average
bool CodeRunningFirstTime = true;
unsigned long TimeSinceCodeStart;
unsigned long LastDataDisplayMillis;
double Baseline = 0.00;
double Factor = 260.00;
double Volume = 0.00;
//DWIN Part
const byte rxPin = 16;
const byte txPin = 17;
#define some_value_add 0x50
unsigned char HMI_some_value[8] = {0x5A, 0xA5, 0x05, 0x82, some_value_add, 0x00, 0x00, 0x00};
unsigned char Buffer[9];
void setup()
{
Serial.begin(115200);
if (!ads.begin())
{
Serial.println("Failed to initialize ADS.");
while (1);
}
else
{
Serial.println("ADS Initialised");
}
// Initialize the readings array
for (int i = 0; i < numReadings; i++)
{
readings[i] = 0;
}
//DWIN Part
Serial2.begin(115200, SERIAL_8N1, rxPin, txPin); // Initialize Serial2 on pins 16 and 17
TimeSinceCodeStart = millis();
LastDataDisplayMillis = millis();
}
void loop()
{
int16_t adc0;
adc0 = ads.readADC_SingleEnded(0);
// Update the total by subtracting the oldest reading and adding the new reading
total = total - readings[readIndex] + adc0;
// Store the new reading in the array
readings[readIndex] = adc0;
// Move to the next index
readIndex = (readIndex + 1) % numReadings;
// Calculate the moving average
average = total / numReadings;
//Serial.println(average);
if((millis()-TimeSinceCodeStart) > 2000)
{
if(CodeRunningFirstTime == true)
{
Baseline = average;
CodeRunningFirstTime = false;
}
}
Volume = (average - Baseline)/Factor;
Data_Display();
Touch_Button_Activity();
}
void Data_Display()
{
if((millis()-LastDataDisplayMillis) >= 0)
{
int t_int = Volume * 100; // Convert float to int to preserve two decimal places
HMI_some_value[6] = highByte(t_int);
HMI_some_value[7] = lowByte(t_int);
Serial2.write(HMI_some_value, 8); // Use Serial2 instead of SoftwareSerial
LastDataDisplayMillis = millis();
}
}
void Touch_Button_Activity()
{
if (Serial2.available() >= 9) // Ensure there are at least 9 bytes available
{
for (int i = 0; i < 9; i++)
{
Buffer[i] = Serial2.read();
}
// Debug: Print buffer content
Serial.print("Buffer: ");
for (int i = 0; i < 9; i++)
{
Serial.print(Buffer[i], HEX);
Serial.print(" ");
}
Serial.println();
if (Buffer[0] == 0x5A)
{
switch (Buffer[4])
{
case 0x55:
// Use the Low Byte (Buffer[8]) to determine the touch button state
switch (Buffer[8])
{
case 0:
Baseline = average;
Serial.println("Baseline set to average");
break;
case 1:
Baseline = average;
Serial.println("Baseline set to average");
break;
case 2:
Factor = average - Baseline;
Serial.println("Factor set to average - Baseline");
break;
default:
Serial.println("Unexpected value in Buffer[8]");
break;
}
break;
default:
Serial.println("No communication received from touch screen.");
break;
}
}
else
{
Serial.println("Invalid start byte in Buffer");
}
}
}
I am able to send data to the LCD but not from the LCD to the board.
I don't understand what you want to say with that.
Which is the "first line commented out?"
first line of your complete sketch?
the line
void Touch_Button_Activity()
?
any other line?
analyse at my writing-style:
I do not write about a whatever "first" line
I repeatedly write the line explicitly
So there is no room for interpretation.
If you comment out the line
void Touch_Button_Activity()
this means you remove the function "Touch_Button_Activity()"
You can solve your problems two ways:
way 1: always quickly posting a short description just for having posted quickly
way2: taking the time to post a complete sketch each and every time
including what gets printed to the serial monitor
writing not with words like "this", "it", 2the second" etc.
but explcitly naming everything by its clearly identifiable and unique name.
Which in the end will be faster than quick postings.
Quick but less informative postings just cause asking back or not answering at all.
=> result delayed solving of problems.
What you've found out is that it really helps to whittle down your sketch to the bare minimum required to demonstrate the problem. So I'd recommend to make a new sketch that only reads input from the LCD/keypad module, and outputs it back to the Serial monitor so you can see what's going on - nothing else. That will allow you to learn to interface with the keypad module properly. Then start dressing it back up and add functionality.
What's biting you currently is a form of interactive complexity; i.e. your system exhibits behavior due to unintended interactions between parts (in this case of your own software) that you did not foresee. The oversight is due to the complexity surpassing your ability to comprehend what's going on. So the fundamental way to deal with this is to break down the whole thing into smaller chunks that you do understand, so that their behavior once again becomes linear and predictable.
Feel free to ignore the second, theoretical paragraph and just remember what the Romans also knew very well: "divide and conquer".
Here is your code with additional debug-printing to the serial monitor that makes visible what is going on.
This is the usual way to analyse and narrow down such problems
I have written above what kind of information you should provide.
// MACRO-START * MACRO-START * MACRO-START * MACRO-START * MACRO-START * MACRO-START *
// a detailed explanation how these macros work is given in this tutorial
// https://forum.arduino.cc/t/comfortable-serial-debug-output-short-to-write-fixed-text-name-and-content-of-any-variable-code-example/888298
#define dbg(myFixedText, variableName) \
Serial.print( F(#myFixedText " " #variableName"=") ); \
Serial.println(variableName);
#define dbgi(myFixedText, variableName,timeInterval) \
{ \
static unsigned long intervalStartTime; \
if ( millis() - intervalStartTime >= timeInterval ){ \
intervalStartTime = millis(); \
Serial.print( F(#myFixedText " " #variableName"=") ); \
Serial.println(variableName); \
} \
}
#define dbgc(myFixedText, variableName) \
{ \
static long lastState; \
if ( lastState != variableName ){ \
Serial.print( F(#myFixedText " " #variableName" changed from ") ); \
Serial.print(lastState); \
Serial.print( F(" to ") ); \
Serial.println(variableName); \
lastState = variableName; \
} \
}
#define dbgcf(myFixedText, variableName) \
{ \
static float lastState; \
if ( lastState != variableName ){ \
Serial.print( F(#myFixedText " " #variableName" changed from ") ); \
Serial.print(lastState); \
Serial.print( F(" to ") ); \
Serial.println(variableName); \
lastState = variableName; \
} \
}
// MACRO-END * MACRO-END * MACRO-END * MACRO-END * MACRO-END * MACRO-END * MACRO-END *
#include <Arduino.h>
#include <Adafruit_ADS1X15.h>
#include <cmath>
Adafruit_ADS1115 ads; /* Use this for the 16-bit version */
const int numReadings = 100; // Number of readings to average
int readings[numReadings]; // Array to store readings
int readIndex = 0; // Index for current reading
int total = 0; // Running total of readings
int average = 0; // Moving average
bool CodeRunningFirstTime = true;
unsigned long TimeSinceCodeStart;
unsigned long LastDataDisplayMillis;
double Baseline = 0.00;
double Factor = 260.00;
double Volume = 0.00;
//DWIN Part
const byte rxPin = 16;
const byte txPin = 17;
#define some_value_add 0x50
unsigned char HMI_some_value[8] = {0x5A, 0xA5, 0x05, 0x82, some_value_add, 0x00, 0x00, 0x00};
unsigned char Buffer[9];
void setup(){
Serial.begin(115200);
if (!ads.begin()){
Serial.println("Failed to initialize ADS.");
while (1);
}
else{
Serial.println("ADS Initialised");
}
// Initialize the readings array
for (int i = 0; i < numReadings; i++){
readings[i] = 0;
}
//DWIN Part
Serial2.begin(115200, SERIAL_8N1, rxPin, txPin); // Initialize Serial2 on pins 16 and 17
TimeSinceCodeStart = millis();
LastDataDisplayMillis = millis();
}
void loop() {
int16_t adc0;
adc0 = ads.readADC_SingleEnded(0);
// Update the total by subtracting the oldest reading and adding the new reading
total = total - readings[readIndex] + adc0;
// Store the new reading in the array
readings[readIndex] = adc0;
// Move to the next index
readIndex = (readIndex + 1) % numReadings;
// Calculate the moving average
average = total / numReadings;
//Serial.println(average);
if ((millis() - TimeSinceCodeStart) > 2000) {
if (CodeRunningFirstTime == true) {
Baseline = average;
CodeRunningFirstTime = false;
}
}
Volume = (average - Baseline) / Factor;
Data_Display();
Touch_Button_Activity();
}
void Data_Display() {
if ((millis() - LastDataDisplayMillis) >= 0) {
int t_int = Volume * 100; // Convert float to int to preserve two decimal places
HMI_some_value[6] = highByte(t_int);
HMI_some_value[7] = lowByte(t_int);
Serial2.write(HMI_some_value, 8); // Use Serial2 instead of SoftwareSerial
LastDataDisplayMillis = millis();
}
}
void Touch_Button_Activity() {
dbgc("TBA",Serial2.available() ); // whenever number Serial2.available() has a different number print once
if (Serial2.available() >= 9) { // Ensure there are at least 9 bytes available
for (int i = 0; i < 9; i++) {
Buffer[i] = Serial2.read();
}
// Debug: Print buffer content
Serial.print("Buffer: ");
for (int i = 0; i < 9; i++) {
Serial.print(Buffer[i], HEX);
Serial.print(" ");
}
Serial.println();
dbgc("buf",Buffer[0]); // whenever Buffer[0]has a different value print once
if (Buffer[0] == 0x5A) {
switch (Buffer[4]) {
case 0x55:
// Use the Low Byte (Buffer[8]) to determine the touch button state
switch (Buffer[8]) {
case 0:
Baseline = average;
Serial.println("case 0 Baseline set to average");
break;
case 1:
Baseline = average;
Serial.println("case 1 Baseline set to average");
break;
case 2:
Factor = average - Baseline;
Serial.println("case 2 Factor set to average - Baseline");
break;
default:
Serial.print("Unexpected value in Buffer[8] value is");
Serial.println(Buffer[8]);
break;
}
break;
default:
Serial.print("default: Buffer[4] has value ");
Serial.println(Buffer[4]);
break;
}
}
else {
Serial.print("Invalid byte in Buffer[0] value is ");
Serial.println(Buffer[0]);
}
}
}
Ok, I have tried a simpler sketch and I am confused.
What I did.
I connected an LED to the ESP32 board to debug.
I tested the LED connections by trying to light the LED by putting the relevant code line in the Loop function.
After the LED was successfully lit, I put the LED lighting code line in the Touch function under if statement, and called the Touch function in the Loop function.
The LED did not light up.
Then, without powering up the LCD, I connected the LCD RX pin to the Tx pin of the ESP32 board, and the Tx pin of of the LCD to the Rx pin of the ESP32 board, using Dupont Jumper cables.
The LCD end of the jumper cables were then cut and soldered to the LCD points, to make sure that the connection was good. The ESP32 board side of the jumper cable is still the dupont jumper type.
The moment the jumper cables touched the relevant pins on the ESP32 came in touch with the Jumper cables, the LED lighted up.
I was surprised how this could happen as the LCD was not powered.
With the jumper cables still connected, I removed the data cable connecting the ESP32 board to he computer, and then reconnected it to the computer. Now the LED did not light up.
Now with the ESP32board connected to he computer and the LED not lit, I removed he jumper cables on the RX Tx pins of the ESP32 board, and reconnected them. Istantly the LED lighted up again.
So apparrently, somehow the if(Serial2.available) condition is fulfiled when the Jumper cables are connected to the unpowered LCD.
What is happening?
Below is my code.
const int ledPin = 18;
const byte rxPin = 16;
const byte txPin = 17;
void setup() {
// setup pin 5 as a digital output pin
pinMode (ledPin, OUTPUT);
Serial2.begin(115200, SERIAL_8N1, rxPin, txPin); // Initialize Serial2 on pins 16 and 17
Serial.begin(115200);
}
void loop() {
Touch();
//digitalWrite (ledPin, HIGH);
}
void Touch()
{
if (Serial2.available())
{
Serial.println("Howdy");
digitalWrite (ledPin, HIGH); // turn on the LED
}
}
Please post a schematic of this experimental setup and some photos of how it's all wired up.
It sounds to me like a dangling wire or unpowered module on the ESP's Serial2 RX is simply creating noise which ends up as a random character in the UART buffer. Try printing out the characters that are received on Serial2; I bet it's just random noise.