Dubbi su uno schema... Controllare le lancette d'un orologio..

Ciao a tutti, stavo guardando questo progetto: http://www.instructables.com/id/Lunchtime-Clock Dovrebbe permettere di controllare dall' arduino il motore di un orologio. La "schematica" è questa: http://www.instructables.com/image/FBKBX93GIYWWEIL/Build-the-circuit.jpg

E il codice per comandare il motore è questo:

TurnTurnTurn(1000);
int TurnTurnTurn(int TimeToWait){
analogWrite(clockpin, 0);
analogWrite(clockpin1, 124); // sets the value (range from 0 to 255)
delay(TimeToWait);
analogWrite(clockpin, 124);
analogWrite(clockpin1, 0);
delay(TimeToWait);
}

Guardando lo schema mi chiedo, non sono inutili due transistor? Non ho mai usato transistors PNP ma "quello che sapevo" è che si possono comandare solo con voltaggio negativo (-5 volt? )... il LOW dell'arduino è interpretato come negativo? E se così fosse, guardando il codice arduino, il motore non dovrebbe fare un TIC avanti ed un TIC indietro? O forse i motorini da orologio non cambiano verso se si inverte la polarità?

Grazie a tutti... sono un po' confuso!! :cold_sweat: :cold_sweat:

Edit: Non ci vuole una resistenza fra le basi e i pin dell' ardu?

non so per la resistenza, ma credo che il transistor si usi per "potenziare" il segnale in uscita dal pin arduino con qualche mA in più presi direttamente dal 7805

sinceramente son stati fatti vari esperimenti nell'udo di arduino come RTC, e salvo l'uso di un quarzo da RTC, l'errore è troppo grande, nell'ordine di minuti di errore in un giorno

è un ponte H, serve per poter controllare il motore in entrambe le direzioni. Da arduino esci con 2 pin con cui regoli direzione e velocità di rotazione. il codice a vederlo così in effetti mi sembra che faccia uno scatto avanti e uno indietro... La resistenza credo che possa essere omessa.

Il motore del orologio normalmente é un motore passo passo a singola bobbina chiamato LAVET


La bobbina fa girare il rotore magetico di un certo angolo (fino arrivare alla direzione yy’ )e a bobbia spenta la scanalatura insieme al rotore magnetico fa che il rotore si gira un po di piú per arrivare per effetto di rilutanza (resistenza del circuito magnetico minore) (posizione direzione xx’).
La bobbina deve essere ecitata una volta in un senso e sucessivamente nel altro senso. Per questo deve essere pilotato con un ponte H. Teoreticamente visto il basso consumo del motore anche 2 uscite totem pole del ATmega potrebbero pilotarlo.
I mecanismi dei orologi sono fatti in modo che il pilotaggio aviene con 1Hz (giro completo del rotore) o anche 1/2 Hz, dipende dall’ ingranaggio.

Il transistore conduce quando circola una corrente nella base. Questo succede quando nel NPN la tensione della base é 0,7V maggiore della tensione del emettitore e nel caso del PNP di 0,7 V minore della tensione del emettitore.

Mettendo un PNP col emettitore a 5V e pilotando la base con 5V non conduce mentre mettendo la base a masssa conduce.

Non si usano mai i PNP come stadi di potenza perché di regola si hanno tensioni piú alte di 5V. Se si usa per esempio 12V con 0V sulla base conduce il transistore, ma anche con 5V conduce. L’ ATmega non riesce a dare una tensione di 12 V che sarebbe necessaria di far interdire il PNP. Serve un secondo transistore NPN per questo. A questo punto é piú semplice dove possibile usare un NPN e interrompere la massa.

Sí, ci volgliono le resistenze di base sui transistori perché tra emettitore e base ci sono sempre 0,7 V di una giunzione PN (o NP). a quel punto non mettendo le resistenze di base si ha un corto tra i 5V e massa diminuito di 0,7V dello transistore. é possibile rompere l’ uscita ATmega o il transistore.

Ciao Uwe

[EDIT]
Rileggendo il progetto ho sempre piú il dubbio che il progetto é nato male.

Userei 2 pile da 1,5V e alimenterei il ATmega e il RTC a 3V
Come pilotaggio per il motore Lavet basta un impulso di qualche msecondo ogni mezzo secondo. Uno su un pin e uno sul al atro pin di pilotaggio.
schema di alimentazione
usite A B
passo 1 L H motore fa un giro di ca 150 gradi durata qualche msecondo.
passo 2 H H motore fermo, rotore gira per i restanti 30 gradi per fare mezzo giro.
passo 3 H L motore fa un giro di ca 150 gradi durata qualche msecondo.
passo 4 H H motore fermo, rotore gira per i restanti 30 gradi per fare mezzo giro.
va avanti con passo 1
in questo modo si minimizza il consumo.

Non serve una PWM.

Oltre questo metterei il controller in sleep che viene svegliato tramite un counter interrupt nel momento giusto (durata programmabile per variare la velocitá die secondi) attivando l’oscillatore interno e un quarzo di 32kHz esterno per triggherare il counter.

[/EDIT]

Grazie mille Uwe!! Sempre il migliore ;)

I mecanismi dei orologi sono fatti in modo che il pilotaggio aviene con 1Hz (giro completo del rotore)

Quello che ho io no, fa 1/4 di giro, ma non conosco la frequenza di commutazione.

Grazie mille Uwe!! Sempre il migliore smiley-wink

Approvo.

Ciao.

Riguardando il disegno dello schema e la lista dei componenti, si vede che i transistor sono 4, non 2. Cambia qualcosa?

L'avevo intuito cosé, il ponte H devi farlo con 4 transistori. ;) ;) ;)

ho trovato nei commenti:

Jan 18, 2011. 10:35 AM sumatra says: Your Instructable would be a lot stronger if you explained your circuit and code. How did you arrive at the circuit and the values for the AnalogWrites? Do you really need the transistors? The ATMega can source/sink 40ma, and I'd be surprised if the clock coil needed anywhere close to that amount of current.

Jan 18, 2011. 12:04 PM randofo (author) says: The value was arrived at because 255 was too much and 100 was not enough. I meant to stick in 127, but put in 124 for some reason and that seems to work fine. I added an H-bridge because the motor is a single coil stepper and needs to be powered in phase (i.e. you need to reverse the polarity). TurnTurnTurn(x) is a variable for pausing between steps of the motor, whereas x is the delay time. 1000 is equivalent to one second. Every day at 11:00, the clock goes into a routine that slows down 80% for 3,600 rotations and then speeds up to 120% for 3,600 rotations and then resumes normal operation.

Jan 20, 2011. 1:36 PM imarcianoloco says: The H-bridge only amplifies the signal it receives from the control pins it's connected to. Polarity stays the same, so I do believe it would work without the H-bridge, just connect the pins directly to the stepper coil... :)

Jan 20, 2011. 3:37 PM randofo (author) says: This is flip-flopping it: analogWrite(clockpin, 0); analogWrite(clockpin1, 124); delay(TimeToWait); analogWrite(clockpin, 124); analogWrite(clockpin1, 0); delay(TimeToWait);

Queste spiegazioni non sono rassicuranti riguardo la bravura del autore di realizzare l' idea carina che ha avuto.

Leo visto che Tu sei quello che é "tornato ai Tuoi firmware". Dimmi se ho scritto giusto riguardante l'ATmega usato coll' oscillatore interno e il quarzo da 32k esterno e di metterlo in sleep.

Ciao Uwe

Attivando il modulo RTC (Real-time Counter) interno all'Atmega328 con un quarzo da 32 kHz esterni si può impostare l'interrupt per avere 1 overflow al secondo. Se però si imposta il micro in sleep, dobbiamo tener conto che all'uscita da uno sleep il micro impiega alcuni cicli di clock per riprendere piena operatività.

Si potrebbe quindi pensare di impostare l'interrupt non esattamente ogni secondo ma ogni 0,99999qualcosa secondi in modo da lasciare lo scarto per ottenere il micro operativo al 100% ogni 1 secondo esatto.

Difatti quel progetto usa un RTC esterno, più preciso per applicazioni in cui la precisione è fondamentale. Potremmo però impostare l'RTC per fargli generare un segnale di clock esterno e leggere con un interrupt il cambiamento di stato del pin, tenendo il micro in sleep e facendolo svegliare da un interrupt su quel pin. In questo modo la precisione è assicurata: possiamo non considerare il tempo che il micro impiega a risvegliarsi perché il comando arriva dall'esterno, sempre ad intervalli regolari.

In pratica non funziona usare un interrupt ogni secondo dato dal RTC. L' idea del orologio é che tra le 11 e 00 va piú veloce del 20% per poi nella pausa pranzo dalle 12 alle 13 andare piú lento e recuperare. Per questo pensavo triggerare l' uscita dall interrupt con un counter a 16 bit impostando a necessitá il valore. Ciao Uwe

Allora si può usare la mia swRTC, usando un quarzo esterno da 8 o 16 MHz, per avere la max precisione. Si calibra la libreria durante un paio di giorno di funzionamento della stessa per ottenere lo scarto tra il tempo calcolato e quello reale e si tara in questo modo il deltaT, ossia lo scostamento temporale detto sopra.

A questo punto è facile variare l'orologio: basta variare il deltaT da applicare in modo che il contatore interno dei secondi vada più o meno veloce.

Alternativamente si può fare tutto senza swRTC, usando come hai detto tu il quarzino esterno da 32 kHz ma qui bisogna considerare che: 1) l'utente deve essere capace di modificare i fuse di un micro per poter impostare l'oscillatore interno 2) l'utente deve sapere attivare il modulo RTC e configurare la routine di interrupt da sé, calcolando il prescaler ed il valore di partenza del contatore interno per avere l'interrupt al momento giusto

Resta poi da gestire, in entrambi i casi, il problema dello sleep. Non si può usare il contatore a 16 bit perché è sul timer 1, e questo viene spento in sleep. L'unico che va anche in modalità POWER-SAVE è il timer 2, che poi è l'unico usabile perché è su di esso che è agganciato il modulo RTC.

In power safe quanto consuma?

Ho controllato perché non ricordavo... pag. 515 del datasheet. Con clock a 1 MHz siamo sugli 0.06 mA a 5V.

Allora con 2 pile da 1,5V va avanti per qualche mese consideranod il consumo del ATmaga da acceso e il consumo del motore. Ciao Uwe

Non so quanto possa consumare il motore e la circuiteria che lo controlla. Se è un passo-passo non è sempre sotto tensione?

No, il motore viene alimentato 1 volte per breve tempo ogni secondo.

Ciao Uwe

Sto guardando un po' di codice per mandare l'ardu in risparmio energetico... Sto leggendo questo: http://interface.khm.de/index.php/lab/experiments/sleep_watchdog_battery/ E vedo che hanno il quarzo collegato direttamente senza i condensatorini verso massa... può creare disturbi alla precisione dell' swRTC? Altra cosa, se mando l'arduino in standby, il timer interno continua a funzionare o devo aggiungere via software il tempo in cui l'ardu ha dormito?

Per far lavorare correttamente il quarzo, i C sono necessari. Se mandi in POWER_SAVE il timer 2 continua a lavorare. Altre modalità potrebbero bloccare il timer (POWER_DOWN e STAND-BY)

Senza condensatori sullo quarzo é possibile che l' oscillatore non oscilli o oscilla con una frequenza sbagliata(mi é capitato con un quarzo da 32kHz che oscillava con 4Mhz), Comunque stiamo divagando.

Facciamo una versione del orologio salva tempo di pausa pranzo nostra piú funzionale?

Ciao Uwe

Si può fare… anche se in realtà devo chiedere in classe se mi fanno mettere la mani sull’ orologio :stuck_out_tongue:
Abbiamo dei prof con la pessima abitudine di entrare in classe 5 minuti prima dell’ inizio ora ahaha…
Secondo me il motore si può collegare direttamente senza il ponte H… Dubito che la lancetta per muoversi beva più di 40/50 mA…
Stavo provando a guardare come mandare l’arduino a dormire per risparmiare energia, non si può certo cambiare la batteria all’ orologio ogni 2 giorni,… ma ho pessimi risultati!
Non va assolutamente in sleep mode!

//****************************************************************
/*
 * Watchdog Sleep Example 
 * Demonstrate the Watchdog and Sleep Functions
 * Photoresistor on analog0 Piezo Speaker on pin 10
 * 
 
 * KHM 2008 / Lab3/  Martin Nawrath nawrath@khm.de
 * Kunsthochschule fuer Medien Koeln
 * Academy of Media Arts Cologne
 
 */
//****************************************************************

#include <avr/sleep.h>
#include <avr/wdt.h>
#include <swRTC.h>
swRTC rtc;


#ifndef cbi
#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
#endif
#ifndef sbi
#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
#endif

int nint;
volatile boolean f_wdt=1;
void setup(){
  Serial.begin(9600);
rtc.stopRTC();
    rtc.setTime(14,29,35);
    rtc.setDate(13,11,2011);
    rtc.startRTC();
  Serial.println("START");

  // CPU Sleep Modes 
  // SM2 SM1 SM0 Sleep Mode
  // 0    0  0 Idle
  // 0    0  1 ADC Noise Reduction
  // 0    1  0 Power-down
  // 0    1  1 Power-save
  // 1    0  0 Reserved
  // 1    0  1 Reserved
  // 1    1  0 Standby(1)

  cbi( SMCR,SE );      // sleep enable, power save mode
  sbi( SMCR,SM0 );     // power save mode
  sbi( SMCR,SM1 );     // power save mode
  cbi( SMCR,SM2 );     // power save mode
  setup_watchdog(9);
}

byte del;
int cnt;
byte state=0;
int light=0;


//****************************************************************
//****************************************************************
//****************************************************************
void loop(){
//Operazioni prima di dormire..
system_sleep();
// Sveglio:
Serial.print(rtc.getHours(), DEC);
    Serial.print(":");
    Serial.print(rtc.getMinutes(), DEC);
    Serial.print(":");
    Serial.print(rtc.getSeconds(), DEC);
    Serial.print("  ");
    Serial.print(rtc.getDay(), DEC);
    Serial.print("/");
    Serial.print(rtc.getMonth(), DEC);
    Serial.print("/");
    Serial.println(rtc.getYear(), DEC);
    delay(2);
  }

//****************************************************************  
// set system into the sleep state 
// system wakes up when wtchdog is timed out
void system_sleep() {

  cbi(ADCSRA,ADEN);                    // switch Analog to Digitalconverter OFF

  set_sleep_mode(SLEEP_MODE_PWR_SAVE); // sleep mode is set here
  sleep_enable();

  sleep_mode();                        // System sleeps here

    sleep_disable();                     // System continues execution here when watchdog timed out 
  sbi(ADCSRA,ADEN);                    // switch Analog to Digitalconverter ON

}

//****************************************************************
// 0=16ms, 1=32ms,2=64ms,3=128ms,4=250ms,5=500ms
// 6=1 sec,7=2 sec, 8=4 sec, 9= 8sec
void setup_watchdog(int ii) {

  byte bb;
  int ww;
  if (ii > 9 ) ii=9;
  bb=ii & 7;
  if (ii > 7) bb|= (1<<5);
  bb|= (1<<WDCE);
  ww=bb;
  Serial.println(ww);


  MCUSR &= ~(1<<WDRF);
  // start timed sequence
  WDTCSR |= (1<<WDCE) | (1<<WDE);
  // set new watchdog timeout value
  WDTCSR = bb;
  WDTCSR |= _BV(WDIE);


}
//****************************************************************  
// Watchdog Interrupt Service / is executed when  watchdog timed out
ISR(WDT_vect) {
  f_wdt=1;  // set global flag
}