Robot con hc-sr04

Buongiorno, sto realizzando un robot che si muove autonomamente come tesina scolastica
Nelle ultime settimane il mio professore mi ha chiesto di sostituire i delay con altre funzioni in modo che il robot possa sempre leggere la distanza dagli oggetti
Il programma che ho sviluppato funziona abbastanza bene solo che alcune volte il sensore restituisce valori totalmente sbagliati (anche 0.4 come se non leggesse nulla).
Non riesco a capire perchè si comporti in questo modo visto che uso la libreria ultrasonic che da sola va benissimo; forse Arduino è troppo poco veloce?
come componenti ho usato:
arduino uno
sensore ultrasuoni hc-sr04
un servo
un ponte h che controlla due motori

arduino, il servo e il sensore sono alimentati da una pila da 9 V mentre il resto da 4 pile AA da 1.5 v

#include <Ultrasonic.h>
  #include <Servo.h> 
 
  Servo myservo;  // create servo object to control a servo 
                // a maximum of eight servo objects can be created 
                
  //pin sensore
  #define TRIGGER_PIN  12
  #define ECHO_PIN     13
  #define RED_LED      9
  #define GREEN_LED    8 
  
  //motore A sinistro
  const int motorAPin1 = 4;    // H-bridge leg 1 (pin 2, 1A) 21 su basetta
  const int motorAPin2 = 3;    // H-bridge leg 2 (pin 7, 2A) 20 su basetta
  
  //motore B destro
  const int motorBPin1 = 6;    // H-bridge leg 1 (pin 2, 1B) 16 su basetta
  const int motorBPin2 = 5;    // H-bridge leg 2 (pin 7, 2B) 17 su basetta
  
  //vcc 18 su basetta 
  //gnd 19 su basetta

  int angolo=0,flag=0;
  float cmMsec, x ,cmdx=16,cmsx=16; //x variabile in cui metto la distanza minima dall'ostacolo
  unsigned long int time,old_time,old_time_s=0;

   
  Ultrasonic ultrasonic(TRIGGER_PIN, ECHO_PIN);
 
  void setup() {
   
 
 
    // set all the other pins you're using as outputs:
    pinMode(motorAPin1, OUTPUT); 
    pinMode(motorAPin2, OUTPUT); 
    pinMode(motorBPin1, OUTPUT); 
    pinMode(motorBPin2, OUTPUT);
    pinMode(TRIGGER_PIN, OUTPUT);  
    pinMode(ECHO_PIN, INPUT); 
    pinMode(RED_LED, OUTPUT);  
    pinMode(GREEN_LED, OUTPUT);
	
	old_time=millis();
	time=millis();
    
     myservo.attach(10); // piedino che controlla servo
     giraservo(160);

     Serial.begin(9600);
  }
 
  void loop() {
  
     long microsec = ultrasonic.timing();
	 
	 time=millis();
	 
	  x=15;

    // controllo se ci sono ostacoli

	if(angolo==0 || angolo==2)
    { cmMsec = ultrasonic.convert(microsec, Ultrasonic::CM);
      Serial.print("primo ");
      Serial.print(cmMsec);
    }
	else
		if(angolo==1)
			{
			 cmsx = ultrasonic.convert(microsec, Ultrasonic::CM);
			 Serial.print("sx ");
			 Serial.print(cmsx);
			}
		else
			if(angolo==3)
				{
					cmdx = ultrasonic.convert(microsec, Ultrasonic::CM);
					Serial.print("dx ");
					Serial.print(cmdx);
				}

	
	 /*scelgo dove far girare il sensore
       caso 0 da 160 a 100
       caso 1 da 100 a 60
       caso 2 da 60 a 100
       caso 3 da 100 a 160   */
	if(time>=old_time+100)
	{
		switch (angolo)
		{
		  case 0:{
				  angolo=1;
				  giraservo(100);
				}break;
		  case 1:{
				  angolo=2;
				  giraservo(60);
				}break;
		 case 2:{
				  angolo=3;
				  giraservo(100);
				}break;
		  case 3:{
				  angolo=0;
				  giraservo(160);
				}break;
		}
        old_time=millis();
	}
	if(cmMsec < x || cmsx< x || cmdx<x) 
      { 
		  fermo(0);
		  if(cmdx<=cmsx)
		  {
			//vado a sinistra
			sinistra(600);
			fermo(0);
                        
		  }
		  else
		  {
			//vado a destra
			destra(600);
			
			fermo(0);	
		  }    
        cmdx=16;
        cmsx=16;
        cmMsec=16;
		
    }
    else
    {		
    // no ostacoli va dritto
	dritto(0);	
    }	
delay(500);
}
 
 
 void sinistra(int tempo)
	 {
	    digitalWrite(motorBPin1, HIGH);   // set leg 1 of the H-bridge low
	    digitalWrite(motorBPin2, LOW);  // set leg 2 of the H-bridge high 
	    digitalWrite(motorAPin1, LOW);   // set leg 1 of the H-bridge low
	    digitalWrite(motorAPin2, HIGH);  // set leg 2 of the H-bridge high 
	    delay(tempo);
	 }
void destra(int tempo)
    {
    digitalWrite(motorAPin1, HIGH);   // set leg 1 of the H-bridge low
    digitalWrite(motorAPin2, LOW);  // set leg 2 of the H-bridge high 
    digitalWrite(motorBPin1, LOW);   // set leg 1 of the H-bridge low
    digitalWrite(motorBPin2, HIGH);  // set leg 2 of the H-bridge high 
    delay(tempo);
    }
void fermo(int tempo)
  {
    digitalWrite(motorAPin1, LOW);   // set leg 1 of the H-bridge low
    digitalWrite(motorAPin2, LOW);  // set leg 2 of the H-bridge high
    digitalWrite(motorBPin1, LOW);   // set leg 1 of the H-bridge low
    digitalWrite(motorBPin2, LOW);  // set leg 2 of the H-bridge high 
    delay(tempo);
  }
 void dritto(int tempo)
   {
    digitalWrite(motorAPin1, HIGH);   // set leg 1 of the H-bridge low
    digitalWrite(motorAPin2, LOW);  // set leg 2 of the H-bridge high
    digitalWrite(motorBPin1, HIGH);   // set leg 1 of the H-bridge low
    digitalWrite(motorBPin2, LOW);  // set leg 2 of the H-bridge high  
    delay(tempo);
   }
 void giraservo(int x)
	{
		myservo.write(x);
	}

a fine loop hai un delay(500); salvo che la libreria ultrasonic non usi interrupt, questo ti fa saltare le tempistiche del sensore.

quindi arduino è abbastanza veloce, sei tu che lo rallenti :slight_smile:

scusate ho sbagliato programma...ho messo quello di prova che ho rallentato per poter leggere meglio i valori...in quello vero non c'è quel delay e la distanza minima (x) è di 10 cm...
ma poi scusa capisco come possa interferire...in teoria la ultrasonic avrebbe dovuto essere finita da un pezzo...

ah, ok, la libreria è bloccante, quindi non è quello il problema.

A questo punto o è un errore di libreria oppure un disturbo, magari causato dai servo. Come li alimenti?

il sensore e il servo sono alimentati attraverso arduino che alimentato a sua volta da una pila a 9 V

no! il regolatore di arduino regge pochi ampere (non ricordo bene, mi pare mezzo), mentre un solo servo può raggiungere quell'amperaggio sotto sforzo.. e tu hne hai almeno 2.

Dunque prova il codice senza i servo, o usandone solo uno senza sforzo. Poi devi procurarti un pacco batteria a parte per i servo, l'importante è che colleghi assieme solo il - delle due batterie.

ok...ma il servo che dico non sono i motori...è un HD-1440A che uso per ruotare il sensore...

ah ok, pensavo lo usassi come motore... uhmm. prova comunque a disabilitarlo

Alimenta il servo dai 6V (se lo regge). Consuma troppo per Arduino e per la batteria a 9V.
Ciao Uwe

grazie a tutti per le risposte...
alimentando solo il sensore con la pila da 9 V il problema sembrerebbe risolto...

dico sembrerebbe perchè non riesco a controllare le letture con la seriale perchè per qualche strano motivo il mio arduino non viene più "visto" dal computer...cioè non riesco neanche a vedere la periferica...ho provato a cambiare cavo e/o computer senza nessun risultato...secondo voi cosa può essere? si è guastata la porta dell'arduino?...perchè per il resto il programma che è caricato funziona sia con le pile sia con il cavo collegato al computer (quindi passa corrente) solo che non riesco più a caricare nessun programma perchè il computer non vede la periferica...

hai qualcosa collegato ai pin 0 e 1? hai collegato assime i - delle batterie tra loro e col GND dell'arduino?

no...ho provato anche a smontare tutto e a collegare al computer solo l'arduino senza nessun componente o cavo..

urca mazurca! non avrai mica fritto il chip seriale/usb?

non saprei...ieri quando l'ho collegato l pc me l'ha preso...ma poi subito è sparito e dal quel momento non è più andato

prova da un'altro pc, o da un altro Sistema Operativo, se hai una liveCD di linux (in pratica linux parte da CD senza dover installare nulla, ottimo perchè essendo su CD sai che il problema non è il SO sminchiato)è ora di usarlo :slight_smile:

ho provato come dicevi tu da un ubuntu che avevo su un cd ma anche li non me lo riconosce...credo proprio che si sia rotto qualcosa...

grazie comunque di tutte le risposte...