Arrays and Servos

Hi @Robin2,

Thank you for putting together this sketch. It worked perfectly on the robotic arm I am building. I just had a question regarding the code, I noticed that a lot of the variables are clustered (not sure what the right term for it is, i.e. byte servoPin[4] = {7,6,10,9}; // you have it all written in one line) and I was looking into adjusting the code so that I am able to set min and max angle values for each servo motor. How would you go about writing that? Once I have this figured out I plan to modify the code to work with the VarSpeedServo library.

My skills are still pretty novice at this point so not sure how to begin.

I'm using the code that you prepared for this post, which I believe is a predecessor of what you've share on this forum.

Code:

#include <Servo.h>

#define mainArm 0
#define jib 1
#define bucket 2
#define slew 3

Servo servo[4];      //code used for attaching upto 4 servos

byte angle[4] = {90, 90, 90, 90};       // middle point for servo angle

byte potPin[4] = {A0, A1, A2, A3};  // input pins to attach your potentiometers
byte servoPin[4] = {7, 6, 10, 9};    // input pins to attach servos

void setup() {

  Serial.begin(9600);
  Serial.println("Starting DiggerCode.ino");


  for (byte n = 0; n < 4; n++) {
    servo[n].attach(servoPin[n]);
  }
}

void loop() {
  readPotentiometers();
  moveServos();
  delay(10);
}

void readPotentiometers() {
  int potVal;
  for (byte n = 0; n < 4; n++) {
    potVal = analogRead(potPin[n]);
   
    if (potVal < 200) {         // dead zone for the joystick I used is 200 to 550.
      angle[n] += 1;
      if (angle[n] > 170) {
        angle[n] = 170;
      }
    }
   
    if (potVal > 550) {         // deadzone upper value
      angle[n] -= 1;
      if (angle[n] < 10) {
        angle[n] = 10;
      }
    }

  }
}

void moveServos() {
  for (byte n = 0; n < 4; n++) {
    servo[n].write(angle[n]);
  }
}

Thanks in advance, greatly appreciate the work you've shared with us so far.

Best,
E

@pinto_e I can inderstand why you posted your question in my old Thread but your problem is different so I have suggested to the Moderator to move you to your own Thread.

This line of code

byte servoPin[4] = {7,6,10,9};

creates an array with 4 elements and 4 numbers in it, for the pins. Using arrays is a great way to make code tidier.

You could create two new arrays - for example

byte minAngle[4] = {20,20,20,20}; // put in your own values
byte maxAngle[4] = {150,150,150,150};

If you are prepared to extend your learning a bit further you should learn about structs. This a case where it would be convenient to create a struct to hold all the data for a single servo and have an array of the structs for all 4 servos.

...R

1 Like

Thread split form here as requested.

@Robin2, thanks for the prompt response! Much appreciated.

The arrays definitely make sense, I can see how they help keep things more organize and less cluttered. I will do some research on the data structures.

Forgive my lack of knowledge, is there a reason why you're declaring using "byte"

byte angle[4] = {90, 90, 90, 90};

instead of "int"?, i.e.:

int angle[4] = {90, 90, 90, 90};

Thank you,

E

If the value of a variable will always be in the range 0 to 255, declaring the variable as byte data type uses 1 byte of SRAM for each array element, int data type uses 2 bytes. Byte saves 1 byte of SRAM per array element.

Arduino data types.

@Robin2, for some context this is the code I had been working on prior to finding your post:

#include <VarSpeedServo.h> 
 
VarSpeedServo servo;        // create servo object to control a servo 
VarSpeedServo servo1;    
VarSpeedServo servo2;    
VarSpeedServo servo3;

int pos = 0;                // related to position?
 
const int potPin = 0;       // analog pin used to connect the potentiometer
const int potPin2 = 1;    
const int potPin3 = 2;   
 
const int servoPin = 9;     // the digital pin used for the servo
const int servoPin2 = 10;  
const int servoPin3 = 11;  

int val;                    // variable to read the value from the analog pin
int val2;                
int val3;                 
 
void setup() {
  pinMode(2, INPUT);        // push button for 'servo' rotation
  pinMode(3, INPUT);        // push button for 'servo' counter rotation
  
  servo.attach(6);                     // attaches the servo to pin
  servo1.attach(servoPin, 1, 127);     // attaches servo to pin and sets range for speed (mainPin, ServoMin, ServoMax)
  servo2.attach(servoPin2, 1, 127);
  servo3.attach(servoPin3, 1, 127); 
} 
 
void loop() {
 while (digitalRead(2) == HIGH && pos < 180) {
    pos++;
    servo.write(pos);
    delay(10);
  }
  while (digitalRead(3) == HIGH && pos > 0) {
    pos--;
    servo.write(pos);
    delay(10);
  }
  
val = analogRead(potPin);            // reads the value of the potentiometer (value between 0 and 1023) 
val = map(val, 0, 1023, 0, 179);     // scale it to use it with the servo (value from 0 and 180) 
servo1.slowmove(val,80);             // sets the servo position according to the scaled value, sets speed) 
delay(20);                           // waits a bit before the next value is read and written
// Base Z rotation

val = analogRead(potPin2);             
val = map(val, 0, 1023, 60, 160);     
servo2.slowmove(val,50);             
delay(20);                            
// Front to back movement

val = analogRead(potPin3);             
val = map(val, 0, 1023, 100, 165);    
servo3.slowmove(val,50);             
delay(20);  
// Up down movement    

}

Also, here is the wiring of my project prior to purchasing some joystick modules.

What I'm trying to achieve is basically translate the same functionality by swapping out the potentimeters for two joystick modules, and swapping the two push buttons for the Push Button Switch Sensor on each joystick module (if that makes sense).

The end goal is to have five servos that I can control with the two joysticks.

Best,

E



groundFungus:
If the value of a variable will always be in the range 0 to 255, declaring the variable as byte data type uses 1 byte of SRAM, int data type uses 2 bytes. Byte saves 1 byte of SRAM.

Arduino data types.

This makes sense, thanks @groundFungus for clarifying.

pinto_e:
What I'm trying to achieve is basically translate the same functionality by swapping out the potentimeters for two joystick modules, and swapping the two push buttons for the Push Button Switch Sensor on each joystick module (if that makes sense).

A I am not beside you to show you how I honestly don't know how to help. You need to try connecting the potentiometers and switches from the joysticks in place of the potentiometers and switches in the diagram.

Start by connecting up one joystick and writing a short Arduino program to display the values on the Arduino Serial Monitor.

Fritzing diagrams are very easy to misunderstand. I suggest (for your benefit as well as ours) that you make a pencil drawing of the circuit without the complication of the solderless breadboard.

...R

1 Like