Category Archives: Software

NixCore X1 with RGB LED Strip

My friends here in Colorado started a new company called NixCore, a Linux enabled processor board that takes 1 Watt of power. They asked me to take their new NixCore X1 product for a spin and see what I could make with it. I looked around the lab/office and came upon my RGB LED strip from China. Since this RGB strip uses a variant of SPI I thought it would be a good test for the little NixCore X1 board.

The NixCore X1 is an Ralink RT5350 SoC (System on Chip) processor running at 360MHz, with 8MB of flash, and 32MB of RAM. The board takes only 1 watt of power (less than 200mA at 5V) and has all the outputs you would expect from a microcontroller, I2C, GPIO, PWM. It also has software based SPI (Since the SPI port is used by the flash) which is still pretty fast. I’ve worked with embedded Linux systems and know how much of a pain it is to get a driver running, so having a Linux install with an SPI driver exposed to userspace was a godsent. With some commands, a simple C file, and a Buildroot compiler I was able to port my Mbed code to the NixCore X1 pretty easily. All I had to do is make a new SPI device on some GPIO pins, open the “/dev/spidev1.0” device and start writing data to it, the driver takes care of all the hard stuff. Using C you can fopen(“/dev/spidev1.0″,”w”) and then write as any other file. Here are the steps:

Build the compiler:
NixCore helped me out with that, but just select mips32r2, Little Endian and uClib on Buildroot and you should be good.

Compile the code:
Given the code, you can control the strip via the command line
(Make sure you add -I and -L entries to the buildroot install)

Install the spi-gpio-custom-driver on the running X1:
insmod spi-gpio-custom bus0=1,22,23,24,0,50000

Run the code:
./[WHATEVER_YOU_NAMED_IT]

This driver is software based and (from my tests) runs up to 400KHz. It uses GPIOs 22 as CLK,23 as MOSI and 24 MOSI (Even though there is no input data) on the NixCore X1. This translates to pins 27,30 and 22 on the header. I hooked up the RGB strip directly to the 3.3V CLK and MOSI and wrote a simple C file based on my Mbed code.

Honestly, to my surprise I was able to control a single pixel of the strip right off the bat, I expected the driver functioned but I was still a little skeptical. It didn’t take long to address the entire strip. At a comm rate of 50KHz this updates the strip at about 40ms or 25 HZ. As I mentioned the rate could be updated to about 400KHz which would be about 200Hz for a 5M strip, more than enough to beat the human eye.

After I made the C application to set the color I took it a step further and added a web page and CGI script to change the color of the strip based on a web page.

Here are some videos of the strip in action:

And, of course, the code and webpage for the processing: Code1, Code2, Makefile, Webpage files.
Goto http://[IP_ADDRESS]/color.html

Overall I really like the NixCore X1 (I am biased since they are my buddies) but you might want to check them out at http://nixcores.com.

Arduino execution time analysis

Recently I was asked to take a look at some code for the Arduino Yun that was developed as a proof of concept for a medical device. The company developing the device was “running out of room” and couldn’t get the Arduino to sample all the ADC inputs in the time period they wanted. I suspect they mean they are running out of processing time to sample/control multiple outputs within their processing window. I have always worked a level down from the Arduino wiring framework and honestly have not worked with the Arduino family much, but when a contract job comes up, you take it. The first thing I noticed in the code was heavy use of floating point values as parameters and returns for lots of functions. Anyone who is embedded knows that floating point operations take WAY more time than integer math, but I was curious as to how much longer. I didn’t find any good online resources that say “floating point divides take XXX instructions”, so I decided to get that information myself.

While I don’t have a Yun, I do have an Arduino Uno which uses the ATMega328, an 8-bit micro with most instructions running at 1 instruction per clock using a 16MHz crystal. I decided to look at each basic math operation for unsigned integer types and floating point types. All input and output variables were created as volatile so the compiler wouldn’t optimize, each operation was performed 1000 times and the results are the average. The method of recording the times was the micros() function which has an accuracy of 4us and does include an unsigned long shift, adding a uint8_t and a multiply by a uint16 literal value. Here are the results on the Uno:

Starting test, looping 1000 times
Control 10ms loop: time 10009 us
Float div: 34 us ~544 instructions, 29/ms
Float mul: 12 us ~192 instructions, 83/ms
Float add: 11 us ~176 instructions, 90/ms
Float sub: 11 us ~176 instructions, 90/ms
uint8 div: 8 us ~128 instructions, 125/ms
uint8 mul: 3 us ~48 instructions, 333/ms
uint8 add: 3 us ~48 instructions, 333/ms
uint8 sub: 3 us ~48 instructions, 333/ms
uint16 div: 16 us ~256 instructions, 62/ms
uint16 mul: 4 us ~64 instructions, 250/ms
uint16 add: 3 us ~48 instructions, 333/ms
uint16 sub: 3 us ~48 instructions, 333/ms
uint32 div: 41 us, ~656 instructions, 24/ms
uint32 mul: 9 us, ~144 instructions, 111/ms
uint32 add: 4 us, ~64 instructions, 250/ms
uint32 sub: 4 us, ~64 instructions, 250/ms

What is interesting is that a uint32_t divide takes more time than a floating point divide! Overall it is clear to see that as the integer gets larger the processing time increases. Floating point operations are 3-4 times as long as integer operations (except for uint32_t divides). I estimated the number of instructions per operation based on 16MHz and how many of each operation could be performed in 1ms.

The next step is to get these values for the Yun and look for performance improvement areas.

Here is the code I used to get these values: http://protological.com/browser/files/timer_sketch.ino.
(Here is the same code but with a macro function, it’s a little cleaner to look at)

Cross compile for Raspberry Pi, VideoCore, MMAL

I have a project which requires full control of the camera board on a Raspberry Pi from a custom C application, so I recently started looking into getting a toolchain and code running on the Pi. The Raspberry Pi is actually a really powerful and advanced SBC, with a full Broadcom VideoCore GPU and a connection to a 5MP camera that can do full 1080 HD video at 30 FPS. The project I am working on takes a single picture from the camera and saves it to the flash. I could use the raspistill application and some bash scripting, however I want full control over the camera and since eventually I will be processing video from a camera, the access should be as fast as possible by using the GPU. The first step was to build a tool chain and cross compiler to get things working, and then make a test application that uses the Multi-Media Abstraction Layer (mmal) library to access the VideoCore (VC) pipeline. I followed these two articles on how to use crosstool-ng to make a crosscompiler for the Pi. The next step was to make a simple application with some hooks into mmal and link it against the mmal libraries. It turns out the easiest way to build the mmal libraries is to clone the userland code for the Pi and build it locally using your new crosscompiler. I modified the cmake file in the makefile/cmake/toolchain/ directory to point to my custom crosstool-ng compiler rather than the compiler from git (Here are my modified buildme and cmake files).

Everything built successfully and the final step was to add in some mmal variables and function calls and build against the mmal libraries. This was more of a pain than I thought it was going to be. There are like 6 libraries that need to be preferences and 5 include paths for the VideoCore and mmal paths. After a few hours of searching and trial and error I found the correct include paths and library paths for GCC and the linker. One really annoying part was the fact that you have to explicitly add ALL libraries to the ld command, even if they are dependencies of libraries and the .so file is in the same directory as an already linked .so file. Take a look at this image and you will get the idea, all was fixed when I added -l entries for each missing lib. Here is what you need to build and link against if you want to access the camera on the Pi via mmal using VideoCore.

Include paths:
-I ../userland/
-I ../userland/build/inc/interface/vcos/
-I ../userland/host_applications/linux/apps/raspicam/
-I ../userland/host_applications/linux/libs/bcm_host/include/
-I ../userland/interface/vmcs_host/linux/
-I ../userland/interface/vcos/pthreads/
-I ../userland/interface/vcos/

Library include path:
-L ../userland/build/lib

Libraries to link:
-lmmal_core
-lmmal
-lmmal_util
-lvcos
-lcontainers
-lbcm_host
-lmmal_vc_client
-lmmal_components
-lvchiq_arm

Microcontroller parameter parsing with AWK

I needed to get all the information on every 16bit Microchip PIC microcontroller into one header file for use in a library. Microchip supplies a pic.h header for processors but it doesn’t have the information I needed including end address of the flash and EEPROM. If you poke around on the Microchip parametric search site, you can select all 16-bit microcontrollers and download a CSV with all the parameters. A little bit of AWK magic and you can get a nice header with whatever data you want.

awk -f process.awk all-microcontrollers.csv > pic.h

AWK script and example output header

microchip microcontroller parameteric search

wxGlade Testing

I was playing around with python and a GUI for a simple plant watering setup I hacked together and I stumbled upon wxGlade. wxGlade is a GUI maker for wxWidgets and can output in C++, Lisp, Perl or python. So far it’s seems pretty cool, I just made a quick test with an image and some text boxes. Attached is the code with an extended class to implement functions.

wxglade_test.zip

wxglade

Serial LCD python code

A while ago I purchased a CFA533 TTL level serial LCD board from Crystalfontz for use with a project. The board has a 16×2 character LCD and 6 buttons with plastic pads arranged in a Dpad pattern. The unit talks serial at 19200 baud. I am ramping up for a new project so I decided to see what this little unit could do and how easy the command set is. The first order of business was to connect to the unit. I am not a fan of stripping tiny wires and soldering to headers, so I thought I would turn to the trusty CNC and make an adapter board. The LCD has a 5×2 header, takes 3.3v-5v, and since it is TTL it needs to interface with some serial adapter. I have a 5v FTDI 232R USB cable that would fit the bill for this, I also dug out some 10 pin ribbon cable, as well as numerous 5v wall transformers with 2.1mm barrel jacks. The board I came up with it pretty simple, 5V, GND, RX, TX all on a 2cmx3cm board.

The next step was to get it chatting with some software. I had some python code that was used a few weeks ago to talk to a PIC via serial so I thought I would modify that to talk the LCD protocol. The protocol is pretty simple, 1 byte for type/command, 1 byte for length, variable data payload and a 2 byte CRC16. The stumbling block came when I tried to compute the CRC16 for some commands. Python has always been a language where you could “import xxxx” and it just works, not so much with CRCs. The datasheet for the LCD says the polynominal used is 0x8408, I tried to use crcmod to define a generator however I kept getting errors about it being too short. Long story short, it appears that Crystalfontz is using a CRC that isn’t very common, so I took the example C in the LCD datasheet and made a simple python function which did the trick. I wanted to write this post so anyone else looking for this CRC could use it.

The final result is a quick command utility that allows python to control almost anything on the LCD.I also got the python running on a Raspberry Pi with pyserial installed. Here are some pictures of the effort as well as the Python code. py_basic_term.py

serial_lcd_pic serial_lcd_testing serial_lcd_interface raspberry pi serial lcd output