//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; } }