Come da titolo sarei interessato a creare nuove porte PWM sul mio attiny , visto la scarsa disponibilità di altri microcontrollori ho pensato di realizzarli via software ma niente , non ne ho idea di come fare , qualcuno mi puó aiutare?
Ciao niko
Un segnale PWM è un segnale ad onda quadra ad una certa frequenza e con un duty cicle, ossia la percentuale del segnale alto rispetto al totale, impostata dall'utente.
Sugli Atmel tale segnale è generato via HW dai timer interni. L'Attiny85 ha nello specifico 2 canali PWM mentre l'Attiny84 ne ha 4. Se non ti bastano, puoi provare a generarli via software. Non si tratta altro che alternare lo stato di un pin da HIGH a LOW ciclicamente. Ad esempio:
void loop() {
digitalWrite(Pin, HIGH);
delayMicroseconds(500);
digitalWrite(Pin, LOW);
delayMicroseconds(500);
}
genera un segnale PWM con duty cicle 50% e frequenza di 1 KHz, se non ho fatto male i conti.
E' ovvio che così il tuo codice non può fare altro, per cui dovresti adattarlo a creare l'onda continuando a gestire il tuo sketch. Però ricordati che se il micro deve fare molti compiti poi la frequenza che ne risulta potrebbe essere alterata per i rallentamenti causati dall'esecuzione dello sketch.
Ok ora proveró , ma il tempo massimo e il tempo minimo della durata di una semionda , cioé 0 e 255 a quanti millisecondo equivalgono?
Sull'Arduino il conto si fa presto: il segnale PWM ha una frequenza di 490 Hz con duty cicle del 50%.
Sui Tiny dipende dalla frequenza del micro e da come viene impostato il timer per generare il segnale: andrebbe analizzato il file che configura questi valori. Così su 2 piedi non so darti valori precisi, dovrei esaminare la cosa.
Scusami, non avevo fatto attenzione al fatto che tu chiedevi 2 casi ben specifici: 0 e 255.
Questi valori equivalgono ad un segnale fisso, non PWM.
In caso di valore 255, il pin viene impostato su HIGH perché un duty cicle del 100% equivale ad avere il segnale sempre su HIGH mentre per quanto riguarda il valore 0, il pin viene messo erroneamente su LOW.
Dico erroneamente perché il calcolo del "fast PWM" considera anche lo 0 dato che la formula secondo il datasheet è (valore registro OCRxA+1) quindi in teoria si perde il caso di un segnale PWM con duty cicle pari a 1/256.
void loop() {
digitalWrite(Pin, HIGH);
delayMicroseconds(500);
digitalWrite(Pin, LOW);
delayMicroseconds(500);
Proveró con questo come punto di partenza e credo che probabilmente funzionerà , poi proveró a generare duty cicle diversi, ti faró sapere .
Grazie
Puoi sempre farti una funzione a cui passi un numero (magari in percentuale) corrispondente al PWM che vuoi ottenere e tramite un calcolino lei dividi i due tempi del duty cycle, volendo potresti passare addirittura due numeri, uno corrispondente al PWM ed uno al pin su cui vuoi applicarlo
Puoi sempre farti una funzione a cui passi un numero (magari in percentuale) corrispondente al PWM che vuoi ottenere e tramite un calcolino lei dividi i due tempi del duty cycle, volendo potresti passare addirittura due numeri, uno corrispondente al PWM ed uno al pin su cui vuoi applicarlo
Bella idea grazie , adesso , dopo il grande pranzo se riesco a non addormentarmi ci provo subito XD
nikone:
Puoi sempre farti una funzione a cui passi un numero (magari in percentuale) corrispondente al PWM che vuoi ottenere e tramite un calcolino lei dividi i due tempi del duty cycle, volendo potresti passare addirittura due numeri, uno corrispondente al PWM ed uno al pin su cui vuoi applicarlo
Bella idea grazie , adesso , dopo il grande pranzo se riesco a non addormentarmi ci provo subito XD
Però pubblicala poi
Io ho realizzato una lampada RGB con un ATtiny85 e ho scritto queste due funzioni per realizzare una variazione di tensione continua, forse possono servirti come spunto:
void swPWMinc(int led){
int i=0;
int j=0;
for(i=0;i<=23;i++){
for(j=0;j<=4;j++){
digitalWrite(led, HIGH);
delay(23-i);
digitalWrite(led, LOW);
delay(i);
j++;
}
}
}
void swPWMdec(int led){
int i=0;
int j=0;
for(i=0;i<=23;i++){
for(j=0;j<=4;j++){
digitalWrite(led, HIGH);
delay(i);
digitalWrite(led, LOW);
delay(23-i);
j++;
}
}
}
in cui il parametro led indica il pin sul quale voglio la variazione. Il valore LOW nel mio caso corrisponde al led acceso.
Comunque alla fine leggendo questo topic ho visto che potevo fare la mia lampada usando i pin 0,1,4 ed effettivamente mi funzionano tutti e tre come PWM.
http://arduino.cc/forum/index.php/topic,75334.0.html
Non l'avevo mai visto ma è uile....
Permettimi una domanda brain ... Perchè inizializzi più volte i e j ? potresti fare tutto all'interno del for...
A me risulta che i tiny85 hanno solo 2 pin pwm gestiti in HW.
Questo dice il datasheet, questo dice la mappatura dei pin nel core Tiny.
Hai ragione, ho fatto un pò di modifiche per cercare la soluzione che mi piacesse di più e poi, quando l'ho trovata non ho più pulito il codice, non c'è nessun motivo per le doppie inizializzazioni
Credo allora che se riesco a generarlo sul pin4 allora sono a posto , comunque lavoreró sul soft PWM
Ciao Niko
Io ho seguito la tua guida e credo di aver usato il tiny core, infatti ho trovato quel post proprio cercando un modo per realizzare il terzo segnale PWM. Però ho provato con i pin segnalati in quel post su un codice che avevo scritto per arduino e mi ha funzionato bene.
Scusate se non vi rispondo subito ma il natale mi chiama
Auguri a tutti!
Mi sono incuriosito e sono andato a rileggere il datasheet, effettivamente hai ragione. Mi sono sempre basato più sulla piedinatura indicata dal file pins_arduino.c del core Tiny che sul datasheet, ma questo riporta che anche i piedini 2 e 3 sono agganciati al timer 1. Quindi in teoria potrebbero esserci 4 pin PWM. Mi suona strano, però, che solo 2 siano indicati nel core Tiny come capaci di generare PWM. Devo chiedere allo scrittore del core Tiny.
EDIT:
in teoria sarebbero 4 segnali ma in pratica sono solo 3 distinti dato che il 4° segnale è l'inverso del 3°, quindi il pin D3 ha un segnale opposto a quello presente sul D4.
Queste news sono molto positive , solo non mi é chiaro come all'ideatore del core Tony sia sfuggito questo particolare , probabilmente errore umano
Comunque brain dice che va per cui l'errore deve essere solo negli schemi di pinout
Ho avuto conferme dal creatore del core Tiny. L'Attiny85 supporta il PWM anche su D4 ed il pinout che è inserito nei commenti del file non è aggiornato.
Ho avuto conferme dal creatore del core Tiny. L'Attiny85 supporta il PWM anche su D4 ed il pinout che è inserito nei commenti del file non è aggiornato.
Grazie Leo per avere chiesto , proveró comunque il PWM via software e poi faró sapere
Ciao Niko
Ciao,
io sto giocattolando con gli attiny45 per un progettino (già avviato per benino :D).
Poichè gestisco degli RGB, cercando appunto come gestire 3 canali PWM ero arrivato ai BlinkM:
http://thingm.com/products/blinkm
che sostanzialmente è molto simile al mio progettino (o forse sarebbe meglio dire il contrario ).
Avevo provato a prendere spunto da questo codice, che implementa il pwm via sw:
http://code.google.com/p/blinkm-projects/source/browse/trunk/BlinkMuino/hardware/blinkm/examples/BlinkMuinoFade/BlinkMuinoFade.pde
ma sinceramente non mi piaceva molto.
Ho trovato molto più di ispirazione questo:
che mi sembra tutto sommato molto più semplice da gestire.
Per 3 PWM non hai problemi, puoi fare tutto da Attiny85, come abbiamo visto il micro è in grado di gestire 3 segnali in HW.
I BlinkM sono oggettini carini ma solo da ammirare perché costano uno sproposito, secondo me. L'unica cosa che può essere utile è il software per creare le varie sfumature di colore, ma solo se non si conoscono i principi dell'ottica e di come si formano i colori secondari.