(P)Imp my (Heatmiser) Thermostats

Mentioned elsewhere that I’ve embarked on using an Imp to speak to all my thermostats (16 of them). All the thermostats live on a RS-485 bus, controlled centrally through an LCD console screen. However, there’s no means of integration. So, thought about using the Imp to act as the master (on the bus) that presents an HTTP interface. The project means I get to explore RS-485, blobs and I thought why not throw in a LCD just for the heck of it.

However, I’ve got as far as breadboarding the Imp, the 2x16 SerLCD and the RS-485 interface, and already have an issue . The SerLCD was working fine for a few hours with a few test messages on it. Now, it just has rubbish appearing (mainly “||” characters).

The SerLCD Rx pin is tied to the Pin 5 (Uart57, Tx). I’ve tried resetting the baud rate to 9600 just in case that’s the problem. Any thoughts gratefully received…

I had the same problem some time ago and fixed
it by putting a resistor between PSB and BLA.

Hope that helps…

What other pins are you using in your design? (ie what other peripherals are in use)

@Hugo

I have uart12 to the RS-485, uart57 to the SerLCD, and Pin 8 as my RTS toggle to the RS485 board and that’s it. I’ve even had the RS485 board disconnected in case that was interfering, so essentially, it just left pin5 hooked up to the SerLCD.

Originally, I had USB power straight into the breadboard and powered teh Imp and SerLCD from that. Now, I’ve got USB straight into the Imp and take the SerLCD power off the Imp.

I’ve should have said that I’ve also been using the class here:

untouched as the SerLCD driver. Strangely, same configuration and code and its been ok for the past couple of hours. I’ve added a port.flush () into the write_string () function. I’m just going to have to let it go for a few hours and see what’s happens.

Unfortunately, I’ve changed so much I’m not sure if I’ve fixed anything or not.

ok, after about an hour, the funny characters are back. I think the transition is roughly in step with 400ms update rate in the SerLCD class.

A 470ohm resister between +ve and Pin 5 (Imp Tx/SerLCD Rx) seems to have ‘fixed’ it. As soon as I take the resister out, it’s back to its strange way, back in and it stops.

@chrischi mentioned

“I had the same problem some time ago and fixed it by putting a resistor between PSB and BLA.”
although I don’t have either of those pins.

What voltage is the LCD running from? Just wondering if it’s a 5v device and expecting 5v logic levels to run it. You do have ground connected to the LCD too, right?

I have the same screen. It seemed to be fine running on either 3.3V or 5V… I didn’t experience any weirdness. I actually prefer that LCD, as the backpack is a bit smaller than the Adafruit version, (though also less featured as well, I presume).

@Hugo

The Imp and the LCD are running from the same 5v supply. It is expecting 5v logic levels to run it, and yes, it’s sharing the same 0v/gnd. The 470 ohm resistor has made it run for 6 hrs fault free.

@Joel Are you using the same SerLCD class?

Major step forward this evening. I’ve sent a command to my Heatmiser thermostat and it has responded! I’ve used blobs. It’s all hardcoded at the moment, but I’ll test some more and then a build a class round it. The CRC16 CCITT code seems to work (I found a c# implementation (without lookups or polynomials) and converted it)

`function ReadThermostat ()
{

// need to send: 07 0A 81 00 00 00 FF FF crc-lo crc-hi

local Packet = blob ()
Packet.seek (0)
Packet.writen (0x07, 'b') // Thermostat ID #7
Packet.writen (0x0A, 'b') // 10 byte packet
Packet.writen (0x81, 'b') // This (master) address #81
Packet.writen (0x00, 'b') // Read=0, Write=1
Packet.writen (0x0000, 'w') // Start address
Packet.writen (0xFFFF, 'w') // Number of bytes

local crcCCITT = 0xFFFF;
foreach (i, byte in Packet)
{
    crcCCITT = crcCCITT ^ ((byte << 8) & 0xFF00)
    local j
    for (j = 0; j < 8; j++) 
    {
        if ((crcCCITT & 0x8000) > 0)
            crcCCITT = (((crcCCITT << 1) ^ 0x1021) & 0xFFFF);
        else
            crcCCITT = crcCCITT << 1;
    }
}

Packet.writen (crcCCITT & 0xFF, 'b')
Packet.writen ((crcCCITT >> 8) & 0xFF, 'b')

pinRTS.write (1)
pThermostat.write (Packet)
pThermostat.flush ()
pinRTS.write (0)

}`

Yep, that is the class I used.