Source Code

 
#include <Servo.h> 

// Define servo objects for the snake segments
Servo s1; 
Servo s2;
Servo s3;
Servo s4; 
Servo s5;
Servo s6;
Servo s7;
Servo s8;
Servo s9; 
Servo s10;
Servo s11;
Servo s12;
Servo panServo;
 
// Define variables
int IRpin = 15;
int distanceReading;
int wallDistance;
int wallDistanceTolerance = 30;
int distanceReadingLeft;
int distanceReadingRight;
int wallDistanceLeft;
int wallDistanceRight;
int panDelay = 1000;

int forwardVal = 0; // Remote control variables
int reverseVal = 0;
int rightVal = 0;
int leftVal = 0;

int counter = 0; // Loop counter variable
float lag = .5712; // Phase lag between segments
int frequency = 1; // Oscillation frequency of segments.
int amplitude = 40; // Amplitude of the serpentine motion of the snake
int rightOffset = 5; // Right turn offset
int leftOffset = -5; // Left turn offset
int offset = 6; // Variable to correct servos that are not exactly centered
int delayTime = 3; // Delay between limb movements
int startPause = 5000; // Delay time to position robot
int test = -3; // Test varialble takes values from -6 to +5
 
void setup() 
{ 

 
// Attach segments to pins 
 s1.attach(2);
 s2.attach(3);
 s3.attach(4);
 s4.attach(5);
 s5.attach(6);
 s6.attach(7);
 s7.attach(8);
 s8.attach(9);
 s9.attach(10);
 s10.attach(11);
 s11.attach(12);
 s12.attach(13);
 panServo.attach(14);
 
// Put snake in starting position
 s1.write(90+offset+amplitude*cos(5*lag));
 s2.write(90+offset+amplitude*cos(4*lag)); 
 s3.write(90+offset+amplitude*cos(3*lag));
 s4.write(90+amplitude*cos(2*lag));
 s5.write(90+amplitude*cos(1*lag));
 s6.write(90+amplitude*cos(0*lag));
 s7.write(90+amplitude*cos(-1*lag));
 s8.write(90+amplitude*cos(-2*lag));
 s9.write(90+amplitude*cos(-3*lag));
 s10.write(90+amplitude*cos(-4*lag));
 s11.write(90+amplitude*cos(-5*lag));
 s12.write(90+amplitude*cos(-6*lag));
 
 
 delay(startPause); // Pause to position robot
} 
 
void loop() {
// Point distance sensor straight ahead
 panServo.write(90);
// Take reading from distance sensor
 delay(1000);
 distanceReading = analogRead(IRpin);
 wallDistance = 40-distanceReading/10;
 
// If wallDistance > wallDistanceTolerance, move forward
 if (wallDistance > wallDistanceTolerance) { 
 for(counter = 0; counter < 360; counter += 1) {
 delay(delayTime);
 s1.write(90+offset+amplitude*cos(frequency*counter*3.14159/180+5*lag));
 s2.write(90+offset+amplitude*cos(frequency*counter*3.14159/180+4*lag));
 s3.write(90+offset+amplitude*cos(frequency*counter*3.14159/180+3*lag));
 s4.write(90+amplitude*cos(frequency*counter*3.14159/180+2*lag));
 s5.write(90+amplitude*cos(frequency*counter*3.14159/180+1*lag));
 s6.write(90+amplitude*cos(frequency*counter*3.14159/180+0*lag)); 
 s7.write(90+amplitude*cos(frequency*counter*3.14159/180-1*lag));
 s8.write(90+amplitude*cos(frequency*counter*3.14159/180-2*lag)); 
 s9.write(90+amplitude*cos(frequency*counter*3.14159/180-3*lag));
 s10.write(90+amplitude*cos(frequency*counter*3.14159/180-4*lag));
 s11.write(90+amplitude*cos(frequency*counter*3.14159/180-5*lag)); 
 s12.write(90+amplitude*cos(frequency*counter*3.14159/180-6*lag)); 
 }
 }

// If wallDistance , wallDistanceTolerance, stop and take
// distance measurements to the left and right
 if (wallDistance < wallDistanceTolerance) {
 panServo.write(170);
 delay(panDelay);
 distanceReadingLeft = analogRead(IRpin);
 delay(panDelay);
 wallDistanceLeft = 40-distanceReadingLeft/10;

 panServo.write(20);
 delay(panDelay);
 distanceReadingRight = analogRead(IRpin);
 delay(panDelay);
 wallDistanceRight = 40-distanceReadingRight/10;
 panServo.write(90);
 delay(panDelay);



 if (wallDistanceLeft > wallDistanceRight) {
// Reverse and then turn left
// Reverse
 for(counter = 360; counter > 0; counter -= 1) {
 delay(delayTime);
 s1.write(90+offset+amplitude*cos(frequency*counter*3.14159/180+5*lag));
 s2.write(90+offset+amplitude*cos(frequency*counter*3.14159/180+4*lag));
 s3.write(90+offset+amplitude*cos(frequency*counter*3.14159/180+3*lag));
 s4.write(90+amplitude*cos(frequency*counter*3.14159/180+2*lag));
 s5.write(90+amplitude*cos(frequency*counter*3.14159/180+1*lag));
 s6.write(90+amplitude*cos(frequency*counter*3.14159/180+0*lag)); 
 s7.write(90+amplitude*cos(frequency*counter*3.14159/180-1*lag));
 s8.write(90+amplitude*cos(frequency*counter*3.14159/180-2*lag)); 
 s9.write(90+amplitude*cos(frequency*counter*3.14159/180-3*lag));
 s10.write(90+amplitude*cos(frequency*counter*3.14159/180-4*lag));
 s11.write(90+amplitude*cos(frequency*counter*3.14159/180-5*lag)); 
 s12.write(90+amplitude*cos(frequency*counter*3.14159/180-6*lag)); 
 } 
 
// Left turn
// Ramp up turn offset
 for(counter = 0; counter < 10; counter += 1) {
 delay(delayTime);
 s1.write(90+offset+.1*counter*leftOffset+amplitude*cos(frequency*counter*3.14159/180+5*lag));
 s2.write(90+offset+.1*counter*leftOffset+amplitude*cos(frequency*counter*3.14159/180+4*lag));
 s3.write(90+offset+.1*counter*leftOffset+amplitude*cos(frequency*counter*3.14159/180+3*lag));
 s4.write(90+.1*counter*leftOffset+amplitude*cos(frequency*counter*3.14159/180+2*lag));
 s5.write(90+.1*counter*leftOffset+amplitude*cos(frequency*counter*3.14159/180+1*lag));
 s6.write(90+.1*counter*leftOffset+amplitude*cos(frequency*counter*3.14159/180+0*lag)); 
 s7.write(90+.1*counter*leftOffset+amplitude*cos(frequency*counter*3.14159/180-1*lag));
 s8.write(90+.1*counter*leftOffset+amplitude*cos(frequency*counter*3.14159/180-2*lag)); 
 s9.write(90+.1*counter*leftOffset+amplitude*cos(frequency*counter*3.14159/180-3*lag));
 s10.write(90+.1*counter*leftOffset+amplitude*cos(frequency*counter*3.14159/180-4*lag));
 s11.write(90+.1*counter*leftOffset+amplitude*cos(frequency*counter*3.14159/180-5*lag)); 
 s12.write(90+.1*counter*leftOffset+amplitude*cos(frequency*counter*3.14159/180-6*lag)); 
 } 
// Continue left turn
 for(counter = 11; counter < 350; counter += 1) {
 delay(delayTime);
 s1.write(90+offset+leftOffset+amplitude*cos(frequency*counter*3.14159/180+5*lag));
 s2.write(90+offset+leftOffset+amplitude*cos(frequency*counter*3.14159/180+4*lag));
 s3.write(90+offset+leftOffset+amplitude*cos(frequency*counter*3.14159/180+3*lag));
 s4.write(90+leftOffset+amplitude*cos(frequency*counter*3.14159/180+2*lag));
 s5.write(90+leftOffset+amplitude*cos(frequency*counter*3.14159/180+1*lag));
 s6.write(90+leftOffset+amplitude*cos(frequency*counter*3.14159/180+0*lag)); 
 s7.write(90+leftOffset+amplitude*cos(frequency*counter*3.14159/180-1*lag));
 s8.write(90+leftOffset+amplitude*cos(frequency*counter*3.14159/180-2*lag)); 
 s9.write(90+leftOffset+amplitude*cos(frequency*counter*3.14159/180-3*lag));
 s10.write(90+leftOffset+amplitude*cos(frequency*counter*3.14159/180-4*lag));
 s11.write(90+leftOffset+amplitude*cos(frequency*counter*3.14159/180-5*lag)); 
 s12.write(90+leftOffset+amplitude*cos(frequency*counter*3.14159/180-6*lag)); 
 } 
// Ramp down turn offset
 for(counter = 350; counter < 360; counter += 1) {
 delay(delayTime);
 s1.write(90+offset+.1*(360-counter)*leftOffset+amplitude*cos(frequency*counter*3.14159/180+5*lag));
 s2.write(90+offset+.1*(360-counter)*leftOffset+amplitude*cos(frequency*counter*3.14159/180+4*lag));
 s3.write(90+offset+.1*(360-counter)*leftOffset+amplitude*cos(frequency*counter*3.14159/180+3*lag));
 s4.write(90+.1*(360-counter)*leftOffset+amplitude*cos(frequency*counter*3.14159/180+2*lag));
 s5.write(90+.1*(360-counter)*leftOffset+amplitude*cos(frequency*counter*3.14159/180+1*lag));
 s6.write(90+.1*(360-counter)*leftOffset+amplitude*cos(frequency*counter*3.14159/180+0*lag)); 
 s7.write(90+.1*(360-counter)*leftOffset+amplitude*cos(frequency*counter*3.14159/180-1*lag));
 s8.write(90+.1*(360-counter)*leftOffset+amplitude*cos(frequency*counter*3.14159/180-2*lag)); 
 s9.write(90+.1*(360-counter)*leftOffset+amplitude*cos(frequency*counter*3.14159/180-3*lag));
 s10.write(90+.1*(360-counter)*leftOffset+amplitude*cos(frequency*counter*3.14159/180-4*lag));
 s11.write(90+.1*(360-counter)*leftOffset+amplitude*cos(frequency*counter*3.14159/180-5*lag)); 
 s12.write(90+.1*(360-counter)*leftOffset+amplitude*cos(frequency*counter*3.14159/180-6*lag)); 
 } 
 }


 if (wallDistanceLeft <= wallDistanceRight) {
 
// Reverse and turn right
// Reverse
 for(counter = 360; counter > 0; counter -= 1) {
 delay(delayTime);
 s1.write(90+offset+amplitude*cos(frequency*counter*3.14159/180+5*lag));
 s2.write(90+offset+amplitude*cos(frequency*counter*3.14159/180+4*lag));
 s3.write(90+offset+amplitude*cos(frequency*counter*3.14159/180+3*lag));
 s4.write(90+amplitude*cos(frequency*counter*3.14159/180+2*lag));
 s5.write(90+amplitude*cos(frequency*counter*3.14159/180+1*lag));
 s6.write(90+amplitude*cos(frequency*counter*3.14159/180+0*lag)); 
 s7.write(90+amplitude*cos(frequency*counter*3.14159/180-1*lag));
 s8.write(90+amplitude*cos(frequency*counter*3.14159/180-2*lag)); 
 s9.write(90+amplitude*cos(frequency*counter*3.14159/180-3*lag));
 s10.write(90+amplitude*cos(frequency*counter*3.14159/180-4*lag));
 s11.write(90+amplitude*cos(frequency*counter*3.14159/180-5*lag)); 
 s12.write(90+amplitude*cos(frequency*counter*3.14159/180-6*lag)); 
 } 
// Turn right
// Ramp up turn offset
 for(counter = 0; counter < 10; counter += 1) {
 delay(delayTime);
 s1.write(90+offset+.1*counter*rightOffset+amplitude*cos(frequency*counter*3.14159/180+5*lag));
 s2.write(90+offset+.1*counter*rightOffset+amplitude*cos(frequency*counter*3.14159/180+4*lag));
 s3.write(90+offset+.1*counter*rightOffset+amplitude*cos(frequency*counter*3.14159/180+3*lag));
 s4.write(90+.1*counter*rightOffset+amplitude*cos(frequency*counter*3.14159/180+2*lag));
 s5.write(90+.1*counter*rightOffset+amplitude*cos(frequency*counter*3.14159/180+1*lag));
 s6.write(90+.1*counter*rightOffset+amplitude*cos(frequency*counter*3.14159/180+0*lag)); 
 s7.write(90+.1*counter*rightOffset+amplitude*cos(frequency*counter*3.14159/180-1*lag));
 s8.write(90+.1*counter*rightOffset+amplitude*cos(frequency*counter*3.14159/180-2*lag)); 
 s9.write(90+.1*counter*rightOffset+amplitude*cos(frequency*counter*3.14159/180-3*lag));
 s10.write(90+.1*counter*rightOffset+amplitude*cos(frequency*counter*3.14159/180-4*lag));
 s11.write(90+.1*counter*rightOffset+amplitude*cos(frequency*counter*3.14159/180-5*lag)); 
 s12.write(90+.1*counter*rightOffset+amplitude*cos(frequency*counter*3.14159/180-6*lag)); 
 } 
// Continue right turn
 for(counter = 11; counter < 350; counter += 1) {
 delay(delayTime);
 s1.write(90+offset+rightOffset+amplitude*cos(frequency*counter*3.14159/180+5*lag));
 s2.write(90+offset+rightOffset+amplitude*cos(frequency*counter*3.14159/180+4*lag));
 s3.write(90+offset+rightOffset+amplitude*cos(frequency*counter*3.14159/180+3*lag));
 s4.write(90+rightOffset+amplitude*cos(frequency*counter*3.14159/180+2*lag));
 s5.write(90+rightOffset+amplitude*cos(frequency*counter*3.14159/180+1*lag));
 s6.write(90+rightOffset+amplitude*cos(frequency*counter*3.14159/180+0*lag)); 
 s7.write(90+rightOffset+amplitude*cos(frequency*counter*3.14159/180-1*lag));
 s8.write(90+rightOffset+amplitude*cos(frequency*counter*3.14159/180-2*lag)); 
 s9.write(90+rightOffset+amplitude*cos(frequency*counter*3.14159/180-3*lag));
 s10.write(90+rightOffset+amplitude*cos(frequency*counter*3.14159/180-4*lag));
 s11.write(90+rightOffset+amplitude*cos(frequency*counter*3.14159/180-5*lag)); 
 s12.write(90+rightOffset+amplitude*cos(frequency*counter*3.14159/180-6*lag)); 
 } 
// Ramp down turn offset
 for(counter = 350; counter < 360; counter += 1) {
 delay(delayTime);
 s1.write(90+offset+.1*(360-counter)*rightOffset+amplitude*cos(frequency*counter*3.14159/180+5*lag));
 s2.write(90+offset+.1*(360-counter)*rightOffset+amplitude*cos(frequency*counter*3.14159/180+4*lag));
 s3.write(90+offset+.1*(360-counter)*rightOffset+amplitude*cos(frequency*counter*3.14159/180+3*lag));
 s4.write(90+.1*(360-counter)*rightOffset+amplitude*cos(frequency*counter*3.14159/180+2*lag));
 s5.write(90+.1*(360-counter)*rightOffset+amplitude*cos(frequency*counter*3.14159/180+1*lag));
 s6.write(90+.1*(360-counter)*rightOffset+amplitude*cos(frequency*counter*3.14159/180+0*lag)); 
 s7.write(90+.1*(360-counter)*rightOffset+amplitude*cos(frequency*counter*3.14159/180-1*lag));
 s8.write(90+.1*(360-counter)*rightOffset+amplitude*cos(frequency*counter*3.14159/180-2*lag)); 
 s9.write(90+.1*(360-counter)*rightOffset+amplitude*cos(frequency*counter*3.14159/180-3*lag));
 s10.write(90+.1*(360-counter)*rightOffset+amplitude*cos(frequency*counter*3.14159/180-4*lag));
 s11.write(90+.1*(360-counter)*rightOffset+amplitude*cos(frequency*counter*3.14159/180-5*lag)); 
 s12.write(90+.1*(360-counter)*rightOffset+amplitude*cos(frequency*counter*3.14159/180-6*lag)); 
 } 
 } 
 
 }
 
} 

Camera UI
cam1