Motore che fischia

Saluti

So che l'argomento e' stato gia' trattato ma complice la mia scarsa preparazione non sono riuscito a risolvere.
Sto utilizzando un vecchio motorino da tergicristallo della panda e con il driver L298N comando
la rotazione in un senso o nell'altro evitando quindi circuiti piu' noiosi e soprattutto l'uso del rele'.
A basse velocita' fischia mentre impostando in analogWrite 250 nessun fischio.Se abbasso il valore e quindi la velocita' anche di poco comincia a fischiare...
Volendo utilizzare anche un'accelerazione e decelerazione il fastidio si avverte troppo.
Ho trovato su internet un'aggiunta allo sketch che pensavo risolvesse il problema ma purtroppo non e' stato cosi'.
Allego lo sketch completo alla visione di chi puo' risolvere il problema.
Ringrazio dell'attenzione.

int enA = 5;
int in3 = 9;
int in4 = 8;
 
void setup()
{
  setPwmFrequency(9, 1);
  
   
  pinMode(enA, OUTPUT);
  pinMode(in3, OUTPUT);
  pinMode(in4, OUTPUT);
  
}

void loop()
{
  
  digitalWrite(in3, HIGH);
  digitalWrite(in4, LOW);
  analogWrite(enA, 250);

   

  delay(2000);

  
  digitalWrite(in3, LOW);
  digitalWrite(in4, HIGH);  
  

  delay(2000);

  
  digitalWrite(in3, LOW);
  digitalWrite(in4, LOW);  
  
  delay(1000);

  
  digitalWrite(in3, LOW);
  digitalWrite(in4, HIGH);  
  

  // accelerazione
  for (int i = 0; i < 250; i++)
  {
    analogWrite(enA, i);
    
    delay(10);
  } 

   decelerazione
  for (int i = 250; i >= 0; --i)
  {
    analogWrite(enA, i);
    
    delay(10);
  }

  
  digitalWrite(in3, LOW);
  digitalWrite(in4, LOW);  
 

  delay(1000);
}
///////CODICE AGGIUNTO PER ELIMINARE IL FISCHIO/////////
[code]

void setPwmFrequency(int pin, int divisor) {
 byte mode;
 if(pin == 5 || pin == 6 || pin == 9 || pin == 10) {
   switch(divisor) {
      case 1: mode = 0x01; break;
      case 8: mode = 0x02; break;
     case 64: mode = 0x03; break;
     case 256: mode = 0x04; break;
     case 1024: mode = 0x05; break;
      default: return;
    }
    if(pin == 5 || pin == 6) {
      TCCR0B = TCCR0B & 0b11111000 | mode;
   } else {
     TCCR1B = TCCR1B & 0b11111000 | mode;
    }
  } else if(pin == 3 || pin == 11) {
    switch(divisor) {
     case 1: mode = 0x01; break;
      case 8: mode = 0x02; break;
     case 32: mode = 0x03; break;
     case 64: mode = 0x04; break;
     case 128: mode = 0x05; break;
      case 256: mode = 0x06; break;
      case 1024: mode = 0x7; break;
     default: return;
    }
    TCCR2B = TCCR2B & 0b11111000 | mode;
  }
}

>1oniudra2: ti ricordo che in conformità al regolamento, punto 7, devi editare il tuo post (quindi NON scrivendo un nuovo post, ma utilizzando il bottone More -> Modify che si trova in basso a destra del tuo post) e racchiudere il codice all'interno dei tag CODE (... sono quelli che in edit inserisce il bottone con icona fatta così: </>, tutto a sinistra).

In pratica, tutto il tuo codice dovrà trovarsi racchiuso tra due tag: [code] _il _tuo_ codice_ [/code] così da non venire interpretato e non dare adito alla formazione di caratteri indesiderati o cattiva formattazione del testo. Grazie.

Guglielmo

Quando hai sistemato lo sketch, mi spieghi perche' aumenti la frequenza del PWM sul pin 9 e poi usi il 5 per ENA

Per evitare il fischio il Pwm dovrebbe superare i 15-20Khz , però se non riesci ottene tale frequenza anche 5-8khz potrebbe essere sufficiente

Arduino riesce facilmente a generare fino a 31.25Khz di Pwm

Come ha fatto giustamente notare Brunello 22 il pin di enA deve essere uguale al primo numero di setPwmFrequency.
Ho messo quindi 5.(Sperando di aver interpretato bene la sua obiezione).
Per arrivare a quelle frequenze consigliate da icio non so come aggiustare il codice aggiunto.....
In quanto lo stesso codice non l'ho capito.
Comunque inserendo il numero del pin(5) uguale al primo numero di setPwmFrequency.Il motore va a scatti
disinteressandosi del codice della prima parte dello sketch.
Oppure se conosci un sistema differente per bypassare l'ostacolo seguiro' il tuo consiglio.
Grazie

se hai messo 5 in setpwmfrequency non ti funziona bene il delay...
tratto da qui:

  • Note that this function will have side effects on anything else
  • that uses timers:
    • Changes on pins 3, 5, 6, or 11 may cause the delay() and
  • millis() functions to stop working. Other timing-related
  • functions may also be affected.
    • Changes on pins 9 or 10 will cause the Servo library to function
  • incorrectly.

quindi sarebbe meglio mettessi tutto sul 9...

tieni presente che le frequenze di base sono diverse:

    • Base frequencies:
  • o The base frequency for pins 3, 9, 10, and 11 is 31250 Hz.
  • o The base frequency for pins 5 and 6 is 62500 Hz.
    • Divisors:
  • o The divisors available on pins 5, 6, 9 and 10 are: 1, 8, 64,
  • 256, and 1024.
  • o The divisors available on pins 3 and 11 are: 1, 8, 32, 64,
  • 128, 256, and 1024.

sul pin 9 con divisore 1 hai 31,25 KHz
sul pin 5 con divisore 1 hai 62,5 KHz

Come ho avuto occasione di ricordare più volte, su Arduino UNO, i timers sono così utilizzati:

Arduino UNO Timers (ATmega328P)

Timer0
Usato da millis() e delay() e per il PWM sui pin 5 e 6
fast hardware pwm
(default 976.5625 Hz)
Pin 5 è anche usato per il “pulse counting”
Pin 8 è usato per il “input capture”

Timer1
Usato dalla libreria Servo e per il PWM sui pin 9 e 10. Libreria e PWM mutuamente esclusivi.
8-bit phase correct pwm mode
(default 488.28125 Hz)

Timer2
Usato per il PWM sui pin 3 e 11
8-bit phase correct pwm mode
(default 488.28125 Hz)

... quindi, meglio evitare di di giocare con Timer0 ::slight_smile:

Guglielmo

Ottime risposte.

Problema risolto il motore non fischia piu'.
Dovendo pero' utilizzare diversi motori simili mi chiedevo se potevate indicarmi i pin abilitati anche per arduino mega.
Grazie.