I’m using the Arduino Motor Shield.
The code is littered with comments, etc, and you will probably find lots of beginner mistakes.
And, byte size:
9,272 bytes (of a 32,256 byte maximum)
Here it is:
#include <Servo.h>
#include <EEPROM.h>
#include <avr/interrupt.h>
#include <avr/power.h>
#include <avr/sleep.h>
/*
robot.ino
@author Michael Antkiewicz
Used to init the robot
*/
int dirA = 12;
int dirB = 13; // not used in this example
int speedA = 10;
int speedB = 11; // not used in this example
Servo rightHand;
Servo leftHand;
int speed = 230;
int speed2 = 255;
int front = 0;
int back = 1;
const int location = 1;
/* Distance Sensor */
const int trigPin = 3;
const int echoPin = 4;
const int inchLimit = 7; //Max amount of space between robot and object
const int centLimit = 8; //Max amount of space between robot and object
/* End Distance Sensor */
const int motor_speed_high = 255;
const int motor_speed_backward = -255;
boolean tooClose = false;
void setup() {
Serial.begin(9600);
//Setup Channel A
pinMode(12, OUTPUT); //Initiates Motor Channel A pin
pinMode(9, OUTPUT); //Initiates Brake Channel A pin
//Setup Channel B
pinMode(13, OUTPUT); //Initiates Motor Channel A pin
pinMode(8, OUTPUT); //Initiates Brake Channel A pin
//EEPROM.write(location, 0);
rightHand.attach(7);
leftHand.attach(6);
}
void loop()
{
//StepForward();
//delay(4000);
//SoftwareServo::refresh();
if (Serial.available() > 0) {
char ch = Serial.read();
Serial.print("Received: ");
Serial.println(ch);
if (ch == '8') {
forward();
} else if (ch == '0') {
brake();
} else if (ch == '2') {
backward();
} else if (ch == '4') {
// left
left();
} else if (ch == '6') {
right();
} else if (ch == 'm' || ch == 'M') {
int val = EEPROM.read(location);
String newval = convertBitToString(val);
Serial.print(newval);
} else if (ch == 'v' || ch == 'V') {
Serial.print(readVcc());
} else if (ch == 'S' || ch == 's') {
Serial.println("Going to sleep...");
sleepNow();
} else if (ch == 'w' || ch == 'W') {
Serial.println("Waking up...");
pinInterrupt();
} else if (ch == 'C') {
rightHand.write(90);
//leftHand.write(180);
} else if (ch == 'D') {
rightHand.write(5);
//leftHand.write(0);
}
}
/*
String serial = readSerial();
if (serial.indexOf("Memorize") >= 0) {
serial.replace("Memorize", "");
serial = split(serial, ':');
Serial.println(serial);
}
*/
//brake();
//backward();
// establish variables for duration of the ping,
// and the distance result in inches and centimeters:
long duration, inches, cm;
// The sensor is triggered by a HIGH pulse of 10 or more microseconds.
// Give a short LOW pulse beforehand to ensure a clean HIGH pulse:
pinMode(trigPin, OUTPUT);
digitalWrite(trigPin, LOW);
delayMicroseconds(2);
digitalWrite(trigPin, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin, LOW);
// Read the signal from the sensor: a HIGH pulse whose
// duration is the time (in microseconds) from the sending
// of the ping to the reception of its echo off of an object.
pinMode(echoPin, INPUT);
duration = pulseIn(echoPin, HIGH);
// convert the time into a distance
inches = microsecondsToInches(duration);
cm = microsecondsToCentimeters(duration);
/*
Serial.print(inches);
Serial.print("in, ");
Serial.print(cm);
Serial.print("cm");
Serial.println();
*/
if (inches <= inchLimit) {
//brake();
//EEPROM.write(location,cm);
}
delay(100);
}
void setspeed()
{
analogWrite(speedB, speed); // set speed (PWM)
analogWrite(speedA, speed2); // set speed (PWM)
}
void forward() {
/*Motor A forward @ full speed
digitalWrite(12, HIGH);
digitalWrite(9, LOW);
analogWrite(3, 255);
//Motor B forward @ full speed
digitalWrite(13, HIGH); //Establishes forward direction of Channel B
digitalWrite(8, LOW); //Disengage the Brake for Channel B
analogWrite(11, 255); //Spins the motor on Channel B at full speed
Serial.print(analogRead(3));
*/
/* //Motor A forward @ full speed
digitalWrite(12, HIGH); //Establishes forward direction of Channel A
digitalWrite(9, LOW); //Disengage the Brake for Channel A
analogWrite(3, 255); //Spins the motor on Channel A at full speed
//Motor B backward @ half speed
digitalWrite(13, LOW); //Establishes backward direction of Channel B
digitalWrite(8, LOW); //Disengage the Brake for Channel B
analogWrite(11, 25); //Spins the motor on Channel B at half speed
delay(3000);
digitalWrite(9, HIGH); //Engage the Brake for Channel A
digitalWrite(9, HIGH); //Engage the Brake for Channel B
delay(1000);
*/
//Motor B forward @ full speed
digitalWrite(13, HIGH); //Establishes forward direction of Channel B
digitalWrite(8, LOW); //Disengage the Brake for Channel B
analogWrite(11, 255); //Spins the motor on Channel B at full speed
//Motor A forward @ full speed
digitalWrite(12, LOW); //Establishes for direction of Channel A
digitalWrite(9, LOW); //Disengage the Brake for Channel A
analogWrite(3, 255); //Spins the motor on Channel A at half speed
delay(1000);
}
void left() {
digitalWrite(dirB,back); // set direction
analogWrite(speedB, 255); // set speed (PWM)
}
void brake() {
digitalWrite(dirB,front); // set direction
analogWrite(speedB, 0); // set speed (PWM)
digitalWrite(dirA,front); // set direction
analogWrite(speedA, 0); // set speed (PWM)
}
void right()
{
digitalWrite(dirB,front); // set direction
analogWrite(speedB, 255); // set speed (PWM)
}
void backward() {
//Motor B forward @ full speed
digitalWrite(13, LOW); //Establishes forward direction of Channel B
digitalWrite(8, LOW); //Disengage the Brake for Channel B
analogWrite(11, 255); //Spins the motor on Channel B at full speed
//Motor A forward @ full speed
digitalWrite(12, HIGH); //Establishes for direction of Channel A
digitalWrite(9, LOW); //Disengage the Brake for Channel A
analogWrite(3, 255); //Spins the motor on Channel A at half speed
delay(1000);
}
long microsecondsToInches(long microseconds)
{
// According to Parallax's datasheet for the PING))), there are
// 73.746 microseconds per inch (i.e. sound travels at 1130 feet per
// second). This gives the distance travelled by the ping, outbound
// and return, so we divide by 2 to get the distance of the obstacle.
return microseconds / 74 / 2;
}
long microsecondsToCentimeters(long microseconds)
{
// The speed of sound is 340 m/s or 29 microseconds per centimeter.
// The ping travels out and back, so to find the distance of the
// object we take half of the distance travelled.
return microseconds / 29 / 2;
}
String convertBitToString(int value) {
int val = value;
String newval = String(val);
newval.replace("1", "Battery ");
newval.replace("2", "is ");
newval.replace("3", "low ");
newval.replace("6", "high ");
newval.replace("4", "I ");
newval.replace("5", "am ");
newval.replace("7", "my ");
newval.replace("8", "close ");
newval.replace("9", "distance ");
// 792
newval.toLowerCase();
return newval;
}
int combine(int a, int b) {
int times = 1;
while (times <= b)
times *= 10;
return a*times + b;
}
long readVcc() {
long result;
// Read 1.1V reference against AVcc
ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
delay(2); // Wait for Vref to settle
ADCSRA |= _BV(ADSC); // Convert
while (bit_is_set(ADCSRA,ADSC));
result = ADCL;
result |= ADCH<<8;
result = 1126400L / result; // Back-calculate AVcc in mV
return result;
}
void sleepNow()
{
// Set pin 2 as interrupt and attach handler:
attachInterrupt(0, pinInterrupt, LOW);
delay(100);
//
// Choose our preferred sleep mode:
set_sleep_mode(SLEEP_MODE_IDLE);
//
// Set sleep enable (SE) bit:
sleep_enable();
//
// Put the device to sleep:
digitalWrite(13,LOW); // turn LED off to indicate sleep
sleep_mode();
//
// Upon waking up, sketch continues from this point.
sleep_disable();
digitalWrite(13,HIGH); // turn LED on to indicate awake
}
//
void pinInterrupt()
{
detachInterrupt(0);
}
String readSerial() {
String content = "";
char character;
while(Serial.available()) {
character = Serial.read();
content.concat(character);
}
if (content != "") {
return content;
}
}