Posts from: September '14
Battery tests update
I haven't updated the battery tests page for a while, but the project is not dead at all. I've been busy with other things (which I will announce here eventually), but the test database has been slowly accumulating new entries, which await to be published, so I have 1½ year backlog to push :)
There are several new things,
- A Facebook page;
- 9 new NiMH AA batteries are tested, see the changelog;
- Date of tests is now noted in the "detailed page" for each battery.
Posted in category Interesting -- 30 Sep 2014, 18:07, 0 comments
Remote control (part 2)
In the previous post I promised to tell you more about the remote control of household loads I made. But first, some background...
Last January I had to do some small house renovation, and I contacted this guy, recommended by friends, who demanded some outlandish amounts for the work. Waay above the market average. It was my mistake, of course - I had told him what I did for living. In Bulgaria, it seems, a lot of people think that programmers dig boatloads of money, so no price is too high if you client is one of those. For that reason, the guys I actually hired later had it that I work as an Electrical Engineer. The cables, breadboards and soldering iron scattered around helped with that ploy ;)
Well, it was a bit unexpected when it came to laying and connecting power wires. The workers left that to me - after all, I should be very good at this kind of stuff. In my case, I ended up with a bunch of spotlights that I had no way of connecting: the only lightswitch in the kitchen was a simple one: a live wire comes from below, and a single wire continues toward the ceiling lamp. Even if I managed to bring neutral from somewhere, I had to dig channels in the walls to reach the spotlights.
For that reason I wired the lights to regular hidden wall sockets, with lazy switches to command them. But this was all meant to be a temporary solution; it was inconvenient to operate them, and I definitely wanted a centralized lighting control, from a single switch.
In the same time, I had bought some RF modules long ago (these ones). They use a 434 MHz band and are intended for hobby work, with pins to be directly inserted into a breadboard. They are capable of transmitting "1 pin" of information - whatever voltage you send to the input pin of the transmitter gets generated on the output pin of the receiver. So the idea I got was to create a circuit that stands in the way between the hidden sockets and the spotlights, where the receiver controls a few relays. And the sender would be used into a miniature circuit, that would fit into the wallswitch socket (without any mains connection there).
As mentioned, the 434 MHz modules are hobby-oriented, and even though the interface to them is very straightforward, the abstraction they provide turns out to be a really flaky one. First, the state transmission is discretized in time - 4800 bps - so it's quite slow. I didn't need speed, so this wasn't an issue, and I initially envisioned a purely "analogue" circuit without any logic - one side has a switch, directly controlling the transmitter, and the other and has the receiver hooked up to some transistors, which command the relays. Well, probably with a RC circuit in between, to filter out any noise. But I was told by somebody about the flakyness of these modules so I went on to check the feasibility of the idea.
Indeed. When the transmitter is turned off, the receiver gets some random noise. Even when the transmitter is powered (and it was expected to be only intermittently), there were bursts of wrong bits on the receiver side - so the necessity of digital logic, employing some kind of error-correcting code, was apparent, least not if I wanted a random disco in my kitchen :)
I prototyped the two parts of this thing on a breadboard first. The sender/receiver were communicating well, and as a guard against the random noises, the transmission starts with a fixed "magic byte", which is checked for correctness at the receive end. I turned off the transmitter and must have had forgotten the receiver running for half an hour, when, to my dismay, I saw that the test LEDs powered up. The noise from the ether had managed to create the magic byte, and the transmit side interpreted the noise afterwards as a command ...
I solved that by increasing the magic bytes to four, and I send the command byte twice, for consistency checking. That got it running, but now it was not reaching every time, especially if there was a wall between the devices (these are the cases with YOU SHALL NOT PASS). I.e., the random noise apparently changes some of the bits of the magic header and the receiver drops the message. To combat that: the message gets sent 10 times, hoping that at least one should gets through.
So the prototype was working, and I went on to solder a miniaturized version of the sender::
After trimming:
The idea is that the whole thing must fit into a wall hole for a light switch - which is very limited volume indeed. Luckily for me, the designers of the transmitter module obviously had applications like mine in mind and had made it quite compact:
The perfboard is just for convenience. I could have point-to-point soldered everything:
The thing is finally connected like this:
Оff
On
An interesting problem that took me a while was how to power the thing. The transmitter requires around 8 mA at ≥3V (it gladly accepts more). But at this usage, any normal battery would drain in a week, so I turn off the transmitter when not in use, ditto for the microcontroller, and they're woken up only when needed. The standby consumption is around 0.1 µA, but the active one is a bit high for coin cells like CR2032: under load it would drop below 3V, so they got out of the question. I thought about a 3-pack of silver-oxide SR44s, which would have worked, but their capacity was too small, the device would need replacements every year or two. A similar solution would have been to use an A23 battery, but it had the same issue, and it also required a regulator. A small lithium-ion cell would have been okay on voltage and capacity, but I doubt that a rechargeable one would hold the charge for more than a year. In the end, I found out what they use in the industry for exactly these kind of things: lithium thyonil-chloride. These beasts last for decades, losing only 1% of charge per year in standby, and pack a huge amount of energy per volume. The nominal voltage is 3.6 volts, which is also welcome. The downside of this chemistry is its intolerance to short circuits: it can explode, and its contents are quite toxic. I even got an order rejected from my electronics supplier for this reason - these batteries are considered hazardous materials, so are not readily shipped. Luckily, another supplier had them in stock, even if the smallest size he had was unnecessarily big for my application.
After the transmitter was ready and tested, I got to make the real receivers as well (I needed two, for the two sides of the kitchen).
Here the perfboard would have been ugly and dangerous - having line voltages on random tracks and sticking wire ends is a no-no. So I designed, and LUBO_1 printed me, PCBs for the purpose:
Added: relays, a rectifier, and a fuse holder:
The rest of the electronics:
In the beginning I fitted these fuses:
0.5 amp ones, which should have been enough for my 80 W spotlights. However, loads like this - lamps, especially incandescent ones - have a huge initial surge current, and the fuses blew almost right away. Lesson learned, I bought and installed slow-acting ones.
The receiver is ready:
I made two copies:
Note that the PCBs are identical - they both have tracks routed for four channels. The first board has a relay and transistor only for channel 1, the second has for channels 2 & 3.
The PCB solves the problem with the line voltages dangling around. Nothing can electrocute you on the upper side. For the back side, I had 4 adhesive rubber pads (which I had randomly picked from Lidl, one of these purchases where you regretted you didn't buy more), so the solder joints are also not touching anything potentially conductuve below. I realized afterwards that the fuse holder and the fuse itself are still at line voltages and went on to search for a solution... and indeed, they have standardized plastic covers for these holders:
plastic cover for fuse holder - standardization ftw
The two receivers, ready for mounting:
Channels 2 & 3:
Channel 1:
The digital control logic has its obvious advantages. I programmed a self-timer to turn off the lights if I forgot them for more than 1½ hours.
So this is the main system. For the fun of it, I decided to make a computer-controlled transmitter, as it was shown in the previous post. There are a lot of ways to connect a PC with a microcontroller, but one of the simplest is to use a parallel port. Sadly, these wonderful things are phased away, but I still have a somewhat old home server laying around... The interesting part here is how I managed to power the sending device from the parallel port directly. As you know, unlike USB, the parallel port interface has no power lines, but it's still possible to "steal" a small amount of current though the data pins. The limit is really small, like 2mA in the strictest specs, but usually you can get around 8-10 mA per pin. Just in case, I wired up four of the eight pins just for power (after a schottky diode each) - so I have 8-40 mA at my disposal for powering the transmitter. When you programmatically send a byte through the parallel port and you set the 4 least significant bits, my device there detects that it's fully powered and turns on the transmitter. The higher four bits/pins are used for communications. Commanding the parallel port is made easy by libieee1284, interfaced though a small C program on Linux. And, of course, I did a simple webinterface, that runs on an apache server. So now, I can control my spotlights (or any other load if I wish) via a wall switch, using a smartphone or a tablet, through ssh, or even periodically via cron...
The hardware of this thing is till on breadboard:
Here's the connection to the server:
I was slightly worried whether the RF would work, since the server and the receivers are in different rooms and the signal must go through two walls. Luckily, it seems that the send-ten-times thing works even here.
So.
In the future I plan to utilize more high-level communication modules, e.g. ZigBee, since coding and debugging noise-proof protocols is not as much fun as it seems. For example, while testing the computer interface, I had a very weird issue. There was no way to turn on the first channel, only to switch it off, if you sent a command for switching off the THIRD one. And also, commands for channel 1 affected channel 2, and commands for 2 affected 3. In the beginning it seemed like a simple bug, but after reviewing each part of the stack that turned not to be the issue. It was just... the tranmitter sending out the bits slightly too fast (which I discovered through trial and error). This is a common theme actually - when you have only one pin for communication, you need to make your protocol self-clocking, i.e., you need to ensure that the two endpoints don't go out of sync. UART does this by employing start and stop bits, but I was sending bits verbatim, since, gee, what could possibly go wrong for 48 bits? In the end, slightly lenghtening one delay solved it. So indeed, are you still thinking that printf-debugging, or through a terminal with gdb is painful, ugly, and obsolete? Meh.
Posted in category Hardware -- 12 Sep 2014, 01:09, 5 comments
Remote Control (part 1)
How it looks like:
And what actually happens under the hood:
Finger: poke!
Touchscreen to driver: we have a registered press on row 16, line 3.
Driver: Will wait a bit to see what happens...
after a bit...
Driver to kernel: got a press, you interested?
Kernel: really? I was just about to send some very important data to NSA...
Driver: interrupt that for a while, the human is pressing something.
Kernel: what kind of press? Single, double, does it move?
Driver: no movement, it's a single press, coordinates are (36, 388)
Kernel: does he hold it?
Driver: no, he already got his finger off the screen.
Kernel: OK.
Kernel to UI layer: you have a single press at (36, 388)
UI layer: this is in the application area. Browser, you have a single press at (36, 356)
Browser: I have a press on one of the pictures, but it has an image map on it, with some javascript behind. And an onClick handler - Javascript, go ahead.
Javascript: first, can you please change the picture to "i/on.png"?
Browser: got it cached, will change it.
Javascript: second, please send this GET request to command.py on the same site/folder. Parameters apply - channel=1&state=1.
Browser: sending right in, will notify you when I get a response.
Browser to kernel: can you open up a TCP connection to 192.168.0.40, port 80?
Kernel: OK
Kernel to wireless card: there you have this SYN packet, can you please forward it to 192.168.0.40? Oh well, you're actually interested in its MAC address, it is, lemme see, 00:1C:C0:BF:87:A1.
Wireless card: done.
Invisible, inappreciable electomagnetic waves, indistinguishable from the surrounding ones, shoot up in to the ether amongst the rest of the natural and artificial noise. Microscopic, short-lived voltages reflect of the walls, fly through the air and wake up an unsuspecting router...
Router: whoa, a packet? It's not for me, though, but I know this 00:1C:C0:BF:87:A1 MAC - it lives at port 2, redirecting.
Switch/server room: incoming packet from port 5... addressed to 00:1C:C0:BF:87:A1. I know him, he's on port 1, redirecting.
Network card to kernel: you've got an incoming packet.
Kernel: this is an IP packet from 192.168.0.101. The firewall says we have to let it in. What's in there? Aah, a TCP to port 80.
Kernel to webserver: you still listening?
Webserver: yes!
Kernel: good. Will send a SYN-ACK back.
Kernel to network card: A packet please, the destination is D4:22:3F:81:03:9E.
Network card: sending.
Switch/server room: now a packet from port 1... addressed to D4:22:3F:81:03:9E, I know him, he's on port 5, redirecting.
Router: a packet, D4:22:3F:81:03:9E is known - he's on the wireless interface.
Invisible, inappreciable electomagnetic waves, indistinguishable from the surrounding ones, shoot up in to the ether amongst the rest of the natural and artificial noise...
Wireless card to kernel: we've got a package from router.
Kernel to wireless card: great, they replied to our SYN. Send them an ACK.
Browser: send them this HTTP GET packet as well, pls.
Wireless card: I'm on it.
Invisible, inappreciable electomagnetic waves ... you get the drill
Router: two packets for 00:1C:C0:BF:87:A1 - port 2, redirecting.
Switch/server room: two packets for 00:1C:C0:BF:87:A1 from port 5, redirecting to port 1.
Network card to kernel: we've got two packets incoming
Kernel to network card: give them to me!
Network card: in what order?
Kernel: I don't care.
Network card: here's the first one.
Kernel: wtf? This is some data, from a connection that is not yet opened. Give me the other packet.... oh well, here's the ACK, it all makes sense now.
Kernel to webserver: incoming connection, do you want it?
Webserver: yes, please.
Kernel: here.
Webserver: okay, they want to fetch http://192.168.0.40/widlar/command.py, with parameters channel=1&state=1. Looking at my config, this has to be a CGI script.
Webserver to Python: you've got an incoming connection, tell me what should I send back?
Python: where is this connection from?
Webserver: 192.168.0.101
Python: they are from the internal network, good. Are there any parameters?
Webserver: yeah, channel=1, state=1.
Python: okay, the channel is set. Is it in [0..3]? Yes. State? [0..1]? Yes. All good, time to call this small C program.
Small C program: huh, somebody started us. We've got parameters! First is '1', is it within [0..3]? Yes. The second? '1', it is in [0..1]. All good.
Small C program to kernel: can I access the parallel port?
Kernel: do you have the necessary privileges?
Small C program: yes, I'm from the apache group.
Kernel: Let's see... okay, have this port descriptor.
Small C program: I want exclusive access, and please send the value 0x5f to the port.
Kernel: deal.
Microcontroller/server room: yawn. Somebody powered me, I betcha they want me to do something. I've got power on three..., not - four pins. This is serious business, I'll power up the transmitter
Small C program: you ready?
Microcontroller/server room: yeah.
Small C program to kernel: send the value 0xdf to the parallel port.
Kernel: done.
Microcontroller/server room: look, they changed the most significant bit, so the command is real. Let's see... we need to set channel 1 to state 1...
Microcontroller to transmitter: can you please send this series of bits via the RF link?
Transmitter: I'm on it
Invisible, inappreciable electomagnetic waves, indistinguishable from the surrounding ones, shoot up in to the ether amongst the rest of the natural and artificial noise...
Reinforced concrete wall: YOU SHALL NOT PASS!
Microcontroller to transmitter: send them again, we can't be sure if the got through...
Transmitter: good.
Reinforced concrete wall: YOU SHALL NOT PASS!
Microcontroller to transmitter: once again...
Transmitter: OK
Microcontroller/kitchen: well, there's some activity lately, as if somebody tries to talk to us, but some of the bits are corrupted. Here, this is the third time I'm seeing the header... and... wait, this time it is OK! So there's a command, let's see. Channel 1 = on. We light up channel 1 then, it's currently off.
Microcontroller/kitchen to Q2: hey, transistor, how's it going?
Transistor Q2: I'm keeping the electrons at the source right now.
Microcontroller/kitchen: let them through.
Transistor to relay: there's a pack of electrons coming to you - just that you know.
Relay: Click!
Electricity: whoa, I've discovered a new path. What could be there? Let's see.... crap, a switching power supply. I hate switching power supplies!
Switching power supply to lights: shine you bastards!
As you can see, I'm having fun with RF modules and their use for some home automation/smart house things. Please visit part 2, where I'm describing the components of this system in more detail, along with pictures.
Kudos to Misho Stanchev for the JS part.
This post strives to be both fun and technically accurate. Report any errors in the comments.
Posted in category Hardware -- 10 Sep 2014, 01:17, 3 comments