-
@d0773d Did you ever get AES working? I just tried it with the smallest JS AES code I could find (https://github.com/mdp/gibberish-aes), stripped required parts, minified it, and it ran out of memory expanding Rcon.
It isn't written for embedded devices, so I might have to port one of the Arduino ones if I can't find something.
-
Very elegant way to do it!
I was recently researching using a cheap SDR dongle for decoding 433 and came across a tool which specifically does that with various protocol support. Example:
http://goughlui.com/2013/12/20/rtl-sdr-433-92mhz-askook-decoding-of-various-devices-with-rtl_433/
It also has a feature to analyse unknown protocols.
As an aside some people have used SDR with GNU Radio to process 433 into audio and use Audacity to view the waveform: http://www.kukk.org/blog/sdr/messing-with-433mhz-equipment/
Doesn't beat a couple of quids worth of components and a bit of JS in a web browser though!
-
Hi @Vicary, this is a lot more difficult than it sounds. I investigated emulating a SD card (not with Espruino) and it was a lot of work. I found a solution for my needs (security testing) by getting a SD->USB Mass Storage adapter, and then emulating USB mass storage with a microcontroller. So it went Microcontroller(emulating USB MS)->adapter->MicroSD->Device
It was pretty slow, and the adapters were hard to find and now discontinued:
http://www.saelig.com/product/mio001.htm
Only other option I saw at the time was an expensive industrial SD card testing unit. I might have another look because it would be so useful.
An easier solution for you might be to use a USB drive to hold your root file system. Emulating a mass storage device is much easier, and I believe there might be devices that allow you to do it (I have one which selects ISOs and emulates a DVD drive).
See https://samhobbs.co.uk/2013/10/speed-up-your-pi-by-booting-to-a-usb-flash-drive
-
@Manxome in a similar way you can attach an Interrupt to a pin on, say, an Arduino, you can set a watch on a pin in Espruino. When the pin changes (rises, falls, or both) it will call your function:
-
On closer inspection, it looks like they based the receiver code on an Arduino project called RCSwitch which appears to listen for and implement 3 different protocols:
http://code.google.com/p/rc-switch/source/browse/trunk/RCSwitch.cpp
These protocols I assume cover a wide variety of those cheap Chinese 433Mhz sensors from eBay, and can "learn" them, but it is not as if it is pulling an unknown protocol out of the air. That would be too difficult with the noise as you say.
With that in mind I guess one would have to implement the protocol for whatever device(s) they are using. So the ability to have the tools/functions available to do that with fast execution is the most useful. So the native code idea sounds like the most flexible.
I am planning on getting my 433 sensors such as temp, humidity, PIR, doorbell, all hooked up to the Espruino, as well as LightwaveRF. So I'll have to figure out how to detect each protocol. This would make a cool 433Mhz sniffer project too ;)
-
Regarding transmit, the array of times would be excellent. If nothing else it simplifies it and can ensure a perfect waveform. With a slight optimisation I was able to get LightwaveRF working with a simple loop around digitalPulse, rather than eval() a string of digitalPulse commands, but it is right on the verge of being too slow.
Regarding receive, I have a device called NinjaBlock which was another Kickstarter which is a home automation and sensor hub. It is a BeagleBone with an attached Arduino cape that does 433Mhz transmit and receive.
Running on the BeagleBone was a Node.js app which talked to their cloud API. You can put the NinjaBlock into learning mode, activate a 433Mhz device such as a doorbell or PIR sensor, and it would learn it. From there you can set it to take actions, e.g. if PIR sensor then take photo and upload to Dropbox. Additionally you could send 433Mhz signals to control devices.
It supported lot of sensors and devices, mainly the cheap ones from eBay. It didn't support LightwaveRF, I guess because the protocol is a little more involved.
Anyway, this is all to say that they have managed to decode different radio signals with an Arduino, and it is open source in case some of the code is helpful:
-
Refactored this a bit and it works nicely. Now going to move my efforts to GitHub:
https://github.com/thomascannon/espruino-lightwaverf/
A humble start, but something to build from. Given it is using JS it would be nice to make it object oriented so we could do:
rooms.list; =["Study","Bedroom"] rooms("Study").allOff; rooms("Bedroom").on("Lamp");
You get the idea anyway.
-
btw, I can't help thinking that your interpretation of the protocol is how it should have been, it makes so much more sense. The encode array you created by adding a bit and turning 10 into 0 now has an obvious pattern running through it. And simply having a longer pause on a 0 is much easier. Of all the people that reversed LightwaveRF and re-implemented the protocol and you are the only one that saw it... :)
-
I got them quite some time ago when they were a fairly new entry on the market, so it could well have been priced to gain market share. I'm not in a rush to expand it so I'll have to keep an eye on prices and try to pick up a deal.
They do remember their pairing, and you can pair several remotes to a single device. They also have a lock function so you can send a message to lock the socket in an on/off state so it can't manually be switched. There is an "all on/off" message useful for turning off all the lights at night, or on in the event of a fire. Many nice features really.
-
Oh, I just looked around and the prices have really gone up at most places. I was paying £15 at most for a dimmer. I have the 2 gang dimmer in one room. The ones I have are Siemens branded, like these:
And a multipack of adaptors + remote for £18 which is reasonable:
Yes there are a couple of problems with it, security and that it is only one-way so you can't query the state of a device or get a reply that your command was successful.
Lack of security is ok for me, the most they can do is prank me by turning my lights on/off and it is unlikely someone would bother where I live.
The one-way issue is annoying, I have some house lights on a timer when I'm away to make the house look like it is occupied, but the system doesn't know if it is working. Though reliability has been close to 100% in my experience. You pay a lot more for 2-way home automation sadly.
-
It works! Thanks @Gordon, your code worked great. I realised you'd already added the byte start bit as per your comment once I traced through the code. The sigLength was of course needed, I'd forgotten to adjust that too.
So for anyone else wanting to try this, hook up the 433 to Espruino as per the tutorial on the Espruino website. Use this piece of test code:
var TX = A0; var encode = [ "1111010", "1110110", "1110101", "1110011", "1101110", "1101101", "1101011", "1011110", "1011101", "1011011", "1010111", "0111110", "0111101", "0111011", "0110111", "0101111"]; function sendNibbles(nibbles) { var repeat = 12; var cmdStream = "var p=digitalPulse;"; var sigLength = 0.5; cmdStream+="p(TX,1,0.25);p(TX,0,0.25);"; //msg start bit nibbles.forEach(function(nibble) { encode[nibble].split("").forEach(function(bit) { var length = (bit=="1")?0.25:1.25; cmdStream+="p(TX,1,0.25);p(TX,0,"+length+");"; sigLength += 0.25+length; }); }); cmdStream+="p(TX,1,0.25);"; //msg end bit sigLength += 0.25; var interval = setInterval(function() { eval(cmdStream); if (repeat-- == 1) clearInterval(interval); }, sigLength+10.25); // delay 10250us between repeats } var on = [0x0,0x0,0xf,0x1,0xf,0xe,0xf,0xe,0xf,0xe]; var off =[0x0,0x0,0xf,0x0,0xf,0xe,0xf,0xe,0xf,0xe]; var socketOn = false; setWatch(function() { socketOn = !socketOn; digitalWrite(LED2,socketOn); sendNibbles(socketOn ? on : off); }, BTN1, { repeat:true, edge:"rising", debounce:10 });
Put the LightwaveRF device into learning mode (usually hold down 1 or 2 buttons until it starts flashing).
Send the "On" message by pressing the button on the Espruino. Device should blink rapidly to indicate code accepted. Press the Espruino button again to turn the device off.
You now have control of the LightwaveRF device with the Espruino.
Now it is time to start working on a more complete implementation...
-
-
-
-
Yes, although quite cheap, it adds up really fast. I just have it in a few areas I wanted to control.
The software is pretty bad as usual, and of course you need to buy an extra expensive box with ethernet connection which does the RF and can be controlled over the network or via their website (it connects out).
-
-
Thank you, that is an amazing response and a really interesting way to look at it. I tried the code but so far it hasn't worked, it seems to remain high afterwards too. It has given me a better understanding of other approaches though.
I haven't hooked it up yet to see the output but will do so after work tonight.
-
-
Hi!
LightwaveRF is a popular 433MHz home automation product line in the UK, sold in B&Q, Maplin etc.
I have an Arduino controlling things using the same kind of 433 transmitter used in the Espruino tutorial, so I thought I'd try to port it to the Espruino at the weekend and had no luck :(
The code for the Arduino which works is here: https://github.com/lawrie/LightwaveRF/blob/master/LightwaveRF.cpp#L188
The protocol with some more accurate values for timings is described here:
https://wiki.somakeit.org.uk/wiki/LightwaveRF_RF_ProtocolI have tried timings and values from the Arduino code and also made it to spec according to the protocol. My code was orginially written to be compact and efficient but when it didn't work I rewrote it to make debugging easier. This is based on the Arduino code:
var TX = A0; function sendBits(bitStream) { bitStream.forEach(function(bit) { digitalPulse(TX,0,0.025); //delay 25us digitalPulse(TX,bit,0.28); //pulse 280us digitalPulse(TX,0,0.28); //pulse 280us if (bit === 0) digitalPulse(TX,0,0.3); //pulse 300us }); } function sendMsg(command) { var repeat = 12; var bitStream = []; bitStream.push(1); //msg start bit for (var b=0;b<10;b++) { //for 10 bytes bitStream.push(1); //byte start bit for (var i = 7; i >= 0; i--) { //split byte into bits bitStream.push( command[b] & (1 << i) ? 1 : 0 ); } } bitStream.push(1); //msg end bit var interval = setInterval(function() { //console.log(bitStream); sendBits(bitStream); if (repeat-- == 1) clearInterval(interval); }, 10.25); // delay 10250us between repeats } var on = [0xf6,0xf6,0xf6,0xee,0x6f,0xeb,0xbe,0xed,0xb7,0x7b]; var off =[0xf6,0xf6,0xf6,0xf6,0x6f,0xeb,0xbe,0xed,0xb7,0x7b]; var socketOn = false; setWatch(function() { socketOn = !socketOn; digitalWrite(LED2,socketOn); sendMsg(socketOn ? on : off); }, BTN1, { repeat:true, edge:"rising", debounce:10 });
I am pretty certain the bitStream is correct, I checked it manually. So I guess the issue is sending the bits. The LightwaveRF protocol is a bit weird, and I wrote the code several different ways. I think it is because I'm not understanding how digitalPulse is working compared to the delays in the Arduino code. For example, I set the TX to an LED and when it finished "sending" the LED remained on when surely it should be low.
Any help would be really appreciated, we could do a lot with Espruino and LightwaveRF!
-
-
Unfortunately that doesn't seem to work for me. On Espruino 1.58, the following code example works:
function onInit() { digitalWrite(LED3,0); //reset blue LED I2C1.setup({scl:B6, sda:B7}); } onInit(); var nfc = require("PN532").connect(I2C1); print(nfc.getVersion()); nfc.SAMConfig(); // start listening setInterval(function() { nfc.findCards(function(card) { print("Found card "+card); card = JSON.stringify(card); if (card=="[4,238,254,40,117,69,0]") digitalWrite(LED3,1); }); }, 1000);
If I unwrap the
onInit()
function so theI2C1.setup()
is run inline at the start, as soon as I typesave()
the Espruino reboots and I get the I2C errors. And every time it starts up after that.It does seem to set it up though:
>dump() var nfc = { "i2c":{ "_options":{"scl":B6,"sda":B7} } }; I2C1.setup({"scl":B6,"sda":B7}); digitalWrite(B6,0); pinMode(B6,"opendrain"); digitalWrite(B7,0); pinMode(B7,"opendrain");
-
Hi, I'm really enjoying playing with the Espruino but recently had a small issue, mainly due to still learning to adapt from classical µC programming style. I figure this may help someone else who Googles for the keywords I did.
I got the NFC module running well, and then wanted it to persist after reboot so typed
save()
. When it rebooted the I2C interface couldn't be brought up (INTERNAL ERROR: Timeout on I2C...
). It seems Espruino tries to restore the state when you saved it rather than re-run the program again, which was weird to me but I get it now.So I figured I'd use
delay()
to give the NFC I2C module enough time to init, but of course there isn't adelay()
function because this isn't how Espruino is supposed to work :)Anyway, I found putting some code in an
onInit()
function with the I2C init code in there, it will get run every time it powers on. This may seem obvious butonInit()
is not yet documented in the Espruino reference as far as I can see.
It would be nice to have a selection of breakout shims for SMT prototyping with I2C chips. Something like:
http://www.adafruit.com/product/1212
Would be cheap and make life easier to experiment with new chips.