# jenswilly.dk

Microcontrollers and embedded electronics

## Calculating stress for an acrylic disk at depth

2. February 2013 16:20 by Jens Willy Johannsen
Categories: Projects | Tags:

For my ROV project, I am considering using a flat acrylic disk instead of a dome for the front "window".
So I needed to calculate if a disk of a certain diameter and thickness would hold up to the pressure exterted at a specific depth.

A couple of hours of Googling led me to these calculations and constants:

The maximum stress a uniformly supported disk is subjected to (of a given material and of a given thickness and radius) is calculated as follows (from here):

 σ = 3(3 + ν)pr² —————— 8t²

Where

 σ is the maximum stress in Pa ν is Poisson's ratio for the material (0.37 for acrylic from here) p is the pressure the disk is subjected to in Pa r is the disk's radius in meters t is the thickness in meters

If the maximum stress exceeds the material's flexural strength, the disk will break.
For acrylic the flexural strength is 100 MPa (from here).

I entered the values for a 6 mm thick 110 mm diameter disk at a pressure equal to 25 meters depth and the result is that the max stress on the disk is 37 MPa. So it will hold.

You can enter your own values in the InstaCalc formula I made here: http://instacalc.com/9335.

1 comment »

## Soft UART on LPC13xx

23. January 2013 11:32 by Jens Willy Johannsen
Categories: ARM, Projects | Tags: , , ,

For the ROV project I need two UART connections (one for RS485 to the onboard controller and one for receiving input from the VNC2 USB host controller).

And since the LPC1347 only has one UART I needed a soft UART for one of the connections. Fortunately for me, NXP provides an implementation in AN10955. There was only one problem with it: it doesn't work. Or rather, it works for a while and then stops receiving anything (scoping the UART line confirmed that the VNC2 chip continued to send data so the problem had to be in the soft UART code).

Yea, intermittent errors – what's not to like… (Read on for the problem and the solution.)

## New power supply

20. January 2013 12:50 by Jens Willy Johannsen
Categories: General | Tags:

How, oh how did I ever live without it?
Just before Christmas I finally caved in (to myself) and got myself a decent bench-top power supply. A TTi PL303-QMD (datasheet/brochure here).

Yes sure, there are more advanced units out there but this one suits my needs just fine: dual 3 ampere outputs (which can be paralleled together for a total of 6 amps), voltage span setting (so the voltage dial only adjusts voltage from e.g. 3.0 to 3.4), 500 mA mode (allowing much finer control over the current setting up to 500 mA).

And now I can't imagine how I ever got by without it. So if you are considering splurging on a decent PSU, consider no more and get this one right now!

PL303QMD (click for larger image)

1 comment »

## DC motor drive from 3.3 V MCU

29. November 2012 22:24 by Jens Willy Johannsen
Categories: Projects | Tags: , , ,

For the ROV project I need to drive six DC motors (waterproof motors from bilge pumps). They are 12 V DC brushed motors running a 6 amps at full speed and I want to control them using PWM (for variable speed) from an LPC1347 MCU.

A popular way of controlling DC motors is by using an H bridge. However, since I only need to drive the motor in one direction I can use a simpler configuration: a single N-channel MOSFET as a low-side switch.

First I need to find a MOSFET that can handle the 6 amps continously and not get too hot. And since I will switching the MOSFET on and off using PWM at a frequency of 20 kHz I also need to consider switching power loss.
Here are a couple of useful links: choosing a MOSFET, MOSFETs and drivers, MOSFET power dissipation.

### Gate current and MOSFET driver

Even though the MOSFET doesn't require a high voltage to fully switch on, the MOSFET gate does have a quite high capacitance (typically, the higher current a MOSFET can handle the higher gate capacitance it has) and in order to switch the MOSFET on and off quickly enough we need a high current (of the order of a few amps).
If the gate current is low it takes longer to switch the MOSFET and the resistance through the MOSFET is much higher when the MOSFET is switching. And higher resistance means higher power loss and higher temperatures.

Since the MCU cannot provide or sink more than 4 mA we'll use a MOSFET gate driver to boost the current from the MCU and to handle the higher sink current.

### Flywheel diode and capacitor

I won't go into details since you can read about it in great detail elsewhere (Wikipedia for example) but you do need a diode and a capacitor on the motor circuit. I tried without diode and capacitor with a scope attached. With no flywheel diode there were some really large voltage spikes every time the motor stopped (about 130 V). And without the capacitor (but with diode) there was a nasty "ringing" (starting out a about 20 V) every time the motor stopped.

So the final circuit is:

Motor drive circuit

## Reading USB joystick data from Vinculum-II

30. October 2012 10:52 by Jens Willy Johannsen
Categories: General | Tags: , , ,

Success! I have managed to write and compile firmware for the FTDI Vinculum-II (VNC2) USB host IC so I can read HID reports from a Saitek Cyborg EVO joystick, parse the data into values for the X, Y, rotation and throttle axes and button states and transmit any change in values by UART which can be received by an MCU.

This is what I did:

First, I got a V2DIP1-32 development module. This is basically a VNC2 (the 32-pin version) on a PCB along with a 12 MHz crystal, a USB A socket, a 3.3 V voltage regulator, an LED and a couple of capacitors and resistors. In other words, only basic support components.

Next, I installed the Vinculum-II Toolchain (the development IDE) version 2.0.0 and then updated to SP1.
The IDE works ok. Especially the application wizard works well and gives you a good starting point for your own firmware by adding the necessary libraries, headers and scaffolding code based on your selection of IC, USB ports in use and required drivers.
But the IDE is Windows-only software… *sigh* I hate that. Fortunately I have my old MacBook Pro with Windows 7 on a Bootcamp partition.

To flash the compiled firmware onto the chip I used FT-Prog
and a FTDI TTL-232R-3V3 cable connected to the VNC2 as described in this application note.

Note: you don't need the VNC2 Debugger/Programmer Module to flash the VNC2 – the USB-to-UART cable is sufficient – even though the FTDI website states that the Debugger/Programmer module is required for initial programming.

On to the firmware itself. I did start by wasting a couple of hours by not reading the VNC2 dev board's datasheet closely enough to notice that the USB socket on the board is connected to USB port 2 and not – as I figured – port 1. After tweaking the supplied example project 'USBHostHID' and reading the documentation I pretty quickly had some firmware that did what I wanted: wait for a HID device with the specified VID/PID to be connected, read HID data, parse the data into corresponding X, Y, Rz, Z and button values and, if any values change, send the new values over the UART connection.

Here's the complete firmware project (including compiled .rom file).
And here is a sample dump of the UART output. If a line starts with a "S" it is a status message, if it starts with "E" it is an error message and otherwise it is a value update.

If you want to use this project to read data from your own joystick (and it's not a Saitek Cyborg EVO), you'll have to change:

1. The VID/PID for the joystick:
```// find VID/PID of Saitek Cyborg EVO device hc_ioctVidPid.vid = 0x06a3; hc_ioctVidPid.pid = 0x0464;```
2. The `parse_hid` method to match your own joystick's HID descriptor.

## Parsing USB joystick HID data

25. October 2012 23:02 by Jens Willy Johannsen
Categories: General | Tags: , ,

As part of using a USB joystick as input device to an MCU I needed to parse the raw HID data of the joystick into values on the various axes and button states.

This is the first time I have had to manually get from a HID descriptor and some raw data to something that makes sense.

## USB joystick as input to MCU

25. October 2012 14:03 by Jens Willy Johannsen
Categories: Projects | Tags: , , , ,

As kind of a bigger, more long-term project I've been thinking about building a small ROV. This is in no way a novel idea – there are lots and lots og DIY ROV projects out there (Google: build your own ROV). I live by a canal in Copenhagen habour so it would be fun to have a small underwater robot to play with.

There is a lot of hardware going into a ROV project so there's lots of potential for learning new technologies. One of the components is, of course, the control input device. I figured I would forego the usual clunky four-way tact switches and use a decent USB joystick instead – a Saitek Cyborg EVO to be specific. It has pitch, roll, yaw and throttle axes as well as a thumb hat switch and about a million push buttons.

This is a USB joystick and it uses the USB HID protocol. So I need the MCU to work as a USB host. This either involves a big nasty pile of firmware code or a MCU with ROM-based USB host drivers.
My current MCU of choice, the LPC1347, does not have USB host capabilities, but its bigger (but older) brother, the LPC1768 (and other in the LPC17xx series) does have USB host drivers.

However, instead of switching to another MCU I've decided use a dedicated USB host IC. That being the FTDI Vinculum-II. This chip will handle all the USB stuff: enumerating, connecting and so on. And it will be programmed with firmware that simply echoes HID data from the joystick to the MCU using either UART or SPI.

So – off to the store to get myself a development board version of the VNC2 (this one) and we'll see if I can get it working with the joystick…

## Measuring battery voltage with ADC on LPC1347

24. October 2012 21:39 by Jens Willy Johannsen
Categories: ARM | Tags:

For the GPS Tracker project, I need to measure the battery voltage using the ADC but since the raw battery voltage is higher than the MCU's VCC of 3.3 V I need to use a voltage divider to get the maximum voltage below 3.3 V. (See this article on microBuilder.eu on how to do that properly.)

For the breadboard prototype I won't worry too much about power consumption but for the final version I probably should make the kind of controlled voltage divider mentioned in the microBuilder article.

## Resistor values

When picking values for the voltage divider I want to use as much of the ADC's full range as possible to get the highest accuracy without exceeding the VDD level . If I just divided by 50% (e.g. two 10k resistors), the measured battery range would be about 0 to 2.1 V. Ideally the range should be 0 to VDD but even though the pins are 5 V tolerant in digital mode they may not exceed VDD in analog mode so I'll try with the 0 to 2.1 V range and see if that is accurate enough.

I also need to balance power consumption and accuracy. Higher value resistors pass less current through the voltage divider but lower current means lower accuracy in the ADC.
It helps to put a capacitor on the input pin so the ADC can pull current out of the capacitor if it needs more than voltage divider can provide. Like this:

E.g. 2 x 1 MΩ resistors and a 0.1 µF capacitor.

With those values, the capacitor will be charged to about ⅔ capacity in 0.2 seconds and that should be ample capacitance for the ADC to perform one measurement and since I'll be doing one-shot ADC conversions the 0.2 secs recharge time (less, actually since the capacitor will not be completely drained by a single conversion) is not a problem.

This is what I need to do in order to perform a one-shot ADC conversion:

1. Configure pin TDI/PIO0_11 as AD0 input pin
`LPC_IOCON->TDI_PIO0_11 = 0x02;`
2. Power up ADC analog block:
`LPC_SYSCON->PDRUNCFG &= ~(1 << 4);`
`LPC_SYSCON->SYSAHBCLKCTRL |= (1 << 13);`
4. Configure control register:
```LPC_ADC->CR = b00000000010000000000010000000001; /* _or */
LPC_ADC->CR = (1<< 0) | (4<< 8) | (1<< 22);```

The control registered is configured as follows:

 (0:7) SEL = 1 to select AD0 pin (pin 32 on LQFP48) (8:15) CLKDIV=4 for 72MHz / 4+1 = 14.4 MHz ADC clock speed (16) BURST=0 for software-controlled conversions (17:21) (reserved) (22) LPWRMODE=1 to enable low-power mode that only powers up ADC circuitry when performing a conversion (23) MODE10BIT = 0 for 12 bit resolution (24:26) START = 000 – no conversion until I say so (27) EDGE – not relevant for software-controlled conversions (28:31) (reserved)

Analog power and voltage reference pins are already connected on the LQFP48 package: VFREP is internally tied to VDD and VFREN is tied to VSS. Likewise for VDDa and VSSa.

### Perform the conversion and read the value

```LPC_ADC->CR |= (1 << 24);              /* start A/D convert */
while( LPC_ADC->GDR & (1 << 31) == 0 ) /* wait until end of A/D convert */
;

if( LPC_ADC->GDR & (1 << 30) )  /* if overrun, return zero */
return 0 ;

return ADC_Data;    /* return A/D conversion value */
```
1 comment »

## Making stuff

12. October 2012 13:42 by Jens Willy Johannsen
Categories: 3D printing | Tags:

I've just ordered one of these nice machines:

Yessiree, a MakerBot Replicator 2 3D printer. Unfortunately, there is 4-6 weeks lead time so I can't begin playing with it right away. Fortunately, that gives me time to brush up on my 3D modelling skills (this 3D printed enclosure came out pretty good though so I'm not starting from scratch).

And there's lots to learn: different types of filament, extruder settings, slicing profiles and whatnot.

Sure, I can wait. I'm not impatient for the Replicator 2 to arrive at all...

## nxpUSBlib on LPC1347

5. October 2012 14:01 by Jens Willy Johannsen
Categories: ARM | Tags: ,

Since I had some problems gettings USB CDC working I decided to try using NXP's nxpUSBlib instead of the more simple examples that I only got almost working. But I ran into a couple of problems...

## LPC1347 support

The first problem was getting the thing compiling for the LPC1347. The most recent version (0.97) does support the LPC1347 but not quite.

Having downloaded the archive and imported everything into Code Red LPCXpresso IDE as per the readme, I tried to configure the BSP (development board), CDL (CMSIS and device) and nxpUSBlib projects for the LPC1347 MCU. No problems.
But when I tried to select the LPC1347 for the Example_VirtualSerialDevice project it turned out that there was no such build configuration. There is a LPC13Uxx configuration for the Example_MassStorageDevice, however.

1 comment »

## GPS Tracker update

5. October 2012 9:16 by Jens Willy Johannsen
Categories: ARM, Projects, Telit GE865 | Tags:

Success! More or less, anyway.

Using the nxpUSBlib (having made a few modifications – I'll do a post on that soon) I've managed to get USB CDC working and I got the GSM initialization and SMS receiving working.

At the moment, on receiving an SMS, the system will reply to the sender with the current GPS status regardless of the contents of the SMS.

(The GPS has no fix because it is on my workbench with no satellites in view.)

## Power supply considerations

But: I need to do some careful design of the power supply. The GSM module is extremely power hungry. Especially when registering on the network or doing any other network related tasks – like sending or receiving SMSes. And the battery I'm currently using can not supply enough power for both the GSM module and (through a linear 3.3 V voltage regulator) the MCU and GPS module.

So I'll have to get a beefier battery (this 2000 mAh one) or this 6000 mAh one) and also add a low ESR capacitor (as recommended in the GSM module datasheet).
And I'll also add P-channel MOSFETs as high-side switches for the GSM and GPS modules in order to be able to switch power on and off to these modules.
At the moment I run the prototype off two separate power supplies: the 3.7 V LiPo battery directly connected to the GSM module and a 9 V battery supplying the MCU and GPS module through a 3.3 V LDO voltage regulator.

## Moving to LPCXpresso

23. September 2012 13:47 by Jens Willy Johannsen
Categories: ARM, Projects | Tags: , , ,

I’ve made quite a bit of headway with the firmware for the GPS Tracker project but there are still some problems – mainly with the command parser and the USB CDC interface.

So I decided I needed some way of debugging the firmware. After looking at several options (they have to run on Mac OS X), I decided to get a LPC1347-based LPCXpresso.

The LPCXpresso consists of two parts:

1. An LPC MCU with a minimal amount of support components: crystal, capacitors, an LED and a mini-USB socket with the required resistors and PNP transistor.
2. The “LPC-Link” which is a programmer and JTAG debugger which connects to the computer by USB. The LPC Link can actually be severed from the MCU part of the board and will then work as a normal JTAG debugger which can be connected to MCUs (LPCXpresso or otherwise) using a 10-pin connector.

The LPCXpresso also comes with a free version of Code Red’s Eclipse-based IDE with built-in/preconfigured support for the GNU tool chain and standard C libraries and debugging views for inspecting memory and peripherals and whatnot.

I prefer the LPCXpresso to the mbed because the MCU board contains no extra components (compared to what I will use on my own boards) and all code is standard C and CMSIS libraries (so no proprietary firmware environment and libraries) – and still I have the ability to debug code and inspect memory at will.

## LPC11U24 + LPC1343 –> LPC1347

The LPCXpresso is available with a number of different LPC MCUs. I chose the LPC1347-based one.

Basically, the LPC1347 is a newer version of the LPC1343 and it has the same GPIO structure as the LPC11Uxx devices and the same USB ROM drivers and it now has EEPROM as well. Read this blog entry on microBuilder.eu for a comparison between the LPC1343 and the LPC1347.

I have decided to focus on only one ARM MCU instead of both the LPC11U24 and the LPC1343 – and that will be the LPC1347 (for now at least). Yes, it has a slightly higher power consumption than the LPC11Uxx but on the other hand it is faster and has a Cortex M3 core instead of a Cortex M0 core.

So the plan is:

1. Make the necessary changes to compile the current firmware code for an LPC1347 (which shouldn’t be too much of a hassle since peripherals for the LPC11U24 and the LPC1347 are pretty much the same) in the LPCXpresso IDE (removing the current linker script and CMSIS files).
2. Rebuild the breadboard prototype using the LPCXpresso.
3. Debug, find the problems and fix them…

## GPS Tracker progress

2. September 2012 14:35 by Jens Willy Johannsen
Categories: ARM, Projects | Tags: ,

For the GPS Tracker project I’ve been working on – struggling with, actually – getting all the communications subsystems working. I need to use UART for communication with the GSM module, soft UART (since the LPC11U24 has only one hardware UART port) for the GPS module and USB CDC for command and debugging.

And apart from the occasional programming blunders (like forgetting to increase a pointer when iterating elements in an array) I’ve had lots and lots of weird problems. But I finally got UART and soft UART working together and then I took a really long, hard look at the example USB CDC code I’ve been working with.
And it turned out that I needed to change a couple of things:

1. The linker script (which should be for an LPC11U24 device) specified a RAM size of only 4 KB. This has been fixed to specify an SRAM size of 6 KB.
2. The USB interface was initialized with a memory buffer at what was, in effect, an arbitrary place in the SRAM memory. The original code used `usb_param.mem_base = 0x10001000` and `usb_param.mem_size = 0x1000`.
For an LPC11U24, location 0x10001000 is at two thirds up in the SRAM area (which is from 0x1000000 to 0x10001800).
This has now been changed to use `usb_param.mem_base = 0x20004800` and `usb_param.mem_size = 0x0800` pointing to the top of the USB RAM area with a size of 2 KB (which is the size of the USB RAM).
3. My `USB_CDC_send()` function calls the `WriteEP` directly. This has been changed to copy data into a serial fifo buffer and calling `WriteEP` from the `VCOM_bulk_in_hdlr()` function when the USB host requests data. And the max packet size is also observed now.

And with these changes in place I was rewarded with the following session on the USB CDC terminal connection:

``````sys test
OK - Response from SYS TEST
sys version
OK - b155 on 2012-09-02 13:34:17 +0200, git 31db1bb904695fc5347a136dbf2c819520162099
gps status
OK - GPS status: 1, sats: 6/12, time: 121246.854, lat: 5538.7522N, lng: 01233.1385E
``````

Nice :)
Next steps are getting the ADC working for monitoring the battery level and implementing the interface for the GSM module.

1 comment »

## GPS Tracker components

14. August 2012 16:33 by Jens Willy Johannsen
Categories: ARM, Projects | Tags:

To continue my GSM-GPS Tracker project, here is an overview of the system and the components it comprises:

(Click to see large version)

## Firmware components

The firmware components can be divided into peripheral drivers and core functionality.

The project is hosted on Github and all the driver code along with linker script, startup code, CMSIS files and Makefile has been moved into a Git submodule (the root of all evil, I know, but in this case it actually made sense) so I can reuse that in my other LPC projects. The submodule is also on Github.

### Peripheral drivers

• ADC for battery voltage monitoring
• UART for GSM module communications (already working)
• Soft UART for GPS module comms since the LPC11U24 only has one hardware UART (already working)
• USB CDC for local programming and debugging (already working)

### Core functionality

• Command parser for commands received by SMS or USB CDC
• NMEA parser to extract coordinates and timestamps from GPS module output
• Position logging storing current and the X last known positions with timestamps

## New project: GPS tracker

10. August 2012 12:15 by Jens Willy Johannsen
Categories: Projects, Telit GE865 | Tags:

It’s about time for a new project and I’ve decided to dust off an old project that I never really got started: a GPS tracker with a GSM/GPRS phone module.

Sure, there are plenty of GSM enabled GPS trackers available – both comercially (like this one) and as hobby projects (this one for example) but that doesn't mean that I can’t 1) learn a lot from making one myself, 2) have fun while doing it and 3) make something better than what is out there…

## Initial requirements

So the initial high-level requirements (aka “what’s it gonna do”) are:

1. Get current position from GPS module.
2. Accept commands as SMS messages from a GSM module.
3. Send position info back as SMS.
4. Continuously send position info to a webserver.

## Design considerations

And my initial design considerations (aka “keep this in mind when designing the thing”) are:

### Power

Everything must be run off a 3.7 V LiPo battery. So think about power consumption and battery capacity.
The LiPo will be charged with a mini-USB cable.

### Enclosure

Think about the size and mounting of GPS and GSM modules as well as antennas for GPS/GSM.
Also, the LiPo battery needs to fit in the enclosure.

I’m thinking either laser-cut acrylic case from Ponoko or 3D printed box from Shapeways

## Components

The components I have in mind for this project right now is:

• MCU: NXP LPC11U24 ARM processor. I’m thinking that is a good project to start switching from AVR to ARM.
• GPS: SUP500F GPS module since that’s what I already have in my parts box. Otherwise I would probably choose a more modern module.
• GSM: Telit GE865 on breakout board – again the reason is mainly that this is what I already have. But it’s still nice.
• LiPo charging IC: The Microchip MCP73831 looks like it fits my purposes perfectly: it is designed to charge one LiPo cell from a USB port and it has bi-directional status output.
• Status LEDs: a couple of 0805 or 1210 SMD LEDs. The exact model is not critical.
• SIM holder: a generic SMD SIM holder. Something like this.
• Battery: 1000 or 2000 mAh 1s LiPo battery. This one for example.

## Next steps

The next step is, of course, cobbling together a prototype. And in order to do that, I will:

• Get the GSM module working: find a suitable SIM, figure out how to send and receive SMS'es and get HTTP GET and PUT working using GPRS.
• Verify that the GPS module works.
• Create block diagrams for hardware and firmaware (i.e. identifying components and dependencies)

Stay tuned…

## LPC ARM USB CDC

2. August 2012 12:55 by Jens Willy Johannsen
Categories: ARM | Tags: , ,

…the unabbreviated title would be very long :)

Anywho, this is just a quick post to link to my Github project which contains firmware for using an LPC11U24 as a USB "communications device" – i.e. a serial port.

At the moment, it simply writes input from the serial interface to the USB and vice versa. So you can connect the device to a computer with both USB and a serial cable (I use a serial-to-USB cable since I have no "real" serial ports on my MacBook Pro) and then open terminal connections to both interfaces (using "screen /dev/tty.xxx 9600" or something similar) and everything typed in one window gets written in the other window.
There's probably a couple of debugging messages as well.

The project is based on NXP's example code found here: http://www.lpcware.com/content/nxpfile/usb-rom-driver-examples-using-lpcxpresso-lpc11uxx and compiles with the Yagarto toolchain.

## Why?

Why would I want to do USB connectivity by way of CDC instead of e.g. HID? Because implementing HID functionality in Mac OS X applications is a pain in the ass, that's why.
Serial port connectivity, however, is so very much simpler. Especially if you use the excellent ORSSerialPort library.

## Where?

Right here: https://github.com/jenswilly/LPC11U24-USBCDC

## From AVR to ARM

27. July 2012 23:23 by Jens Willy Johannsen
Categories: ARM

It seems more and more people are moving away from using AVR and PIC microprocessors and switching to ARM processors. So I thought I might take a look as well.

I'll skip the usual intro stuff about ARM (read about it on Wikipedia or somewhere). For my purposes, the ARM Cortex-M series which is the "Microcontroller profile" is what's interesting. The general sentiment is that the 32 bit ARM Cortex-M MCUs are better and faster the 8 bit AVR and PIC processors and have support for more peripherals. The only real disadvantage is that there are no ARM processors available in DIP packages for easy prototyping. Although I must add that another disadvantage is that there are a lot more code examples etc. available for AVR and PIC compared to pretty much any ARM processor.

## Choice of processor

It looks like the Cortex-M0 and Cortex-M3 are what I'll be using. The M0's are best suited for low-power (as in battery powered) systems while the M3's are faster with higher performance and support for more peripherals.

There are several manufacturers of ARM Cortex-M0 and -M3 microprocessors. Among them are:

• Atmel (SAM3)
• STMicroelectronics (STM32)
• NXP (LPC)
• Energy Micro (Gecko)
• TI (Stellaris)

It seems like the SMT32 and the LPC series are the most widely used. At least those were the devices I found the most information about. For now, I have chosen the NXP LPC series as my ARM of choice because:

1. I can find enough information about them (mind you, there are nowhere near as much info and examples for ARM MCUs on the Internet as there is for the 8-bit AVR or PIC MCUs).
2. They are cheap.
3. They are readily available (meaning they are in stock at RS).
4. It looks like it there is a Mac OS X compatible toolchain.
5. Some of them have nice on-chip USB bootloaders.

… but in all honesty I could probably have picked any other from the list and never known the difference. Just like PIC vs. AVR or Canon vs. Nikon. So just pick whichever one you fancy that looks like it'll do the job and learn how to use it. I chose NXP's LPC series.

## mbed

The mbed is a development board with either a LPC11U24 (Cortex-M0) or LPC1768 (Cortex-M3). It is built on a board with two rows of 0.1" pins suitable for mounting on a breadboard. The mbed is kind of like the ARM equivalent of AVR's Arduino: it is easy to program and has wrappers for most hardware and peripheral functions. The IDE and compiler are web-based so you write all code in a browser-based editor and download the compiled binary file. The mbed can be attached to the computer (Mac, Windows or Linux) by a USB cable and will appear as a USB mass storage device (aka "a disk"). Firmware is flashed by copying over the binary file to the USB disk and resetting the mbed.

Code for the mbed is written in C++ and uses libraries for hiding all the hardware register stuff. An example program for flashing a LED (really, really fast) looks like this:

```#include "mbed.h"

DigitalOut myled(LED1);

int main() {
while(1) {
myled = 1;
myled = 0;
}
}
```

But it is also possible to forego the `mbed.h` libraries and use straight-up ARM C code in the mbed online IDE. Which appeals to me because I would like not to be tied to the mbed hardware and libraries so I can make my own ARM-powered devices. Here's how the same code might look in non-mbedified code (which still compiles fine in the mbed IDE):

```#include "LPC11Uxx.h"

int main(void)
{
LPC_SYSCON->SYSAHBCLKCTRL |= (1>> 6) | (1>> 16);
LPC_IOCON->PIO1_8 = 0x00000080;
LPC_GPIO->DIR[1] = 0x00000F00;

while( 1 )
LPC_GPIO->PIN[1] ^= (1>> 9);

return 0;
}
```
1 comment »

## Flashing LPC11U24 or LPC1343 from Mac OS X

27. July 2012 22:53 by Jens Willy Johannsen
Categories: ARM | Tags: ,

Here is how to flash an LPC11U24 or LPC1343 from Mac OS X using the ROM-based USB bootloader.
This post is just code snippet-style and I'm assuming you have a compiled .bin file and have the MCU connected with a USB cable so a disk named "CRP DISABLD" appears on the desktop.

2. In Terminal do
`\$ df -h`

to identify the filesystem device that is mounted as the CRP DISABLD disk. It will be something like "/dev/disk1" (which I will use in this example).

3. Unmount the disk using
`\$ diskutil unmount /dev/disk1`
4. Copy binary file to device using
`\$ dd if=firmware.bin of=/dev/disk1 seek=4`

This is where the tricky stuff happens. In order for everything to work we must write data beginning at sector 4. And if we just copy the file in the Finder the OS will start at sector 6.

## IR Remote working!

23. June 2012 13:51 by Jens Willy Johannsen
Categories: Projects | Tags: , ,

Yessiree!

It works! Pretty darn well in fact!

Although I did have a couple of minor problems when I had assembled the board.
First, I could not connect to the BLE112 module with the CC Debugger in order to load firmware onto the Bluetooth module. Not so good... I spent quite some time tracing the connections of the programming header and the BLE112 module and comparing with the prototype but everything seemed to match so I feared I had a malfunctioning BLE112 module. Which would bad since those are by far the most expensive part and not easy to unsolder – in fact, it would probably require ordering more parts and building a completely new board. However – a bit more connection tracing, this time at the pins of the 2.54 to 1.27 mm adapter board attached to the CC Debugger, revealed that there was a faulty ground connection. It looks like it's the pin on the programming header itself that has a poor connection. Fortunately I can fix this by making a temporary green-wire fix (by temporary I mean hand-held) while programming the module. Whew!
Then came the next problem. I had actually discovered this when I was assembling the board: I had forgotten the 4k7 Ω pull-up resistors for the I2C interface of the EEPROM! Doh! And it turned out that the ATmega couldn't communicate with the EEPROM. This was easily fixed, however, by simply activating the ATmega's pull-ups for PC4 and PC5.

With the problems fixed, everything worked like a charm. With all IR LEDs in place the range is excellent (tough I have yet to see if I can control the neighbors' TV sets :). And it looks just awesome in its laser-cut acrylic case with countersunk screws and threaded insets (so no screw heads or nuts protrude from the case).

There is still a bit of iOS app programming remaining, like converting the app to a universal app so it'll run on iPad as well as iPhone.

Enjoy the pictures – click for full-size version:

## IR Remote Enclosure

3. June 2012 20:52 by Jens Willy Johannsen
Categories: Projects | Tags: , ,

While the PCB is getting made, I've done some work on the enclosure.

It is being made from five layers of 5 mm transparent acrylic from Ponoko.The layers are held together by M3 countersunk machine screws. While the front and middle layers have 3 mm holes for the screws, the rearmost layer has 4 mm holes for fixing the screws by using threaded insets. The rearmost layer also has three holes for mounting the PCB. The PCB will also be mounted with M3 screws into threaded instets and lifted a bit off the back using nylon spacers (which I need since there are a couple of through-hole parts).

The opening in the bottom of the middle layers are for the DC power plug.

Here are some rendered images:

(Click for large versions.)

And here's a short animation – click to play video:

## Multi-remote App

31. May 2012 0:26 by Jens Willy Johannsen
Categories: Projects | Tags: ,

I've done some more work on the app. It is now possible to configure the user interface by way of an XML file. At the moment modifying the XML file requires building the app again but this will be changed so the XML file can be downloaded and uploaded from within iTunes.

The XML file specifies a number of "pages" (in the screenshots I have two pages: "TV" and "Channels"). The user swipes sideways to navigate between the pages.

Each page has a layout that specifies how large the buttons are and where they are positioned. Right now the app only supports "medium buttons" (3 x 4 buttons) and "large buttons" (3 x 3 buttons) but more will be added.

Each button position on a page can be left empty or hold a button. A button is configured with an ID (the command ID used – thus the same command can be sent from more than one button), a color (which sets the button's background image), a text and a mode. Mode is either "normal" (command is sent on touch up), "touchdown" (command is sent on touch down) or "repeat" (command is continously being sent as long as the button is pressed).

View a sample configuration file here.

Screenshots – click to see full screenshot:

## PCB test

29. May 2012 22:45 by Jens Willy Johannsen
Categories: Projects | Tags:

The PCB for the BLE multi-remote is done and it looks like everything fits. Except for the 10 µF capacitor (left side, middle) where I've used a C instead of B sized footprint. This is why you should always print out a 1-to-1 sized version of the PCB and place the actual components on it (never mind the values, of course, as long as the correct packages are used):

(Click for large version)

Oh, and if you can't find the TSOP34838 IR receiver anywhere then that's because I forgot to include it in the schematic and board… I just realized that. Doh!
Anyway, it's been added where C7 (bottom-middle) is now and C7 has been moved a bit to the left and up and rotated 90°.

## Problems with timing

29. May 2012 22:31 by Jens Willy Johannsen
Categories: Projects | Tags:

I've run into a few problems with the AVR firmware. (The GitHub repository for which is located here.) Recording of IR signals works fine and the values I record correspond nicely to the theoretical reality ("theoretical reality"?). If you can't remember the protocols and timings, you can find a great explanation of the various protocols here.

But – when I send the signals they are too long (as recorded by my oscilloscope connected to the output pin of the MCU which controls the IR LEDs).
My first approach was:

IR_HIGH;
_delay_us( high_duration );
IR_LOW;
_delay_us( low_duration );

First I tried simply subtracting a "trim" value from each recorded duration. Which almost worked. But the necessary trim value became so high that, for short durations, the total delay became less than zero microseconds (which, of course, was interpreted as a really high number instead). And even if I clamped the delay values so they couldn't be less than zero, the pulses were still too long.

So instead I now use the 16 bit TIMER1 (TIMER0 is used to generate the 38 kHz output to modulate the IR signal). I configure the timer for CTC mode with the same duration as when sampling IR signals. When learning signals I increase a counter (16 bit resolution) to record the pulse as a number of "sample intervals".
Now when sending, I simply use the raw recorded counter value and decrease a counter on every compare match of the timer. When reaching zero, I toggle the IR signal and reset the counter to the next value in the recorded sequence. When I reach a counter value of zero I stop the timer and the signal is complete.

And a whole 'nother thing is that I've been running the MCU on 3.3 V at 16 MHz. Which according to the datasheet (section 28.3 Speed Grades) is out of spec. Sure, it may well run fine but in this case where timing is crucial I had better throttle it down to 12 MHz which is inside the Safe Operating Area.

And lo and behold – everything works!

## PCB layout

20. May 2012 22:27 by Jens Willy Johannsen
Categories: Projects | Tags:

The first revision of the PCB layout for the multi-remote project is done. Mind you, I always go through a couple of revisions before getting it manufactured (because I always mess something up in the first few attempts).

You can see a zoomable version of the PCB layout on my Solderpad project page.

1 comment »

## Four buttons and a MOSFET

12. May 2012 21:28 by Jens Willy Johannsen
Categories: Projects | Tags:

I've made a couple of upgrades to the iPhone app: it now has four command buttons as well as "Toggle debug window", "Record IR" and "Scan for devices" buttons. The command buttons and the Record button are only enabled when a device is connected. And the Scan button is only visible (replaces the Record button) when no device is connecte

The app now starts searching automatically when becoming active. If it discovers the last device it was connected to, it connects immediately. Otherwise, it shows a list of devices and lets the user pick a device to connect to. Only devices that advertise the correct service UUID are listed.

The UI also got a little upgrade – it's still just a prototype, mind you...

Icon:

Screen shots (click for full-size version):

MOSFET

Also, I've added a MOSFET (IRL1404 – for the PCB version I'll use a IRLML2502) to drive the IR LED with more power. Before, the LED was just driven directly from a MCU pin (which, as everyone knows, is bad form). Now, the MCU pin is connected to the gate of the MOSFET (logic-level) which turns on the LED and current limiting resistor for 100 mA in a common-source configuration.

As expected, the range improved tremendously. And I'm still only using one wide-angle LED.

## Prototype working

9. May 2012 21:14 by Jens Willy Johannsen
Categories: Projects | Tags:

I have gotten a prototype assembled and working. So far, I've got the following working:

iOS app

• Connect and disconnect to devices advertising a specific service UUID
• Automatically connect if a known device UUID is found
• Read RESPONSE attribute (although it is not used for anything at the moment)
• Send commands by updating the COMMAND attribute
BLE112 module
• Send commands  to the MCU over serial USART when the COMMAND attribute is updated. (Only the command type is sent now – the sequence ID is not yet included.)
• Commands are also sent to the MCU when a client device connects or disconnects (which is ignored at the moment).
MCU
• Record an IR signal and store it in the EEPROM.
• Playback the IR signal stored in EEPROM (or a hardcoded test sequence).
• Write the stored IR signal to serial for debugging.
• Respond to commands received on the serial line and trigger recording, playback or one of the debugging commands.

And it works! I can switch my television on and off from my iPhone :)
Next step is to use both high-intensity and wide-angle IR LEDS and to drive them at much higher power (right now the one wide-angle LED is being driven directly by the MCU – which you should never do).

Here is a picture of the prototype in all its glory:

(Click for full-size version.)

And here is another picture with the individual parts labelled:

(Click for full-size version.)

1 comment »

## IR codes and storage

7. May 2012 20:27 by Jens Willy Johannsen
Categories: Projects | Tags:

Here's some notes on how to store IR codes for the IR controller project:

If I were using pre-programmed codes in a few known formats (like RC-5 or NEC1) I could store the commands using just the two or three bytes that actually make up the sequence. For example, a NEC sequence consists of one address byte and one command byte (although it is sent as a lead-in followed by four bytes).

But mostly I will need to record IR signals and store those. The proper way of doing it would probably be to parse the recorded signal, identify the protocol and store the required few bytes. But that sounds like way too much work. So instead I'll just be storing the time intervals for on-off pairs. I would like to use one byte for each time code and if I use 100 µs resolution I will get from 0.1 ms to 25.5 ms in .1 ms intervals. I think that might be good enough – but time will tell :)

Storage

Firstly, an ATmega328P has only 1 KB of EEPROM storage. And most likely, that will not be enough. So I'll be using an external EEPROM chip. The "24C" series seems to be very widely used and uses a simple I2C protocol. So something like Microchip's 25LC512 seems suitable (512 Kbits, 3.3 V and is available in both DIP and SOIC packages) and will give me an extra 64 KB of non-volatile memory. I'm thinking that will be enough.

The IR codes will have differing lengths. And the correct way of storing those in the EEPROM would involve some kind of allocation table and stuff in order not to waste memory space. But instead of messing around with all that I've decided to go for a super-simple solution there every IR code uses a fixed size (like 128 bytes – something that is a whole multiple of the EEPROM chip's page size). That way I can easily access the code for a specific index.

The data will be in raw time-on, time-off format and terminated by a 0 value (since a 0 ms pulse will never occur).

Thus, for my LG television which uses the NEC1 protocol, an "off" command (address 0x04, command 0xC5) can be stored like this:

90, 45,
06, 06, 06, 06, 06, 17, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06,
06, 17, 06, 17, 06, 06, 06, 17, 06, 17, 06, 17, 06, 17, 06, 17,
06, 17, 06, 06, 06, 17, 06, 06, 06, 06, 06, 06, 06, 17, 06, 17,
06, 06, 06, 17, 06, 06, 06, 17, 06, 17, 06, 17, 06, 06, 06, 06, 00

For a total of 67 bytes for a code that basically consists of two bytes! Way inefficient, I know, but it's easy to use.

Using a size of 128 bytes for one IR code will accomodate codes of up to 64 IR pulses and I will be able to fit 512 codes into the EEPROM – and that should be more buttons that I'll ever need. (Maybe I will need to up the size to 256 bytes – we'll see.)

1 comment »

## BLE112 prototype

4. May 2012 15:11 by Jens Willy Johannsen
Categories: Projects | Tags:

I've made some progress on the BLE112 module. So far, I have:

• Got it wired up in the most basic configurations (VDD, GND, debugging and RESET and TX/RX for UART1, alternative 1 and UART0, alternative 2).
• Got the CC Debugger working.
• Created a project consisting of a hardware setup specification, a simple GATT specification and a BGScript.
• Created an iPhone app that scans for Bluetooth LE devices with the required service UUID, connects to a peripheral and finds the two required attributes (one for sending commands to the BLE112 and one for reading responses).

So far, so good. But I've run into a small problem: I can send serial data from the BLE112 (in response to a startup event or when an attribute changes its value – like when the iOS app writes a value to the command attribute) but I can't seem to receive serial data on the BLE112. Everything should be configured correctly (I think) but the event handler simply doesn't get called in the BGScript.

Maybe the port needs to configured differently. Or maybe I will give up and try using SPI instead and see if that helps.

However, since the BLE112 is used only to receive commands from the iPhone and pass them on to the MCU (like "send IR code such-and-such"), I may not even need to send data from the MCU to the BLE112...

I'll do some more troubleshooting and see if I find a solution.

(It seems I'm not the only one with this problem.)

## Trying to get hold of a Bluetooth LE module

26. April 2012 21:23 by Jens Willy Johannsen
Categories: Uncategorized | Tags:

For the remote control project, I'm still undecided on whether to use Wi-Fi or Bluetooth LE for connectivity.

Bluetooth LE is still a quite new technology and there aren't many manufacturers of Bluetooth LE chips and modules. Read this article for a good guide to the availabe chips and modules (most of which seem to be based on TI's CC2540 chip).

There's no way I'm going to mess around with the chip itself – impedance matching of the antenna trace and shielding and whatnot are better left in more capable hands. So I'll be using a complete module. And Bluegiga's BLE112 seems nice: it's based on the CC2540 and there's plenty of documentation on Bluegiga's Tech Forum (you need to register to access the documentation which if both free and easy – no NDA's or anything).

However… There are not a lot of distributors of the BLE112. Mouser has it. But it "may require a licence to export from the United States". But I went ahead and ordered a couple of BLE112 modules and a CC DEBUGGER (which is necessary for configuring the BLE112 module).
It turns out that Mouser was not able to export the CC Debugger to Denmark and for the BLE112 I had to fill out an "Customer End-User Certificate" so they can decide whether I'm eligible for getting my hands on that kind of technology or not. (Strangely enough, Bluegiga is based in Finland which is practically Denmark's next-door neighbors.)

I did, however, manage to get a CC Debugger from the Danish branch RS Components instead (since they ship from Europe there is no export hassle) and I'm still waiting to hear from Mouser…

1 comment »

## IR Remote Control project

24. April 2012 22:33 by Jens Willy Johannsen
Categories: Projects | Tags:

For my day job, I develop iPhone apps. Fairly often people are interested in developing an app that interacts with some sort of hardware device. Usually the setup they envision is not feasible, sometimes it's nowhere near possible. But I digress...
To demonstrate one possible iOS-to-hardware setup, I made a small prototype consisting of a GainSpan GS1011MIE Wi-Fi module, an ATmega328 and a LED (if you understand Danish or know how to use Google Translate, you can read about it here.)

Wanting to build something slightly more useful than remote controlled LED, I came up with the idea of a remote controlled IR remote control (yeah I know, "remote controlled remote control"). Specifically, a remote control that can control everything from TV, DVD, Apple TV and set-top box which is controlled from an iOS app.

Initial ideas in no particular order include: