My PID returns values from -2100 up to 1300 or so. This is sent to analogWrite(outputPin, outPut) and seems to work (moderately) well. The only way I could view these numbers is with a serial-link to Monitor.
Since I understood that PWM should only take 0 to 255, I thought to investigate this a bit:-
// just what the hell gives which outputs in PWM
// Analog output
int outPutPin = 10; // select the pin for output to the motor
int x;
void setup()
{
Serial.begin(9600);
pinMode(outPutPin, OUTPUT);
}
void loop()
{
for(int i =0; i<=255; i+=15)
{
x = -2100 +i;
analogWrite(outPutPin, x);
Serial.println(x);
delay(5000);
}
}
And my motor quite happily spins at speeds from zero to some maximum.
Why? Perhaps the analogWrite() does a Mod (%) so I tried:-
Cutting to the nitty gritty,
// just what the hell gives which outputs in PWM
......
void loop()
{
for(int i =0; i<=255; i+=15)
{
// mod with 255
x = (-2100 +i)%255;
analogWrite(outPutPin, x);
Serial.println(x);
delay(5000);
}
}
This works just like the previous code. The numbers show as being Negative.
Can anyone please explain how the analogWrite() gets its working range - so I can correct my PID if necessary?
Thanks,
Geoff
The gory details are in the file named wiring_analog.c in the arduino core. I think it just takes the least significant lower 8 bits of the int value and uses that as the duty cycle value for the PWM signal. I think you really need to scale that PID output range into a 0-255 value if your going to use analogWrite, perhaps using the map function.
int pwmoutputValue = map(PIDoutputValue, -2100, 1300, 0, 255);
analogWrite(pin#,pwnoutputValue);
Thanks Lefty,
Originally I had my outPut defined as
byte myOutPut = 0;
which (seems to) strips the number down to byte (2^8) size - what it does with the rest of the number is beyond my ken!
The output falls-over at some overload conditions, so I thought I'd try to analyse what's happening. I looked at the output from the PID and that's when I found the crazy numbers.
I freely admit I didn't think about what my "byte myOutPut" might be doing.
Geoff
So much to learn and only 25 hours in each day.
The PWM output is a byte, essentially.
If you tell it analogWrite(1,255) it writes solid on, analogWrite(1,256) is solid off (just like analogWrite(1,0)), analogWrite(1,257) and analogWrite(1,1) are identical in function, and so on.
Just like if you were using a byte to store >0-255.
You can play with it a bit, feed the PID into a byte, then Serial.print it. You'll need to convert it to an int when you print it (Serial.println((int)myByte) or you'll get ascii characters. That'll show you exactly what the PWM is doing.