Problema conflitto analogWrite è servo.h

Salve a tutti, ho acquistato delle sheld L298P per fare dei kit robot poi da rivendere, il problema è che non mi ero accorto che questa sheld probabilmente ha un errore di progettazione, in quando utilizza i pin 10 e 11 per gestire la velocità dei motori, il problema è che quei pin vengono gestiti dai timer 2 e 3 di Arduino uno, che quindi vanno in conflitto con la libreria servo.h, la cosa ancora più strana è che sulla scheda è presente l’uscita del servo sul pin 9...
Adesso sono giorni che ci sbatto la testa ma non trovo soluzioni per cercare di far funzionare tutto senza problemi, visto che purtroppo ne ho comprate tante mi chiedevo se qualcuno sa darmi una mano su come risolvere questo problema...

Ciao a tutti, ancora non sono riuscito a risolvere il mio problema purtroppo...
Ora mi stavo chiedendo se magari ci sarebbe modo di cambiare la gestione dei timer di arduino sui pin 10 e 11, cioè fare in modo che qui pin vengano gestiti con il timer 0, oppure con il timer 1, in modo poi da lasciare libbero il timer 2 per la gestione della libreria servo, mi sembra di aver capito che c'è la possibilità di cambiare la frequenza del PWB ma non la gestione dei timer mi sbaglio?

Tabella riassuntiva per Arduino UNO ...

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)

... l'unica cosa che puoi cambiare è la frequenza di Timer1 e Timer2, NO di Timer0 o non funzionano più le tempistiche (millis(), delay(), micros(), ecc.).

I Timers sono collegati fisicamente ad alcuni pin e NON puoi riassegnarli.

Guglielmo

DavidElectroMaker:
Salve a tutti, ho acquistato delle sheld L298P per fare dei kit robot poi da rivendere,

Sono curioso, hai un link al prodotto ?

gpb01:
Tabella riassuntiva per Arduino UNO ...

Ciao, grazie mille per la risposta...
Purtroppo già conoscevo la abbella dei timer a cui sono collegati i pin, infatti come pensavo non c'è modo di farlo funzionare se non andare a modificare la scheda tagliando la pista, rifacendo poi i collegamenti sui pin 5,6 in modo da non avere probelmi…

Una cosa ancora non ho capito, io devo spostare il servo solo quando il robot e fermo, ma nemmeno con la funzione servo.detach(); ci sarebbe modo di far funzionare il tutto?

nid69ita:
Sono curioso, hai un link al prodotto ?

Ciao, si certo la scheda a questa:

Grazie per il link.
Da quel che leggo, mi spiace ma hai fatto un acquisto errato.
La scheda non ha una progettazione errata. Lo dice chiaramente e in più punti, questo il più chiaro:
The shield uses the following pins which remain available if you are not using that function:

  • Ultrasonic Sensor Ping Control = D7, D8
  • Servo motor control = D9
  • DC motor control = D10,D11, D12, D13
  • Buzzer = D4

Ovvero la shield è progettata per pilotare motori 2 o 4 DC sui pin indicati; i quali non richiedono la servo.h che a sua volta richiede un timer.
Poi la scheda permette di usare 1 servo sul pin 9 ad esempio per pilotare un servo per muovere un sensore tipo un ultrasonico.

Collegare 2 servo come motori non è previsto nella progettazione. Mi spiace. Non credo riuscirai ad "adattarla" via software.

nid69ita:
Grazie per il link.
Da quel che leggo, mi spiace ma hai fatto un acquisto errato.
La scheda non ha una progettazione errata. Lo dice chiaramente e in più punti, questo il più chiaro:

Ciao, grazie mille per la risposta, forse non mi sono spiegato bene ho forse ho capito male io qualcosa…
Allora in pratica questa scheda la devo utilizzare proprio cosi come e progettata, ovvero:

Controllare 4 motori DC, 2 per lato (4WD)
1 servo motore per muovere il sensore ultrasuoni per la funzione evita ostacoli
etc…

In pratica la devo usare cosi come e costruita, il problema e che la velocità dei motori viene gestita sui pin 10,11 che utilizzano sia il timer 1 sia il timer 2, adesso visto che la libreria servo.h utilizza il timer 1 non mi permette di utilizzare il pin 10 come analogWrite contemporaneamente per gestire la velocita dei primi 2 motori….

Non capisco se davvero sia un errore oppure mi sfugge qualcosa...
Quello che ho capito ed è sicuro che non posso utilizzare la libreria servo.h perché in conflitto con il timer 1 sul pin 10, però adesso che ci penso il pin 9 non è stato scelto a caso perché è comunque un pin PWM, non è che c’è modo di usare il servo sul pin 9 senza andare ad utilizzare la libraria servo.h, magari con la funzione: delayMicroseconds()?

Secondo Wikipedia, devi mandare impulsi di durata fra 1 e 2ms ogni 20ms circa (questo tempo non è critico). Prova.

DavidElectroMaker:
... pin 9 non è stato scelto a caso perché è comunque un pin PWM ...

... peccato che i "servo" NON sono pilotati in PWM, ma lavorano in PPM (Pulse Position Modulation) dove l'informazione può essere veicolata in due modi, sia tramite durata della sola parte alta o parte bassa, del segnale, che tramite posizione dell'impulso se è un treno d'impulsi componente un pacchetto di dati. :wink:

Volendo puoi certamente provare a generare tu il treno di impulsi che devi mandare al servo, ma forse, la tua idea di utilizzare alternativamente ed in tempi diversi o il PWM o il Servo, potrebbe anche funzionare ... è da provare ... ::slight_smile:

Guglielmo

... oppure potresti pensare di passare ad un "servo digitale" che allora si pilota tramite dei veri comandi (normalmente dati su un canale seriale) e NON con un segnale implsivo come i servo analogici classici. :slight_smile:

Ti consiglio i servo digitali "Dynamixel AX-12" ... ovviamente costano di più di quelli analogici, ma sono tutt'altra cosa! Per i Dynamixel QUI si trova una libreria per parlarci e QUI alcune spiegazioni.

Guglielmo

Ma... magari mi sbaglio io.
Se un servo lo colleghi al pin 9, anche se il timer1 è collegato al pin 10 ma come servo non usi il pin 10 a me pare la libreria servo.h non ha problemi e non da problemi ad un motore dc sul pin 10

EDIT: ah, ricordavo male, io usavo la Mega. Anche la libreria servo lo dice, no problem su Mega
https://www.arduino.cc/en/reference/servo
"On boards other than the Mega, use of the library disables analogWrite() (PWM) functionality on pins 9 and 10, whether or not there is a Servo on those pins. On the Mega, up to 12 servos can be used without interfering with PWM functionality"

Effettivamente... la shield è pensata male.

Potresti provare a fare un detach del servo e verificare se analogWrite funziona.

Federico

Ciao, grazie a tutti per la risposta e per l'aiuto…
Finalmente sono riuscito a far muovere il servo senza utilizzare la libreria servo.h , in pratica ho utilizzato la funzione: delayMicroseconds(); e mettendo in LOW ed in HIGH il pin a cui e collegato il servo, in base alla durata del delay la posizione del servo cambia…
Di seguito metto il codice per chi fosse interessato e curioso di provare…

int ServoPin = 9;

void setup() {
   pinMode(ServoPin, OUTPUT);
}

void loop() {
   digitalWrite(ServoPin, HIGH); 
   delayMicroseconds(1500);
   digitalWrite(ServoPin, LOW); 
   delayMicroseconds(1500);
}

DavidElectroMaker:
Finalmente sono riuscito a far muovere il servo senza utilizzare la libreria servo.h , in pratica ho utilizzato la funzione: delayMicroseconds() ...

... effettivamente, se cerchi dovrebbero esistere librerie che fanno proprio questo, NON usano il segnale generato dai timers, ma simulano la cosa via software (più o meno come stai facendo tu). Prova a guardare QUI :smiley:

Guglielmo