Friday, April 17, 2015

The computer network in space - Part 1!

First in flight

First in flight is the (unofficial - official is "Esse quam videri") North Carolina motto.

Our launch is not a first in flight from a HAB (high altitude balloon) perspective (see also: "Rocket man and the Near Space Circus"), but the mechanical aspects (see also the article on our self-leveling rigging: "learn from the past - 103 years old technology in space"), hardware and network topology and innovations packed in the software will definitely be first in flight.

Team Near Space Circus HAB "NSC01" ready to launch


  • Sending micro controllers into near space to take measurements? Done.
  • Sending a raspberry pi with a camera module into near space? Done.
  • Sending multiple gopros into near space? Done.
  • Taking pictures from near space? Done.
Anything left to do that hasn't been done?

Genesis of NSC01

One would think there is nothing left to do that has not been done before. Really, launching weather balloons for gathering data and taking high altitude pictures has been done many thousands of times before, even well before the age of the digital camera.

In fact, in NASA technical memorandum TM X-2208 published in 1971, it covers flights done in the later part of 1969 by the Langley Research Center in Virginia. This served as inspiration as to part of the payload for our own launch, an homage if you will. In this flight, they used medium format film cameras, both in the visible spectrum and the infrared.

So we started with that concept, we will have a Raspberry Pi with an infrared (PiNoir type) camera, and another with a regular CSI camera. Plus a very analog tech which I'll cover in Part 3.

And we quickly realized that we just opened Pandora's box... Innovation was possible everywhere we looked.

Eye in the sky

In my collection of Raspberry Pi related stuff, I had a few cameras already, including one infrared with an S-mount and lens. For a first flight, we could have simply gone with that and a regular raspberry pi camera (with its neutral lens which is not bad at all quality wise; neutral lenses are relatively easy to make compared to wide or tele lens). But we really wanted a wider shot, particularly as the 1080p video is cropped and gives even less coverage.

I didn't want to destroy the other modules to add the S-mount (commonly used on CCTV cameras), so I opted instead for a magnetic mount with a conversion lens. That way the camera can be used without conversion lens, or with a telephoto, wide or even a fish eye conversion lens.

Fish eye, wide, S-mount and magnetic mount RPI cameras

Of course, most people discard conversion lens as junk. And optically, they are terrible, with lots of barrel distortion and other issues. In fact, barrel distortion is easy to see on videos on youtube taken with wide (it is the built in lens actually) lens "extreme sports" type of video cameras that are so popular. The closer to the edge, the more it distorts.

But this was not going to be a show stopper for us. With the right software, I was convinced we could get some really decent shots. So I mounted a camera with a wide angle lens on top of the raspberry pi case, powered the pi with my phone spare battery pack (with a micro USB lead) and took pictures to calibrate my software (written in Python) and then went downtown Winston Salem to take pictures of buildings with lots of horizontal and vertical lines. Distortion is easily seen there.

And the results were quite nice:

Raspberry Pi camera with low cost wide angle, software corrected

What is left is the normal angling of lines due to perspective, but barely any lens distortion. Nice. Now let's move on to the computer.

Like groceries

So, a HAB with a few computers is like doing groceries for a family with a few kids. The more kids, the more expensive it gets. A single Raspberry Pi model A+ is only $20 plus shipping. And we knew from day 1 that we would use two of them. At a minimum.

Then we started looking at options to mount 4 cameras on the payload. For 360 panoramic pictures... Well, with the wide angle lens we used we'd need 5. But 6 is a nice round number, and due to crop factor of the 1080P mode, just making 360 degrees. How to connect 6 CSI cameras to 2 Raspberry Pi?

Plan A was building or buying a multiplexer. But time ran out for building, and we couldn't buy a real multiplexer. We did have a CSI switcher (made for 4 cameras per board) that I had ordered from Turkey. I had it in hand, but it never did work. I tried to get a replacement but the vendor never contacted me back. Caveat emptor.

Plan B was 1 Raspberry Pi per camera. And we had 6 regular cameras for the 360 panoramic, and 1 infrared CSI camera facing downward. So 7 Raspberry Pi it is...

Imagine your grocery bill with 7 kids...

Micro SD in their numbered SD adapters to avoid confusion

And so it went for our project. 7 Pi, 7 cameras, 7 micro sd memory cards (a mix of 32GB and 64GB cards), enough battery power for all of that. Oh yeah, power...

12V != 5V

We figured that for all the gear we would have onboard (7 Raspberry Pi, 7 CSI cameras, 1 USB camera, 2 GPS, sensors, 1 APRS transmitter doing 10W bursts every 2 minutes), we would use 3S (3 cells is series) Lithium Polymer batteries, commonly used in RC and drone applications.

Two 3S 4000 mAh LiPos with XT60 connectors; cameras

We went with two, in order to make it easier to distribute the weight and redundancy. But that meant connecting them together in parallel. This was perfect for the APRS transmitter (transmitting our location, voltage and temperature every two minutes) as it expected a 12V source.

The two LiPo batteries connect on this side

But the Raspberry Pi expect 5V, not 12V. So we added two UBECs. These are switching voltage regulators. They are not really designed to run in parallel, but we ran them for 12 hours straight many times with no issues. Look on RC forums, people say you cant do it. Well, you can. They do lose some of their efficiency that way, because they use PWM to regulate their output and measure their output as part of that. When 2 are in parallel, the output of one interferes some with the feedback loop of the other. Still, we were ok to lose some efficiency for redundancy.

5V UBECs (switching, not linear)
And we needed an octopus loom with 7 microusb to distribute the 5V to the 7 Raspberry Pi. It's about as light weight as we could make it... We did try to connect directly to GND and 5V on the GPIO header, but when it came time to network the 7 Pi together, it caused some issues. I'll talk about that in Part 2.

Power distribution to 7 Raspberry Pi

Where is the network?

I did say we had a computer network we were sending into space, didn't I?

Raspberry Pi #1, 2 and 7

And I'll leave you today in conclusion of part 1 with a shot of the 7 Raspberry Pi networked inside the payload.

All 7 Raspberry Pi before the power wiring harness is put in place

Part 2 will go into the details of the network itself, the master/slave component and the deadman's switch and part 3 will talk about the data gathering aspects. And in the interim, try to guess how we are networking the 7 Raspberry Pi.

And you can track our first launch progress (and real time data on the day of the launch) by keeping an eye on #NSC01 on twitter, following @pyptug or myself.

Francois Dion

Thursday, April 9, 2015

Raspberry Pi A+ going into (near) space

High Altitude Balloon

A group of people from the Piedmont Triad of North Carolina will be launching a HAB as part of the Global Space Balloon Challenge. If you want to track it on twitter, check out hashtag #NSC01. As the launch date approaches, traffic and details will go up, so check it out. You can also follow @pyptug (the telemetry will be posted there) or myself @f_dion (some technical details and photos).

Raspberry Pi A+

The model A+, thanks to its low weight and low power consumption is a perfect candidate for a flight computer. But why limit oneself to a single unit? Stay tuned as we post pictures and details...


Not only do we run Python for all the tasks of the flight computers, but we are also running visual (on a map) simulations of the balloon path. This is done through integration with google maps and flask. We will post more details soon.

Tuesday, February 24, 2015

J is for ... autojump!

Shell addon

At our last PYPTUG meeting, I was demoing Dshell. While at it I suggested using the j command. AKA, autojump:

On some linux distros, it is possible to install from the repo. On debian and derived systems (ie, ubuntu, mint etc), instructions to enable it after the install are in /usr/share/doc/autojump/README.Debian

Once installed and trained, you'll ask yourself how you've been able to live without it.

The j command itself is defined within a shell file. For example, for bash, you'll find this piece of code:

# default autojump command
j() {
if [[ ${1} == -* ]] && [[ ${1} != "--" ]]; then
autojump ${@}
output="$(autojump ${@})"
if [[ -d "${output}" ]]; then
echo -e "\\033[31m${output}\\033[0m"
cd "${output}"
echo "autojump: directory '${@}' not found"
echo "\n${output}\n"
echo "Try \`autojump --help\` for more information."

Although this part is all bash scripting, the actual autojump command is written in something else altogether.

Python powered

Autojump has been around for many years, to this day, few people actually are aware of it. In fact, as I typed j, a quick survey around the room confirmed my gut feel.
Python powered
I have blogged and tweeted about it before, but mostly in passing. Hopefully this post will bring a bit more exposure to this really useful tool.

And, do have a look at the python code ( ). It has some interesting use of the lesser known SequenceMatcher class of the difflib module, and good use of lambdas. Oh, and yeah, it's pep8 formatted. Thank you.


Monday, February 23, 2015

DShell and cybersecurity - tonight

Check it out tonight:

I'll talk some about dshell, crypto and more (see Adam's main talk)

Tonight, Feb. 23rd 2015 at Wake Forest U in Winston Salem.


Saturday, February 14, 2015

Raspberry Pi 2 and RPi.GPIO...

Raspberry Pi 2

So, you just bought a new Raspberry Pi 2 Model B. The one with 4 cores and 1GB of RAM. You want to run some python code that uses RPi.GPIO. You have the January 2015 Raspbian. You should be good to go, right?


Let's revisit RPi.GPIO, the python module for interfacing with hardware on the Pi. Yes, it does come pre-installed. Latest Raspbian (January 2015) includes RPi.GPIO 0.5.9. But then, you try to run your script and it tells you

pi@raspberrypi ~ $ sudo python
RuntimeError: This module can only be run on a Raspberry Pi!

Hmm, ok, whatever, this is a Raspberry Pi! So we will have to upgrade the RPi.GPIO python module. While at it, let's install the python dev, setuptools and pip:

pi@raspberrypi ~ $ sudo apt-get install python-dev python-setuptools
Reading package lists... Done
Building dependency tree
Reading state information... Done
The following extra packages will be installed:
  libexpat1-dev libssl-dev libssl-doc python-pkg-resources python2.7-dev
Suggested packages:
  python-distribute python-distribute-doc
The following NEW packages will be installed:
  libexpat1-dev libssl-dev libssl-doc python-dev python-pkg-resources
  python-setuptools python2.7-dev
0 upgraded, 7 newly installed, 0 to remove and 23 not upgraded.
Need to get 32.1 MB of archives.
After this operation, 43.5 MB of additional disk space will be used.
Do you want to continue [Y/n]? y
Get:1 wheezy/main libexpat1-dev armhf 2.1.0-1+deb7u1 [210 kB]
Get:2 wheezy/main python-dev all 2.7.3-4+deb7u1 [920 B]
Get:3 wheezy/main libssl-dev armhf 1.0.1e-2+rvt+deb7u14 [1,505 kB]
Get:4 wheezy/main libssl-doc all 1.0.1e-2+rvt+deb7u14 [1,206 kB]
Get:5 wheezy/main python2.7-dev armhf 2.7.3-6+deb7u2 [28.7 MB]
Get:6 wheezy/main python-pkg-resources all 0.6.24-1 [63.6 kB]
Get:7 wheezy/main python-setuptools all 0.6.24-1 [449 kB]
Fetched 32.1 MB in 2min 3s (260 kB/s)
Selecting previously unselected package libexpat1-dev.
(Reading database ... 88962 files and directories currently installed.)
Unpacking libexpat1-dev (from .../libexpat1-dev_2.1.0-1+deb7u1_armhf.deb) ...
Selecting previously unselected package libssl-dev.
Unpacking libssl-dev (from .../libssl-dev_1.0.1e-2+rvt+deb7u14_armhf.deb) ...
Selecting previously unselected package libssl-doc.
Unpacking libssl-doc (from .../libssl-doc_1.0.1e-2+rvt+deb7u14_all.deb) ...
Selecting previously unselected package python2.7-dev.
Unpacking python2.7-dev (from .../python2.7-dev_2.7.3-6+deb7u2_armhf.deb) ...
Selecting previously unselected package python-dev.
Unpacking python-dev (from .../python-dev_2.7.3-4+deb7u1_all.deb) ...
Selecting previously unselected package python-pkg-resources.
Unpacking python-pkg-resources (from .../python-pkg-resources_0.6.24-1_all.deb) ...
Selecting previously unselected package python-setuptools.
Unpacking python-setuptools (from .../python-setuptools_0.6.24-1_all.deb) ...
Processing triggers for man-db ...
Setting up libexpat1-dev (2.1.0-1+deb7u1) ...
Setting up libssl-dev (1.0.1e-2+rvt+deb7u14) ...
Setting up libssl-doc (1.0.1e-2+rvt+deb7u14) ...
Setting up python2.7-dev (2.7.3-6+deb7u2) ...
Setting up python-dev (2.7.3-4+deb7u1) ...
Setting up python-pkg-resources (0.6.24-1) ...
Setting up python-setuptools (0.6.24-1) ...

pi@raspberrypi ~ $ sudo easy_install pip
Searching for pip
Best match: pip 6.0.8
Processing pip-6.0.8.tar.gz
Running pip-6.0.8/ -q bdist_egg --dist-dir /tmp/easy_install-pPyrAv/pip-6.0.8/egg-dist-tmp-UwhkN5
warning: no previously-included files found matching '.coveragerc'
warning: no previously-included files found matching '.mailmap'
warning: no previously-included files found matching '.travis.yml'
warning: no previously-included files found matching 'pip/_vendor/Makefile'
warning: no previously-included files found matching 'tox.ini'
warning: no previously-included files found matching 'dev-requirements.txt'
no previously-included directories found matching '.travis'
no previously-included directories found matching 'docs/_build'
no previously-included directories found matching 'contrib'
no previously-included directories found matching 'tasks'
no previously-included directories found matching 'tests'
Adding pip 6.0.8 to easy-install.pth file
Installing pip script to /usr/local/bin
Installing pip2.7 script to /usr/local/bin
Installing pip2 script to /usr/local/bin

Installed /usr/local/lib/python2.7/dist-packages/pip-6.0.8-py2.7.egg
Processing dependencies for pip
Finished processing dependencies for pip

pip install RPi.GPIO

Now, if we try to install RPi.GPIO, it'll complain that it is already installed. So we will have to use the --upgrade option:

pi@raspberrypi ~ $ sudo pip install RPi.GPIO
Requirement already satisfied (use --upgrade to upgrade): RPi.GPIO in /usr/lib/python2.7/dist-packages

Let's try --upgrade

pi@raspberrypi ~ $ sudo pip install --upgrade RPi.GPIO
Collecting RPi.GPIO from
  Downloading RPi.GPIO-0.5.10.tar.gz
Installing collected packages: RPi.GPIO
  Found existing installation: RPi.GPIO 0.5.9
    DEPRECATION: Uninstalling a distutils installed project (RPi.GPIO) has been deprecated and will be removed in a future version. This is due to the fact that uninstalling a distutils project will only partially uninstall the project.
    Uninstalling RPi.GPIO-0.5.9:
      Successfully uninstalled RPi.GPIO-0.5.9
  Running install for RPi.GPIO
    building 'RPi.GPIO' extension
    gcc -pthread -fno-strict-aliasing -DNDEBUG -g -fwrapv -O2 -Wall -Wstrict-prototypes -fPIC -I/usr/include/python2.7 -c source/py_gpio.c -o build/temp.linux-armv7l-2.7/source/py_gpio.o
    gcc -pthread -fno-strict-aliasing -DNDEBUG -g -fwrapv -O2 -Wall -Wstrict-prototypes -fPIC -I/usr/include/python2.7 -c source/c_gpio.c -o build/temp.linux-armv7l-2.7/source/c_gpio.o
    gcc -pthread -fno-strict-aliasing -DNDEBUG -g -fwrapv -O2 -Wall -Wstrict-prototypes -fPIC -I/usr/include/python2.7 -c source/cpuinfo.c -o build/temp.linux-armv7l-2.7/source/cpuinfo.o
    gcc -pthread -fno-strict-aliasing -DNDEBUG -g -fwrapv -O2 -Wall -Wstrict-prototypes -fPIC -I/usr/include/python2.7 -c source/event_gpio.c -o build/temp.linux-armv7l-2.7/source/event_gpio.o
    gcc -pthread -fno-strict-aliasing -DNDEBUG -g -fwrapv -O2 -Wall -Wstrict-prototypes -fPIC -I/usr/include/python2.7 -c source/soft_pwm.c -o build/temp.linux-armv7l-2.7/source/soft_pwm.o
    gcc -pthread -fno-strict-aliasing -DNDEBUG -g -fwrapv -O2 -Wall -Wstrict-prototypes -fPIC -I/usr/include/python2.7 -c source/py_pwm.c -o build/temp.linux-armv7l-2.7/source/py_pwm.o
    gcc -pthread -fno-strict-aliasing -DNDEBUG -g -fwrapv -O2 -Wall -Wstrict-prototypes -fPIC -I/usr/include/python2.7 -c source/common.c -o build/temp.linux-armv7l-2.7/source/common.o
    gcc -pthread -fno-strict-aliasing -DNDEBUG -g -fwrapv -O2 -Wall -Wstrict-prototypes -fPIC -I/usr/include/python2.7 -c source/constants.c -o build/temp.linux-armv7l-2.7/source/constants.o
    gcc -pthread -shared -Wl,-O1 -Wl,-Bsymbolic-functions -Wl,-z,relro build/temp.linux-armv7l-2.7/source/py_gpio.o build/temp.linux-armv7l-2.7/source/c_gpio.o build/temp.linux-armv7l-2.7/source/cpuinfo.o build/temp.linux-armv7l-2.7/source/event_gpio.o build/temp.linux-armv7l-2.7/source/soft_pwm.o build/temp.linux-armv7l-2.7/source/py_pwm.o build/temp.linux-armv7l-2.7/source/common.o build/temp.linux-armv7l-2.7/source/constants.o -o build/lib.linux-armv7l-2.7/RPi/
Successfully installed RPi.GPIO-0.5.10
pi@raspberrypi ~ $ 

OK, we are now ready to get to work. 0.5.10 works with the Raspberry Pi 2 model B.


Friday, February 13, 2015

Remember the SmartiPi kickstarter?


Or perhaps not. So here's a video reminder

Post kickstarter is taking pre orders, if you missed the original kickstarter campaign. I was a backer of the campaign, and I'm expecting mine real soon now.

If you are getting this to use with the Raspberry Pi camera module, check out this pdf:


SciPyCon Latin America - [Misiones - Argentina] [Mayo 2015]

Tercera Conferencia Anual Científica de Python 
Del 20 al 22 de Mayo en Misiones, Argentina.
Se encuentra abierto el llamado a propuesta de charlas y registraciones al evento.
Para más información consultar en: 
Se agradece difusión. 

Sin duda, de interes para muchos de mi lectores.