Compact – a small Arduino Robot


I made a chassis plate on my CNC and built a robot using an Arduino Duemilanove and the Robot Builder’s Shield.

Isn’t it cute? Here is more info about it:

Compact – a Small Arduino Robot

About Gabriel (Ro-Bot-X)

Robots, nature, bees, and gardening, how do they mix together? After too much indoor activities one needs to get out and breathe! Harvest natural energy and create a little paradise. And ask the robots to help, of course.
This entry was posted in Arduino and tagged , , . Bookmark the permalink.

29 Responses to Compact – a small Arduino Robot

  1. Bao Tran says:

    Sir,
    I assemble the RBS (follow the RBS manual), connect the Arduino and upload the code (sample program for compact robot). At first the servo begin to scan (eg. from 0 – 180 deg) then it stop, and robot start moving forward and keep moving forward. The robot would not stop or reverse even the sharp range sensor was covered with hand or paper. etc…PLEASE HELP. Thank you so much.

    • Ro-Bot-X says:

      There is an error on the IR_Pin definition, please change this line:
      #define IR_Pin 14 // digital pin 14 (analog pin 0)
      with this:
      #define IR_Pin 0 // analog pin 0

      Sorry about that…

      • Bao Tran says:

        Sir,
        I changed the code to #define IR_Pin 0 // analog pin 0.
        Robot still behave the same, the servo begin to scan (eg. from 0 – 180 deg) then it stop, and robot start moving forward and keep moving forward. The robot would not stop or reverse even the sharp range sensor was covered with hand or paper. etc…WOULD YOU PLEASE HELP or link me to the program that make the robot work like the video on this web site Let’s Make Robot #robot_em_video.
        Thank you so much.

  2. Ro-Bot-X says:

    First I suggest to remove the jumpers J1 and J2 so the motors and the servo do not get power. Then open up the Arduino Serial Monitor and watch to see the sensor values. You need to have the USB cable connected to the Arduino board to be able to see the values in the Serial Monitor.

    If you don’t see any values, it means that your sensor is not plugged correctly, that might explain why the robot does not behave as it is supposed to. So, make sure that the sensor is plugged to the A0 connector, with the black wire towards the exterior of the board, the red wire in the middle and the white wire towards the A0 mark on the board.

    If you see the distance values correctly, then perhaps there is some other error in the program, you will need to post the code so I can look over it to correct it.

    But I suspect the sensor is the cause of all your problems.

    • Bao Tran says:

      Sir,
      YES, You are right. The GP2D12 was not plugged correctly.
      Robot can detect the object, and do turn left, turn right, move forward.
      But can not do reverse (move backward), and it stuck in the corner, until the battery ran out! attached below is the program I copy from your site. PLEASE HELP.

      Program sample.
      Here is a sample program used on my Compact robot:

      // Compact, a small Arduino (Duemilanove) robot
      // 2 Pololu micro motors 100:1 and small wheels,
      // one HXT900 micro servo, one Sharp IR sensor,
      // 2 AAA battery holders, the Robot Builder’s Shield
      //
      // Arduino pinout:
      //
      // Shield Funct Arduino ATmega168 Arduino Funct Shield
      // +—–\/—-+
      // Reset 1| PC6 PC5 |28 D19 A5 SCL
      // Rx D0 2| PD0 PC4 |27 D18 A4 SDA
      // Tx D1 3| PD1 PC3 |26 D17 A3
      // Int0 D2 4| PD2 PC2 |25 D16 A2
      // Int1 D3 5| PD3 PC1 |24 D15 A1
      // M1B D4 6| PD4 PC0 |23 D14 A0 IR sensor
      // 7| VCC GND |22
      // 8| GND AREF |21
      // Xtal 9| PB6 AVCC |20
      // Xtal 10| PB7 PB5 |19 D13 SCK LED
      // M1A OC0B D5 11| PD5 PB4 |18 D12 MISO Pan servo
      // M2A OC0A D6 12| PD6 PB3 |17 D11 OC2A MOSI
      // M2B D7 13| PD7 PB2 |16 D10 OC1B
      // D8 14| PB0 PB1 |15 D 9 OC1A
      // +———–+
      //

      #include

      //Inputs/outputs
      #define Motor_1_PWM 5 // digital pin 5 // Right Motor
      #define Motor_1_Dir 4 // digital pin 4
      #define Motor_2_PWM 6 // digital pin 6 // Left Motor
      #define Motor_2_Dir 7 // digital pin 7
      #define IR_Pin 14 // digital pin 14 (analog pin 0)
      #define PanPin 12
      #define LedPin 13

      #define SR 1 //Sharp Short Range sensor
      #define MR 2 //Sharp Medium Range sensor
      #define LR 3 //Sharp Long Range sensor
      #define center 90

      //Variables
      byte dir=0;
      byte speed1=250;
      byte speed2=255;
      int turn90=110;
      int turn45=55;
      int straight=500;
      int stopTime=200;
      int IRdistance=0;
      int treshold=20; //20cm min distance
      Servo Pan;

      //————————————————————————-

      void setup() {

      // set motor pins as output and LOW so the motors are braked
      pinMode(Motor_1_PWM, OUTPUT);
      pinMode(Motor_1_Dir, OUTPUT);
      pinMode(Motor_2_PWM, OUTPUT);
      pinMode(Motor_2_Dir, OUTPUT);
      Stop();
      Pan.attach(PanPin);
      Pan.write(center); //90 degrees, looking straight ahead
      StepDelay();
      pinMode(LedPin, OUTPUT);
      digitalWrite(LedPin, LOW);
      Forward();
      }
      void loop(){
      Drive();
      }

      //————————————————————————-

      void Drive(){
      IRdistance=Read_Sharp_Sensor(MR, IR_Pin);
      Serial.print(“IRdistance “);
      Serial.println(IRdistance);
      if (IRdistance<10){
      Stop();
      StepDelay();
      TurnAround();
      }
      if (IRdistance<treshold){
      Stop();
      StepDelay();
      Avoid();
      Forward();
      }
      delay(50);
      }
      void TurnAround(){
      Reverse();
      Pan.write(center);
      StepDelay();
      Stop();
      Left();
      delay(turn90);
      delay(turn90);
      Stop();
      StepDelay();
      Forward();
      }
      void Avoid(){
      int prev=0;
      dir=2;
      for (byte i=0; iprev){
      dir=i;
      prev=IRdistance;
      }
      }
      Pan.write(center);
      StepDelay();
      switch (dir){
      case 0:
      Right();
      delay(turn90);
      Stop();
      StepDelay();
      break;
      case 1:
      Right();
      delay(turn45);
      Stop();
      StepDelay();
      break;
      case 2:
      Forward();
      break;
      case 3:
      Left();
      delay(turn45);
      Stop();
      StepDelay();
      break;
      case 4:
      Left();
      delay(turn90);
      Stop();
      StepDelay();
      break;
      }
      delay(500);
      }

      // Read Sensors
      int Read_Sharp_Sensor(byte model, byte pin) {
      int value = 0;
      value = analogRead(pin);
      switch (model) {
      case SR: //short range, aka GP2D120 (4-30cm)
      return (2914/(value+5))-1;
      break;
      case MR: //medium range, aka GP2D12 (10-80cm)
      return 5*1384.4*pow(value,-.9988); //multiplied by 5, different sensor
      break;
      case LR: //long range, aka GP2Y0A02YK (20-150cm)
      return 11441*pow(value,-.9792);
      break;
      }
      }
      void StepDelay() {
      for (byte t=0; t<10; t++){
      delay(20);
      }
      }

      //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

      void Forward(){
      digitalWrite(Motor_1_Dir, LOW); // forward
      digitalWrite(Motor_2_Dir, LOW); // forward
      analogWrite(Motor_1_PWM, speed1); //
      analogWrite(Motor_2_PWM, speed2); //
      return;
      }
      void Reverse(){
      digitalWrite(Motor_1_Dir, HIGH); // reverse
      digitalWrite(Motor_2_Dir, HIGH); // reverse
      analogWrite(Motor_1_PWM, 255-speed1); //
      analogWrite(Motor_2_PWM, 255-speed2); //
      return;
      }
      void Right(){
      digitalWrite(Motor_1_Dir, HIGH); // reverse
      digitalWrite(Motor_2_Dir, LOW); // forward
      analogWrite(Motor_1_PWM, 255-speed1); //
      analogWrite(Motor_2_PWM, speed2); //
      return;
      }
      void Left(){
      digitalWrite(Motor_1_Dir, LOW); // forward
      digitalWrite(Motor_2_Dir, HIGH); // reverse
      analogWrite(Motor_1_PWM, speed1); //
      analogWrite(Motor_2_PWM, 255-speed2); //
      return;
      }
      void Stop()
      {
      digitalWrite(Motor_1_PWM, LOW);
      digitalWrite(Motor_1_Dir, LOW);
      digitalWrite(Motor_2_PWM, LOW);
      digitalWrite(Motor_2_Dir, LOW);
      return;
      }

  3. Ro-Bot-X says:

    Glad the sensor is working now.

    You have to play a little with the code, for the moment this code is the unmodified version from the PDF file, that still has the wrong definition for the IR_Pin. So I have no idea what you actually did to your code. But here’s what you can do: in the Drive() function, right after the distance is read, the code looks if the distance is less than 10 cm, if it’s true, stops the robot, then calls the TurnAround() function. The TurnAround() function drives the robot in reverse, then after a small delay, stops and turns left 90 degrees 2 times, to achieve a 180 degree turn. So:
    – you can play with the critical distance (change the 10 value to something you think works best for your robot)
    – you can add more delay after the Reverse() command
    – you need to adjust the turn delay times, as your robot might turn slower or faster than mine.

    Hope this clears some things in the code.

    • Bao Tran says:

      Sir,
      I change the Irdistance<14
      Add 2 delay after Reverse() function.
      …void TurnAround(){
      Reverse();
      StepDelay();
      StepDelay();
      Pan.write(center);
      StepDelay();

      The robot is still helpless, stuck at the corner and can not move backward.
      I do not know how to adjust the turn delay times?
      Please HELP me.
      Thank you so much

      • Ro-Bot-X says:

        Well, there are some variables called turn90 and turn45 that represent miliseconds. In the code, you have delay(turn90), so you need to adjust the variables so your robot actually turns 90 degrees. After you adjust the turn90 variable, just divide it by 2 and write that to the turn45 variable. Here is a function that makes the robot drive in a square pattern:

        first, place this line right after the definition of the other variables: int driveTime=2000;

        void square(){
        for (byte i=0;i<4;i++){
        Forward();
        delay(driveTime);
        Stop();
        delay(stopTime);
        Right();
        delay(turn90);
        Stop();
        delay(stopTime);
        }
        }

        Call this function in your loop() and nothing else.

        The robot will drive forward for 2 seconds and turn right, 4 times. Adjust the turn90 variable until your robot drives in a perfect square. After this works, replace all StepDelay() functions with a delay(driveTime). You may also need to adjust the driveTime value to something that works for your robot.

  4. Don McRae says:

    I have been following these comments I am still at the test the Sharp IR. I verfied that the IR is hooked up right and that it is getting 4.5 volts. with the USB cable hooked up and the Serial monitor on I don’t get numbers I get something that looks like small letter y ‘s p’s that look like b’s and p’s together. But no numbers. I can control the string of characters by moving a piece of white paper in front of the IR but no numbers that would work in a spread sheet. I did verify that pin 0 is hooked to pin 23 on the Atmega 168. I have both GP2D15 02 and GP2D120 3Y tested both with a volt meter and they seem to read distance. I am not sure what to do next. Any suggestions?

    • Ro-Bot-X says:

      The fact that you have funny letters and no numbers in the Serial Monitor means the baud rates do not match. You have to set both to the same value to work. Make sure that in your code in the setup() function you have this line:
      Serial.begin(9600);
      Then, in the Serial Monitor window, look in the bottom right corner and you’ll find a drop down list that should say “9600 baud”. If one of these values is different, change it to match the other one.

      • Don McRae says:

        The bot works!! By adding that Serial.begin(9600) did it. Thanks for the help!! Will have to work with the back up and turn timing. but it works.
        Not clear on how to send photos.

      • Ro-Bot-X says:

        Glad it works! To send pictures, either upload them to Flickr or something like that, or email them to me and I’ll put them up here for you.

        Thanks!

  5. Don McRae says:

    Here is a pic of my bot:

  6. Don McRae says:

    http://www.flickr.com/photos/18939304@N08/5476664891/
    This is a movie of my bot with your board controlling it. It is the best I can do. U tube was too hard. Hope this shows what you wanted to see.

  7. Don McRae says:

    HI I was wondering when you will have the uservotino kits available. I have a Robotic arm that would work as a compact controller.
    I was thinking is there a way to protect my or keep my little Xbot from falling off a table top. He can see ahead but can’t see a drop off.

  8. Ro-Bot-X says:

    Don, at the moment the uServotino boards have a little flaw (the blue capacitors are too close to the crystal case, so they have to be bended and the crystal soldered higher on the board so it does not touch the capacitor leads), if you can live with that, I can send you a kit for $21.

    To keep the bot from falling off the table, you need a photo reflective sensor, usually the same used for line following. This sensor is a perfect example, and it has the same pinout as a regular servo: http://www.pololu.com/catalog/product/958
    Since it is an analog sensor, you attach it to an analog pin and you have to experiment with the readings to see what is an appropriate threshold to detect the edge of the table. You can also get the female-female cables: http://www.pololu.com/catalog/product/779

  9. Don McRae says:

    I think that I can live with that mismatch if you can send me a photo of what it should look like. I think once the board is here and the parts are put in place I can make it work.
    In the mean time I will check out the reflective sensor might need a little help with the software though.

  10. Ro-Bot-X says:

    Ok then, I’ll send you a Paypal request for $21 + 3 for shipping and handling. And I can help out with the software too. I think I have the digital version of that sensor, I got 3 of them for line following. Over the weekend I’ll take some readings to see how well they detect the edge of the table.

    Cheers!

  11. Don McRae says:

    I ordered the analog senser. Did you have a chance to check your senser?

  12. Michel Laganiere says:

    HI, I will to build your Compact – Arduino small Robot , but if I understand well I have to build your Robot builder shield before ?

    On your store your have two Robot builder shield kit ? whitch one is the good one for this project ? regular or V2 ?

    Do you offer a ready ( plug and play ) version ? if yes how much is it ( wt shipping ) to Montreal, Quebec J5Y3W8 ?

    =============

    Question 2, on this ro-bot-X blog , you explain a error on the code

    Please can you send to me your shematic for connection and a final correct version of the code by reply this email ( if possible no zip ) please on Word page or ..

    Excuse my dummy question’s because I’m a junior in robotic and I will start with your fantastic Robot project

    Thank you very much for reply

    Michel Laganière

    laganieremichel@sympatico.ca

    • Ro-Bot-X says:

      Hi Michel,

      I sell the RBS as a bare board or as a kit you can solder yourself, so you can do some of the work and save the money for other robotic parts. If you want to get an assembled RBS, go to Creatron Inc website and order from them, they will tell you how much is the shipping. Version 2 is the one they carry, and the one I recommend because it has the onboard power switch that is very handy.

      Regarding the code question, I will send you a revised version so you can start easy, but you have to learn Arduino language (C++) by following the (Adafruit) tutorials I linked on my store to better understand what each line of code does and to be able to develop the code further for your needs.

      Cheers and good luck with your project!

  13. Michel Laganiere says:

    Thank You Very Much !!!

    Please dont forget to send to me a revised version of the code !!

    laganieremichel@sympatico.ca

    Regards
    Michel

  14. Michel Laganiere says:

    Hello, I’m now ready to start to build my Robot !
    Please can you share with me the right code for your fantastic small Arduino Robot ?

    Thanks in advance !!!

    Regards
    Michel, Canada

    laganieremichel@sympatico.ca

  15. Michel Laganiere says:

    Thank you very much !!!!

    Cheers !!!!!

    Michel

  16. Pedro says:

    I. I have a problem with de code . in this line for (byte i=0; prev) it appears the following error “expected ´;´before ‘)’ token. can you help me?

    • Gabriel (Ro-Bot-X) says:

      The code is incomplete. It seems that you lost quite a chunk of code when you copy-pasted. Or is it WordPress fault? I tried to write the code correctly but it got chopped off too. I wonder where is the problem…

      Anyway, without seeing the code exactly how it appears in your Arduino IDE I can’t help I’m afraid. You probably missed either a semicolon or a curly bracket somewhere that’s why the compiling error appears.

      Write me a message on Compact’s page on LMR. http://letsmakerobots.com/node/23022

      Cheers!

  17. michel says:

    Hi , the code is ok but check your motor type ( the number of turn in a minite) you have to ajusts the temps on the code for a correct run!

Leave a reply to Michel Laganiere Cancel reply