Generare impulso di durata tON fissa

Hola a todos, mi pongo a voi nel tentare di risolvere un problema che da settimane mi arrovella: con arduino uno riesco a generare un impulso di livello logico alto di durata fissa, senza introdurre ritardi o inserendolo dentro cicli for che rallentino tutto il programma?

Finora ho provato usando digitalWrite, libreria tone e analogWrite. Tutte e 3 senza successo..

Grazie.

Aldo

In questi casi si usa uno dei timer hardware presenti dentro il microcontoller. Arduino di base usa il timer0 con un interrupt su overflow del contatore, per incrementare la variabile dei millisecondi, questo valore viene restituito dalla funzione millis().

Altre librerie usano gli altri due timer e possono nascere problemi di conflitto tra librerie.

Se tutte è tre le soluzioni hanno fallito vuol dire la tua applicazione richiede dei vincoli di tempo stretti e per rispettarli non puoi usare quelle comode funzioni.

Le risorse hardware come i timer non sono semplici da gestire, comunque trovi info nel datasheet del microcontroller, sulla rete cercando: avr timer ecc.

Ciao.

Che durata deve avere l' impulso? Ciao Uwe

Grazie MauroTec, ho trovato un paio di siti dove mi sembra sia spiegato bene il funzionamento dei timer, stasera ci do un'occhiata.

Invece per Uwe, l'impulso deve durare un tempo compreso tra 1 mS e 2 mS, devo pilotare delle bobine ed evitare 1 che la scintilla sia troppo scarsa 2 che vadano in overheating

Grazie ad entrambi!

Aldo

Se ti servono durate tra 1 e 2mS puoi usare la libreria servo.h Ciao Uwe

Prova a caricare Blink without Delay (lo trovi fra gli esempi forniti di serie). Puoi fare una cosa simile ma usando micros() invece di millis().

Ok esaminerò tutte le soluzioni che mi avete proposto! Grazie

Aldo

Allora ho provato sia con la libreria servo che seguendo l’esempio blink senza delay.

Usando servo.h, l’impulso è perfettamente di 1 mS però si genera quando pare a lui, nel senso che l’ho inserito all’interno di un if ma non rispetta la condizione dell’if;

Usando blink senza delay, ho scritto in questo modo

if (Toothcount == 18)                                                            //scintilla coppia 1-4 anticipato di 6°
    {
        impulso=micros();
        if (impulso - impulso_prece > dwell)
        {
          impulso_prece=impulso;
          digitalWrite(bobina1,HIGH);
          digitalWrite(bobina4,HIGH);
        }
    }

ma l’impulso non dura 1 mS, dura circa 20uS.
Le variabili sono tutte ulong e poste pari a 0 nella dichiarazione, a parte dwell = 1 (supponendo 1mS).

Grazie.

Aldo

Uhm … se usi micros(), lavori in microsecondi, non in millisecondi, quindi porre dwell ad 1 non credo ti possa dare 1ms :wink: … dovrebbe essere 1000 (meno il tempo di esecuzione delle istruzioni, ovviamente, se vuoi precisione, e ricordandosi che lavorando in microsecondi, mi pare che ci sia il limite della risoluzione di 4 microsecondi per volta)

Si effettivamente devo aumentare a 1000 il valore della variabile...

Ho appena provato ma non cambia, l'impulso rimane sempre di 20uS

Grazie.

Il contatore ha una risoluzione di 4 microsecondi, ma volendo una durata dell'impulso fra 1 ed 1.5 millisecondi va bene lo stesso. Ovviamente da quel solo pezzo di codice si capisce poco. In particolare dovresti portare le uscite ad 1 (ma se hai esigenze di velocità e ne devi portare più di una contemporaneamente forse ti conviene usare PORTx comunque questo dettaglio si potrà vedere in un momento successivo) e dopo 1250 microsecondi riportarle a zero. Quindi dovresti: definire uno stato che ti dice se devi generare l'impulso se lo devi generare, porta ad 1 le uscite e fai partire il conteggio dei microsecondi verifica se sono passati i 1250 microsecondi stabiliti, se sono passati, porta a 0 le uscite

Lavorare con librerie e variabili ad alto livello è comodo e consente portabilità del codice, ma quando lavori con timing ristretti devi perdere qualche comodità e scendere di livello. Ti consiglio di lavorare direttamente sui registri e sulle porte.(http://www.arduino.cc/en/Reference/PortManipulation) Dovrei fissare i pin delle bobine e per cambiarli dovrai cambiare il codice relativo e non semplicemente la variabile posta all'inizio dello sketch ed inoltre non potrai cambiare microcontrollore senza rivedere la parte sui registri. Però arrivi a velocità di esecuzione maggiori.

Comunque leggendo il commento sullo sketch mi pare che stia lavorando a qualche motore. Ho letto dell'"anticipo". Ci sono altri progetti quasi completi sul funzionamento di motori marini tramite Arduino. Fai una ricerca sul forum.

PaoloP: Lavorare con librerie e variabili ad alto livello è comodo e consente portabilità del codice, ma quando lavori con timing ristretti devi perdere qualche comodità e scendere di livello.

Dipende anche dalla tolleranza massima ammessa, se gli basta una precisione di +/-40 us va bene pure lavorare con la micro() e le digitalWrite, c'è pure da mettere in conto l'errore introdotto dal risonatore di serie su Arduino, nettamente maggiore rispetto ad un quarzo.

Ok ragazzi, vi ringrazio per i consigli. Questo week-end ci lavoro e vi terrò aggiornati.

Grazie.

Aldo

Probabilmente infrangerò qualche regola del forum, ne sono conscio, però vi rimando al link della discussione generale del mio progetto. Come ultimo post troverete l'intero codice nella sua ultima versione più gli ultimi consigli che mi avete suggerito in questo post per generare l'impulso di durata fissa (che era poi l'intento di questo post).

Mi scuso fin d'ora per il mio comportamento.

http://forum.arduino.cc/index.php?topic=291995.30

Aldo

Mi scuso fin d'ora per il mio comportamento.

Sarà ma io considero ciò manifestazione di buon senso e se per assurdo fosse contro il regolamento allora il regolamento è sbagliato e deve essere cambiato.

Ciao.