Sunday, January 19, 2014

Rescuing an "unhappy" EM406A GPS



I'm not sure of exactly what happened, but while I was mucking about with my datalogger this afternoon, the EM406A GPS sensor started emitting what looked like garbage in place of the usual NMEA sentences. A little googling revealed a thread on the Arduino forums which contained a link to Ken's blog post over at DIYDrones. I grabbed a copy of Ken's code and tried it out.


As the comments in the code indicate, some mucking about with the baud rate was indicated. Attempts at 57600 and 38400 seemed to make no difference, but after trying 9600 baud I got a single NMEA sentence followed by a bunch of binary data (presumably SiRF), and feeling encouraged at that result, I tried the magic at 4800 baud and also changed the configured baud rate (see lines 53-55 in the below code) to 4800. It worked, and now my EM406A is emitting NMEA sentences and no binary SiRF data.


Along the way I adjusted the code to take advantage of the extra USARTs available on an Arduino Mega2560 board. The GPS is connected to RX1/TX1, and some status messages are emitted to the usual Serial console. After attempting the rescue process, it also starts dumping the data stream from the GPS onto the Serial console so you can see immediately if it was successful or not.


Summary: happy and very relieved - didn't want to buy another sensor! Post a comment and don't forget to thank Ken if this was useful to you - this is his rescue code, not mine!


Friday, January 3, 2014

My highlights of 2013

  1. March: Seeing Opeth live in concert again, at Enmore Theatre in Sydney. Mikael Akerfeldt appears to have his growl back. Hands-down the best gig I've ever been to, of any genre. Can't wait for their next tour (and mooted new album, also)
  2. April-May: Visiting the UK and especially Finland with my friend Tiina. I'd visited the UK back in 1984 when I was a wee lad, but didn't really remember anything. Was great to go back. But... Finland was stunning. We spent two weeks exploring it. Definitely going back there. Also on the way back to the UK (we flew home from London) I ticked off another bucket-list item - we visited the original Legoland in Billund, Denmark. I'd wanted to go there ever since I saw pictures of it (I think in one of those Lego Ideas books published by Lego) back in primary school.
  3. June: Visiting Japan very briefly, spending three nights in Tokyo, ostensibly to see Van Halen's concert at the Tokyo Dome. While there I caught up with an old friend who now lives in Tokyo, and ticked off another bucket list item - spending a few hours ogling all the wonderful things at the Toyota Automobile Museum near Nagoya. The Shinkansen (bullet train) to Nagoya was also pretty interesting.
  4. October: Acquired a new motorcycle - 2013 KTM 990 SuperMoto R. Ludicrous fun. Sounds wonderful. Somewhat impractical fuel range. Completely unsuited to highway slab rides, but brilliant for sporty rides and generally being a hooligan, which is just what I'd wanted

sampling multiple analog signals asynchronously with Arduino

So while I was assembling a fellow #arduino denizen's synth project on a breadboard, he commented that Arduino's analogRead hadn't been fast enough to read the pots. After poring over the AVR ATmega328 datasheet for a while I was able to get an interrupt-driven analog-to-digital conversion happening. This is documented in many folks' blogs but most of the pages I've seen only demonstrate one, and I needed four. His acidmatic synth is now rather a lot of fun to twiddle, and I will keep hacking on it, and build a permanent version in an enclosure.


Stripped-down demo code follows. Note that this requires an analog reference signal to be wired up to the AVR. This can actually be done in software if you just want it to be set at Vcc or some other voltage visible to the microcontroller, but I was getting very tired and that part of the datasheet was not making any sense. On my 16Mhz ATmega328, the below code yielded somewhere north of 2000 samples per second per pot. Easily enough for this application.



Monday, July 15, 2013

PCF8574-based I2C LCD backpacks

So it seems that there's a lot of these about. A while back I picked up a bunch of cheap LCD backpacks on eBay, they look like this:



Like most of these cheap LCD backpack units, it utilises a GPIO expander chip. In this case, the chip used is a PCF8574. Most of the other I2C backpacks for Hitachi LCDs seem to utilise Microchip's MCP23008, which seems to be the little brother of the MCP23017 I've been playing with lately. So I had quite a hunt for some quick and easy code libraries to test out the backpacks with. I found one in Atlassian Bitbucket. I used version 1.2.1.


I then found this page which describes a number of the cheap eBay backpacks and clones. The third code example worked fine with the above library.


Unfortunately, after reducing the test sketch to merely the below, it was still gobbling 4768 bytes of flash. Unacceptably large, I think.




At some point in the past I'd picked up a bunch of black-on-green 16x2 LCDs for next to nothing. The total cost per LCD+backpack combo should come to easily less than $10 (AUD) each, including shipping. Pretty happy with that. They even work properly!

Friday, July 5, 2013

How I compile Stellaris projects under OSX

So I don't really know much about the TI Stellaris yet, having mainly used AVR chips to date. But I have a couple of the Stellaris Launchpads, and have managed to get the toolchain working under Mac OS X. I'm not going to repeat all the steps required for that here; you can use this page as a good starting point for that, and noting that you can save yourself a whole bunch of time/hassle by setting up MacPorts and doing this:


sudo port install arm-none-eabi-{gcc,binutils,gdb}


In my $HOME/Code/stellaris directory I have a single Makefile called Makefile.simple, and a separate subdirectory for each project. Its contents look like this:


CC=arm-none-eabi-gcc
LD=arm-none-eabi-ld
OBJCOPY=arm-none-eabi-objcopy
CPU=cortex-m4
STELLARIS_TOP=$(HOME)/build/stellaris/stellaris
CFLAGS_STELLARIS=-mthumb -mcpu=$(CPU) -mfpu=fpv4-sp-d16 -mfloat-abi=softfp -ffunction-sections -fdata-sections -MD -I$(STELLARIS_TOP)
CFLAGS=-std=c99 -Wall -Os $(CFLAGS_STELLARIS)
LDFLAGS_LEFT=-T $(PROG).ld --entry ResetISR 
LDFLAGS_RIGHT=--gc-sections

$(PROG).bin: $(PROG).o startup_gcc.o $(PROG).ld
 $(LD) $(LDFLAGS_LEFT) -o $(PROG).bin $(PROG).o startup_gcc.o $(LDFLAGS_RIGHT)

$(PROG).out: $(PROG).bin
 $(OBJCOPY) -O binary $(PROG).bin $(PROG).out

clean:
 $(RM) $(PROG).bin $(PROG).out $(PROG).[od] startup_gcc.[od]

flash: $(PROG).out
 lm4flash $(PROG).out

You can see in the above that STELLARIS_TOP is set to the location in which I have unpacked (actually git clone...) StellarisWare. This is provided to gcc so that it can find C include files. Adjust as necessary if you are using my Makefile

In each project subdirectory I have a few files:


$ ls
Makefile       blinky.c       blinky.ld      startup_gcc.c

The Makefile merely includes ../Makefile.simple and specifies the name of this project:


PROG=blinky
-include ../Makefile.simple

The other files (blinky.ld and startup_gcc.c), at least at this learning stage, are the same for every project; I just copy them over from project to project.


To build my project, I just type make:


$ make
arm-none-eabi-gcc -std=c99 -Wall -Os -mthumb -mcpu=cortex-m4 -mfpu=fpv4-sp-d16 -mfloat-abi=softfp -ffunction-sections -fdata-sections -MD -I/Users/jslee/build/stellaris/stellaris   -c -o blinky.o blinky.c
arm-none-eabi-gcc -std=c99 -Wall -Os -mthumb -mcpu=cortex-m4 -mfpu=fpv4-sp-d16 -mfloat-abi=softfp -ffunction-sections -fdata-sections -MD -I/Users/jslee/build/stellaris/stellaris   -c -o startup_gcc.o startup_gcc.c
arm-none-eabi-ld -T blinky.ld --entry ResetISR  -o blinky.bin blinky.o startup_gcc.o --gc-sections

My project compiled and linked OK, so it is ready to send to the Launchpad with lm4flash:


$ make flash
arm-none-eabi-objcopy -O binary blinky.bin blinky.out
lm4flash blinky.out
ICDI version: 9270

Please let me know if you found this useful! I also use a similar Makefile structure for building and flashing AVR and MSP430 projects.

Sunday, June 30, 2013

MCP23017 and the Bus Pirate

So I wired up an MCP23017 GPIO expander to my Bus Pirate and couldn't understand why it wasn't acknowledging commands. Upon closer inspection of the datasheet I discovered that it expects an extra bit set in the I2C device address byte. The datasheet refers to this as the "Device Opcode".


Thus, if your device address lines are all tied to ground, ie. an address of 0x20, the address to write to is 0x40.


Once you've connected everything, the first step is to put your Bus Pirate in I2C mode and turn on the power:


HiZ>m4
Set speed:
 1. ~5KHz
 2. ~50KHz
 3. ~100KHz
 4. ~400KHz

(1)>1
Ready
I2C>W
POWER SUPPLIES ON

This example assumes you've tied all three address lines from the MCP23017 to ground, making its I2C address 0x20. Now we'll configure both IO banks to be all outputs; the 0:3 notation tells the Bus Pirate to write the value three times. The first 0 selects the IODIRA register address. The second and third 0s clear all the bits in the IODIRA and IODIRB registers, thus configuring them as outputs.


I2C>[0x40,0:3]
I2C START BIT
WRITE: 0x40 ACK 
WRITE: 0x00 ACK 0x00 ACK 0x00 ACK 
I2C STOP BIT

Finally, we turn on all eight GPIOA pins by writing 0xFF to register 0x12.


I2C>[0x40,0x12,0xFF]
I2C START BIT
WRITE: 0x40 ACK 
WRITE: 0x12 ACK 
WRITE: 0xFF ACK 
I2C STOP BIT

As always, read the fine datasheet!

Quickstart guide: TI MSP430 on OSX Mountain Lion

I had all of this stuff working on my other OSX laptop but for some reason it wasn't as trivial to setup on my new laptop as it was last time around, mainly due to the USB driver. So I thought I'd save some notes for Google's (and possibly my!) future reference.


If this all fails on Mavericks when it arrives, I'll try to remember to update it.


  1. Install Xcode (I installed the commandline tools from inside Xcode too [Xcode menu => Preferences => Downloads tab]; these are probably not actually required)
  2. Install MacPorts
  3. Install the toolchain bits:
    sudo port install msp430-{binutils,gcc,gdb,libc}
  4. Get the fixed kernel extension source code - the TI download is broken under Mountain Lion and possibly Lion as well:
    git clone https://github.com/freespace/ez430rf2500.git
  5. Follow the README.md instructions included with the ez430rf2500 source to install the driver
  6. Plug in your Launchpad
  7. If everything is working, this should get you to an mspdebug shell: sudo mspdebug rf2500
[jslee@shamata Release] $ sudo mspdebug rf2500
MSPDebug version 0.21 - debugging tool for MSP430 MCUs
Copyright (C) 2009-2012 Daniel Beer 
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

Trying to open interface 1 on 002
Initializing FET...
FET protocol version is 30066536
Set Vcc: 3000 mV
Configured for Spy-Bi-Wire
fet: FET returned error code 4 (Could not find device or device not supported)
fet: command C_IDENT1 failed
fet: identify failed
Trying again...
Initializing FET...
FET protocol version is 30066536
Set Vcc: 3000 mV
Configured for Spy-Bi-Wire
Sending reset...
Device ID: 0xf201
  Code start address: 0xf800
  Code size         : 2048 byte = 2 kb
  RAM  start address: 0x200
  RAM  end   address: 0x27f
  RAM  size         : 128 byte = 0 kb
Device: MSP430F2012/G2231
Number of breakpoints: 2
fet: FET returned NAK
warning: device does not support power profiling
Chip ID data: f2 01 01

Available commands:
    =           erase       isearch     opt         run         setwatch_w  
    alias       exit        load        power       save_raw    simio       
    break       fill        load_raw    prog        set         step        
    cgraph      gdb         locka       read        setbreak    sym         
    delbreak    help        md          regs        setwatch    verify      
    dis         hexout      mw          reset       setwatch_r  verify_raw  

Available options:
    color           gdb_loop        iradix          
    fet_block_size  gdbc_xfer_size  quiet           

Type "help " for more information.
Press Ctrl+D to quit.

(mspdebug) regs
    ( PC: 0ffff)  ( R4: 0dfde)  ( R8: 0fbef)  (R12: 0ffdf)  
    ( SP: 0ffff)  ( R5: 0f613)  ( R9: 07ffc)  (R13: 0feff)  
    ( SR: 00000)  ( R6: 0edff)  (R10: 0ffff)  (R14: 07bef)  
    ( R3: 00000)  ( R7: 0fbef)  (R11: 0cff7)  (R15: 0f5fc)  
0xffff:
    0ffff: ff                        
(mspdebug) 

If all this works, you should be able to compile stuff and use mspdebug to load it into MSP430 flash via the Launchpad.