I have an interesting bug in my code.
First a little background I'm trying to make a "simple" menu system together with freeRTOS, an encoder and an I2C LCD (16x2).
I have a string array just sitting there in the code doing nothing. Somehow it's printed to the LCD.
Never does Lcd.print make a call to that string.
here below is the sting on line 44 - 46.
Then I thought well let's remove this string and when that bug happens t esp32 crashes with a LoadProhibited fault.
I know what this error means (it means you can't read this bit of memory) so think this is just the way I send the data out to the lcd.
I have uploaded The code to Github and here is a video what happens.
thank you for the help in advance, sorry for another esp32 topic on the Arduino forum
Without examining it too closely, I'd begin to think that your method for initialising the Strings is, somehow, leaving them without a null terminator in their internal representation, allowing them to be concatenated with other unrelated display items.
Interesting problem though.
6v6gt:
Without examining it too closely, I'd begin to think that your method for initialising the Strings is, somehow, leaving them without a null terminator in their internal representation, allowing them to be concatenated with other unrelated display items.
that was also what i was thinking. here is where it gets more interesting.
when i do the same without freeRTOS (vTaskSuspend(), vTaskResume() and tasks pinned to core) this bug doesn't happen.
but the controlling code is more complex. and requires more space.
I don't see a string array (or an array of strings for that matter) anywhere in your code. I do see hoverer an awful lot of arrays of String. That's certainly very different
But if things start to appear on screen out of the blue, you probably overshoot an array or mangle a pointer somewhere. I don't get when the bug happens from the video but it's probably around that bit of code.
Things I noticed:
if ((long)(micros() - LastMicros) >= 25 * 1000) {
Dit you mean to make the multiplication a long? Because making the subtraction long makes NO sense. That would mangle any roll over protection you have from using unsigned and subtraction.
I don't want to distract you from finding out what exactly happened because we may learn something, but I'd tend to use this example of defining character arrays rather than Strings for your menu items. These are constants, so I guess you could event have them in flash memory ("PROGMEM") only, instead of also in RAM.
char *myStrings[] = {"This is string 1", "This is string 2", "This is string 3",
"This is string 4", "This is string 5", "This is string 6"
};
void setup() {
Serial.begin(9600);
}
void loop() {
for (int i = 0; i < 6; i++) {
Serial.println(myStrings[i]);
delay(500);
}
}
septillion:
I don't see a string array (or an array of strings for that matter) anywhere in your code. I do see hoverer an awful lot of arrays of String. That's certainly very different
oh didn't see that typo woops.
septillion:
But if things start to appear on screen out of the blue, you probably overshoot an array or mangle a pointer somewhere. I don't get when the bug happens from the video but it's probably around that bit of code.
what happens is this: mode has changed, goes into the task does its job and returns.
In that task it does something like this:
Pause the main menu task.
Changes the boundary of the encoder
Prints the mode on the LCD.
resume the main menu task.
Pause the task its in. (so demo or music)
when the button is pressed in the main menu the boundary is changed.
Now i wrote this down, think that 6 needs to go between 4 and 5.
Septillion thanks for the thing you noticed. changed it and works even better.
When the menu system is more worked out I want to compare the string that's on-screen and the "back" string.
so the code knows when to return to the main menu.
i have done this:
if (!settings[parameters.currentScherm].equals("Terug")) {
if I use the code here below do I lose this function?
char *myStrings[] = {"This is string 1", "This is string 2", "This is string 3",
"This is string 4", "This is string 5", "This is string 6"
};
I know that's an interesting way to compare a string. I went this way so it isn't hard to understand what I'm comparing against.
Also, I went this way so if the string ("back") is put somewhere else i didn't need to search in the code and change the 2.
thank you for the tip!
6v6gt:
But, if you want to do it as you had, but with character arrays, you'd do something like:
if ( strcmp ( settings[parameters.currentScherm] , "Terug" ) { // strcmp() returns 0 if match
shouldn't it be:
if ( !strcmp ( settings[parameters.currentScherm] , "Terug" )){ // strcmp() returns 0 if match
No. Look carefully at the comment following the 'if' statement. I had already anticipated that it might be confusing and it looks like the original code should execute only if there is no match
sebasdt1:
what happens is this: mode has changed, goes into the task does its job and returns.
In that task it does something like this:
Pause the main menu task.
Changes the boundary of the encoder
Prints the mode on the LCD.
resume the main menu task.
Pause the task its in. (so demo or music)
when the button is pressed in the main menu the boundary is changed.
Now i wrote this down, think that 6 needs to go between 4 and 5.
But back to the main problem or bug.
when i moved 6. between 4. and 5. (changed where a new boundary is set) The bug happened less but is still there.
so that means somewhere in the code i need to check if the value of the encoder is between the set boundary.
6v6gt:
No. Look carefully at the comment following the 'if' statement. I had already anticipated that it might be confusing and it looks like the original code should execute only if there is no match