Salve a tutti vi presento un progetto molto carino e accattivante basato, come al solito, su Arduino: è un semplice robot a due ruote, che, invece di avere una terza ruota pivotante per mantenersi in equilibrio, sfrutta un sistema di rivelatori di distanza che gli permettono di restare sempre in piedi nella posizione corretta. Per fare ciò, infatti, impiega due sensori di prossimità (in questo caso Sharp) molto economici, con un range tra i 50 cm e i 3 cm. L’algoritmo che ne permette il funzionamento, infatti, prende in input i valori dei due sensori: se la loro differenza è prossima a 0, allora permette ai due servi di muoversi.

Questa è la prima versione del codice che contiene ancora delle incertezze, infatti se il robot si inclina eccessivamente in avanti o indietro e resta inclinato sul pavimento non è in grado di modificare autonomamente la sua posizione.

Prima versione del codice:

 

Servo left;
Servo right;

#define servoLeftPin     9
#define servoRightPin   10
#define servoZero       81
#define IRFront         0
#define IRBack          1
#define ledPin          13

int frontSense = 0;
int backSense = 0;
int orientation = 0;

void setup() {
pinMode(ledPin, OUTPUT);
left.attach(servoLeftPin);
right.attach(servoRightPin);
left.write(servoZero);
right.write(servoZero);
Serial.begin(9600);
}

void getOrientation() {
  frontSense = 0;
  backSense = 0;
  orientation = 0;
 for (int i = 0; i < 10; i++) {
  frontSense = analogRead(IRFront) + frontSense;
  backSense = analogRead(IRBack) + backSense;
  if (i == 9) {
   frontSense = frontSense / 10;
   backSense = backSense / 10;
   orientation = frontSense - backSense;
  }
 }
}

void loop() {
getOrientation();

float delta = orientation / 8;
if(delta > 90) delta = 90;
if(delta < -90) delta = -90;
left.write(81 - delta);
right.write(81 + delta);
Serial.println(orientation);
}
Seconda versione del codice che elimina il problema:
Servo left;
Servo right;

#define servoLeftPin     9
#define servoRightPin   10
#define servoZero       81
#define IRFront         0
#define IRBack          1
#define ledPin          13

int frontSense = 0;
int backSense = 0;
int orientation = 0;
int fall = 0;

void setup() {
pinMode(ledPin, OUTPUT);
left.attach(servoLeftPin);
right.attach(servoRightPin);
left.write(servoZero);
right.write(servoZero);
Serial.begin(9600);
}

void getOrientation() {
  frontSense = 0;
  backSense = 0;
  orientation = 0;
 for (int i = 0; i < 10; i++) {
  frontSense = analogRead(IRFront) + frontSense;
  backSense = analogRead(IRBack) + backSense;
  if (i == 9) {
   frontSense = frontSense / 10;
   backSense = backSense / 10;
   orientation = frontSense - backSense;
  }
 }
}

void loop() {
getOrientation();

float delta = orientation / 8;
if(delta > 90) delta = 90;
if(delta < -90) delta = -90;
if(orientation > 250) fall = fall + 1;
if(orientation < -250) fall = fall - 1;
left.write(81 - delta);
right.write(81 + delta);
if (fall == 25 || fall == -25) {
   left.write(servoZero);
   right.write(servoZero);
   delay(250);
   fall = 0;
}
Serial.print(orientation);
Serial.print("   ");
Serial.println(fall);
}

Video dimostrazione: