Predictable LED troubles

In november 2008 i replaced 2 conventional fluorescent tubes by a LED version. Thinking they would last a long, long time was very, very wrong… In october 2009, not even a year after i started using them, the first tube started acting strange; one of the three rows of a total of 342 LEDs wasn’t burning anymore. Next day, the second row of 114 LED’s stopped burning. Guess what happened the day after that… a rough calculation tells me this tube has done its job for 360 x 5 = 1800 hours. Multiplying by 10 doesn’t even come close to what is advertised!

So i called the supplier for replacement tubes.

LED tube

LED tube, "version 2"

He promised me he would send me 2 new tubes, although he warned me in advance that it could take some time.. OK, i wasn’t in a hurry for replacement cause one tube was still working. But in the 2nd week of January i called again  to ask why it took so long for my LED tubes to arrive? The result was a very interesting conversation and i was given a bit of insight on how the LED market is working nowadays.

For example, i was told that the supplier had experienced a huge amount of failing LED light products being returned, especially during the hot summer of 2009. Bad design led to massive overheating of LED tubes and other LED products, causing lots and lots of  malfunctions..

Another thing the supplier told me, is that they had stopped selling most of the brands and had now limited their product range to only the high end segment; only those (with an equally high price tag) products could possibly live up to the life expectations that are so strongly advertised. Between the lines, you could read that his business had been seriously threatened by all the problems they faced with LED products in 2009. Quite a story for a normal ‘consumer’ like me who likes to try out new products, technologies and gather experiences with those products.

In my opinion, LED is hugely overrated in specifications, lifetime expectation and savings. I’ve bought at least 10 LED bulbs in the past year of which 3 stopped working in their first days. That’s 25-30%! within a week.  Needless to say i have very big doubts about the quality of the current LED technology.

And what will happen when my newly placed LED tubes stop working again in, say, 6 years? Will those tubes be replaced again, at no charge? Guess not.

No, for me LED is a nice product for the manufacturers, who don’t fully control the process of producing a good LED product yet but don’t mind making big money with it already, letting the customers pay 80 Euro for a single LED tube and delivering garbage.

And for politicians, who are encouraging the use of LED to show off how ‘green’ they are, while believing the LED producers on their blue eyes regarding to the quality of LED products. I wonder how much of them are actually using LED products themselves.

Me? I’ve learned my lesson and will not buy any LED product until my box of spare energy saving lamps is completely empty.

Wireless Pressure Sensor – small fix

The fact that in the setup i made yesterday, the XBee module sometimes had trouble setting up the connection was troubling me, so i tried to figure out what was going on. My guess was that the CTS line was not monitored, so i built a counter into the loop that waits for CTS to get high; and made this counter part of the packet payload so that i could monitor what was going on; this counter  was always 1, meaning CTS was high at the time the first CTS check was done!

Hmm, seeing that, the error was found very quickly: CTS was attached to the wrong digital input, so CTS wasn’t monitored at all… fixed the wiring and now everything’s OK.

Second thing i changed was for the sake of convenience: the new sketch does the temperature and pressure calculations “on board”, so now the payload immediately shows value that are easily interpreted. I also took the time to create a small Delphi program that uses my XBee API to log all the packets that are received in a more readable style:

31-1-2010 20:43:30:Packet payload=[2 215 100159]
31-1-2010 20:43:41:Packet payload=[7 215 100150]
31-1-2010 20:43:52:Packet payload=[0 215 100153]
31-1-2010 20:44:03:Packet payload=[0 215 100156]
31-1-2010 20:44:14:Packet payload=[0 215 100166]
31-1-2010 20:44:25:Packet payload=[5 215 100156]
31-1-2010 20:44:36:Packet payload=[10 215 100159]
31-1-2010 20:44:47:Packet payload=[0 215 100150]
31-1-2010 20:44:59:Packet payload=[0 215 100156]
31-1-2010 20:45:10:Packet payload=[0 214 100153]

The first value is the time in milliseconds that it takes for the CTS to become high, the second value is the temperature in 1/10th of a degree and the last value is the pressure in mbar.  Neat 🙂

Wireless Pressure Sensor – first results

JeeNode connected to XBee

JeeNode connected to XBee

Here you see my first setup of a JeeNode with pressure sensor connected to a XBee Series 2 module.  And it’s working! With Hyperterminal i captured the raw data coming in on my XStick:

XBee API mode packets with sensor data

XBee API mode packets with sensor data

The ‘experts’ will immediately recognize the first character (tilde, ~) as being the frame header of a XBee packet. The payload on the first line is ‘26311 39767’. All characters before that are XBee API frame related as well as the last character, which is the checksum. When you have a look at the code you can see what the payload is made of.

This is absolutely very cool; it think in total it has cost me an evening to put this all together; something i would have never dared dreaming about a year ago!

But there’s still a lot to do:

There seems to be a timing issue in the code, cause i saw the XBee having a bit of trouble joining the PAN. Maybe give it some more time in the setup routine, or give some more time during powering up the XBee to send a new sample… we’ll see.

I need to write some software on PC-side to test reliability of it all.

How long will the batteries survive? I haven’t got a clue… and how am i going to test this? For example, i can’t switch off my PC now, cause the XStick is powered by it; XStick not powered means no PAN means the XBee will keep on searching for the PAN and will use much much more power…

To make the whole package smaller, i need to stop using the pin headers on the JeeNode and just solder the wires right onto the board.

A big step ahead, but still a lot of questions to be answered…

Here’s the code that is currently running on the JeeNode:

#include <Ports.h>
#include <RF12.h>
#include "PortsBMP085.h"
#include <avr/sleep.h>
#include <NewSoftSerial.h>

NewSoftSerial XBSerial = NewSoftSerial(2, 3);
PortI2C two (2);
BMP085 psensor (two);

int pinXBee=7;                        // to Control XBee on/off
int pinCTS=6;                         // to monitor CTS

static int SampleInterval = 1000;     // 60000;
static int HeartBeatInterval = 10000; // 300000;
static int CTS=0;                     // value of XBee CTS pin

struct {
    int16_t temp;
    int32_t pres;
} payload;

static void lowPower (byte mode) {
    // prepare to go into power down mode
    set_sleep_mode(mode);
    // disable the ADC
    byte prrSave = PRR, adcsraSave = ADCSRA;
    ADCSRA &= ~ bit(ADEN);
    PRR &= ~ bit(PRADC);
    // zzzzz...
    sleep_mode();
    // re-enable the ADC
    PRR = prrSave;
    ADCSRA = adcsraSave;
}

EMPTY_INTERRUPT(WDT_vect); // just wakes us up to resume

static void watchdogInterrupts (uint8_t mode) {
    MCUSR &= ~(1<<WDRF); // only generate interrupts, no reset
    cli();
    WDTCSR |= (1<<WDCE) | (1<<WDE); // start timed sequence
    WDTCSR = bit(WDIE) | mode; // mode is a slightly quirky bit-pattern
    sei();
}

static byte loseSomeTime (word msecs) {
    // only slow down for periods longer than twice the watchdog granularity
    if (msecs >= 32) {
        for (word ticks = msecs / 16; ticks > 0; --ticks) {
            lowPower(SLEEP_MODE_PWR_DOWN); // now completely power down
            // adjust the milli ticks, since we will have missed several
            extern volatile unsigned long timer0_millis;
            timer0_millis += 16L;
        }
        return 1;
    }
    return 0;
}

static MilliTimer SampleTimer;     // Interval for reading a sample from the BMP085
static MilliTimer HeartBeatTimer;  // forced maximum interval (Heartbeat)

static byte periodicSleep (word msecs) {
    // switch to idle mode while waiting for the next event
    lowPower(SLEEP_MODE_IDLE);
    return SampleTimer.poll(msecs);
}

static void Send (const void* ptr, byte len) {

  unsigned long tXB1;    // time XBee was woken up
  unsigned long tXB0;    // time XBee was put to sleep

  Serial.println("Sending payload");
  HeartBeatTimer.set(0);

  CTS = HIGH;
  tXB1=millis();
  // wake up Xbee
  digitalWrite(pinXBee,LOW);

  // wait for CTS to become LOW
  do
  {
    CTS=digitalRead(pinCTS);
  } while (CTS != LOW);

  // wait 2 msec otherwise data will be received all messed up
  delay(2);

  // send dummy data
  XBSerial.print(payload.temp);
  XBSerial.print(" ");
  XBSerial.println(payload.pres);

  Serial.print(payload.temp);
  Serial.print(" ");
  Serial.println(payload.pres);

  // wait again for XBee to finish transmission
  delay(2);

  // switch off XBee
  digitalWrite(pinXBee,HIGH);
}

static int16_t prevTemp;           // save previous temp value
static int32_t prevPres;           // save previous temp value

// this code is called once per second, but not all calls will be reported
int ReadSensor() {

    int16_t temp = psensor.measure(BMP085::TEMP);
    int32_t pres = psensor.measure(BMP085::PRES);

    Serial.print("Readings: ");
    Serial.print(temp);
    Serial.print(' ');
    Serial.print(pres);
    Serial.println(' ');

    int changed = (temp != prevTemp) || (pres != prevPres);
    prevTemp = temp;
    prevPres = pres;

    payload.temp = temp;
    payload.pres = pres;

    changed = 1;            // force sending always during testing
    return changed;

}

void setup() {

  // setup XBee
  pinMode(pinXBee,OUTPUT);
  digitalWrite(pinXBee,LOW);
  pinMode(pinCTS,INPUT);
  digitalWrite(pinCTS,LOW);   // really necessary?
  delay(10);

  XBSerial.begin(9600);
  // give XBee some time to join PAN
  delay(5000);

  // let the world know we're here
  XBSerial.println("n[TempPres]");
  Serial.println("n[TempPres]");

  watchdogInterrupts(0); // 16ms
}

void loop() {
    if (periodicSleep(SampleInterval)) {
      // sensor values changed or heartbeat interval elapsed?
      if (ReadSensor() || (HeartBeatTimer.poll(HeartBeatInterval)))
      {
         Send(&payload, sizeof payload);
       }

    }
}

Making a Wireless Pressure Sensor

I don’t own a weather station, nor do i intend to buy one, but i always did like the idea of having a pressure sensor. Now i have 🙂

This BMP085 based pressure sensor doesn’t only do pressure, but can also measure the temperature. Time to hook it up to a JeeNode!

Due to the fact that our plans for today had to be canceled by the bad weather, i had some extra time to test this Pressure Sensor. First i had to solder the 2nd JeeNode i bought last week, cause it was still unassembled in it’s plastic bag. Soldering a JeeNode is quite easy to do; it’s really hard to do something wrong… This time i left the RF12 radio off because i wanted to use one of my XBee modules to send the raw measured values. And i attached a battery holder, cause eventually this is my goal: a battery powered pressure sensor.

I installed the Ports library, uploaded the BMP085 demo sketch from the Ports Library examples  to the JeeNode and everything ran fine:

BMP 26265 39759 225 99390
BMP 26260 39755 225 99372
BMP 26267 39761 226 99400
BMP 26263 39756 225 99378
BMP 26265 39759 225 99390
BMP 26263 39758 225 99384
BMP 26261 39757 225 99378

Next step will be adding code for the XBee and sleeping. To bad, time’s up for now… hopefully, later this evening i have some time left to finish this sensor.

JeeNodev4 with BMP085 Sensor

JeeNodev4 with BMP085 Sensor

Major upgrade of Fritz!Box Plugin for Homeseer

This week i published a major Upgrade for the Fritz!Box Plugin for Homeseer.

As i mentioned before, there were still some interesting things that could be added to the Plug-in and i thought it was time to revive the Plugin by adding some functionality that was asked for, make it future proof by supporting the newer firmware versions. Some of the things that have been added in the last 2 weeks are:

– Retrieving the Phone Book from the Fritz!Box and using it for Caller ID(entification);

– Searching websites on the Internet for Caller ID;

– Supporting the challenge/response security mechanism built into new firmware;

– Switching the WLAN from Homeseer;

– some useful stuff for use in scripts;

– upgrade of configuration pages to ASP.NET.

You can read all about it in more detail on domoticaforum.eu

This should do for some time; maybe some small additions or fixes, but that’s it for now; time to move on to development of another brand new and exciting Plugin! 🙂

JeeNodes!

They arrived last Tuesday. 2 JeeNodes, together with a JeeLink and a pressure sensor. And an additional Arduino for experimental stuff.

JeePlug

JeeLink

Although i had a lot of other things to do, i just couldn’t resist building at least one of the two i ordered. The JeePlug kit is easily soldered together so after half an hour i had my JeePlug and first JeeLink running. Next thing to do is get the Pressure Sensor working, receiving the data and processing it in my Domotica system.With all the information provided on Jean-Claude Wippler’s website that shouldn’t be a problem 🙂

So when you find a pressure chart on my website in the near future, you know where the data’s coming from…

Digital Code Lock

Last Friday a Digital Code Lock arrived. I want to see if i can do something useful with it. It is intended for use with a door opener.
Above the keypad there are 3 LEDs of which 2 are freely usable; the 3rd (middle) bi-color LED shows the status of the code lock.  The code lock comes with a manual with description of all connections and some connection examples.

Digital Code Lock

Digital Code Lock

Code Lock Internals

Code Lock Internals

It’s one of the cheaper code locks, but if all goes well and i’m satisfied i might buy another more eye-catching one.

This model has a sabotage switch inside just like the tamper switch on the inside of Visonic sensors. I’m going to connect this switch to a Visonic MCT302 aux input located inside my house and any attempt to sabotage the code lock will fire the alarm. One of the freely usable LEDs is going to display the status of the alarm, the other free LED doesn’t have a function assigned yet. Just a matter of time…

The Code Lock will be supervised by an Arduino so i can make full use of all the functionality it has to offer.

To be continued…

Extensions for the Fritz!Box Plugin for Homeseer

It has been quiet regarding the Fritz!Box Plugin for Homeseer for a while, but that’s going to change; when others start creating scripts around my Plugin then you know there’s something missing and it’s time to have a look at it…

The last couple of days i was looking at how i could spend the huge amounts of free time i have lately and decided to spend it on extending the Plugin with some extra features; the Fritz!Box has a lot to offer, so there are still a lot of things to explore.

But first i had to tackle the new way of logging in to the Web-interface that has changed in the recent firmware versions (xx.04.74 and higher). This new method of logging in involves calculating MD5 value based on a challenge provided by the Fritz!Box, and having read once that a lot of faulty MD5 routines exist, i decided to look into that issue first. I mean, creating additional functionality without supporting the latest firmware sounds rather stupid to me.
OK, the sequence of actions to do a successful login were clear to me, that wouldn’t be the problem; only thing i hoped for was that the calculation of the MD5 hash would succeed with the .NET provided classes/routines. So i created a simple function that could return the MD5 of a given string:

MD5-Hash

The resulting md5bytes should contain the correct hash value when each byte was written as hex string value and all 16 of them were concatenated. But something strange was going on…

The AVM documentation stated the resulting MD5 should be: 9e224a41eeefa284df7bb0f26c2913e2 And what did i get? 58224a41eeefa284df7bb0f26c2913e2.

What’s this… well OK, it’s almost the same, maybe it will work, lol.
On the contrary, this ain’t funny at all of course… what’s going on here ??? I just didn’t know what was wrong; was it the encoding? The AVM guideline speaks of UTF-16LE (LE = Little Endian), BOM, trailing 0-bytes, Codepoints; not really the stuff i deal with on a daily basis, so …??

Searching MSDN i found this:

Not mine

With just a tiny adjustment (there where the cursor is) and it worked…

I still don’t understand why; these things can really bug me and now i’m struggling to either just go on and let it be, or go to the bottom of this?

Let’s hope i don’t encounter to much of these mysteries..  🙁

New Pronto TSU9600 firmware

Philips Pronto TSU9600

Philips Pronto TSU9600

Today i spent some time on my most expensive User Interface, the Philips Pronto TSU9600.

New firmware was released in December 2009 and also a new version of ProntoEdit Professional (PEP). The previous  major firmware update with a lot of new features was somewhere in July 2009, but due to lack of time i didn’t come very much further than updating the firm- and software and that was it. Now it was time to have a really good look at what this latest firmware and PEP version would bring. I must say, i’m impressed. It’s very clear that Philips has done a lot for making life of those who have to work with PEP a lot more pleasant 🙂

For example the use of PS (ProntoScript) Libraries. Where my old configuration had a lot of the same code on each activity page, it can now be put into 1 PS Library and added to the configuration at system level; no more redundant code!

The HTTP library is also a big improvement. The code i had to interface with my Domotica system was based on a TCPSocket, but when i went through the HTTP Library, i knew i was only 1 step away from implementing XML-RPC on the Pronto. One thing i missed was a way to do a HTTP POST, but that wasn’t that hard to create myself:

  // Convenience method to send text to an HTTP server
  //
  // Parameters:
  //   aUrl      HTTP URL
  //   aBody     the body
  //   aCallback Callback to invoke with text data upon success
  function postHTTP(aUrl, aBody, aCallback)
  {
    var req = new HttpRequest();
    req.postBody = aBody;
    req.open('POST', aUrl, true);
    req.setRequestHeader("Connection", "close");
    req.setRequestHeader("Accept-Charset",
                         "*; q=0.2, ISO-8859-15; q=0.9, ISO-8859-1,utf-8");
    req.onreadystatechange = function (aEvt) {
      if (req.readyState === READYSTATE.COMPLETED) {
        if (req.status === 200) {
          if (aCallback) {
            aCallback(req.responseText);
          }
        } else {
          System.print("HTTP status: " + req.status);
        }
      }
    };
    req.send(aBody);
  }

Next i created an additional Javascript library and some wrapper routines, which make it possible to have the Pronto ‘talk’ to the XML-RPC interface of my Domotica system:

  var httpLib = com.philips.HttpLibrary;
  var msg = new xmlrpc.XMLRPCMessage("SetDevice");

  msg.addParameter(Addr);
  msg.addParameter(aValue);
  httpLib.postHTTP('http://xx.xx.xx.xx', msg.xml(), aCallBack);

Now all my User Interfaces (website, ASUS TOP, Pronto) are using the same interface to my system. That really makes me very happy!

After some testing, today i did a complete remake of 2 of the most used activities. And this time it was fun!; i can assure you, it hasn’t always been that way in the past… Now all i have to do is add a ProntoScript one-liner to the Button Action:

XMLRPC_SetDevice("XELOS","MUTE");

This is the script for muting my TV; with no additional code except for the PS Libraries.

I’m very satisfied with my Pronto and how Philips keeps developing new features for it; and i haven’t even come to the features of the latest release yet; there’s still a whole lot more to explore!