Millis and potentiometer

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 
  }
}

Why do people give human qualities to motors ?

Place some Serial prints in the code to see if things are advancing as you think they are.

Why are some people bothered by other people using the evolution of language in personalized and fluid ways?

Thanks for the suggestion I will give it a try.

1 Like

Nice!

1 Like

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.

1 Like

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.

I hope you have a current limiting resistor in series with the LED.

1 Like

Sure do. Haha. 330 ohms. I am not having another one go rogue and try to take my eye out. :joy:

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
  }
}
1 Like

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.

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.