Introduction: Sensor Platform Robot With IR Control

About: I am an electronics hobbyist from Cape Town South Africa always interested in learning new skills and having fun doing it.

Hi there

This is my electronic robot project that I started because I wanted to learn more about interfacing sensor electronics with microcontrollers as well as build a platform that I could use to test out some of my programs, since it's always more satisfying to see a program make something move. For perhaps this reason or maybe more, some would like to build this or something similar. Hopefully this instructable will be able to help out with that.

Most robots are designed with a purpose and some specifications. I however started with some sensors that I wanted to use and just ended up with this so it's a bit of a mess. Some parts of this project may get a bit heavy on the theory side but should still be easy enough to follow and you could always read up if you'd like to know more.

I definitely recommend that you have some experience working with arduino, at least the basics. I also recommend that you be comfortable working with electronics and applying some basic electronics principles. These are not requirements for this project but it would make it easier. If you are doing some things for the first time you may need to do some extra research but that just means you'll benefit more from doing this project. I'll try to leave some further reading links where I can.

Step 1: Tools and Materials

The above diagram should provide a good idea of what you'll need to build this project. The most important parts are the Arduino Nano, Motor driver, op-amp IC's and IR proximity sensor modules. The rest should be easy enough to find. For the chassis I used a laser-cutting service to cut the design and they provided the plastic as well. I'll leave a spreadsheet of all the materials I used for you to download.

You will also need the following tools:

Soldering iron

Solder wire

Heat Gun

Screwdrivers

helping hands (optional, useful for soldering)

Attachments

Step 2: Body Design

The body design is a simple variation of the design in this instructable. It is laser-cut from 3mm thick perspex/acrylic plastic. I don't own a laser-cutter so I made use of a nearby laser-cutting service who also supplied the material as mentioned before. There is enough room to possibly mount more sensors in the future plus it looks great as well.

The design files that I'm leaving here are slightly updated from the one I've actually built. When I drew the brackets that were meant to mount the motors, I didn't account for the thickness of the material so they didn't fit correctly. Instead I used cable ties through the bracket slots which actually worked nicely. Hopefully, I will provide an update when I test the newer design but it should still be useful for you. Additionally I added some extra holes that can be used for inserting cables and mounting more sensors.

Step 3: Structure Assembly

It's fairly easy and straightforward to put all the parts together. It's best to hold off assembling until the electronics are done as some of those parts will need to be attached first. If you just want to see how everything fits together the assembly is as follows:

The castor wheel attaches to the bottom of the base through the 4 holes in the front with M3x6mm bolts. The slots near the center/towards the rear are for the brackets which hold the motors with M3x30mm bolts. Since my first design cut had incorrectly sized brackets I improvised and used cable ties through the bracket slots to fasten the motors. This worked surprisingly well, just bend the tie around the corners and it'll fit nicely. It does wiggle if you force it but otherwise it's stable.

The front base and back base pieces slot in between the base and upper base pieces. It's held together by the M4x55mm bolts. I use 2 nuts for each bolt, 1 to fasten the upper base to the top of the bolt and one to fasten the base.

All the tower pieces slot together and are fastened only by the slots on the tower top piece with M3x6 bolts. The tower then slots into the upper base and fastened with more M3x6 bolts.

Step 4: Electrical Overview

The overall design looks is depicted above. There are three electronic components to this design. The arduino nano itself, the motor driver, and what I'll call the sensor board from now.

Battery

A 9V battery provides power to the Arduino Nano which can accept a 7-12V input on Vin which it then regulates to power the board. The sensor board has a 5V regulator which is used to power the amplifiers. The motor driver accepts a 6-15V supply.

Processor

The Nano board provides the brain power for this project. This project uses most of the I/O pins available on the board, a lot of it is due to the many pins required for the motor driver. The Arduino Nano is just as easy to program and use as the Arduino UNO as well as being compact enough that it fit's nicely within the mechanical structure of the rover.

Motor Driver

The T6612FNG dual motor driver will be used to drive the two geared DC Motors. The driver can source current up to 1.2A with a 3.2A peak which is more than enough for the geared motors that I used. The driver also allows bidirectional control of the motors and accepts a PWM input from the Nano for speed control. It takes seven I/O pins on the Arduino 2 of which are the needed PWM pins.

Sensor Board

I made a separate circuit board for the amplifier circuits which are used to condition signals from the the LDR sensors, the Microphone and the output to the buzzer.

LDR's

LDR's(Light dependent resistor) or photoresistors are used to sense the ambient light in the room. LDR's are common, easy to acquire components. Their effectiveness is dependent on the amount of lighting in a room. So for this project we will make use of a potentiometer and a Wheatstone bridge to ensure that we get the right sensitivity and stability in the sensor.

Microphone

An electret microphone will be used to sense sound. For the microphone to work we will need to make use of an amplifier to generate a signal large enough to be recognized by the arduino.

Buzzer

A simple buzzer circuit will be connected so that our bot will also be able to make sounds.

IR proximity

Infrared proximity sensors allow the rover to detect when an obstacle is in front of it and thus avoid crashing into the obstacle. No additional circuitry will be needed, as we will be using a self contained module that can be directly connected to the arduino. The module outputs either a digital signal with a adjustable distance sensing via an on-board potentiometer, or an analog signal. I have just used the digital output for now.

IR reciever

The IR receiver allows the rover to be controlled with an IR remote. The IR receiver used is a TSOP382 which is found in many common appliances/devices such as TV's,DVD players, sound systems, air conditioners etc. The IR transmitting remote is used to transmit data to the receiver and works the same as the remotes for the aforementioned devices. In fact you could use an old TV remote that you have lying around. And if you like to tear things apart you could probably get your IR receiver module from an old DVD player or another device as well, you probably weren't using it anyway.

Step 5: Power Distribution

As you saw in the electrical overview section there are three main boards that need to be powered. The sensor board, the arduino and the motor driver. The Arduino has an on-board regulator to handle the 9V battery source. The motor driver can handle up 15V. The sensor board is different however. While it does use the 9V for some parts of the circuit, the op-amps are supplied with 5V. To get 5V I used an LM7805 voltage regulator. The added caps are there to make sure that the supply is stable. I used ceramic capacitors and those values are the one's recommended on the LM7805's datasheet. It's not critical that you have them and you don't have to use those exact values but it is a good habit to do anyways.

Step 6: Light Sensing Circuit

Light sensing with LDR's is relatively easy and there are a few interesting things that you could do with a light sensor. You could program behaviours into the bot that either respond to the presence or absence of light. This circuit will be used to generate a digital on/off signal for the Arduino, using a comparator by configuring 2 of the amplifiers on the OPA2344 IC chip. For tuning the sensor we will use a Wheatstone bridge.A wheatstone bridge is made up of two voltage dividers in parallel, it's used to turn a change in resistance into a change in voltage. Each side of the wheatstone bridge is connected to the inputs of the comparator. When the sides of the bridge are unbalanced this triggers the comparator's output. The comparator outputs are then coupled to the digital input pins on the arduino.

Two circuits will be needed for each LDR, I also added a potentiometers to the wheatstone bridge so that the sensitivity of the sensors can be adjusted for different lighting situations.

Two amplifiers are configured as comparators from the OPA2344 chips that we have. A comparator takes two signals as inputs, compares them and generates an output. For the two inputs we'll be using the two sides from the wheatstone bridge. The variable signal from the LDR side and the fixed signal from the resistor side.

The pin layout of the OPA2344 is as shown above. As you'll see in the layout of the physical circuit I've used the A amplifier from each chip for the sensors.

further reading

Wheatstone bridge circuits

Voltage Comparator explanation

Step 7: Microphone Amplifier and Speaker Driver

The microphone amplifier is probably the most complex circuit for this project but it's pretty cool. The electret microphone produces a very small signal on it's own that's why an amplifier is necessary to generate a larger signal that can be read by the Arduino.

Microphone Amplifier Circuit

The first part of the circuit biases the microphone since it is a component that has polarity.The output pin needs to be positively biased with reference to the ground pin that is done with a 10k through the +9V from the battery. If you want to, you can measure the change in voltage with a scope by attaching the probe to the output and ground pins of the mic. You should see a very small change, in the millivolt range, when you speak into the mic.The capacitor is there to block out the DC component of the signal so to speak, since we're only concerned with the AC portion generated from sound. The amplifier is configured to as an inverting amplifier with a gain of approx. 40 with the 2.7k and 100k resistor. The gain is calculated as -100k/2.7k the negative sign shows that it is negative. I'll leave a link on common amplifier topologies if you'd like to learn more. The OPA2344 is a single source amplifier and we want to amplify an AC signal. That means we'll have to set a non-zero reference between the 5V source and ground so that we can have a middle-point over which the signal can alternate. The best reference would obviously then be 2.5V since that gives the most leeway in either direction. This is done using two 10k resistors as a voltage divider connected to the non-inverting input of the amplifier.

Speaker Driver Circuit

The speaker is driven by the last amplifier left of the four amplifiers on this board. It basically works as a buffer between the Nano and the buzzer component itself. If you wanted to expand on the project you could possibly configure this amp to drive a sizable speaker. The amplifier is setup as a voltage follower. The difference between this setup and driving the buzzer directly from the Arduino is that the current comes from the regulated battery supply instead of the Arduino directly.

Further Reading

The inverting amplifier

Step 8: Recieving IR

To receive IR signals from a remote you will need the TSOP382 IR receiver module and an IR transmitting remote, you can even use an old TV remote, the more buttons the better. I had several remotes lying around including one that came with the sparkfun IR kit seen in the picture from step 1.

You can read up more on IR communication from here. There's a lot of information about the working principles, theory and application infrared signals to transmit information wirelessly. There is a lot of information out there but you don't need to understand it all to follow along here. Go through with that tutorial in the link to setup the IR sensor on the arduino and keep a record of the hex codes that you print from your remote. This programming code and the hex codes you record will be used in the final code for this project. I ended up using 8 buttons but you may have more or less buttons depending on your IR remote. It's not that important how many buttons you have but I recommend at least 4 for directional control of your rover.

Step 9: Motor Driver

The I/O pins on the Arduino aren't able to directly drive the motors. Motor drivers are commonly used for this purpose like the L293d chip. The driver I used is the TB6612FNG dual-motor which provides the added features of stopping and braking on top of being able to control the direction and speed of each motor. The driver module itself is from Sparkfun and it come's with an arduino library as well that you can check out on their website. I recommend following that tutorial if you'd like to test that the motors, the driver and the arduino library works.

Your driver module will likely come with the headers separately so you'll have to solder them yourself. Remember to solder the pins facing downwards so that you can easily plug it into a breadboard. You can setup the hardware with the lasercut plastic chassis and the wheels to watch it move or you could breadboard it and just observe the motors spinning and take note of their direction to make sure you've hooked it up correctly. You'll also have to solder some wires onto the motors. Make sure to leave enough length as the wire will need to reach from the motors at the bottom of the base to the motor driver mounted at the top of the upper base it will all go through the pre-cut holes though.

Step 10: Electrical Schematic

I designed the sensor board using Fritzing. The components are soldered onto a perfboard. I routed most of the connections to the pin header on the left hand side of the board. The other connections are for the microphone and the input to the buzzer driver circuit.

I made a separate file with the Arduino Nano and the motor connections so that things didn't get too messy. It includes the breadboard because that's how it's installed on the rover itself.

I'll leave the files here for you to download so that you can check the connections. Also note where the track breaks are on the board. You can use a stanley knife or a drill to break the track connections on the board.

Step 11: Full Structural Assembly and Wiring

Now that you have the circuit boards assembled it's time to gather all your components and your plastic chassis to put everything together.

The first step is to attach the motors and the castor wheel. Using the small 3x6mm bolts, fasten the castor wheel through the four front holes in the base. Then attach the motors with the brackets and the M3x30 bolts to the base as well, using the rectangular holes near the center of the base. I used hot glue to attach the wheels to the motors but I first had to drill the wheel shafts to increase the size of the inner diameter since the motor shaft was too big too fit into the wheel's. I then used double sided tape to attach the battery holder at the rear end of the base and the buzzer at the front end directly above the castor wheel. I then used a cable tie to fasten the sensor board to the base.

The next part is to install some components onto the upper base. First detach the power rails on each side of the breadboard. This is so that it will fit inside the tower piece. Then remove the tape covering on the bottom and place it on the upper base plate in-between the holes along the center. I then cut the LDR leads just a little shorter. After that cut some wire leads with enough length to reach from the LDR's to the pin header on the sensor board. Solder the wire onto the LDR pins and put some wire heat shrink over it but leave about 3mm space on the LDR lead because next you'll need to hot glue the LDR's to the front corners of the upper base. Use the pictures as a reference if anything seems confusing. There are two holes below the 4mm holes for the long bolts, those are for attaching the IR proximity sensors. Using the 10mm nylon stand-offs attach the sensor modules and bolt them on each side, use nuts as spacers if you're using longer bolts. Attach the upper base plate using the M4x55mm bolts and the front and back base plates. I soldered wires onto the power switch long enough to reach the breadboard. I then glued the power switch on the left rear corner of the upper base.

Before attaching the tower piece you'll first need to do most of the wiring. I didn't not anticipate how delicate this work would be, manipulating wires in a somewhat closed off area was challenging, I'd recommend using a pair of tweezers or something to help. Wire it according to the IO list and the schematic. You may also want to hold off putting the tower piece on until you've loaded and tested the code. Then come back to this section to finish it.

The tower piece is assembled quite easily, it's only fastened through the slot on the top piece with m3 bolts. Once the tower is put together it slots into the upper base through the four pre-cut slots and also fastened with m3 bolts. You will now be able to wire in the IR proximity sensors.

Step 12: Software

The software section of this project is rather simple and should provide enough examples for you to play around with and extend functionality to a whatever applications that you have in mind. I have written four separate programs that show how to implement the four different types of sensors. All the programs follow a similar procedure. All the necessary libraries are added and the pins and variables are declared. In the setup function, the I/O are configured. And in the loop section we read the sensors to determine the state and then execute an output operation with the motors depending on the state. Reading from more sensors at a time adds quite a bit more complexity so that may be an interesting challenge for you once you become comfortable with these.

The first program is obstacle avoidance with the IR proximity sensors. This program activates the motors on the rover depending on whether there an object is detected and which side it is on. you can adjust the range of the sensors on the physical modules.

//***************************************************************************************
//  Obstacle avoidance with IR prox sensors
//  Sketch 1
//
//  Description; Avoid obstacles using infrared proximity sensors
//
//  By JetLab
//
//
//***************************************************************************************
    
// This is the library for the TB6612 that contains the class Motor and all the functions
// Pins for all motor driver inputs, The PWM defines must be on PWM pins
#define STBY 8
#define AIN1 2
#define PWMA 10
#define AIN2 4
#define BIN1 5
#define PWMB 6
#define BIN2 7
    
//Define the possible states for the robot to be in
#define forward_state 0
#define reverse_state 1
#define turn_state_R  2
#define turn_state_L  3
#define idle_state    4
    
// these constants are used to allow you to make your motor configuration 
// line up with function names like forward.  Value can be 1 or -1
const int offsetA = 1;
const int offsetB = 1;
    
// Initializing motors.  The library will allow you to initialize as many
// motors as you have memory for.  If you are using functions like forward
// that take 2 motors as arguements you can either write new functions or
// call the function more than once.
Motor motor1_left  = Motor(AIN1, AIN2, PWMA, offsetA, STBY);
Motor motor2_right = Motor(BIN1, BIN2, PWMB, offsetB, STBY);
//
//Declare input pins
int LeftProx = 11;  
int RightProx = 12;
    
//Declare Output pin
int PWRBLOCK = 17;
int Buzzer = 16;
    
//Declare and initialize states
int currentState = forward_state;
int lastState = idle_state;
boolean LeftProxState = false;
boolean RightProxState = false;
    
void setup(){
  pinMode(LeftProx,INPUT);;
  pinMode(RightProx,INPUT);
  pinMode(Buzzer,OUTPUT);
  pinMode(PWRBLOCK,OUTPUT);
  digitalWrite(PWRBLOCK,LOW);
  digitalWrite(Buzzer,LOW);
    
  //The serial communication is optional if you'd like to view the state change on the serial monitor
  Serial.begin(9600);            
  Serial.println("The states");
    
void loop(){
  //Retrieves the digital input data from sensors
  readSensors();
  //Determine states from sensors
  currentState=getSensorState();
  //Activate Motors depending on the state
  Serial.println(currentState);
  int number = random(2,4);
  if(currentState!=lastState){
    lastState = currentState;
    switch(currentState){
      //case 1:Move forward
      case forward_state:
        //function to move forward
        forward(motor1_left,motor2_right,170);
        Serial.println(currentState);
      break;
      //case 2:Brake, reverse then change direction
      case idle_state:
        //Stop, reverse, turn left or right on randomly
        brake(motor1_left,motor2_right);
        delay(100);
        back(motor1_left, motor2_right, -180);
        delay(500);
        if(number==2){
          left(motor1_left, motor2_right, 150);
          delay(200);
        }
        else{
          right(motor1_left, motor2_right, 150);
          delay(200);
        }
        Serial.println(currentState);
      break;
      //case 3:Turn right
      case turn_state_R:
        //function to move to the right
        motor2_right.brake();
        delay(100);
        motor1_left.drive(150);
        Serial.println(currentState);
      break;
      //case 4:Turn Left
      case turn_state_L:
        //function to move to the left
        motor1_left.brake();
        delay(100);
        motor2_right.drive(150);
        Serial.println(currentState);
      break;
    }
   }
    
void readSensors(){
  //Note: Sensors are active LOW
  LeftProxState = !digitalRead(LeftProx);    
  RightProxState = !digitalRead(RightProx);
}
     
int getSensorState(){
  //If no object in front of the bot, move forward
  if(!LeftProxState&&!RightProxState){
    return forward_state;  
  }
  //If there's an object in front, beep and stop
  if(RightProxState&&LeftProxState){
    return idle_state;
  }
  //If there's an object on the left,turn right
  if(LeftProxState){
    return turn_state_R;
  }
  //If there's an object on the right, turn left
  if(RightProxState){
    return turn_state_L;
  }
}

The second program is the light following program which follows light sensed by the LDR's. The program can be changed from light following to light avoiding simply by removing the exclamation (!) in the digitalRead lines:

LeftPhotoState = !digitalRead(LPHOTO);

//*****************************************************************************************
//  Light Following Mode
//  Sketch 2
//
//  Description; Controls the robot to follow/avoid light and teigger when a sound is heard
//
// By JetLab
//
//*****************************************************************************************
    
// This is the library for the TB6612 that contains the class Motor and all the
// functions
#include <SparkFun_TB6612.h>
    
// Pins for all motor driver inputs, The PWM defines must be on PWM pins
#define STBY 8
#define AIN1 2
#define PWMA 10
#define AIN2 4
#define BIN1 5
#define PWMB 6
#define BIN2 7
    
//Define the possible states for the robot to be in
#define forward_state 0
#define turn_state_R  1
#define turn_state_L  2
#define idle_state    3
    
// these constants are used to allow you to make your motor configuration 
// line up with function names like forward.  Value can be 1 or -1
const int offsetA = 1;
const int offsetB = 1;
    
// Initializing motors.  The library will allow you to initialize as many
// motors as you have memory for.  If you are using functions like forward
// that take 2 motors as arguements you can either write new functions or
// call the function more than once.
Motor motor1_left  = Motor(AIN1, AIN2, PWMA, offsetA, STBY);
Motor motor2_right = Motor(BIN1, BIN2, PWMB, offsetB, STBY);
    
//Declare input pins
int LPHOTO = 19;  // set LPHOTO as pin 19
int RPHOTO = 18;  // set RPHOTO as pin 18
    
//Declare output pins
int BUZZER = 16;
int PWRBLOCK = 17;
    
int i; //for the startup buzzer loop
   
//Declare and initialize states
int currentState = forward_state;
int lastState = idle_state;
    
void setup() {
  //The serial communication is optional if you'd like to view 
  //the state change on the serial monitor, useful for debugging
  //Just uncomment all the serial communication lines
  //Serial.begin(9600);
  //Serial.println("States");
  pinMode(LPHOTO,INPUT);
  pinMode(RPHOTO,INPUT);
  pinMode(BUZZER,OUTPUT);
  pinMode(PWRBLOCK,OUTPUT);
      
  digitalWrite(BUZZER,LOW);
  digitalWrite(PWRBLOCK,LOW);
    
  // Startup sound, beep a bunch of times!
  for (i=1; i<5; i++)
  {
    tone(BUZZER, 1000, 100*i);
    delay(100*i);
  }</p><p>}
    
void loop() {
  // make sure the motors are inactive
  motor1_left.brake();        
  motor2_right.brake();
    
  currentState = readPhotosensors();
    
  runStates();
      
}
    
int readPhotosensors(){
  boolean LeftPhotoState;
  boolean RightPhotoState;
    
  digitalWrite(PWRBLOCK,HIGH);
  //allow time for settling before taking readings
  delayMicroseconds(20);        
    
  //Can be set to active HIGH or active LOW depending
  //on whether you want to follow light or avoid light
  LeftPhotoState = !digitalRead(LPHOTO);
  RightPhotoState = !digitalRead(RPHOTO);
      
  //If both sensors see light, then move forward
  if(LeftPhotoState&&RightPhotoState){
    return forward_state;
  }
  //If no sensor is active, then stop/don't move
  if(!LeftPhotoState&&!RightPhotoState){
    return idle_state;
  }
  //If the Left sensor sees light, then move right
  if(LeftPhotoState){
    return turn_state_R;
  }
  //If the Right sensor sees light, then move left
  if(RightPhotoState){
    return turn_state_L;
  }
  digitalWrite(PWRBLOCK,LOW);
}
    
void runStates(){
        
    switch(currentState){
      //case 1: Move forward
      case forward_state:
        noTone(BUZZER);
        digitalWrite(BUZZER,LOW);
        forward(motor1_left,motor2_right,180);
        //Serial.println(currentState);
      break;
      //case 2: Stop moving
      case idle_state:
        noTone(BUZZER);
        digitalWrite(BUZZER,LOW);
        brake(motor1_left,motor2_right);
        delay(100);
        //Serial.println(currentState);
      //case 3: Turn right
      case turn_state_R:
        digitalWrite(BUZZER,HIGH);
        motor2_right.brake();
        motor1_left.drive(150);
        tone(BUZZER, 300, 500);
        //Serial.println(currentState);
      break;
      //case 4: Turn Left
      case turn_state_L:
        digitalWrite(BUZZER,HIGH);
        motor1_left.brake();
        motor2_right.drive(150);
        tone(BUZZER, 300, 500);
        //Serial.println(currentState);
      break;  
    }
}

In the third program the rover simply waits to read an audio signal from the microphone amplifier circuit. During the reading time, the highest analog input value is recorded. If this value exceeds the predefined analog threshold value for the microphone then a motor demonstration is activated.

//*****************************************************************************************
//  Sound Activation Mode
//  Sketch 3
//
//  Description; Performs motor demonstration upon detection of a audio signal
//
// By JetLab
//
//*****************************************************************************************
    
// This is the library for the TB6612 that contains the class Motor and all the
// functions
#include <SparkFun_TB6612.h>
    
// Pins for all motor driver inputs, The PWM defines must be on PWM pins
#define STBY 8
#define AIN1 2
#define PWMA 10
#define AIN2 4
#define BIN1 5
#define PWMB 6
#define BIN2 7
    
// these constants are used to allow you to make your motor configuration 
// line up with function names like forward.  Value can be 1 or -1
const int offsetA = 1;
const int offsetB = 1;
    
// Initializing motors.  The library will allow you to initialize as many
// motors as you have memory for.  If you are using functions like forward
// that take 2 motors as arguements you can either write new functions or
// call the function more than once.
Motor motor1_left  = Motor(AIN1, AIN2, PWMA, offsetA, STBY);
Motor motor2_right = Motor(BIN1, BIN2, PWMB, offsetB, STBY);
    
int PBLOCK = 17;  // set PBLOCK as pin 17
int BUZZER = 16;  // set BUZZER as pin 16
int MICINP = 14;    // set MICINP as pin 14
    
int MICTHRESH = 560; // set microphone trigger threshold (possible values 0-1023)
    
int i; //for the startup buzzer loop
int MaxVal;
    
void setup() {
      
  // set outputs
  pinMode(BUZZER, OUTPUT);
  pinMode(PBLOCK, OUTPUT);
  Serial.begin(9600);
    
  digitalWrite(BUZZER,LOW);
    
  // Startup sound, beep a bunch of times!
  for (i=1; i<5; i++)
  {
    tone(BUZZER, 1000, 100*i);
    delay(100*i);
  }
      
      
}
    
void loop() {
      
  motor1_left.brake();        // turn off both motors 
  motor2_right.brake();  
      
  MaxVal = ListenToMic();
  Serial.println(MaxVal);
  //If the largest voltage detected exceeds the threshold then run through the demo
  if(MaxVal > MICTHRESH){
    //Run a beeper that alternates frequencies
    for (i=0; i<5; i++){
        tone(BUZZER, 1500, 1000);
        tone(BUZZER, 900,  1000);
    }
        
    MotorDemo();  
  }
      
}
    
    
int ListenToMic(){
  // listen to the microphone for ~500 ms
  int  maxval = 0;
  int val;
  for (i=1; i<500; i++)
  {
    val = analogRead(MICINP);
    if (val > maxval)
      maxval = val;
    delay(1);
  }
  return maxval;
}
    
void MotorDemo(){
    
  //Jitter for a little bit
   motor1_left.drive(-255,100);
   motor2_right.drive(255,100);
   brake(motor1_left, motor2_right);
   delay(50);
   motor1_left.drive(255,100);
   motor2_right.drive(-255,100);
   brake(motor1_left, motor2_right);
   delay(50);
   motor1_left.drive(-255,100);
   motor2_right.drive(255,100);
   brake(motor1_left, motor2_right);
   delay(100);
    
   //Move forward
   forward(motor1_left, motor2_right, 210);
   delay(1000);
    
  //Spin right then left
   motor1_left.drive(255,600);
   motor2_right.drive(-255,600);
   brake(motor1_left, motor2_right);
   delay(100);
   motor1_left.drive(-255,600);
   motor2_right.drive(255,600);
   brake(motor1_left, motor2_right);
   delay(100);
    
   //Move backwards
   back(motor1_left, motor2_right, -210);
   delay(1000);
    
}

The last program allows for manual control with the Infrared transmitter remote. This code is configured for the IR remote I got with the IR kit from Sparkfun. The remote has 4 buttons for direction, a center button and 'A', 'B' and 'C' buttons. It also has a power button that I'm not using, that's nine buttons in total. You can add or remove button cases and change the functionality as you want, the operating principle remains the same.

//***************************************************************************************
//  IR control with sparkfun remote
//  Sketch 4
//
//  Description; Recieve IR signal to control the rover
//
//  By JetLab
// // //*************************************************************************************** #include <SparkFun_TB6612.h> // This is the library for the TB6612 that contains the class Motor and all the functions #include <IRremote.h> // This is the library for the IR reciever that contains the IR functions // Pins for all motor driver inputs, The PWM defines must be on PWM pins #define STBY 8 #define AIN1 2 #define PWMA 10 #define AIN2 4 #define BIN1 5 #define PWMB 6 #define BIN2 7 // these constants are used to allow you to make your motor configuration // line up with function names like forward. Value can be 1 or -1 const int offsetA = 1; const int offsetB = 1; // Initializing motors. The library will allow you to initialize as many // motors as you have memory for. If you are using functions like forward // that take 2 motors as arguements you can either write new functions or // call the function more than once. Motor motor1_left = Motor(AIN1, AIN2, PWMA, offsetA, STBY); Motor motor2_right = Motor(BIN1, BIN2, PWMB, offsetB, STBY); //Initialize the input pins int RECV_PIN = 9; int LPHOTO = 19; int RPHOTO = 18; int MICINP = 14; //Initialize the output pins int PWRBLOCK = 17; int BUZZER = 16; int MICTHRESH = 560; // set microphone trigger threshold (possible values 0-1023) int i; int val; int maxval; IRrecv irrecv(RECV_PIN); decode_results results; void setup() { // set outputs pinMode(BUZZER, OUTPUT); pinMode(PWRBLOCK, OUTPUT); digitalWrite(BUZZER,LOW); // set inputs pinMode(LPHOTO, INPUT); pinMode(RPHOTO, INPUT); Serial.begin(9600); Serial.println("Enabling IRin"); irrecv.enableIRIn(); // Start the receiver Serial.println("Enabled IRin"); // Startup sound, beep a bunch of times! for (i=1; i

Step 13: Testing and Operation

Between those four programs you'll have used all the sensors and actuators that we've configured in this project. The only library that you needed to install was for the motor driver, make sure that it was installed correctly. If they all run smoothly then all the hardware should be hooked up just fine. Check that there are no shorts or open circuits, those may be the most obvious and common problems but are easily fixed. If some things are not working you can always go back to the schematic to check that the connections are correct.

If you've followed along with the instructions and followed through with the build then you should have your very own rover platform with which you can continue to build on, improve and use to learn more about electronics and programming. I hope you enjoyed this instructable and that it helps you with your project, even just a small way.