Need help to simplify working code

Hello (again)!

I wrote this code, it’s for an art project where I have a patch of papier-mache mushrooms on which eyes will be attached to servos. People will walk along a sidewalk along which 5 consecutive sensors will be laid.

When a person fires the first sensor, the eyes of each mushroom will turn to look in the direction on the activated sensor. Then, when the second sensor is triggered, the eyes will turn to that new direction, and so on giving the impression the the mushrooms follow you with their eyes.

Since the mushrooms will be separated by some distance , I need each of their pair of eyes to turn a different amount, so that their ‘looks’ are concentric and not parallel, all pointing to the place where the person is standing. (is that clear?)

So I wrote this code, I’ts a start, it works for 1 sensor, in the code it’s a button since I use buttons for the prototype.

All the servos start at 90 degrees, when I hit the button:

servo 1 stays at 90
servo 2 turns to 112
servo 2 turns to 134
servo 2 turns to 156
servo 2 turns to 179 (because at 180 the servo gets parkinsons disease…)

When I release the button all the servos go back to 90 degrees.

here it is

#include <Servo.h>                                                                
                   
Servo myservos[5];                                                               // variables for each  servo                                         
int buttonPin = 2;                                                               // pin to which button is connected                                                                                                                 
int buttonState;                                                                 // pressed or not (serves as some sort of counter)                           
int lastButtonState;                                                             // to compare with buttonState
int angles[] = {0, 0, 0, 0, 0};                                                  // for each servo, values will increment here from 90 to 179 and back               
int positions1[] = {90, 112, 134, 156, 179};                                     // maximum positions that corresponding servos will reach

void setup() {                             
  
                                             
   myservos[4].attach(7);                                                        // connecting servos to Arduino pins                
   myservos[3].attach(8);                 
   myservos[2].attach(9); 
   myservos[1].attach(10); 
   myservos[0].attach(11);               
   pinMode (buttonPin, INPUT);                                                          
}
void  moveButton() {                                                             // creates a function that will do all the work                     
  buttonState = digitalRead(buttonPin);                                          // reads the buttonPin and assign its value to buttonState                    
    if (buttonState != lastButtonState) {                                        // compares the two values                                                                  
      if (buttonState == 1)  {                                                   // if new value is 1 then proceed, if not, go to else                                                                                                                                                       
                      
             for(angles[4] = 90; angles[4] <= positions1[4]; angles[4] += 1){    // for each incremented angles, write the incrementing values to the according  
             myservos[4].write(angles[4]);}                                      // 'myservos' variable. This will tell the servo to move.
             for(angles[3] = 90; angles[3] <= positions1[3]; angles[3] += 1){
             myservos[3].write(angles[3]);}
             for(angles[2] = 90; angles[2] <= positions1[2]; angles[2] += 1){
             myservos[2].write(angles[2]);}
             for(angles[1] = 90; angles[1] <= positions1[1]; angles[1] += 1){
             myservos[1].write(angles[1]);}
             for(angles[0] = 90; angles[0] <= positions1[0]; angles[0] += 1){
             myservos[0].write(angles[0]);}                    
                              
      delay(100);
    }       
      else  {                                                                       
                                                                              
             for(angles[4] = 179; angles[4] >= 90; angles[4] -= 1){             // all servos go back to 90 degrees 
             myservos[4].write(angles[4]);}
             for(angles[3] = 156; angles[3] >= 90; angles[3] -= 1){ 
             myservos[3].write(angles[3]);}
             for(angles[2] = 134; angles[2] >= 90; angles[2] -= 1){ 
             myservos[2].write(angles[2]);}
             for(angles[1] = 112; angles[1] >= 90; angles[1] -= 1){ 
             myservos[1].write(angles[1]);}
             for(angles[0] = 90; angles[0] >= 90; angles[0] -= 1){ 
             myservos[0].write(angles[0]);}
                                                                                       
          delay(100);                                                        
        }
      }
    lastButtonState = buttonState;                                              // updates the 'counter'            
    delay(20);                                                      
}
void loop(){                                                                           
                                                        
          moveButton();                                                          // activates the movebutton function  
                                                                  
}

Now, I’m trying to simplify the moveButton function, here’s my try, it doesn’t work but I think I’m not so far from something. (I’ve been trying a lot to get here: )

#include <Servo.h>                                                                
                   
Servo myservos[5];                                         
int buttonPin = 2;                                                                                                    
int buttonState;                           
int lastButtonState;
int angles[] = {0, 0, 0, 0, 0};               
int positions1[] = {90, 112, 134, 156, 179};


void setup() {                             
                                             
   myservos[4].attach(7);                
   myservos[3].attach(8);                 
   myservos[2].attach(9); 
   myservos[1].attach(10); 
   myservos[0].attach(11);               
   pinMode (buttonPin, INPUT);                                                          

}  
void  moveButton(int cycle) {
 
  buttonState = digitalRead(buttonPin);                    
    if (buttonState != lastButtonState) {                                                                  
      if (buttonState == 1){  
               
             for(angles[0, 1, 2, 3, 4] = 90; angles[cycle] <= positions1[cycle]; angles[cycle] += 1){ 
             myservos[cycle].write(angles[cycle]);

           }
                  
                              
      delay(100);
  }      
      else  {                                                                       
                                                                              
             for(angles[cycle] = 179; angles[cycle] >= 90; angles[cycle] -= 1){ 
             myservos[cycle].write(angles[cycle]);
 
           }

                                                                                       
          delay(100);                                                        
        }
    }    
    lastButtonState = buttonState;           
    delay(20);                                                      
  
}
void loop(){                                                                           
    int runner;                                                                        
    for (int runner = 4; runner >= 0; runner--) {                                                    
          moveButton(runner);  
    }                                                              
}

So, if anyone could give me some hints on what’s wrong and how to fix it, would help me a lot. And at the same time, telling me if it will be possible to include 4 more buttons with 4 new sets of angular displays, the way I’m building this code…

Thanks a lot,

Kaporal_P

The difference between these two loops from your original code is obvious, is it not?

for(angles[[glow]4[/glow]] = 90; angles[[glow]4[/glow]] <= positions1[[glow]4[/glow]]; angles[[glow]4[/glow]] += 1){    // for each incremented angles, write the incrementing values to the according  
             myservos[[glow]4[/glow]].write(angles[[glow]4[/glow]]);}                                      // 'myservos' variable. This will tell the servo to move.

for(angles[[glow]3[/glow]] = 90; angles[[glow]3[/glow]] <= positions1[[glow]3[/glow]]; angles[[glow]3[/glow]] += 1){
             myservos[[glow]3[/glow]].write(angles[[glow]3[/glow]]);}

Create an outer for loop:

for(int i=4; i>=0; i--)
{
  for(angles[[glow]i[/glow]] = 90; angles[[glow]i[/glow]] <= positions1[[glow]i[/glow]]; angles[[glow]i[/glow]] += 1)
  {    // for each incremented angles, write the incrementing values to the according  
             myservos[[glow]i[/glow]].write(angles[[glow]i[/glow]]);
  }
}

Yes, of course it is, and I knew without really knowing that there needed to be 'another' incrementation for each 'pass' of the loop, but my brain wouldn't let me go there, that's why I'm here!

ok now I'll go try and fix that code, I'll be back soon to say how it went,

thanks

Yesssss, it works! Beautiful!

Another thing I spent a lot of time on was trying to create an array for the setup part

void setup() {                             
                                             
   myservos[4].attach(7);                
   myservos[3].attach(8);                 
   myservos[2].attach(9); 
   myservos[1].attach(10); 
   myservos[0].attach(11); }

I could use the loops incrementation for myservos but then I’d need another one for the attach part. Would there be a way to reference the loops incrementation to an array that would then assign values to the attach part?

Would it be a legitimate way to proceed or is it too risky to get mistakes?

Thanks again.

p.s. Is it ok to ask other questions regarding the same topic in the same thread or should I start a new one?

btw, here’s the corrected code

#include <Servo.h>                                                                
                   
Servo myservos[5];                                         
int buttonPin = 2;                                                                                                    
int buttonState;                           
int lastButtonState;
int angles[] = {0, 0, 0, 0, 0};               
int positions1[] = {90, 112, 134, 156, 179};


void setup() {                             
                                             
   myservos[4].attach(7);                
   myservos[3].attach(8);                 
   myservos[2].attach(9); 
   myservos[1].attach(10); 
   myservos[0].attach(11);               
   pinMode (buttonPin, INPUT);                                                          
}

void  moveButton(int cycle){  
  int subrunner;
  for(int subrunner=4; subrunner>=0; subrunner--){
  buttonState = digitalRead(buttonPin);                    
    if (buttonState != lastButtonState){                                                                  
      if (buttonState == 1){  
        for(angles[subrunner] = 90; angles[subrunner] <= positions1[subrunner]; angles[subrunner] += 1){    
        myservos[subrunner].write(angles[subrunner]);
        }
        delay(50);
      }
      else{                                                                       
        for(angles[subrunner] = 179; angles[subrunner] >= 90; angles[subrunner] -= 1){
          myservos[subrunner].write(angles[subrunner]);
        }
        delay(50);                                                        
      }
    }
  }        
  lastButtonState = buttonState;           
  delay(20);                                                      
}

void loop(){                                                                           
  int runner;                                                                        
  for (int runner = 4; runner >= 0; runner--){                                                    
    moveButton(runner);  
  }                                                              
}

I think you could do that.

int x = 11 ;

for (i=0;i<5;i++){
myservos*.attach(x); // starts at 0,11, goes up to 4,7*
x–; //subtract 1 from x every time
}

Again, such a nice way to trick the Thing, works beautifully, I need to learn to think like a machine, your solutions are so simple and seem so obvious.

Thanks for all the help,

appreciated

kap

The problem with that approach is that it won’t work if you need to change the pin numbers, by moving to a Mega, for instance.

Better would be to put the servo pins in an array, like the servo objects are.

int servoPins[] = {11, 10, 9, 8, 7};
const int servoCnt = 5;

Then, the attach loop:

for(int i=0; i<servoCnt; i++)
{
   myservos[i].attach(servoPins[i]);
}

Now, if you need to change the pins used by the servos, or add more servos, the logic doesn’t need to change.

p.s. Is it ok to ask other questions regarding the same topic in the same thread or should I start a new one?

Keep adding questions to this thread, in my opinion.

By the way, in loop, you have:

int runner; // this variable is never used
for(int runner = 4; runner >= 0; runner--)

The runner variable in the block following the for loop is NOT the one declared before the for loop. If it the one declared in the for loop.

If you try to use runner after the for loop, the one declared in the for loop (and valued) will have gone out of scope, leaving on the uninitialized one.