problema rc car + arduino + sensore ultrasuoni

Salve a tutti,
vorrei collegare un arduino uno ad una rc car da pochi euro. Inoltre tramite l'utilizzo di un sensore ad ultrasuoni farle evitare gli ostacoli.

La macchinina è equipaggiata di motori DC e prevede l'utilizzo di tre batterie ministilo da 1,5 V.
Ho collegato l' arduino ad una board L298, e le uscite della board ai due motorini, come alimentazione ho montato una batteria da 9 V che va a fungere sia da alimentazione dell' arduino tramite il vin che da alimentazione dei motori ( la scheda provoca una caduta di tensione di circa 2 V quindi dovrebbero arrivare 6 V in luogo di 4,5 V ma sono disposto a rischiare di accorciare la vita ai motorini).
Scrivendo un semplicissimo sketch, che dice alla macchinina di andare avanti, controllare la distanza dall'ostacolo fornita dal sensore, invertire il senso di marcia e girare per 1,5 secondi se questa è inferiore a 10 cm poi riprendere il cammino; ho un problema:

la macchinina dopo pochissimo tempo non riesce più a muoversi, sollevata sembra fare quanto richiesto nello sketch.
sostituendo l'alimentazione dei motori con 6 V di un alimentatore collegato alla rete la macchinina si muove perfettamente quindi credo sia un problema di scarsa corrente(la board dovrebbe poterne fornire a sufficienza), ma non capisco come potesse muoversi prima con le pile da 4,5 V e non muoversi dopo con la batteria da 9 V.

la board L298 è questa:

qualcuno può aiutarmi?

la batteria da 9V ti dura pochissimo e non ha nemmeno la capacita' dei picchi di corrente necessari, non a caso le pile transistor le trovi nei telecomandi, ma non nelle macchinine

Nkn ci avevo minimamente pensato.... grazie. Quindi mi consigli di usare la 9v per arduino e le ministilo in serie per i motori? O dovrei comprare una lipo ? Ho visto che parecchi usano questo tipo per le macchine rc

la lipo ha come pro le piccole dimensioni a parita' di potenza, ma anche lei ha le sue rogne, sia per ricaricarla che come correnti di scarica da rispettare.
Io inizierei ad usare 4 semplici stilo non ricaricabili, delle belle alcaline, e quindi alimentare a 6V tutto. Poi in futuro decidi come passare alle ricaricabili se necessario.

grazie 1000 per le info :slight_smile:

mi metto in coda a questo post. Per non aprirne uno simile.

Anche io vorrei realizzare una macchinina RC controllata da arduino. Pensavo di usare una gig nikko vecchia che ho oppure comprarne una scadente dal cinese tanto per iniziare.

Ora da quello che ho capito, oltre arduino ho bisogno almeno della board per i motori. poi pensavo di prendere un modulo wi fi o bluethoot per comandarla dal PC.

Sull'elettronica penso di potermela cavare con qualche tutorial. Sulla parte di programmazione, per ora, il buio.

per la macchinina, al fine di semplificare il tutto pensavo di prendere quelle con i due motori contrapposti, tipo carro ramato per capirci. così da non avere un ulteriore servo da comandare. però vedo che alla fine sulla board dovrebbe essere facile anche mettere le ruote sterzanti.
quanto è difficile secondo voi questo progetto?

ciao, anche io sono all'inizio per ora non ho trovato grandissime difficoltà.
Ho comprato una macchinina da 6 euro l'ho aperta e aveva due motorini DC uno per comandare le ruote post e uno per la sterzata ho tagliato i cavetti che li collegavano alla scheda di controllo e li ho collegati ad una board L298 (puoi comprare anche la motorshield è piu' comoda ma costa di piu' oppure puoi comprare un integrato della serie L293 e risparmi ancora di piu' ma hai meno corrente in uscita, per la gig nikko mi sa che non va bene).
Inoltre ho comprato e collegato ad arduino un sensore ad ultrasuoni che mi da la distanza dall'ostacolo.
la parte piu' difficile e' fare buoni collegamenti.
In sostanza la programmazione è molto semplice: ho scritto delle funzioni avanti() indietro() destra() sinistra() fermo() e scan() che comandano in maniera opportuna i motorini e il sensore
la scheda ti da un enable e 2 segnali per ogni motore se uno è alto e l'altro è basso il motore va in un senso antrimenti nell'altro se sono uguali rimane fermo.
per il sensore il programmino si trova in rete.
grossolanamente nel loop fai :
avanti()
scan()
if( distanza < 10){
indietro()
sleep(1000)
sinistra()
sleep(1000)
}
ed è fatto!
Secondo me è fattibile come primo progetto, ci sono quasi riuscito devo solo affinare il tutto
pure io volevo comprare una wifi shield ma costa tantissimo! mi sa che cercherò un ripego.

ho comprato le batterie ministilo, va meglio ma sembra sempre che la corrente sia poca soprattutto dopo un po' di tempo gli devo dare le bottarelle senno' rimane ferma.

sono tornato all'alimentatore a muro, e ho un altro problema:
la macchina va a sbattere contro l'ostacolo, io ho settato 20 cm come distanza alla quale la macchina deve invertire il senso di marcia sterzare e andare avanti, invece la macchina o sbatte o si ferma giusto in tempo eppure il sensore sembra avere una buona dinamica, forse è l'inerzia e il pavimento scivoloso?
ho risolto usando il pwm e facendola andare piu' piano pero' è sorto un ulteriore problema cioè quando sterza e va avanti è come se richiedesse troppa corrente e rimane ferma anche se uso l'alimentatore

avete dritte da darmi?

il codice che uso cmq è il seguente :

//motore anteriore
int m1 = 3;
int m1_a = 4;
int m1_b = 5;
//motore posteriore
int m2 = 9;
int m2_a = 6;
int m2_b = 7;
//sensore ultrasuoni
int ali = 11;
int triggerPort = 12;
int echoPort = 13;
//luce
int L1 = 1;
int L2 = 2;


int ferma(){
analogWrite( m2, 255 );
digitalWrite( m2_a, LOW );
digitalWrite( m2_b, LOW );
}
void avanti(){
analogWrite( m2, 255 );
digitalWrite( m2_a, LOW );
digitalWrite( m2_b, HIGH );
}
int indietro(){
analogWrite( m2, 155 );
digitalWrite( m2_a, HIGH );
digitalWrite( m2_b, LOW );
}
void sx(){
digitalWrite( m1, HIGH );
digitalWrite( m1_a, LOW );
digitalWrite( m1_b, HIGH );
}
void dx(){
digitalWrite( m1, HIGH );
digitalWrite( m1_a, HIGH );
digitalWrite( m1_b, LOW );
}

void dritto(){
digitalWrite( m1, HIGH );
digitalWrite( m1_a, LOW );
digitalWrite( m1_b, LOW );
}
int scan(){
  //porta bassa l'uscita del trigger
digitalWrite( ali, HIGH );
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;
 
Serial.print( "durata: " );
Serial.print( duration );
Serial.print( " , " );
Serial.print( "distanza: " );
 
//dopo 38ms è fuori dalla portata del sensore
if( duration > 38000 ) Serial.println( "fuori portata");
else { Serial.print( r ); Serial.println( "cm" );}
 
//aspetta 1.5 secondi
delay( 500 );
return r;
}
void ostacolo(){
  ferma;
  delay(500);
indietro();
  delay( 1500 );
  dx();
  avanti();
delay( 2500 );
dritto();
}
void setup() {
pinMode( L1, OUTPUT );
pinMode( L2, OUTPUT);
  
pinMode( m1, OUTPUT );
pinMode( m1_a, OUTPUT);
pinMode( m1_b, OUTPUT );
pinMode( m2, OUTPUT );
pinMode( m2_a, OUTPUT );
pinMode( m2_b, OUTPUT );
pinMode( triggerPort, OUTPUT );
pinMode( echoPort, INPUT );
pinMode( ali, OUTPUT );

Serial.begin( 9600 );
Serial.println( "Sensore ultrasuoni: ");
 
}

 
void loop() {
digitalWrite( L2, HIGH );
digitalWrite( L1, LOW );
int m=0;
m= scan();
Serial.print( m);

while(m>20)

{
   m=scan();
  avanti();

}

ostacolo();
}

misurala sta corrente, altrimenti vai a spanne

ho comprato un tester! allora col trasformatoreimpostato a 6V ho una corrente di 0,36-0,4 A e 5,01 V sul motorino, mentre con 4 batterie ministilo in serie ho una corrente di 0,25-0,29 A e circa 4V (indi deduco si siano già scaricate)

possibile che devo mettere 4 ministilo in serie e 4 in parallelo? la macchinina prima si muoveva egregiamente con 3 ministilo in serie.

mezzo Ampere e' tantissimo, le ministilo ti dureranno sempre poco, se vuoi sapere di preciso cerca le caratteristiche delle ministilo che stai usando e vedi quanto tempo ti durano con quei consumi,
Per il discorso invece della logica di funzionamento vedo che hai molti delay nel tuo sketch, che bloccano il micro, quindi l'ostacolo viene rilevato male, dovresti eliminarne il piu' possibile passando alla funzione millis (vedi esempio blink withoutdelay)

A quanto ho capito stai utilizzando un solo pacco batterie sia per l'arduino che per i motori, giusto?
Ti consiglio di separare l'alimentazione utilizzando una batteria a 9 v per l'arduino ed un secondo pacco batterie per l'alimentazione dei motori, così facendo le tue batterie dureranno qualcosa in più.
Per quanto riguarda il codice devi togliere un pò di delay e aumentare la distanza minima dall'ostacolo trovando la giusta distanza di arresto per evitare di sbattere, magari utilizzando il "freno" ponendo entrambi gli imput (es. Input1 e input2) LOW o HIGH.

Io ho utilizzato una GIG NIKKO radiocomandata, il vano batterie dell'auto lo uso per l'alimentazione del motor driver e dei motori e una batteria a 9 V alimenta l'arduino e il sensore ad ultrasuoni.

un ulteriore consiglio monta un interruttore per spegnere l'arduino quando non lo devi utilizzare

alexio grazie anche a te per l'aiuto, la situazione attuale è :

  • le alimentazioni sono separate, uso una 9V per arduino e un alimentatore a tensione variabile impostata 6V o 7,5V vorrei ottenere il funzionamento prima così e poi vedere di usare le batterie ministilo (poichè mi durano un 15 min)

  • ho aggiornato la funzione scan() del sensore eliminando il delay e sostituendolo con un while che sfrutta la funzione mills() e la dinamica è migliorata tantissimo infatti ora si ferma immediatamente.

-nel corpo del programma:

void loop() {

int m=0;

Serial.print( m);
m= scan();
while(m>20)

{
  m= scan();
  
  avanti();

}
m= scan();
ostacolo();
}

ho un problema se nel sottoprogramma ostacolo()
che dovrebbe fare,
indetro();
dx();
delay(1500);
diritto();
avanti();

quando vado ad utilizzare:

unsigned long currentMillis2 = millis();
 while(currentMillis2 - previousMillis2 > 1500) {
    // save the last time you blinked the LED 
    previousMillis2 = currentMillis2;}

al posto di delay(1500) arduino non lo vede proprio ignora tutto il sottoporgamma, se apposto di tutto il blocco metto ferma(); o indietro(); funziona egregiamente, se metto indetro(); dx(); esegue solo la prima istruzione....
mi sto un po avvilendo....

alexio magari mi faresti buttare un' occhio al tuo sketch.

Questo è il mio codice, o per lo meno quello che sono riuscito a trovare, non uso sempre lo stesso pc per programmare l'arduino quindi non ricordo se questa è l'ultima versione o meno

#include <Servo.h>

/* GIGNIKKO_RobotCar 
by Alessio Ciofi

Nel progetto è stato utilizzato:
- Una automobilina telecomandata abbastanza grande da poter contenere le schede.
- Un sensore ad ultrasuoni HC RS04.
- Un servo motore.
- Una scheda Arduino Motor shield.
- Una scheda Arduino uno v.3

*/
int triggerPort = 7;
int echoPort = 6;
Servo myservo;
int pos = 90;
int vel;

void setup (){
  
  pinMode (triggerPort, OUTPUT);
  pinMode (echoPort, INPUT);
  Serial.begin (9600);
  Serial.println("sensore ultrasuoni:");
  myservo.attach(5);
  pinMode(12, OUTPUT);
  pinMode(9, OUTPUT);
  pinMode(13, OUTPUT);
  pinMode(8, OUTPUT);
}
  long funzionesonar(){
  
    digitalWrite(triggerPort, LOW);
    digitalWrite(triggerPort, HIGH);
    delayMicroseconds(10);
    digitalWrite( triggerPort, LOW);
    long durata = pulseIn (echoPort, HIGH);
    long distanza = durata * 0.034 /2;  
    delay(500);
    Serial.println(distanza);
    return distanza;
}

void Ferma(){
    digitalWrite(8, HIGH);
    digitalWrite(11,HIGH); 
    analogWrite(3,0);
    analogWrite(11,0);
    
  }
  
void Indietro(){
  analogWrite(11,0);
  digitalWrite(8, HIGH);
  digitalWrite(9, HIGH);
  delay(100);
  digitalWrite(12, LOW);
  digitalWrite(9, HIGH);
  analogWrite(3, vel);
  delay(1500);
  Serial.println("Indietro"); 
    
}

void Avanti(){
  
  analogWrite(11,0);
  digitalWrite(8,HIGH);
  digitalWrite(9,HIGH);
 
  digitalWrite(12,HIGH);
  digitalWrite(9,LOW);
  analogWrite(3,vel);
  
  Serial.println("Avanti");
  
}

void SvoltaSx (){
  
  digitalWrite(9,HIGH);
  digitalWrite(8,HIGH);
  delay(100);
  digitalWrite(13, LOW);
  digitalWrite(8, HIGH);
  analogWrite(11, 255);
  
  digitalWrite(12, HIGH);
  digitalWrite(9, LOW);
  analogWrite(3, vel);
  delay(1500);
    
  Serial.println("SX");
  
}

  void SvoltaDx (){
  
    digitalWrite(9,HIGH);
    digitalWrite(8,HIGH);
    delay(100);
    digitalWrite(13, HIGH);
    digitalWrite(8, LOW);
    analogWrite(11, 255);
    digitalWrite(12, HIGH);
    digitalWrite(9, LOW);
    analogWrite(3, vel);   
    delay(1500);
    Serial.println("DX");
  
}

void loop (){
  long cx, sx, dx;
  
  long distanza = funzionesonar();
  
  if (distanza < 150) {
    vel=200;
    
  }else vel=255;
   
  if (distanza > 100) Avanti();
    
  else{
    // Attesa scelta servo-sensore
    Ferma();    
    myservo.write(90);
    cx = funzionesonar();
    delay(500);
    
    myservo.write(120);
    sx = funzionesonar();
  
    delay(500);
    
    myservo.write(60);
    dx = funzionesonar();
 
    myservo.write(90);
    if (cx<35) Indietro();
    if (dx<35) Indietro();
    if (sx<35) Indietro();
    else{
    if (sx>dx) SvoltaSx();
    else SvoltaDx();
    }
  
  }
}

la variabile vel non prenderla in considerazione, quando ho scritto questo sketch, ero convinto (poichè riportato su numerosi progetti non solo sul web ma anche in alcuni testi che parlano di arduino) che potesse regolare la velocità dell'automobilina attraverso l'impostazione del segnale pwm sull'ingresso enable del motor driver; ma come potrai constatare in un altro topic di questo forum l298 da corrente ad arduino - Hardware - Arduino Forum non risponde al modo più idoneo all'utilizzo del motor driver. il valore della variabile vel dovrà essere HIGH o LOW in modo da attivare + o - il motor driver.
ATTENZIONE. il mio progetto include un servo motore che si attiva facendo ruotare il sensore ultrasuoni a dx e a sx, quando il sensore intercetta un ostacolo, in modo da verificare la via di uscita per poi intraprenderla.
Il codice è sempre perfezionabile, per questo è bello incontrarsi in forum come questo. Spero che questo sketch possa darti uno spunto per perfezionare il tuo codice

grazie! sono stato un po' indaffarato per questo non ho risposto prima cmq l'ultima volta la macchinina andava molto meglio.

vorrei chiedervi un consiglio per il compleanno volevo regalarmi qualcos' altro per arduino magari per estendere il progetto macchinina.

ad esempio il piccolo servomotore per ruotare l'ultrasuoni di cui parlava alexio e un lcd con controller seriale.
Inoltre ho visto la shield wifi ma è parecchio costosa (89euro) quelle da 40 adafruit sono tute esaurite, mi sembra piu' conveniente un l'arduino yun(65 euro) , mi piaceva anche l'xbee sfruttabile per un eventuale futuro quadricottero ma il prezzo va su.

poi ho pensato che per comandare la macchinina basterebbe un modulo bluetooth molto meno costoso e potrei prendere un ethernet shield molto meno costosa per continuare a giocare.

mi dareste qualche suggerimento?

il bluetooth puoi usarlo, parliamo di una decina di metri di distanza raggiungibile.
altra possibilita' i trasmettitori rf, vendono l'accoppiata tx rx a pochi euro

per il discorso wifi intendi sempre sulla macchinina ? altrimenti se e' per studio o cmq progetti fissi prendi la eth schield, i concetti da apprendere saranno poi utilizzabili un domani sul wifi, e nel frattempo spendi poco.

se decidi per il BT cerca la guida di Pitusso, e' fatta molto bene. Io ho usato un HC-07 per un mio progetto

si la wifi la volevo usare per comandare la macchinina, che ne pensi dell'arduino yun? è stupido prenderlo avendo un arduino uno?
pero' ho letto che è parecchio diverso, se ho capito bene, dovrebbe essere un pc completo con sistema operativo wifi e ethernet shield piu' l'I/O tipico di arduino.

prendere su robot-italy una ethernet shield (compativile) un modulo relè un LCD seriale e un bluetooth HM-10 (dovrebbe essere molto simile all' HC-07) mi verrebbe a costare circa 71.20 euro arduino yun verrebbe a costare 71.02....

quale delle due soluzioni è piu' interessante?

Spetta un attimo
Bt e ethernet non centrano nulla, la macchinina o la fai bt o via rete.
Visto che una macchina con un cavo di rete non ha senzo devi decidere tra wifi-schield o bt-schield da innestare sulla uno.
Oppure la sola yun, ma ti serve più esperienza.

sisi ovvio lo so la shield ethernet la prendevo per farci qualcos'altro o abbinargli un router con openwrt magari piu' in là.

cmq alla fine ho preferito prendere piu' componenti rispetto alla sola yun , ciao

Ciao, sto cercando di fare la stessa cosa su un altra macchinina (Nikko Max) ma non capisco uno cosa: sul servo tu hai messo il sonar? Se si come? io utilizzo il servo già presente nella macchina. Collego il motore all'uscita Motor A e il servo a Motor B ma non funziona.

Immagine shield: http://fabtolab.com/image/cache/data/Accessories/Motors/Controllers/l298n-function.-900x700.jpg