I am new to Arduino and coding. Have a question as to why this sketch wont run. The wiring is all correct and each sketch will run independently. I have combined these three, and two work. The led will come on and the potentiometer will work to control the 360 servo. The my120Servo will not work. It is supposed to work as like the sweep function using millis instead of delay. It will work when alone as an independent sketch. When combined with the other two it just stubbornly sits there. Is this because the serial monitor is already being used by the potentiometer? I was under the impression a millis sketch would run regardless of what was going on in the serial monitor because it was programmed based off the running time of the Arduino. Is this an incorrect assumption?
Your time and contribution is greatly appreciated. Thank you.
#include <Servo.h>
Servo my360Servo; //360 modified servo
Servo my120Servo;
const int servoPin = 3; // the pin number for the servo signal
const int servoMinDegrees = 5; // the limits to servo movement
const int servoMaxDegrees = 120;
int servoPosition = 5; // the current angle of the servo - starting at 5.
int servoForwardInterval = 40; // millisecs between servo moves
int servoReturnInterval = 40;
int servoInterval = servoForwardInterval; // initial millisecs between servo moves
int servoDegrees = 1; // amount servo moves at each step
// will be changed to minus
unsigned long currentMillis = 0; // stores the value of millis()
unsigned long previousServoMillis = 0;
int readVal; //read the value from the analog pin 4
int readPent=A4;
int redLeds = 7;
void setup() {
Serial.begin(9600);
my360Servo.attach(9); // servo attached to pin 9
pinMode(redLeds, OUTPUT);
my120Servo.write(servoPosition); // sets the initial position
my120Servo.attach(3);
}
void loop() {
digitalWrite(redLeds, HIGH);
currentMillis = millis(); // capture the latest value of millis()
if (currentMillis - previousServoMillis >= servoInterval) {
previousServoMillis += servoInterval;
servoPosition = servoPosition + servoDegrees;
if (servoPosition <= servoMinDegrees) {
// servo reset speed change
if (servoInterval == servoForwardInterval) {
servoInterval = servoReturnInterval;
}
if ((servoPosition >= servoMaxDegrees) || (servoPosition <= servoMinDegrees)) {
servoDegrees = - servoDegrees; // reverse direction
// and update the position to ensure it is within range
servoPosition = servoPosition + servoDegrees;
}
my120Servo.write(servoPosition);
}
readVal=analogRead(readPent); // reads potentiometer value which is 0 and 1023)
Serial.println(readVal); // value viewed in serial monitor after printed message (292 is stop, Clockwise at 297, Counter clockwise at 288.
readVal= map(readVal, 0, 1023, 0, 180); // scaling potentiomter to use with servo 0 and 180, but 180 does not matter since with 360 it will continue to spin.
my360Servo.write(readVal); // writes value to servo
}
}
In the IDE, try Tools > Auto Format or < CTRL >T to format the code.
Also, I would make servoInterval an unsigned int to be consistent with currentMillis and previousServoMillis, although I do not think that is causing any problems.
Thank you I will do that with the servoInterval. I just got the sketch working. Wound up starting over and just copying and pasting my two old sketches into a new sketch, and ditching the LED. Instead I just plugged the LED into the ground and the power rail on the breadboard, since all I want is the LED to turn on when the power boots up. Weirdly enough this fixed all the problems. No idea why. Thank you for you input.
Thank you, but I can't really take credit for that one. There is a tutorial on here that teaches you how to use the millis function and it's taken from there.
As for the original problem you were having, after auto-formatting the code it is easier to see that you have the my120Servo.write inside of an if statement, so it only gets executed when servoPosition <= servoMinDegrees
void loop() {
digitalWrite(redLeds, HIGH);
currentMillis = millis(); // capture the latest value of millis()
if (currentMillis - previousServoMillis >= servoInterval) {
previousServoMillis += servoInterval;
servoPosition = servoPosition + servoDegrees;
if (servoPosition <= servoMinDegrees) {
// servo reset speed change
if (servoInterval == servoForwardInterval) {
servoInterval = servoReturnInterval;
}
if ((servoPosition >= servoMaxDegrees) || (servoPosition <= servoMinDegrees)) {
servoDegrees = - servoDegrees; // reverse direction
// and update the position to ensure it is within range
servoPosition = servoPosition + servoDegrees;
}
my120Servo.write(servoPosition);
}
readVal = analogRead(readPent); // reads potentiometer value which is 0 and 1023)
Serial.println(readVal); // value viewed in serial monitor after printed message (292 is stop, Clockwise at 297, Counter clockwise at 288.
readVal = map(readVal, 0, 1023, 0, 180); // scaling potentiomter to use with servo 0 and 180, but 180 does not matter since with 360 it will continue to spin.
my360Servo.write(readVal); // writes value to servo
}
}
Ahhhhhhhh. Okay but why is it not executing the entire condition including the or.
if ((servoPosition >= servoMaxDegrees) || (servoPosition <= servoMinDegrees)) {
do this stuff }
update and move
}
Why would it get tripped up and only execute the second half of the condition? Or do I understand it wrong.
Well, you start with servoPosition of 5. You keep incrementing it by servoDegrees, which is initially 1, until it is below servoMinDegrees of 5. That will occur when servoPosition overflows the maximum value for an int and becomes negative. At that point, servoDegrees is set to -1, then added to servoPosition, causing servoPosition to underflow the maximum negative int and become positive. Now you write servoPosition to the servo, but that is a value of 32767, which is well out of range for any sensible servo positon (I have not looked too deeply into the servo library, but that is likely going to be taken as an attempt to output a 32767 microsecond pulse to the servo, which will not work).
From this point, with servoDegrees set to -1, the value of servoPosition will decrease until it is below servoMinDegrees, at which point servoDegrees is set to +1, and a value of 5 is written to the servo.
The result will be that the servo is getting positioned alternately to 32767 and 5, with the servo probably only responding to the 5 and ignoring the other, so it does not move.