Page 1 of 1

Arduino ATMEGA328P 1MHz: tone() a intermittenza

PostPosted: 20 Apr 2015, 10:23
by Datman
Buongiorno a tutti
Vorrei porre a voi un problema che ancora non sono riuscito a risolvere, nonostante anche le mie richieste di aiuto in newsgroup e forum.

Ho realizzato un apparecchietto che in certe condizioni deve emettere un BIIIP. Inizialmente il 328P girava quarzato a 16MHz e non accadeva nulla di strano; poi, quando tutto era più o meno finito, ho cominciato a ottimizzare, principalmente per ridurre l'assorbimento, che era circa 14mA. L'alimentazione viene fornita da una pila da 9V, con la tensione regolata a 5V da uno stabilizzatore micropower low-dropout.

Ho, perciò, riprogrammato i fuse per il funzionamento con clock interno a 1MHz (8MHz/DIV8) inserendo nel file boards.txt una voce "Arduino uno 1MHz (ATmega328)":

uno1MHz.name=Arduino uno 1MHz (ATmega328)
uno1MHz.upload.protocol=arduino
uno1MHz.upload.maximum_size=32256
uno1MHz.upload.speed=9600
uno1MHz.bootloader.low_fuses=0x62
uno1MHz.bootloader.high_fuses=0xd9
uno1MHz.bootloader.extended_fuses=0xfd
uno1MHz.bootloader.path=optiboot
uno1MHz.bootloader.file=optiboot_atmega328.hex
uno1MHz.bootloader.unlock_bits=0x3F
uno1MHz.bootloader.lock_bits=0x0F
uno1MHz.build.mcu=atmega328p
uno1MHz.build.f_cpu=1000000L
uno1MHz.build.core=arduino
uno1MHz.build.variant=standard

Il bootloader in realtà non mi serve, perché programmo con USBasp, ma così programmo i fuse.

Tutto sembrava funzionare normalmente tranne le temporizzazioni delayMicroseconds(100), problema che ho risolto impiegando delay(.12) (per ottenere 100uS ho dovuto impostare 0,12 causa la tolleranza dell'oscillatore interno).

C'è, invece, un piccolo problema: adesso il "BIIIP" ha delle interruzioni periodiche, un "cri-cri-cri" circa ogni 400mS per un BIIIP a 1kHz. Da che cosa dipende??? Con il clock a 16MHz non lo fa...
I 400mS della ripetizione del disturbo variano se cambio la frequenza del BIIIP
Il difetto è lo stesso anche cambiando I/O (4, 6, 12...)
Il difetto non parte sempre con lo stesso ritardo rispetto all'inizio del suono, ma ha una sua temporizzazione indipendente dal momento in cui il suono ha inizio.

Ecco uno sketch di test:

int a=12; //Pin su cui è collegato il buzzer piezo
void setup()
{
pinMode (a, OUTPUT);
}
void loop()
{
tone(a, 1000);
delay (2000);
noTone(a);
delay (1000);
}

A che cosa può essere dovuto? Interrupt?
E' un difetto del compilatore (IDE di Arduino)?
Come posso risolvere il problema?

Grazie!
Gianluca

Re: Arduino ATMEGA328P 1MHz: tone() a intermittenza

PostPosted: 20 Apr 2015, 11:37
by deluca
Salve Datman e benvenuto al forum.
Prima di procedere con richieste relative alla risoluzione di problematiche varie,
ti consiglio di presentarti nella sezione dedicata al fine di farti notare da quanti più iscritti possibili.

Saluti.

Re: Arduino ATMEGA328P 1MHz: tone() a intermittenza

PostPosted: 20 Apr 2015, 16:38
by Datman
Fatto! :-)

Riguardo al mio quesito, ho fatto un'altra prova e ho scoperto che con un clock a 16MHz il problema si manifesta ugualmente, ma quando vengono generate frequenze superiori. Avevo letto, infatti, che una persona chiedeva aiuto (in inglese) perché generava 20kHz ma il segnale che veniva prodotto non era inudibile, come si aspettava! Allora hanno cominciato a fare ipotesi assurde sulle armoniche... :-)
Con il clock a 1MHz, il rumore è inudibile (sembra... devo controllare con l'oscilloscopio) generando 970Hz; a 16MHz il rumore è assente a 15500Hz. Questo avviene con il 328P che ho qui montato. Con un altro esemplare a 1MHz bisogna, certo, considerare l'elevata tolleranza dell'oscillatore RC interno.

Re: Arduino ATMEGA328P 1MHz: tone() a intermittenza

PostPosted: 20 Apr 2015, 17:37
by Leonardo
Ciao Gianluca,

Benvenuto al forum,

Se il vero scopo è migliorare l'efficienza energetica agirei sull'alimentazione sostituendo la pila da 9v con delle stilo o una LiPo ed elimineri l'LDO se possibile.

Prima di agire sulla frequenza la strada da seguire è eliminare qualsiasi delay() e utilizzare gli stati di sleep del microcontrollore, otterresti vantaggi molto maggiori anche se è un po più complicato.

Leonardo

Re: Arduino ATMEGA328P 1MHz: tone() a intermittenza

PostPosted: 20 Apr 2015, 19:33
by Leonardo
La funzione tone() è basata sugli interrupt ed ho verificato il comportamento che descrivi.

La libreria di Arduino funziona generalmente bene a 8 o 16 MHz, 1 MHz è una frequenza un po atipica per gli utenti di Arduino e potresti passare ad una programmazione di basso livello per non avere questo tipo di problemi. Il passo è però molto lungo e la difficoltà maggiore.

Re: Arduino ATMEGA328P 1MHz: tone() a intermittenza

PostPosted: 21 Apr 2015, 08:33
by Datman
Grazie :-)
C'è qualche buon testo sulla programmazione a basso livello degli Atmel? Vorrei un testo completo, senza dover stare a cercare informazioni qua e là per la rete, senza nemmeno rendermi conto se su un argomento c'è qualche altra cosa importante che devo sapere...

Re: Arduino ATMEGA328P 1MHz: tone() a intermittenza

PostPosted: 22 Apr 2015, 08:26
by deluca
@datman,
a basso livello, intendi programmazione assembly? o altro...

Se non hai difficoltà con l'inglese uno dei testi che ricordo è questo:

Embedded Systems Design with the Atmel AVR Microcontroller di Steven Barrett

Re: Arduino ATMEGA328P 1MHz: tone() a intermittenza

PostPosted: 22 Apr 2015, 09:01
by Datman
Beh... In generale le istruzioni preferisco leggerle in Inglese o in Tedesco, piuttosto che in Italiano tradotto... :-)
Me la cavo bene con l'Inglese tecnico.
Grazie, cerco un'anteprima del libro in rete.

Re: Arduino ATMEGA328P 1MHz: tone() a intermittenza

PostPosted: 22 Apr 2015, 09:03
by Leonardo
Penso che la richiesta sia riferita alla mia risposta precedente, che intendeva l'utilizzo diretto dei timer e delle interruzioni del microcontrollore, anche con linguaggi come il C senza necessariamente scendere nell'assembly. Il libro quindi è appropriato.

Re: Arduino ATMEGA328P 1MHz: tone() a intermittenza

PostPosted: 22 Apr 2015, 09:14
by Datman
Grazie anche a te, Leonardo.
Vedo che nel testo si fa riferimento al 164. Che differenze ci sono rispetto al 328?

Re: Arduino ATMEGA328P 1MHz: tone() a intermittenza

PostPosted: 22 Apr 2015, 09:39
by Datman
C'è anche The AVR Microcontroller and Embedded Systems using assembly and C, di Muhammad Ali Mazidi, Sarmad Naimi, Sepher Naimi. Interessante... Lo conoscete?

Re: Arduino ATMEGA328P 1MHz: tone() a intermittenza

PostPosted: 22 Apr 2015, 13:57
by deluca
Si lo conosco e devo dire che non è male.