I have a strange issue: This code only works, if the "Serial.print(".");" statement is present in the powerOn/Off animation function.
Any ideas why?
Thanks for your help!
EDIT: "Does not work" means the "shiftOutOwn" function does not shift out any data (measured with oscilloscope). With the print(), it does.
EDIT2: Solution found: Making the variables volatile
Sure, sorry for that!
This code controlls a shift-register as well as two mosfets (C1&C2) which are attached to a 7-segment display.
Without the print() statements, nothing lights up, with print(), the 7 segment shows the animation.
The reason for that is, that the shift_out function does not shift out any data without the print()
You are using Serial-print without Serial.begin(baudrate);
not sure if this makes a difference.
executing the line Serial.print()
needs some additional time
So have you tested what your code does if you increase the other delays() that you are using?
I have tested multiple delays, for example 10ms, 100ms, 1000ms
There is no change, as long as the "Serial.print(".");" is not present in the code, no data is shifted out
Instead of "Serial.print(".");" I can also use "interrupts();", then it works
But it really needs to be after every time I cange the value of "CHAR1", like this:
Yes, the interrupt is called for sure. Checked that with the oscilloscope as well. And no, delay() does not block the timer interrupt.
I have found a sloution, to make the CHAR1 and CHAR2 variables " volatile"
Not sure why it only works then, but this solves the case for me
Not sure why it only works then, but this solves the case for me
The compiler always tries to optimize code so as to make it run faster. While it will assign a space in memory to hold a variable, it's entirely possible that it will be able to make the code run faster by putting the variable into a CPU register, and never actually updating the memory copy. In this case, since the setup() and loop() functions change the value but never use it, the compiler might even optimize the variable away entirely.
Meanwhile, your interrupt code uses those variables. That code probably ends up grabbing the copy from memory that may, or may not have been updated by the main program.
The volatile keyword is there to solve this problem. It warns the compiler that the contents of this variable are subject to change without warning, so do not do any optimization involving this variable. The general rule is that any variable that appears in interrupt, AND non interrupt code, MUST be declared volatile. The same volatile keyword must also be used for any 'variable' that may be changed by external hardware. If you dig way down into the header files, you'll find that the hardware registers like TCCR2A and TCNT2 are declared as volatile.