My first robot

Hallo LMR community!

After following your great projects for over one year, it's time to submit my first robot. As long as I can remember, I was always been interested in robots. Thanks to arduino now I'm able to build my own robots.

Step 1

It is a simple rover that uses an ultrasonic sensor on a servo to detect obstacles, and two continuous rotation servos to drive. The chassis is made from aluminium.

 

Step 2
- added yoghurt cup as body to protect robot's life from my little son ;-)
- added a accu pack with charging jack
- changed the the ultrasonic sensor on the servo agains two static ultrasonic sensors
- added a red/green LED's as eyes for signal the obstacles state
- added a audio shield for arduino (http://www.elv.de/audio-shield-fuer-arduino-asa1-bausatz.html) with 2 8ohm speakers
- added a ir proximity sensor as floor sensor
Front view:
- R/G LEDs behind the eyes
- 2 ultrasonic sesors
- 1 ir sensor at the bottom
Rear view:
- power switch on the top (on-postion for robot driving off-position for charging)
- charging jack
Top view:
- the USB socket is behind a cover, hence comfortable USB-connection is possible
Inner view:
I'll try to upload a video with the speaking demo of the robot.
UPDATE 2014-06-28
I've uploaded the video of the sound test. You'll also see the crash marks of the crash between my son and the robot.

Navigate around and speak


This is a companion discussion topic for the original entry at https://community.robotshop.com/robots/show/my-first-robot-31

NICE!

maybe I need to go this route to start instead of those omni wheels lmao   very cool robot.

That is certainly a cool

That is certainly a cool one, especially with the protective cover :slight_smile: I really like that big wheels.

But why you want to use two speakers, is one not enough?

This one has the thing I

This one has the thing I enjoy: some personnality!

The yoghurt cup is a great idea.

Thanks for your positive

Thanks for your positive comments! I like you guys of the LMR community :slight_smile:

The speakers are inside the cover, hence the loudness is not really sufficient.

Pretty cool! I want one too

Pretty cool! I want one too and let it run around the kitchen table :smiley:

Wow!

My goodness that is very impressive! I love the R2-D2 noises!

What servos do you use for this robot?

Thank you in advance, and again, very impressive work!

Hallo Diddi8011,na der ist

Hallo Diddi8011,

na der ist ja niedlich, sehr schön!

Würdest du dein Code auch zugänglich machen? Würde mich sehr freuen!

Viele Grüße

mario

 

Hallo Mario,hier ist der

Hallo Mario,

hier ist der chaotische Code. Dieser funtioniert wenn du auch aufgeführten libraries benutzt. AudioShield.h ist von ELV, die andereren müssten Standard sein.

Der Code ist etwas komlexer, weil ich eine Möglichkeit wollte, jederzeit über die serielle Schnittstelle das Kommando über den Roboter zu übernehmen. Diese funtioniert auch, ich habe es aber in meinem Beitrag nicht vorgestellt. Mit dem Befehl <99> wird der autonome Modus beendet und man den Roboter mit <1>, <2>, <3>, <4> steuern.

//Inputs/outputs
#include <SD.h>
#include <SPI.h>
#include <AudioShield.h>
#include <stdio.h>

#define L1 2
#define L2 9
#define LPWM 10
#define RPWM 45
#define R1 42
#define R2 43

long randNumber;
char string1[10];
char inData[10];
int index;
boolean started = false;
boolean ended = false;
unsigned long time;

byte Lspeed=200;
byte Rspeed=200;
int left, right, i, k, bottomState;
int LGled = 30;
int LRled = 31;
int RGled = 32;
int RRled = 33;
int bottomSensor = 21;
int Dur = 400;
int danger = 30;
int counter = 0;

typedef void (FunctionPointer) ();
// Declare looping actions function names, declared lower.
FunctionPointer xActions[] = {loopActionA,loopActionB,loopActionC};
// Define actions status flags. Set to 1 to auto execute a start.
int xActionsFlags[] = {1,1,0};
int xActionsCount = sizeof(xActions);

void xActionTrigger(int id=0, int action=0) {
  // The id represent it’s position in the flags array.
  // Action 1 = executed, 0 not.
  xActionsFlags[id] = action;
}

// Exectute all loop functions.
void xDoActions() {
// Execute all looped function.
for(unsigned int j=0; j < xActionsCount; j++) {
    if( xActionsFlags[j] == 1 ) { // Execute the action if.
    xActionsj; // Call the related loop action.
    }
    }
}
// LOOPING FUNCTIONS

void loopActionA() {
        // read serial data between < >
    if (Serial.available() > 0) {
      char aChar = Serial.read();
      if(aChar == ‘<’)
      {
        started = true;
        index = 0;
        inData[index] = ‘\0’;
      }
      else if(aChar == ‘>’)
      {
        ended = true;
      }
      else if(started)
      {
        inData[index] = aChar;
        index++;
        inData[index] = ‘\0’;
      }
   
    if(started && ended)
    {
      char Pin[4]={inData[0],inData[1]};
      char Value[4]={inData[2],inData[3],inData[4]};
      // Convert the string to an integer
      int inPin = atoi(Pin);
      int inValue = atoi(Value);
      //Serial.print("command:  ");
      Serial.println(inPin);
      switch (inPin){
       case 1:
        Serial.println(“command forward”);
        goForward();
        delay(200);
        Stop();
        break;
      case 2:
        Serial.println(“command backward”);
        goBackward();
        delay(200);
        Stop();
      break;
      case 3:
        Serial.println(“command left”);
        leftSpin(150);
        Stop();
      break;
      case 4:
        Serial.println(“command right”);
        rightSpin(150);
        Stop();
      break;
      case 8:
        Serial.println(“command speak”);
        randNumber=random(1,17);
        if (randNumber > 10) sprintf(string1, “0%d.mp3”,randNumber);
        if (randNumber < 10) sprintf(string1, “00%d.mp3”,randNumber);
        sound(string1);
      break;
      case 11:
        Serial.println(“auto mode”);
        Stop();
        xActionTrigger(1,1);
        xDoActions();
      break;
      case 99:
        Serial.println(“manual mode”);
        Stop();
        xActionTrigger(1,0);
        xDoActions();
      break;
      }
    }
}
}

void loopActionB() {
    // autonomus drive
    bottomState = digitalRead(bottomSensor);
    if (bottomState == LOW){
    left=Sensor( 24 , 25 );
    delay(40);
    right=Sensor( 26 , 27 );
    delay(40);
    if (left > danger && right > danger)
    {
      goForward();
      counter = 0;
      digitalWrite(LGled,1);
      digitalWrite(RGled,1);
      digitalWrite(LRled,0);
      digitalWrite(RRled,0);
    }
    else if (left < 15 || right < 15)
    {
      Stop();
      digitalWrite(LRled,1);
      digitalWrite(RRled,1);
      digitalWrite(LGled,0);
      digitalWrite(RGled,0);
      randNumber=random(1,17);
      if (randNumber > 10) sprintf(string1, “0%d.mp3”,randNumber);
      if (randNumber < 10) sprintf(string1, “00%d.mp3”,randNumber);
      sound(string1);
      goBackward();
      delay(1000);
      scan();
   }
    else if (left < danger || right < danger)
    {
      counter++;
      digitalWrite(LGled,1);
      digitalWrite(RGled,1);
      digitalWrite(LRled,1);
      digitalWrite(RRled,1);
      Stop();
        if (left>right && left>danger) {
    //Serial.println(“left is better”);
    leftSpin(Dur);
  }
  else if (right>left && right>danger){
    //Serial.println(“right is better”);
    rightSpin(Dur);
  }
  else if (right<danger && left<danger){
    if (right=left || left>right){
      goBackward();
      delay(500);
      leftSpin(Dur); 
    }
    else if (right>left){
      goBackward();
      delay(500);
      rightSpin(Dur);
    }
      if (counter = 8){
      Stop();
      sound(“013.mp3”);
      goBackward();
      }
    }
    }
    else {
    digitalWrite(LRled,1);
    digitalWrite(RRled,1);
    digitalWrite(LGled,0);
    digitalWrite(RGled,0);
    falling(); 
    }
    }
}

void loopActionC() {
    // Do something…
}

int Sensor(int trigPin, int echoPin)
{
  int duration;
  pinMode(trigPin, OUTPUT);
  pinMode(echoPin, INPUT);
  digitalWrite(trigPin, LOW);
  delayMicroseconds(2);
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(5);
  digitalWrite(trigPin, LOW);
  duration = pulseIn(echoPin, HIGH);
  duration = duration / 58;
  return duration;
}

void ForwardR(){
  digitalWrite(RPWM,Rspeed);
  digitalWrite(R1,HIGH);
  digitalWrite(R2,LOW);
}
void ForwardL(){
  digitalWrite(LPWM,Lspeed);
  digitalWrite(L1,HIGH);
  digitalWrite(L2,LOW);
}
void BackwardR(){
  digitalWrite(RPWM,Rspeed);
  digitalWrite(R1,LOW);
  digitalWrite(R2,HIGH);
}
void BackwardL(){
  digitalWrite(LPWM,Lspeed);
  digitalWrite(L1,LOW);
  digitalWrite(L2,HIGH);
}
void Stop(){
  digitalWrite(RPWM,0);
  digitalWrite(LPWM,0);
  digitalWrite(R1,HIGH);
  digitalWrite(R2,HIGH);
  digitalWrite(L1,HIGH);
  digitalWrite(L2,HIGH);
}

void goForward(){
  ForwardR();
  ForwardL();
}

void goBackward(){
  BackwardR();
  BackwardL();
}
void leftSpin(int spinDur){
  BackwardL();
  ForwardR();
  delay(spinDur);
}
void rightSpin(int spinDur){
  BackwardR();
  ForwardL();
  delay(spinDur);
}

void falling (){
   goBackward();
   delay(400);
   BackwardL();
   ForwardR();
   delay(800);
}

void scan(){
  if (left>right && left>danger) {
    //Serial.println(“left is better”);
    leftSpin(Dur);
  }
  else if (right>left && right>danger){
    //Serial.println(“right is better”);
    rightSpin(Dur);
  }
  else if (right<danger && left<danger){
    if (right=left || left>right){
      goBackward();
      delay(500);
      leftSpin(Dur); 
    }
    else if (right>left){
      goBackward();
      delay(500);
      rightSpin(Dur);
    }
  }
}

void sound(const char
mpFile){
  //Puffer für MP3-Decoder anlegen
  //MP3-Decoder erwartet Daten immer in 32 Byte Blöcken
  unsigned char buffer[32];
  //Datei öffnen und abspielen 
  if( File SoundFile = SD.open(mpFile, FILE_READ) )
  {
    //Blaue LED während dem Abspielen leuchten lassen
    LED_BLUE_ON;
    //Verstärker einschalten
    VS1011.UnsetMute();
    //Datei bis zum Ende abspielen
    while( SoundFile.available() )
    {
      //Puffer mit Daten aus der Datei füllen
      SoundFile.read( buffer, sizeof(buffer) );
      //Daten aus Puffer an MP3-Decoder senden
      VS1011.Send32( buffer );
    }
    //Internen Datenpuffer vom MP3-Decoder mit Nullen füllen
    //damit sicher alles im Puffer abgespielt wird und Puffer leer ist
    //MP3-Decoder besitzt 2048 Byte großen Datenpuffer
    VS1011.Send2048Zeros();
    //Verstärker deaktivieren
    VS1011.SetMute();
    //Blaue LED nach dem Abspielen ausschalten
    LED_BLUE_OFF;
    //Datei schliessen
    SoundFile.close();
  }
  else
  {
    //Datei nicht gefunden
    //Rote LED für 2s leuchten lassen
    LED_RED_ON;
    delay( 2000 );
    LED_RED_OFF;
  }
}

void blinkyEyes(){
  for (int i=0; i<3; i++){
  digitalWrite(LGled,1);
   digitalWrite(RGled,1);
   delay(350);
   digitalWrite(LGled,0);
   digitalWrite(RGled,0);
   delay(200);
  }
}
//--------------------------------------------------------------------------
void setup() { 
  // set motor pins as output and LOW so the motors are braked
  Serial.begin(9600);
  pinMode(L1,OUTPUT);
  pinMode(L2, OUTPUT);
  pinMode(LPWM, OUTPUT);
  pinMode(RPWM, OUTPUT);
  pinMode(R1, OUTPUT);
  pinMode(R2, OUTPUT);
  pinMode(LGled, OUTPUT);
  pinMode(LRled, OUTPUT);
  pinMode(RGled, OUTPUT);
  pinMode(RRled, OUTPUT);
  pinMode(bottomSensor, INPUT);
  //digitalWrite( 12 , LOW );
  //pinMode(LedPin, OUTPUT);      
  //digitalWrite(LedPin, LOW);
   xActionTrigger(0,1); // First action active
   xActionTrigger(1,1); // Second action active
     //Einrichten der LEDs
  pinMode(LED_BLUE, OUTPUT);
  pinMode(LED_RED, OUTPUT);
  //beide LEDs ausschalten
  LED_BLUE_OFF;
  LED_RED_OFF;
  //SD-Karte initialisieren
  //SD_CS als parameter übergeben, da hier ChipSelect anders belegt
  if( SD.begin( SD_CS ) == false )
  {
    // Programm beenden, da keine SD-Karte vorhanden
    return;
  }
  //MP3-Decoder initialisieren
  VS1011.begin();
  blinkyEyes();
  sound(“010.mp3”);
  //attachInterrupt(2, falling, RISING);
}

void loop()
{
    xDoActions();
}