Make your own LED light bulb

Well, not exactly “make” more “re-fit” a failed cheap Chinese LED light. I’ve bought a fair few different ones on AliExpress over the last 18 months or so and, to be honest, haven’t been impressed by any of them. Everything is done cheaply and they don’t last any longer than cheap tungsten bulbs as a result. Typically, you have a metal film capacitor on the input, a full- or half-bridge rectifier, a “just about in spec” electrolytic capacitor on the output, a couple of resistors and then far too many SMD LEDs wired in series.

These particular large globe style bulbs have about 45 LEDs in series. That’s just asking for trouble as there’s no way they’re all identical in terms of the current they draw. Inevitably, one burns itself out and the whole thing is then landfill. Ok, they’re cheap, but there’s a reason for that.

The latest "failed" LED bub

The latest “failed” LED bulb

Above you can see the latest “fail” – the ringed LED is actually closed-circuit so that isn’t, whilst it’s a problem, the reason for the “no-worky” behaviour. I couldn’t be bothered doing any more testing so didn’t go on to identify the culprit LED.

Also in the picture are a few bits I’ve acquired – 5 x 1W LED beads, 5 boards to fit them on, 5 x AMC7135 350mA constant sink current regulators and the insides of a readily available Samsung wall-wart. My plan was to use the new components to build an LED bulb that should last for a long time (well, a very, very long time I would hope).

So, let’s make a start…

Mount LEDs, solder wires to "wall wart"

Mount LEDs, solder wires to “wall wart”

Mount the LEDs on the flat side of the board…

5 x 1W LEDs

5 x 1W LEDs

They’re just stuck on with hot glue – what can possibly go wrong 🙂 ?

Next, put the constant current drivers on the other side…

Add some regulation

Add some regulation

And then the guts of the wall wart

240Vac to 5Vdc

240Vac to 5Vdc

Pop in the housing…

Cram it all in...

Cram it all in…

Put the cover on to make it look just like it did before

Oh, look! A cheap Chinese LED bulb...

Oh, look! A cheap Chinese LED bulb…

Test:

Back in the garage

Back in the garage

The new bulb is the closest one. It’s “proper” white rather than any of that lame “warm white” – I don’t care if I have harsh lighting in the garage, I just want to see.

It’s probably not quite as bright as the “original” but it seems bright enough – haven’t checked it out in the dark yet but I’m sure it will be fine.

There’s a fair bit of work involved in doing this but if you cobbled together a fairly basic circuit board then you could eliminate most of the wiring and the LED boards. You’d also be able to conduct heat away from the LEDs properly – although a 30 minute test didn’t show any apparent heat issues.

All in, I’m pleased with that and I’ll replace the others with this alternative LED bulb when they fail.

Posted in Uncategorized | Leave a comment

Solar Garden Light switching

Solar cells have their uses – connecting to a “grid” for mass power generation isn’t one of them – but charging a battery to light up your garden with LEDs when it goes dark is. I was asked recently about how to switch on the LEDs when it went dark. That’s an interesting question as you could, obviously, chuck in an LDR and a small micro-controller and job done. But that’s boring and since I know I don’t know much about transistors I wanted to play with other ideas to try and learn something.

The first idea was to connect the battery voltage to the base of a PNP transistor.

Simple PNP transistor

Simple PNP transistor

 

That would switch on when the voltage from the solar panel dropped. What could possibly go wrong with that?

In this case, the transistor switches on when the voltage at the base is 0.7V less than the voltage at the emitter. If we assume we’re using a decent Li-ion battery then we’ll have 4V (say) at the emitter when the battery is fully charged. Assuming a 5V solar panel then we’ll start to switch on the LED when the panel voltage drops to around 3.3V and it will be fully on when it drops to 2.8V. That means it will be on in daylight since it’ll still be quite light to get 2.8V out of a solar panel.

So we can reduce the switch on voltage only by reducing the voltage at the emitter. But… that’s the battery voltage so we couldn’t then use that to drive the LED since it will be too low.

The next idea was to use “a few” Zener diodes in series to drop the battery voltage to something “sensible” at the emitter. We could then use the collector to drive the base of an NPN transistor. The NPN transistor would be connected to the LED and sink current when the transistor came on. The LED would also be connected to the battery so we’ll be able to fully drive the LED as long as we can sink enough current through the NPN transistor.

That circuit (ok, I’m very rusty with EagleCad) looks like:

Two transistor solar switch with selectable on voltage

Two transistor solar switch with selectable on voltage

So, we connect the emitter of the PNP transistor to one of the terminals 1-6 of the diodes to select with voltage we want to use as a reference.

For my test circuit, I measured 4.2V from the battery and the following voltages were available at the diode jumper:

Position Voltage
1 3.2
2 2.8
3 2.4
4 1.9
5 1.5
6 1.2

Cobbling this together was straightforward and, using a bench PSU in place of a solar panel, easy to test.

Switch board, battery

The battery has a cheap charging / discharge protection board attached (red LED indicates charging). The yellow/white wires represent the feed from the solar panel (also fed to the battery charging inputs). The orange jumper wire is set to supply a 2.4V voltage to the emitter of the PNP transistor.

The "solar panel"

The “solar panel”

With LED attached

With LED attached

When it done gone dark - "solar panel" unplugged

When it done gone dark – “solar panel” unplugged

So with 2.4V selected, what happens?

With the supply at 5V, the LED is off and the battery charger is charging.

At around 4.2V, the charging circuit is disabled and the LED stays off.

When the voltage reaches 1.5V the LED illuminates very weakly (we would expect 1.7V from the BC327 datasheet).  By 0.3V it appears to be fully on.

Now, the next value from our “diode ladder” is 1.9V which is a full 0.5V less than we had above. Switching to that as the emitter voltage means that the LED never fully turns on – it’s probably better to have it coming on a little too early then never getting up to full brightness.

Up above I said that “it appears to be fully on”. Let’s do some measurement rather than just relying on hand-wavy bollocks – none of that “post-normal” science bullshit here 🙂

Time to reach for the trusty μCurrent Gold and do some measurements, all taking the 2.4V value at the emitter since that seems to work best for me with my battery.

 

Voltage (V) Current (mA)
1.5 0.1
1.2 0.7
1.0 1.4
0.0 56

So, that’s way off “fully on” – I was expecting about 350mA and a quick test powering the LED direct gives 330mA as the observed value.

Even though this appears to be “working”, it plainly isn’t. Using the 2.8V level (so the LED switches on about 0.4V earlier) we’re only feeding 140mA to the LED, at 3.2V the figure is 210mA.

The PNP transistor is a BC327, with BC337 for the NPN. I came up with 100Ω as a suitable value for the base resistor in the simplest case at the start of this post. That’s the value I’ve used in the two transistor case as well. I’ve been through it again, and again, and I still think that they are reasonable values.

A quick experiment reducing the PNP resistor to 1Ω and the NPN resistor to 10Ω gave an initial current for the LED of 240mA – that’s much better but still not what it should be. After a couple of hours this had fallen off to 80mA anyway – maybe the battery isn’t behaving as it should? I went lower since I thought that even if the smoke came out of the transistors that it would tell me something (apart from that I don’t know what I’m doing).

Anyway, out of time now. Will try to figure out what the problem is – it’s slightly frustrating as it seems to be mostly working almost as I want it to.

Posted in Uncategorized | Leave a comment

The Matrix

Here’s a final post for 2014!

I’ve been busy with our “bungy” recently – we’re having a lot of decorating etc. done so have been moving stuff around and playing at being a proper bloke rather than just mucking about with my toys this Xmas.

A while ago, I picked up some Adafruit NeoMatrix displays. Five of them to be exact, and at about £25+ a pop that’s not an insignificant investment to have lying around doing nothing.

So, it was time to do something with them. As documented elsewhere, I managed to kill one of them by a slight accident with voltage 😳 Time to move on… As they stand, an 8×8 display is great, and colourful, and er, whatever. But not really much use. My (obvious) idea was to 2×2 the 8×8’s so I get a 16×16 matrix. Would that be “good enough” for animation?

Adafruit do a fine library for controlling the NeoMatrix so I decided to use that – do check out the stuff at josh.com though. I may well end up trying to merge the two since memory becomes a big problem with these puppies. Since memory would clearly be an issue and I didn’t have enough arsed to plumb in an SD card reader I dug out a cheap ENC28j60 ethernet module that I’ve, sort of, played with in the past. After a bit of research, I opted for the UIPEthernet library for Arduino and got to work.

First, the hardware…

The NeoMatrices came in 2 by 2...

The NeoMatrices came in 2 by 2…

That’s 4 NeoMatrix boards stuck together (with bits of wood and hot glue 😳 ). Common ground points are soldered for extra strength. The 2 x 2 is arranged with the first matrix at the top left, second at top right, then bottom left and finally bottom right – all from the front of course.

Since I got the boards, Adafruit now advise a 1000μF capacitor across the power input for the pixels and a 300-500Ω resistor in line with the signal (I used 470Ω).

There’s a mini-USB for powering the LEDs but, after a cock-up with a 2A wall wart, I had to switch to a beefier power supply – 256 pixels x 3 colours @ 20mA each is 5.12A. Shame I didn’t do that simple sum before running full on, in yer face, white with a 2A wall wart that now smells of burnt plastic 😳

After playing around with an Arduino Uno for a little while, it became obvious that 2K of SRAM just wasn’t going to cut it. At all.

At some point, I bought an Arduino Mega2560 so I switched to that – it has 8K of SRAM so much more headroom to store the pixel data and buffer things received over ethernet. Here’s the Arduino code:

#include <Adafruit_GFX.h>
#include <Adafruit_NeoMatrix.h>
#include <Adafruit_NeoPixel.h>

#define PIN 6

Adafruit_NeoMatrix matrix = Adafruit_NeoMatrix(8, 8, 2, 2, PIN,
  NEO_TILE_TOP   + NEO_TILE_LEFT   + NEO_TILE_ROWS   + NEO_TILE_PROGRESSIVE +
  NEO_MATRIX_TOP + NEO_MATRIX_LEFT + NEO_MATRIX_ROWS + NEO_MATRIX_PROGRESSIVE,
  NEO_GRB + NEO_KHZ800);

// Ethernet server
#include <UIPEthernet.h>
EthernetServer server = EthernetServer(1234);

void setup() {
  //Serial.begin(115200);

  uint8_t mac[6] = {0xa0,0xa1,0x02,0x03,0x04,0x05};
  IPAddress myIP(192,168,0,99);
  Ethernet.begin(mac,myIP);
  server.begin();

  matrix.begin();
  matrix.setBrightness(25);
  matrix.fillScreen(matrix.Color(0, 128, 0));
  matrix.show();
}

void loop() {
  int size;

  if (EthernetClient client = server.available())
    {
      while((size = client.available()) > 0)
        {
          uint8_t* msg = (uint8_t*)malloc(size);
          size = client.read(msg,size);
          //Serial.println(size);
          if ( size == 768 ) {
            int p = 0;
            for (int j=0; j<16; j++) {
              for (int i=0; i<16; i++) {
                byte r = msg[p+0];
                byte g = msg[p+1];
                byte b = msg[p+2];
                p += 3;
                matrix.drawPixel(i, j, matrix.Color(r, g, b));
              }
            };
          } else if ( size == 3 ) {
            byte r = msg[0];
            byte g = msg[1];
            byte b = msg[2];
            matrix.fillScreen(matrix.Color(r, g, b));
          } else if ( size == 1 ) {
            matrix.setBrightness(msg[0]);
          }
          matrix.show();
          free(msg);
        }
      client.println("OK");
      client.stop();
    }
}

It’s fairly simple (well, more like “brain-dead” to be honest). A one byte packet sets the brightness level, 3 bytes represents an RGB colour that all the pixels get set to and 768 bytes is interpreted as 16×16 RGB image data. Anything else is ignored. That’s a problem because TCP/IP can fragment packets to improve performance as it sees fit so not all of my 768 byte images arrive in one piece – yes, that means frames can get randomly dropped. Not good.

I use Python to sort out the images and pull out multiple frames if it’s an animation. Here’s the main program:

from __future__ import print_function

import sys
import time

import frames
import matrix

HOST = '192.168.0.99'
PORT = 1234

images = frames.Frames(sys.argv[1])

m = matrix.Matrix(HOST, PORT)
m.setBrightness(20)
try:
    if images.length > 1:
        while True:
            for img in images.images:
                m.send(img.tobytes())
                time.sleep(0.2)
    else:
        m.send(images.images[0].tobytes())
        while True:
            x = raw_input("")

except:
    m.off()

sys.exit(0)

There are a couple of modules to go with that, firstly “frames.py” to sort out the images:

from __future__ import print_function

from PIL import Image

# Default image size
_WIDTH = 16
_HEIGHT = 16


class Frames(object):

    '''
    Turn an image file into a list of 16x16 RGB frames that can
    be sent to an RGB LED display.
    '''

    def __init__(self, fileName, width=_WIDTH, height=_HEIGHT):
        self.width = width
        self.height = height
        img = Image.open(fileName)
        frame = self.__forceSize(img)

        results = [frame]

        # Look for additional frames
        nframes = 0
        while True:
            nframes += 1
            try:
                img.seek(nframes)
            except EOFError:
                break
            results.append(self.__forceSize(img))

        self.images = results
        self.length = len(results)

    def __forceSize(self, img):
        img = img.convert('RGB')
        img.thumbnail((self.width, self.height), Image.ANTIALIAS)
        # check size
        size = img.size
        if size[0] != self.width or size[1] != self.height:
            tmp = Image.new(img.mode, (self.width, self.height))
            tmp.paste(img, (0, 0))
            img = tmp
        return img

And “matrix.py” to handle talking to the display:

from __future__ import print_function

import sys
import socket

class Matrix(object):

    def __init__(self, ip, port):
        self.ip = ip
        self.port = port

    def send(self, stuff):
        try:
            sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        except socket.error, msg:
            sys.stderr.write("[ERROR] %s\n" % msg[1])
            sys.exit(1)

        try:
            sock.connect((self.ip, self.port))
        except socket.error, msg:
            sys.stderr.write("[ERROR] %s\n" % msg[1])
            sys.exit(2)

        # Send the data
        sock.send(stuff)

        # Wait for reply
        data = sock.recv(16)
        string = ""
        while len(data):
            string = string + data
            data = sock.recv(16)

        assert string.strip() == "OK"

        sock.close()

    def off(self):
        self.setBrightness(0)

    def setBrightness(self, brightness):
        data = bytearray()
        data.append(brightness)
        self.send(data)

    def rgb(self, r, g, b):
        data = bytearray()
        data.append(r)
        data.append(g)
        data.append(b)
        self.send(data)

The Python Imaging Library is used to do the heavy lifting and the socket stuff is just based on the standard example. I’m leaving this here for now (insufficient 2014 arsed reserves remaining 😆 ) but I’ll get back to it and improve it for next Xmas. I need to handle packet fragmentation and probably add some kind of command/protocol so I can also do scrolling text (as supported by the Adafruit library). It would be nice to handle bigger displays too so maybe using an ATmega1284 (yes, I have one) with 16K RAM would help – as would merging the library by Josh (no pixel storage) with the Adafruit library so I only have to store the data received over ethernet.

All in all, it’s fairly amazing that you can put something together like this so easily. What was that about standing on the shoulders of giants? Finally, here’s the obligatory crap video…

Happy New Year!

 

Update: Code now on GitHub (so I can find it again) as megaMatrix and PyMatrix

Posted in Uncategorized | Tagged , , , | Leave a comment

Garageland #3

Well it took longer than I expected but it’s all done now.

When I came to put the yellow crap in the case it became obvious that it wouldn’t fit when the micro USB was connected. That was fairly obvious and I should have spotted it before. I did come across a breakout board amongst all the other stuff the other day so I tried that instead – it would require a bit of soldering but it would easily fit into the case, even with the USB connector. Testing the voltages on the pins though showed that they were mostly about 2V, even pins that should be low since that’s what I was setting them to. At that point I abandoned the yellow crap.

A quick rummage in my box of bits yielded a board I built to drive my sadly neglected robot. It’s a bit of a mess as I tried to fix what I thought were noise problems by throwing capacitors at it and hoping something stuck. Anyway, it’s just a bog standard “breadboard Arduino” so it is perfect for this application – especially as it’s hidden out of sight.

Dr Frankenstein's Arduino

Dr Frankenstein’s Arduino

I added the micro USB connector and a resistor to ground to allow me to put an LED in the enclosure lid (just to show that it’s alive and kicking really).

Next up I fettled the wiring including twisting up a couple of meters for the ultrasonic sensor. That’s where things went wrong. I had used some wire I have a lot of, mostly with breadboards or for short runs. It’s fine for that but the ultrasonic sensor wouldn’t work with it. It turned out to be much too thin and have way too high a resistance over that length and the sensor just wasn’t triggering. I dug out a thicker gauge of wire and made an even longer run of that which worked fine.

It’s all up and running now. Unfortunately I didn’t take any photos of the finished layout – it’s pretty much as shown yesterday. I did take a short video though…

I wanted the side door in the shot as it isn’t possible to see that the light goes off otherwise. That’s it, no fancy delays or other faffage – it just jobs the jobs as things happen. Here’s the code (which I may, or may not, get around to uploading to GitHub as it’s relatively trivial):

// ---------------------------------------------------------------------------
// lightEmUp
//
// Simple state machine to switch on garage lights when the door opens and 
// to switch them on again (after a when the doors close again.
//
// This is *really* simple. It does nothing clever, at all.
//
// When we start up, we start by turning the relay off (it should be anyway
// while we've been powered down).
//
// We then check if the door is open or closed and save the state.
//
// Then we just repeatedly call the sensor distance routine:
//
//    If we're OPEN and we see something in range, assume the door has closed 
//    and turn off the relay. Make the new state CLOSED.
//    
//    If we're CLOSED and we don't see anything in range then we assume that
//    the door has opened. Turn on the relay and make the new state OPEN.
//
// Then we do a dumb delay for 0.5s since all we're doing is looking for
// something in range.
//
// ---------------------------------------------------------------------------

// Actions occur only on the transition between states so define the 
// following obvious states:
enum States {OPEN, CLOSED};
States state;

#include <NewPing.h>

// Declare the ultrasonic sensor
const int SONAR_PIN=7;          // Arduino pin tied for HC SR-04 trigger and echo
const int MAX_DISTANCE=30;      // Maximum distance (cm)
NewPing sonar(SONAR_PIN, SONAR_PIN, MAX_DISTANCE); // NewPing setup of pins and maximum distance.

// Pin to control relay
const int relayPin = 8;

// Pin to blink an LED to show we are alive
const int ledPin = 9;
int ledCount = 0;

// Return distance in cm
unsigned int getDistance() {
  unsigned int cm = sonar.ping() / US_ROUNDTRIP_CM; // Send ping, get distance (cm).
//  Serial.print(cm);
//  Serial.println(" cm");
  return cm;
}

void setup() {
  
//  Serial.begin(115200);
  
  // Setup relay pin
  pinMode(relayPin, OUTPUT);
  digitalWrite(relayPin, LOW);
  
  // Setup LED
  pinMode(ledPin, OUTPUT);
  digitalWrite(ledPin, LOW);

  delay(500);

  // Determine initial state
  if ( getDistance() > 0 ) {
    state = CLOSED;
  } else {
    state = OPEN;
  }
}

void loop() {
  unsigned int dist = getDistance();
  
  switch (state) {
    case CLOSED:
      if ( dist == 0 ) {
        // Door has opened, lightEmUp!
        digitalWrite(relayPin, HIGH);
        state = OPEN;
      }
      break;

    case OPEN:
      if ( dist > 0 ) {
       // Door has closed, switch off
        digitalWrite(relayPin, LOW);
        state = CLOSED;
      }
      break;;
  }
  
  // toggle LED (flash every 2.5s)
  if ( ++ledCount == 5 ) {
    digitalWrite(ledPin, HIGH);
    ledCount = 0;
  }
  delay(100);
  digitalWrite(ledPin, LOW);
  
  // We'll update at around 2Hz, allow for delay just above
  delay(400);
}

Well, that’s done. The sensor position might need some tweaking if the passing of the car interferes with the operation of the lights – the other option is to reduce the sensor range.

Now I’m totally happy with the garage doors without messing up the control panel or shelling out a fortune.

Posted in Uncategorized | Leave a comment

Garageland #2

Managed to find a couple of hours this afternoon so into the garage I went.

I’d written the code for the microcontroller this morning – I really have kept it very simple but I’ll test it before posting it here and sticking it on GitHub. I think “simple” should work but I’ll be able to see how it does in the real world tomorrow. Time for some real work 😆

First up, I had to pop a new double socket up in the garage – there’s a need for one on the car’s battery side anyway, that side is not accessible when the car is in so less danger of treading on the sensor and there’s just more room. It was a simple decision.

Secondly, I needed to run a live from the lighting junction box and return switched live from the relay. Nothing special there then.

After a bit of drilling and wire pulling I ended up with this:

New socket, relay and box for "yellow crap"

New socket, relay and box for “yellow crap”

Here’s a close-up of the relay:

Fotek SSR

Fotek SSR

And some “context”:

Crime scene

Crime scene

All I need to do now is pop the microcontroller in the black box, run 3 wires to an HC SR-04 ultrasonic sensor on the floor and power the lot with a USB wall-wart. I’ve popped the cover plate over the relay and tested it with a 9V battery – it works just fine. I do like this solid-state stuff, you can switch it on with as little as 3V and you don’t have to fanny around with diodes – what’s not to like?

So, just a bit of low voltage “wiring” to do and this will be finished tomorrow 🙂

Posted in Uncategorized | Leave a comment

Garageland

I had a tasty roller shutter garage door installed a few weeks ago. It’s something I’ve always wanted and I have to say that I’m nearly very happy with it. Ok, so it cost a lot of dough and “nearly” doesn’t really cut it. I’m sure for another wedge of cash I could have it do everything I want but I really don’t want to spend that wedge 😀

The problem is “light”. It comes with a nice looking control panel with a built in light:

Let there be light, just not very much of it...

Let there be light, just not very much of it…

The light is, well, pants. It’s like something you’d find in a fridge or an oven. What I would really like is for it to switch on the 4 x 15W LED bulbs I installed a while ago so I get proper light in the garage when I’m trying to squeeze my lardy old V8 in there.

I’ve been thinking about ways of doing this, mostly involving popping the lid of that nice, shiny, new control panel and soldering wires to stuff inside (like the bulb holder). That would let me switch a relay to control the main garage lights.

Problem. I don’t really want to faff about with this thing. It’s brand new, I’m ham-fisted, I can find ways to break plastic tabs on things that don’t even have any plastic tabs. And it’s under a long warranty, until I hammer my way in.

Hmmm….

I think I may have a solution…

One of these:

HC-SR04 Ultrasonic Sensor

HC-SR04 Ultrasonic Sensor

I’ve got room to put one of these (hot-glued to that very box in fact) on the floor so I can tell if the garage door is there or not. Then that would need a microcontroller of some description – I wonder if I have anything like that 🙄

Yellow crap

Yellow crap

Yes, I bought this rip-off shite on Kickstarter. If I ever meet Mr Dimitri Albino in person I’ll make sure to shake him very warmly by the throat. At least I got nearly all of my stuff. Shame it’s shit though.

This is a Mega 328 on some kind of badly designed Arduino Uno shaped wannabe board. All I need is the Atmel chip so I’ll use up some of this yellow crap if I can. It seems to work and I’ll probably use it. I do have a couple of my own 328 based boards kicking around though so may use one of those instead, they were ones I made early on and the soldering is a bit clumsy. I guess I trust them more than I trust the yellow crap though 🙂

I’ll need something to put the controller in:

It's a box!

It’s a box!

I was very pleased to find these at £2.49 + VAT in the Ciseco shop. Less pleased to spot that I can get them for 85p from Farnell 🙁

Right, so I also need a switched live to drive the main lights. Ah, I have some of these…

Is it real, or is it a Fotek clone from China?

Is it real, or is it a Fotek clone from China?

Got these cheap from “Guess where?”. There are reports of lots of look alike stuff doing the rounds. Apparently the rip-offs get hot when you switch them quickly. I won’t be switching quickly 😉

I’ll need to cover that up otherwise some 10 foot tall retard with a compulsion to touch live wires might walk into my garage and hurt themselves 🙄 Got that covered then…

A relay, in a box

A relay, in a box

Stick a lid on that, put it up nice and high (so the 10ft retard will also need a screwdriver to get the front plate off) and Job’s your uncle. Or whatever.

It looks like a really simple way to do this. A “state machine” running on the yellow crap should easily take care of controlling the relay and then I’ll have decent light when I open the garage door in the dark. And I’ll still have a warranty on my garage door control box.

I’ll be giving this a go in the next couple of days. It really does feel like a straightforward little project – not much pain and an awful lot of gain.

So, what have I missed… 😆

Posted in Uncategorized | Leave a comment

Preparing for Xmas…

What? Well somebody has to 😳

Apart from the G35 addressable RGB lights, I’m going to use some of these “Meteor Shower/Rain” LED lights in our porch – I had a play with them here. I have 4 lots of 8 x 30cm tubes so that should be enough to dangle in a small area.

Each set of 8 tubes seems to need no more than 250mA to drive it so powering all of this isn’t a big deal. What I do need to do is drill a hole into the loft space to bring out the 5V supply – that doesn’t seem to be a big deal (once I’ve been up there and found some leccy to use). I can’t say I really want to be going outside to switch them on and off though (or going up in the loft for that matter). I’ve been interested in radio devices for a while (I’ve bought various kinds but never really got anywhere with them) and it is an obvious solution – just hit a web page from phone/tablet/pc to turn the lights on and off.

I’ve had a fair few things now from Ciseco and their stuff seems to be very well though out. I have a URF Radio Module, a slice of radio (for raspberry pi) and an SRF Shield (the last two being part of a Kickstarter campaign). So, after a bit of research I decided to go for their RFμ-328 board and the developer board designed for it.

They’re very easy to use and the developer board seems very well though out to me – it’s a steal at £3.99 too!

Ciseco RFu-328 Developer Board

Ciseco RFu-328 Developer Board

For this application, I need (say) a 2A USB wall wart to drive the controller board and the lights (that gives plenty of headroom). The RFu-328 needs 3.3V so a voltage regulator is required. I decided to use on of my favourite logic-level N-channel MOSFET chips to switch ground for the LEDS and apart from that, a screw terminal and an LED to show on/off when testing that’s about it.

Finished board

Finished board

Luckily, Ciseco also sell a really good looking and great value case which I’ve housed the whole thing in.

I decided to use their LLAP protocol and library – maybe that’s abuse rather than use, but what the hell. The code was simple to generate and works really well (it is simple, so it should).

//////////////////////////////////////////////////////////////////////////
// LLAP N-Channel MOSFET Controller for XMAS Lighting
//
// Written for RFu-328
// Uses the Ciseco LLAPSerial library
//
//////////////////////////////////////////////////////////////////////////

#include <LLAPSerial.h>
#define DEVICEID "XM"    // LLAP device ID
#define RADIO_SELECT 8
#define PWR_PIN 6
int state = 0;
bool valid = false;

void setup() {
  Serial.begin(115200);
  pinMode(RADIO_SELECT, OUTPUT);  // switch on the radio
  digitalWrite(RADIO_SELECT, HIGH);
  delay(1000);                    // allow the radio to start
  pinMode(PWR_PIN, OUTPUT);
  digitalWrite(PWR_PIN, LOW);

/*  
  // One off commands to set device id then we can
  // program this device in the presence of others
  enterCommandMode();
  sendCommand("ATMYXM");
  sendCommand("ATAC");
  sendCommand("ATWR");
  sendCommand("ATDN");
*/

  LLAP.init(DEVICEID);
  LLAP.sendMessage(F("STARTED"));
}

void loop() {
  // Wait for message and act on it
  if (LLAP.bMsgReceived) {
    valid = false;
    LLAP.bMsgReceived = false;
    if (LLAP.sMessage == "ON-------") {
      state = 1;
      digitalWrite(PWR_PIN, state);
      valid = true;
    } else if (LLAP.sMessage == "OFF------") {
      state = 0;
      digitalWrite(PWR_PIN, state);
      valid = true;
    } else if (LLAP.sMessage == "TOGGLE---") {
      state = 1-state;
      digitalWrite(PWR_PIN, state);
      valid = true;
    } else if (LLAP.sMessage == "STATUS---") {
      valid = true;
    }
    
    if ( valid ) {
      LLAP.sendInt("STATUS", state);
    } else {
      LLAP.sendMessage("ERROR");
    }
    // Small delay to give the message time to get out
    delay(20);
  }
}

/*
The following code is taken from:
http://openmicros.org/index.php/component/kunena/10-ciseco-support/8009-changing-settings-of-srf-on-urf-rf-question?Itemid=0
*/

uint8_t enterCommandMode()
{
  Serial.print("+++");
  delay(500);
  while (Serial.available()) Serial.read();  // flush serial in - get rid of anything received before the +++ was accepted
  delay(500);
  return checkOK(500);
}

uint8_t sendCommand(char* lpszCommand)
{
  Serial.print(lpszCommand);
  Serial.write('\r');
  return checkOK(100);
}

uint8_t checkOK(int timeout)
{
  static uint32_t time = millis();
  while (millis() - time < timeout)
  {
    if (Serial.available() >= 3)
    {
      if (Serial.read() != 'O') continue;
      if (Serial.read() != 'K') continue;
      if (Serial.read() != '\r') continue;
      return 1;
    }
  }
  return 0;
}

I’ll get around to putting that on GitHub at some point. Also need to write a simple web interface for the raspberry pi with slice of radio that will look after all of my RFu-328 devices (I have plans, big plans, for multiple sensors and much more automation around the place).

So, apart from all the physical bits (small things like leccy, drilling holes, putting up hooks to hang the lights on 🙄 this counts as “job nearly jobbed” 😆

All that’s left for now is the “action” shot 🙂

Festive Fun!

Festive Fun!

The “black box” (upper-middle on the right) is the Ciseco project box with everything in. As well as being able to control it remotely it’s all possible (and necessary) to program it remotely too. I’m very impressed with this Ciseco stuff, I suspect it’s going to be damaging my credit card over the next few months 🙂

Posted in Uncategorized | Leave a comment