Esperimento Arduino applicato a robotica di base

Ciao a tutti, sono Giovanni, laureando NABA (nuova accademia di belle arti di Milano). Mi complimento con Massimo e tutti quelli che hanno collaborato al progetto di questo magico microcontrollore.

Sto lavorando a questo piccolo robot come abstract per la tesi di laurea (che si baserà su un’analisi dell’evoluzione della robotica nell’arte contemporanea e i possibili futuri sviluppi).

Componenti utilizzati:
-microprocessore arduino duemilanove
-breadboard sperimentale
-cablaggi vari
-due servi parallax a rotazione continua
-due sensori di contatto + le due resistenze da 10 ko necessarie
-un led a 3 pin (bicolore verde-rosso) + resistenza da 220 o necessaria
-Balsa e parte del kit SERB dei canadesi di oomlout (è
precipitato giu dalle scale e si è in parte sbriciolato :’()

Il codice che ho scritto è questo:

#include <Servo.h>
#define LEFT 0
#define RIGHT 1
int inPinsx = 2;
int inPindx = 3;
int speed = 0;
int ledPin1 = 13;
int ledPin2 = 7;
Servo left;
Servo right;

void setup() {
pinMode(inPinsx, INPUT);
pinMode(inPindx, INPUT);
pinMode(ledPin1, OUTPUT);
pinMode(ledPin2, OUTPUT);
left.attach(9);
right.attach(10);
}

int checkContact() {
int side = 0;
if(digitalRead(inPinsx) == LOW)
side += 1;
if(digitalRead(inPindx) == LOW)
side += 2;

return side;
}

void servoSpeed(int side, int speed) {
speed = speed * 90 / 100;

switch(side) {
case LEFT:
left.write(90 - speed);
break;
case RIGHT:
right.write(90 + speed);
break;
}
}

void loop() {
int contact = checkContact();
digitalWrite(ledPin1, LOW);
digitalWrite(ledPin2, LOW);
if(contact == 0) {
if(speed < 100)
speed += 1;

servoSpeed(LEFT, speed);
servoSpeed(RIGHT, speed);

delay(20);
} else {
speed = 0;
digitalWrite(ledPin1, HIGH);
servoSpeed(LEFT, -100);
servoSpeed(RIGHT, -100);
delay(700);

switch(contact) {
case 1:
digitalWrite(ledPin1, LOW);
digitalWrite(ledPin2, HIGH);
servoSpeed(LEFT, 0);
servoSpeed(RIGHT, 40);
delay(800);
break;
case 2:
digitalWrite(ledPin1, LOW);
digitalWrite(ledPin2, HIGH);
servoSpeed(LEFT, 40);
servoSpeed(RIGHT, 0);
delay(800);
break;
case 3:
if(round((float)rand() / RAND_MAX) == 0) {
servoSpeed(LEFT, 40);
servoSpeed(RIGHT, -40);
} else {
servoSpeed(LEFT, -40);
servoSpeed(RIGHT, 40);
}
delay(400);
break;
}
}
}

Cosi’ gira a caso evitando gli ostacoli percepiti con i sensori di contatto e accende il led verde se colpisce solo con uno dei due, oppure luce di colore rossa con entrambi.

Non so se il codice è ridondante oppure malscritto perchè non me ne intendo.(ringrazio Vanni e Tino per il supporto C)

A questo punto vorrei continuare la sperimentazione aggiungendo
-sensore ir per rilevamento precipizi
-sensore ir montato su servo a rotazione continua per identificazione oggetti
-sensore piezoelettrico per rilevamento suoni
-piccola cassa piezoelettrica

Mi chiedevo, è possibile, montando un sensore piezoelettrico su ogni lato del robot, che arduino possa capire da dove arriva un suono e di conseguenza seguirlo?

Quello che vorrei realizzare è una sorta di robot da compagnia capace di ricaricare le proprie batterie (stilo nikel-cadmio) con 4 pannelli solari da 6.8v 180ma in parallelo. Quindi avere la possibilità di essere sempre acceso e capace di rispondere a stimoli esterni. Molti lo definiscono un progetto Philip -D-i-c-k- oriented ;D
(cosa ci vuole tra i pannelli e le batterie?)

Grazie a tutti e spero possa essere utile a qualcuno questo tipo di sperimentazione.
Gio.

Ciao!

intanto... complimenti per il progetto, sembra ben fatto... e mi spiace per la caduta dalle scale ;\

per quanto riguarda il "ricaricare" i pannelli ti consiglio di prendere una cosa tipo questa: http://home.howstuffworks.com/solar-light.htm adesso le vendono anche da ikea a 5 euro, pannello solare + batteria stile + caricabatteria... fai un pò di reverse e trovi subuti, altrimenti aspetti qualche giorno e posterò io qualcosa al riguardo ;) ad ogni modo. Se hai già i pannelli solari... lo schema sembrerebbe questo: http://www.makeitsolar.com/images/schematic003.gif ma devi "vedere" che uscita hai dai pannelli e calcolarti le resistenze (quali?)

per "capire" da dove viene il suono, in teoria dovrebeb funzionare, ma sinceramente non saprei proprio :\

se posso permettermi, ti consiglio un sensore per la luce, così si ferma "alla luce" per ricaricaricare le batterie [magari quando hanno un voltaggio inferiore a X, e quindi quasi scariche] :)

spero d'esser stato d'aiuto!

Ma se io volessi acquistare un pannello solare, dove vado ? Da ikea sti pannelli che dici tu non li ho mai visti..

è una delle ultime cose ikea... stanno nella sezione giardinaggio, a pochi euro ti prendi una lampada a led con pannello solare e ricarica batteria stilo :D io vado domani a prendela, la smonto subito e vi faccio sapere ;D

ma porca .... sono stato ieri all'ikea. fai un album fotogrfico dello smontaggio !!!

Ciao , mi hai preceduto anche io sono alle prese con un bot :) ... sono anche io un nuovo user di Arduino e sto sperimentando ... posteresti lo schema di come hai collegato tutto :) ?? ... Grazie mille ...

Ciao a tutti.
Grazie mille per i consigli dei lampioncini solari, in effetti c’è dentro tutto quello che ho bisogno.
Pero’ la sfida sarebbe farselo da solo ;D. L’idea dei sensori di luce è ottima e anche secondo me sono fondamentali. Il fine di questo progetto sarebbe una sorta di gatto elettrico acceso 24 ore su 24 con capacità di interagire con suono/luce e movimento con l’esterno.
L’impianto elettrico è la copia degli esempi sul sito x le varie connessioni. Quando ho un secondo di tempo rifaro’ il tutto un po’ meglio, eliminando la bread e saldando decentemente. Poi vorrei mettere chiaramente lo schema qui nella discussione.

ho trovato questo tutorial per ricaricare batterie con pannelli solari:

dite che basta come sistema?
io dovrei caricare 4 stilo in serie
ho un pannello solare da 6.8v 180 mA
Ho acquistato il diodo citato nel tutorial e collegato il tutto
il pannello non supera i 5.5 v al sole, quindi mi sembra possa andare bene. Voi cosa ne dite?

Sto sperimentando un sensore piezoelettrico per dare l’udito al BOT, mi sono procurato un let e una cassa uguale a quella nel tutorial sul sito e ho inserito parte del codice nell’esempio nel mio codice di base, per far si che a qualsiasi minimo imput ricevuto dalla cassa (threshold 1) deve accendere un LED.
Ho riscontrato i seguenti problemi:
anche a threshold 1 non percepisce il parlato se non parlando ad alta voce e vicino alla cassa (questo caricando il codice dell’esempio).http://arduino.cc/en/Tutorial/Knock

Questo è il codice da me postato precedentemente con l’aggiunta del knock sensor:

#include <Servo.h>
#define LEFT 0
#define RIGHT 1
int inPinsx = 2;
int inPindx = 3;
int speed = 0;
int ledPin1 = 13;
int ledPin2 = 7;
int ledPin3 = 12; // led connected to control pin 13
int knockSensor = 5; // the knock sensor will be plugged at analog pin 0
byte val = 0; // variable to store the value read from the sensor pin
int statePin = LOW; // variable used to store the last LED status, to toggle the light
int THRESHOLD = 1; // threshold value to decide when the detected sound is a knock or not
Servo left;
Servo right;

void setup() {
pinMode(inPinsx, INPUT);
pinMode(inPindx, INPUT);
pinMode(ledPin1, OUTPUT);
pinMode(ledPin2, OUTPUT);
pinMode(ledPin3, OUTPUT); // declare the ledPin as as OUTPUT
Serial.begin(9600); // use the serial port
left.attach(9);
right.attach(10);
}

int checkContact() {
int side = 0;
if(digitalRead(inPinsx) == LOW)
side += 1;
if(digitalRead(inPindx) == LOW)
side += 2;

return side;
}

void servoSpeed(int side, int speed) {
speed = speed * 90 / 100;

switch(side) {
case LEFT:
left.write(90 - speed);
break;
case RIGHT:
right.write(90 + speed);
break;
}
}

void loop() {
{
val = analogRead(knockSensor); // read the sensor and store it in the variable “val”
if (val >= THRESHOLD) {
statePin = !statePin; // toggle the status of the ledPin (this trick doesn’t use time cycles)
digitalWrite(ledPin3, statePin); // turn the led on or off
Serial.println(“Knock!”); // send the string “Knock!” back to the computer, followed by newline
delay(1); // short delay to avoid overloading the serial port
}
}
int contact = checkContact();
digitalWrite(ledPin1, LOW);
digitalWrite(ledPin2, LOW);
if(contact == 0) {
if(speed < 100)
speed += 1;

servoSpeed(LEFT, speed);
servoSpeed(RIGHT, speed);

delay(20);
} else {
speed = 0;
digitalWrite(ledPin1, HIGH);
servoSpeed(LEFT, -100);
servoSpeed(RIGHT, -100);
delay(700);

switch(contact) {
case 1:
digitalWrite(ledPin1, LOW);
digitalWrite(ledPin2, HIGH);
servoSpeed(LEFT, 0);
servoSpeed(RIGHT, 40);
delay(800);
break;
case 2:
digitalWrite(ledPin1, LOW);
digitalWrite(ledPin2, HIGH);
servoSpeed(LEFT, 40);
servoSpeed(RIGHT, 0);
delay(800);
break;
case 3:
if(round((float)rand() / RAND_MAX) == 0) {
servoSpeed(LEFT, 40);
servoSpeed(RIGHT, -40);
} else {
servoSpeed(LEFT, -40);
servoSpeed(RIGHT, 40);
}
delay(400);
break;
}
}
}

Mi rendo conto che per gli amanti di C sia un accrocchio e che ci saranno 10 cose che non vanno, ma non me ne intendo.
Caricando il codice la sensibilità diminuisce rispetto al codice dell’esempio e sembra avere una reattività molto piu’ random.
Forse è un errore di codice? Sapreste darmi una spiegazione?
C’è un modo per ottenere piu’ sensibilità e prendere in considerazione valori piu’ bassi di threshold1? Vorrei con questo sistema dare più interattività al bot.

Sono due giorni che cerco di inserire nel codice che arduino produca un suono con una cassa piezo output se sente del suono con la cassa piezo di imput, sarebbe carino riuscire con un delay a “rispondere” a un suono percepito con una sequenza di note casuali ogni volta diverse (molto alla C1P8).

Ciao a tutti, ho "aperto" la lampada ikea... 12 euro: 1 pannello solare (devo ancora controllare con il tester quanto esce) 1 circuito con 3 resistenze, 1 diodo e 1 microprocessore 2 batterie stilo ricaricabili 1 interruttore waterproff 6 led ultraluminescenti

ikea... saggia risparmiatrice, non ha utilizzato nessun sensore di luce, il controller accende il led se non arriva energia dai pannelli solari, altrimenti ricarica la batteria :)

la cosa più difficile sarà ricaricare le batterie solo se ce ne sarà bisogno... any idea?

per l'audio non saprei... comunque quando incolli il codive dovresti usare l'apposito metodo (rappresentato con un cancelletto) quando scrivi un post, cioè (code)(/code) sostituendo le parentesi tonde con delle quadre :D

Un po' come funzionano i pummer bot presentati tempo addietro su makezine dunque, per la ricarica

Spe... ma non sara' mica una torcia elettrica ricaricabile ad esergia solare, con un pannello dietro e davanti 6 led bianchi, la torcia e' argentata come colore e ha un piccolo cavalletto metallico se vuoi, per farla stare in posizione?

Se e' quella ne ho una a casa, presa circa 2 mesi fa a 11 euro se nn ricordo male... Ma mi piange il cuore perderla! E' cosi cariiina :)

non c’è nessuno che possa darmi una mano con il codice? sono proprio niubbo da questo punto di vista

Dunque.. se non ti funziona neanche questo http://arduino.cc/en/Tutorial/Knock dovrebbe trattarsi di un problema di elettroniche, volevo provare lo sketch per capire ma ho il piezo e non la resistenza nell'ordine dei megahom...

Buonasera a tutti, sto utilizzando Arduino da qualche tempo e lo trovo veramente ben strutturato, complimenti a tutti gli sviluppatori. Purtroppo non posso dare nessun consiglio di robotica ma "girellando" in internet ho trovato una persona che anziché un gatto ha costruito un cane (C.A.BOT :Chien Artificiel roBOT), utilizzando un microcontrollore ATMEL ATMega32 (non Arduino). b.urbani.free.fr/pagecabot/cabot.htm Forse può essere spunto per qualche idea.

Io a questo punto sono fermo a livello software perchè non me ne intendo. Non riesco a integrare il suono nelle if e nei casi e soprattutto non capisco perchè nel secondo codice da me postato il sensore sonore perde sensibilità rispetto al codice d'esempio con stesso threshold.

Qualcuno sa darmi una mano? Gio.

allora… ho tato una controllata al codice e ne ho approfittato per allinearlo un pò meglio e mettergli qualche commento in più e relativo debug su seriale… eccoti il

#include <Servo.h>

/* INPUT DEVICES */
int inPinsx = 2; // contact sensor left
int inPindx = 3; // contact sensor right
int knockSensor = 5;  // the knock sensor will be plugged at analog pin 5


/* OUTPUT DEVICES */
// servos
Servo left;
Servo right;
// leds connected to controls pin 7, 12 and 13
int ledPin1 = 13;
int ledPin2 = 7;
int ledPin3 = 12;

#define LEFT 0
#define RIGHT 1

byte sound = 0;         // variable used to store the value read from the piezo (0-1024)
int THRESHOLD = 1;  // readed sounds under this value will be ignored

int statePin = LOW;   // variable used to store the last LED status, to toggle the light

int speed = 0; // variable used to store the servor's speed
int max_speed = 100; // maximum servo's speed to use

void setup() {
  Serial.begin(9600);       // use the serial port
  
  pinMode(inPinsx, INPUT);
  pinMode(inPindx, INPUT);

  pinMode(ledPin1, OUTPUT);  
  pinMode(ledPin2, OUTPUT);
  pinMode(ledPin3, OUTPUT);

  left.attach(9);
  right.attach(10);
}

void loop() {
  sound = analogRead(knockSensor); // read the sensor and store it in the variable "sound"
  if (sound >= THRESHOLD) {
    statePin = !statePin; // toggle the status of the ledPin (this trick doesn't use time cycles)
    digitalWrite(ledPin3, statePin); // turn the led on or off
    Serial.print("Received a sound: ");
    Serial.println(sound);
  }
  
  int contact = checkContact(); // check contact sensor status (0=null | 1=sx | 2=dx | 3=both)

  digitalWrite(ledPin1, LOW);
  digitalWrite(ledPin2, LOW);
  
  if(contact == 0) {
  // nothing is touching
    if(speed < max_speed) { speed += 1; } // increment speed still < max_speed
    Serial.print("Actual speed is:  ");
    Serial.println(speed);
    servoSpeed(LEFT, speed); // set left servo speed
    servoSpeed(RIGHT, speed); // set right servo speed
    delay(20);
  } else {
  // something have touched
    speed = 0; // stop speed
    digitalWrite(ledPin1, HIGH); // turn on collision led
    servoSpeed(LEFT, -100); // set left servo to go back
    servoSpeed(RIGHT, -100); // set right servo to go back
    Serial.println("Moved back... I'v hurted something!");

    delay(700);

    switch(contact) {
      case 1:
      // only sx have collided, go right
        Serial.println("Turning right...");
        digitalWrite(ledPin1, LOW); // turn off collision led
        digitalWrite(ledPin2, HIGH);  // turn on redirection led
        servoSpeed(LEFT, 0);
        servoSpeed(RIGHT, 40);
        delay(800);
        break;
      case 2:
      // only dx have collided, go left
        Serial.println("Turning left...");
        digitalWrite(ledPin1, LOW); // turn off collision led
        digitalWrite(ledPin2, HIGH); // turn on redirection led
        servoSpeed(LEFT, 40);
        servoSpeed(RIGHT, 0);
        delay(800);
        break;
      case 3:
      // multiple collision... go random!
        Serial.print("Turning ... random... at.... ");
        digitalWrite(ledPin1, LOW); // turn off collision led
        digitalWrite(ledPin2, HIGH); // turn on redirection led
        if(round((float)rand() / RAND_MAX) == 0) {
          Serial.println("left strong");
          servoSpeed(LEFT, 40);
          servoSpeed(RIGHT, -40);
        } else {
          Serial.println("right strong");
          servoSpeed(LEFT, -40);
          servoSpeed(RIGHT, 40);
        }
        delay(400);
        break;
    }
    digitalWrite(ledPin1, LOW); // turn off collision led
    digitalWrite(ledPin2, LOW);  // turn off redirection led
  }
}

// check collision with contact sensors
int checkContact() {
  int side = 0;
  if( (digitalRead(inPinsx) == LOW) && (digitalRead(inPinsx) == LOW) ) {
    return(3);
  } else if (digitalRead(inPinsx) == LOW) {
    return(1);
  } else if (digitalRead(inPindx) == LOW) {
    return(2);
  }
  return 0;
}

// move servos
void servoSpeed(int side, int speed) {
  speed = speed * 90 / 100;
  switch(side) {
    case LEFT:
      left.write(90 - speed);
      break;
    case RIGHT:
      right.write(90 + speed);
      break;
  }
}

purtroppo non ho avuto modo di testarlo, ad ogmi modo il problema del piezo credo che sia dovuto dalla resistenza, alla fin fine lo sketch che hai preso da http://arduino.cc/en/Tutorial/Knock mi sa che serve per sapere quando uno bussa, ma attaccando il piezo alla porta :slight_smile:

Comunque se colleghi la seriale come print ti ho messo il valore di lettura (da 1 minimo a 1024) prova a toccarlo e vedi a quanto ti arriva, poi prova a urlarci dentro e vedi a quanto arriva… se per farlo arrivare a 1024 devi cantare il magnotta al megafono… mi sa che la resistenza va cambiata con una un pò più light :slight_smile:

fammi sapere che sono curioso!

Ciao a tutti ragazzi.
Sto ampliando il robottino.
Ho aggiunto una cassa piezoelettrica per percepire suoni (o cambiamenti nella media), un’altra cassa piezo per produrre bip vari, un led infrarosso montato come sensore di luminosità x cercare la luce e ricaricarsi con i pannelli solari. Chiaramente un solo sensore non basterà, e devo vedere di integrare nel codice la nuova funzionalità.
Abbiamo lavorato molto sia all’hardware che al codice.
Grazie a Martino e Vanni ecco cosa è venuto fuori, a livello di codice:

#include <Servo.h>

// Words for clarity
#define LEFT 1
#define RIGHT 2
#define LEDSERVO 0
#define LEDSND 1

// Parameters
#define BUMPS_TO_STOP 3                 // number of obstacles to stop after
#define RANDOM_START_SECONDS 120        // mean time in seconds for random start
#define BACKWARD_MSECONDS 700           // time to go back after hitting an obstacle in milliseconds
#define ROTATION_MSECONDS 500           // time of the rotation in milliseconds
#define SPEED 100                       // speed to go
#define SNDMEAN 150                      // number of samples to mean

// Digital pins
#define ledPin1      2                  // LED 1 red
#define ledPin2      3                  // LED 1 green
#define ledPin3      4                  // LED 2 blue
#define winkerPin1   7                  // winker LEFT
#define winkerPin2   8                  // winker RIGHT
#define servoPin1    9                  // servo LEFT
#define servoPin2   10                  // servo RIGHT
#define outSndPin   11                  // speaker

// Analog pins
#define inSndPin     5                  // sound sensor

// Variables
float actualSpeed = 0.0;
boolean moving = false;
int speedLeft = 0;
int speedRight = 0;
Servo left;
Servo right;

int contact = 0;
int contactCount = 0;
int contactStep = 2;
long contactTime = 0;

int meanSnd[SNDMEAN];
long meanSndCount = 0;

void setup() {
  pinMode(ledPin1, OUTPUT);
  pinMode(ledPin2, OUTPUT);
  pinMode(ledPin3, OUTPUT);
  pinMode(winkerPin1, INPUT);
  pinMode(winkerPin2, INPUT);
  left.attach(servoPin1);
  right.attach(servoPin2);
  pinMode(outSndPin, OUTPUT);
  
  randomSeed(analogRead(0));
}

// Winkers
int checkContact() {
  if(digitalRead(winkerPin1) == LOW)
    return LEFT;
  if(digitalRead(winkerPin2) == LOW)
    return RIGHT;

  return 0;
}

// Servo
void servoContinue() {
  if(moving) {
    if((actualSpeed < 1))
      actualSpeed += 0.004;
  }
  else
    actualSpeed = 0;

  servoSpeed(LEFT, round(speedLeft * actualSpeed));
  servoSpeed(RIGHT, round(speedRight * actualSpeed));
}

void servoGo(int speed) {
  speedLeft = speedRight = speed;
  servoReset();
}

void servoReset() {
  actualSpeed = 0;
  servoContinue();
}

void servoRotate(int side) {
  switch(side) {
  case LEFT:
    speedLeft = 40;
    speedRight = -40;
    break;
  case RIGHT:
    speedLeft = -40;
    speedRight = 40;
    break;
  }
  servoReset();
}

void servoSpeed(int side, int speed) {
  speed = speed * 90 / 100;
  switch(side) {
  case LEFT:
    left.write(90 + speed);
    break;
  case RIGHT:
    right.write(90 - speed);
    break;
  }
}

// LED
void setLed(int led, int state) {
  switch(led) {
  case LEDSERVO:
    switch(state) {
    case 0:
      digitalWrite(ledPin1, LOW);
      digitalWrite(ledPin2, LOW);
      break;
    case 1:
      digitalWrite(ledPin1, HIGH);
      digitalWrite(ledPin2, LOW);
      break;
    case 2:
      digitalWrite(ledPin1, LOW);
      digitalWrite(ledPin2, HIGH);
      break;
    }
    break;
  case LEDSND:
    if(state == 0)
      digitalWrite(ledPin3, LOW);
    else
      digitalWrite(ledPin3, HIGH);
  }
}


// Sound
void sndPlay() {
  sndTone(1275);
  sndTone(1915);
}

void sndTone(int tone) {
  for(long i = 0; i < 80000; i += tone * 2) {
    digitalWrite(outSndPin, HIGH);
    delayMicroseconds(tone);
    digitalWrite(outSndPin, LOW);
    delayMicroseconds(tone);
  }
}

// Movement
void start() {
  contactCount = 0;
  moving = true;
}

void stop() {
  meanSndCount = 0;
  moving = false;
  
  setLed(LEDSND, 0);
}

void loop() {
  if((! moving) && (random(0, 3000) + random(0, RANDOM_START_SECONDS) == 0))
    start();
  
  if(moving && (contactStep == 0) && (contactCount >= BUMPS_TO_STOP))
    stop();
    
  if(! moving) {
    int snd = analogRead(inSndPin);
    meanSnd[meanSndCount++ % SNDMEAN] = snd;
    if(meanSndCount >= SNDMEAN) {
      float mean = 0;
      for(int i = 0; i < SNDMEAN; i++)
        mean += meanSnd[i];
      mean /= SNDMEAN;
    
      if(snd < round(mean) - 1) {
        start();
        setLed(LEDSND, 1);
      }
    }
  }
  else {
    if(contactTime < millis() - (BACKWARD_MSECONDS + ROTATION_MSECONDS + random(0, 200))) {
      contact = checkContact();
      if(contact != 0) {
        contactCount++;
        contactStep = 1;
        contactTime = millis();
        setLed(LEDSERVO, 1);
        servoGo(-100);
        sndPlay();
      }
      if(contactStep == 2) {
        contactStep = 0;
        setLed(LEDSERVO, 0);
        servoGo(SPEED);
      }
    } else {
      if((contactTime < millis() - BACKWARD_MSECONDS) && (contactStep == 1)) {
        contactStep = 2;
        setLed(LEDSERVO, 2);
        servoRotate(contact);
      }
    }
  }
  
  servoContinue();
}

Mi dareste una mano a integrare il sensore di luce?
Spero che il nostro lavoro torni utile alla comunità ;D

per inserire codice DEVI usare il tasto in alto # altrimenti la pagina diventa illegibile

Fatto scusatemi ma non avevo notato la tag :o

Ciao a tutti ragazzi.
Ecco il codice aggiornato:

#include <Servo.h>

// words for clarity
#define LEFT 1
#define RIGHT 2
#define LEDBICOLOR 0
#define LEDTRICOLOR 1

// parameters
#define BUMPS_TO_STOP 5                 // number of obstacles to stop after
#define RANDOM_START_SECONDS 120        // mean time in seconds for random start
#define RANDOM_SOUND_SECONDS 30         // mean time in seconds for random sound
#define RANDOM_STEER_SECONDS 3          // mean time in seconds for random steering
#define BACKWARD_MSECONDS 800           // time to go back after hitting an obstacle in milliseconds
#define ROTATION_MSECONDS 500           // duration of the rotation in milliseconds
#define STEER_MSECONDS 1000             // duration of the random steering
#define SPEED 100                       // speed to go
#define STEER_PERCENT 3                 // percent of SPEED to set one of the servos to steer
#define SNDMEAN 150                     // number of samples to mean

// digital pins
#define ledPin1      2                  // LED 0 red
#define ledPin2      3                  // LED 0 green
#define ledPin3      4                  // LED 1 blue
#define ledPin4      5                  // LED 1 green
#define ledPin5      6                 // LED sensor
#define winkerPin1   7                  // winker LEFT
#define winkerPin2   8                  // winker RIGHT
#define servoPin1    9                  // servo LEFT
#define servoPin2   10                  // servo RIGHT
#define outSndPin   11                  // speaker
#define ledPin6     12                  // LED sensor

// analog pins
#define inSndPin     5                  // sound sensor

// variables
float actualSpeed = 0.0;                // percent of actual moving speed we are accelerating to
boolean moving = false;                 // stopped or moving
int speedLeft = 0;                      // speed we want on left servo
int speedRight = 0;                     // speed we want on right servo
Servo left;
Servo right;

int contact = 0;                        // did we hit? where?
int contactCount = 0;                   // number of hits since start
int contactStep = 0;                    // part of the hit manouver we are in
long contactTime = 0;                   // time of hitting
boolean steering = false;               // steering or going straight
boolean lightCheck = true;

long lightTime = 0;                     // time of last light check
long startTime = 0;                     // time of last random start
long steerTime = 0;                     // time of last random steering change
long soundTime = 0;                     // time of last random sound

int meanSnd[SNDMEAN];                   // past values of sound sensor
long meanSndCount = 0;                  // number of values stored


// setup
void setup() {
  pinMode(ledPin1, OUTPUT);
  pinMode(ledPin2, OUTPUT);
  pinMode(ledPin3, OUTPUT);
  pinMode(ledPin4, OUTPUT);
  pinMode(ledPin6, OUTPUT);
  pinMode(winkerPin1, INPUT);
  pinMode(winkerPin2, INPUT);
  left.attach(servoPin1);
  right.attach(servoPin2);
  pinMode(outSndPin, OUTPUT);
  
  randomSeed(analogRead(0));
  digitalWrite(ledPin6, LOW);
  Serial.begin(9600);
}


// winkers
int checkContact() {
  if(digitalRead(winkerPin1) == LOW)
    return LEFT;
  if(digitalRead(winkerPin2) == LOW)
    return RIGHT;

  return 0;
}


// servo
void servoContinue() {
  if(moving) {
    if((actualSpeed < 1)) {
      actualSpeed += 0.009;
    }
    if(steering && (steerTime < millis() - STEER_MSECONDS)) {
      speedLeft = speedRight = max(speedLeft, speedRight);
      steering = false;
      steerTime = millis();
    }
  }
  
  servoSpeed(LEFT, round(speedLeft * actualSpeed));
  servoSpeed(RIGHT, round(speedRight * actualSpeed));
}

void servoGo(int speed) {
  if(speed < 0) {
    setLed(LEDBICOLOR, 1);
  }
  else {
    setLed(LEDBICOLOR, 0);
  }
  
  speedLeft = speedRight = speed;
  servoReset();
}

void servoReset() {
  actualSpeed = 0;
  servoContinue();
}

void servoRotate(int side) {
  setLed(LEDBICOLOR, 2);
  
  switch(side) {
  case LEFT:
    speedLeft = 40;
    speedRight = -40;
    break;
  case RIGHT:
    speedLeft = -40;
    speedRight = 40;
    break;
  }
  servoReset();
}

void servoSpeed(int side, int speed) {
  speed = speed * 90 / 100;
  switch(side) {
  case LEFT:
    left.write(90 + speed);
    break;
  case RIGHT:
    right.write(90 - speed);
    break;
  }
}

void servoSteer(int side) {
  steering = true;
  steerTime = millis();
  
  switch(side) {
  case LEFT:
    speedLeft = round(speedLeft * STEER_PERCENT / 100.0);
    break;
  case RIGHT:
    speedRight = round(speedRight * STEER_PERCENT / 100.0);
    break;
  }
}


// LED
void setLed(int led, int state) {
  switch(led) {
  case LEDBICOLOR:
    switch(state) {
    case 0:
      digitalWrite(ledPin1, LOW);
      digitalWrite(ledPin2, LOW);
      break;
    case 1:
      digitalWrite(ledPin1, HIGH);
      digitalWrite(ledPin2, LOW);
      break;
    case 2:
      digitalWrite(ledPin1, LOW);
      digitalWrite(ledPin2, HIGH);
      break;
    }
    break;
  case LEDTRICOLOR:
    switch(state) {
    case 0:
      digitalWrite(ledPin3, LOW);
      digitalWrite(ledPin4, LOW);
      break;
    case 1:
      digitalWrite(ledPin3, LOW);
      digitalWrite(ledPin4, HIGH);
      break;
    case 2:
      digitalWrite(ledPin3, HIGH);
      digitalWrite(ledPin4, HIGH);
      break;
    }
  }
}


// sound
void sndPlay(int sound) {
  switch(sound) {
  case 0:               // sound when hitting an obstacle
    sndTone(1275);
    sndTone(1915);
    sndTone(2000);
    break;
  case 1:               // sound when starting
    sndTone(2100);
    sndTone(1500);
    sndTone(1200);
    break;
  case 2:               // random sound
    for(int i = 0; i < 3; i++)
      sndTone(random(1200, 3000));
    break;
  }
}

void sndTone(int tone) {
  for(long i = 0; i < 80000; i += tone * 2) {
    digitalWrite(outSndPin, HIGH);
    delayMicroseconds(tone);
    digitalWrite(outSndPin, LOW);
    delayMicroseconds(tone);
  }
}


// movement
void start() {
  contactCount = 0;
  steerTime = soundTime = millis();
  moving = true;
  servoGo(SPEED);
  sndPlay(1);
  setLed(LEDTRICOLOR, 2);
}

void stop() {
  startTime = millis();
  meanSndCount = 0;
  moving = false;
  servoGo(0);
  setLed(LEDTRICOLOR, 0);
}

void hit() {
  contactCount++;
  servoGo(-SPEED);
  sndPlay(0);
}


// time
long randomTime(long since, long about) {
  return since - (millis() - round(about * random(5, 15) / 10));
}


// main loop
void loop() {
  if(! moving) {
    if(lightTime < millis() - 1000) {
      lightTime = millis();
      long light = 0;
      for(int i = 0; i < 3; i++) {
        pinMode(ledPin5, OUTPUT);
        digitalWrite(ledPin5, HIGH);
        pinMode(ledPin5, INPUT);
        digitalWrite(ledPin5, LOW);
        for(; light < 90000; light++)
          if(digitalRead(ledPin5) == 0)
            break;
      }
      lightCheck = light < 10000;
      
      Serial.println(light);
      if(lightCheck)
        setLed(LEDBICOLOR, 2);
      else
        setLed(LEDBICOLOR, 1);
    }
    
    if(lightCheck && randomTime(startTime, RANDOM_START_SECONDS * 1000L) < 0)
      start();
  }
  else if(contactStep == 0) {
    if(randomTime(soundTime, RANDOM_SOUND_SECONDS * 1000L) < 0) {
      soundTime = millis();
      sndPlay(2);
    }
    
    // check number of hits
    int remaining = BUMPS_TO_STOP - contactCount;
    if(remaining == 0)
      stop();                     // too many hits, stop ;)
    else if(remaining == 1)
      setLed(LEDTRICOLOR, 1);     // turn off one led, we are going to stop next hit
  }
  
  if(! moving) {
    // sound sensor to start
    int snd = analogRead(inSndPin);
    meanSnd[meanSndCount++ % SNDMEAN] = snd;
    if(meanSndCount >= SNDMEAN) {
      float mean = 0;
      for(int i = 0; i < SNDMEAN; i++)
        mean += meanSnd[i];
      mean /= SNDMEAN;
    
      if(lightCheck && (snd < round(mean) - 1))
        start();                  // sound activated start
    }
  }
  else {
    // moving and hitting obstacles
    switch(contactStep) {
    case 0:                       // moving straight
      contact = checkContact();
      if(contact != 0) {
        contactStep = 1;
        contactTime = millis();
        hit();
      }
      else {
        if((! steering) && (randomTime(steerTime, RANDOM_STEER_SECONDS * 1000L) < 0))
          servoSteer(random(LEFT, RIGHT + 1));
      }
      break;
    case 1:                       // moving backwards after hit
      if(contactTime < millis() - BACKWARD_MSECONDS) {
        contactStep = 2;
        servoRotate(contact);
      }
      break;
    case 2:                       // rotating after moving backwards
      if(contactTime < millis() - (BACKWARD_MSECONDS + ROTATION_MSECONDS + random(0, 200))) {
        steerTime = millis();
        contactStep = 0;
        servoGo(SPEED);
      }
    }
  }
  
  // go on accelerating
  servoContinue();
}

Abbiamo implementato con un led a infrarossi un sensore di luce (come spiegato nel sito), in questo caso il nostro robottino entrera’ in start solo se ci sara’ un tot di luminosità.

Implementata la possibiltà di curvare random.