Arduino mini robot platform

A simple robot using a modified SMARS body and an arduino mini pro

This project is one of the two platforms i intent to use  for testing ideas on robot navigation and sensors.

In this version a modified SMARS body was used. So what the hell is this smars  i  hear you say huh?

SMARS acronym of “Screwless/Screwed Modular Assemblable Robotic System” is a simple robot designed to the educational field  as noted from its creator in thingiverse    .
That means that you can create a robot chassis using or remixing the components found on that page. So basicaly i used a remix of SMARS found here and i actualy reversed its direction and added some parts for a custom holder for a small powerbank

The bumper was also custom designed and the hinge that holds it. All other parts where found in the part drawers..

The whole thing is built around an arduino mini pro that i have reused in many projects and now it was time it to find its home .
For motion  it uses two 9g servo motors modified to continuous rotation.

 

These motors are kinda noisy , weak  and actualy are anything but ideal for moving robot  because of their inconsistency of rotational speed (in other words , good luck of making the robot go straight) but i dont mind.

Also on the – repurposed – board there was a 433Mhz receiver connected to the arduino in case i want to add a remote controller.

The first test using a compass and aaa batteries.Not good

On the head ,right under the ultrasonic proximity sensor i added a simple ir distance sensor , the TCRT5000 at 950nm. This is just a ir led / ir phototransistor pair without any other circuitry so some extra coding had to be done.

I`ve decided to place this just to do some basic cliff sensing (with mixed results since it gets affected by the surfaces color..). The reason to use this thing was because it was dirt cheap and super compact.

Parts used
1x arduino mini pro
2x sg90 9g 5v microservos from tower pro
1x  srf05 ultrasonic proximity sensor
1x tcrt5000 ir proximity sensor
1x limit switch
1x 10k resistor for the bumper switch
some sil pins for connecting everything on the board

So heres “a” code for this robot. And i say a code because its depends on what i want to test. Still i havent use the 433Mhz receiver .Anyway


/*---------------------------------------
 Written for arduino mini pro using the ATmega328P.
 The ultrasonic distance sensor is a SRF05 , the ir sensor is
 a TCRT5000 from Vishay and the servos are 2 9g tower pro (sg90)
 converted to continuous rotation.
 
 connections:
 pin2 - SRF05 TRIG
 pin3 - SRF05 ECHO
 pin4 - Bumper switch
 pin6 - IR trig (the led side)
 pin8 - Left servo
 pin9 - right servo 
 A3 - IR sense (the photodiode side)
 
-----------------------------------------*/


#include 
#include 
//-----------------------------------------
#define LEFTSERVOPIN  8
#define RIGHTSERVOPIN  9

Servo leftServo; 
Servo rightServo; 

bool freezeAllMotorFunctions = false;// Yep yep

int speed = 20; //sets the speed of the robot (both servos) a percentage between 0 and 100

unsigned long previousMillis = 0; 
const long interval = 1000;//ena defterolepto?
uint8_t timecounter = 0;//apo8kh xronou

unsigned long ir_previousMillis = 0;//ir timecounter
const long ir_interval = 1;//ir interval
uint8_t ir_timecounter = 0;//apo8kh xronou gia to ir
int ir_ping = 0;//otan einai 1 kanei ping to ir
int ir_step=0;

int motionType = 0;
int motionDir = 0;
uint8_t turningTime = 2;

int a,b,c;
const int  BUMPER_PIN = 4; 
const int  IR_TRIG = 6; 
const int  IR_READ = 3; 
int buttonState = 0; 
int lastButtonState = 0;
int bumper_hit = 0; 
int floorDistance = 0;

const unsigned int TRIG_PIN=2;
const unsigned int ECHO_PIN=3;
const unsigned int BAUD_RATE=9600;

void setup() {
  Serial.begin(BAUD_RATE); 
  /*radar*/
  pinMode(TRIG_PIN, OUTPUT);
  pinMode(ECHO_PIN, INPUT);
  pinMode(IR_TRIG,OUTPUT);
  pinMode(BUMPER_PIN, INPUT);
  
  /*motors*/
  if(!freezeAllMotorFunctions) serbSetup();
}

void checkBumper(){
//  if(ir_ping == 1){
    buttonState = digitalRead(BUMPER_PIN);
    if (buttonState != lastButtonState) {
      if (buttonState == HIGH) {
        bumper_hit = 1;
      } else {
        bumper_hit = 0;
      }
    }
    
    lastButtonState = buttonState;
//  }
}

int checkFloorDistance(){
   digitalWrite(IR_TRIG,HIGH);    // Turning ON LED
  if(ir_step==0 && ir_ping == 1){
    a=analogRead(IR_READ);        //take reading from photodiode(pin A3) :noise+signal
    digitalWrite(IR_TRIG,LOW); 
    ir_step = 1;
  }
  if(ir_step==1 && ir_ping == 1){
    b=analogRead(IR_READ);        // again take reading from photodiode :noise
    c=a-b;
    ir_step = 0;
    return(c);
  }
}

int checkSonarObsticle(){
  digitalWrite(TRIG_PIN, LOW);
  delayMicroseconds(2);
  digitalWrite(TRIG_PIN, HIGH);
  delayMicroseconds(10);
  digitalWrite(TRIG_PIN, LOW);
  
  const unsigned long duration= pulseIn(ECHO_PIN, HIGH);
  int distance= duration/29/2;
  return(distance);
}

void serbSetup(){
  setSpeed(speed);
  pinMode(LEFTSERVOPIN, OUTPUT);     //sets the left servo signal pin to output
  pinMode(RIGHTSERVOPIN, OUTPUT);    //sets the right servo signal pin to output
  activateMotors();
}

void setSpeed(int newSpeed){
  if(newSpeed >= 100) {newSpeed = 100;}     //if speed is greater than 100 make it 100
  if(newSpeed <= 0) {newSpeed = 0;}         //if speed is less than 0 make it 0 
  speed = newSpeed * 0.9;                   //scales the speed to be between 0 and 90
}

void goForward(){
  leftServo.write(70 + speed);
  rightServo.write(91.5 - speed);
}

void goBackwards(){
  leftServo.write(93 - speed);
  rightServo.write(70 + speed);
}

void goRight(){
  leftServo.write(70 + speed);//ff
  rightServo.write(70 + speed);//bk
}

void goLeft(){
  leftServo.write(90 - speed);//bk
  rightServo.write(90 - speed);//ff
}

void deactivateMotors(){
 leftServo.detach();
 rightServo.detach();
}

void activateMotors(){
  leftServo.attach(LEFTSERVOPIN);
  rightServo.attach(RIGHTSERVOPIN);
}



void loop() {

  int floorDist = checkFloorDistance();
  int distance = checkSonarObsticle();
  checkBumper();


//  Serial.println(floorDist);

  
  if(motionType == 0){
    if(distance==0){
//      if(!freezeAllMotorFunctions) goForward();
    } else { //detected obsticle   
      if(distance<=10){ // sonar - object too close timecounter = 0; motionType = 1; } else if(bumper_hit == 1 || floorDist>-15){ // bumper - hit something - cliff detected
        timecounter = 0;
        motionType = 2;
//        Serial.println("Bumper hit");
      } else {
        motionType = 0;
        if(!freezeAllMotorFunctions) goForward();
      }
    }
  }



  //stop motors before every move
  if(timecounter ==1){
    if(!freezeAllMotorFunctions){
    deactivateMotors();
//    delay(100);
    activateMotors();
//    delay(100);
    }
  }

  unsigned long currentMillis = millis();
  
  //motion Timer------------------------------------
  if (currentMillis - previousMillis >= interval) {
      previousMillis = currentMillis;

      if(motionType == 1){ //turn away
        if(timecounter == turningTime){
          motionType = 0;
          if(motionDir == 0) motionDir = 1;
          else if(motionDir == 1) motionDir = 0;
          
        } else {
          timecounter++;
          if(motionDir == 1) {
            if(!freezeAllMotorFunctions) goRight();
            Serial.println("Going Right");
          } else {
            if(!freezeAllMotorFunctions) goLeft();
            Serial.println("Going left");
          }
        }
             
      } else if(motionType == 2){ // go back and then turn away
        if(timecounter == turningTime){
          timecounter = 0;
          motionType = 1;//then turn          
        } else {
          timecounter++;
          if(!freezeAllMotorFunctions) goBackwards();
//          Serial.println("Going backwards");
        }
      }     
  }


  //ir timer and bumper debounce  ----------------------------
  if (currentMillis - ir_previousMillis  >= ir_interval) {
    ir_previousMillis  = currentMillis;
    ir_ping = 1;
  } else {
    ir_ping = 0;
  }
  //-----------------------------------------------------------

}

anyway , the code isn`t winning any contests but its ok for testing. I had some issues with the cliff sensor when i tried to use it on bright marble floor but you can adjust the ir sensitivity just altering the “floorDist>-15” argument or erase the whole thing

 

Anywayyz mates

cheerz!