logo

giovedì 28 ottobre 2010

ripristino configurazione monitor

a volte può succedere,che provando le varie risoluzioni del monitor non si riesca più a tornare alla configurazione iniziale. A me è successo. preso dal panico del momento sono uscito per evitare ulteriori danni, ma, dopo essermi tranquillizzato (1ora e mezza dopo), ho cercato la soluzione su internet, ma niente, non c'era il mio problema, lo sconvolgimento grafico è stato gigantesco.
Ma ecco la classica "illuminazione", io lo definisco "CULO". ho provato ad accedere da ospite,ed era tutto come prima della "frittata".  ho rifatto lo stesso procedimento, cioè: Sistema>Preferenze>Monitor e ho riportato quella configurazione sulla mia sessione. PUFF come per magia è tornato tutto come prima.       

domenica 24 ottobre 2010

Il Semaforo Arduino

semaforo
// Semaforo
int ledDelay = 10000;
int SrossoPin = 7;
int SgialloPin = 6;
int SVerdePin = 5;
void setup() {
pinMode(SrossoPin, OUTPUT);
pinMode(SgialloPin, OUTPUT);
pinMode(SverdePin, OUTPUT);
}
void loop()
{
digitalWrite(SrossoPin, HIGH);
delay(ledDelay);
digitalWrite(SrossoPin, LOW);
digitalWrite(Sgiallo, HIGH);
delay(ledDelay);
digitalWrite(SgialloPin, LOW);
digitalWrite(SverdePin, HIGH);
delay(ledDelay);
digitalWrite(SverdePin, LOW);
digitalWrite(SgialloPin, HIGH);
delay(2000);
digitalWrite(SgialloPin, LOW);
}

Super Car Arduino

// LED EFFETTO CHASE
// Dichiara e inizializza un array per i pin
byte ledPin[] = {4, 5, 6, 7, 8, 9, 10, 11, 12, 13};
int ledDelay(65);    // tempo di attesa prima del cambiamento
int direction = 1;
int currentLED = 0;
unsigned long changeTime;
void setup() {
// setta i pin per l’output
for (int x=0; x<10; x++) {
pinMode(ledPin[x], OUTPUT); }
changeTime = millis();
}
void loop() {
// gestisce il controllo del tempo di attesa
if ((millis() - changeTime) > ledDelay) {
changeLED();
changeTime = millis();
}
}
void changeLED() {
// spegne tutti i LED
for (int x=0; x<10; x++) {
digitalWrite(ledPin[x], LOW);
}
// accende il LED corrente
digitalWrite(ledPin[currentLED], HIGH);
// incrementa in base al valore della direzione
currentLED += direction;
// cambia il valore della direzione si è raggiunto l’ultimo LED
if (currentLED == 9) {direction = -1;}
if (currentLED == 0) {direction = 1;}
}

mercoledì 20 ottobre 2010

dare un comando al pulsante

EXEC
[ Processo = ] EXEC Comando [ WAIT ] [ FOR { { READ | INPUT } | 
{ WRITE | OUTPUT } } ] [ AS Nome ]

EXEC Comando TO Variabile
Esegue un comando. Per gestire il comando viene creato un oggetto Process interno.
Il comando deve essere specificato come un array di stringhe contenente almeno un elemento. Il primo elemento di questo array è il nome del comando, gli altri sono parametri opzionali.

  • Se WAIT è specificato, allora l'interprete attende la fine del comando. Altrimenti, il comando viene eseguito in background.
  • Se FOR è specificato, allora l'input-output del comando viene rediretto cosicché il tuo programma possa intercettarli:
    • Se WRITE è specificato, puoi mandare dati allo standard input del comando usando l'oggetto Process con istruzioni d'output comuni: PRINT, WRITE, ... . Nota che necessiti di un riferimento all'oggetto Process per questo.
    • Se READ è specificato, allora verranno generati eventi ogni volta che il comando manda dati al suo stream standard output: l'evento Read viene sollevato quando vengono mandati dati allo stream standard output, e l'evento Error viene sollevato quando vengono mandati dati allo stream standard error. Usa l'oggetto Process con Funzioni di Stream e Input/Output per leggere lo standard output del processo.
Se utilizzi le parole chiave INPUT e OUTPUT invece di READ e WRITE, allora il processo viene eseguito in un terminale virtuale. Questo significa che il processo penserà di essere eseguito dentro un vero terminale. Nome è il nome dell'evento usato dall'oggetto Process. Per default, è "Process".
Puoi avere un riferimento all'oggetto Process interno creato usando un assegnamento.
Se usi la seconda forma, il comando viene eseguito, l'interprete attende la sua fine, e l'output completo del comando viene messo nella stringa specificata.

Esempio

' Ottieni il contenuto della directory
EXEC [ "ls", "-la", "/tmp" ] WAIT

' Metti il contenuto della directory nella stringa
DIM sOutput AS String
EXEC [ "ls", "-la", "/tmp" ] TO sOutput

' Metti il contenuto della directory nella stringa, ma in background

DIM sOutput AS String

' Viene usato un nome di evento specifico
EXEC [ "ls", "-la", "/tmp" ] FOR READ AS "Contenuto"

...

PUBLIC SUB Contenuto_Read()

  DIM sLinea AS String

  READ #LAST, sLinea, -256

  sOutput &= sLinea

END

PUBLIC SUB Contenuto_Kill()

  PRINT sOutput

END

Se vuoi sapere quanti bytes puoi leggere in un gestore di eventi Process_Read, usa la funzione Lof.

Dato che gli argomenti vengono mandati direttamente al processo, non hai bisogno di racchiuderli tra virgolette, come dovresti fare in una shell.
' perl -e 'print while <>;' diventa

EXEC [ "perl", "-e", "print while <>;" ] FOR READ WRITE

Gambas2, l'alternativa libera a Visual Basic per Linux


Gambas (http://gambas.sf.net) è un IDE per lo sviluppo in BASIC, per Linux. L'ambiente ricorda moltissimo il noto Visual Basic, e per molti comandi è compatibile con la sua sintassi, anche se la compatibilità al 100% non è il suo obbiettivo.

Perchè usare Gambas? Con tutti i linguaggi che c'erano su Linux, perchè Gambas? La risposta è molto semplice. Sebbene Linux abbondi di linguaggi di programmazione, non abbonda affatto di ottimi ambienti di sviluppo e di facile uso. Gambas si propone di essere facile da usare e permette anche a chi ha poca esperienza con la programmazione di iniziare a scrivere programmi di una qualche utilità.
Orientato agli oggetti disponibile per piattaforme GNU/Linux ed altri sistemi Unix o assimilati la cui sintassi è basata sul linguaggio BASIC. Gambas indica al contempo sia il linguaggio che l'IDE (Integrated Development Environment), esso stesso scritto in Gambas. L'interprete di Gambas è scritto in C/C++.

Gambas è nato nel 1999 per mano di un programmatore francese di nome Benoît Minisini che voleva realizzare un nuovo linguaggio di programmazione per Linux, facile da apprendere e semplice da utilizzare come il Visual Basic di Microsoft, di cui però non è un clone, come rimarca con decisione il suo autore [1]. Anche se molto spesso si tende ad usare la similitudine con il Visual Basic per spiegare ai profani a cosa più assomiglia Gambas, i punti di contatto sono limitati al linguaggio di base, il BASIC, ma la sintassi dei comandi e la struttura dei programmi è diversa tant'è che un programma dell'uno non può girare sull'altro.

Gambas è free software ed è rilasciato sotto licenza GPL.

Dove trovare Gambas





La documentazione che potete trovare su Gambas è per adesso quasi interamente in inglese (a parte quelle che trovate tradotta su Gambas.it) ma è sicuramente un ottimo punto di partenza per iniziare a studiare il linguaggio:
  • A Beginner Guide To Gambas: si tratta di un manuale in formato PDF di circa 400 pagine dove potrete trovare una panoramica completa di tutto l'ambiente, dei controlli, del linguaggio, affrontando problematiche comuni della programmazione, comprendendo anche la gestione degli errori e la programmazione object-oriented.
  • Wiki ufficiale del progetto Gambas: si tratta della documentazione ufficiale del progetto ed è in formato Wiki, in modo che tutti gli sviluppatori possano di volta in volta dare il proprio contributo.
  • Network Programming with Gambas: Tutorial sulla programmazione Socket tramite Gambas.

Risorse Esterne
fonte: ptlug
Ultima versione stabile: 2.1.7

http://people.freebsd.org/~acm/screen/gambas2-freebsd.png

You get them from the Subversion repository. To get a snapshot of the future 3.0 version, do:
$ mkdir trunk
$ svn checkout https://gambas.svn.sourceforge.net/svnroot/gambas/gambas/trunk/
$ cd trunk
$ ./reconf-all
To get a snapshot of the 2.x development version, do:
$ mkdir 2.0
$ svn checkout https://gambas.svn.sourceforge.net/svnroot/gambas/gambas/branches/2.0
$ cd 2.0
$ ./reconf-all
Do not forget to install automake and autoconf, otherwise the ./reconf-all script will not work.

Stable Version Source Packages (ChangeLog)

Package Version Format
gambas2-2.17.0.tar.bz2 2.17.0 tar.bz2
gambas2-2.16.0.tar.bz2 2.16.0 tar.bz2
gambas2-2.15.2.tar.bz2 2.15.2 tar.bz2
gambas2-2.14.0.tar.bz2 2.14.0 tar.bz2

martedì 19 ottobre 2010

FRITZING

PDF Stampa E-mail
Scritto da Mario Emanuele Lagadari   
Giovedì 05 Novembre 2009 17:06
Fritzing è un open-source iniziativa a sostegno designer, artisti, ricercatori e
appassionati a compiere il passo dalla creazione di prototipi fisici ad un prodotto reale.
Scaricabile dal sito:
http://fritzing.org/download/
Fritzing PCB's View consente :
  • Di progettare ed esportare i file per creare circuiti stampati.
  • È possibile esportare il disegno per un servizio professionale di produzione di PCB.
La teoria dei circuiti stampati PCB potrebbe sembrare difficile a prima vista per un principiante. Per via che questa teoria mostra solo le informazioni necessarie per la progettazione. Anche se può essere meglio interpretata se utilizziamo l'uso dei vari livelli che costituiscono il progetto.
Per imparare ad utilizzare gli strumenti Fritzing di progettazione PCB, consideriamo l' utilizzo di una serie di fasi :
  • Prima di tutto consideriamo lo schema creato nella Breadboard View:
big_design_pcb_1

  • Visualizzando la selezione PCB nel Navigator costituito dal rettangolo verde su cui veranno disposti i vari elementi ed i vari collegamenti tra i vari componenti definiti da linee sottili avremmo:

  • big_design_pcb_3
  • Ridimensioniamo il rettangolo, utilizzando una forma Arduino o una scheda con una forma personalizzata. Per far ciò selezionare la scheda e scegliere / modificare la forma preferita in Impostazioni.


big_design_pcb_5
Dopo aver terminato la costruzione del circuito, salvare il progetto. Si potrebbe voler esportare il circuito come un file di immagine o PDF.
  1. Selezionare il progetto da esportare (basetta, schematico o PCB).
  2. Dalla barra dei menu, selezionare File> Esporta> e il formato desiderato.
  3. big_building_circuit_7

  • Adesso andremmo a disporre gli elementi sul rettangolo lasciando un adeguato spazio fra i vari elementi e cercando di non disporli molto vicino ai bordi.
    Questo sarà molto importante dato che la posizione dei pezzi avrà un grande effetto sul processo di routing. Ad esempio :
big_design_pcb_9








big_design_pcb_9PS: funziona in tutti i sistemi operativi, seguire le istruzioni nella pagina di download in alto.

pwm



Arduino - Programmazione
Scritto da Brainbooster   
Lunedì 05 Luglio 2010 22:44
PDF Stampa E-mail
Che cos'è il PWM


Ovvero prendiamo confidenza con il PWM di Arduino Duemilanove
La modulazione di larghezza di impulso (Pulse Width Modulation) può essere usata da Arduino in diversi modi. In questo tutorial cercherò di spiegare l'uso di PWM "semplici" , così come come utilizzare il PWM  ed i registri che lo regolano per un maggiore controllo sul ciclo di lavoro e di frequenza.
Un segnale PWM è un'onda quadra (meglio rettangolare) che varia da 0V a VCC (tensione di uscita massima che per arduino è 5V) , dove la frequenza è costante , e cambia la frazione di tempo in cui il segnale è attivo  a VCC ( detto ciclo di lavoro utile o dutycycle) può essere variata tra 0 e 100 %.
Your browser may not support display of this image.
Il PWM ha diversi utilizzi :
  • Variare la luminosità di un led LED (tramite un filtro rc), fornendo una tensione analogica tra lo 0% e il 100%.
  • Generare di frequenze udibili e quindi audio
  • Controllare la velocità dei motori
  • Controllare servomotori da modellismo
  • Puo essere usato come generatore di segnale modulante
  • Ed altro ancora
Semplice PWM con l'uso del comando analogWrite
Il linguaggio di programmazione Arduino, rende il PWM facile da usare , è sufficiente chiamare analogWrite(Pin , dutyCycle ), Dove dutyCycle è un valore da 0 a 255, e Pin è uno dei pin PWM (3, 5 , 6, 9 , 10, o 11). Il comando analogWrite fornisce una semplice interfaccia per il PWM hardware, ma non fornisce alcun controllo sulla frequenza.
Ma andiamo un pò più in profondità... ci sono altre opzioni che forniscono più flessibilità :)
Il PWM manuale su tutti i pin
È possibile  creare "manualmente" un PWM su ogni pin semplicemente "spegnendo" e "accendendo" un pin in uscita. ad esempio:
void setup ()

{

pinMode (13, OUTPUT) ;

}

void loop ()

{

digitalWrite (13 , HIGH) ;   / / Lascio il pin "acceso" (per 100ms)

delayMicroseconds (100); / / Circa il 10 %  di duty cycle (sarebbe 1KHz)

digitalWrite (13, LOW);     / / Spengo il pin ed aspetto il prossimo ciclo

delayMicroseconds (900) ;/ / Attesa prima del prossimo ciclo (per 900ms)

}

Facendo così, si ha il vantaggio di poter utilizzare qualsiasi pin di uscita digitale . Inoltre, avete il pieno controllo del duty cycle e della frequenza. Uno dei principali svantaggi è che ogni interrupt inciderà negativamente sui tempi , a meno che non si disattivino gli interrupt. Un altro svantaggio è che non si può lasciare girare il processo mentre il processore fa qualcos'altro. Infine , è difficile determinare le costanti appropriate per un ciclo di funzionamento particolare e la frequenza richiesta, a meno che non si calcoli attentamente dai cicli di clock.
Uso del PWM parlando con i registri dell'atmega di Arduino
Il chip ATmega168P/328P ha tre timer PWM , che controllano le 6 uscite PWM. Manipolando il timer del chip direttamente tramite i registri , è possibile ottenere un maggiore controllo rispetto al analogWrite per "piegarlo" alle nostre necessità.
Il datasheet dell'ATmega328P  fornisce una descrizione dettagliata dei timer PWM, ma ati può essere difficile da capire, a causa delle molteplici modalità di uso dei timer.
Proviamo a capirci qualcosa. (datasheet alla mano ;) )
Il ATmega328P ha tre timer conosciuti come Timer 0, Timer 1 e Timer 2 . Ogni timer ha due output con dei registri a comparazione che controllano la larghezza PWM per il timer di due uscite : quando il timer raggiunge il valore di comparazione impostato nel registro , l'uscita corrispondente è attivata . Le due uscite per ogni timer normalmente hanno la stessa frequenza , ma possono avere cicli di lavoro differenti (a seconda dei rispettivi valori dei registri a comparazione).
Ciascuno dei timer ha un prescaler che genera il suo clock dividendo il clock di sistema per un fattore di Prescale come 1, 8, 64 , 256 o 1024. Arduino duemilanove ha un clock di sistema di 16MHz e la frequenza di clock del timer sarà la frequenza di clock di sistema diviso per il fattore Prescale . Attenzione il Timer 2 ha un diverso insieme di valori Prescale rispetto agli altri timer .
I timers sono complicati da diverse modalità di uso e controllo. Le modalità PWM principali sono " PWM Fast "e" PWM a correzzione di fase ". Il timer può essere pilotato con valori 0-255 (8 bit) , o da un valore fisso, se serve. (Il  Timer 1  è dotato di modalità supplementari per supportare valori fino a 16 bit. ) Ogni uscita può anche essere invertita.
Il timer può anche generare interrupt con overflow , ma questo và oltre le mie possibilità esplicative (per adesso).
Timers e Registri
Per controllare ogni timer vengono utilizzati vari registri. I Timer / Counter dei Registri di controllo  TCCRnA e TCCRnB contengono il bit di controllo principale per i timers.Questi registri possono contenere diversi gruppi di bit :
  • bit di Generazione di forme d'onda ( WGM ): questa e la modalità di controllo globale del timer. (Questi bit sono divisi tra TCCRnA e TCCRnB .)
  • bit Clock Select ( CS ): questo serve a controllare il prescaler sul clock
  • bit di comparazione uscita A ( COMnA ): questo serve ad attivare / disattivare / l'output invertito per  l'uscita A
  • bit di comparazione uscita B ( COMnB ): questo serve ad attivare / disattivare / l'output invertito l'uscita B
Le uscite di comparazione dei Registri OCRnA e OCRnB servono ad impostare i livelli a cui le uscite A e B saranno "azionate". Quando il valore del timer corrisponde al valore di registro , l'uscita corrispondente viene modificata come specificato dalla modalità.
I bit sono leggermente diversi per ogni timer , (vedi datasheet per i dettagli).Come dicevamo prima, il Timer 1 è un timer a 16 bit e dispone di modalità aggiuntive e Timer 2 ha valori diversi di prescaler .
Fast PWM
Nel "semplice" PWM , il timer conta ripetutamente 0-255 . L'uscita si accende quando il timer è a 0, e si spegne quando il timer corrisponde a quanto impostato nell'apposito registro. Più alto è il valore nel registro di uscita , maggiore è il dutycycle. Questa modalità è nota come Fast PWM Mode.
L'esempio seguente illustra come usare le uscite per due valori particolari di OCRnA e OCRnB . Da notare che entrambe le uscite hanno la stessa frequenza, ed usano la frequenza di un ciclo completo di clock .
Fast PWM Mode
L'esempio di codice seguente imposta il PWM sui pin 3 e 11, (Timer 2). Per riassumere le impostazioni di registro , Il bit di generazzione di forma d'onda WGM lo impostiamo a 011 (selezione fast PWM mode). Impostiamo i bit COM2A e COM2B a 10 (PWM non invertito per le uscite A e B). l'impostazione del bit CS la mettiamo a 100 (quindi dividiamo il clock di sistema per 64). (Poiché i bit sono diversi per i diversi timer , consultare il datasheet .)
Le uscite dei registri di comparazione sono impostate arbitrariamente a 180 e 50 per il controllo del dutycycle del PWM per le uscite A e B. (Naturalmente, si può anche modificare i registri direttamente invece di utilizzare pinMode, ma è necessario impostare il pin di uscita. )

Su Arduino Duemilanove , abbiamo questi valori :
* Frequenza dell'uscita A: 16 MHz / 64 / 256 = 976.5625Hz
* Uscita A dutycycle: (180 +1) / 256 = 70,7%
* Frequenza dell'uscita B: 16 MHz / 64 / 256 = 976.5625Hz
* Uscita B dutycycle: (50 +1) / 256 = 19,9%
La frequenza di 16MHz (frequenza del clock di sistema), diviso per il valore prescaler (64) , diviso per i 256 cicli necessari per un ciclo del timer.
PWM a correzione di fase
La seconda modalità di PWM  è chiamata phase-correct PWM. In questa modalità , il timer conta da 0 a 255 e poi di nuovo giù a 0. L'uscita si spegne, appena il timer raggiunge il valore del registro di comparazione di uscita durante la salita , e si gira nuovamente appena il timer raggiunge il valore del registro di comparazione di uscita durante la discesa . Il risultato è un uscita più simmetrica . La frequenza di uscita sarà pari a circa la metà del valore per la modalità fast PWM, perché avverrà allo scadere del tempo , sia in su che in giù (un pò dome le memorie DDR dei pc).
L'esempio seguente imposta il PWM a correzione di fase sui pin 3 e 11, (Timer 2). I bit di forma d'onda WGM sono impostati su a 001 (fase -correct PWM).
Gli altri bit sono uguali allèesempio del fast PWM .
pinMode (3, OUTPUT) ;

pinMode (11, OUTPUT) ;

TCCR2A = _BV ( COM2A1 ) | _BV ( COM2B1 ) | _BV ( WGM21 ) | _BV ( WGM20 );

TCCR2B = _BV ( CS22 );

OCR2A = 180 ;

OCR2B = 50;
Su Arduino Duemilanove , abbiamo questi valori:
  • Frequenza uscita A : 16 MHz / 64 / 255 / 2 = 490.196Hz
  • Dutycycle uscita A: 180/255 = 70,6%
  • Frequenza uscita B : 16 MHz / 64 / 255 / 2 = 490.196Hz
  • Dutycycle uscita B : 50 / 255 = 19,6%
Come vedete dai valori, il PWM phase correct , divide la frequenza in due rispetto al fast PWM, perché il timer scatta sia a monte che a valle . Sorpresa delle sorprese, la frequenza è divisa per 255 invece di 256, e ai calcoli del Ciclo non aggiunge uno come per il fastPWM.
Oltre il limite : fast PWM
Entrambi le modalità di PWM dispongono di un modo aggiuntivo che permette di controllare la frequenza di uscita . In questa modalità , il timer conta da 0 a OCRA, invece  che da 0 a 255. Questo dà un controllo sulla frequenza di uscita più preciso rispetto alle modalità precedenti. (Per un controllo di frequenza ancora più preciso, usa il timer 1 a 16 bit ).
Si noti però,che in questa modalità, solo uscita B può essere utilizzata per il PWM ; OCRA non può essere utilizzato in due modi contemporaneamente. Tuttavia, vi è una modalità speciale per caso "Toggle Ocna on Match "che cambia lo stato di uscita A alla fine di ogni ciclo , generando un duty cycle fisso del 50% e la frequenza di un mezzo in questo caso.
Nel diagramma seguente, il timer viene azzerato quando cicla OCRnA , producendo una frequenza di uscita più veloce per OCnB che negli esempi precedenti. Nota come Ocna cambia una volta per ogni reset del timer.
Fast PWM con cimatura di OCRA.
Il codice seguente imposta PWM fast sui pin 3 e 11, (Timer 2), utilizzando OCR2A come valore di limite superiore del timer. Il bit di forma d'onda e generazione WGM sono impostati su 111 per PWM fast ma ora OCRA  ha il controllo sul limite superiore. Il limite superiore di OCR2A lo fissiamo arbitrariamente a 180 , e  OCR2B lo fissiamo arbitrariamente a 50. OCR2A adesso e in modalità " Attiva quando corrisponde", imposiamo il bit COM2A a 01 .
pinMode (3, OUTPUT) ;

pinMode (11, OUTPUT) ;

TCCR2A = _BV ( COM2A0 ) | _BV ( COM2B1 ) | _BV ( WGM21 ) | _BV ( WGM20 );

TCCR2B = _BV ( WGM22 ) | _BV ( CS22 );

OCR2A = 180 ;

OCR2B = 50;
Sul Arduino Duemilanove , abbiamo questi valori :
  • Frequenza di uscita A: 16 MHz / 64 / (180 +1) / 2 = 690.6Hz
  • Dutycycle uscita A : 50%
  • Frequenza di uscita B : 16 MHz / 64 / (180 +1) = 1381.2Hz
  • Dutycycle uscita B: (50 +1) / (180 +1) = 28,2%
Si noti che in questo esempio, il timer va da 0 a 180, che però prende 181 cicli di clock , per cui la frequenza di uscita è divisa per 181. L'uscita A ha la metà della frequenza dell'uscita B perché la modalità di confronto cambia l'uscita A una volta per ogni ciclo completo del timer .
Oltre ogni limite : ma per il phase-correct PWM
Allo stesso modo , il timer può essere configurato per il phase -correct PWM e ciclare quando raggiunge OCRnA .
L'esempio seguente imposta PWM phase correct sui pin 3 e 11, (con il Timer 2), utilizzando OCR2A come valore superiore per il timer. I bit del WGM sono impostati su a 101 per PWM phase correct con il controllo del limite superiore. Il limite superiore  OCR2A è fissato arbitrariamente a 180 , e la OCR2B (registro di confronto) è fissato arbitrariamente a 50. OCR2A modalità è impostato su " Attiva su corrispondenza al confronto", impostando i bit COM2A a 01 .
pinMode (3, OUTPUT) ;

pinMode (11, OUTPUT) ;

TCCR2A = _BV ( COM2A0 ) | _BV ( COM2B1 ) | _BV ( WGM20 );

TCCR2B = _BV ( WGM22 ) | _BV ( CS22 );

OCR2A = 180 ;

OCR2B = 50;
Sul Arduino Duemilanove , abbiamo questi valori :
  • Frequenza dell'uscita A: 16 MHz / 64 / 180 / 2 / 2 = 347.2Hz
  • Dutycycle uscita A : 50%
  • Frequenza dell'uscita B: 16 MHz / 64 / 180 / 2 = 694.4Hz
  • Dutycycle uscita B: 50 / 180 = 27,8%
Si noti che in questo esempio, il timer va da 0 a 180 e di nuovo a 0 , il che prende 360 cicli di clock. Così, tutto è diviso per 180 o 360, a differenza del caso PWM fast, che invece ha diviso tutto con per 181 ( vedi sotto per i dettagli).
L'errore "Off- by-one".
Avrete notato che PWM fast e PWM phase correct sembrano essere off- by-one l'uno  rispetto all'altro , dividendo per 256 invece che per 255 e aggiungendo uno in vari luoghi.
Supponiamo che il timer sia impostato in modalità PWM fast è impostata a contare fino a un valore di OCRnA di 3. Il timer assumerà i valori 012301230123 ... Si noti che ci sono 4 cicli di clock per ogni ciclo del timer. Così, la frequenza sarà divisa per 4 e non 3. Il dutycycle sarà un multiplo di 25%, dato che il segnale sara "alto" a  0, 1, 2 , 3 o 4 . Allo stesso modo, se il timer conta fino a 255 , ci saranno 256 cicli di clock in ogni ciclo del timer , e il dutycycle sarà multiplo di 1 / 256 . Quindi, PWM fast divide per N +1 , dove N è il valore del timer massimo (sia OCRnA o 255).
Ora consideriamo la modalità PWM phase correct con il timer conta fino ad un valore di OCRnA 3. I valori di timer sarà 012321012321 ... Ci sono 6 cicli di clock per ogni ciclo del timer ( 012.321 ). Così la frequenza sarà diviso per 6. Il ciclo di lavoro sarà un multiplo di 33%, dato che il segnale sarà "alto"  per 0, 2 , 4 o 6 dei 6 cicli . Allo stesso modo, se il timer conta fino a 255 e ritorno verso il basso , ci saranno 510 cicli di clock in ogni ciclo del timer , e il dutycycle sarà un multiplo di 1 / 255 . Quindi, PWM phase correct divide per 2N , dove N è il valore del timer massimo.
La seconda differenza importante è che il PWM fast tiene l'output ad alto per un ciclo più lungo del valore del registro di comparazione. La motivazione di ciò è che PWM fast  conta fino a 255 , il dutycycle può essere 0-256 cicli, ma il registro può contenere solo un valore da 0 a 255. Cosa succede al valore mancante ? La modalità PWM fast mantiene l' alta l'uscita per cicli di N +1 quando il registro di comparazione è impostato su N così un registro con valore di 255 è 100 % del dutycycle, ma un registro con valore 0 è non dutycycle  0 %, ma 1 / 256 del dutycycle. Questo a differenza del PWM phase correct, in cui un valore di registro di 255 è 100 % del dutycycle e un valore di 0 è un dutycycle dello 0%.
Timer e Arduino
Il Arduino supporta PWM su alcuni dei pin di uscita. Può non essere immediatamente evidente che c'è in timer che ne controlla l'utilizzo , ma la tabella seguente chiarirà la situazione. Essa fornisce, per ogni uscita del temporizzatore, il pin di uscita sul Arduino (cioè l'etichetta serigrafata sulla scheda) , il pin sul chip ATmega , e il nome e poco di porta di uscita . Per esempio Timer 0 OC0A uscita è collegata all'uscita Arduino pin 6 , utilizza chip pin 12 che è anche conosciuto come PD6 .
Timer di uscita Uscita su Arduino Pin sul chip Nome pin
OC0A                          6                          12                 PD6
OC0B                          5                          11                 PD5
OC1A                          9                          15                 PB1
OC1B                         10                          16                 PB2
OC2A                         11                          17                 PB3
OC2B                           3                            5                 PD3
Arduino inizializza il prescaler su tutti e tre i timer per dividere il clock per 64. Timer 0 è inizializzato in PWM fast, mentre i Timer 1 e Timer 2 vengono impostati come PWM phase correct .
Il Arduino utilizza il Timer 0 interno per i comandi Millis () e delay () , quindi sappiate che modificando la frequenza di questo timer quei comandi danno segni di pazzia. Usare le uscite PWM, invece,  è sicuro se non si cambiamo le frequenze.
Con il comando analogWrite (pin , duty_cycle ) si imposta il pin appropriato PWM e  l'output appropriato nel registro di comparazione (Con il caso particolare di dutycycle del Timer 0 su 0). Il comndo digitalWrite () disattiva l'uscita PWM se viene chiamato su un pin timer.
Se si utilizza analogWrite (5, 0) si ottiene un dutycycle dello 0% , anche se il pin 5 del timer ( Timer 0) utilizza PWM fast. Come è possibile , quando un valore di PWM fast di 0 produce un ciclo di 1 / 256 , come spiegato sopra? La risposta è che analogWrite " bara" , ha un codice per i "casi speciali" per spegnere il pin quando si usa il Timer 0 con un dutycycle pari a 0. Come conseguenza , il ciclo che doveva essere 1 / 256 non è disponibile quando si utilizza analogWrite su Timer0 , e vi è un salto nel ciclo di lavoro reale tra i valori di 0 e 1.
Spero che questo piccolo tutorial messo insieme studianodo varii documenti reperibili sulla rete ed il datasheet dell'atmega 328, sia utile a tutti voi così come è stato utile per mè.
trovate il documento originale su cui è basato questo tutorial all'indirizzo: http://www.arcfn.com/2009/07/secrets-of-arduino-pwm.html