aumentare diminuire velocità motore dc

buongiorno a tutti
sto costruendo un piccolo robot autonomo a 4 ruote dal funzionamento molto semplice, infatti ho fatto in modo che non appena colpisce un ostacolo si muova nel verso opposto
Non sono molto ferrato in programmazione per cui volevo chiedervi se qualcuno sa come modificare il mio codice in modo che dopo aver colpito un ostacolo si fermi per un secondo poi riparta nella direzione opposta ma aumentando per gradi la velocità da zero ad un valore massimo "speed".
ho provato ma non so proprio come fare.
grazie mille a tutti in anticipo

ecco il codice

#define dir_1 46
#define pwm_1 3
#define dir_2 47
#define pwm_2 2                 
#define ant1 23          
#define post1 22
int val1 = 0;
int vval1 = 0;          //PWMMAX 256
int val3 = 0;
int vval3 = 0;
int stato1 = 0;
byte speed = 100; 



void setup() {  
  Serial.begin(9600); 
  pinMode(ant1, INPUT);
  pinMode(post1, INPUT);
  pinMode(pwm_1,OUTPUT);
  pinMode(dir_1,OUTPUT);
  pinMode(pwm_2,OUTPUT);
  pinMode(dir_2,OUTPUT); 

}  

void loop() {  
  val1 = digitalRead(ant1); 
  val3 = digitalRead (post1);

  //SWITCH1
  
  if ((val1 == HIGH) && (vval1 == LOW)){  
    stato1 = 1 - stato1;  
                 // attesa di 15 millisecondi  
  }   
  
  vval1 = val1;            // ricordiamo il valore precedente di val  
  
    if (stato1 == 1) { 
    digitalWrite(dir_1,LOW);
    digitalWrite(dir_2,HIGH);
    analogWrite(pwm_1,speed);
    analogWrite(pwm_2,speed);  
    }   
  else {  
    digitalWrite(dir_1,HIGH);
    digitalWrite(dir_2,LOW);
    analogWrite(pwm_1,speed);
    analogWrite(pwm_2,speed);

    
  }  

  //SWITCH3

     if ((val3 == HIGH) && (vval3 == LOW)){  
    stato1 = 1 - stato1;  
                    // attesa di 15 millisecondi  
  }   
  
  vval3 = val3;            // ricordiamo il valore precedente di val  
  
    if (stato1 == 1) { 
    digitalWrite(dir_1,LOW);
    digitalWrite(dir_2,HIGH);
    analogWrite(pwm_1,speed);
    analogWrite(pwm_2,speed);

     
  }   
  else {  
    digitalWrite(dir_1,HIGH);
    digitalWrite(dir_2,LOW);
    analogWrite(pwm_1,speed);
    analogWrite(pwm_2,speed);

  }

  
}

ho provato anche ad inserire un ciclo for ma continua a ripeterlo da 0 a speed senza interrompersi mentre vorrei che una volta arrivato a speed mantenesse la velocità

#define dir_1 46
#define pwm_1 3
#define dir_2 47
#define pwm_2 2                 
#define ant1 23          
#define post1 22
int val1 = 0;
int vval1 = 0;          //PWMMAX 256
int val3 = 0;
int vval3 = 0;
int stato1 = 0;
byte speed = 80;
int pwm_value=0; 



void setup() {  
  Serial.begin(9600); 
  pinMode(ant1, INPUT);
  pinMode(post1, INPUT);
  pinMode(pwm_1,OUTPUT);
  pinMode(dir_1,OUTPUT);
  pinMode(pwm_2,OUTPUT);
  pinMode(dir_2,OUTPUT); 

}  

void loop() {  
  val1 = digitalRead(ant1); 
  val3 = digitalRead (post1);

  //SWITCH1
  
  if ((val1 == HIGH) && (vval1 == LOW)){  
    stato1 = 1 - stato1;  
                 // attesa di 15 millisecondi  
  }   
  
  vval1 = val1;            // ricordiamo il valore precedente di val  
  
    if (stato1 == 1) { 
 for (pwm_value=0; pwm_value<speed; pwm_value=pwm_value+5){
 digitalWrite(dir_1,LOW); //controls the direction the motor
 digitalWrite(dir_2,HIGH);
 analogWrite(pwm_2,pwm_value); 
 analogWrite(pwm_1,pwm_value); 
 delay(100);

}
    digitalWrite(dir_1,LOW);
    digitalWrite(dir_2,HIGH);
    analogWrite(pwm_1,speed);
    analogWrite(pwm_2,speed);  
    }   
  else {  
    digitalWrite(dir_1,HIGH);
    digitalWrite(dir_2,LOW);
    analogWrite(pwm_1,speed);
    analogWrite(pwm_2,speed);

    
  }  

  //SWITCH3

     if ((val3 == HIGH) && (vval3 == LOW)){  
    stato1 = 1 - stato1;  
                    // attesa di 15 millisecondi  
  }   
  
  vval3 = val3;            // ricordiamo il valore precedente di val  
  
    if (stato1 == 1) { 
    digitalWrite(dir_1,LOW);
    digitalWrite(dir_2,HIGH);
    analogWrite(pwm_1,speed);
    analogWrite(pwm_2,speed);

     
  }   
  else {  
    digitalWrite(dir_1,HIGH);
    digitalWrite(dir_2,LOW);
    analogWrite(pwm_1,speed);
    analogWrite(pwm_2,speed);

  }

  
}

Che scheda stai utilizzando ?

per il controllo motori sto usando questa scheda

e su ogni canale ho collegato una coppia di motori
come microprocessore uso un arduino mega

stato1 è sempre a 1 per questo esegue il ciclo for

Questo codice dovrebbe muovere nella direzione opposta al sensore attivo quando incontra
uno ostacolo

se scrivi nel codice:

#define debug

puoi simulare gli switch(sensori) e verificare se va nella direzione giusta

#define vai_indietro B00010000 // setta a '1' PD4 , ovvero pin 47
#define vai_avanti B00001000 // setta a '1' PD3 , ovvero pin 46

qui c'e scritto che PD4 ( leggendo PD0 da destra) configura dir per andare indietro. Verifica che non sia
l'opposto.
Comunque il codice è commentato, vedi un pò se ti puo servire

  #define pwm_1 3
  #define pwm_2 2                 
  
  #define dir_2 47  // PORTA D
  #define dir_1 46  // PORTA D

  #define ant1 23     //PORTA B    sensore anteriore
  #define post1 22    // PORTA B   sensore posteriore

  #define vai_indietro B00010000  // setta a '1' PD4 , ovvero pin 47
  #define vai_avanti   B00001000  // setta a '1' PD3 , ovvero pin 46
  
 
  int val1 = 0;  // legge lo stato del sensore anteriore
  int val3 = 0;  // legge lo stato del sensore posteriore
   
  byte speed = 80;
  int pwm_value=0;
 
  void setup() { 
    Serial.begin(9600);
    pinMode(ant1, INPUT);
    pinMode(post1, INPUT);
    pinMode(pwm_1,OUTPUT);
    pinMode(dir_1,OUTPUT);
    pinMode(pwm_2,OUTPUT);
    pinMode(dir_2,OUTPUT);
  
  } 

/*
 * COMMENTARE '#define debug'  QUANDO SI PROVA IL ROBOT
 */

//  #define debug
    
  void loop()
  { 
    byte dirMask=B00011000;  
    byte dir;  
    
    val1 = digitalRead(ant1); // HIGH = sensore non attivo , LOW = sensore attivo ( switch premuto)
    val3 = digitalRead (post1); // HIGH = sensore non attivo , LOW = sensore attivo ( switch premuto)

 #ifdef debug
    int v1 =LOW;   // Simula lo switch anteriore premuto (attivo)
    int v3 =HIGH;  // Simula lo switch posteriore Non premuto ( Non attivo)
    val1 = v1;
    val3 = v3;
 #endif
    
    
   if (val1 ^ val3)  // la condizione è vera solo se uno dei due sensori è attivo ( LOW = 0 volts = switch chiuso ). Se entrambi sono HIGH oppure entrambi sono LOW , la condizione è falsa.
                 // per cui se il robottino è chiuso davanti e dietro , rimmarà fermo e non eseguirà quindi il ciclo for.
    {
      delay(1000); 
      
      if (val1==LOW) dir = vai_indietro;  // Se è stato il sensore val1 ad attivarsi allora configura la scheda motore per andare indietro ( verificare che non sia l'incontrario..)
      if (val3==LOW) dir = vai_avanti;    // Se è stato il sensore val3 ad attivarsi allora configura la scheda motore per andare avanti ( verificare che non sia l'incontrario..)

      PORTD = (PORTD &~dirMask) | dir;  // setta a 1 ( HIGH ) il bit corrispondente e quindi il bit della direzione (dir) desiderata. Solo un pin per volta è HIGH 

      Serial.print("PORTD "); Serial.println(PORTD);   // debug, visualizza quali bit (in decimale) ha settato per determinare la direzione ( verificare che siano quelli giusti)
      
     for (pwm_value=0; pwm_value<speed; pwm_value=pwm_value+5)  // Esegue un ciclo di pwm come da codice originale
     {
        analogWrite(pwm_2,pwm_value);
        analogWrite(pwm_1,pwm_value);
        delay(100);
     }
    }  // a questo punto il sensore attivo si sarà disattivato ( a meno che non sia rotto) rendendo la condizione di cui sopra , falsa impedendo il ripetersi del ciclo for.
  }

Ora provo a caricare il codice e vedo cosa succede.
Grazie mille
da solo di sicuro non ci sarei riuscito

Se hai arduino mega 2560, devi provare a caricare questo scketch

  #define pwm_1 3
  #define pwm_2 2                 
 
  #define dir_2 47  
  #define dir_1 46  

  #define ant1 23     //PORTA B    sensore anteriore
  #define post1 22    // PORTA B   sensore posteriore

  int val1 = 0;  // legge lo stato del sensore anteriore
  int val3 = 0;  // legge lo stato del sensore posteriore
   
  byte speed = 80;
  int pwm_value=0;
 
  void setup() {
    Serial.begin(9600);
    pinMode(ant1, INPUT);
    pinMode(post1, INPUT);
    pinMode(pwm_1,OUTPUT);
    pinMode(dir_1,OUTPUT);
    pinMode(pwm_2,OUTPUT);
    pinMode(dir_2,OUTPUT);
 
  }

/*
 * COMMENTARE '#define debug'  QUANDO SI PROVA IL ROBOT
 */

//  #define debug
   
  void loop()
  {
   
    val1 = digitalRead(ant1); // HIGH = sensore non attivo , LOW = sensore attivo ( switch premuto)
    val3 = digitalRead (post1); // HIGH = sensore non attivo , LOW = sensore attivo ( switch premuto)

 #ifdef debug
    int v1 =LOW;   // Simula lo switch anteriore premuto (attivo)
    int v3 =HIGH;  // Simula lo switch posteriore Non premuto ( Non attivo)
    val1 = v1;
    val3 = v3;
 #endif
   
   
   if (val1 ^ val3)  // la condizione è vera solo se uno dei due sensori è attivo ( LOW = 0 volts = switch chiuso ). Se entrambi sono HIGH oppure entrambi sono LOW , la condizione è falsa.
                 // per cui se il robottino è chiuso davanti e dietro , rimmarà fermo e non eseguirà quindi il ciclo for.
    {
      delay(1000);
     
      if (val1==LOW) // Se è stato il sensore val1 ad attivarsi allora configura la scheda motore per andare indietro ( verificare che non sia l'incontrario..)
      { 
        digitalWrite(dir_1,HIGH);
        digitalWrite(dir_2,LOW);
      }  
      
      if (val3==LOW) // Se è stato il sensore val1 ad attivarsi allora configura la scheda motore per andare avanti ( verificare che non sia l'incontrario..)
      { 
        digitalWrite(dir_1,LOW);
        digitalWrite(dir_2,HIGH);
      }  
       

     
     for (pwm_value=0; pwm_value<speed; pwm_value=pwm_value+5)  // Esegue un ciclo di pwm come da codice originale
     {
        analogWrite(pwm_2,pwm_value);
        analogWrite(pwm_1,pwm_value);
        delay(100);
     }
    }  // a questo punto il sensore attivo si sarà disattivato ( a meno che non sia rotto) rendendo la condizione di cui sopra , falsa impedendo il ripetersi del ciclo for.
  }

Ciao
Sei un grande
Ho avuto solo questa sera la possibilità di provarlo e funziona davvero bene
Ho notato solo un piccolo problema infatti se mentre sta accelerando incontra un ostacolo continua ad eseguire il ciclo for fino a quando non raggiunge la velocità massima
Non esiste un modo per far si che anche durante il ciclo for percepisca la variazione di stato degli switch?
Grazie davvero

Prima l'avevo provato senza ruote. ora l'ho provato posandolo a terra.
Ci sarebbe un altro problema infatti quando colpisce un ostacolo anche se ha raggiunto la massima velocità nn si ferma immediatamente. Infatti le ruote continuano a girare per credo un secondo

Continuano a girare per un secondo, dato da:

 if (val1 ^ val3)  // la condizione è vera solo se uno dei due sensori è attivo ( LOW = 0 volts = switch chiuso ). Se entrambi sono HIGH oppure entrambi sono LOW , la condizione è falsa.
                 // per cui se il robottino è chiuso davanti e dietro , rimmarà fermo e non eseguirà quindi il ciclo for.
    {
      delay(1000);
       ^^^^^^^^^^^^^^^^

gli stai dicendo che se uno dei sensori è attivo deve aspettare un secondo prima di fare altro

Marco3615:
...in modo che dopo aver colpito un ostacolo si fermi per un secondo...

paulus1969:
gli stai dicendo che se uno dei sensori è attivo deve aspettare un secondo prima di fare altro

Esatto è quel delay_ms(1000);
@Marco3615:Dovresti provare tu a modificarlo. Devi imparare un pezzetto alla volta e poi metterli insieme come un puzzle...
comunque occhio e croce dovrebbe essere così. Controllalo al limite lo correggi
Il FOR lo elimini , sfrutti il loop per creare un ciclo dove includere tutto il tuo codice
Raggiunta la velocità massima mantiene quel valore fino al prossimo ostacolo dove partirà nuovamente da zero.

 if (pwm_value<speed)  
 {
 pwm_value=pwm_value+5;

        analogWrite(pwm_2,pwm_value);
        analogWrite(pwm_1,pwm_value);
 delay(100);
 } 
   
    if (val1 ^ val3) 
    {

//       delay(1000);  /* Si ferma per un secondo solo una volta dopo aver rilevato un ostacolo. */
   
   if (val1==LOW) /* Se è stato il sensore val1 ad attivarsi allora configura la scheda motore per andare indietro. */
       {
        digitalWrite(dir_1,HIGH);
        digitalWrite(dir_2,LOW);
    pwm_value=0; /* contatore a zero per nuova velocità.*/ 
       } 
    
       if (val3==LOW) 
       {
        digitalWrite(dir_1,LOW);
        digitalWrite(dir_2,HIGH);
    pwm_value=0; /* contatore a zero per nuova velocità */
       } 
 }
  }