How to safely power off from REPL?

The official pyboard running MicroPython.
This is the reference design and main target board for MicroPython.
You can buy one at the store.
Target audience: Users with a pyboard.
Post Reply
mosi
Posts: 24
Joined: Tue Oct 07, 2014 12:07 am

How to safely power off from REPL?

Post by mosi » Wed Oct 08, 2014 11:17 pm

Hi,
I would like to aggressively power off the board with the USER button.

The plan:
- pressing USR button resets the board
- press&hold for 2 seconds powers off the board
When a pin is activated, external IC cuts-off the main power to processor.

The issue:
SDcard is still plugged in and the OS complains about "Eject the USB flash disc first before removing device".
also,
my Mac crashes in the process 1 in 6 times (probably due to USB drivers or SD card?)

Question:
- How to remove SD card from being used as mass storage?
See pyb.usb_mode('CDC+HID') which does not work in this context.
- How to prepare the micropython and the processor for being shut down aggressively from within an IRQ ?
- is there a better timing method for Switch() callback?
- how could I call more complicated functions for LED PWM pulsing from within the Switch() callback IRQ routine?

Thank you!

Code: Select all

import pyb

####### Init Timers ###############
micros = pyb.Timer(2, prescaler=83, period=0x3fffffff)
micros.counter(0)

### power-off pin, when high, the main power is cut to processor
POWER_OFF = Pin.cpu.B1.init(pyb.Pin.OUT_PP, pull=pyb.Pin.PULL_DOWN, af=-1)

sw         = pyb.Switch()

# BTN_callback
def BTN_callback():
  timeout=2000000 #microseconds
  pyb.LED(1).toggle()
  pyb.LED(2).toggle()
  pyb.LED(3).toggle()
  micros.counter(0)
  while (sw() and (micros.counter()<timeout) ):
    pyb.LED(3).toggle()
    pyb.LED(1).toggle()
  if (micros.counter()>=timeout):
    print('Switching OFF:\n')
    pyb.sync()
    pyb.usb_mode('CDC+HID')
    pyb.sync()
    PIN_OFF.high()  ## this is where the power is lost
  else:
    print("Reset here::")
  pyb.LED(1).on()
  pyb.LED(2).off()
  pyb.LED(3).off()

sw.callback(BTN_callback)


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

Re: How to safely power off from REPL?

Post by dhylands » Thu Oct 09, 2014 12:12 am

To prevent the "you must eject the sdcard" you need to not enable mass storage in the first place (there is no way for the pyboard to initiate the eject - your mac has to do that).

You can prevent mass storage from being used by putting the pyb.usb_mode('CDC+HID') in your boot.py file. Any later than that and mass storage is already started and thus its too late.

You also don't need to tie up a timer anymore for your microsecond timer. You can use pyb.micros() and pyb.elapsed_micros() I don't see elapsed_micros on the doc page, but if you have recent firmware it exists.

Code: Select all

start_time = pyb.micros()
while pyb.elapsed_micros(start_time) < some_value:
    do_something()
I'm not sure that all of your function will work from interrupt context. Like pyb.sync(). It will depend on the relative priority of the USB interupts versus the switch interrupt.

It looks like the Yellow LED can be connected to channel 1 of timer 2.

Also note that the switch callback is a raw callback. You should probably put some debounce logic in there. You can get multiple edges when you press and release the button.

Post Reply