Arduino ATMEGA328P 1MHz: tone() a intermittenza

Sezione dedicata ai Microcontrollori e ai Sistemi Embedded

Arduino ATMEGA328P 1MHz: tone() a intermittenza

Postby Datman » 20 Apr 2015, 10:23

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
Last edited by Datman on 20 Apr 2015, 12:28, edited 3 times in total.
Datman
 
Posts: 7
Joined: 20 Apr 2015, 09:19

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

Postby deluca » 20 Apr 2015, 11:37

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.
Ciao
Il mio sito: http://www.delucagiovanni.com ......e la chat: chat/
User avatar
deluca
Site Admin
 
Posts: 1104
Joined: 19 Jun 2011, 10:44
Location: 95123 - Catania (Italy)

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

Postby Datman » 20 Apr 2015, 16:38

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.
Datman
 
Posts: 7
Joined: 20 Apr 2015, 09:19

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

Postby Leonardo » 20 Apr 2015, 17:37

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
Last edited by Leonardo on 20 Apr 2015, 19:36, edited 1 time in total.
Il mio blog di elettronica: http://electro-logic.blogspot.it
User avatar
Leonardo
 
Posts: 502
Joined: 29 May 2013, 22:31
Location: Parma

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

Postby Leonardo » 20 Apr 2015, 19:33

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.
Il mio blog di elettronica: http://electro-logic.blogspot.it
User avatar
Leonardo
 
Posts: 502
Joined: 29 May 2013, 22:31
Location: Parma

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

Postby Datman » 21 Apr 2015, 08:33

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...
Datman
 
Posts: 7
Joined: 20 Apr 2015, 09:19

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

Postby deluca » 22 Apr 2015, 08:26

@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
Ciao
Il mio sito: http://www.delucagiovanni.com ......e la chat: chat/
User avatar
deluca
Site Admin
 
Posts: 1104
Joined: 19 Jun 2011, 10:44
Location: 95123 - Catania (Italy)

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

Postby Datman » 22 Apr 2015, 09:01

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.
Datman
 
Posts: 7
Joined: 20 Apr 2015, 09:19

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

Postby Leonardo » 22 Apr 2015, 09:03

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.
Il mio blog di elettronica: http://electro-logic.blogspot.it
User avatar
Leonardo
 
Posts: 502
Joined: 29 May 2013, 22:31
Location: Parma

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

Postby Datman » 22 Apr 2015, 09:14

Grazie anche a te, Leonardo.
Vedo che nel testo si fa riferimento al 164. Che differenze ci sono rispetto al 328?
Datman
 
Posts: 7
Joined: 20 Apr 2015, 09:19

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

Postby Datman » 22 Apr 2015, 09:39

C'è anche The AVR Microcontroller and Embedded Systems using assembly and C, di Muhammad Ali Mazidi, Sarmad Naimi, Sepher Naimi. Interessante... Lo conoscete?
Datman
 
Posts: 7
Joined: 20 Apr 2015, 09:19

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

Postby deluca » 22 Apr 2015, 13:57

Si lo conosco e devo dire che non è male.
Ciao
Il mio sito: http://www.delucagiovanni.com ......e la chat: chat/
User avatar
deluca
Site Admin
 
Posts: 1104
Joined: 19 Jun 2011, 10:44
Location: 95123 - Catania (Italy)


Return to Microcontrollori e microprocessori

Who is online

Users browsing this forum: No registered users and 3 guests

cron