I may have discovered a wrinkle with the TFT_eSPI library.
First, Bill did document the library version used in the original build: v 2.4.79. He also documented the required change to User_Setup_Select.h in order for the library to work with the TTGO module.
What I discovered is that modification is discarded if you change the library version. You have to remember to reimplement the change.
You should also select the TTGO board (I use TTGO LoRa32-OLED)
The one who has the most fun, wins!
Hello,
Yes, I have two power supplies. I turned off the motors in the video. The car runs perfectly, though. See the video.
For confirmation:
ESP32 Board: 2.0.17
Neo Pixel v-Miller: 2.8.4
TFT v. Bodmer: 2.2.20
In version 1.4.20, there is no "User_Setups/Setup25_TTGO_T_Display.h" file.
I made the changes to the TFT. I'm aware that the User_Setup_Select.h file needs to be adjusted when switching to a different version. I'm using "User_Setups/Setup25_TTGO_T_Display.h".
With other versions, the display remains black.
I'm selecting the T1 board as the TTGO board. However, I'll try the TTGO LoRa32-OLED.
When I insert your code, no values appear in the serial monitor, except for the "ModeValue" values. I also don't want you to waste unnecessary time on this. It has to work without the bars.
imortant
When I insert your code, no values appear in the serial monitor, except for the "ModeValue" values.
This isn't clear to me. The video didn't come through on my end so I can't tell what the output looked like. It sounds like it looked like this:
motorMode : 0 mecanumMode: 0 mtrRF_PWM : 0 mtrLF_PWM : 0 mtrRR_PWM : 0 mtrLR_PWM : 0
It's important if the text labels showed up.
The one who has the most fun, wins!
I inserted the code into the `b_callback` function of the robot-remote sketch (image 1). The output is set to serial monitor zero.
Originally, the serial monitor of the robot-car sketch outputs this (image 2).
When I insert the code into the `b_callback` function of the robot-car sketch, I get an error message.
"
exit status 1
'struct_message_rcv' {aka 'struct struct_message_rcv'} has no member named 'motorMode'
If I simply add:
Serial.printf(
"motorMode : %i\n"
"mecanumMode: %i\n"
"mtrRF_PWM : %i\n"
"mtrLF_PWM : %i\n"
"mtrRR_PWM : %i\n"
"mtrLR_PWM : %i\n"
the following appears on the serial monitor of the robot-car sketch (video).
Also attached is the video of the moving car.
First,
Also attached is the video of the moving car.
Christmas is saved! Ho-ray! Your grandkids will have a wonderful toy to play with. Yay for you! The display may not be working but we can live with that. So we don't want to mess that up.
Second,
When I insert the code into the `b_callback` function of the robot-car sketch, I get an error message.
Disturbia.
This defect is very resistant to diagnosis and resolution and an example of Murphy's Law: Anything that can go wrong, will go wrong.
We're getting the messages between the remote and car confused. You added the code to the car OnDataRecv but I asked to add it to the remote OnDatatRecv:
Could you please add and run the following code to the remote OnDataRecv:
The remote sends a message to the car that contains data about the joystick:
// mec-robot-remote.ino ...
// Create a structured object for sent data
typedef struct struct_message_xmit {
int xAxis;
int yAxis;
bool pbSwitch;
} struct_message_xmit;
// Create a structured object for sent data
struct_message_xmit xmitData;
//...
The car receives this message using a matching structure:
// mec-robot-car.ino ...
// Define a data structure for received data
typedef struct struct_message_rcv {
int xAxis;
int yAxis;
bool pbSwitch;
} struct_message_rcv;
// Create a structured object for received data
struct_message_rcv rcvData;
// ...
// car b_callbacks.ino
// Callback function executed when data is received
void OnDataRecv(const uint8_t* mac, const uint8_t* incomingData, int len) {
if (len == 0) {
// No data received, error condition
// Stop all motors
stopMotors();
// Put LEDs into Error mode
ledError();
// Set controller values to default
joyXaxis = 127;
joyYaxis = 127;
joySwitchState = true;
return;
}
memcpy(&rcvData, incomingData, sizeof(rcvData));
//Serial.print("X = ");
//Serial.print(rcvData.xAxis);
//Serial.print(", Y = ");
//Serial.print(rcvData.yAxis);
//Serial.print(", SW = ");
//Serial.println(rcvData.pbSwitch);
// Pass received values to local variables
joyXaxis = rcvData.xAxis;
joyYaxis = rcvData.yAxis;
joySwitchState = rcvData.pbSwitch;
// Check to see if we are changing Mecanum mode
if (joySwitchState == true) {
// Switch was pressed, toggle mecanum mode
toggleMecanumMode();
}
// Update last received time counter
lastRecvTime = millis();
}
Adding my code to this function will generate the error message you got because struct_message_rcv doesn't contain wheel PWM data.
So, this isn't where we wish to make the change.
The car sends a message to the remote that contains data about the wheels:
// mec-robot-car.ino
//...
// Define a data structure for sent data
typedef struct struct_message_xmit {
byte motorMode;
int mecanumMode;
int mtrRF_PWM;
int mtrLF_PWM;
int mtrRR_PWM;
int mtrLR_PWM;
} struct_message_xmit;
// Create a structured object for sent data
struct_message_xmit xmitData;
//...
The remote receives this message using a matching structure
// mec-robot-remote.ino
// ...
// Define a data structure for received data
typedef struct struct_message_rcv {
bool motorMode;
int mecanumMode;
int mtrRF_PWM;
int mtrLF_PWM;
int mtrRR_PWM;
int mtrLR_PWM;
} struct_message_rcv;
// Create a structured object for received data
struct_message_rcv rcvData;
//...
Here is my change to the remote OnDataRecv
// remote b_callbacks.ino
// Callback function executed when data is received
void OnDataRecv(const uint8_t* mac, const uint8_t* incomingData, int len) {
// Get receievd data
memcpy(&rcvData, incomingData, sizeof(rcvData));
// Pass received values to local variables
motorModeValue = rcvData.motorMode;
mecanumModeValue = rcvData.mecanumMode;
mtrRFpwmValue = rcvData.mtrRF_PWM;
mtrLFpwmValue = rcvData.mtrLF_PWM;
mtrRRpwmValue = rcvData.mtrRR_PWM;
mtrLRpwmValue = rcvData.mtrLR_PWM;
//Serial.println(mecanumModeValue);
Serial.printf(
"motorMode : %i\n"
"mecanumMode: %i\n"
"mtrRF_PWM : %i\n"
"mtrLF_PWM : %i\n"
"mtrRR_PWM : %i\n"
"mtrLR_PWM : %i\n"
, rcvData.motorMode
, rcvData.mecanumMode
, rcvData.mtrRF_PWM
, rcvData.mtrLF_PWM
, rcvData.mtrRR_PWM
, rcvData.mtrLR_PWM
);
}
I successfully compiled this code on my system before I posted it because I didn't want to give you code that doesn't compile.
And yet Murphy's Law insured that's exactly what happened.
The result of this should be that when the both the car and remote have power and the remote (only) is connected to the USB port, the remote will print out the stream of messages from the car about the wheel PWM values. We want to see that those values change in response to the joystick and. hopefully, get reflected in the display.
But the way this is going, don't hold your breath! 😉
The one who has the most fun, wins!
Okay, I've inserted your code into the remote sketch and uploaded it. The serial monitor shows the following. See the images. I hope I did it right this time and you can make sense of it. Nothing happens when I move the joystick.
Okay, I've inserted your code into the remote sketch and uploaded it.
This means it successfully compiled. That's good.
We only changed the receive function on the remote, so the remote should be sending the joystick messages to the car as before. That's what we want.
We haven't touched the car so it should still be receiving the joystick messages from the remote as before. We want that too.
The serial monitor shows the following.
The serial monitor image indicates that the remote isn't getting any messages from the car. This is good news depending on the answer to the question:
Is the car still moving as before?
The one who has the most fun, wins!
Nothing happens when I move the joystick.
This is really a postscript to the previous post. (trying to avoid the dreaded "spam" detector)
Under the assumption that the car moves as before, the conclusion is that the communication from the car to the remote is faulty. So, I started to review that execution pathway.
And I came across this in mec-robot-car.ino:
// setup
//...
// Initilize ESP-NOW
if (esp_now_init() != ESP_OK) {
Serial.println("Error initializing ESP-NOW");
return;
}
// Initilize ESP-NOW
if (esp_now_init() != ESP_OK) {
return;
}
//...
Disturbia. This can't be good.
It may be benign, but it is clearly not intended. And the symptoms point to a problem with ESP-NOW.
I checked the source code archive and it's there and it also in the video.
The one who has the most fun, wins!
Sorry, I was out yesterday and couldn't get back to you.
Yes, the car is still running.
I've added a serial output to the remote sketch for testing purposes:
// Initialize ESP-NOW
if (esp_now_init() != ESP_OK) {
connectStatus = "ESP-NOW Error";
Serial.println("Error initializing ESP-NOW");
connectError = HIGH;
return;
} else {
connectStatus = "ESP-NOW OK";
Serial.println("ESP-NOW ok");
connectError = LOW;
}
and
// Add peer
if (esp_now_add_peer(&peerInfo) != ESP_OK) {
connectStatus = "No peer added";
connectError = HIGH;
Serial.println("Error peer");
return;
} else {
connectStatus = "ESP-NOW Ready";
connectError = LOW;
Serial.println("peer i.o");
}
Output in the serial monitor.
ESP-NOW ok
peer i.o
To rule out any hardware problems, I've ordered another TTGO-T1 and an ESP32-WROVER-E/IE. They should arrive by the end of the week. I simply can't understand why the first project worked perfectly, but the second one just doesn't work at all.
God's ways are mysterious. 😆 😔 😕
Sorry, I was out yesterday and couldn't get back to you.
Yikes! This was a near thing! I was convinced you had dropped the thread, so I'd returned back to some of my other interests. I was about to clear the project files and libraries off my system, because I thought the thread was dead, but just happened to look at the forum before doing it. (I didn't get notifications because you didn't use my forum name in the replies.)
I forgot that this thread is badly stretched out due to time zones, language, and the difficulty of diagnosing "from afar." Everything we've done up until now would have taken an hour or two if we were in the same room. So, going forward, I think I need to get an extra helping of patience.
Yes, the car is still running.
I hope you realize this is a major result. This greatly simplifies the testing and isolates the problem to a fairly narrow pathway. To borrow Bill's image of the components
We've eliminated the pathway from the remote to the car (red square) so we can focus on the pathway from the car to the remote. Since the car uses a standard ESP32 chip, we can eliminate the physical car (green square) and use just any ESP32 chip for testing. We still have to use the remote because it's the only device that replicates the problem. (Please say you didn't solder the chip directly to the perfboard but used mounting pins.)
The testing is focused on two issues:
- ESP=NOW communication between the car and remote
- The graphics commands the remote sends to the TTGO display.
We can test these separately.
The ESP-NOW testing should start with verifying the MAC address the car uses to communicate with the remote. Double check using the getmac sketch on the remote. From there we can check if the car is able to send out messages to an ESP32 other than the remote. This will also indicate if the remote should be able to receive messages from any ESP32.
For the TTGO graphics commands, we can "force" the remote to display the bars for the wheels independently from the ESP-NOW messages.
So, the first thing I'd do is double check the remote MAC address and verify that it's being used by the car. There may be some other ESP-NOW tests we can perform but that's the most obvious one.
We still have the library version carousel to go through.
From your code snippet I see that you're able to program well enough so that I don't need to explain code in detail. You know how to leave a "breadcrumb" trail. So, hopefully, the above gives you enough to code some tests.
I simply can't understand why the first project worked perfectly, but the second one just doesn't work at all.
This isn't accurate. Most of the car features are working. Just the display, which is "glitter" in functionality terms, isn't working.
You're asking an "advocate for quality and testing" guy why the software isn't working? One word; it rhymes with "Resting."
The project isn't repeatable. Testing.
The software is fragile. Testing.
The hardware is fragile. Testing.
The project takes a long time to build. Serious testing.
I'm not sure what to do next? Write a test.
Once you learn how to write even simple tests, the code will improve and the fun returns. You become the master of the project and not the ignorant lackey.
(Calm down Tim! Take a breath.)
The one who has the most fun, wins!
@tfmccarthy Okay. I'll start running some tests. The MAC addresses should definitely be correct. If I enter other addresses for testing, no connection is established. This means the default mode 0 isn't displayed; instead, it shows "Car not found." I'll take my time with this and get back to you. Please be patient.
Okay. I'll start running some tests. ... I'll take my time with this and get back to you. Please be patient.
Okay.
In the meanwhile, I'll take this opportunity to mention to dronebot #0 (aka @dronebot-workshop) that I'm aware that much of what I've talked about here is covered in the project documentation. I've repeated material because it seems like it may have been missed on a first read.
I do think we've discovered a minor defect, and we've addressed the esp32 library upgrade issue (though this still needs final verification). There's an additional modification I would propose for the library upgrade. That is to use the esp32 library version to distinguish the interface to the ESP-NOW API. I think this might be easier than the solution from the "ESP32 Boards Manager 3 – Updating Your Old Code" video, i.e., separate source files. If this sounds reasonable to you then I can try to create a post to that thread describing it.
Otherwise, I wanted to make it plain that I was paraphrasing much of your article.
The one who has the most fun, wins!
@tfmccarthy Hi,
It took a while, but I'm finally finished. I got a new display and an ESP32. And what can I say—it works! Graphs are being displayed. I don't know why or how. The main thing is that it's working.
I'd like to thank you very much for your help and wish you and everyone in the community a wonderful, and above all, peaceful Christmas.
Fantastic!
Well done.
I'm not sure but I think this makes you a certified mecanum car repair man.
I'm happy it worked out and glad to have helped.
The one who has the most fun, wins!




