I’ve emailed the winners of the Pi book giveaway. In no particular order, your emails are:







Check your email for instructions. Thanks for playing, everyone, and I’ll be doing this again soon, perhaps with my new book from MAKE. Stay tuned!

I’m holding a giveaway of my latest book from Apress, Learn Raspberry Pi Programming With Python. I’m giving away 5 copies, and one winner will also receive a Raspberry Pi Model B+ to go with it. To enter, just do the following:

Follow me on Twitter: @wolfram_donat

Tweet me an update, letting me know you’ve entered, using the hashtag #RaspberryPiPythonBook

Finally, send an email to RaspberryPiPythonBook@wolframdonat.com. I’ll email the winners when the giveaway ends Nov. 1.

Finally finished the zombie crawler. Based on this guy’s design, I used two windshield wiper motors, two ESCs, a transmitter/receiver combination, and two RC batteries. Those Li-Poly batteries are something else – 3.7A for an hour of use, packed into a tiny package. Awesome stuff. Anywhere, here’s Bartok, the first segment of my upcoming demo reel:

And if you’re wondering, yes – I sell these.

This is something I come across from time to time, and it seems that the procedure is a bit different than it is for Linux, so I thought I’d save the process that I found works (if only so I can find it again later myself.)

Edit ~/.bash_profile (this way you only screw with your own PATH, and no other users’. Say you need to add “/Applications/Graphics/Pixie/bin” to your path, as I did (seriously, getting Pixie to work on OS X is proving to be a massive headache). Let’s also say you need to edit your DYLD_LIBRARY_PATH (Mac’s equivalent of Linux’s LD_LIBRARY_PATH) as you may need to for Pixie. Add the following lines to the end of the file:

export PATH="/Applications/Graphics/Pixie/bin:$PATH"
export DYLD_LIBRARY_PATH="/Applications/Graphics/Pixie/lib:$DYLD_LIBRARY_PATH"

Save it, and enter

source ~/.bash_profile in your terminal to make the change effective immediately. This should do the trick in 10.8 Lion. Pixie’s install instructions mention some nonsense about “DYLIB_LIBRARY_PATH” for the Mac – ignore it. Seriously.

There is a deplorable lack of info on the web about how to do this without an Arduino; that is, via hardware only instead of software. Thus, after much blood, sweat and tears, I hope to save others the same trials. Read on:

Power the Wifly. Make sure it’s powered with 3.3V, not 5. When connecting for the first time for setting up an ad-hoc network, jump pin 8 to pin 1 when powering up. The red, green and yellow LEDs will blink quickly.

Open your wireless manager and look for an ad-hoc network named something similar to “Wifly-GSX-9f.” Try to connect to it. You may have to edit the wireless connection IPv4 settings to reflect a “Link-local,” rather than a “DHCP” connection. Try to connect again.

Once your computer has connected to the network, open a terminal and type the following:

telnet 2000 is the default IP address of the Wifly unit, and 2000 is the default connection port. It should connect almost immediately, greeting you with

Connected to
Escape character is '^]'.

Enter $$$ and press ‘Enter.’ The unit will respond



set ip address

The unit will echo the command and respond with


Now type, one after another:

set ip netmask
set ip dhcp 0
set wlan ssid my_chosen_ssid_name

Now disconnect all power from the Wifly, reconnect it, and try to telnet to the same address ( 2000) again. You should be able to connect without any problems. If you disconnect from the network, remember that you have now renamed it, and you need to look for your chosen ssid, not “Wifly-GSX-XXX.”

At some point in image processing, you may want to see image edges on a live basis – for OCR, perhaps, or just because it looks kinda cool… Here’s an nifty little bit of C code (now somewhat deprecated) that will convert a live stream from a webcam to a black-and-white, edge-illuminated image.

#include <cv.h>
#include <highgui.h>
#include <stdio.h>

int main(){

int c, i, j;

//capture frame from camera
CvCapture* capture = cvCaptureFromCAM(CV_CAP_ANY);
fprintf(stderr, "Error: capture is NULL \n");
return -1;
//set resolution of capture
cvSetCaptureProperty(capture, CV_CAP_PROP_FRAME_WIDTH, 256);
cvSetCaptureProperty(capture, CV_CAP_PROP_FRAME_HEIGHT, 192);

//create window for display


//find/mark edges using canny
IplImage* frame = cvQueryFrame(capture);
IplImage* grey = cvCreateImage(cvGetSize(frame), 8, 1);
cvCvtColor(frame, grey, CV_RGB2GRAY);
IplImage* frame2 = cvCreateImage(cvSize(grey->width+6, grey->height+6), grey->depth, grey->nChannels);

CvPoint offset = cvPoint(3,3);
cvCopyMakeBorder(grey, frame2, offset, IPL_BORDER_REPLICATE, cvScalarAll(0));
IplImage* edges = cvCreateImage(cvGetSize(frame2), IPL_DEPTH_8U, frame2->nChannels);
cvCanny(frame2, edges, 4900, 39200, 7);

cvShowImage("canny", edges);

//wait for a keypress
int c = cvWaitKey(10);
if (c!=-1) break;

} //end while

cvReleaseCapture (&capture);
return 0;

} //end main

It’s a small window size (256×192) in this case because I was running it on the Raspberry Pi, and the Pi can’t handle a large window size – gets bogged down in the processing. Just reset those values to whatever your processor can handle.

After spending hours and hours getting Ubuntu to install on a Windows 8-optimized laptop (more on that later) I was having incredible problems getting the wireless to work. Honestly, I haven’t had problems with Linux and wireless since Ubuntu 8, but my 12.04 install just refused to recognize the Ralink RT5390R wireless card installed in my HP laptop. It’s an HP2000 laptop with a Ralink RT539B card.

Finally, after some serious searching, particularly in the Ubuntu forums, I got it working, with the help of some posts by users chili555 and ironv. If anyone else is having problems, here’s what solved it for me.

1. Download the driver from Ralink’s website. Assuming you also have the 539B card, download the RT539x PCIe package from http://www.ralinktech.com/en/04_support/support.php?sn=501

2. Unpack:

tar xvjf -filename

3. Here’s where things change. Edit ./os/linux/config.mk file to reflect the following:


4. Now search for NIC5392_PCIe_DEVICE_ID in all directories.

grep -r -n NIC5392_PCIe_DEVICE_ID .
./include/chip/chip_id.h:60:#define NIC5392_PCIe_DEVICE_ID 0x5392
./include/chip/rt5390.h:67:#define NIC5392_PCIe_DEVICE_ID 0x5392
./os/linux/pci_main_dev.c:75: {PCI_DEVICE(NIC_PCI_VENDOR_ID, NIC5392_PCIe_DEVICE_ID)}
./os/linux/rt_rbus_pci_drv.c:1380: (device_id == NIC5392_PCIe_DEVICE_ID)
./os/linux/rt_rbus_pci_drv.c:1669: case NIC5392_PCIe_DEVICE_ID:

Now, everywhere that turns up (see the above example) you must add an additional line, directly after it and formatted exactly the same, with NIC539B in place of NIC5392. So if you do another

grep -r -n NIC539B_PCIe_DEVICE_ID .

you’ll get:

./include/chip/chip_id.h:61:#define NIC539B_PCIe_DEVICE_ID 0x539B
./include/chip/rt5390.h:68:#define NIC539B_PCIe_DEVICE_ID 0x539B
./os/linux/pci_main_dev.c:76: {PCI_DEVICE(NIC_PCI_VENDOR_ID, NIC539B_PCIe_DEVICE_ID)}
./os/linux/rt_rbus_pci_drv.c:1381: (device_id == NIC539B_PCIe_DEVICE_ID)
./os/linux/rt_rbus_pci_drv.c:1670: case NIC539B_PCIe_DEVICE_ID:

5. Once that’s done,

sudo make
sudo make install
sudo modprobe -r rt5390sta
sudo modprobe rt5390sta

Then reboot. Your wireless should now be working.

REMEMBER: this fix only works if you have the 539B device!! If you’re not sure, run

lspci -nn | grep 0280

That line should finish with “Device [1814:539b]”.

Good luck!

It’s a nifty little trick that can come in handy. In my case, I use it to notify me if my webserver suddenly becomes unavailable for some reason. It uses the fact that most cell phones can be texted via email by using a certain adress, such as cell#@provider.net. The code I use:

def send_text(str):

HOST = "smtp.gmail.com"

SUBJECT = "Server offline!"
TO = "xxxxxxxxxx@txt.att.net"

FROM = "python@mydomain.com"

text = str
BODY = string.join(("From: %s" % FROM, "To: %s" % TO, "Subject: %s" % SUBJECT, "", text), "\r\n")

s = smtplib.SMTP('smtp.gmail.com',587)




s.login("username@gmail.com", "mypassword")

s.sendmail(FROM, [TO], BODY)