Buongiorno a tutti. Ho un semplice sketch che genera un segnale pwm sul pin digitale 10.
Se provo a generare ripetutamente lo stesso impulso, nell'oscilloscopio vedo il segnale corretto.
Ma se vario il duty cycle per alcuni periodi, il segnale non mi appare come me lo aspetto.
Ma per altri tipi di segnale no.
Ad esempio, ho provato a generare un segnale il cui ciclo dura 100ms ed è fatto così:
50% del duty cycle per 20ms
75% del duty cycle per 40ms
100% del duty cycle per 40ms
Ho fatto degli screenshot relativi a questo segnale e non mi sembra che abbia la forma d'onda desiderata.
Sapete dirmi se magari per una questione hardware le variazioni di duty cycle impiegano un certo ritardo?
Grazie
non è che si vede benissimo la forma donda (forse dovresti stringere la bsae dei tempi), poi se vari li Duty mentre magari sta lavorando ci possono essere dei "malfunzionamenti" (approprosito come vari il Duty...via serial, potenzionetro...)
poi se metti anche il programmino magari si puo dare un occhio che non si siano erroi strani (non io ma quelli bravi )
Varo il duty cycle mentre sta già lavorando.
int pwmPin = 10;
const int periodsNumber = 3;
const int time[periodsNumber] = {20,40,40};
int dutyCycle[periodsNumber] = {128,192,255};
void setup() {
pinMode(pwmPin, OUTPUT);
}
void loop() {
for (int j = 0; j < periodsNumber; j++) {
analogWrite(pwmPin, dutyCycle[j]);
delay(time[j]);
}
}
Precisione e digitalWrite/analogWrite sono 2 cose che non possono andare d'accordo. Sono istruzioni di Arduino che richiedono parecchio tempo (in termini di cicli di clock) per essere eseguiti. Vai di manipolazione diretta dei registri del timer per ottenere tempi più esatti. Non so neanche se ti conviene andare di delay oppure impostare un secondo timer che solleva un interrupt dalla cui ISR setti la temporizzazione del primo.
Vai di manipolazione diretta dei registri del timer per ottenere tempi più esatti. Non so neanche se ti conviene andare di delay oppure impostare un secondo timer che solleva un interrupt dalla cui ISR setti la temporizzazione del primo.
Scusami, credo proprio di non aver capito. Non tanto perchè sono cose che non conosco, ma non saprei proprio cosa cercare anche per fare da solo.
Come primo passo traduco tutto in C?
Se vuoi velocità ed automazione l'unica è andare di timer che pilota il timer.
Imposti un timer per sollevare un interrupt ad intervalli regolari, una frazione dell'intero periodo.
Ad esempio, se l'intero ciclo è di 100 ms e poi intervieni al 50%, al 75% ed al 100% del ciclo, avrai quindi un tempo di 4/4.
Imposti quindi il timer affinché abbia un periodo tra un overflow ed il successivo pari ad 1/4 del ciclo. Ad ogni overflow con un interrupt controlli a che "punto" sei e setti poi il registro che regola il duty cycle del 2° timer di conseguenza.
E' più difficile a spiegarsi che a farsi.
leo72:
Precisione e digitalWrite/analogWrite sono 2 cose che non possono andare d'accordo.
Metti nel calderone pure il fatto che sta usando Arduino come oscilloscopio, il che introduce ulteriori fattori di errori visti i limiti operativi del suo ADC.
Credo di aver realizzato un codice migliore intervenendo direttamente sui registri.
Ho cambiato solo la frequenza per poter osservare meglio il segnale con base dei tempi più ristretta.
#define F_CPU 8000000
#define ARDUINO 105
#include "Arduino.h"
const int periodsNumber = 3;
const int time[periodsNumber] = {20,40,40};
int dutyCycle[periodsNumber] = {127,63,0};
void setup() {
//IMPOSTA IL PIN DIGITALE 10 COME OUTPUT
DDRB = _BV(PB2);
//IMPOSTA LA MODALITA' FAST PWM MODE CON OCR1A AL TOP, PRESCALER A 64 E IL PIN DIGITALE 10 IN MODALITA' INVERTITA
TCCR1A = _BV(COM1B1) | _BV(COM1B0) | _BV(WGM11) | _BV(WGM10);
TCCR1B = _BV(CS11) | _BV(CS10) | _BV(WGM13) | _BV(WGM12);
//IMPOSTA IL VALORE DI TOP
OCR1A = 255;
//IMPOSTA IL DUTY CYCLE DEL PIN DIGITALE 10
OCR1B = 0;
}
void loop() {
for (int j = 0; j < periodsNumber; j++) {
OCR1B = dutyCycle[j];
delay(time[j]);
}
}
Cavolo ci dev'essere un problema col parser presente sul sito. Il codice è renderizzato in modo illeggibile, almeno per me...
strano, io lo vedo benissimo, anche aggiornando la pagina
Sto procedendo così: imposto il timer2 come riferimento nel tempo del segnale pwm, nel senso che ha come funzione solo quella di generare ad intervalli regolari, es. 10ms un interrupt di overflow.
Nella ISR di questo interrupt con l'ausilio di altre variabili tengo conto di quale posizione del ciclo ho raggiunto (1-10) e da qui prendo decisioni su come variare il duty cycle del pwm controllato dal timer1.
Procedo scrivendo e testando il codice. Spero che mi porterà ai risulati aspettati.
In ogni caso è stato utili compiere questo studio.
ultrasound91:
strano, io lo vedo benissimo, anche aggiornando la pagina
Anch'io ora da casa, forse è un problema legato alla combinazione SO/browser di lavoro (WinXP/Chrome)