analogWrite() Max Value in Question

JeffByrd

Member
From Teensyduino 1.19, file: pins_teensy.c

Code:
void analogWrite(uint8_t pin, int val) {
	uint32_t cval, max;

#if defined(__MK20DX256__)
	if (pin == A14) {
		uint8_t res = analog_write_res;
		if (res < 12) {
			val <<= 12 - res;
		} else if (res > 12) {
			val >>= res - 12;
		}
		analogWriteDAC0(val);
		return;
	}
#endif

	max = 1 << analog_write_res;
	if (val <= 0) {
		digitalWrite(pin, LOW);
		pinMode(pin, OUTPUT);	// TODO: implement OUTPUT_LOW
		return;
	} else if (val >= max) {
		digitalWrite(pin, HIGH);
		pinMode(pin, OUTPUT);	// TODO: implement OUTPUT_HIGH
		return;
	}

I believe the 'max' value for analogWrite is wrong. I believe it should be
Code:
max = (1 << analog_write_res)-1;
At least this works better for me.

Jeff
 
wow.
pwm takes one of 257 values :eek:

Yes. But if you prefer 256, you can just not use the last one.

A couple years ago, I put some substantial time into testing against Arduino's implementation, to make sure the results are the same for 0 to 255.
 
ah, some of my led cicuits have their range inverted (0 is full on and 256 is off)
I never understood when using a byte (rather than an int) my leds would'nt turn off completely at 255... Guess I have my answer now !
 
ah, some of my led cicuits have their range inverted (0 is full on and 256 is off)
I never understood when using a byte (rather than an int) my leds would'nt turn off completely at 255... Guess I have my answer now !

This is exactly what happened to me!
It's works great now that I understand the logic.

Jeff
 
Well, I need to go edit some code now!
Code:
int analogWriteMaxValue = ( pow( 2, analogWriteResValue) -1 )  //wrong
int analogWriteMaxValue = pow( 2, analogWriteResValue)    //right!
 
Well, I need to go edit some code now!
Code:
int analogWriteMaxValue = ( pow( 2, analogWriteResValue) -1 )  //wrong
int analogWriteMaxValue = pow( 2, analogWriteResValue)    //right!

You really do not want to use pow to calculate 2**analogWriteResValue, because that converts everything to double precision floating point, which it then has to emulate in integer arithmetic. At the end, you would need to convert it back to integer. I'm guessing, but I would suspect that pow takes thousands if not tens of thousands of instructions to implement. Fortunately the chips are fast, but even so, you probably want to use the cpu for other things and/or read more analog values.

What you want is to use is bit shifting. If you shift the value left n bits, it is the same as multiplying it by the appropriate power of 2. So you want to do:
Code:
int analogWriteMaxValue = 1 << analogWriteResValue;
 
Back
Top