RTC not waking from IDLE

Questions and discussion about The WiPy 1.0 board and CC3200 boards.
Target audience: Users with a WiPy 1.0 or CC3200 board.
Post Reply
jdoege
Posts: 6
Joined: Thu Mar 03, 2016 5:56 pm

RTC not waking from IDLE

Post by jdoege » Sun Aug 28, 2016 4:23 pm

Hello,

I am attempting to create a motor control loop for a small stepper motor to drive a clock. It must turn at 1rpm and I am setting it up to "tick" once per second. Using the real time clock, I set up a repeating alarm every second and an interrupt handler that simply sets a global flag, once per second. The main control loop looks for that flag and if it is true, calculates how many steps the motor must take to move 6degrees (1 second) and calls a step routine that does that.

My problem is that I'd like to idle the controller between steps so as to keep the outputs energized, but the irq doesn't seem to wake from idle as expected. It only works when I sleep the controller, but that de-energizes the outputs which will cause missed steps if I am half-stepping. I can't see what I am doing wrong and would appreciate any insights. I am using MicroPython 1.8.3. Here is my code:

[code]
import machine
from machine import RTC
from machine import Pin
import time
import untplib

rtc = RTC()
rtc_wake = False

mota = Pin('GP14', mode=Pin.OUT)
motb = Pin('GP15', mode=Pin.OUT)
motc = Pin('GP16', mode=Pin.OUT)
motd = Pin('GP17', mode=Pin.OUT)
state = 0

def step( n ):
global state
for i in range (0,n) :
time.sleep_ms(20)
if ( state == 0 ) :
mota.value(1)
motb.value(0)
motc.value(0)
motd.value(0)
state = 1
elif ( state == 1 ) :
mota.value(0)
motb.value(1)
motc.value(0)
motd.value(0)
state = 2
elif ( state == 2 ) :
mota.value(0)
motb.value(0)
motc.value(1)
motd.value(0)
state = 3
else:
mota.value(0)
motb.value(0)
motc.value(0)
motd.value(1)
state = 0

def wakeup(rtc_o) :
global rtc_wake
rtc_wake = True

def tt() : #get correct current time for future timekeep feature
global rtc
ntpc = untplib.NTPClient()
ntpresp = ntpc.request('north-america.pool.ntp.org', version=3, port=123)
CSToffset = 5*60*60
rtc.init(time.localtime(time.time() - CSToffset + ntpresp.offset ))

def go() :
global rtc
global rtc_wake
steps = 63488 #integer number of steps (for 28BYJ-48 512step/rev motor from Adafruit)
secs = 7425 #for integer number of seconds (for 28BYJ-48 512step/rev motor from Adafruit)
oldsteps = 0
newsteps = 0
currsecs = 0
deltasteps = 0

tt()
rtc.alarm(time=1000, repeat=True) # wake up once per second
rtci = rtc.irq( trigger=RTC.ALARM0, handler=wakeup, wake=( machine.SLEEP | machine.IDLE ) ) # wake from any state
while True: # event loop
machine.sleep() # this works but shuts off the outputs
#machine.idle() # this doesn't work (but should as far as I can see)
if rtc_wake:
rtc_wake = False
currsecs = currsecs + 1
newsteps = ( currsecs * steps ) // secs
deltasteps = newsteps-oldsteps
oldsteps = newsteps
if oldsteps == steps:
oldsteps = 0
currsecs = 0
step( deltasteps )

go()
[/code]

Also, I haven't seen reference to how many alarms can be active at any given time, does anyone here know?

Again, any insight or recommendations would be appreciated.

Best regards,
Jason Doege

User avatar
dhylands
Posts: 3821
Joined: Mon Jan 06, 2014 6:08 pm
Location: Peachland, BC, Canada
Contact:

Re: RTC not waking from IDLE

Post by dhylands » Sun Aug 28, 2016 5:59 pm

I haven't played with the RTC stuff much.

machine.idle will return the NEXT time ANY interrupt happens on the system. So it probably is working fine. The system tick timer interrupts every millisecond. So normally you use micahine.idle() in a loop waiting for the event you're interested in.

Since you're driving a motor, I suspect the current consumed by the motor will totally dwarf the current consumed by the CPU.

Lowering the clock rate on the CPU will also yield lower power consumption.

jdoege
Posts: 6
Joined: Thu Mar 03, 2016 5:56 pm

Re: RTC not waking from IDLE

Post by jdoege » Sun Aug 28, 2016 7:20 pm

Thanks. I'm not so worried about power consumption. It doesn't work if I have neither machine.sleep() nor machine.idle() calls, too. It only appears to work properly if I have the machine.sleep() call in the event loop, that's the only reason I have that there, but, because that de-energizes the IOs, that is ultimately unsuitable for my application.

jdoege
Posts: 6
Joined: Thu Mar 03, 2016 5:56 pm

Re: RTC not waking from IDLE

Post by jdoege » Wed Aug 31, 2016 8:05 pm

Lacking response on the forum, does anyone have guidance for how to obtain some help?

-Jason

User avatar
pythoncoder
Posts: 5956
Joined: Fri Jul 18, 2014 8:01 am
Location: UK
Contact:

Re: RTC not waking from IDLE

Post by pythoncoder » Thu Sep 01, 2016 9:24 am

It might help if you explained why you want to idle between steps if you're not concerned about power consumption. What are you actually trying to achieve?
Peter Hinch
Index to my micropython libraries.

jgmdavies
Posts: 57
Joined: Tue Aug 09, 2016 2:39 pm

Re: RTC not waking from IDLE

Post by jgmdavies » Thu Sep 01, 2016 10:54 am

Hi Jason,

I just tried the following in my WiPy running 1.8.3:
timer3.py

Code: Select all

import machine

count = 0


def wakeup():
	global count
	count += 1
	return

def go():
	global count
	count = 0
	rtc = machine.RTC()

	# wake up once per second
	rtc.alarm(time=1000, repeat=True)

	# wake from any state
	rtci = rtc.irq( trigger=machine.RTC.ALARM0, handler=wakeup, wake=( machine.SLEEP | machine.IDLE ) )

	return
I was hoping to monitor by checking 'timer3.count' from the REPL, but the REPL hangs immediately I run the go() function, as per the discussion in http://forum.micropython.org/viewtopic.php?f=11&t=2127 (the FTP server also dies, and the normal heartbeat LED flashes stop...).

So I'm wondering: are you sure your 'wakeup' is being called, do you still get the heartbeat LED flashes, and do you still have the REPL?

Jim

Post Reply