Howdy,
I got a ATTiny85 that I'm trying to program to send a pulse after a time period once a interrupter was triggered. The code works until I pass the time period longer than ~32s. I have the period declared as an unsigned long. Is there any reason for 32s to work but not 33s? Thanks in advance.
Post the code. Read the forum guidelines to see how to properly post code and some information on how to get the most from this forum.
Use the IDE autoformat tool (ctrl-t or Tools, Auto format) before posting code in code tags.
Which core are you using, also?
It sounds like somewhere the number of milliseconds is getting cast to a 16-bit signed integer.
Ok, so I figured it out but I'm not sure why it worked. It appears that the compiler is interpreting
unsigned long interval = (unsigned long)(1000*60*33);
as an int and
unsigned long interval = 1980000;
as an unsigned long. If anyone can explain why please let me know.
unsigned long interval = (unsigned long)(1000*60*33);
The compiler does the calculation using int, then casts the result to unsigned long.
Tell the compiler that at least one of the numbers in the calculation is an unsigned long:
unsigned long interval = 1000UL*60*33;
To make it a bit more explicit, the compiler will treat any integer literal that fits within an integer as an int and values that only fit within a long as a long. After that, normal type promotion rules apply.
Thus, (unsigned long) (32767*2)
will overflow, because both of those values fit in an int, but the result doesn;t.. But (unsigned long) (32768*100)
will not because one of the operands needs a larger datatype,
And of course, (unsigned long) 32767*2
without parens around second half won't, because typecasts come before arithmetic in order of operations.
And this is why the fact that the Arduino IDE turns off warnings by default is so bad:
With warnings on it will tell you when it does that:
C:\Users\Spence\Documents\Arduino\sketch_jan07a\sketch_jan07a.ino:3:47: warning: integer overflow in expression [-Woverflow]
unsigned long interval = (unsigned long)(32700*2);
~~~~~^~
I've actually made DxCore and megaTinyCore enable warnings regardless of that setting, because so many users are unaware that the IDE is hiding valuable debugging information by default. next ATTinyCore will too. I got fed up with fielding issues that would have been obvious had warnings been enabled.
Humans are imperfect creatures. It is hubris to think you do not need them, and folly to believe that warnings should be allowed to coexist with us (at least within embedded C - I can't speak to other development regimes. It is usually a serious enough bug that if that part of the code were exercised, it would not be possible to mistake it for correct behavior. Even cases like unused variables, which are sometimes okay during development (you just haven't written the code to use it yet) are often from less benign causes - variables declared in two different scopes but used in one, or the code that uses a variable being unreachable when you expect and intend for it to be reachable. Why the IDE doesn't enable them by default is mystifying. Their guiding philosophy seems to be that as much code as possible should compile with no red text.... even though a bug in behavior where there are no hints in the compiler output that something is amiss is orders of magnitude harder to debug and correct than when a warning points right to it.
This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.