Problema configurazione programma

salve a tutti. chiedo scusa per la generalità del titolo e arrivo al dunque.
non riesco a configurare la modalità automatica. questo è uno sketch per un auto radiocomandata.

il programma funziona tutto tranne che in questo. o meglio l auto non gira anche se è nel codice ma suona se la distanza è inferiore.

#include <SoftwareSerial.h>
#define echoPin 2 // Pin to receive echo pulse
#define trigPin 3

SoftwareSerial BluetoothSerial = SoftwareSerial(0, 1); //si richiama il modulo bluetooth

const int input1m1 = 9; //input1 per il motore 1
const int input2m1 = 10;//input2 per il motore 2
const int enablem1 = 11;//regolatore motore 1
char marcia;
int velmotore = 0;

void setup() {
Serial.begin(9600);
BluetoothSerial.begin(9600); //si stabliscono le variabii generali
pinMode(echoPin, INPUT);// set echopin input
pinMode(trigPin, OUTPUT); // set pin trigger output
pinMode(input1m1, OUTPUT);
pinMode(input2m1, OUTPUT);
pinMode(enablem1, OUTPUT);
pinMode(6, OUTPUT);
pinMode(7, OUTPUT);
}

void loop() {
if (BluetoothSerial.available()){
marcia=BluetoothSerial.read(); //vengono lette le marce e di conseguenza la velocità

if(marcia==‘1’){
velmotore = 25;
}

if(marcia==‘2’){
velmotore = 51;
}

if(marcia==‘3’){
velmotore = 76;
}

if(marcia==‘4’){
velmotore = 102;
}

if(marcia==‘5’){
velmotore = 127;
}

if(marcia==‘6’){
velmotore = 153;
}

if(marcia==‘7’){
velmotore = 178;
}

if(marcia==‘8’){
velmotore = 204;
}

if(marcia==‘9’){
velmotore = 229;
}

if(marcia==‘q’){
velmotore = 254;
}

if (marcia==‘U’){
inizio:
digitalWrite(trigPin, LOW); // Set the trigger pin to low for 2uS
delayMicroseconds(2);
digitalWrite(trigPin, HIGH); // Send a 10uS high to trigger ranging
delayMicroseconds(10);
digitalWrite(trigPin, LOW); // Send pin low again
int distance = pulseIn(echoPin, HIGH); // Read in times pulse
distance= distance/58;
if((distance>30)&&(distance!=0)){ // a volte arrivano degli zeri e quelli non li devo prendere in considerazione
digitalWrite(input1m1,HIGH); // accendo un motore e spengo l’altro così posso girare
digitalWrite(input2m1,LOW);
analogWrite(enablem1, 150);
}
if((distance<30)&&(distance!=0)){
analogWrite(enablem1, 0); //il motore si ferma e indica col cicalino l’arresto
digitalWrite(7,HIGH);
delay(500);
digitalWrite(7,LOW);
delay(500);
goto inizio;
}
}
if(marcia==‘u’){
digitalWrite(input1m1,HIGH); // accendo un motore e spengo l’altro così posso girare
digitalWrite(input2m1,HIGH);
goto fuori;
}

fuori:
if(marcia==‘W’){
digitalWrite(6,HIGH);
}
if(marcia==‘w’){
digitalWrite(6,LOW);
}
if(marcia==‘V’){
digitalWrite(7,HIGH);
}
if(marcia==‘v’){
digitalWrite(7,LOW);
}
if(marcia==‘F’){
digitalWrite(input1m1, HIGH); //vengono impostati i valori per i quali il motore va avanti
digitalWrite(input2m1, LOW);
analogWrite(enablem1, velmotore); //si imposta la velocità grazie al pin PWM
Serial.print(“avanti”);
}

else{
analogWrite(enablem1, 0); //senza comando il motore si ferma
}

if(marcia==‘B’){
digitalWrite(input1m1, LOW); //vengono impostati i valori per i quali il motore va indietro
digitalWrite(input2m1, HIGH);
analogWrite(enablem1, velmotore); //si imposta la velocità grazie al pin PWM
}
}
}

Il codice devi racchiuderlo nei tag code, vedi sezione 7 del regolamento, spiega bene come fare ( pulsante </> ).
Altrimenti parte del codice può essere visualizzata male o mancare perchè interpretato come attributo del testo stesso.

Io ti consiglio di usare lo switch() come statement:
http://www.tutorialspoint.com/cprogramming/switch_statement_in_c.htm

switch()
{ case '1': velmotore = 25; break; 
  case '2': velmotore = 51; break; 
  ... etc ...
  case 'U': funzU();
}

e tutto quel grosso blocco di ‘U’ lo metti in una funzione void:

void funzU()
{inizio:
 digitalWrite(trigPin, LOW);                   // Set the trigger pin to low for 2uS
 delayMicroseconds(2);
 digitalWrite(trigPin, HIGH);  
}

piccola rettifica sono riuscito a far funzionare la modalità automatica. L'unico problema ora è che non riesco a uscire

if (marcia=='U'){ inizio: digitalWrite(trigPin, LOW); // Set the trigger pin to low for 2uS delayMicroseconds(2); digitalWrite(trigPin, HIGH); // Send a 10uS high to trigger ranging delayMicroseconds(10); digitalWrite(trigPin, LOW); // Send pin low again int distance = pulseIn(echoPin, HIGH); // Read in times pulse distance= distance/58; if((distance>30)&&(distance!=0)){ // a volte arrivano degli zeri e quelli non li devo prendere in considerazione digitalWrite(input1m1,HIGH); //il motore gira digitalWrite(input2m1,LOW); analogWrite(enablem1, 128); } else{ analogWrite(enablem1, 0); //il motore si ferma e indica col cicalino l'arresto digitalWrite(7,HIGH); delay(500); digitalWrite(7,LOW); delay(500); } if(marcia=='u'){ digitalWrite(input1m1,HIGH); // spengo il motore ed esco dalla mod_auto digitalWrite(input2m1,HIGH); goto fuori; } else{ goto inizio; } }

ora come posso fare a risolvere sto fatto? Grazie mille a tutti

Elimina i goto, non sono costrutti che dovrebbero essere usati in C tanto meno da una persona poco esperta.

il goto di uscita funzionava prima. secondo me è il goto di "ciclo", che non lo fa eseguire. se lo sostituissi con un for potrebbe andare? e dentro il for metterei l' if di uscita. che ne dici?

Quando il programma in c viene tradotto in assembly il goto e il while presentano la stessa struttura, ma li stiamo parlando di programmazione poco sopra il livello macchina. In C si tende a deprecare l'utilizzo del goto perchè è un costrutto non necessario che vanifica il paradigma strutturato del linguaggio. Cerca di evitare il goto e optare invece per dei cicli che possano essere while, do while o in casi di enumerazione for. Inoltre il debug di un progetto con while al posto dei goto diventa piu semplice ed immediato. Inizia ad apportare queste modifiche e vedrai che il codice diventerà piu semplice da correggere.

Ps giusto per curiosità gli if else e lo switch compilati hanno praticamente lo stesso peso, cosa che non si puo dire di semplici serie di if e di uno switch, quindi scegli o lo switch o la combinazione di if else ma evita sfilze di if, per il processore significa ogni volta processarli tutti, l'uso degli else consente una gestione piu intelligente.

< if (marcia==‘U’){
for(i=0;i<2;i++){
digitalWrite(trigPin, LOW); // Set the trigger pin to low for 2uS
delayMicroseconds(2);
digitalWrite(trigPin, HIGH); // Send a 10uS high to trigger ranging
delayMicroseconds(10);
digitalWrite(trigPin, LOW); // Send pin low again
int distance = pulseIn(echoPin, HIGH); // Read in times pulse
distance= distance/58;
if((distance>30)&&(distance!=0)){ // a volte arrivano degli zeri e quelli non li devo prendere in considerazione
digitalWrite(input1m1,HIGH); // accendo un motore e spengo l’altro così posso girare
digitalWrite(input2m1,LOW);
analogWrite(enablem1, 200);
}
if((distance<30)&&(distance!=0)){
analogWrite(enablem1, 0); //il motore si ferma e indica col cicalino l’arresto
digitalWrite(7,HIGH);
delay(500);
digitalWrite(7,LOW);
delay(500);
}
if(marcia==‘u’){
digitalWrite(input1m1,HIGH); // accendo un motore e spengo l’altro così posso girare
digitalWrite(input2m1,HIGH);
goto fuori;
}
i–;
}
}>

il codice l ho modificato con il for. dici che va bene??

scusa ho sbagliato. è questo, ma ancora non riesco a uscirne

</if (marcia==‘U’){
for(i=0;i<2;i++){
digitalWrite(trigPin, LOW); // Set the trigger pin to low for 2uS
delayMicroseconds(2);
digitalWrite(trigPin, HIGH); // Send a 10uS high to trigger ranging
delayMicroseconds(10);
digitalWrite(trigPin, LOW); // Send pin low again
int distance = pulseIn(echoPin, HIGH); // Read in times pulse
distance= distance/58;
if((distance>30)&&(distance!=0)){ // a volte arrivano degli zeri e quelli non li devo prendere in considerazione
digitalWrite(input1m1,HIGH); // accendo un motore e spengo l’altro così posso girare
digitalWrite(input2m1,LOW);
analogWrite(enablem1, 200);
}
else{
analogWrite(enablem1, 0); //il motore si ferma e indica col cicalino l’arresto
digitalWrite(7,HIGH);
delay(500);
digitalWrite(7,LOW);
delay(500);
}
if(marcia==‘u’){
digitalWrite(input1m1,HIGH); // accendo un motore e spengo l’altro così posso girare
digitalWrite(input2m1,HIGH);
goto fuori;
}
i–;
}
}/>

Il for proprio non lo capisco. Ne le scelte logiche collegate al sensore di profondità. e per favore usa i tag code, è fastidioso leggere il codice cosi. Spiega a questo punto quali sono i problemi che rimangono.

  1. il for l ho creato in modo che sia in ciclo infinito. L’idea era quella di farlo girare finchè non si decidesse di uscire dalla “modalità”

  2. i comandi del sensore servono a:
    a-far girare il motore con distanza superiore a 30cm
    b-far fermare il motore con distanza inferiore a 30cm e a indicare lo stop con suono alternato del cicalino

  3. il mio unico problema è che una volta entrato in questa “modalità” non riesco a uscirne, come se il comando di uscita non arrivi nemmeno.

ti allego il programma completo

#include <SoftwareSerial.h>
#define echoPin 2                            // Pin to receive echo pulse
#define trigPin 3

 SoftwareSerial BluetoothSerial = SoftwareSerial(0, 1); //si richiama il modulo bluetooth
 
 const int input1m1 = 9; //input1 per il motore 1
 const int input2m1 = 10;//input2 per il motore 2
 const int enablem1 = 11;//regolatore motore 1
  char marcia;
 int velmotore = 0;
int i;

void setup() {
   Serial.begin(9600);
   BluetoothSerial.begin(9600);  //si stabliscono le variabii generali
   pinMode(echoPin, INPUT);// set echopin input
   pinMode(trigPin, OUTPUT); // set pin trigger output
   pinMode(input1m1, OUTPUT);
   pinMode(input2m1, OUTPUT);
   pinMode(enablem1, OUTPUT);
   pinMode(6, OUTPUT);
   pinMode(7, OUTPUT);
}

void loop() {
 if (BluetoothSerial.available()){
    marcia=BluetoothSerial.read(); //vengono lette le marce e di conseguenza la velocità

 if(marcia=='1'){
    velmotore = 25;
    }
    
     if(marcia=='2'){
    velmotore = 51;
    }
    
     if(marcia=='3'){
    velmotore = 76;
    }
    
     if(marcia=='4'){
    velmotore = 102;
    }
    
     if(marcia=='5'){
    velmotore = 127;
    }
    
     if(marcia=='6'){
    velmotore = 153;
    }
    
     if(marcia=='7'){
    velmotore = 178;
    }
    
     if(marcia=='8'){
    velmotore = 204;
    }
    
     if(marcia=='9'){
    velmotore = 229;
    }
    
     if(marcia=='q'){
    velmotore = 254;
    }
    
 if (marcia=='U'){
   for(i=0;i<2;i++){
  digitalWrite(trigPin, LOW);                   // Set the trigger pin to low for 2uS
  delayMicroseconds(2);
  digitalWrite(trigPin, HIGH);                  // Send a 10uS high to trigger ranging
  delayMicroseconds(10);
  digitalWrite(trigPin, LOW);                   // Send pin low again
  int distance = pulseIn(echoPin, HIGH);        // Read in times pulse
  distance= distance/58;
   if((distance>30)&&(distance!=0)){  // a volte arrivano degli zeri e quelli non li devo prendere in considerazione
    digitalWrite(input1m1,HIGH); // accendo il motore
    digitalWrite(input2m1,LOW);
    analogWrite(enablem1, 200);
   }
   else{
      analogWrite(enablem1, 0);  //il motore si ferma e indica col cicalino l'arresto
      digitalWrite(7,HIGH);
      delay(500);
      digitalWrite(7,LOW);
      delay(500);
   }
   if(marcia=='u'){
    digitalWrite(input1m1,HIGH); // spengo il motore e finisco il ciclo
    digitalWrite(input2m1,HIGH);
    goto fuori;
   }
 i--;
   }
 }

fuori:
if(marcia=='W'){
  digitalWrite(6,HIGH); // comando luci
}  
if(marcia=='w'){
  digitalWrite(6,LOW);
}
if(marcia=='V'){
  digitalWrite(7,HIGH); // comando clacson
}  
if(marcia=='v'){
  digitalWrite(7,LOW);
}  
if(marcia=='F'){
     digitalWrite(input1m1, HIGH); //vengono impostati i valori per i quali il motore va avanti
     digitalWrite(input2m1, LOW);
     analogWrite(enablem1, velmotore); //si imposta la velocità grazie al pin PWM
     Serial.print("avanti");
  }
  
  else{
   analogWrite(enablem1, 0); //senza comando il motore si ferma
}
  
  if(marcia=='B'){
  digitalWrite(input1m1, LOW); //vengono impostati i valori per i quali il motore va indietro
  digitalWrite(input2m1, HIGH);
  analogWrite(enablem1, velmotore); //si imposta la velocità grazie al pin PWM
  }
}
}

Clash230: 1) il for l ho creato in modo che sia in ciclo infinito. L'idea era quella di farlo girare finchè non si decidesse di uscire dalla "modalità" [...] 3) il mio unico problema è che una volta entrato in questa "modalità" non riesco a uscirne, come se il comando di uscita non arrivi nemmeno.

Per questo si usa il while che deve comprendere la condizione di uscita dal ciclo

mi puoi dire come lo faccio? se mi scrivessi quella parte di ciclo mi faresti un grandissimo favore

nel senso in che modo strutturo il codice while? come faccio a mettere la condizione di uscita?

Sinceramente trovo qualche difficoltà a capire la logica del programma. Correggimi se sbaglio, tu invii un byte via Bluetooth, questo byte indica principalmente vai avanti ad una determinata velocità o fermati, oppure sterza in automatico, questo non lo capisco, se la macchina sta andando in avanti dovrebbe comunque verificare se sta per scontrarsi con qualcosa e sterzare, se invece è ferma questa verifica non serve, tu invece separi l'avanzare dallo sterzare, e questo ha poco senso.

io per ora muovo un singolo motore, come se fosse in banco di prova. nella modalità il motore controlla la distanza, se è come indicato gira altrimenti si ferma e segnala col cicalino che si è fermato, e questa cosa funziona alla perfezione.

io non riesco a uscire dal ciclo, come faccio?? per favore se sai come strutturare il programma mi scrivi come fare?

Sto cercando proprio di aiutarti ma se stai andando nella direzione sbagliata e noi non capiamo come deve funzionare il sistema rischiamo di darti soluzioni errate!
Potresti spiegare bene cosa deve fare il sistema a parole tue, lascia perdere la logica di funzionamento, che nel tuo sketch è fin troppo contorta.

in pratica è il programma di un auto radiocomandata.
con gli if controllo:
1)manualmente:
-velocità
-direzione (avanti o dietro)
-clacson
-luci

2)automaticamente:
il programma qui dovrebbe far girare a una velocità prestabilita il motore (in avanti) e fermarlo e suonare se c è un ostacolo a un distanza .

il mio obiettivo è di dare al programma versatilità, ovvero attivare la modalità automatica e quindi debilitare tutti i controlli automatici, ma poterci uscire, ripristinando quindi i controlli manuali.

il programma esegue correttamente:
-controlli manuali
-ingresso in modalità automatica ed esecuzione della stessa

non funziona:
-uscita dalla modalità automatica e quindi fine delle sue funzioni e ritorno al controllo manuale

piu chiaro di cosi non posso :smiley:

Ora è perfetto, grazie. Allora il sistema potresti svilupparlo (dentro loop) cosi

[blocco 1] Controllo se sono presenti dati nel buffer di ricezione, se sono presenti verifichi cosa con un blocco switch o una serie di if else, all'interno di queste istruzioni dovrai apportare modifiche a delle variabili globali (velocità, modalità ecc)

[blocco 2] Qui si articolerà il sistema di controllo e ci dividiamo in due strade

[blocco 2.1] modalità manuale Qui piloti lo sterzo e tutte le modifiche legate alla modalità normale

[blocco 2.2] modalità automatica Gestisci il sistema automatico, fai n letture e verifiche ed intervieni se ce ne bisogno

riprendi dal blocco 1

Questo è il sistema piu semplice per non incappare in loop senza uscita. Ti può andare? Piu avanti potresti renderlo piu intelligente ed efficiente.

il problema è che poi se entro nel blocco 2.2 non so come uscirne, e io non voglio fare n letture. deve continuare ad eseguire il blocco finche non arriva il comando che lo ferma ed esce, anche all infinito se serve. e qui ritorniamo al mio problema: come faccio a uscire???

tu lo divide in blocchi io l ho messo insieme effettivamente cambia solo la disposizione

Clash230: tu lo divide in blocchi io l ho messo insieme effettivamente cambia solo la disposizione

Linguaggio strutturato, la disposizione è tutto! XD

Cosi vai in loop perché il tuo programma continua a rifinire nel blocco automatico ad ogni loop finché non arriva una modifica dalla seriale esempio

void loop()
{
    if(available())
    {
        switch(rx())
        {
            case 'a': mode = 0; break;
            case 'b': mode = 1; break;
            case 'c': vel = 1; break;
            case 'd': vel = 2; break;
            //[...]
        }
    }

    if(mode == 0)
    {
        analogWrite(5, vel);
        //[..]
    } else if(mode == 1)
    {
        bool c = verifica();
        if(c) giraADestra();
    }
}

Non ti piace? Puoi fare anche cosi.

void loop()
{
    do
    {
        if(available())
        {
            switch(rx())
            {
                case 1: mode = 1; break;
                case 2: vel = 1; break;
                case 3: vel = 2; break;
                //[...]
            }
        }
    } while (mode == 0);

    do
    {
        //Automatico
        if(available() && rx() == 1) mode = 0;
    } while(mode == 1);
}

Hai l'imbarazzo della scelta.