Dead cheap li-ion charger – TP4056


There’s a chip called TP4056 that’s quite good for charging li-ion/li-po cells. You can buy the chip really cheap, or like above – a finished board with usb power in for $1.50 (!) on ebay including shipping. I bought one, soldered on a couple of silicon wires with magnets attached to the end. Also added a plug-able tiny voltmeter (ebay, but this other one from fasttech also looks quite good). I’m not sure how the voltmeter affects the charging (as it feeds off the charging current), but I recon it should be quite fine.

Resistor valuesPer default it uses 1 amp of charging current, which is quite good for large cells, but you can modify it by changing one of the onboard resistors – lower values and you can use it for smaller cells safely.

It’s quite a decent little charger, it manages pretty close to true CC/CV (constant current / constant voltage). It does get a bit hot when charging at 1 amp, especially in the start when the voltage difference between input and output is large, but nothing too worrying.

Termination seems to happen according to spec – just around 4.20 volt.

All in all – quite happy with it. I recon the chip (or even the board) could easily be built into projects that need li-ion/po charging, or even into a battery pack. Can’t beat the price! 🙂

Building a home automation system – The broker and sensors (Part 2)

Every now and then (when I have time..) I do a bit of work on what’s going to become my home automation system. At the moment it’s pretty basic, it’s simply events going over a message broker that small stubs of code react to. Most of it runs on my raspberry pi and a few jeenodes (atmega328 + hoperf rfm12b radio) as wireless sensors.

Everything connects to a simple message broker built on ZeroMQ – and I love it! ZeroMQ is so great to work with, it takes most of the hassle of network socket programming away leaving you to concentrate on what really matters. There is no daemons to deal with (as with most other message buses), it’s lightning fast, but doesn’t really handle persistant messaging.

At the core of the system I have this running on my raspberry pi:


It’s very simple – just two ZeroMQ sockets – one running in a push/pull configuration, another running in a pub/sub configuration. A relay for my sensor nodes will connect to it and push it JSON formated data from the different sensors located in my apartment.

"nodeid": 2,
"temperature": 2.19,
"voltage": 335,
"counter": 1215,
"event": "sensor",
"timestamp": "2012-09-24T15:49:28.369Z",
"location": "refrigerator"
"nodeid": 3,
"temperature": 23.5,
"voltage": 369,
"counter": 20,
"event": "sensor",
"timestamp": "2012-09-24T15:52:08.450Z",
"location": "livingroom-bookshelf"

The broker will relay events such as these, the two examples are wireless sensor nodes located in my refrigerator (currently holding 2.19C and battery voltage of 3.35v) and the other one in my livingroom bookshelf (2.19C and 3.69v). The broker will receive these (and others), and send them out to subscribers of sensor events. It makes it really easy to make something that reacts to the temperature, you can connect to the broker and subscribe to sensor events in 2-3 lines of code in most languages. Example:


As you can see, it would be very simple to expand this and create something that let me know if a battery of a sensor was running low. Or something that would PID adjust a heating source in the living room. Or something that would warn me if temperature in the fridge was running high.. or.. or.. or.. Beauty of it is that you don’t have to think about network stuff like disconnects..

I’ve made a small program in C# running on my HTPC that registers a few global hotkeys. If I press ctrl-alt-o then a small event will be sent out from the C# program, to the message bus, to everyone that subscribes to “receiver” events. There is a small program that does this and relays the message to a microcontroller, which in turn talks to my Pioneer VSX-2016av surround receiver via the SR bus I talked about in an earlier post. For example, sending events like these to the broker will toggle the power of the surround receiver and turn the volume up 5 steps.

"event": "receiver",
"action": "power"
"event": "receiver",
"action": "volumeup",
"count": 5

Quick example above, sorry for the camera shake.

It’s getting there, now I have sensor data and control over the surround receiver. The next steps will be to expand the available sensor data – I wish to add a DHT22 Humidity sensor and also a light sensor (LDR?) to the sensor nodes soon. And also maybe PIR (passive ir). I also need to add control over power soon (lighting and heating).

At the moment they are only using a DS18B20 temp sensor. When I have all the components in place I’ll make a small PCB with room for all the components, the radio and a smaller atmel microcontroller. Currently they take up a bit more space than needed.

Pioneer SR-Link control

I have a decent (but aging) surround receiver connected to my HTPC – a Pioneer VSX-2016av. Because of it’s age it really doesn’t have any good ways to control it from a PC (USB or even serial).

As part of my home automation setup it would be great to be able to control some of the features on the receiver. Volume up, volume down, power off, power on, etc.. Most of the time I use a wireless keyboard as an interface to my HTPC (running XBMC) – and the remote control for the receiver is only really used for volume control. Would love to be able to control these directly from the keyboard.

I’ve tried to control this receiver via IR, and actually set up a microcontroller to record the IR signal from the remote today. After decoding the modulated (38 khz) pulses I was able to play back the same signal and do stuff on the receiver from a microcontroller via IR. This could work.. but you actually have to point the IR diode more or less directly at the front of the receiver – reflections doesn’t work (maybe I could try a more powerful LED?). Was thinking about mounting the LED directly on the receiver, but it looks ugly 😦

Then I noticed the SR-link (in and out) ports on the back of the receiver. It’s a system Pioneer (and some other companies?) use for linking hifi/video equipment. You can use it to relay IR control and even transfer configuration options (in SR+). So I hooked up a microcontroller to the SR input port – you can use a mono 3.5″ jack – signal is on the middle pin. Ground can be taken directly from the chassis (shield on RCA-port for example).

Spent a while experimenting with this, by listening to the SR-output port while using the remote control. The signal is high (5v) as default, and pulled low on every IR pulse. Tried to replicate this using a microcontroller connected to SR Input on the receiver – wasted a lot of time beliving the signal should be 38 khz modulated – just like IR – but alas – no need for modulation – it won’t actually work if you modulate. Finally got it working – awesome! Now i can control my receiver from a microcontroller.

My goal is to get this directly connected to a Raspberry PI (which is going to be the HUB of my home automation system). If I can I really want to skip the microcontroller – and do it directly from the rasp-pi. I ported my microcontroller code to the PI, but it seems that I can’t get the timing accurate enough (running in userland).

Microsecond timing accuracy is a bitch in linux, I guess I could do this in kernel space – but that’s a lot of effort. Guessing I’ll probably have to go the microcontroller route. Also wish I had a decent scope, so that I could see how much jitter I’m dealing with here.

WR-703N External Antenna Mod (DIY)

UPDATE: Don’t do this mod, there are better techniques. Example: Solder directly to PCB antenna, or trying the J4 bridge mod as described here:

Maybe you’ve heard about the TP-Link WR-703N router? It’s a small “pocket”-router with wlan, 1x lan, 1x usb, Atheros chipset, 32 mb ram, 4 mb flash. It can run OpenWRT, and it’s really really cheap ($23 on ebay currently). They require very little power to run (100ma ish) and are powered via a micro-usb connector. And they have great hack potential (come on.. $23 for a linux thingy with lan, wlan, usb, gpio, etc..). You can upgrade the flash memory to at least 8 Mb, and even upgrade RAM to 64 mb if you have access to a hot air rework setup.

I’ve received two, and have just ordered a third, and have quite a few projects I want to use them for. Battery powered mesh network is one, great for getting networking in weird locations, they can run for many hours on a single 18650 battery. Also thinking about using one for a “umbrella warning sign” near the front door (I live in Bergen (Norway), a city with over twice the annual precipitation of the “Rain City” Seattle). A simple laser cut acrylic umbrella logo with the router’s pcb behind – using GPIO to drive a LED if rain is expected the next 8-10 hours.

Ebay link (be sure to buy the blue version!)

The routers have a tiny internal PCB-antenna, so on one of them I’ve added an external SMA connector. There are several ways of doing this, one is to solder the new antenna connector to the top of the existing PCB-antenna. A chinese website (google translate..) suggested desoldering a capacitor “upstream” and connect to the pads it used. I tried this, but will try both to see which works the best later.

Buy a SMA connector on Ebay with pigtail. Pry the blue cover off the router. Extract the PCB. Locate C114 on the backside. Desolder it (easiest is to place the soldering iron parallel to the capacitor so that you’re heating both pads). Solder the antenna core to the pad closest to the flash memory IC. Solder the antenna shield to the other pad (see image above). Cut the existing PCB antenna track.

Use a 6mm drill bit to make a suitable hole for the antenna connector (make sure there is room for the PCB under the connector).



Sous Vide (french for under vacuum) is a cooking technique where food is sealed in airtight plastic bags and submerged in a water bath held at a specific temperature. Cooking sous vide usually takes a long time, but it has the advantage that the food is cooked perfectly evenly, you are able to heat a steak to the exact same temperature through out the entire piece of meat. A cut through a normal steak cooked on a pan usually reveals a gradient going from brown/gray to pink/red in the middle – less heat penetrate to the middle, so when the inside is medium rare the outside is usually well done++. A cut through a sous vide cooked steak looks more like the above – constant color and consistency through out the entire steak (the steak is normally finished (very quickly) in a frying pan to caramelize and kill any surface bacteria). The result tastes really great, and it’s hard to mess up – you can leave a steak in the water bath for hours without any problems. Cooking in a bag preserves so much of the moisture in the meat, and the long cooking time breaks down a lot of the connective tissue – leaving you with a perfectly cooked steak that is super-moist and tender enough to eat with only a fork.


Sous-vide BabyTop

Photo by FotoosVanRobin – CC BY-SA 2.0


A professional sous vide setup costs at least >$1000, so it’s a bit out of reach for the normal home cook – except for the DIYers.. It’s not that hard to build yourself if you put your mind to it. What you need is the following components:

  1. Water bath with a electric heater.
  2. Some method of circulating the water.
  3. A way of accurately regulate the heater based on water temperature
  4. Some way of plastic bag packing you meat.

Water bath with heater is easy enough, there are tons of items out there that does this – slow cookers and rice cookers for example. I use a simple rice cooker, the cheaper/simpler the better (we’re going to cycle it’s power on/off, a dumb cooker will behave better facing a power loss). To circulate the water I use a simple ebay aquarium pump (payed $9.90 for mine). To pack the meat in airtight bags you can either buy a cheap vacuum-packer or simply use zip-lock bags (fill your sink with water, add meat to bag, submerge bag in water but keep the opening above waterlevel – pressure from the water will press out all the air, seal the bag..) 

That’s the easy part, the hard part is regulating the heater to accurately hit a specific temperature. A simple thermostat won’t do, because of the long dead time in such a system – you end up with a cycle overshooting and undershooting the target temperature – this is a job for a real PID controller (proportional–integral–derivative controller)

A PID-controller monitors a system and tries to bring it to a specific state by providing a output value. For example, monitors the temperature of a water bath and tries to bring it to exactly 60 degrees celcius by regulating a heater. The forumula consists of three terms, first the gain – how hard to press the pedel to accelerate to a certain speed based on the current speed. The second part is an integral, looking back, how fast where we changing when we applied this much pressure to the pedal in the past.. Third term is a derivative trying to predict the future, when do I need to stop accelerating to be able to make the next turn.

Implementing such a formula seems straight forward and only requires a few lines of codes – but there are surprisingly many things to concider and special cases to deal with when implementing it – read more about it at Brett Beuregard’s blog. Brett has made a nice library for atmel microcontrollers (arduino based), you can find it here: PID v1.

So what I have done is to make a microcontroller based PID controller. It’s based on an Atmega 328p chip running the arduino bootloader, it has three buttons and an 4×20 character LCD to handle user interaction. And a DS18B20 one wire temperature sensor to meassure the temperature of my water bath and a SSR (Solid State Relay) to cycle the power of the rice cooker on and off.

It’s a fairly simple build, all of the components can be bought cheaply on ebay or electronicsshops like futurlec.

If the video doesn’t work, click here: 

See schematic and pictures of the setup below:

Bill of materials:

  • Atmega 328p (futurlec)
  • 3 Buttons (ebay)
  • 20×4 LCD (ebay)
  • Solid state relay (ebay – Futek) – you might need a heatsink, i use the metal plate in my enclosure.
  • Contrast potmeter
  • LED
  • 16 mhz crystal / ceramic resonnator
  • Basic resistors, capacitors, transistors
  • Enclosure, preferably with metal backplate (ebay..)
  • 220 IEC input and output sockets (futurlec..)
  • DS18B20 temperature probe (ebay..)
  • Stripboard (ebay)

In total I think it cost me around $30 to build it (not including the pump and rice cooker), not too bad. You could easily make it cheaper by using simpler items – do you really need a 20×4 LCD? 

The source code is available at Bitbucket, please feel free to use it for whatever you want:

Note that the schematic doesn’t include power curcuit and programming headers.

I’ve built the controller into a simple case (w/ metal backplate) I found on ebay. If you have a powerful heater you should concider adding a heatsink to the SSR, they can get hot when switching large currents. With the metal-backplating, my 350W rice cooker never even make the SSR go above room temperature. See pictures of the case and setup below:

Future work:

  • It needs a bit of calibration (the gain, integral and derivative) to avoid initial overshoot and small ocillations when changing load.
  • Add bluetooth, I have a small bluetooth to ttl module I can connect to get wireless serial (to interface it with pid controller gui)
  • Add internal power supply, should be enough space in the box for a 5v transformer.

Stay tuned for more posts on how to calibrate the beast 🙂

Also, check out eGullet for more information about cooking Sous Vide (temperature tables.. recipes.. safety concerns..)

MSP430 Coffeetimer

The MSP430 is a familty of cheap microcontrollers from Texas Instruments featuring ultra low power usage. TI offers a devkit with everything you need to get started (USB-based development board and 2 microcontrollers from the value line) called the MSP430 Launchpad. The killer – it’s dead cheap – $4.30 for two microcontrollers and the launchpad including shipping (fedex!). You can also probably manage to get a few MCUs for free as samples. TI is probably selling the kit at a loss really trying to get into the hobbyist market, which is primarily dominated by the Arduino (and to a lesser degree Atmel in general and Microchip Pic). I was very impressed by the power usage, a guy managed to run them for 10 weeks as a clock on a couple of capacitors (granted – 10F caps).

Anyway, I have a 1 hour safety timer connected to my coffee maker (one of those devices that tick down and cut the power after one hour). Being a really cheap device from a low cost “wallmart” like shop I guess it was no surprise when it broke. It doesn’t tick down anymore, seems like the motor burned out – it’s mostly mechanical with a disc rotating one revolution and then cut the power by physically hitting a switch. I liked having the extra safety this device provided – and wanted a new one. Figured it was a good chance to learn some MSP430 programming. Turning the coffee maker on and off using a relay would be pretty simple, but I really don’t want to fuck with 220V mains and leave it without supervision (which probably also voids my home insurance).

I have a few radio controlled Nexa power switches (which are CE certified), so I hooked up one of the MSP430 microcontrollers from the launchpad kit to a remote with a few transistors. Programmed the microcontroller to sleep and wait for a interrupt from small push button, on interrupt it turns on the coffee maker (via the remote – connected with two transistors) and starts a timer. The timer blinks a led every now and then before turning off the coffee maker one hour+ later. Put the whole thing in a small ikea plastic container with 2 AA-batteries, which should last severals years if the MSP430 is as power efficient as they say.

There’s a few gotchas when programming the MSP430s, for example the watchdog timer.. The MCU features a watchdog that resets the device after a short time (VERY anoying..), unless you disable the timer – it’s on by default. Other than that it was more or less straight forward. You can either use the supplied eclipse-based code composer from texas instruments (proprietary and windows only) – or the open source msp430-gcc toolchain (runs on both linux and mac).. Code written in the code composer will probably not compile using msp430-gcc, there seems to be different syntax for defining interrupts – and intrinsic functions often have different names and functions depending on which compiler you use. I’ve tried both, the TI software nicely integrates a debugger that can step through lines and instructions in the IDE as they are running on the chip – Spy-Bi-Wire (pretty awesome feature for a $4.30 pricetag). For the open source toolchain you can use mspdebug to open a network port where you can connect using gdb.. providing you with more or less the same features, but it’s way more cumbersome to use gdb than a IDE-integrated debugger.. But then again, I don’t often use a debugger (even for normal software – my method of debugging often involves throwing prints everywhere), so I guess having to not run the proprietary IDE in a virtual machine is worth the loss of the IDE integrated debugger.

Also, setting up the internal timers required reading quite a lot of TI documentation, more so than other microcontrollers I’ve tried. The community using it is also small and there are few libraries available. But anyway, got it running – and now it turns on and off my coffee maker.

In conclusion, I don’t think TI will make that big of an impact on the hobbyist market with this, the alternatives are easier to use, have better documentation, usefull libraries and less cumbersome development tools. But then again – it’s a really cheap way to get started on MCUs.

Posting the coffee timer code as a future reference, maybe some of the boilerplate code can be useful for others as well.

* Coffetimer (safetytimer)
* Activated when button (pin 4) is grounded.
* Connected to a RF - remote control on pin 5 and 6
* via a couple of transistors, controling the
* coffemakers power outlet.
* */

#include "msp430g2231.h"

#define LONGDELAY (1000000 / (8*8)) * 4
#define SHORTDELAY (1000000 / (8*8*8))
#define POWERONTIME 4500

const int redLed = BIT0;
const int button = BIT4;
const int powerOn = BIT5;
const int powerOff = BIT6;

volatile int powerActive = 0;
volatile unsigned int onTime = 0;
volatile int blinkState = 0;

unsigned int i, y;

void main(void) {


P1DIR = ~button; // Button is input, rest output..
P1OUT &= ~(powerOn | powerOff | redLed);

P1REN |= button; // Pull up
P1IES |= button; // High to low interrupt
P1IE |= button; // Interrupt on button..
P1IFG = 0; // Clear INT flag

// Use internal occilator as timer source.. / 8.. /8
BCSCTL1 = CALBC1_1MHZ; // Set range
BCSCTL2 |= DIVS_3; // Divder / 8 for smclk
TACTL = TASSEL_2 + MC_1 + ID_3 + TACLR; // Timer A, SMCLK src, up mode, divider / 8..

CCTL0 = CCIE; // capture/compare interrupt go!


while(1) {
powerActive = 0;
onTime = 0;

// Go to sleep, wait for button
P1IFG = 0;

// Waking up from button push..
// Blink and power on coffemaker..
for (i = 0; i < 4; i++) {
P1OUT ^= redLed | powerOn;
for (y = 0; y < 40; y++)
P1OUT &= ~(redLed | powerOn);

powerActive = 2;


// Waking up from timer.. blink and turn off coffeemaker..
for (i = 0; i < 12; i++) {
P1OUT ^= redLed | powerOff;
for (y = 0; y < 40; y++)
P1OUT &= ~(redLed | powerOff);


// Button interrupt
#pragma vector=PORT1_VECTOR
__interrupt void port1_isr(void)
if (powerActive == 0) {

// Power on coffeemaker..
powerActive = 1;

} else if (powerActive == 2) {

// Power off coffeemaker ahead of time..
onTime = POWERONTIME + 1;
P1OUT &= ~redLed;
powerActive = 0;

P1IFG = 0;

// Timer interrupt, blink twice every few seconds..
#pragma vector=TIMERA0_VECTOR
__interrupt void timera0_isr(void)
if (powerActive != 2)

CCR0 = (++blinkState % 4) ? SHORTDELAY : LONGDELAY;

if (blinkState % 2)
P1OUT |= redLed;
P1OUT &= ~redLed;

onTime += (blinkState % 4) ? 1 : 4;

// Wake from sleep if coffeemaker has been on long enough
if (onTime > POWERONTIME) {
P1OUT &= ~redLed;
powerActive = 0;