Sunday 7 October 2012

sending dynamic text from the Pi to the LoL Shield via Gertboard

Getting fixed scrolling text on the LoL Shield from the uploaded arduino program is one thing (see previous posting), but we really want to get the text delivered into the program dynamically. This is where the serial GPIOs on the Pi can help out.

I wrote a small arduino program to read characters from the serial port and display them on the LoL Shield. Note that I had to edit the Charlieplex.cpp file from the LoLShield library to remove a (apparently unused) Serial.end() call. Line 373 on my copy.

Once the program is uploaded to your ATmega on the Gertboard, you can deliver text via serial on the Pi using any method you like, e.g. interactively via one of:

  • minicom ama0
  • screen /dev/ttyAMA0 9600
(Press return to tell the program you've finished entering your characters.)

Alternatively, you can send your text programmatically via a python, C, bash script by writing to the /dev/ttyAMA0 device, e.g.:

  • $ echo 'weeee!' > /dev/ttyAMA0 
Remember, when sending/receiving serial data between the Pi and the Gertboard's ATmega, you must connect the GP14-15 pins in J2 to the MCTX and MCRX pins just above them.

//
// displays text sent via serial e.g.
// echo 'weeee!' > /dev/ttyAMA0
//
#include "Charliplexing.h"
#include "Myfont.h"
#include "Arduino.h"

unsigned char buffer[140];
int c;
int i = 0;
int len;

void setup() {
    Serial.begin(9600);
    LedSign::Init();
}

void doMsg() {
    Myfont::Banner(len, buffer);
}

void loop() {
    if(Serial.available()) {
        int c = Serial.read();
        if(c != -1) {
            if(c == '\n' || c == '\r') {
                buffer[i] = '\0';
                len = i;
                i = 0;
                doMsg();
            } else {
                buffer[i++] = c;
            }
        }
    } else {
        if(len > 0) {
            doMsg();
        }
    }
}



Wednesday 3 October 2012

LoL Shield on Gertboard

Bought a giant LoL (lots of LEDs) shield from Olimex on Ebay. This shield has a matrix of 9x14 LEDs which can be individually driven. The shield has pinouts for Arduino boards, but wiring up 12 digital outputs from the ATmega chip on the Gertboard (PD0-PB5) to 12 digital inputs on the shield (2-13) allows the arduino IDE on the pi to drive the shield perfectly. Take a look at arduino images on the web to see where the digital pins 2-13 would connect to your shield.

Download the library from http://code.google.com/p/lolshield/  and place it in ~/sketchbook/libraries (create these directories if they don't exist),  then restart arduino IDE if open, and finally open the LolShield/examples directory in your arduino IDE and upload.

Note that I had to placate the compiler with a couple of 'const' references in the LolShield example/library code, and I had to remove the programming wires from the Gertboard after uploading to prevent the pi's GPIO pins from interfering with the ATmega chip at runtime.

The LoL Shield library lets you do loads of cool things from scrolling text, to vu-meters. I'll be having fun for some time, I think!


Monday 24 September 2012

twitter feed on LCD

I used the python-twitter module from https://code.google.com/p/python-twitter/ to add the ability to display the latest mention of a twitter account to the LCD, along with manual scrolling of the text to fit into the 16 character wide display. You'll need to log into dev.twitter.com with the account and enable an 'application' to get the oauth keys which you place into the initial twitter.Api() call, replacing the xxx entries with your own. The code fetches the latest mentions every 30 seconds. In between those fetches, it scrolls the text from right to left and repeats when the line has all been shown.

Here's the new main routine adapted from the original code as referenced in the post on LCD a couple of days ago:


def main():
  # Main program block
  api = twitter.Api(consumer_key='xxx',
    consumer_secret='xxx',
    access_token_key='xxx',
    access_token_secret='xxx')

  GPIO.setmode(GPIO.BCM)       # Use BCM GPIO numbers

  GPIO.setup(LCD_E, GPIO.OUT)  # E
  GPIO.setup(LCD_RS, GPIO.OUT) # RS
  GPIO.setup(LCD_D4, GPIO.OUT) # DB4
  GPIO.setup(LCD_D5, GPIO.OUT) # DB5
  GPIO.setup(LCD_D6, GPIO.OUT) # DB6
  GPIO.setup(LCD_D7, GPIO.OUT) # DB7
  GPIO.setup(LED_ON, GPIO.OUT) # Backlight enable

  # Initialise display

  lcd_init()

  GPIO.output(LED_ON, True)

  
  while(True):
    nowTime = time.time()
    loopTime = nowTime + 30
    print 'loop'
    results = api.GetMentions()
    msg1 = '               from @' + results[0].user.screen_name + '                '
    msg2 = '               ' + results[0].text + '                 '
    
    msg1Idx = 0
    msg2Idx = 0
    while(time.time() < loopTime):
      view1 = msg1[msg1Idx:msg1Idx + 16]
      if(msg1Idx + 16 > len(msg1)):
        msg1Idx = 0
      view2 = msg2[msg2Idx:msg2Idx + 16]
      if(msg2Idx + 16 > len(msg2)):
        msg2Idx = 0
       
      lcd_byte(LCD_LINE_1, LCD_CMD)
      lcd_string(view1, 1)
      lcd_byte(LCD_LINE_2, LCD_CMD)
      lcd_string(view2, 1)
      time.sleep(0.2) 
      msg1Idx += 1
      msg2Idx += 1

Sunday 23 September 2012

Gertboard

Ordered a Gertboard from http://www.tandyonline.co.uk which arrived 2 days later, even with the 3-4 day shipping option. 

The Gertboard is a Raspberry Pi expansion board, which offers 12 buffered IO ports with LEDs, 3 pushbuttons, a DAC, an ADC, a motor controller, 6 open collector channels and probably the coolest of all, an Arduino microcontroller (Atmega328P) which can be programmed by the pi, using the standard Arduino IDE with tweaks from here. Here's a shot of the Gertboard running the 'blink' Arduino example sketch:



The Gertboard comes unassembled, and takes a few hours to put together. Tandy's packaging is excellent, with components in an ordered strip. There are a bunch of sample C programs to test each of the subsystems, which I'm enjoying working through to validate the soldering.

Thursday 20 September 2012

LCD fun

I bought a cheap HD44780 LCD from ebay, and followed the excellent instructions at http://www.raspberrypi-spy.co.uk/2012/08/16x2-lcd-module-control-with-backlight-switch/ to great success:


2 Raspberry Pis communicating via morse code

Our second Pi arrived in the post today from Cool Components, which arrived the next day after they shipped it. Nice! But what on earth can you do with 2 raspberry pis?

You can set up one to be an LED morse code transmitter, and one to be a phototransistor morse code receiver:



I got the idea from a post on the forums about a project described on http://c.cam108.me/ to monitor a power meter that indicates load by the frequency of a flashing LED. I took the phototransistor from there and found that it works very well with the LEDs contained in my SK Pang kit.

In my project, the sender is a typical GPIO output controlled LED, with python code to take an english message from the user and convert it into morse code LED pulses. I took the python morse code dictionary from http://www.cl.cam.ac.uk/~db434/raspi/morse_code/ to save a little work. 

The receiver setup is identical to the one in the power meter project, but with C code to monitor the LED pulses and convert them from morse code back into english. I used C because the python runtime turned out to be quite imprecise on the timing loops. With some tuning, I could get the C code to correctly interpret the active LED durations, and the pauses between. Because I was following the power meter project's C source, I also used the bcm2835 C library which can be found at http://www.open.com.au/mikem/bcm2835/



I prototyped this all on a single Pi initially, so don't let that stop you if you only have the one. 

The one minor issue with the phototransistor, is that it is quite sensitive to ambient light, so I covered the units with card during execution. Note that the current receiver code spits out the previous message when a new one arrives (i.e. pauses are currently only terminated with the next LED pulse).


Thursday 13 September 2012

Following the excellent instructions at D. Bodnar's pi page: http://www.trainelectronics.com/RaspberryPi/ I successfully made a serial cable for the pi.

I bought an rs232 to ttl chip from http://cgi.ebay.co.uk/ws/eBayISAPI.dll?ViewItem&item=221068548032 very cheap, and it even arrived next day!

Initially, I soldered the chip right-to-left, which didn't work. It was only by noticing the layout of the resistors in D. Bodnar's page above that I realised the chip was inverted. Note that this chip has 6 resistors, unlike the above page. Click the image to enlarge it. I guess I'm lucky I didn't fry it, or the pi. The chip did get very hot. Ahem.



Once the cable was complete, I needed to test it via a terminal. I don't have a windows machine with a COM port, so I used a linux laptop and ran

screen /dev/ttyS0 115200

On my crunchbang 11 linux setup, this initially just returned '[screen is terminating]'. Suspecting permissions on /dev/ttyS0 I ran the command again as root, pressed Return a few times, and it worked! I'll work out what the permissions issue on /dev/ttyS0 is later.


Note the ttyAMA0 presented by the pi compared to the normal tty1 you see over e.g. HDMI console. Interestingly, the terminal stays connected after a reboot and you can see the pi's output as it is restarting.
 


Tuesday 11 September 2012

More fun with understanding the pi's GPIO using python, and the breadboard (solderless circuit board for prototyping electronics) kit from SK Pang:
  • Connect GPIO18 (pin position 12 - yellow wire in the image) to breadboard connected to LED's positive anode (longer leg). The LED's cathode is connected to a resistor, which is connected to ground on the breadboard. The red wire connects breadboard ground with the GPIO header pin 6, which is ground.

  • Install python RPi.GPIO via: sudo apt-get install python3-rpi.gpio
import time
import RPi.GPIO as GPIO

GPIO.setmode(GPIO.BCM) # use formal names, not pin positions
GPIO.setup(18, GPIO.OUT) # set GPIO18 to be output rather than input

for TIMES in range(10):
     GPIO.output(18, True) # enable GPIO18
     time.sleep(1)
     GPIO.output(18, False) # disable GPIO18
     time.sleep(1)
  • run script (as root: GPIO is privileged) sudo python3 led.py
  • the LED will flash on for a second and off for a second in a loop 10 times.
Takeaway: GPIO allows programmatic control of the input/output pins on the Pi. There are python, C, Java and assembler (any more?) options for controlling GPIO on the Pi.

Wow, using the instructions at https://projects.drogon.net/raspberry-pi/gpio-examples/tux-crossing/ I quickly knocked up a working pelican crossing demo:


Such fun! The 7 year old also thought it was cool. Promising start!
Lesson 6 of the Baking Pi series gets you writing code to generate framebuffer graphics via the GPU on the Pi. Much fun getting it working. There is some uncertainty about whether to align the data to 4 or 12 byte boundary. 4 worked for me.

In other news, I ordered the SK Pang Pi starter kit to try my hand at some electronics, and get the kids to see how stuff works.


Sunday 9 September 2012

the config.txt on the SD card needs the line

kernel_old=1 

if the Baking Pi OS is going to run with the latest firmware images.

Explained here.
While swapping over my locally built Baking Pi kernel.img files over the stock linux one on the SD card, I made a mistake and lost my linux one. I'd done an apt-get install update recently, which had installed an update to the raspbian version, but the download images at rasberrypi.org haven't updated to that one yet. So I didn't have a way to restore my stock kernel.

So I built a new one. On the pi. Which took several hours. But it worked fine. I was following http://elinux.org/RPi_Kernel_Compilation#Kernel_compilation for this.

I've also been having problems with Lesson 5 of the Baking Pi tutorial. Instead of blinking out morse code on the OK LED, my version just lit the LED permanently. Puzzled, I looked at the model answer for the lesson, and the code was very similar. I built and booted that version and got the same behaviour: solid LED. Most odd. To eliminate my mac toolchain as being the culprit, I built and installed Lesson 5 model answer on the pi itself by editing the makefile and removing the yagarto prefix from the makefile, i.e. changing

ARMGNU ?= arm-none-eabi
to
ARMGNU ?=

but this resulted in the same behaviour: a solid LED light. I've asked on the forums for help.

Saturday 8 September 2012

While I use an IDE for most development, I've been just using an editor for editing ARM asm on the Mac. Originally I was using Vi, but everyone's raving about Sublime Text 2, so I'm giving that a try. It does syntax highlighting (something you miss when you're used to it), but doesn't support ARM asm out of the box. It *does* support TextMate language bundles, though. Here's one for ARM asm:

 https://github.com/aumuell/ARM-assembly.tmbundle

I know Vi will also have good support for ARM syntax highlighting, but my Vi-fu isn't strong enough to pursue that.


Friday 7 September 2012

This is the most fun coding I've done in years. Lesson 4 of the Baking Pi ARM OS series has you write your own system wait function based on the Pi's microsecond-precise timer. Such a buzz seeing the LED flash on and off at the right time!

I showed it to my 7 year old who's been playing with and enjoying Scratch programming, and she said 'that is cool!'. This makes me happy.

Wednesday 5 September 2012

Configuring the rPi for remote X access (e.g. running X apps on the rPi and displaying them remotely on another linux machine): after installing ssh on the rPi, I set the IP to be static via /etc/network/interfaces 

auto lo

iface lo inet loopback
iface eth0 inet static
address 192.168.1.201
netmask 255.255.255.0
gateway 192.168.1.254

(note the non-standard gateway for me, thanks to BTHomeHub3)

and enabled X11 forwarding over ssh via /etc/ssh/ssh_config uncommenting

ForwardX11Trusted yes
AddressFamily any

then:
    ssh -X 1pi@192.168.1.201 

to log in remotely. Once in, you can enable X11 connections on the client machine (running X) with:
    xhost +

After this, typing X application names in your remote ssh shell on the rPi should cause them to display on your client linux box.

To enable networking with usb wifi instead, install and use wicd-curses to configure the wifi adapter.
Yay! We have pi!



and the lovely green case from modmypi:


And you can even see through the holes in the top to see the OK LED flashing on and off from the OS tutorial: http://www.cl.cam.ac.uk/freshers/raspberrypi/tutorials/os/ok02.html

I found I couldn't drive the keyboard + mouse + usb wifi on the unpowered hub (no surprise), so I'll be getting a powered one. However, the dell 27" monitor has HDMI input, so it'll be easier to configure in the office than trailing ethernet around the house.

Tuesday 4 September 2012

Still no RPi :(

But I have been working through some of the tutorials in the previous post, and noticed that some people were writing output to stdout using the C library's puts and some using printf (with, of course, printf being especially useful if you want dynamic output).

But while the following program:

.globl main
.align 2
.section .rodata
hello:
    .asciz "hello"
.text
main:
    ldr r0, =hello
    bl puts
    mov r7, #1
    swi 0

compiles(assembles?) and runs fine, substituting printf for puts causes no output. I posted the query to the Raspberry Pi Bare Metal forum and got an immediate answer: use \n at the end of the hello string othewise it won't flush the buffer to stdout. A followup post explained that this program exits using syscall 1, which frees up the unix resources, but not C stdio. A proper return from main is required for a program using the C library:

.globl main
.align 2
.section .rodata
hello:
    .asciz "hello"
.text
main:
    stmfd sp!, {lr}
    ldr r0, =hello
    bl printf
    mov r3, #0
    mov r0, r3
    ldmfd sp!, {lr}

(and WHOA! gotta work on getting code samples to markup better than that!)

Sunday 2 September 2012

Ordered a Pi from https://www.modmypi.com/shop/raspberry-pi/raspberry-pi-and-modmypi-case which shipped immediately (for £37.98 with case + shipping + vat). Lime green case. Oh, yes.

While waiting for the Pi to arrive, I was reading http://www.cl.cam.ac.uk/freshers/raspberrypi/tutorials/os/ and was itching to get started working through the assembly language exercises, so I wondered if there was a Pi emulator. Of course there is, this is the Internet, baby. However, note that for the OS on ARM tutorial above, although you will be able to assemble, link and run the exercises on a Pi emulator, none of the hardware (e.g. LEDs) on the Raspberry Pi are emulated, so you won't be able to 'see' the fruits of your labour (or even confirm your code is running correctly) until you run it on a real Pi. So for these exercises, the author expects you to be editing and assembling locally via a toolchain available for mac/linux/windows on his download page.

For the learning process (see below) of writing, assembling, linking and running and debugging ARM programs, the emulator is perfect:

http://www.raspberrypi.org/phpBB3/viewtopic.php?f=9&t=2961 for emulator installation instructions.

Note the:
         apt-get install lxde xorg python geany

command fails until you first do:
         apt-get update 

This'll get you an emulated debian-ARM vm running in an emulated debian-raspberry pi vm in virtualbox. Next, give yourself root rights:

         su -
         Password: password
         visudo

will bring up an editor to let you add your new user to the sudoers list. add a row:
         username ALL=(ALL) ALL

where username is the name you've added. Then:
         apt-get install gcc gdb

will add gcc (and gdb) for your ARM vm.

You may need to reconfigure the keyboard mappings for your emulator:
         apt-get install console-data

This means you can now write ARM assembly, use /usr/bin/as to assemble it & /usr/bin/ld to link it. If you want to link against the linux system calls / standard c libraries, you can assemble and link using gcc.

In addition to the OS on ARM tutorial above, I found the following two sites very useful for getting to grips with ARM assembly:

http://www.fourtheye.org/armasm.shtml steps you through some simple to increasingly complex examples. Did you ever think you'd understand bubblesort in assembler?

http://www.peter-cockerell.net/aalp/html/frames.html is an old but still very relevant book on programming ARM with very useful sections on the ARM instruction set and all the options and variants and twizzles and doodads that you'll see in example code in the above links.