Your Title Text

Shane's Page

//This program is my version of hello world.
//I intend to drive two servos with random numbers
//while reporting the servo postions via a sparkfun
//serialLCD.  The servos rotate 0 to 180 counter clock
//wise so the numbers going to the LCD will have to 
//be reversed.

#include <Servo.h>
Servo servo1,servo2;                              //Uses servo libary to create to servos
unsigned long speedpot, oldspeedpot;              
int pos1,pos2,opos1,opos2;                  
unsigned long timer[10];
byte timerState[10];

void setup()
{
  servo1.attach(12);                              //Assin servo 1 control to pin 12
  servo2.attach(13);                              //Asign servo 2 control to pin 13
  pinMode(13,OUTPUT);
  digitalWrite(13,HIGH);
  Serial.begin(9600);                             //Start coms back to serial monitor for troubleshooting
  delay(500);                                     // wait for display to boot up
  LCDservo();
}

void loop()
{
  {
  if ((pos1 != opos1) || (pos2 != opos2))          //If servo one or two has not made it to the new postion
    {                                              //then it checks the timer and increments the postion and 
      if (delayMilliSeconds(1,speedpot))           //increments place holder.
      {
        sweepservos();
      }
    }    
    else
    {
      if (delayMilliSeconds(2,10000))
      {
        opos1 = pos1;
        opos2 = pos2;
        pos1 = randompos();
        pos2 = randompos();
        writenewpostion(pos1,pos2);
      }
    }
  oldspeedpot = speedpot;
  speedpot = checkspeedpot(oldspeedpot);
  }
}  

// Function reads pot, checks for changes and displays new speed as detected.
unsigned long checkspeedpot(unsigned long last)
{                                        
  unsigned long x,y,z;
  x = analogRead(5);
  y = map(x, 0,1023, 0, 30);
  // z = last- y;
  //  z = abs(z);
  if ((last- y) > 5 )
    {
      do  
        {
          x= analogRead(5);
          y = map(x, 0,1023, 0, 30);
          LCDspeed(y,500);
          
        } 
      while((analogRead(5) - x) > 2 );
      LCDspeed(y,3000);
      LCDservo();
      writenewpostion(pos1,pos2);   
    }    
  else  
    {
      y = last;
    }
  return y;
}


// Function to sweep servos one degree per timer setting
void sweepservos()
{
  if (pos1 > opos1)  
  { 
    ++opos1;
    servo1.write(opos1);
  }
  if (pos1 < opos1)
  { 
    --opos1;
    servo1.write(opos1);
  }
  if (pos2 > opos2)  
  { 
    ++opos2;
    servo2.write(opos2);
  }
  if (pos2 < opos2)
  { 
    --opos2;
    servo2.write(opos2);
  }
}


/*
This function takes in two variables.  The first is the angle
to display and the second indicates which line to display it on.
*/
void writetolcd(char angle[10],int line)
{
  Serial.write(254); // This is a control character for Sparkfuns serial display
  Serial.write(line); // This is the data for the the control character.
  Serial.write(angle); // write out the Servo angle
}

void writenewpostion(int p1,int p2)
{
  int p1rev, p2rev;      
  char ascipos1[10],ascipos2[10];
  p1rev = revangle(p1);             //Sends the angle out to a funtion to reverse it.
  p2rev = revangle(p2);
  sprintf(ascipos1,"%3d",p1rev);    // create strings from the numbers
  sprintf(ascipos2,"%3d",p2rev);    // right-justify to 4 spaces
  writetolcd(ascipos1,136);         //sends 136 for LCD line 1 postion 9
  writetolcd(ascipos2,200);         //sends 200 for LCD line 2 postion 9
}

/*
This Funtion is used to reverse the angles
so that the servos sweep from 0 on the left
to 180 on the right
*/
int revangle(int pos)              
{                                 
  int rev;                         
  rev = map(pos,0,180,180,0);
  return rev;
}

/*
Not sure this required a function, but here it is.
This is called to come up with "random" numbers.
Why the qoutes?  Watch those random numbers....
I've not watched for a long time but the first 
three or four are always the same.
*/
int randompos()                    
{
  int npos;
  npos = random(0,180);
  return npos;
}

/*
This funtion clears the display and then changes the
display to the delay screen.  It displays the value,
set by the pot, between each degree of movement on
the servos.  This comes up when the pot postion is
changed and displays for 3 seconds before changing back
to the servo angle screen
*/
void LCDspeed(unsigned d, int timetodisplay)
{
  char delayascii[10];
  sprintf(delayascii,"%3d",d);   // create strings from the numbers
  Serial.write(254);       // cursor to beginning of first line
  Serial.write(128);

  Serial.write("Sweep delay(ms):"); // clear display + legends
  Serial.write("                ");

  Serial.write(254);
  Serial.write(192);

  Serial.write(delayascii);
  delay(timetodisplay);
}

/*
This function clears the diaplay and sets it up to 
display the Servo angles.
*/
void LCDservo()
{
  Serial.write(254); // cursor to beginning of first line
  Serial.write(128);

  Serial.write("Servo 1:        "); // clear display + legends
  Serial.write("Servo 2:        ");
}

/*
The code below is not mine and comes from the Arduino playground.
the code writen by Chad Higgin and the source can be found at
http://arduino.cc/playground/Code/DelaySeconds 
Thanks Chad.
*/
int delayHours(byte timerNumber,unsigned long delaytimeH){    //Here we make it easy to set a delay in Hours
  delayMilliSeconds(timerNumber,delaytimeH*1000*60*60);
}
int delayMinutes(byte timerNumber,unsigned long delaytimeM){    //Here we make it easy to set a delay in Minutes
  delayMilliSeconds(timerNumber,delaytimeM*1000*60);
}
int delaySeconds(byte timerNumber,unsigned long delaytimeS){    //Here we make it easy to set a delay in Seconds
  delayMilliSeconds(timerNumber,delaytimeS*1000);
}

int delayMilliSeconds(int timerNumber,unsigned long delaytime){
  unsigned long timeTaken;
  if (timerState[timerNumber]==0){    //If the timer has been reset (which means timer (state ==0) then save millis() to the same number timer,
    timer[timerNumber]=millis();
    timerState[timerNumber]=1;      //now we want mark this timer "not reset" so that next time through it doesn't get changed.
  }
  if (millis()> timer[timerNumber]){
    timeTaken=millis()+1-timer[timerNumber];    //here we see how much time has passed
  }
  else{
    timeTaken=millis()+2+(4294967295-timer[timerNumber]);    //if the timer rolled over (more than 48 days passed)then this line accounts for that
  }
  if (timeTaken>=delaytime) {          //here we make it easy to wrap the code we want to time in an "IF" statement, if not then it isn't and so doesn't get run.
     timerState[timerNumber]=0;  //once enough time has passed the timer is marked reset.
     return 1;                          //if enough time has passed the "IF" statement is true
  }
  else {                               //if enough time has not passed then the "if" statement will not be true.
    return 0;
  }
}

Website Builder