Pages: 1 ... 3 4 [5] 6 7 ... 9   Go Down
Author Topic: Come far lavorare ATmega a 128KHz di clock  (Read 6251 times)
0 Members and 1 Guest are viewing this topic.
Rome (Italy)
Offline Offline
Tesla Member
***
Karma: 120
Posts: 9185
"Il Vero Programmatore ha imparato il C sul K&R, qualunque altro testo è inutile e deviante."
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

se hai qualche applicazione fatta mi sarebbe utile come spunto /difficoltà con l'inglese), in ogni caso  1µA di consumo  mi risolverebbe il problema finché campo, considerando che alimento il circuito con una batteria da 3,6V di circa 1000mA!

Oggi pomeriggio ti scrivo uno sketch di prova che mette l'ATmega a nanna, consumo < 1uA, e si risveglia, con un bello sbadiglio, quando cambi stato a INT1 o INT0, così hai la base per lavorarci attorno.

Logged

Lamezia Terme
Offline Offline
Shannon Member
****
Karma: 415
Posts: 11993
Le domande di chi vuol imparare rappresentano la sua sete di sapere
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

 smiley-lol smiley-lol smiley-lol smiley-lol a buon rendere...ma ne sai troppo più di me  smiley-red
Logged

Guida alla programmazione ISP e seriale dei micro ATMEL (Caricare bootloader e sketch):
http://www.michelemenniti.it/Arduino_burn_bootloader.php
Guida alla Programmazione ATmega328 noP:
http://www.michelemenniti.it/atmega328nop.html
Articoli su Elettronica In:
http://www.michelemenniti.it/elettronica_in.html

Global Moderator
Italy
Offline Offline
Brattain Member
*****
Karma: 313
Posts: 21645
Logic is my way
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

@garinus:
non è che forse i tuoi problemi dipendono dal tempo di uscita dal reset? Se leggi sui datasheet dei micro, essi necessitano di un tempo minimo affinché la procedura di reset sia portata a termine correttamente. Se imposti tempi troppo brevi, potresti avere problemi di autoreset.
Logged


Rome (Italy)
Offline Offline
Tesla Member
***
Karma: 120
Posts: 9185
"Il Vero Programmatore ha imparato il C sul K&R, qualunque altro testo è inutile e deviante."
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Eccoti un semplice sketch di prova per lo sleep.
Il funzionamento è banale, il programma esegue un loop di 10 secondi, facendo lampeggiare il led, dopo di che viene messo il micro in sleep.
Portando a 0 logico INT0 (PD2 = pin 2), è attiva la sua pull up, il micro si risveglia, esegue la funzione per l'interrupt abbinato ai pin, l'ho lasciata vuota, ma puoi sempre metterci qualcosa dentro, e riparte con il loop di 10 secondi.
L'interrupt su INT0 è sempre attivo, se vuoi attivarlo e disattivarlo solo per lo sleep togli i commenti alle relative righe all'interno della funzione per lo sleep.
Il test l'ho fatto con una Luigino 328, il che complica non poco le cose per la misura della corrente vista la presenza del led power, l'FTDI, il regolatore, tutte cose che consumano mA, pertanto ho scollegato dallo zoccolo il pin 7 (Vcc) dell'ATmega e l'ho collegato all'alimentazione (5V) tramite il mio multimetro da banco settato come misuratore di corrente.
Il mio multimetro ha una risoluzione di 10 nA (5 mA fondo scala) per le correnti DC, quando l'ATmega entra in sleep, modo power down, misuro solo 140 nA, spero non siano troppi per la tua applicazione  smiley-mr-green

Code:
#include <avr/sleep.h>  // libreria standard (avrlib) per lo sleep

/* Sleep test */
// INT0 PD2, INT1 PD3

#define Sveglia 2       // pin corrispondente a INT0
#define LED    13

void sbadiglio()        // risveglio dallo sleep
{
  // inserire eventuali azioni legate all'interrupt
}

void setup()
{
  pinMode(Sveglia, INPUT);
  pinMode(LED, OUTPUT);
  
  digitalWrite(Sveglia, 1);              // pull up attiva sul pin 2
  attachInterrupt(0, sbadiglio, LOW);    // interrupt 0
  set_sleep_mode(SLEEP_MODE_PWR_DOWN);   // setta registri per il modo sleep
  sleep_enable();                        // abilita la sleep all'uso
}

void A_nanna()                      // funzione attivazione sleep
{
    /*
    Modalità sleep per ATmega 328p
  
    SLEEP_MODE_IDLE
    SLEEP_MODE_ADC
    SLEEP_MODE_PWR_DOWN
    SLEEP_MODE_PWR_SAVE
    SLEEP_MODE_STANDBY
    SLEEP_MODE_EXT_STANDBY
    
    */  
 
    //attachInterrupt(0, sbadiglio, LOW); // riattiva l'interrupt
    sleep_mode();                          // mette in stato di sleep
    sleep_disable();      // disattiva la modalità sleep e riporta il micro a piena operatività
    //detachInterrupt(0);  // disattiva l'interrupt
}

void loop()
{
  for(byte i=0;i<10;i++)
   {
    digitalWrite(LED, HIGH);
    delay(500);
    digitalWrite(LED, LOW);
    delay(500);
   }
 
  A_nanna();               // mette il micro in sleep
}
Logged

Palermo
Offline Offline
God Member
*****
Karma: 2
Posts: 745
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Ma è possibile metterlo in pausa e comandare il riavvio tramite un ne555?
Logged

Gianfranco

Rome (Italy)
Offline Offline
Tesla Member
***
Karma: 120
Posts: 9185
"Il Vero Programmatore ha imparato il C sul K&R, qualunque altro testo è inutile e deviante."
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Ma è possibile metterlo in pausa e comandare il riavvio tramite un ne555?

Il riavvio è sempre legato ad un interrupt, o un reset, o un evento watchdog, se l'NE555 è in qualche modo collegato ad uno degli interrupt supportati nelle varie modalità di sleep allora si è possibile.
Esempio pratico, se il 555 genera un impulso collegato a INT0 a INT1, non importa se alto o basso, puoi usare direttamente lo sketch sopra come template.
Logged

Lamezia Terme
Offline Offline
Shannon Member
****
Karma: 415
Posts: 11993
Le domande di chi vuol imparare rappresentano la sua sete di sapere
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Ottimo, grazie, domani farò i test e ti saprò dire anche qual 'è il consumo preciso.
Una sola cosa, poiché lavoro con sensori di antifurto, che sono normalmente chiusi, e un capo è a massa, impostando
Code:
digitalWrite(Sveglia, 1);              // pull up attiva sul pin 2
attachInterrupt(0, sbadiglio, LOW);    // interrupt 0
sarebbe sempre attivo, se ho ben capito; ora la pull-up io l'ho già attivata di mio perché assieme al software mi blocca gli impulsi spurii del contatto, però contestualmente sul pin c'è uno stato LOW (contatto chiuso a massa), per cui il software si aspetta l'high (contatto aperto. Posso invertire oppure devo mettere una pull-down esterna e collegare il sensore al positivo invece che a GND? In tal modo quando lui si apre la pull-down forza a LOW e si attiva, credo.

inoltre ho un altro problema: a volte questo strab sensore resta aperto, in base alla posizione, e potrebbe restarlo per tutto il giorno (il tx per attivarsi vuole una sequenza low-high), quindi poiché gestisco già questa cosa via software, secondo te potrei mettere in sleep il micro anche col sensore aperto?
Logged

Guida alla programmazione ISP e seriale dei micro ATMEL (Caricare bootloader e sketch):
http://www.michelemenniti.it/Arduino_burn_bootloader.php
Guida alla Programmazione ATmega328 noP:
http://www.michelemenniti.it/atmega328nop.html
Articoli su Elettronica In:
http://www.michelemenniti.it/elettronica_in.html

Global Moderator
Milano, Italy
Offline Offline
Edison Member
*****
Karma: 15
Posts: 1163
Arduino rocks
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Imparare e gestire la funzione sleep interesserebbe anche a me smiley-razz per questo mi stavo documentando.

Sono concetti un po' articolati quindi ci metterò un po' a comprenderli e padroneggiarli...passando al dunque:

leggevo che col watchdog non è possibile solo resettare il micro ma anche scatenare un interrupt, cosa che in alcune applicazioni sarebbe più comoda rispetto ad usare un interrupt esterno. Penso alle applicazioni che devono funzionare ad intervalli di tempo, tipo campionami questo sensore ogni tot secondi.

Dato che abbiamo un pezzo da 90 come astrobeed, e non da meno anche uwefed, leo72 e menniti...si potrebbe affrontare l'argomento in modo completo, no?
Logged

F

Lamezia Terme
Offline Offline
Shannon Member
****
Karma: 415
Posts: 11993
Le domande di chi vuol imparare rappresentano la sua sete di sapere
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Federico, ti ringrazio per la fiducia, ma, come si dice dalle mie parti, non confondiamo l'oro col rame! Purtroppo io con i nomi ai quali mi hai affiancato non c'entro nulla, diciamo che con leo stiamo collaborando con buon profitto reciproco, ma astrobeed (e lo dice il nome stesso smiley-wink) e Uwe (che forse non deriva da suo vero nome, ma è l'interpretazione tedesca di UFO  smiley-lol) sono proprio di un altro pianeta! Io sto imparando moltissimo da loro e non ne faccio segreto, onore al merito (che di questi tempi è raro)!
Diciamo che me la cavo con la sperimentazione, perché sfrutto i metodi che mi derivano dal tipo di lavoro che faccio, e me la cavo anche meglio con la produzione di documentazione (idem), ma senza il loro aiuto starei ancora lì, dov'ero 2-3 mesi fa, completamente rincoglionito ( smiley-red) e ipnotizzato dal blink del led, primo esperimento assoluto di ogni neofita di Arduino.
Sono completamente d'accordo con te sul fatto che l'argomento si possa sviluppare; personalmente, compatibilmente col lavoro e la famiglia ( smiley-kitty) mi sono imposto di trascrivere in maniera scientifica ogni tecnica che imparo e riesco a gestire in modo completo; così ho fatto con la programmazione degli ATmega, il frutto sono quasi 70 pagine di Guida (giunta alla 3a versione) che pubblicherò appena (appunto!) completo tutti gli esperimenti.
Logged

Guida alla programmazione ISP e seriale dei micro ATMEL (Caricare bootloader e sketch):
http://www.michelemenniti.it/Arduino_burn_bootloader.php
Guida alla Programmazione ATmega328 noP:
http://www.michelemenniti.it/atmega328nop.html
Articoli su Elettronica In:
http://www.michelemenniti.it/elettronica_in.html

Rome (Italy)
Offline Offline
Tesla Member
***
Karma: 120
Posts: 9185
"Il Vero Programmatore ha imparato il C sul K&R, qualunque altro testo è inutile e deviante."
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

inoltre ho un altro problema: a volte questo strab sensore resta aperto, in base alla posizione, e potrebbe restarlo per tutto il giorno (il tx per attivarsi vuole una sequenza low-high), quindi poiché gestisco già questa cosa via software, secondo te potrei mettere in sleep il micro anche col sensore aperto?

La soluzione è semplice, invece di risvegliare su uno stato logico ben preciso, che può essere sia LOW che HIGH, risvegli quando c'è un cambio di stato, quindi sia HIGH->LOW che LOW->HIGH, per farlo basta che metti la keyword CHANGE nella modalità di attivazione dell'interrupt.
Ti allego solo come viene modificata la funzione che mette in sleep, commenta, o cancella, l'attivazione dell'interrupt che si trova in SETUP in modo da attivare l'interrupt solo prima di entrare in sleep e disattivarlo quando ne esce.

Code:
void A_nanna()                      // funzione attivazione sleep
{
    /*
    Modalità sleep per ATmega 328p
  
    SLEEP_MODE_IDLE
    SLEEP_MODE_ADC
    SLEEP_MODE_PWR_DOWN
    SLEEP_MODE_PWR_SAVE
    SLEEP_MODE_STANDBY
    SLEEP_MODE_EXT_STANDBY
    
    */  
 
    attachInterrupt(0, sbadiglio, CHANGE); // riattiva l'interrupt
    sleep_mode();                          // mette in stato di sleep
    sleep_disable();      // disattiva la modalità sleep e riporta il micro a piena operatività
    detachInterrupt(0);  // disattiva l'interrupt
}

« Last Edit: May 08, 2011, 01:14:45 am by astrobeed » Logged

Lamezia Terme
Offline Offline
Shannon Member
****
Karma: 415
Posts: 11993
Le domande di chi vuol imparare rappresentano la sua sete di sapere
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Grande astrobeed! registrato, a più tardi per i primi esiti. Grazie davvero.
Logged

Guida alla programmazione ISP e seriale dei micro ATMEL (Caricare bootloader e sketch):
http://www.michelemenniti.it/Arduino_burn_bootloader.php
Guida alla Programmazione ATmega328 noP:
http://www.michelemenniti.it/atmega328nop.html
Articoli su Elettronica In:
http://www.michelemenniti.it/elettronica_in.html

cuneo
Offline Offline
God Member
*****
Karma: 3
Posts: 785
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
ma, come si dice dalle mie parti, non confondiamo l'oro col rame!
via ultimamente vanno tutti e due al rialzo...

Quote
Insert Quote

@garinus:
non è che forse i tuoi problemi dipendono dal tempo di uscita dal reset? Se leggi sui datasheet dei micro, essi necessitano di un tempo minimo affinché la procedura di reset sia portata a termine correttamente. Se imposti tempi troppo brevi, potresti avere problemi di autoreset.

ho provato tutti i tempi impostabili ma niente.. pensavo fosse causato dal fatto che avevo un grosso cond dopo il 7805 e il tiny consumando poco impiegava un pò a spegnersi circa mezzo secondo e pensavo che il problema fosse causato dal fatto che la corrente non scendesse di colpo ma calava lentamente ma sono tutte ipotesi perchè non sono riuscito a risolvere il problema in nessuna maniera quindi... boh.
Logged

0
Offline Offline
Sr. Member
****
Karma: 0
Posts: 453
Arduino rocks
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Per chi utilizza il prescaler ho modificato la libreria (http://www.arduino.cc/playground/Code/Prescaler) aggiungendo una parte per l'inizializzazione corretta della seriale (trueSerialbegin):
Code:
/*
 * prescaler.h
 *
 * Provides useful tools to manage the clock prescaler and issues
 * related to time and delays. Allows to easily set the prescaler
 * and get access to its value. Also provides alternative functions
 * to the millis() and delay() functions.
 *
 * (c) 2008 Sofian Audry | info(@)sofianaudry(.)com
 * http://sofianaudry.com
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef PRESCALER_INC
#define PRESCALER_INC

#include "WProgram.h"

/**
 * Prescaler division
*/
#define CLOCK_PRESCALER_1   (0x0)
#define CLOCK_PRESCALER_2   (0x1)
#define CLOCK_PRESCALER_4   (0x2)
#define CLOCK_PRESCALER_8   (0x3)
#define CLOCK_PRESCALER_16  (0x4)
#define CLOCK_PRESCALER_32  (0x5)
#define CLOCK_PRESCALER_64  (0x6)
#define CLOCK_PRESCALER_128 (0x7)
#define CLOCK_PRESCALER_256 (0x8)

HardwareSerial MBSerial = Serial; ///< Pointer to Serial class object

// Initialize global variable.
static uint8_t __clock_prescaler = (CLKPR & (_BV(CLKPS0) | _BV(CLKPS1) | _BV(CLKPS2) | _BV(CLKPS3)));

inline void setClockPrescaler(uint8_t clockPrescaler) {
  if (clockPrescaler <= CLOCK_PRESCALER_256) {
    // Disable interrupts.
    uint8_t oldSREG = SREG;
    cli();

    // Enable change.
    CLKPR = _BV(CLKPCE); // write the CLKPCE bit to one and all the other to zero

    // Change clock division.
    CLKPR = clockPrescaler; // write the CLKPS0..3 bits while writing the CLKPE bit to zero

    // Copy for fast access.
    __clock_prescaler = clockPrescaler;

    // Recopy interrupt register.
    SREG = oldSREG;
  }
}

inline uint8_t getClockPrescaler() {
  return (__clock_prescaler);
}

inline uint16_t getClockDivisionFactor() {
  return ((uint16_t)(1 << __clock_prescaler));
}

/**
 * Time in milliseconds.
 *
 * NOTE: This is the equivalent of the millis() function but it readjusts it according
 * to the current clock division. As such, be careful of how you make use of it, in
 * particular remember it will be wrong if the clock division factor is changed during the
 * course of computation. Remember that you can reset the overflow counter by calling the
 * init() function from wiring.h.
 */
inline unsigned long trueMillis()
{
  return millis() * getClockDivisionFactor();
}

// Waits for #ms# milliseconds.
// NOTE: Please see comment above.
inline void trueDelay(unsigned long ms)
{
  unsigned long start = trueMillis();
  while (trueMillis() - start < ms);
}


inline void trueSerialbegin(unsigned int n_serial, long baudrate)
{
  switch(n_serial)
  {
#if defined(__AVR_ATmega2560__)
    case 1:
      MBSerial = Serial1;
      break;
      
    case 2:
      MBSerial = Serial2;
      break;
      
    case 3:
      MBSerial = Serial3;
      break;
#endif
    
    case 0:
    default:
      MBSerial = Serial;
      break;
  }
  
  MBSerial.begin(baudrate * (int)getClockDivisionFactor());
}

/**
 * Rescales given delay time according to division factor. Should be called before a call
 * to delay(). Insures compatibility with function using delay().
 * Example use:
 * delay( rescaleDelay(1000) ); // equivalent to wait(1000)
 */
inline unsigned long rescaleDuration(unsigned long d)
{
  return (d / getClockDivisionFactor());
}

/**
 * Rescales given time (in milliseconds or microseconds) according to division factor. Should
 * be called
 */
inline unsigned long rescaleTime(unsigned long t) {
  return (t * getClockDivisionFactor());
}

#endif

La seriale viene inizializzata correttamente solo per valori per cui la moltiplicazione:
baudrate * (int)getClockDivisionFactor()
è minore di 230400.

PS: stavo cercando di capire dove le librerie HardwareSerial e wiring prendono  la F_CPU perchè basano su tale dato per calcolare i ritardi e frequene della seriale, voi per caso lo sapete?
« Last Edit: May 08, 2011, 04:52:51 am by ypkdani » Logged

Global Moderator
Italy
Offline Offline
Brattain Member
*****
Karma: 313
Posts: 21645
Logic is my way
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Nel file boards.txt: cerchi la sezione relativa all'hardware che vuoi modificare.
Credo (perché non sono un esperto di C) che tu possa comunque ridefinire quel valore nel tuo codice:
#define F_CPU xx000000UL

In alcune librerie l'ho visto fare.
Logged


Global Moderator
Italy
Offline Offline
Brattain Member
*****
Karma: 313
Posts: 21645
Logic is my way
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

@michele:
Lo hai visto questo 3d?
http://arduino.cc/forum/index.php/topic,59682.0.html
Logged


Pages: 1 ... 3 4 [5] 6 7 ... 9   Go Up
Jump to: