Programming for my robotic bull project

Hey all,
I’m currently in the middle of a project where I’m trying to make a mechanical bull with some servos. The objective is to get the hip beam to move clockwise while the knee moves counterclockwise, and the the opposite motion in a fast and control motion to make the bucking motion of the bull. The problem I’m running into right now is that my current code causes the servo to just jiggle back and for about 10 degrees extremely fast and doesn’t feel smooth. Also it seems that my currentMillis0 is not getting subtracted because the serial monitor just counts up and never goes back to zero.

P.S the current beams are temporary I’m currently making new ones. that look like this

/* servo*/
#include<Servo.h>
int angle = 0;

/*Rear hip and Knee of bull*/ 
// Left Side
Servo lhh; //Initialize Left Hind Hip
Servo lhk; //Initialize Left Hind Knee
//Right Side
Servo rhh; //Initialize Right Hind Hip
Servo rhk; //Initialize Right Hind Knee

/* Front hip and Knee of bull */
//Left Side
Servo lfh; //Initialize Left Front Hip 
Servo lfk; //Initialize Left Front Knee
//Right Side
Servo rfh; //Initialize Right Front Hip
Servo rfk; //Initialize Right Front Knee

/*Rider*/
Servo R; //Initialize Rider

/* Timing */
unsigned long previousMillis0=0;
unsigned long previousMillis1=0;
unsigned long startMillis;
unsigned long currentMillis0;
unsigned long currentMillis1;

/* Hold Random Value */
long randomNumber;



void setup() {
  /*Left Side Hind*/
  lhh.attach(2);//Hind Hip
  lhk.attach(3);//Hind Knee
  /*Left Side Front*/
  lfh.attach(4);//Front Hip
  lfk.attach(5);//Front Knee
  
/* Right Side Hind*/
  rhh.attach(6);//Hind Hip
  rhk.attach(7);//Hind Knee
  /*right Side Front*/
  rfh.attach(8);//Front Hip
  rfk.attach(9);//Front Knee

  

  randomSeed(analogRead(A0));// generate a random seed, DON'T connect anything to pin A0)
  
  Serial.begin(9600);
}

void jump(){

lhh.write(65);
lhk.write(55);
currentMillis0 = millis();
currentMillis1=millis();
if (currentMillis0 - previousMillis0 >= 25){
for(int angle = 5; angle <= 110;angle++)
lhh.write(angle); //*.write(int) sets degree position of servo
previousMillis0=currentMillis0;
}
if (currentMillis1 - previousMillis1 >=25){
for(int angle = 5;angle>=55;angle--)
lhh.write(angle);
previousMillis1=currentMillis1;}
    //lhk.write (angle);
    //{for (int angle = 1; angle>=110;angle--)
    //lhk.write(angle);

    /* right side
    rhh.write(angle);
    rhk.write(angle);*/
    
    }

This code needs a LOT more explanation. What calls the jump() function? Where is the loop() function?

tydeocean: my current code causes the servo to just jiggle back and for about 10 degrees extremely fast and doesn't feel smooth.

Your code has 9 servos in. Give us a bit more of a hint, which servo just jiggles?

And I can't see any code that tries to subtract currentMillis0 from anything.

Steve

Please post your entire sketch.

for(int angle = 5;angle>=55;angle--) doesn't make sense since 'angle>=55' will be false and it will exit the loop immediately.

/* servo*/
#include<Servo.h>
int angle = 0;

/*Rear hip and Knee of bull*/ 
// Left Side
Servo lhh; //Initialize Left Hind Hip
Servo lhk; //Initialize Left Hind Knee
//Right Side
Servo rhh; //Initialize Right Hind Hip
Servo rhk; //Initialize Right Hind Knee

/* Front hip and Knee of bull */
//Left Side
Servo lfh; //Initialize Left Front Hip 
Servo lfk; //Initialize Left Front Knee
//Right Side
Servo rfh; //Initialize Right Front Hip
Servo rfk; //Initialize Right Front Knee

/*Rider*/
Servo R; //Initialize Rider

/* Timing */
unsigned long previousMillis0=0;
unsigned long previousMillis1=0;
unsigned long startMillis;
unsigned long currentMillis0;
unsigned long currentMillis1;

/* Hold Random Value */
long randomNumber;



void setup() {
  /*Left Side Hind*/
  lhh.attach(2);//Hind Hip
  lhk.attach(3);//Hind Knee
  /*Left Side Front*/
  lfh.attach(4);//Front Hip
  lfk.attach(5);//Front Knee
  
/* Right Side Hind*/
  rhh.attach(6);//Hind Hip
  rhk.attach(7);//Hind Knee
  /*right Side Front*/
  rfh.attach(8);//Front Hip
  rfk.attach(9);//Front Knee

  

  randomSeed(analogRead(A0));// generate a random seed, DON'T connect anything to pin A0)
  
  Serial.begin(9600);
}

void jump(){

lhh.write(65);
lhk.write(55);
currentMillis0 = millis();
currentMillis1=millis();
if (currentMillis0 - previousMillis0 >= 25){
for(int angle = 5; angle <= 110;angle++)
lhh.write(angle); //*.write(int) sets degree position of servo
previousMillis0=currentMillis0;
}
if (currentMillis1 - previousMillis1 >=25){
for(int angle = 5;angle>=55;angle--)
lhh.write(angle);
previousMillis1=currentMillis1;}
    //lhk.write (angle);
    //{for (int angle = 1; angle>=110;angle--)
    //lhk.write(angle);

   /*void rest(){
  lhh.write(50);
  lhk.write(30);*/
}


void loop() {
  currentMillis0 = millis();
  randomNumber =random(2,10); //select a random number between 2 and 10
  Serial.println(currentMillis0);
  jump();
  
  }

This is the entire code, I only have the left rear leg attached right now. I’m trying to get it working one piece at a time.

I see 3 problems here:

First, a servo motor is controlled with a PWM pulse width between 1ms and 2ms to control the servo position (freq is 50hz). Your loop that writes the angle does not have a delay in it. Therefore before a single pulse width of the correct length can get out you are setting another. Use a 15ms delay like the servo sample code does and you will probably see correct movement.

Secondly, as I said before, your second loop will not execute. I believe you intend it to read:

for(int angle = 110;angle>=5;angle--)

Third, if you were trying to execute these sweeps every 25ms that is way to fast for the servo to reach its position before sweeping back. That explains the jiggle as well.

Also, the way you have this coded setting currentMillis0 in the main loop has no effect.

Okay, I think I found where I must start with this. currently 4 of the eight servos operate in the opposite direction due to them being flipped. I would like for them to rotate the same way for a given degree. for example 40 will sweep both left and right servos counterclockwise 40 degrees even though they are facing opposite directions. I understand that I must subtract 180 from the 4 servos i which to change but i do not know how to implement this in the code.

/* servo*/
#include<Servo.h>
int angle=0;
/*Rear hip and Knee of bull*/ 
// Left Side
Servo lhh; //Initialize Left Hind Hip
Servo lhk; //Initialize Left Hind Knee
//Right Side
Servo rhh; //Initialize Right Hind Hip
Servo rhk; //Initialize Right Hind Knee

/* Front hip and Knee of bull */
//Left Side
Servo lfh; //Initialize Left Front Hip 
Servo lfk; //Initialize Left Front Knee
//Right Side
Servo rfh; //Initialize Right Front Hip
Servo rfk; //Initialize Right Front Knee

/*Rider*/
Servo R; //Initialize Rider

/* Timing */
unsigned long previousMillis0=0;
unsigned long previousMillis1=0;
unsigned long startMillis;
unsigned long currentMillis0;
unsigned long currentMillis1;

/* Hold Random Value */
long randomNumber;



void setup() {
  /*Left Side Hind*/
  lhh.attach(2);//Hind Hip
  lhk.attach(3);//Hind Knee
  /*Left Side Front*/
  lfh.attach(4);//Front Hip
  lfk.attach(5);//Front Knee
  
/* Right Side Hind*/
  rhh.attach(6);//Hind Hip
  rhk.attach(7);//Hind Knee
  /*right Side Front*/
  rfh.attach(8);//Front Hip
  rfk.attach(9);//Front Knee

/* random angles to test movment*/
lhh.write(40);// higher angle hip movs toward tail end
rhh.write(40);//higher angle hip moves toward head
lhk.write(120);//high angle knee moves toward head
rhk.write(65);
rfh.write(0);
lfh.write(170);
lfk.write(75);
rfk.write(80);
  

  randomSeed(analogRead(A0));// generate a random seed, DON'T connect anything to pin A0)
  
  Serial.begin(9600);
}

void jump(){
for(int angle= 80;angle>40;angle -=1)
lhh.write(angle);
for(int angle=90;angle<=140;angle +=1)
rhh.write(angle);
delay(500);
for (int angle= 40;angle<80;angle +=1)
lhh.write(angle);
for (int angle=140;angle>90;angle-=1)
rhh.write(angle);
delay(500); 
}


void loop() {
  currentMillis0 = millis();
  randomNumber =random(2,10); //select a random number between 2 and 10
jump();

  /*for later coding
  if (currentMillis - previousMillis >= randomNumber){
    /* write code to release rider*/
  }

I still think you need delays in your for loops in order to allow at least one PWM cycle to complete and allow the servo to respond to one angle before writing another.

I agree with that, I believe that is whats in the jump function, which then gets called in the loop. But right now that is not the issue I face, the servos are operating opposite each other so getting the leg movement correct is very difficult because let say that in order for the left leg to sweep out 40 degrees counter clockwise, to get the right leg to do the same I need to write 140 degrees. With 8 servos doing 8 different angles its gets confusing what angle each leg needs to be at. I’m looking to see if I can get all the servos to sweep the same direction regardless of their orientation.

OK. But your jump function does not have delays in the loops. It could be problematic later.