What would happen if my code were to produce an argument for analogWrite() with a negative integer for the duty cycle? Suppose the duty cycle started off as 255 and then decreased rapidly but smoothly down to 0 and then went negative? What would happen?
What happened when you tried?
You can always check the value prior to using it, then limit it to 0 or 255.
Also use type 'byte' 0-255
.
Well if you look at the source files, you get:
void analogWrite(uint8_t pin, int val)
So 'val' can be -32768 to 32767
It also does not check to see if 'val' is between 0 and 255
However, it sets OCR_ _ registers to 'val' and the OCR_ _ registers are only 8 bits. So my bet is that setting them to any number out of range of 0-255 will result in truncation. For example, if you entered 256 as val, then that is
0000 0001 0000 0000
XXXX XXXX 0000 0000 = 0
and it would truncate the rightmost 8 bits off and the OCR_ _ register would get 0. Same thing with negative numbers.
analogWrite(value) takes 0 to 255, 8 bits. 0x00 to 0xff.
How would you send it a negative #?
I think if you used a signed int, the upper 8 bits get tossed, and what you think of -1, 0xffff, would instead be treated as 255, 0xff.
so my bet is that setting them to any number out of range of 0-255 will result in truncation
No, they wrap.
void setup() {
Serial.begin(115200);
analogWrite(9,-10);
Serial.println(OCR1A);
analogWrite(9,260);
Serial.println(OCR1A);
}
void loop() {}
But...thats exactly what truncation is...
-10 is 11110110 in binary 2s complement, if you treat it as unsigned, you get 246
260 is 1 00000100 in binary, if you truncate the higher bits, you get get 4
Wrapping / Truncation are the same
cattledog:
No, they wrap.
Thanks to the magic of twos-complement artithmetic.
I was hoping that wouldn't be the case. I cannot afford a valid entry being registered by the analogWrite command when the entry is not the intended one.
Is there perhaps a recommended strategy for keeping all values greater than 255 stuck to 255 and values less than 0 stuck to 0?
Just test the value before you stick it in analogWrite() Answer given in reply #1 by Larry D
if(value >255)
value = 255;
if (value<0)
value = 0;
Sure I can do that. I figured there might be a more elegant way of it but if not, this is short and simple enough I guess.
You can use constrain() but there's no magic there. It basically does the same thing as cattledog's code.
From Arduino/Arduino.h at 5102ed46ee75be65c4fc9fc676a51d4f4c9ada2f · arduino/Arduino · GitHub
#define constrain(amt,low,high) ((amt)<(low)?(low):((amt)>(high)?(high):(amt)))
Brilliant. That's the rabbit I was hoping someone would pull from their hat.