Low power nap needed

johndk

Senior Member
I tried searching the forum for 'nap' and came up empty. I suppose it's not much used.

'Nap' is not implemented on an x2 and so I'm looking for an alternative which will take me to ultra-low power for a period of one second, wake up to take some readings, and then back to sleep. This will be repeated indefinitely on my remote trying to conserve as much battery as possible. Ideally, it would also include 'disablebod' for additional savings.

I can use 'sleep', but that can't get me down to the second increments I would like to use.

Anyone have suggestions for the best way to implement that?

I was hoping to use an interrupt wakeup supplied by my radio being activated by the master module which has an RTC. But the radio sits on the hser pins (c.6 and c.7) which don't do interrupts ... darn. Adding an RTC to the remote would seem to negate power savings I could achieve by a short, deep, sleep. I've found a very low power one (PCF85263A) which might do if I can't come up with an alternate solution. But that also means I'd have to alter my PCB.

Suggestions welcome.
 

johndk

Senior Member
Since there are no ideas forthcoming, I think I will revise my circuit to include the low power RTC and set up an interrupt based on a 1Hz square wave heartbeat.
 

hippy

Ex-Staff (retired)
You could perhaps use a smaller PICAXE which supports nap to control power to the X2. Some sort of hardware switching will reduce power consumption to a minimum.
 

PhilHornby

Senior Member
I was hoping to use an interrupt wakeup supplied by my radio being activated by the master module which has an RTC. But the radio sits on the hser pins (c.6 and c.7) which don't do interrupts ... darn. Adding an RTC to the remote would seem to negate power savings I could achieve by a short, deep, sleep.
Could you just make an extra connection from your radio (i.e. C.6/C.7) , to Picaxe pin that does do a hardware interrupt?

Failing that, maybe the following circuit, in concert with a 'Sleep 0' might implement a scheduled wake-up from deep-sleep, once per second:-

RTC.png The connection to the Picaxe being one of the hardware interrupt capable pins. Before the next 'sleep 0', set the pin to be an Output and drive it low for 5mS to discharge the capacitor for next time. The component values would obviously require tweaking and the time interval wouldn't be particularly stable, but it might do the job.
 

johndk

Senior Member
Thanks for that idea Phil. I'd prefer to have a more consistent timing than the RC circuit is likely to provide as the battery voltage decreases. But I like the idea of using a radio connection to another pin as an interrupt. Can I assume correctly that tying the radio txd pin (which currently goes to my hserin pin (c.7) to an additional pin that provides hint (b.0) will give the correct result? Will the hint pin connection not interfere with the serial transmission to hserin? That would be a lovely and simple solution if this can be done.

Hippy, yes, a simpler chip could also solve the problem. But I've come to rely on that nice large scratchpad in the 28x2.

The clock chip I mentioned only consumes about 28uA, which is pretty darn good. But it means an extra component and a crystal. My PCB space is pretty tight at the moment. So I'm hoping we can leach an interrupt from the serial transmission.
 

johndk

Senior Member
I was just looking over the interrupt section and realized that interrupts can be generated off of flag conditions. My radio is already set to background receive and therefore sets the hserflag. Can that flag generate an interrupt to wake the chip out of a 'sleep 0' condition?
 

hippy

Ex-Staff (retired)
My radio is already set to background receive and therefore sets the hserflag. Can that flag generate an interrupt to wake the chip out of a 'sleep 0' condition?
Unfortunately not. Linking your serial to one of the HINTx pins should however work and shouldn't interfere with serial reception.
 

johndk

Senior Member
Thanks Hippy. I'll try the hint pin first. It's still a good solution without extra components.
 

johndk

Senior Member
Okay. I got the interrupt working just fine. BUT ... there's always a but .... It seems that with the int active, I no longer get the background receive function. Without the interrupt activated (PCB connection to INT0 still in place), I get good data transfer. When I activate interrupt, I no longer do. The hintflag is not set and the hintptr is not incremented and no data is placed in scratchpad. I thought it might be that I had the processor in sleep mode waiting for an interrupt. So I tried running without the sleep state and still was not able to get data to scratchpad.

I have the 'hserin [100],sp_rcv_buf,20' command in main, before I wait for the interrupt. It didn't make sense to put it in the 'interrupt' sub, but I'm willing to try that next.

My interrupt is set up as follows:
hintsetup %00000001 ;interrupt for B.0
setintflags %00000001,%00000001 ;interrupt when hint0flag = 1

With interrupt activated, I only seem to be able to generate 1 interrupt, even though I send one per sec. The others are ignored. I do set hint0flag = 0 at the end of the 'interrupt' sub, but maybe I'm missing something.

Any ideas?
 
Last edited:

lbenson

Senior Member
I'm not sure I know what I'm talking about here, or if it's relevant, but does your background serial receive idle high or low? Do you need to interrupt on 0 rather than 1?
 

hippy

Ex-Staff (retired)
There's a lot of code there, and it's rather difficult to tell what is going on. You seem to be using a blocking HSERIN with timeout, while using interrupt with true background receive enabled, and adding sleeping within an interrupt. I really wouldn't like to guess what actually happens under those circumstances.
 

PhilHornby

Senior Member
Redeclare interrupt

With interrupt activated, I only seem to be able to generate 1 interrupt, even though I send one per sec. The others are ignored. I do set hint0flag = 0 at the end of the 'interrupt' sub, but maybe I'm missing something.
The Picaxe is unusual in that you have to re-enable the interrupt for it to be called again - ie re-issue the Hintsetup/setintflags. Usually this is the last thing to do before returning from the ISR, but in your case this is probably not the right place.

... does your background serial receive idle high or low? Do you need to interrupt on 0 rather than 1?
It's not entirely clear (to me) at what point in the serial data stream you will enter that interrupt service routine for the 1st time, but you almost certainly don't want it to be called for every bit, of every byte of your incoming message :eek: I assume you'd re-declare the interrupt, just before the next "sleep 0". (Unless you are going to swap from using HSERIN to background processing, in which case you might want a different flavour of Hintsetup/setintflags to be active, until the "sleep 0".)

I don't know how quickly the Picaxe wakes from its "sleep 0", but I can imagine the 1st bit (and therefore the 1st byte) received "going missing" and not being caught by the background Hardware serial processing. You might need to send a dummy message to wake the Picaxe and then send the real data after it's had chance to fully wake up?
 

johndk

Senior Member
Phil. Thanks for reminding me that I have to re-issue the hinsetup. I'm not doing that and will try that at the next go-round. Something else that occurred to me is that I'm resetting the hserptr to 0 rather than to the beginning of the buffer. I'm thinking that might be causing some problems as well.

As to waking from sleep with the interrupt, I DO count the correct number of bytes coming in. I haven't yet confirmed that they are the "right" bytes. But the interrupt appears to be fast enough to catch them all.

Hippy. I was a bit confused by the timeout and count for hserin. That's why they're in there ... more to see the effects. All I want it to do is buffer the bytes in background receive and set the flag (and with the interrupt, I don't even need the flag).
 

PhilHornby

Senior Member
As to waking from sleep with the interrupt, I DO count the correct number of bytes coming in. I haven't yet confirmed that they are the "right" bytes. But the interrupt appears to be fast enough to catch them all.
But at the moment, the interrupt only gets triggered once.

What I was trying to say, is that unless you're going to do all the message processing in the ISR (and then go back to sleep), you wouldn't want to simply re-enable it with those same parameters - because it will then get triggered many more times than you want (potentially by every bit transition of the serial data signal).

You could have some code at the beginning of the Interrupt Service Routine to ascertain why it's being called and then take different action for different events. (Remembering that currently you only have a single event - i.e. the change of state of the serial line from low to high)
 

johndk

Senior Member
I see what you're saying. I was hoping to achieve that by using the hserptr. My packets will always be a known size (20 bytes, in this example). I was therefore going to wait until I had 20 bytes after the interrupt, process, reset the hserptr and hserflag, and then re-enable the interrupt.

What I don't have a handle on, is how to deal with collisions. I will control communication as much as possible by having the master originate most communications and talk to only one remote at a time. But there is a relatively small chance that master or remote will receive overlapping packets. I'm going to assume that the data in such a case will become corrupt and probably have the wrong number of bytes. Seems like I'll have to do some error checking and send a NAK (or something similar) if I get a corrupt packet.
 

PhilHornby

Senior Member
I see what you're saying. I was hoping to achieve that by using the hserptr. My packets will always be a known size (20 bytes, in this example). I was therefore going to wait until I had 20 bytes after the interrupt, process, reset the hserptr and hserflag, and then re-enable the interrupt.
That sounds as good a scheme as any (with the possible caveat about that first bit/byte getting lost during the wake-up process). My experience with interrupts on the Picaxe has been that, you either do all the work in the ISR, or the absolute bare minimum (such as setting a flag). The speed of the Picaxe is such, that any attempt to do anything substantial usually results in the next interrupt condition being missed. (Though having "pauses" and "counting loops" in an Interrupt Service Routine does feel decidedly odd :eek:)

What I don't have a handle on, is how to deal with collisions. I will control communication as much as possible by having the master originate most communications and talk to only one remote at a time. But there is a relatively small chance that master or remote will receive overlapping packets. I'm going to assume that the data in such a case will become corrupt and probably have the wrong number of bytes. Seems like I'll have to do some error checking and send a NAK (or something similar) if I get a corrupt packet.
You haven't detailed the overall architecture of your project, so can't really comment. It can't be any worse than the mess I got myself into, with 6 battery-powered remote nodes randomly waking from sleep and trying to connect to a central node using Bluetooth. A little forethought would have saved a lot of later aggravation :eek: For reasons that seemed sensible at the time, each remote node was set to be a Bluetooth Master with the central node being the one and only Slave. What I discovered, was that if two Masters try to connect to the same Slave simultaneously , neither will ever succeed :( .
 

johndk

Senior Member
I've learned from my almost finished project that there is only one master. Otherwise, spells trouble. Though it wasn't a wireless application, I'm sure the same applies.

What I'm looking for right now is a snippet that does CRC. I thought that would be a nice quick way to check packet integrity and be able to send out a NACK if necessary. I haven't coded one before and it doesn't look too complex. But if there's a snip out there, I'd appreciate a look before I dive in. A quick search yielded zip. If anyone knows of one, please pass it on.
 
Top