aiuto robot evita ostacoli

Salve a tutti,
ho costruito un robot che dovrebbe evitare ostacoli tramite in sensore di prossimità ad ultrasuoni hy-srf05
collegato ad arduino mega, il robot e mosso da due motori dc controllati da un driver l298n.
Il problema è che il robot gira su se stesso,diciamo che non avanza per niente, secondo il codice il robot dovrebbe andare avanti e nel caso in cui trovi un ostacolo prima girerebbe a destra, poi a sinistra e infine andrebbe dove a rilevato piu spazio, ma in realtè rimane sempre sullo stesso punto.
Non so se il problema derivi dal codice:

long duration;
long dursx;
long durdx; 
const int en1 = 2; //pin enable
const int en2 = 3;
const int m1fd = 22; //controlli motore
const int m2fd = 23;
const int m1bk = 24;
const int m2bk = 25;
const int pinping = 26; //pin sensore distanza
const int sterzo = 600; //durata dello sterzo
const int distanza = 500; //distanza minima ostacoli
int motore1 = 67;//pwm motore dx
int motore2 = 74;//pwm motore sx

/*
LiquidCrystal Library - Hello Worl
const int LCD RS pin to digital pin 26
const int LCD Enable pin to digital pin 27
const int LCD D4 pin to digital pin 28
const int LCD D5 pin to digital pin 29
const int LCD D6 pin to digital pin 30
const int LCD D7 pin to digital pin 31
const int LCD R/W pin to ground
const int 10K resistor:
const int ends to +5V and ground
const int wiper to LCD VO pin (pin 3)
*/

// include the library code:
#include <LiquidCrystal.h>

// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(27, 28, 29, 30, 31, 32);


void setup() {
 pinMode(m1fd, OUTPUT);
 pinMode(m1bk, OUTPUT);
 pinMode(m2fd, OUTPUT);
 pinMode(m2bk, OUTPUT);
 pinMode(en1, OUTPUT);
 pinMode(en2, OUTPUT);
 analogWrite(en1,motore1);
 analogWrite(en2,motore2);
 dritto();

 }

void loop() {
 if (echo() < distanza){ //trovato un ostacolo
  analogWrite(en1,170);
  analogWrite(en2,170);
  ferma();
  sinistra();
  delay(sterzo);
  ferma();
  dursx = echo(); //guarda a sinistra
  destra();
  delay(sterzo*2);
  ferma();
  durdx = echo(); //guarda a destra
  if (dursx < distanza && durdx < distanza){
    destra();
    delay(sterzo);
  } else if (dursx > durdx) {
    sinistra();
    delay(sterzo*2);
  } //sceglie dove c'è più spazio
  dritto();
  analogWrite(en1,motore1);
  analogWrite(en2,motore2);
 }
}

void dritto() {
  digitalWrite(m1bk,LOW);
  digitalWrite(m2bk,LOW);
  digitalWrite(m2fd,HIGH);
  digitalWrite(m1fd,HIGH);   
  // set up the LCD's number of columns and rows: 
  lcd.begin(16, 2);
  // Print a message to the LCD.
  lcd.print("Sono,un,robot");

}

void rovescia() {
  digitalWrite(m1fd,LOW);
  digitalWrite(m2fd,LOW);
  digitalWrite(m1bk,HIGH);
  digitalWrite(m2bk,HIGH);
  // set up the LCD's number of columns and rows: 
  lcd.begin(16, 2);
  // Print a message to the LCD.
  lcd.print("Stò,effettuando,un,inversione,di,marcia!");
  
}

void destra() {
  digitalWrite(m1fd,LOW);
  digitalWrite(m2fd,HIGH);
  digitalWrite(m1bk,HIGH);
  digitalWrite(m2bk,LOW);
  // set up the LCD's number of columns and rows: 
  lcd.begin(16, 2);
  // Print a message to the LCD.
  lcd.print("girare,a,destra!");
  
}

void sinistra() {
  digitalWrite(m1fd,HIGH);
  digitalWrite(m2fd,LOW);
  digitalWrite(m1bk,LOW);
  digitalWrite(m2bk,HIGH);
  // set up the LCD's number of columns and rows: 
  lcd.begin(16, 2);
  // Print a message to the LCD.
  lcd.print("girare,a,sinistra!");
  
} 

void ferma() {
  digitalWrite(m1fd,LOW);
  digitalWrite(m2fd,LOW);
  digitalWrite(m1bk,LOW);
  digitalWrite(m2bk,LOW);
  delay(50);
  // set up the LCD's number of columns and rows: 
  lcd.begin(16, 2);
  // Print a message to the LCD.
  lcd.print("Spostati,ho,fretta!");

  
}


long echo() {
  pinMode(pinping, OUTPUT);
  digitalWrite(pinping, LOW);
  delayMicroseconds(2);
  digitalWrite(pinping, HIGH);
  delayMicroseconds(5);
  digitalWrite(pinping, LOW);
  pinMode(pinping, INPUT);
  duration = pulseIn(pinping,HIGH);
  return duration;
}

Nel caso in cui il problema non derivi dal programma qualcuno di voi potrebbe darmi qualche indicazione su come risolvere questo problema??

grazie

Fedrix

  1. sei sicuro che il codice del sensore sia giusto ? (Quella funzione "echo" ) Io prima di tutto mi assicurerei con uno sketch più semplice e senza i motori (usa la mano a distanza del sensore) che il sensore e il codice funzioni.

  2. se nel codice non ci sono errori, per poterti aiutare, capirai bene che dovrai fornire uno schema di come hai collegato le varie parti, altrimenti non è possibile aiutarti.

Grazie mille per il suggerimento, ora provo a fare come mi hai detto.

P.S. il sensore l ho collegato con il metodo di un solo pin(trigger ed echo sono insieme e out a massa),potrebbe dipendere da questo metodo di collegamento?

scusate per la domanda,forse un po ingenua :sweat_smile: ,ma come dovrei cambiare la funzione "echo" :sweat_smile: :sweat_smile:

salve a tutti,dopo varie prove con il sensore hy-srf05 ho deciso di sostituirlo con un HC-SR04 (che già avevo),ma dopo innumerevoli modifiche sono riuscito a mandarlo dritto, però non rileva alcun ostacolo e va a sbattere.
Avendo confermato che si tratta di un problema di codice vi chiedo un’aiuto,anzi vi supplico, infatti non ho mai programmato arduino per dei sensori ad ultrasuoni :sweat_smile:

Vi posto qui sotto l’ultimo codice che ho fatto:

int triggerPort = 52;
int echoPort = 53;
const int en1 = 2; //pin enable
const int en2 = 3;
const int m1fd = 22; //controlli motore
const int m2fd = 23;
const int m1bk = 24;
const int m2bk = 25;
const int sterzo = 800; //durata dello sterzo
long duration;
long sinista;
int motore1 = 67;//pwm motore dx
int motore2 = 74;//pwm motore sx

void setup() {
  pinMode( triggerPort, OUTPUT );
  pinMode( echoPort, INPUT );
  pinMode(m1fd, OUTPUT);
  pinMode(m1bk, OUTPUT);
  pinMode(m2fd, OUTPUT);
  pinMode(m2bk, OUTPUT);
  pinMode(en1, OUTPUT);
  pinMode(en2, OUTPUT);
  analogWrite(en1,motore1);
  analogWrite(en2,motore2);
  digitalWrite(m1bk,LOW); // avanti
  digitalWrite(m2bk,LOW);
  digitalWrite(m2fd,HIGH);
  digitalWrite(m1fd,HIGH);   

}
void loop() {
  //porta bassa l'uscita del trigger
  digitalWrite( triggerPort, LOW );
  //invia un impulso di 10microsec su trigger
  digitalWrite( triggerPort, HIGH );
  delayMicroseconds( 10 );
  digitalWrite( triggerPort, LOW );
  long duration = pulseIn( echoPort, HIGH );
  long r = 0.034 * duration / 2;


  if( r > 15 && r <= 50){

    digitalWrite(m1fd,LOW); //ferma
    digitalWrite(m2fd,LOW);
    digitalWrite(m1bk,LOW);
    digitalWrite(m2bk,LOW);
  }

  {
    digitalWrite(m1fd,LOW); //destra
    digitalWrite(m2fd,HIGH);
    digitalWrite(m1bk,HIGH);
    digitalWrite(m2bk,LOW);

  }
  {
    digitalWrite(m1bk,LOW); //avanti
    digitalWrite(m2bk,LOW);
    digitalWrite(m2fd,HIGH);
    digitalWrite(m1fd,HIGH); 
  }
}

Vi ringrazio moltissimo per il tempo che mi state dedicando e vi ringrazio già da ora per delle vostre eventuali risposte.

Fedrix

Per i sensori ad ultrasuoni io ho sempre usato una libreria. http://playground.arduino.cc/Code/NewPing oppure https://code.google.com/p/arduino-new-ping/

Qui un tutorial senza libreria, fatta con pulsein: http://www.instructables.com/id/Simple-Arduino-and-HC-SR04-Example/step3/Upload-the-sketch/

Grazie mille, ora gli darò un occhiata.

Salve a tutti,seguendo il consiglio di “nid69ita” ho cercato di cambiare l’esempio per le mie necessità,sono riuscito a far girare il robot se la distanza dall’ostacolo è minore di 50cm,ma subito sorgono 2 problemi:

1-non riesco a capire come far andare avanti il robot dopo che ha girato.
2-il robot gira dopo circa 2 secondi anche se la distanza dall’ostacolo è di circa 2 metri.

probabilmente mi sono buttato su un progetto più grandi delle mie possibilità,quindi vi chiedo se poteste dirmi dove è che sbaglio e magari darmi delle indicazioni su come correggere i miei errori.
qui sotto ecco l’ultimo codice che ho scritto:

#define trigPin 13
#define echoPin 12
const int en1 = 2; //pin enable
const int en2 = 3;
const int m1fd = 22; //controlli motore
const int m2fd = 23;
const int m1bk = 24;
const int m2bk = 25;
int motore1 = 67;//pwm motore dx
int motore2 = 74;//pwm motore sx

void setup() {
  pinMode(trigPin, OUTPUT);
  pinMode(echoPin, INPUT);
  pinMode(m1fd, OUTPUT);
  pinMode(m1bk, OUTPUT);
  pinMode(m2fd, OUTPUT);
  pinMode(m2bk, OUTPUT);
  pinMode(en1, OUTPUT);
  pinMode(en2, OUTPUT);
  analogWrite(en1,motore1);
  analogWrite(en2,motore2);
  digitalWrite(m1bk,LOW);
  digitalWrite(m2bk,LOW);
  digitalWrite(m2fd,HIGH);
  digitalWrite(m1fd,HIGH);   
}

void loop() {
  long duration, distance;
  digitalWrite(trigPin, LOW);  // Added this line
  delayMicroseconds(2); // Added this line
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(10); // Added this line
  digitalWrite(trigPin, LOW);
  duration = pulseIn(echoPin, HIGH);
  distance = (duration/2) / 29.1;
  if (distance < 50) {  // This is where the LED On/Off happens
    digitalWrite(m1fd,HIGH);
    digitalWrite(m2fd,LOW);
    digitalWrite(m1bk,LOW);
    digitalWrite(m2bk,HIGH);
    delay (500);
    
  }

}

Ringrazio anticipatamente tutti coloro che spero mi risponderanno e mi scuso se quello che chiedo e banale.

Fedrix

Aggiungi un else e piloti entrambi i motori in avanti. Così quando vicino ruota, quando lontano va dritto

Sul discorso misura distanza quei sensori vanno bene per misure grandi ? Non è che 50cm sono più o meno a limite e quindi non rileva bene che sei a 2 metri ?

Ho provato ha fare come mi hai detto, ma il robot appena rileva un ostacolo gira a sinistra però poi con campo libero continua a girarsi tondo,qualcuno sa dirmi come farlo funzionare???

ecco il mio codice:

#define trigPin 13
#define echoPin 12
const int en1 = 2; //pin enable
const int en2 = 3;
const int m1fd = 22; //controlli motore
const int m2fd = 23;
const int m1bk = 24;
const int m2bk = 25;
int motore1 = 67;//pwm motore dx
int motore2 = 74;//pwm motore sx

void setup() {
  pinMode(trigPin, OUTPUT);
  pinMode(echoPin, INPUT);
  pinMode(m1fd, OUTPUT);
  pinMode(m1bk, OUTPUT);
  pinMode(m2fd, OUTPUT);
  pinMode(m2bk, OUTPUT);
  pinMode(en1, OUTPUT);
  pinMode(en2, OUTPUT);
  analogWrite(en1,motore1);
  analogWrite(en2,motore2);
  digitalWrite(m1bk,LOW);
  digitalWrite(m2bk,LOW);
  digitalWrite(m2fd,HIGH);
  digitalWrite(m1fd,HIGH);   
}

void loop() {
  long duration, distance;
  digitalWrite(trigPin, LOW);  // Added this line
  delayMicroseconds(2); // Added this line
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(10); // Added this line
  digitalWrite(trigPin, LOW);
  duration = pulseIn(echoPin, HIGH);
  distance = (duration/2) / 29.1;
  if (distance < 50) {  
    digitalWrite(m1fd,HIGH);
    digitalWrite(m2fd,LOW);
    digitalWrite(m1bk,LOW);
    digitalWrite(m2bk,HIGH);
}
else 
{
  digitalWrite(m1bk,LOW);
  digitalWrite(m2bk,LOW);
  digitalWrite(m2fd,HIGH);
  digitalWrite(m1fd,HIGH);   
}

}

Sono veramente disperato,spero riusciate a darmi una mano.

grazie mille Fedrix

fedrix2001:
Ho provato ha fare come mi hai detto, ma il robot appena rileva un ostacolo gira a sinistra però poi con campo libero continua a girarsi tondo,qualcuno sa dirmi come farlo funzionare???

ecco il mio codice:

#define trigPin 13

#define echoPin 12
const int en1 = 2; //pin enable
const int en2 = 3;
const int m1fd = 22; //controlli motore
const int m2fd = 23;
const int m1bk = 24;
const int m2bk = 25;
int motore1 = 67;//pwm motore dx
int motore2 = 74;//pwm motore sx

void setup() {
  pinMode(trigPin, OUTPUT);
  pinMode(echoPin, INPUT);
  pinMode(m1fd, OUTPUT);
  pinMode(m1bk, OUTPUT);
  pinMode(m2fd, OUTPUT);
  pinMode(m2bk, OUTPUT);
  pinMode(en1, OUTPUT);
  pinMode(en2, OUTPUT);
  analogWrite(en1,motore1);
  analogWrite(en2,motore2);
  digitalWrite(m1bk,LOW);
  digitalWrite(m2bk,LOW);
  digitalWrite(m2fd,HIGH);
  digitalWrite(m1fd,HIGH); 
}

void loop() {
  long duration, distance;
  digitalWrite(trigPin, LOW);  // Added this line
  delayMicroseconds(2); // Added this line
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(10); // Added this line
  digitalWrite(trigPin, LOW);
  duration = pulseIn(echoPin, HIGH);
  distance = (duration/2) / 29.1;
  if (distance < 50) { 
    digitalWrite(m1fd,HIGH);
    digitalWrite(m2fd,LOW);
    digitalWrite(m1bk,LOW);
    digitalWrite(m2bk,HIGH);
}
else
{
  digitalWrite(m1bk,LOW);
  digitalWrite(m2bk,LOW);
  digitalWrite(m2fd,HIGH);
  digitalWrite(m1fd,HIGH); 
}

}





Sono veramente disperato,spero riusciate a darmi una mano.

grazie mille Fedrix

Ciao, non ho mai usato sensori ultrasuoni e stavo cercando di capire come funziona il tuo codice. Una cosa:
Perchè questo:

digitalWrite(m1bk,LOW);
  digitalWrite(m2bk,LOW);
  digitalWrite(m2fd,HIGH);
  digitalWrite(m1fd,HIGH);

Nel setup??? Immagino per farlo partire dritto… Ma se lo hai già nel loop, nell’else, non capisco il senso.
Seconda cosa: Potresti aiutarti con qualche Serial.print per capire quello che succede. Tienilo attaccato al pc, lo tieni sollevato da terra e impegni il sensore con la mano. Mettine uno appena prima dell’if che ti dia la distanza rilevata dal sensore.
Leggi distance, e appena prima di distance leggi duration. Almeno sai quale dei due è sbagliato.
Non ho mai usato sensori ultrasuoni, ma ti posto un codice che secondo me può esserti d’aiuto.

Azz dall'ebook non riesco a copiarlo. Oggi pomeriggio vedo se riesco a recuperarlo altrove. Funzionasse col tuo sensore potresti implementarci il controllo dei motori perchè ti dà proprio una misura in distanza.

Garda, mi ,basta anche una foto, me lo copierò a mano :grinning: :grinning: . Un altra cosa quando collego il sensore hy-srf05 con il pin OUT dove va collegato? Io non l'ho collegato, potrebbe dipendere da questo???

Grazie mille a tutti

fedrix2001:
Garda, mi ,basta anche una foto, me lo copierò a mano :grinning: :grinning: .
Un altra cosa quando collego il sensore hy-srf05 con il pin OUT dove va collegato?
Io non l’ho collegato, potrebbe dipendere da questo???

Grazie mille a tutti

Ok, foto fatta. Se mi scrivi una mail a cui mandarla te le mando. Qua non so come cavolo allegare qualcosa. Nello schema che ho io sul libro i pin che escon dal sensore son tutti collegati. Ho fatto foto anche a quello.

fra poco ti mando la mia mail tra i messaggi personali solo un attimo...

dopo numerosissimi tentativi ho capito che questo progetto e sopra la mia portata per cui chiedo a qualcuno di buona volontà se cortesemente ha la voglia di correggere i miei errori oppure se qualcuno ha fatto un progetto come il mio se potrebbe inviarmi il codice, questo non lo faccio per avere la cosiddetta “pappa pronta”,ma solo perchè arrivato a questo punto non so cosa fare e perchè poi quel codice lo capirò e in modo tale che in futuro sarò in grado di farlo.

Per informativa a chi avesse fatto un progetto simile al mio qui sotto lo descrivo:
Il mio robot è mosso da 2 motoriduttori 12v alimentati esternamente e controllati tramite una schedina che monta un l298n,il sensore è un hy-srf05 ma potrei nanche usare un HC-SR04(dato che già lo ho) e soprattutto uso un Arduino Mega2560

Mentre il codice che attualmente uso è questo:

int durata;            // durata dell'impulso
int distanza;          // distanza dell'oggetto
int pin_segnale = 8;   // pin Arduino a cui è collegato l'SRF05
const int en1 = 2; //pin enable
const int en2 = 3;
const int m1fd = 22; //controlli motore
const int m2fd = 23;
const int m1bk = 24;
const int m2bk = 25;


void setup()
{
  pinMode(m1fd, OUTPUT);
  pinMode(m1bk, OUTPUT);
  pinMode(m2fd, OUTPUT);
  pinMode(m2bk, OUTPUT);
  pinMode(en1, OUTPUT);
  pinMode(en2, OUTPUT);
  digitalWrite(en1, HIGH);
  digitalWrite(en2, HIGH);
  digitalWrite(m1bk,LOW);
  digitalWrite(m2bk,LOW);
  digitalWrite(m2fd,HIGH);
  digitalWrite(m1fd,HIGH); 


}


void loop()
{
  pinMode(pin_segnale, OUTPUT);
  digitalWrite(pin_segnale, LOW);
  delayMicroseconds(2);
  digitalWrite(pin_segnale, HIGH);
  delayMicroseconds(10);
  digitalWrite(pin_segnale, LOW);
  pinMode(pin_segnale, INPUT);
  durata = pulseIn(pin_segnale, HIGH);
  distanza = durata/58;




  if (distanza <= 5 )
  { //se la distanza dell' ostacolo dal robot e minore o uguale a 25cm il robot va indietro
    // sterza
    digitalWrite(m1fd,LOW);
    digitalWrite(m2fd,HIGH);
    digitalWrite(m1bk,HIGH);
    digitalWrite(m2bk,LOW);
  }
  else
  {
    digitalWrite(en1, HIGH);
    digitalWrite(en2, HIGH);
    digitalWrite(m1bk,LOW);
    digitalWrite(m2bk,LOW);
    digitalWrite(m2fd,HIGH);
    digitalWrite(m1fd,HIGH); 
  }

}

Che presenta i seguenti problemi:
-dopo circa 2 secondi di attivita anche se davanti al sensore non ce nulla il robot inizia a sterzare.
-quando sterza non si ferma più, gira in tondo all’infinito.

Ringrazio anticipatamente tutti coloro che spero mi risponderanno e mi congratulo veramente con tutto il forum perchè è davvero molto importante per chi come me è alle prime armi con arduino.

Grazie mille.

Fedrix

Molto male arrenderti. Usa dei serial print per trovare l'errore e vedrai che lo trovi!!! Quando gira cerca di capire perchè lo fa. Magari è una questione di sensibilità del sensore, di orientamento (sicuro che non veda il pavimento???). Non ti arrendere.

ok ora provo

Togli il pinmode dal loop, sposta in setup. Togli i digutal write dal setup, nin servono. Pilota due led su if ed else eliminando i motori, muovendoko con le mani puoi capire in realtime se il sensore fa ciò che vuoi, potrebbero esserci problemi alla scheda dei motori, così te ne accorgi. Ancge dei serial print du debug vanno bene, ma forse ti è più intuitivo il segnale dei led, scegli tu.

Arrendersi.... Mai :grinning:

Ok ora provo, ma credo che dovrò aspettare una settimanella per tornare a lavorare a questo progetto: a scuola è tempo di verifice ... :slightly_frowning_face: