Pilotaggio motore CC con L298N

Buonasera.

Ritorno su questo tema perchè avrei realizzato artigianalmente una scheda con a bordo un Arduino v4 e uno shield L298N collegato in modo che, una volta staccato il PC, il driver possa alimentare anche Arduino.

MI ritrovo un problema al quale, dopo un giorno di prove, non sono riuscito a venire a capo.

Allego qui sotto la scheda con i dispositivi installati.
Ovviamente, prima dei collegamenti, sono stati testati con cura gli isolamenti reciproci delle zone 12v, 5v e ground.

E qui lo schema che ho seguito (lo vedete diverso dall’immagine sopra perché lo schema è stato tracciato sulla parte ramata sottostante).

Qui sotto lo sketch.


```cpp
// GestCCMotor_L298N
// Controllo motore in CC con driver L298N per piattaforma di inversione tramite 
// quattro pulsanti.

/* Se la piattaforma è in posizione di transito la variabile "posizione" vale 1.
   Se la piattaforma è in posizione deviata la variabile "posizione" vale 2.
   Il programma in partenza considera il ponte in posizione 1, se così non è
   perchè si è verificata una disalimentazione della piattaforma col ponte in
   una qualche altra posizione, alla ripartenza del sistema di controllo si
   può riallineare correttamente la piattaforma in posizione 1 il tasto 3.

   Casi.
   Posizione        Tasto                                         Posizione
   piattaforma     premuto            Rotazione                   successiva
    1                 1             180° antioraria                    1
    1                 2              15° antioraria                    2
    2                 1              15° oraria                        1
    2                 2             165° antioraria                    1
    -                 3     rotazione continua in senso orario         - 
    -                 4     rotazione continua in senso antiorario     - 
 
*/

int motorPin1    = 11;
int motorPin2    = 12;
int Pinvelocita  = 9;

int posizione = 1;
int buttonState1 = 0;
int buttonState2 = 0;
int buttonState3 = 0;
int buttonState4 = 0;
//int buttonState5 = 0;

// Assegnazione numeri pin:
const int buttonPin2 = 2;  // nome pulsante e pin associato
const int buttonPin4 = 4;  // nome pulsante e pin associato
const int buttonPin5 = 5;  // nome pulsante e pin associato
const int buttonPin6 = 6;  // nome pulsante e pin associato
//const int buttonPin7 = 7;  // nome pulsante e pin associato

//const int gradi180   = 44100; // numero di millisecondi per una rotazione di 180°
const int gradi180   = 5000; // numero di millisecondi per una rotazione di 180°
const int gradi15    = gradi180 / 180 * 15;  // numero di millisecondi per una rotazione di 15°
const int gradi165   = gradi180 / 180 * 165; // numero di millisecondi per una rotazione di 165°
const int step       = 3;  // numero di millisecondi step rotazione continua
const int velocita   = 70; // Settaggio velocità di rotazione

void setup() 
{
//Definizione pin di I/O
pinMode(buttonPin2, INPUT);
pinMode(buttonPin4, INPUT);
pinMode(buttonPin5, INPUT);
pinMode(buttonPin6, INPUT);
//pinMode(buttonPin7, INPUT);

pinMode(Pinvelocita, OUTPUT);
pinMode(motorPin1, OUTPUT);
pinMode(motorPin2, OUTPUT);

//inizializzo la comunicazione seriale cosi da mostrare i valori nel Monitor Seriale
  Serial.begin(9600);
}

// Loop principale
void loop() 
{
 /*Invio i dati letti al Monitro seriale, cosi da poterli vedere a video
  Serial.print("Posizione = ");
  Serial.println(posizione);
*/
 // Leggi stato del bottone 1
 buttonState1 = digitalRead(buttonPin2);

/*Invio i dati letti al Monitor seriale, cosi da poterli vedere a video
        Serial.print("Bottone1 = ");
        Serial.println(buttonState1);
*/
 // Controlla se il bottone 1 è stato premuto (valore HIGH)
 if (buttonState1 == HIGH) 
  {
    //Invio i dati letti al Monitor seriale, cosi da poterli vedere a video
       Serial.print("buttonState1 = ");
       Serial.println(buttonState1);
       
    if (posizione == 1) 
    {
      //Aziona il motore per 180° senso antiorario
      //scrivi stato LOW/HIGH nei due pin di moto del motore              
        digitalWrite(motorPin1, LOW);
        digitalWrite(motorPin2, HIGH);
        analogWrite(Pinvelocita,velocita); //ENA pin
   
      // Millisecondi di durata rotazione - Valore da verificare. 
        delay(gradi180);

      //attiva freno
        // digitalWrite(motorPin1, HIGH);
        // digitalWrite(motorPin2, HIGH);
        analogWrite(Pinvelocita,0); //ENA pin
    } 
        else 
    {
      //Aziona il motore per 15° senso orario
      //scrivi stato HIGH/LOW nei due pin di moto del motore              
        digitalWrite(motorPin1, HIGH);
        digitalWrite(motorPin2, LOW);
        analogWrite(Pinvelocita,velocita); //ENA pin
       
        delay(gradi15);
    
      //attiva freno
        digitalWrite(motorPin1, HIGH);
        digitalWrite(motorPin2, HIGH);
        analogWrite(Pinvelocita,0); //ENA pin

        posizione = 1; 
    }

    buttonState1 = 0;
  }

 // Leggi stato del bottone 2
  buttonState2 = digitalRead(buttonPin4);
       
  // Controlla se il bottone 2 è stato premuto (valore HIGH)
  if (buttonState2 == HIGH) 
   {
    //Invio i dati letti al Monitor seriale, cosi da poterli vedere a video
       Serial.print("buttonState2 = ");
       Serial.println(buttonState2);

     if (posizione == 1) 
      {
      //Aziona il motore per 15° senso antiorario
      //scrivi stato HIGH/LOW nei due pin di moto del motore              
        digitalWrite(motorPin1, LOW);
        digitalWrite(motorPin2, HIGH);
        analogWrite(Pinvelocita,velocita); //ENA pin

      // Millisecondi di durata rotazione - Valore da verificare. 
        delay(gradi15);

      //attiva freno
        digitalWrite(motorPin1, HIGH);
        digitalWrite(motorPin2, HIGH);
        analogWrite(Pinvelocita,0); //ENA pin

        posizione = 2;
      }
        else 
      {
        //Aziona il motore per 165° senso antiorario
      //scrivi stato HIGH/LOW nei due pin di moto del motore              
        digitalWrite(motorPin1, LOW);
        digitalWrite(motorPin2, HIGH);
        analogWrite(Pinvelocita,velocita); //ENA pin

      // Millisecondi di durata rotazione - Valore da verificare. 
        delay(gradi165);

      //attiva freno
        digitalWrite(motorPin1, HIGH);
        digitalWrite(motorPin2, HIGH);
        analogWrite(Pinvelocita,0); //ENA pin

        posizione = 1;
      } 

      buttonState2 = 0;
   }

 // Leggi stato del bottone 3
  buttonState3 = digitalRead(buttonPin5);

/*Invio i dati letti al Monitor seriale, cosi da poterli vedere a video
        Serial.print("Bottone3 = ");
        Serial.println(buttonState3);
*/

  // Controlla se il bottone 3 è stato premuto (valore HIGH).
  if (buttonState3 == HIGH) 
   {
    //Invio i dati letti al Monitor seriale, cosi da poterli vedere a video
       Serial.print("buttonstate3 = ");
       Serial.println(buttonState3);

       //Aziona il motore in rotazione oraria continua fino al rilascio del pulsante
       //La variabile "posizione" mantiene il valore che aveva
       
       //Scrivi stato HIGH/LOW nei due pin di moto del motore              
        digitalWrite(motorPin1, HIGH);
        digitalWrite(motorPin2, LOW);
        analogWrite(Pinvelocita,velocita); //ENA pin

      /*Invio i dati letti al Monitor seriale, cosi da poterli vedere a video
        Serial.print("Velocita(p3)= ");
        Serial.println(velocita);
      */ 

       //Ciclo con minimo delay per avere la massima precisione nel posizionamento
         while (buttonState3==HIGH)
          {
            delay(step);

            buttonState3 = digitalRead(buttonPin5);
          }

       //attiva freno
        digitalWrite(motorPin1, HIGH);
        digitalWrite(motorPin2, HIGH);
        analogWrite(Pinvelocita,0); //ENA pin

        buttonState3 = 0;
   }

 // Leggi stato del bottone 4
  buttonState4 = digitalRead(buttonPin6);

/*Invio i dati letti al Monitor seriale, cosi da poterli vedere a video
        Serial.print("Bottone4 = ");
        Serial.println(buttonState4);
*/
  // Controlla se il bottone 4 è stato premuto (valore HIGH).
  if (buttonState4 == HIGH) 
   {
       //Invio i dati letti al Monitor seriale, cosi da poterli vedere a video
       Serial.print("buttonstate4 = ");
       Serial.println(buttonState4);

       //Aziona il motore in rotazione antioraria continua fino al rilascio del pulsante
       //La variabile "posizione" mantiene il valore che aveva
       
       //Scrivi stato LOW/HIGH nei due pin di moto del motore              
        digitalWrite(motorPin1, LOW);
        digitalWrite(motorPin2, HIGH);
        analogWrite(Pinvelocita,velocita); //ENA pin
         
        /*Invio i dati letti al Monitor seriale, cosi da poterli vedere a video
        Serial.print("Velocita(p4)= ");
        Serial.println(velocita);
        */
        //ciclo con minimo delay per avere la massima precisione nel posizionamento
         while (buttonState4==HIGH)
          {
            delay(step);

            buttonState4 = digitalRead(buttonPin6);
          }

       //attiva freno
        digitalWrite(motorPin1, HIGH);
        digitalWrite(motorPin2, HIGH);
        analogWrite(Pinvelocita,0); //ENA pin
     
        buttonState4 = 0;
        // posizione = 1;
   }
   //Invio i dati letti al Monitor seriale, cosi da poterli vedere a video
  
}
```

Come già scrissi in un precedente thread, uso 4 pulsanti per far ruotare in vari modi una piattaforma girevole.

Nello sketch ho messo dei “serial.print” per vedere il pulsante che viene premuto.

I pulsanti 1, 2 e 3 fanno quello che devono fare ma, premendo il pulsante 4, a volte il pulsante mostrato risulta essere il 4, a volte l’1 con i corretti movimenti corrispondenti.

Qui sotto il risultato dell’output del serial print premendo 5 volte il pulsante 4.

Alla prima pressione lo sketch passa dal ramo “If” come se avesse intercettato la pressione del pulsante 1 (buttonstate1) invece che 4 (buttonState4).
Alla seconda, terza e quarta lo sketch rileva correttamente la pressione del pulsate 4 (buttonstate4) e passa dal ramo ”If” giusto.
Alla quinta pressione ancora una volta lo sketch rileva la pressione del pulsante 1 (buttonstate1) invece che 4 (buttonState4).

Questo comportamento non si verifica premendo i pulsanti 2 e 3 e, quando avevo testato il l’impianto con la breadboard, non avevo rilevato questo comportamento.

Mi potete dare una dritta?

Grazie.

Massimo.

Aggiungo che la rilevazione del pulsante 1 invece che il pulsante 4 pare accadere quando do un colpo brevissimo sul pulsante.

Del resto questo é l’uso per il quale esistono i pulsanti 3 e 4 che sono intesi per delle microregolazioni (orario e antiorario) della posizione del ponte girevole.

Inoltre i pulsanti usati sulla breadboard sono diversi da quello più grandi e precablati usati qui.

Massimo.

Io voto che tu abbia un errore di cablaggio

Da quanto sono le resistenze di pull-down?

I resistori sono da 10k.

I fili in uscita dai pulsanti vanno dritti ai pin, non vedo errori di cablaggio.

Con un errore di cablaggio credo funzionerebbe sempre in un modo, non una volta riconoscere come premuto il pulsante 1 e un’altra il pulsante 4.

Comunque ho finito ora di sostituire la scheda Arduino con un’altra e ora funziona ma il mistero, per me, resta.

Grazie per la risposta.

Massimo.

Giusto un’altro paio di domande.

Il chip quadrato argentato si arroventa durante l’uso: é normale?

I 5v forniti dall’L298N devo collegarli al pin Vin di Arduino?

Grazie.

Direi di no

Tensioni e correnti di lavoro?

Quello è Esp32 e può diventare caldo, ma non esagerato. Dovresti misurare, "arroventa" dice poco.

No.

#Ducembarr

Al momento mi pare che Arduino non funzioni più, non so che cosa sia successo.

Ho solo portato 12v e spiccioli che vengono dall’alimentazione esterna a Vin.

Le correnti non le ho misurate, quando arriva l’altro Arduino che avevo già ordinato riprovo e te lo dico però mi dovresti specificare quali ti interessano.

#Kmin

Arroventato vuol dire che non riesco a tenerci un dito sopra.

Col nuovo Arduino riprovo e, se sarà sempre rovente, misurerò con la termocoppia.

Intanto grazie ad entrambi.

Massimo.

Si, ma può essere 55°C o 100°C, Primo va bene, secondo no.
Cmq, verifichi tuo circuito per errori e se vuoi fai una schema per postare qui prima che connetti arduino nuovo..

Ok, approfitto per chiederti una cosa.

Il manuale dell’L289N dice che il dispositivo ha uno stabilizzatore interno che fornisce i 5v sia e sé stesso che a un suo morsetto d’uscita dedicato.

Se l’alimentazione esterna è minore di 12v si può lasciare in sede il jumper che permette questa funzione, se è maggiore bisogna levare il jumper e portare i 5v esternamente (da Arduino o da altra sorgente immagino).

La mia alimentazione è 12,2-12,3v e ho lasciato il jumper in sede senza conseguenze, così facendo ho usato i 5v dell’L289N per tutto il circuito, portandoli anche ai 5v di Arduino permettendogli di funzionare anche non essendo collegato alla USB (cosa che dovrà fare una volta installato tutto l’impianto).

Il problema e che, se Arduino non è collegato al PC, non posso fare il debugging del software quindi ce l’ho attaccato lo stesso per fare un bel pò di prove senza danni evidenti.

Posso, alla lunga, aver creato conseguenze?

Io non consiglio. Non mi fido regolatore di driver chinese. Documentazione non offre nemmeno opzione per alimentare R4 via 5v pin. Quindi usi 6-24v via vin oppure usb. E lasci driver alimentato da suo regolatore.

Guarda un pò se ti ci ritrovi.

Quindi, per seguire il tuo consiglio, prendo i 12v in ingresso dall’alimentatore li porto a Vin di Arduino, stacco i 5v in uscita dall’L298N dal circuito e li prendo dai 5v di Arduino?

Anche, ma personalmente preferisco non connettere driver 5v pin nessuna parte.
E per evitare interferenze da motori, non alimenterei motori e arduino da stesso psu.

No, no, d’accordo, il 5v dell’L298N lo stacco dal circuito e faccio alimentare i 5v da Arduino così i due dispositivi sarebbero separati con l’unico punto in comune dei 12v in ingresso che andrebbero sia al driver che alla Vin di Arduino.

Però tu ritieni che il funzionamento del motore potrebbe introdurre variazioni ai 12v in ingresso e quindi ai 12v della Vin, ho capito bene?

Ma possono crearsi danni o solo malfunzionamenti?

L’alimentatore è uno da PC con 3A di uscita e mi pare che i 12v siano abbastanza stabili comunque vedremo quando arriva l’altro Arduino

Piu malfunzionamenti.
In ogni caso devi essere 100% sicuro che GND tra PSU e driver è solido in ogni situazione.

Ps. Alcuni PSU da PC hanno bisogno di un carico su 5V per regolare 12V stabilmente...

Il mio è un alimentatore da laptop, solo due fili in uscita: 12v e GND.

Una cosa da aggiungere, esp32 occupa per wireless, quindi se carichi un sketch senza, non dovrebbe riscaldarsi per niente.

Grazie per la precisazione, quando arrivano i nuovi arduino ti scoccio di nuovo.