I am very new to programming and I am having a hard time understanding how to replace delay with millis in the Arduino software. I am trying to control the speed of my DC motor in my Sparkfun Redboard kit with a potentiometer while running my servo in the background constantly sweeping back and forth. I have figured out that it is the delay in my code that is messing with how the motor and servo are acting and have researched and tried to figure out how to convert the delay over to millis with no success. If anyone can please help me with my code that would be awesome and to totally understand the proccess of converting delay over to millis that would be even better. Thank you very much.
#include <Servo.h>
const int SERVO = 3;
const int FAN = 5;
const int POT1 = A1;
Servo servo;
int pos = 0;
int increment;
int updateInterval;
unsigned long lastUpdate;
void setup(){
pinMode(FAN, OUTPUT);
servo.attach(SERVO);
}
void loop(){
{
for(pos = 0; pos <= 180; pos += 1)
{
servo.write(pos);
delay(20);
}
for(pos = 180; pos>=0; pos-=1)
{
servo.write(pos);
delay(20);
}
int fanSpeed = map(analogRead(POT1), 0, 1023, 0, 255);
analogWrite(FAN, fanSpeed);
}
}
Yeah I have. It uses code for LEDs and for some reason I cant seem to figure out how to make it work for the servo while incorporating the DC motor being controlled by the potentiometer.
See my edit. Changed more then that as a tip. Please read all
#include <Servo.h>
// Byte is okay (and smaller ;) )
// User better names. For example, now you have SERVO and Servo. Bit confusing
// The confention MyConstVarName is more standard then the ALL_CAP. Latter is used for defines.
const byte ServoPin = 3;
const byte FanPin = 5;
const byte PotPin = A1;
Servo servo;
byte pos = 0; //Again, only goes to 180 so byte is okay
const byte ServoUpdateInterval = 20; //Change to unsigned it if you need a bigger interval then 255
unsigned long lastServoUpdate; //Clear variable names!
void setup(){
pinMode(FanPin, OUTPUT);
servo.attach(ServoPin);
}
void loop(){
// { <---- Is already above!
//alright, insert Blink Without Delay here
if(millis() - lastServoUpdate >= ServoUpdateInterval){
lastServoUpdate = millis(); //Save for the next time
//Now do the movement needed :D
//Don't keep it stuck here, let it run free in teh loop
//for(pos = 0; pos <= 180; pos += 1){
if(pos < 180){
servo.write(++pos);
}
//for(pos = 180; pos>=0; pos-=1)
else if(pos > 0){
servo.write(--pos);
}
}
//int fanSpeed = map(analogRead(PotPin), 0, 1023, 0, 255);
analogWrite(FanPin, map(analogRead(PotPin), 0, 1023, 0, 255)); //If you don't use it anywhere else.
// analogWrite(FanPin, (analogRead(PotPin) << 2); is the smae :D
// } <---- Is already below
}
septillion:
Don't let it get stuck in a long for loop
See my edit. Changed more then that as a tip. Please read all
So I tried this code and the servo doesn't sweep back and forth just moves 180 and then stops. What would i need to add in order for it to sweep from 0 to 180 then back to 0 continuously?
Here is the code I am using. I got it to work as I needed it. The servo sweeps continuously and i am able to adjust my motor speed with my potentiometer. I was trying to to add in a button that would act as an on/off switch for the whole program. So I would up load it to my arduino uno and it wouldn't start until i press the button then it would run continuously until I pushed the button again and it would turn off. How would I incorporate that into the code I already have?
#include <Servo.h>
const int ServoPin = 3;
const int FanPin = 5;
const int PotPin = A1;
Servo servo;
int servoPosition = 90;
int servoInterval = 40;
int servoDegrees = 2;
unsigned long currentMillis = 0;
unsigned long previousServoMillis = 0;
void setup(){
Serial.begin(9600);
pinMode(FanPin, OUTPUT);
servo.write(servoPosition);
servo.attach(ServoPin);
}
void loop(){
currentMillis = millis();
if (currentMillis - previousServoMillis >= servoInterval) {
previousServoMillis += servoInterval;
servoPosition = servoPosition + servoDegrees; // servoDegrees might be negative
if (servoPosition <= 0){
servoInterval;
}
}
if ((servoPosition >= 180) || (servoPosition <= 0)) {
servoDegrees = - servoDegrees;
servoPosition = servoPosition + servoDegrees;
}
servo.write(servoPosition);
analogWrite(FanPin, map(analogRead(PotPin), 0, 1023, 0, 255));
}
I don't know if this helps people, but my answer is this:
Your loop needs to ask and answer the question "what do I need to be doing right now". You loop reads the input pins, looks at the state that it has previously stored in the variables, looks at millis(), and and decides what to do.
"ok, pin 1 is down, and it's 500 ms since the last ping, but I have not returned ping on pin 2 yet, so I need to drive pin 2 high and make a note that the return ping is in progress." or whatever.
Some time later, it will go "pin 1 is down, and a return ping is in progress, but it's been 750ms since the last ping, so I need to drop pin 2 and note that the ping has been sent"
The code itself isn't written as a list of things-to-do, as it would be in a more usual programming environment. The list of things-to-do is kinda diced and scattered across "what should I do in these conditions?" blocks.
gundy89:
I was trying to to add in a button that would act as an on/off switch for the whole program.
Then you need a variable to record whether the servo should move (or not). When you press the button it should change that variable from true to false or false to true.
The code that moves your servo should only operate if that variable is true.