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]

Saturday, February 1, 2014

Arduino Library Installer

I got tired of downloading, unzipping and moving Arduino libraries to install them, so I wrote a little script that does that for me!
It's a python script that downloads the zip files, unzips them and moves them to the libraries-folder. The URLs to the .zip-files are listed in an .csv-file called 'repo'.
Right now it only works on Linux and you have to change the username in the source code, to you get the correct paths. There already are some libraries in the repo-file, but it's a short list compared to the long list of libraries available. So, if you have a github-account, feel free to commit URLs!
The code also needs more work, so you people don't have to change the source to their usernames, make it run on other platforms and make the repo-file available online, so you always get the latest list of libraries.

I would be happy about any feedback. I hope this can be useful to some people.

https://github.com/turbinenreiter/ard-lib-inst

Tuesday, December 10, 2013

Live plotting of data from serial port using python, pyserial and pyqtgraph

In preparation of a radio-downlink of the rocket to a ground station, using nrf24l01+ modules, I tried to liveplot data from the acceleration sensor on the PC via USB-serial.
Apparently, this was much more trouble than I thougth, but with a lot of help and stealing I finally got it.

This is the Arduino code!
This is the python code!

And here is what it does!

Moving stuff!

Is this good?

Well, I'm quite happy with this working, almost gave up. Speed is okay-ish, but there is some kind of bottleneck on the serial port. The example code which this is based in runs on 300fps with data generated by pythons random module, adding the reading from serial data drops the fps to a mere 10. On the Arduino-side, I use a delay of 100ms, meaning 10Hz, and when I try to go faster, the live plot becomes a lag plot, with a delay between input and display of a couple of seconds. This is sad because with 10Hz you really can't see any vibrations or shocks.
I will have to investigate in the serial connection and what it actually does to make that faster.

On the rocket side I terribly crashed my (n)th attempt on building a reliable parachute ejection system and the parcel service lost my order of new stuffs to build the (n+1)th prototype. The next one will work. Me hopes.

Wednesday, November 13, 2013

Now we have an acceleration data logger ...

Long time no see!

After months I managed to do some more work on this project. I put an Arduino Nano on somewhat resembling an unholy alliance between a breadboard and a soldered prototype board and don't question my craftsmanship!
It's terribly soldered on the backside.
There is an added Micro-SD Breakoutboard on which the data is stored. The arduinosketch can be found on the githubpage under the name datalogger. It also does free fall detection now. Why?


Because I'm going to use this on a water rocket to trigger the parachute ejection. However, before I do that, I need a reliable parachute ejection system to ensure that the parachute will open. Because without parachute, the datalogger won't survive.

On the INS side of the project I looked into ways of filtering the data to get some accuracy, but then I stopped doing that because I'm doing this for fun.

I hope to be back with some actual data from the rocket flight soon.

Saturday, June 15, 2013

Arduino based Inertial Navigation System - first steps


Intro

So, this weekend I've started working on a simple, Arduino-based Inertial Navigation System.
Using accelerometers and gyroscopes it is possible to calculate the traveled distance and the direction, from a known startpoint. The main problem of this method is that to get these distances, you have to perform integrations of the accelerations. Integration means that also every little error in measurement will be integrated, so they add up over time and the accuracy gets worse and worse. Therefore you need very good sensors and smart algorithms, being the reason why professional systems are expensive.

A constant error ...
integrated over time twice ...
leads to an increasing error.
For this cheap and easy project I use cheap sensors and easy algorithms, so the whole system will be very inaccurate. Nevertheless, I think it will be useful for me to learn, and for others running into similar  problems that I will have to solve. Also, the functions can be expanded, adding logging, additional sensors and a GPS-module, making it a combined navigation system.
These are my first steps and far from a finished project. Right now I'm basically just reading the sensor data.

Parts


Parts on breadboard.
My desk is actually white.
  1. Arduino Uno [info@arduino]
  2. MPU6050 Breakout Board [info@sainsmart]
  3. LEDs, resistors, switches, etc.
There are different MPU6050 Breakout Boards and I guess you could use all of them the same way. It combines a 3-axis accelerometer and a 3-axis gyroscope, so it provides all neccessary data for 3D-navigation.

First breadboard test

Breadboard drawn with fritzing.
I used this how-to to learn how to hook up the MPU6050.
      • MPU6050 / Arduino Uno
      • VCC / 3V3
      • GND / GND
      • SCL / A5
      • SDA / A4

Arduino sketch

To read the sensor data, I used i2cdevlib from jrowberg and the SainSmart tutorial, where you can find the MPU6050 library.
The first sketch just reads the sensor data and stores the acceleration in x-direction it in the EEPROM. The EEPROM can store 1024 bytes. That means it can store 1024 numbers between 0 and 255. The sensor data come as integers, ranging from −32,768 to 32,767, so the value has to be divided and shifted. After the button is pressed, data is logged for 10 seconds with 100Hz.
The second sketch reads the data from the EEPROM and prints it to the serial monitor. From there I copied the data into a .txt-file, which I processed and visualized using a simple Python-script.
At first, the sensor was upside down, resulting in -1g, then turned around, 1g, and then yanked around a little.

Next steps

  • find a algorithm to integrate the sensor values
  • add a micro-SD card reader for data logging
  • add a magnetic sensor to find north
  • add a barometric sensor to get the heigth
I will host the whole project on github and post what's going on here.