Sunday, May 4, 2014

Finally my pyboard arrived!

So, some months ago, some great guy from the UK decided to solve all my problems by implementing the python programming language for micro-controllers, sparing me the terrors of learning C or getting mad over Arduino. The kickstarter he run included a micor-controller board, called pyboard, which finally arrived yesterevening.

So, ...

Let's build a datalogger!

The board has a SD-card slot, 4 LEDs, one user programmable switch, a reset switch and a built-in acceleromter with a range of +-1.5g.

Usually, if you plug the the board to your USB port, the SD-card is mounted. On that SD-card, you copy your python-scripts and upon reset, the board runs them. Now, if you are trying to write data to the SD-card with the micro-controller, that becomes a problem, because essentially the computer and the controller both use the file system at the same time and break it.
To avoid that, the boot.py file, which is the first script the microcontroller runs, get's a little sophistication:

1:  import pyb  
2:    
3:  pyb.LED(3).on()  
4:  pyb.delay(2000)  
5:  pyb.LED(4).on()  
6:  pyb.LED(3).off()  
7:  switch = pyb.Switch()          # check if switch was pressed decision phase  
8:    
9:  if switch():  
10:    pyb.usb_mode('CDC+MSC')  
11:    pyb.main('cardreader.py')      # if switch was pressed, run this  
12:  else:  
13:    pyb.usb_mode('CDC+HID')  
14:    pyb.main('datalogger.py')      # if switch wasn't pressed, run this  
15:    
16:  pyb.LED(4).off()  

Now, after reset, the board boots with USB mode set to 'CDC+HID'. That means, the board isn't recognized as a mass storage device by your computer, but as an Human Interface Device - a mouse. Import for us - not being a storage device, the computer doesn't mount the SD-card and the microcontroller is the only one using it'S filesystem. Hurray!
Also, the cardreader.py script is run. This script does all the work:

1:  import pyb  
2:    
3:  # creating objects  
4:  accel = pyb.Accel()  
5:  blue = pyb.LED(4)  
6:  switch = pyb.Switch()  
7:    
8:  # loop  
9:  while True:  
10:    
11:    # start if switch is pressed  
12:    if switch():  
13:      pyb.delay(200)           # delay avoids detection of multiple presses  
14:      blue.on()              # blue LED indicates file open  
15:      log = open('1:/log.csv', 'w')    # open file on SD (SD: '1:/', flash: '0/)  
16:    
17:      # until switch is pressed again  
18:      while not switch():  
19:        t = pyb.millis()              # get time  
20:        x, y, z = accel.filtered_xyz()       # get acceleration data  
21:        log.write('{},{},{},{}\n'.format(t,x,y,z)) # write data to file  
22:    
23:      # end after switch is pressed again  
24:      log.close()             # close file  
25:      blue.off()             # blue LED indicates file closed  
26:      pyb.delay(200)           # delay avoids detection of multiple presses  

The script starts to log the data when the switch is pressed, and stops when it's pressed again. You can restart and stop it as often as you wan't, but the file will be overwritten.
Now we have log.csv file on the SD-card, containing all our data. How do we get it on the computer? And how do we change the scripts on the SD-card in case they are buggy? The boring version would be to remove the SD-card an put it into the computers SD-card reader. The other version would be to use the pyboard as SD-card reader. This is not only more convenient, but also kinda cool.
So, boot.py takes care of that. pressing reset flashes the orange LED, then pressing and holding the switch until the orange LED goes out, enables the 'CDC+MSC' mode. That means, our pyboard is recognized as a mass storage device again and the SD-card is mounted.

Whats's next?

You know me. It goes into the water rocket. The parachute deployment works now. Well, 9 out of 10.
I also had a group of students (13-14 years old) working on an 'Ignition Stage' (basically an Ardunio logging accelerations and pressure, as well as triggering the parachute based on that data) for the rockets. It's not completely finished yet, but it will be sometime and it will be cool.

[Special thanks to lurch, who wrote the boot.py. See the development process here.]
[source on git, hopefully to be merged]
[Original project on git]