8 Servos one UNO Robot Arm

Ive mixed up some code from example sketches

to control serveral RC servos for a robot arm project for my daughter
we have an i2c 16 channel board on the way but i figured id test a bit and got whats posted below.
there are section // out because i didnt have enough wire to get my flight sim Joystick controller wired to the board
but i found an old printer cable to scavenge later

the last delay controls the loop and therefore the servo speeds.
Im still trying to figure out millis
a push in the right direction to monitor the code and smooth the operations of the servos at higher rates to allow for better control of the servos would be appreciated

/*

*/
// This is my one uno robot arm control scetch
// pieces grabbed from several sources
//This sketch can control up to 8 servos on one "arduion uno" as setup. my uno is old!!
// this works with buttons and pots or joystick control and 5 way momentary buttons
//buttons can be 5 way momentary from fleabay to set servos to a position and hold.
//pots will hold position as well but joy stick will recenter
//angle1, angle2, angle3 can be set to a start position at (int angle1 = 90;) from 0 to 180/270 deg for a start position on robot arms when arduino starts,
//reset and powerup will bring servos to this position.
//Buttonservo3 and joyservo4 are setup for 270 deg servos.
//To reverse servo direction on pots swap 0, 180/270 value in "val? = map(val?, 0, 1023, 180, 0)"
// Last delay at bottom ( delay(10);) will control speed of servos. by slowing loop


#include <Servo.h>


const int  posSwitch1 = 4;            
const int  negSwitch1 = 3;           
const int  servoPin1 = 2;           
Servo buttonservo1;                  

//  const int  posSwitch2 = 7;         
//  const int  negSwitch2 = 6;            
//  const int  servoPin2 = 5;          
//  Servo buttonservo2;                   

//  const int  posSwitch3 = 10;          
//  const int  negSwitch3 = 9;         
//  const int  servoPin3 = 8;            
//  Servo buttonservo3;                  

const int potpin1 = A0;              
const int servoPin4 = 13;          
Servo joyservo1;                     

const int potpin2 = A1;               
const int servoPin5 = 1;             
Servo joyservo2;                    

//  const int potpin3 = A2;              
//  const int servoPin6 = 11;            
//  Servo joyservo3;                      

//  const int potpin4 = A3;             
//  const int servoPin7 = 12;            
//  Servo joyservo4;                      

int angle1 = 90;                      //sets start/boot servo angle to middle position for buttonservo1 change to set start position of arm joint
//  int angle2 = 90;                      //sets start/boot servo angle to middle position for buttonservo2 change to set start position of arm joint
//  int angle3 = 135;                     //sets start/boot servo angle to middle position for buttonservo3 270deg servo change to set start position of arm joint

int change = 2;              //Servo Adjust movement value in deg        

int val1;                         
int val2;                             
//  int val3;                          
//  int val4;                        

void setup() {


  pinMode(posSwitch1, INPUT_PULLUP);       
  pinMode(negSwitch1, INPUT_PULLUP);          
  buttonservo1.attach(servoPin1);             

  //   pinMode(posSwitch2, INPUT_PULLUP);       
  //   pinMode(negSwitch2, INPUT_PULLUP);      
  //   buttonservo2.attach(servoPin2);          

  //   pinMode(posSwitch3, INPUT_PULLUP);         
  //   pinMode(negSwitch3, INPUT_PULLUP);         
  //   buttonservo3.attach(servoPin3);            

  joyservo1.attach(servoPin4);        
  joyservo2.attach(servoPin5);        
  //   joyservo3.attach(servoPin6);         
  //   joyservo4.attach(servoPin7);         
}

void loop() {


  if ( digitalRead(posSwitch1) == LOW) {  
    angle1 = angle1 + change;               
  }

  if ( digitalRead(negSwitch1) == LOW) { 
    angle1 = angle1 - change;              
  }

  //   if( digitalRead(posSwitch2) == LOW) {  
  //   angle2 = angle2 + change;              
  //  }

  //   if( digitalRead(negSwitch2) == LOW) {  
  //   angle2 = angle2 - change;              
  //   }

  //   if( digitalRead(posSwitch3) == LOW) {  
  //   angle3 = angle3 + change;              
  //   }

  //   if( digitalRead(negSwitch3) == LOW) {  
  //   angle3 = angle3 - change;              
  //   }


  angle1 = constrain(angle1, 0, 180);    
  buttonservo1.write(angle1);            

  //   angle2 = constrain(angle2, 0, 180); 
  //   buttonservo2.write(angle2);            

  //   angle3 = constrain(angle3, 0, 270);    
  //   buttonservo3.write(angle3);         

  val1 = analogRead(potpin1);         
  val1 = map(val1, 0, 1023, 180, 0);     
  joyservo1.write(val1);                 

  val2 = analogRead(potpin2);           
  val2 = map(val2, 0, 1023, 0, 180);     
  joyservo2.write(val2);                 

  //   val3 = analogRead(potpin3);            
  //   val3 = map(val3, 0, 1023, 0, 180);     
  //   joyservo3.write(val3);                 

  //   val4 = analogRead(potpin4);            
  //   val4 = map(val4, 0, 1023, 0, 270);    
  //   joyservo4.write(val4);                 



  delay(10);                             
}

You could switch from servo.write(0-180) to servo.writeMicroseconds(1000-2000).
Just adjust your map function for the new range.

The delay(10) isn’t really going to do anything for your servos being set by analog reads as they will take 20milliseconds to complete a comparison.

But your digital reads will increment faster than the servo could so the servo will become a step behind.

Maybe Increase that delay to 20, or start using millis timing and do not “read” the digital port unless 20millis have past since the last read.

Slumpert:
Maybe Increase that delay to 20, or start using millis timing and do not “read” the digital port unless 20millis have past since the last read.

its the millis i was interested in,
how would you modify the working code above to incorporate millis instead of the one single delay that controls the loop

OGP:
its the millis i was interested in,
how would you modify the working code above to incorporate millis instead of the one single delay that controls the loop

Go look at the "Blink Without Delay" example that comes with the IDE. Look at the if statement that checks millis to see if it is time to toggle the light. Take out the code that toggles the light and put the code you want run at some regular interval in there. Change the interval value to however often you want your code to run.

If you want to understand more, there are a great many tutorials and explanations all over the web about how to use the Blink Without Delay idea for timing. It would be a total waste to expect someone to recreate all of that here.

Look at the top of the programming questions forum. There's a sticky thread for millis and then in the useful links section there are a number of others. Read some of that and then ask questions if you don't understand. But please try to make use of some of what we've already done instead of asking that we recreate the entire lesson on each thread for each individual poster.

Not responding as expected with millis

here is the code i put together
the joystic servo works great.
the button though just goes from 90 at start to full left then full right with a single button push.
its not incrementing one step at a time while the button is pushed and stopping when released.

#include <Servo.h>


const int  posSwitch1 = 4;            // Create Switch and assign to pin
const int  negSwitch1 = 3;            // Create Switch and assign to pin
const int  servoPin1 = 6;             // Create Servo digital output pin and assign
int angle1 = 90;
unsigned long previousposSwitch1Millis = 0;
unsigned long previousnegSwitch1Millis = 0;
int posSwitch1interval = 10;
int negSwitch1interval = 10;
Servo buttonservo1;

const int potpin1 = A0;               // analog pin used to connect the potentiometer
const int servoPin2 = 8;             // Create Servo digital output pin and assign
int val1;
unsigned long previouspotpin1Millis = 0;
int joypot11interval = 10;
Servo joyservo1;

int change =+ 1;

unsigned long currentMillis = 0;

void setup() {             ///////////////////

  pinMode(posSwitch1, INPUT_PULLUP);          // initialize the pins
  pinMode(negSwitch1, INPUT_PULLUP);          // initialize the pins
  buttonservo1.attach(servoPin1);             // attaches the servo on pin to the servo object

  joyservo1.attach(servoPin2);

}// end setup

void loop() {              /////////////////////

  currentMillis = millis();

  ReadposSwitch1();
  ReadnegSwitch1();
  Readpotpin1();

}

void ReadposSwitch1()
{
  if (millis() - previousposSwitch1Millis >= posSwitch1interval) {
    if ( digitalRead(posSwitch1) == LOW) {  //reads pin contact to ground. button push plus+ increment
      angle1 = constrain(angle1, 0, 180);
      angle1 = angle1 + change;               //changes servo angle by increment until button released.
      buttonservo1.write(angle1);
      previousposSwitch1Millis += posSwitch1interval;
    }
  }
} //end read


void ReadnegSwitch1()
{
  if (millis() - previousnegSwitch1Millis >= negSwitch1interval) {
    if ( digitalRead(negSwitch1) == LOW) { //reads pin contact to ground. button push Negetive- increment
      angle1 = constrain(angle1, 0, 180);
      angle1 = angle1 - change;              //changes servo angle by increment until button released.
      buttonservo1.write(angle1);
      previousnegSwitch1Millis += negSwitch1interval;
    }
  }
} //end read

void Readpotpin1()
{
  if (millis() - previouspotpin1Millis >= joypot11interval) {
    val1 = analogRead(potpin1);            // reads the value of the potentiometer (value between 0 and 1023)
    val1 = map(val1, 5, 1023, 200, 5);     // scale it to use it with the servo (value between 0 and 180) or whatever
    joyservo1.write(val1);                 // sets the servo position according to the scaled value
    previousnegSwitch1Millis += joypot11interval;
  }
} //end read

Fixed it

void ReadSwitch1()
{
 if (millis() - previousSwitch1Millis >= Switch1interval) {
      if ( digitalRead(posSwitch1) == LOW) {  //reads pin contact to ground. button push plus+ increment
      angle1 = angle1 + change;               //changes servo angle by increment until button released.
    }
    if ( digitalRead(negSwitch1) == LOW) { //reads pin contact to ground. button push Negetive- increment
      angle1 = angle1 - change;              //changes servo angle by increment until button released.
    } 
      angle1 = constrain(angle1, 0, 180);
      buttonservo1.write(angle1);
      previousSwitch1Millis += Switch1interval;
    }
  }
 //end read

Here is the Base code for a 2-button control and a pot controlled servo without delays.

Just copy what you need into your robot for physical control of a servo.

#include <Servo.h>


const int  buttonServoInput1 = 4;            // Create Switch and assign to pin
const int  buttonServoInput2 = 3;            // Create Switch and assign to pin
const int  buttonServoOutput = 6;             // Create Servo digital output pin and assign
unsigned long previousbuttonServoMillis = 0;
int buttonServoInterval = 5;
int angle = 90;
int moveDeg = 1;
Servo buttonServo;

const int joyServoIn = A0;               // analog pin used to connect the potentiometer
const int joyServoOut = 8;             // Create Servo digital output pin and assign
unsigned long previousJoyServoMillis = 0;
int joyServoInterval = 5;
int val;
Servo joyServo;



unsigned long currentMillis;

void setup() {             ///////////////////

  pinMode(buttonServoInput1, INPUT_PULLUP);          // initialize the pins
  pinMode(buttonServoInput2, INPUT_PULLUP);          // initialize the pins


  buttonServo.attach(buttonServoOutput);             // attaches the servo on pin to the servo object
  
  joyServo.attach(joyServoOut);

}// end setup

void loop() {

  currentMillis = millis();
  controlbuttonServo();
  controljoyServo();
}

void controlbuttonServo()
{
  if (currentMillis - previousbuttonServoMillis >= buttonServoInterval) {
    if ( digitalRead(buttonServoInput1) == LOW) {  //reads pin contact to ground. button push plus+ increment
      angle = angle + moveDeg;               //changes servo angle by increment until button released.
    }
    if ( digitalRead(buttonServoInput2) == LOW) { //reads pin contact to ground. button push Negetive- increment
      angle = angle - moveDeg;              //changes servo angle by increment until button released.
    }
    angle = constrain(angle, 0, 180);
    buttonServo.write(angle);
    previousbuttonServoMillis = currentMillis;
  }
} //end read

void controljoyServo()
{
  if (currentMillis - previousJoyServoMillis >= joyServoInterval) {
    val = analogRead(joyServoIn);            // reads the value of the potentiometer (value between 0 and 1023)
    val = map(val, 5, 1023, 200, 5);     // scale it to use it with the servo centered and full swing wit joystick, normal(val, 0, 1023, 0, 180)(value between 0 and 180 for 180 servo) or whatever
    joyServo.write(val);                 // sets the servo position according to the scaled value
    previousJoyServoMillis = currentMillis;
  }
} //end read