Onda quadra e pwm...

Salve a tutti,

sto cercando di capire bene il funzionamento dei segnali pwm su arduino, per produrre un'onda quadra che mi funga da clock...
Mi spiego meglio, se volessi ottenere una cosa come:


| || || |___________
A B C

con un intervallo tra B e C da me desiderato, come posso fare?

Da quanto mi è parso di capire inoltre, l'andamento del segnale pwm prescinde dall'esecuzione di uno sketch, in quanto non richiede elaborazione da parte della cpu, ma interessa solo i timer...

Spero che le mie informazioni non siano solo il frutto di supposizioni, false credenze e letture sbagliate...

Grazie in anticipo

seppe

E' così, viene usato un interrupt per generare un segnale PWM. Sta a te programmare i registri del micro per impostare il periodo (il tempo tra un impulso ed il successivo) ed il duty cicle, ossia la % del periodo occupata dal fronte alto dell'onda.
Es. un segnale con periodo di 1 ms con duty cicle del 50% significa che ogni ms viene generato un impulso il cui fronte resta alto per il 50% del tempo, ossia 0,5 ms.

Un duty cicle del 30% significa che l'onda sta alta per 0,3 ms, e bassa per il restante 70%.

Sul datasheet ci sono i registri da manipolare per regolare gli interrupt, ma sul forum tempo fa astrobeed pubblicò per menniti un piccolo codice che generava un tale segnale.

Confermo, cerca "barriera infrarossi", nella discussione c'è proprio il codice di Astrobeed, in quel caso era una frequenza di circa 38KHz, ma puoi facilmente adattarla per ottenere frequenza e duty cycle che ti servono, funziona a meraviglia!!!!

Grazie ragazzi! Come sempre risolvete tutti i miei problemi...

Ultima domanda... posso generare contemporaneamente, due onde quadre distinte e separate con periodo e duty cicle differenti sempre sfruttando gli interrupt ??

seppe

si, arduino ha 3 timer, però devi fare attenzione che i timer controllano anche cose come i delay etc..., quindi devi stare attento a controllare cosa vai a "danneggiare"

Lesto, ho un solo dubbio; ho dovuto abbandonare la tecnica usando il tiny, che ha solo due timer, in quanto cercavo di usarla assieme allo sleep, risultato: insonnia totale :fearful:! forse un secondo timer usato contemporaneamente al primo creerebbe diversi problemi. Cioè intendo rafforzare i tuoi dubbi, per me la cosa si complica parecchio. Se le due frequenze fossero una multipla dell'altra io genererei la più alta ed userei un divisore esterno, al limite, ma è tutta teoria...

@menniti
in effetti i periodi sono uno il multiplo dell'altro... ma non i duty cicle...

seppe:
@menniti
in effetti i periodi sono uno il multiplo dell'altro... ma non i duty cicle...

In questo caso la cosa temo si complichi; comunque io non ho mai usato due diversi timer in contemporanea quindi non saprei aiutarti per generare la seconda frequenza, se ti trovi quel Topic e ti metti a sudare sul datasheet del 328 alla fine dovresti tirare fuori qualcosa.
Ti dò un'altra dritta: alcuni mesi fa, con una serie di test ho scoperto che è possibile portare sul pin 14 del 328 (pin 8 di Arduino) la frequenza dell'oscillatore; basta programmare i fuses in modo da attivare questo pin, in modo automatico ed indipendente dal resto di spara fuori una bellissima square con duty 50% alla frequenza del clock (16MHz nel caso di Arduino, o quella che usi nel caso degli stand alone); magari ti può tornare utile anche questa cosa.

menniti:
Lesto, ho un solo dubbio; ho dovuto abbandonare la tecnica usando il tiny, che ha solo due timer, in quanto cercavo di usarla assieme allo sleep, risultato: insonnia totale :fearful:! forse un secondo timer usato contemporaneamente al primo creerebbe diversi problemi. Cioè intendo rafforzare i tuoi dubbi, per me la cosa si complica parecchio. Se le due frequenze fossero una multipla dell'altra io genererei la più alta ed userei un divisore esterno, al limite, ma è tutta teoria...

dovrei vedere il tuo codice, sinceramente non ho mai usato i timer e quello che so è un accrocchio tra il datasheet dell'atmega e un pò di info raccolte in giro per il forum

seppe:
@menniti
in effetti i periodi sono uno il multiplo dell'altro... ma non i duty cicle...

se i periodi sono multiplo uno dell'altro e cambia solo il duty cicle, allora puoi usare lo stesso timer senza problemi. Altrimenti come spieghi il fatto che arduino, nonnostante abbia solo 3 timer, abbia 6 uscite PWM? (e quindi sì, tutti i PIN possono diventare PWM)

lesto:
Altrimenti come spieghi il fatto che arduino, nonnostante abbia solo 3 timer, abbia 6 uscite PWM? (e quindi sì, tutti i PIN possono diventare PWM)

Perché ogni timer può generare due PWM, hanno la stessa frequenza ma duty cycle diverso, inoltre tra timer e timer ci sono delle differenze sulle modalità PWM supportate.
Attenzione che lo spettro ottenibile di frequenze con il PWM è limitato e può avere un'elevata granularità a seconda del punto della banda in cui si lavora, altro limite è che gli step per il duty cycle sono solo 256.

Quindi si potrebbero generare due frequenze diverse (multiple o meno) con due duty cycle diversi, senza troppi problemi?

menniti:
Quindi si potrebbero generare due frequenze diverse (multiple o meno) con due duty cycle diversi, senza troppi problemi?

Si, però utilizzando due timer diversi.

Ok, grazie, metto in saccoccia per la prossima necessità XD

Eh sì, il discorso è complesso. L'ho scoperto anch'io programmando contatori temporali basati sui timer e modalità sleep (mega328) oppure interrupt sui cambiamenti dello stato dei pin e sleep (tiny84). Molte cose possono interagire fra di loro e non è facile trovare la giusta alchimia per far funzionare tutto a dovere.

bene... vi spiego cosa vorrei realizzare a questo punto... (nel frattempo sto spulciando il post di menniti sulla barriera ad infrarossi...)

Ho intenzione di scrivere un driver per un display lcd 320x240 sharp che mi è capitato sottomano (c'è un mio post di qualche giorno fa a riguardo).

Ho trovato i datasheet,li ho studiati, ho trovato anche un modo per semplificarmi la vita, ma fa uso di un processore motorola che possiede il controller integrato per questi lcd (con un package per me impossibile da sfruttare...); e mi sono reso conto con certezza che il display va pilotato così com'è, senza altra elettronica da aggiungere...

La storia è questa, l'lcd è a matrice di punti, e si comanda scrivendo 4 bit per volta (D0, D1,D2,D3). Ci sono i valori CP1, CP2 ed S che bisogna portare in stato logico alto, rispettivamente ogni riga, ogni punto e ogni schermata (dopo la prima linea, per quest'ultimo).

In totale, S ha periodo di 14 ms; CP1 di 58 us e CP2 di 725 ns. Tali conclusioni vengono tratte dai riferimenti al datasheet, secondo il quale per un refresh massimo di 14 ms (periodo di S), risulta:

CP1 = S / 240
CP2 = CP1 / 80

La durata dello stato logico HIGH per CP1 e CP2 deve essere tra 60 e 130 ns. Per S può arrivare quasi al doppio...

Ora, visto che da software non riuscivo a mantenere questi standard di tempo (ovviamente mi verrebbe da dire...) ho pensato al pwm; il problema è: riesce arduino a darmi un periodo di 725 ns su un timer e 58 us su un altro (S lo gestisco in altro modo...)??

Mi verrebbe da pensare anche, quanto tempo ci metto a mandare i 4 bit all'lcd?

seppe

Per precisazione, le frequenze (le ho appena calolate...) sono:

CP2 = 1,379 MHz
CP1 = 17,24 KHz
S = 71,43 Hz

In totale il frame frequency del display è 80 Hz.

seppe

seppe:
Per precisazione, le frequenze (le ho appena calolate...) sono:

CP2 = 1,379 MHz
CP1 = 17,24 KHz
S = 71,43 Hz

In totale il frame frequency del display è 80 Hz.

seppe

Togliti dalla testa l'idea di generare frequenze così precise, come ti ha già detto Astrobeed il pwm ha solo 256 passi, impossibile gestire risoluzioni di decine o centinaia di Hz. Nelle prove per la barriera, dovendo ottenere 38,00KHz sono riuscito ad arrivare a ±6-700Hz, i TSOP che ho usato hanno una gamma molto ampia (minimo 34÷41KHz) quindi tutto ok, ma tu non hai queste tolleranze.

una soluzione quindi sarebbe usare un 555 ??
La atmel produce una mcu con lcd controller che voi sappiate??

Io ho trovato una mcu motorola, MC68EZ328, che però come vi ho detto non sono capace di usare...

Una mcu atmel con un package "umano" magari ...

seppe

Un 555 per ogni frequenza; usando due trimmer invece del partitore fisso, puoi ottenere frequenza e duty cycle desiderati. Poi ti servirà una logica per inviare questi segnali al tuo integrato, non so se potrai gestirli semplicemente agendo sull'alimentazione dei 555 o se ti serviranno, p.es. dei tri-state pilotati da un micro per commutarli; insomma avrai parecchio da divertirti, credo, ma comunque la vedo dura. Certo se ce la fai, sarà una soddisfazione coi czz XD

Eh si menniti la vedo molto dura... soprattutto per che con l'elettronica sto quasi a zero!!
solo che è davvero uno spreco non provare e abbandonare un lcd touch da 6" !!

continuerò a cercare soluzioni...