I've got three small 5-7volt motors and I'm controlling the RPM of each motor with three 10k pots which modulate the analogWrite commands on three channels of an UNO. Essentially, everything works fairly well, except the system is not reading the pots right. In my code, I'm specifying mapping my analog values from my pots (0-1023) to the 8-bit range apparently required by the analogWrite command (0-255). Very simple. But I'm not able to utilize the full travel of the pot. 1023/255 occurs at about 1/3 of the total travel
In other words, when I look at the PWM with a scope, the PWM flatlines at 255, but that's occurring before the halfway mark in the pot's total travel. What I want is a smooth gradient from pot at zero, all the way through the ~300 degrees of it's travel. I assumed that the analogRead command would divide 0 volts to VCC (which is about 5 volts in this case) by 1024, thereby digitizing the entire sweep of the pot from min to max. But what's happening isn't even close. I'm sure I'm missing something here, I'm a rank amateur at all of this.
Can someone offer a few suggestions and/or corrections to this problem? Here is my code:
int speedSet1 = A0;
int speedSet2 = A1;
int speedSet3 = A2;
int motor1 = 9;
int motor2 = 10;
int motor3 = 11;
int speedVal1 = 0;
int speedVal2 = 0;
int speedVal3 = 0;
int motor1Speed = 0;
int motor2Speed = 0;
int motor3Speed = 0;
//int motor1Limit = 33;
//int motor2Limit = 33;
//int motor3Limit = 33;
int LED1 = 5;
int LED2 = 6;
int LED3 = 7;
void setup() {
pinMode(LED1, OUTPUT);
pinMode(LED2, OUTPUT);
pinMode(LED3, OUTPUT);
Serial.begin(9600);
}
void loop() {
//Motor 1
speedVal1 = analogRead(speedSet1);
motor1Speed = map(speedVal1, 0, 1023, 0, 255);
if (motor1Speed <= motor1Limit) //If at or below lower speed limit..
{
digitalWrite(motor1, LOW); //Turn off LED and send 0 to motor (Stop)
digitalWrite(LED1, HIGH);
}
else //Otherwise...
{
digitalWrite(LED1, LOW); //Turn on LED and send PWM to motor
analogWrite(motor1, motor1Speed); //according to value from pot
}
//Motor 2
speedVal2 = analogRead(speedSet2);
motor2Speed = map(speedVal2, 0, 1023, 0, 255);
if (motor2Speed <= motor2Limit)
{
digitalWrite(motor2, LOW);
digitalWrite(LED2, HIGH);
}
else
{
digitalWrite(LED2, LOW);
analogWrite(motor2, motor2Speed);
}
//Motor 3
speedVal3 = analogRead(speedSet3);
motor3Speed = map(speedVal3, 0, 1023, 0, 255);
if (motor3Speed <= motor3Limit)
{
digitalWrite(motor3, LOW);
digitalWrite(LED3, HIGH);
}
else
{
digitalWrite(LED3, LOW);
analogWrite(motor3, motor3Speed);
}
// Let's monitor what's going on with motor 1
Serial.print("motor1Speed = " );
Serial.print(motor1Speed);
Serial.print(" speedVal1 = ");
Serial.println(speedVal1);
delay(5);
}
Can you please post a copy of your circuit, a picture of a hand drawn circuit in jpg, png?
Hand drawn and photographed is perfectly acceptable.
Please include ALL hardware, power supplies, component names and pin labels.
Doh! I get that high side/low side thing backwards sometimes... The base resistors are 1K, and although the schematic says TIP122, I'm actually using TIP120's. I don't think that matters too much though. I'll try relocating the motor feeds as suggested and retry. Oh- and the 9v supply is just a ordinary wall wart 1000mA.
Ok. I relocated motor power feeds as suggested. Big improvement. Still not getting anywhere near a full spread of speed throughout the pot travel. Everything maxes out shortly before I've turned the control halfway up. Plus, there's a lot of crosstalk now. As I modulate the speed of one motor, the other two are somewhat affected. I need for there to be more isolation between the three channels. Is it even possible? I think there's sufficient current in the system, but it seems that these motors really suck it up and bring about fairly large voltage fluctuations, from about 6 volts with all motors on full blast to about 13 volts with no load. But the biggest problem is with the PWM not covering the full travel of the speed controls. Any ideas?
I've never understood why, or at least I fail to remember, but ppl recommend that when switching between analog readings it is advised to read once, throw it away and read again for reals.
The numbers I'm getting are what you would expect; The mapping command doing a perfect job. However, I'm still arriving at 255/1023 at about the halfway point of the pot's travel. I tried a 5k linear pot and the behavior was virtually the same. I tried it with motors and without and saw no significant difference. Is it just a coincedence that everything maxes out at the halfway point, or is there something to that? Very frustrating. The analogRead command is simply not using the entire range of voltage it sees.
Problem solved. I had the pots across my A voltage (unregulated). I put them across the GND - 5V on the arduino and, well I sure felt stupid after I pondered the wheres and whys...