USB Power Sense Home Easy controller + basic Arduino UPS

Hi All - I've been working on this a solution to a problem I posted in Bar Sport (http://arduino.cc/forum/index.php/topic,69420.0.html)

Got this working today after my other TV troubles (see other thread) I was inspired to get it done.

It's a Home Easy based solution. It uses the following:
A Home Easy radio controlled socket (http://www.maplin.co.uk/remote-controlled-socket-kit-510546?ordercode=N11JQ)
A 433MHz radio transmitter (http://www.maplin.co.uk/transmitter-and-receiver-pair-22965)
A 1F super capacitor (http://www.maplin.co.uk/double-layer-capacitors-98185)
A 5v boost regulator (http://www.hobbytronics.co.uk/pololu-5v-boost-regulator?keyword=boost%20reg)
2 x 1N5817 schottky
A 470uF 16v capacitor
And finally - an Arduino Pro Mini (5v 16MHz) (Arduino Pro Mini 328 - 5V/16MHz

As usual, I stood upon the shoulders of giants and owe a lot to the work done by Ed on http://www.jellard.co.uk/ and the playground stuff on Home Easy

So the theory of operation is as follows - when the USB port on the device (TV) is turned on the Arduino powers up and the cap charges. The arduino sketch sends a power on command to the Home Easy socket. When the USB port is turned off (TV off), the capacitor provides the power via the boost regulator (this allows the cap to be drained to around 1v whilst still providing 5v for the Arduino). The voltage output of the capacitor quickly drops below the 4.88v trigger point. Once this happens the arduino detects it and sends a power off command to the Home Easy socket. It continues to do this once a second until it browns out.

setup:
set everything up

main loop
Check the voltage seen on the capacitor
if voltage is greater than 4.88v then instruct the Home Easy remote socket to turn on
if voltage is less than or equal to 4.88v then instruct the Home Easy remote socket to turn off

That's pretty much it. I think it's a handy device for a number of applications. Essentially anything with a USB port can instruct another device to be powered up when it gets power and vice versa and no messing with high voltages :smiley: It also has a reasonable means of giving an Arduino project a kind of UPS to allow it to shutdown gracefully. I get about 10 seconds of transmitting before things get strange, obviously - more capacitors in parallel would up this time. I know that the 5v and grounds take a weird route on my bread board - I'll put it all together properly on strip board tomorrow and box it up.

Code - for what it's worth. You'll be needing the Home Easy library

#include "HomeEasy.h"
HomeEasy homeEasy;
int onOff = 0;
bool bit2[26]={};
bool bit3[4]={};
bool hedevice[4]={};
int txPin = 6;
int pwrIn;

void setup(){
homeEasy = HomeEasy();
homeEasy.registerAdvancedProtocolHandler(processReceivedRemote);
homeEasy.init();
pinMode(txPin, OUTPUT);
Serial.begin(9600);
setHEDevice(0); //Set destination home easy device (first device, 0)
itob(410166,26); //Sender code from remote control - change this to match yours
}

void loop(){
pwrIn = analogRead(3);
Serial.print(pwrIn);
if (pwrIn>1000) {
  transmit(1);
  delay(10);
  transmit(1);
  delay(1000);
}
else {
  transmit(0);
  delay(10);
  transmit(0);
  delay(1000);
}
}

void processReceivedRemote(unsigned long sender, unsigned int recipient, bool on, bool group) {
Serial.print("Sender: ");
Serial.print(sender);
Serial.print("\nRecipient: ");
Serial.print(recipient);
Serial.print("\nOn: ");
Serial.print(on);
Serial.print("\nGroup: ");
Serial.print(group);
Serial.print("\n\n");
}

void transmit(int blnOn) {
int i;
// Do the latch sequence..
digitalWrite(txPin, HIGH);
delayMicroseconds(275); // bit of radio shouting before we start.
digitalWrite(txPin, LOW);
delayMicroseconds(9900); // low for 9900 for latch 1
digitalWrite(txPin, HIGH); // high again
delayMicroseconds(275); // wait a moment 275
digitalWrite(txPin, LOW); // low again for 2675 - latch 2.
delayMicroseconds(2675);
// End on a high
digitalWrite(txPin, HIGH);
// Send HE Device Address
for (i=0; i<26;i++) {
sendPair(bit2[i]);
}
// Send 26th bit - group 1/0
sendPair(false);
// Send 27th bit - on/off 1/0
sendPair(blnOn);
sendPair(bit3[0]); //MSB
sendPair(bit3[1]);
sendPair(bit3[2]);
sendPair(bit3[3]); //LSB
digitalWrite(txPin, HIGH); // high again (shut up)
delayMicroseconds(275); // wait a moment
digitalWrite(txPin, LOW); // low again for 2675 - latch 2.
}
void sendPair(boolean b) {
// Send the Manchester Encoded data 01 or 10, never 11 or 00
if(b) {
sendBit(true);
sendBit(false);
} else {
sendBit(false);
sendBit(true);
}
}
void sendBit(boolean b) {
if (b) {
digitalWrite(txPin, HIGH);
delayMicroseconds(310); //275 orinally, but tweaked.
digitalWrite(txPin, LOW);
delayMicroseconds(1340); //1225 orinally, but tweaked.
} else {
digitalWrite(txPin, HIGH);
delayMicroseconds(310); //275 orinally, but tweaked.
digitalWrite(txPin, LOW);
delayMicroseconds(310); //275 orinally, but tweaked.
}
}
void itob(unsigned long integer, int length)
{ //needs bit2[length]
// Convert long device code into binary (stores in global bit2 array.)
for (int i=0; i<length; i++){
if ((integer / power2(length-1-i))==1){
integer-=power2(length-1-i);
bit2[i]=1;
}
else bit2[i]=0;
}
}
void setHEDevice(int integer) {
int length = 4;
// Convert long device code into binary (stores in global sendDevice array.)
for (int i=0; i<length; i++){
if ((integer / power2(length-1-i))==1){
integer-=power2(length-1-i);
hedevice[i]=1;
}
else hedevice[i]=0;
}
}
unsigned long power2(int power){ //gives 2 to the (power)
unsigned long integer=1;
for (int i=0; i<power; i++){
integer*=2;
}
return integer;
}

Update - Just added an extra diode between USB 5v and the cap.

Great idea. :slight_smile: (But what happens when (if) you want to use the TV's USB for something else? .....USB hub I guess).

Wow this is a genius idea. I would love to see a schematic of how everything is wired up - would you mind sending it on?

I've got to try this one myself. Much cheaper solution than having Power Cell - LiPo Charger/Booster I've seen used elsewhere. Im thinking of having a unit that will announce when its started up and shut down - this solution would be perfect.