Hallo Leute,
Ich bau grad ne lorawan Platine mit ATMEGA4809, RFM95 und 2 wasserfesten
ds18b20 um Bodentemperaturen zu messen. Ich nutze die mcci lmic library
und deswegen Arduino.
Dabei gehe ich gerade die gesamte Software durch um die Wachzeit des uC
zu minimieren.
Also, beim ds18b20 muss man ihm 600ms zum auslesen geben und dabei
wollte ich den uC schlafen legen. Während den 20 minütigen Schlafphasen
nutze ich den PIT (Periodic interrupt timer) um die Node aus dem
Tiefschlaf zu wecken. Ich dachte ich kann einfach den PIT prescaler auf
PIT_DIV1024 setzen was mit dem 1k RTC grob eine Sekunde ist, passt und
tschüss...
Falsch gedacht, offensichtlich hängt der erste Interrupt davon ab in
welcher Zählphase der RTC grad ist und erst beim zweiten Interrupt ist
der Intervall korrekt.
Mit den TCA und TCB kann ich keinen Interrupt auslösen der den uC aus
dem deep sleep weckt(und hab auch kaum mal was damit gemacht)
Hat da jemand eine Ahnung wie ich die 600ms schlaf hinkriege?
Hier ein kleines blinky Beispielprogramm bei dem ich den Nano Every zum
rumprobieren nutze
> Also, beim ds18b20 muss man ihm 600ms zum auslesen geben
Wo hast du diese Information her?
Für 11 bit reichen auch 375 ms. Evtl weniger.
Kannst du nicht einfach bei 32kHz auf idle schalten, und Vollgas, wenn
gebraucht? Die 1.5 mA für den Sensor und das HF machen den uc ja zum
Kleinverbraucher.
Andreas N. schrieb:> Mit den TCA und TCB kann ich keinen Interrupt auslösen der den uC aus> dem deep sleep weckt
Der TCA und der TCB sind nicht zum Schlafen gedacht. Aber der RTC
verbraucht im SMODE_STDBY weniger als 2µA, und hat auch die OVF und CMP
Interrupts.
Nanu, Andreas N., "nach Diktat verreist"?
So ganz verstehe ich die Frage nicht: der PIT läuft durch, für die lange
Pause wählt man einen Ausgang mit großem Teiler, für die
Temperaturmessphase einen mit passend kleinem.
Sorry für die lange inaktivität,hatte viel zu tun, jemand sollte mal den
48 Stunden Tag erfinden
neuer PIC Freund schrieb im Beitrag #7129532:
>> Also, beim ds18b20 muss man ihm 600ms zum auslesen geben>> Wo hast du diese Information her?> Für 11 bit reichen auch 375 ms. Evtl weniger.>> Kannst du nicht einfach bei 32kHz auf idle schalten, und Vollgas, wenn> gebraucht? Die 1.5 mA für den Sensor und das HF machen den uc ja zum> Kleinverbraucher.
Ach Sorry, du hast recht. Es waren 750ms bei 12 bit!!! 11 bit langen
aber, also 375ms....
Wie meinst du das, die Main clock auf 32k schalten und ein
_delay_ms(375); und dann wieder die mainclock auf vollgas?
S. Landolt schrieb:> Nanu, Andreas N., "nach Diktat verreist"?>> So ganz verstehe ich die Frage nicht: der PIT läuft durch, für die lange> Pause wählt man einen Ausgang mit großem Teiler, für die> Temperaturmessphase einen mit passend kleinem.
So dachte ich mir das ja auch.
Im Datenblatt Example 22-1. PIT Timing Diagram for PERIOD(im Anhang)
scheint es dass der RTC erst nach einer Periode den interrupt richtig
erkennt, eben das ist mir nicht ganz klar.
Oben in meinem Beispielprogramm blinkt die led eben nicht nach den
eingestellten Perioden und irgenwie bin ich ratlos.
Hallo,
kannst du das "hakt irgendwie..." näher beschreiben?
Ich habe mir ein Bsp. genommen und etwas umgebaut. Die RTC triggert mit
seinem Overflow den ADC mittels Event jede Sekunde, der macht eine
Messung und in der Hauptschleife wird nur auf die Fertigmeldung des ADC
gewartet. Das RTC Overflow funktioniert demzufolge. Im ADC Interrupt
könnte man die RTC jedesmal stoppen und neu konfigurieren o.ä.
Hier ein Muster (Programmausschnitt, in Assembler), wie ich mir den
Ablauf vorstelle: lange Pause durch LED an C0 dargestellt, blinkt 4 s
an, 4 s aus; Messphase durch LED an A7 dargestellt, leuchtet zu Beginn
jeder Pause für 1 s.
Andreas N. schrieb:> Während den 20 minütigen Schlafphasen> nutze ich den PIT (Periodic interrupt timer)
Beim PIT beträgt die längste Periode nur 32s. Der RTC kann wesentlich
längere Perioden generieren.
Hier ist ein Beispielcode (getestet am ATtiny402)
Periodendauer: ca. 10 min
LED-Leuchtdauer: ca. 0.5s
1
#include<avr/io.h>
2
#include<avr/interrupt.h>
3
#include<avr/sleep.h>
4
5
ISR(RTC_CNT_vect)
6
{
7
if(RTC.INTFLAGS&RTC_OVF_bm)
8
{
9
PORTA.OUTSET=PIN3_bm;// LED on
10
RTC.INTFLAGS=RTC_OVF_bm;// clear RTC OVF interrupt flag
11
}
12
elseif(RTC.INTFLAGS&RTC_CMP_bm)
13
{
14
PORTA.OUTCLR=PIN3_bm;// LED off
15
RTC.INTFLAGS=RTC_CMP_bm;// clear RTC CMP interrupt flag
16
}
17
}
18
19
intmain(void)
20
{
21
PORTA.DIRSET=PIN3_bm;// PA3 output (LED)
22
23
RTC.CLKSEL=RTC_CLKSEL_INT1K_gc;// 1024 Hz from OSCULP32K
24
while(RTC.STATUS>0){}// wait for all register to be synchronized
25
RTC.INTCTRL=RTC_OVF_bm|RTC_CMP_bm;// enable RTC OVF and CMP interrupts
26
RTC.PER=0x4aff;// RTC period (10 min)
27
RTC.CMP=0x000f;// RTC compare value (500 ms)
28
RTC.CTRLA=RTC_RUNSTDBY_bm|RTC_PRESCALER_DIV32_gc|RTC_RTCEN_bm;// enable Run In Standby, RTC clock/32 (32Hz), enable RTC
Hallo Georg Danke dir!!
Ich spiel grad mit deinem Programm und hab versucht den unterschied
zwischen RTC_OVF und RTC_CMP zu verstehen... im prinzip dasselbe nur
dass OVF den RTC zurücksetzt und CMP nicht.
Das würde heissen:
-OVF
-ds18b20 start reading
-sleep
-CMP
-ds18b20 read sensor und send
-sleep
Morgen versuch ich mal ob das geht
Das ding läuft!! und ich habs gleich mit PIT kombiniert und einen
ds18b20 eingebaut. Da ist noch einiges nicht schön aufgeräumt aber es
tut grad was es soll
Danke Danke an euch alle
1
#include<avr/io.h>
2
#include<avr/interrupt.h>
3
#include<avr/sleep.h>
4
#include<OneWire.h>
5
6
ISR(RTC_CNT_vect)
7
{
8
if(RTC.INTFLAGS&RTC_OVF_bm)
9
{
10
//PORTB.OUTSET = PIN5_bm; // LED on
11
PORTB.OUTTGL=PIN5_bm;
12
RTC.INTFLAGS=RTC_OVF_bm;// clear RTC OVF interrupt flag
13
14
}
15
16
elseif(RTC.INTFLAGS&RTC_CMP_bm)
17
18
{
19
20
//PORTB.OUTCLR = PIN5_bm; // LED off
21
PORTB.OUTTGL=PIN5_bm;
22
23
RTC.INTFLAGS=RTC_CMP_bm;// clear RTC CMP interrupt flag
24
25
}
26
27
}
28
29
ISR(RTC_PIT_vect)
30
{
31
/* Clear flag by writing '1': */
32
RTC.PITINTFLAGS=RTC_PI_bm;
33
}
34
35
voidsetup()
36
{
37
Serial.begin(250000);
38
39
40
PORTB.DIRSET=PIN5_bm;// PA3 output (LED)
41
PORTB.OUTSET=PIN5_bm;
42
43
RTC.CLKSEL=RTC_CLKSEL_INT1K_gc;// 1024 Hz from OSCULP32K
44
45
while(RTC.STATUS>0){}// wait for all register to be synchronized