Unit is in low power mode most of the time. Running from 5 volts; drawing less that a few microamps.
Every minute, a 30kHZ square wave burst (about 20 mSec long) is sent to LED1 and another pin listens to a remote control receiver for a reflected IR wave. If received, LED2 flashes for 100mSec every 2 seconds. Power is supplied from an IO pin and is removed from the receiver when not active.
Every minute or few minutes, an A to D reading is taken to check on battery voltage. If below a threshold, another LED flashes for 10 mSec every 4 seconds to alert the user.
Pins:
UPDI
LED1
LED2
Receiver Vdd
Receiver signal
The 412 was chosen for its low price, UPDI programming and features. Quantities in the hundreds.
Below is code I found and modified that gets the basic RTC/PIT system working but I don't yet see how to incorporate the needed functions. What's the general way to call functions in a sleeping system?
Is the project too much for the chip? Would a different chip, or a 2 chip solution make it easier? I have experience with PIC chips but very little with AVR.
If that code does what you want, you could try something like the following.
(Are you sure you need to clear the interrupt flag? With most devices that is automatic.)
ISR(RTC_PIT_vect){
RTC.PITINTFLAGS = 1; //clear PI flag
}
// in main(), loop(), etc.
while(1){
asm( "sleep ");
i=(i+1)%10;
if(i==0) ledON();
if(i==1) ledOFF();
}
That is how wake from sleep is supposed to work. The interrupt starts the CPU running at the instruction immediately following the sleep instruction, as described in the Gammon tutorial linked above.
Yes, I read the link. Good reading. I have used sleep mode with other processors and was aware that the instruction after the sleep command gets executed upon wakeup.
My main source of confusion is the RTC/PIT usage which I am very unfamiliar with. The code in the link is more familiar to me than the code above with macros (like PIN3_bm which I can't seem to find the definition of) and with everything being done by manipulating registers.
Can I still use digitalWrite() and other "Arduino" functions?
The functions I need to call in the loop need to use something like delay(), which doesn't seem to work here.
The sleep instruction should be called in the main program, and wake up should start the processor running the next instruction. That is where you should execute all "normal" function calls and instructions.
For delay() to function normally, interrupts have to be on. It will not work as you expect within an ISR and may even hang up the processor if you try. If delay() doesn't work in the main loop, then the global interrupts may be off.
I haven't looked carefully at the ATtiny412 data sheet, but you should study it very carefully, as there are many differences between that series and the AVR series of MCUs discussed by Nick Gammon.
Interesting. I think another difference is that the wdt only resets the chip, but with the older tinys you could use it in a non-reset mode to prodice a periodic interrupt. Is this correct?
Yes, that is correct, and the wdt periodic interrupt is very handy. The ISR can be completely empty. The 32 kHz oscillator looks like a very nice replacement for the wdt, with the latter's few options for timing.
Exactly. Just trying to learn the basic ropes here.
In terms of dialing out different times for tasks, why doesn't the RTC prescaler work in the below code?
LED continues to toggle once per second regardless of what's loaded in the RTC prescaler bits.
Hmm- Yes the 412 datasheet shows RTC is not prescaled for PIT, but the 202/402 shows it is. I'm actually programming the 202 and that prescaler doesn't work there but the graphic suggests it should. More digging...