HELP! Adding a new subroutine to my program causes other subroutines to be sporadic

Status
Not open for further replies.
I finally got my Teensy 4.1 to run my "Christmas tree" program using 2 parallel output pins to drive 2 WS2811 200 led string sections in my "prototype" 400 led "tree" comprised of ten 40-led strands. 3 firework subroutines in the program allow up to 3 aerial fireworks to display at the same time. They worked great. Then I decided to add a "rain" subroutine. Without even calling the routine, just the presence of the subroutine in my code causes my firework subs to be sporadic, eventually causing the program to hang. I first had the problem using an Arduino Due, so, thinking it was an insufficient memory or a cpu speed problem, I switched to the Teensy 4.1. I've attached the program sketch. go to the rain subroutine and see where I blocked out the last part of the sub. With just the last 2/3 of the sub blocked the fireworks work fine, but if I unblock this section, it's enough to mess up the fireworks! I hope someone more experienced might know what the problem is. Please help me out!

I'm using Arduino IDE 1.8.13 with the FastLED 3.3.3 library on a Windows 10 tower.
 

Attachments

  • Tree_Show.txt
    45.5 KB · Views: 74
There are a large number of arrays, writing (or reading) to any one of them outside its bounds could trigger such a problem,
so you need to add checks on all the array setting to track this down. Some of these arrays are more logically
structs or arrays of structs, and structs are safer and more readable.

You could try individually commenting out array writes in rain() to see if you can narrow it down that way.

Monolithic code like this is always much harder to debug than well-structured code with lots of little functions,
since small functions are easier to test and understand.
 
Also sometimes here it might help if you printed out some additional information about your build, like what did the system say about your build
For example I compiled and see a number of warnings:
Code:
"C:\\arduino-1.8.13\\hardware\\teensy/../tools/arm/bin/arm-none-eabi-g++" -c -O2 -g -Wall -ffunction-sections -fdata-sections -nostdlib -MMD -std=gnu++14 -fno-exceptions -fpermissive -fno-rtti -fno-threadsafe-statics -felide-constructors -Wno-error=narrowing -mthumb -mcpu=cortex-m7 -mfloat-abi=hard -mfpu=fpv5-d16 -D__IMXRT1062__ -DTEENSYDUINO=153 -DARDUINO=10813 -DARDUINO_TEENSY41 -DF_CPU=600000000 -DUSB_SERIAL -DLAYOUT_US_ENGLISH "-IC:\\Users\\kurte\\AppData\\Local\\Temp\\arduino_build_224732/pch" "-IC:\\arduino-1.8.13\\hardware\\teensy\\avr\\cores\\teensy4" "-IC:\\arduino-1.8.13\\hardware\\teensy\\avr\\libraries\\FastLED" "-IC:\\Users\\kurte\\Documents\\Arduino\\libraries\\SPI" "C:\\Users\\kurte\\AppData\\Local\\Temp\\arduino_build_224732\\sketch\\yyy.ino.cpp" -o "C:\\Users\\kurte\\AppData\\Local\\Temp\\arduino_build_224732\\sketch\\yyy.ino.cpp.o"
In file included from C:\Users\kurte\Documents\Arduino\yyy\yyy.ino:12:0:
C:\arduino-1.8.13\hardware\teensy\avr\libraries\FastLED/FastLED.h:14:21: note: #pragma message: FastLED version 3.003.003
 #    pragma message "FastLED version 3.003.003"
                     ^
yyy:108: warning: narrowing conversion of '-1' from 'int' to 'long unsigned int' inside { } 
 };
 ^
yyy:108: warning: narrowing conversion of '-1' from 'int' to 'long unsigned int' inside { } 
yyy:108: warning: narrowing conversion of '-1' from 'int' to 'long unsigned int' inside { } 
yyy:108: warning: narrowing conversion of '-1' from 'int' to 'long unsigned int' inside { } 
yyy:108: warning: narrowing conversion of '-1' from 'int' to 'long unsigned int' inside { } 
yyy: In function 'void firework0()':
yyy:228: warning: comparison between signed and unsigned integer expressions 
     for (int i = 0; i < burstheight[FWNo] + 1; i++)
                       ^
yyy:260: warning: comparison between signed and unsigned integer expressions 
       for (int i = 0; i < burstheight[FWNo] + 1; i++)
                         ^
yyy: In function 'void firework1()':
yyy:455: warning: comparison between signed and unsigned integer expressions 
     for (int i = 0; i < burstheight[FWNo] + 1; i++)
                       ^
yyy:487: warning: comparison between signed and unsigned integer expressions 
       for (int i = 0; i < burstheight[FWNo] + 1; i++)
                         ^
yyy: In function 'void firework2()':
yyy:679: warning: comparison between signed and unsigned integer expressions 
     for (int i = 0; i < burstheight[FWNo] + 1; i++)
                       ^
yyy:711: warning: comparison between signed and unsigned integer expressions 
       for (int i = 0; i < burstheight[FWNo] + 1; i++)
                         ^
yyy: In function 'void rain()':
yyy:913: warning: comparison between signed and unsigned integer expressions 
       for(int k = 0; k < droptypeparam[j][NUMPIXALS]; k++)
                        ^
yyy:915: warning: comparison between signed and unsigned integer expressions 
         for(int i = 0; i < droptypeparam[j][NUMPIXALS]; i++)
                          ^
yyy:958: warning: comparison between signed and unsigned integer expressions 
         if(raindrop[i][DROPTYPENO] == droptype)
                                    ^
yyy:963: warning: comparison between signed and unsigned integer expressions 
           for(int k = 0; k < droptypeparam[droptype][NUMPIXALS]; k++)
                            ^
yyy: In function 'void tree(int, int, int, int, int, int, int, int, int, int, int)':
yyy:1002: warning: unused variable 'fadenum' 
               fadenum = 0,
               ^
yyy:1003: warning: unused variable 'hue' 
               hue = 0;
               ^
C:\Users\kurte\Documents\Arduino\yyy\yyy.ino: At global scope:
yyy:30: warning: 'nxtitemno' defined but not used 
 static int itemno = 0, nxtitemno = 1;
                        ^
yyy:33: warning: 'curcsec' defined but not used 
 static unsigned long curcsec = 0, nxtmovcsec = 1, startcsecdelay = 1, csecdelay = startcsecdelay ;
                      ^
yyy:33: warning: 'nxtmovcsec' defined but not used 
 static unsigned long curcsec = 0, nxtmovcsec = 1, startcsecdelay = 1, csecdelay = startcsecdelay ;
                                   ^
yyy:33: warning: 'csecdelay' defined but not used 
 static unsigned long curcsec = 0, nxtmovcsec = 1, startcsecdelay = 1, csecdelay = startcsecdelay ;
                                                                       ^
yyy:44: warning: 'laststrand' defined but not used 
 static unsigned int strand[4], laststrand[4], fwring[4], burstheight[4], slowamt[4], doshootit[4];
                                ^
yyy:47: warning: 'startnxt' defined but not used 
 static unsigned long startnxt;
                      ^
yyy:48: warning: 'doithere' defined but not used 
 static unsigned int doithere[20][5][11], doithereno = 0, FWNum = 0, colrnum = 0;
                     ^
yyy:48: warning: 'doithereno' defined but not used 
 static unsigned int doithere[20][5][11], doithereno = 0, FWNum = 0, colrnum = 0;
                                          ^
yyy:48: warning: 'FWNum' defined but not used 
 static unsigned int doithere[20][5][11], doithereno = 0, FWNum = 0, colrnum = 0;
You might want to look through the different warnings and see if anything jumps out.
If you have not already done so, you can turn on showing all warnings, by going to the preferences page.

Also it does not appear to be likely, but I also see by chance you might be overflowing memory. I hacked up a version of code originally by FrankB which shows more info about the build:
Code:
FlexRAM section ITCM+DTCM = 512 KB
    Config : aaaaaaab (DDDDDDDDDDDDDDDI)
    ITCM :  24432 B	(74.56% of   32 KB)
    DTCM :  17088 B	( 3.48% of  480 KB)
    Available for Stack: 474432
OCRAM: 512KB
    DMAMEM:  12384 B	( 2.36% of  512 KB)
    Available for Heap: 511904 B	(97.64% of  512 KB)
Flash:  33840 B	( 0.42% of 7936 KB)
Note I believe @Frank B has a library that shows more or less the same information.

What I was looking at is how full is the lower 512KB code (ITCM) and Data (DTCM), such that maybe not much room for stack. I have seen cases where adding more more routine, caused the code size to grow such that it no longer fit in the number of 32KB blocks that ITCM was using, so it takes another 32KB block, which reduces the size available for DATA by that 32KB... But it looks like your code fits in one 32kb block.
And it looks like a lot of room left for stack...

As @MarkT mentioned sometimes in cases like this, I will use helper functions to do assignments, that could be defined as inline such that it adds no overhead except when you turn on debug stuff. And then in these helper functions I have things that check the index or indexes are in range, and if not prints out stuff. Also when I do that I may also pass in an optional parameter, like a caller number such that each different place I call it I give it a different number, so when the error happens it points back to where this happened...

Or in cases like this now, I might try hooking up the GDBStub stuff and try setting breakpoint at the print and then see where I am in the code.
 
Hey MarkT and KurtE, a most awesome THANKS to you both for your replies. I guess it's obvious my programming skills are reminiscent of the good old BASIC days. I will checkout all suggestions today and get back if unsuccessful. Again, thanks for taking the time!
 
Hi again,
I just posted followup apparently on a different category, Project Guidance (couldn't figure out why I couldn't find this post and finally figured it out). Here is what I posted there under "HELP2! Adding a new..."
Help again! Tried lots of things. Got rid of all compile warnings and narrowed the problem down to 4 lines of code plus 3 to get rid of a do while loop (line inside loop ok) If these 7 lines are commented out then firework subs work fine. If any ONE of the 4 lines or the do while loop is uncommented then I get the erratic firework behavior with eventual hang (which behavior always occurs exactly the same no matter which line is uncommented). Also, if I copy and paste ONE of these 4 lines into another subroutine, it will cause the same problem until commented out. Don't know if this is significant, but each of the 4 lines contain variables that are unsigned long variables, while lines among and after these 4 lines do not! I did try moving rain variable declarations to within the rain sub, but still same problem. I was thinking of trying the Arduino Pro IDE which looks like it has an easy interface to work with for debugging. I think it is still beta, any thoughts on it? I've attached a new copy of the sketch with the lines commented out in the rain subroutine. Again, anytime you can spare to help me is much, much appreciated!!
 

Attachments

  • Tree_Show.txt
    45.9 KB · Views: 175
PS. Here's response I gave to defragster on this other new post (I've included line numbers):
Dear defragster,
Thank you for your response! Sorry, I'm a newbie to this posting process and didn't think to add info to help those joining after the first post which was just "HELP! Adding a new...". The project is a "Christmas tree", the prototype of which has 10 strands of 40 WS2811 leds each. I wrote code to fill tree with bands/strands of colors that move, then I added code to display aerial fireworks. All worked well. Then I added a subroutine to display falling "rain", which worked fine, but then when I try to display the fireworks, they are erratic and finally hang. If you are interested, I would appreciate your help. The commented out lines mentioned above are in the void rain() sub which starts at line 897. The rain variables are declared at the beginning of the program (line 63). The 7 commented out lines begin on line 948. Again, thanks!
 
Some times it is real hard here to know what is going on in place like this.

For example you say that the function rain() is not called. yet changing lines of code in it effect things? Which needles to say should not happen. Sometimes this turns out that something corrupted memory before this point. So one thing I would do is to add something like: Serial.println("Rain Called"); Serial.flush();
At the start of the function just to make sure it was not called.

Other times it could be something like you are using the same array in some of the functions and one is influencing the other...

Does the screw up happen immediately or is randomly go bad... Which is harder to debug.

So not sure what to suggest to do next.

If it were me, I might try a complete dart board of things to see if anything sheds a light on it.

a) Throw a lot of Serial.print(... functions in all over everywhere printing out as much data that might shed light on issues.

b) I might add in debug code like GDBStub stuff, might put in either I think Frank has library, or the ST7735_t3 uncannyeyes 240x240 example sketch, not I PR to fix some of it), but there is code that tries to fill the stack with set value and then you call function go get an idea of how much stack space is used... I might put calls in to that at some locations to get ideas...

c) I might see if I can increase the size of many of the arrays by some fudge factor, and then maybe fill those in with some specific value, which the code maybe at times comes out to verify that data is still the default value...

d) If I think some main memory area might get corrupted, I might try some hacks, where I copy that memory some place else and then after call that I am suspecting might screw it up), I would then compare the array to the copy and see if they are still the same.

d1) Like I mentioned before (I think), I might replace all of the direct assignments to arrays, but instead go through some helper functions, which test the bounds and lets you know when you are out of bounds.

e) If you can setup a small version of the sketch that works properly without that code, I might again hack up the code that dumps many of the tables, maybe by Serial prints...
I would then keep that output to some editor, then enable the code, and run it again. And then compare the two dumps to get an idea what may have changed.

Again I know that there is nothing definitive here. But so far I don't see anything in your description to help localize the underlying issue. Unfortunately that is the nature of issues like this.
Example recently I spent a day reordering the pixels in an image depending on rotation and found a bug in my computation of which array index should be used, and I corrupted memory. I found it when I did what I mentioned of using a helper function to do the assignments.
 
KurtE, Thanks for taking the time to make these suggestions! I don't know anything about stacks and stack space. maybe that's where the problem is. Not sure how to check it, I'll have to research how to do it. Is there a way to increase amt of memory set aside for stacks? Again thanks!!
 
defragster - Thanks for checking for me. I'm embarrassed to say that I got my program to work after discovering a "for" loop that was supposed to go to 13, but somehow had gotten a 6 accidentally inserted to make it go to 163 (array was only 13 long)!

Thanks again to KurtE and MarkT for your help!
 
Status
Not open for further replies.
Back
Top