-
• #27
Debounce of 0.35 helps, but still usually gets FIFO_FULL. Going higher than that causes it to fail to recognize messages, which is strange, seeing as the message pulses should be 0.6ms long. I have a few ideas to try tomorrow.
However, during the transmissions and receiving, it performs beautifully! I've successfully received transmissions up to 30 bytes long so far (240 bits!), and expect to be able to go higher so while it's receiving, its clearly handling the input just fine.
-
• #28
Wow, that really is good! Thanks for the update...
This should make a really cool module :)
-
• #29
But i'd be interested to see what's up with debounce - it could be an implementation issue I guess...
-
• #30
changed sigOff() a bit, so it should still count it, even if the next bit of noise looks like a bit.
function sigOff(e) { var d=e.time-e.lastTime; if (d>0.0005 && d<0.0013) n+=d>0.0008?1:0; else{ n=""; } if (n.length==z) parseRx(n); }
z is global variable with the bit size of the packet being received.
>runTest4(32,5,0); =undefined Listening started 0110010001100101011001100110011101101000011010010110101001101011011011000110110101101110011011110111000001110001011100100111001101110100011101010111011001110111011110000111100101111010011110110111110001111101011111100111111110000000100000011000001010000011 B0:100 B1:101 B2:102 B3:103 B4: 104 B5: 105 B6: 106 B7: 107 B8:108 B9:109 B10:110 B11:111 B12: 112 B13: 113 B14: 114 B15: 115 B16:116 B17:117 B18:118 B19:119 B20: 120 B21: 121 B22: 122 B23: 123 B24:124 B25:125 B26:126 B27:127 B28: 128 B29: 129 B30: 130 B31: 131
Starting transmit 32 byte payloadTransmit 3 called... B0: 100 B1: 101 B2: 102 B3: 103 B4: 104 B5: 105 B6: 106 B7: 107 B8: 108 B9: 109 B10: 110 B11: 111 B12: 112 B13: 113 B14: 114 B15: 115 B16: 116 B17: 117 B18: 118 B19: 119 B20: 120 B21: 121 B22: 122 B23: 123 B24: 124 B25: 125 B26: 126 B27: 127 B28: 128 B29: 129 B30: 130 B31: 131 Payload generated. Sending round 0 Sending round 1 Sending round 2 Sending round 3 Sending round 4 Transmit done
sendRaw([0xC0,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130],5);
(first byte is being used as a signal as to what the size of the transmission is)
256 Receive done Parsing long packet 192 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 Done
Test code:
var txpin=C7; var rxpin = C6; var n=""; var wf; var z=32; //This is the length of packet to receive, in bits. function sendRaw(dat,rep) { rep=rep?rep:5; var l=dat.length; var d = digitalPulse; var p=txpin; var h; for (var v=0;v<rep;v++) { for (i = 0; i < 25; i++) { d(p,1,0.4); d(p,0,0.4); } d(p,1,0.5); //end training burst d(p,0,2); for (var j=0;j<l;j++) { h=dat[j]; for (k=7;k>=0;k--) { d(p,1,((h>>k)&1)?1.1:0.6); d(p,0,0.65); } } d(p,0,0); } digitalWrite(txpin,0); } function sigOff(e) { var d=e.time-e.lastTime; if (d>0.0005 && d<0.0013) n+=d>0.0008?1:0; else{ n=""; } if (n.length==z) parseRx(n); } function parseRx(rcv) { console.log(rcv); stopListen(); var b3=parseInt(rcv.substr(24,8),2); var b2=parseInt(rcv.substr(16,8),2); var b1=parseInt(rcv.substr(8,8),2); var b0=parseInt(rcv.substr(0,8),2); var b4=parseInt(rcv.substr(32,8),2); var b5=parseInt(rcv.substr(40,8),2); var b6=parseInt(rcv.substr(48,8),2); var b7=parseInt(rcv.substr(56,8),2); var b8=parseInt(rcv.substr(64,8),2); var b9=parseInt(rcv.substr(72,8),2); var b10=parseInt(rcv.substr(80,8),2); var b11=parseInt(rcv.substr(88,8),2); var b12=parseInt(rcv.substr(96,8),2); var b13=parseInt(rcv.substr(104,8),2); var b14=parseInt(rcv.substr(112,8),2); var b15=parseInt(rcv.substr(120,8),2); var b16=parseInt(rcv.substr(128,8),2); var b17=parseInt(rcv.substr(136,8),2); var b18=parseInt(rcv.substr(144,8),2); var b19=parseInt(rcv.substr(152,8),2); var b20=parseInt(rcv.substr(160,8),2); var b21=parseInt(rcv.substr(168,8),2); var b22=parseInt(rcv.substr(176,8),2); var b23=parseInt(rcv.substr(184,8),2); var b24=parseInt(rcv.substr(192,8),2); var b25=parseInt(rcv.substr(200,8),2); var b26=parseInt(rcv.substr(208,8),2); var b27=parseInt(rcv.substr(216,8),2); var b28=parseInt(rcv.substr(224,8),2); var b29=parseInt(rcv.substr(232,8),2); var b30=parseInt(rcv.substr(240,8),2); var b31=parseInt(rcv.substr(248,8),2); console.log("B0:"+b0+" B1:"+b1+" B2:"+b2+" B3:"+b3+" B4: "+b4+" B5: "+b5+" B6: "+b6+" B7: "+b7); console.log("B8:"+b8+" B9:"+b9+" B10:"+b10+" B11:"+b11+" B12: "+b12+" B13: "+b13+" B14: "+b14+" B15: "+b15); console.log("B16:"+b16+" B17:"+b17+" B18:"+b18+" B19:"+b19+" B20: "+b20+" B21: "+b21+" B22: "+b22+" B23: "+b23); console.log("B24:"+b24+" B25:"+b25+" B26:"+b26+" B27:"+b27+" B28: "+b28+" B29: "+b29+" B30: "+b30+" B31: "+b31); } function startListen() { wf=setWatch(sigOff,C6,{repeat:true,debounce:0.35,edge:"falling"}); console.log("Listening started"); } function stopListen() { if (wf) {clearWatch(wf);} wf=0; n=""; } function runTest(add,inc) { z=32; var csc=31^0xF2^add; csc=(csc&15)^(csc>>4)^inc; sendRaw([31,0xF2,add,((inc<<4)+csc)],5); setTimeout("startListen()",400); setTimeout("stopListen()",2500); } function runTest4(datalength,replyrepeat,sub) { z=datalength*8-sub; var csc=31^0xF4^datalength; csc=(csc&15)^(csc>>4)^replyrepeat; sendRaw([31,0xF4,datalength,((replyrepeat<<4)+csc)],5); setTimeout("startListen()",400); setTimeout("stopListen()",2500); } function sendLong4() { sendRaw([0x40,100,101,102],5); } function sendLong8() { sendRaw([0x40,100,101,102,103,104,105,106],5); } function sendLong16() { sendRaw([0x80,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114],5); } function sendLong32() { sendRaw([0xC0,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130],5); }
And on the Arduino:
[#define](https://forum.espruino.com/search/?q=%23define) ListenST 1 [#define](https://forum.espruino.com/search/?q=%23define) CommandST 2 [#define](https://forum.espruino.com/search/?q=%23define) TransmitST 3 [#include](https://forum.espruino.com/search/?q=%23include) <EEPROM.h> [#define](https://forum.espruino.com/search/?q=%23define) rxpin 19 [#define](https://forum.espruino.com/search/?q=%23define) txpin 18 unsigned char MyAddress=31; byte lastPinState; unsigned long lastPinHighTime; unsigned long lastPinLowTime;; unsigned long lastTempHighTime=0; unsigned long lastTempLowTime=0; unsigned char rxdata; byte lastTempPinState; int bitsrx; int rxing; int MyState; unsigned char MyCmd; unsigned char MyParam; unsigned char MyExtParam; unsigned long curTime; int count=0; int badcsc=0; int pksize=32; char rxaridx; unsigned char txrxbuffer[32]; byte TXLength; void setup() { lastPinState=0; lastPinLowTime=0; lastPinHighTime=0; rxdata=0; bitsrx=0; rxing=0; MyState=2; Serial.begin(9600); } void loop() { curTime=micros(); if (MyState==ListenST) { onListenST(); } else if (MyState==CommandST){ onCommandST(); } else { MyState=ListenST; //in case we get into a bad state somehow. } } void onCommandST() { if (MyCmd==0xF2) { Serial.println("Starting transmit info"); prepareEEPReadPayload(); delay(500); doTransmit(5); ClearCMD(); MyState=1; } else if (MyCmd==0xF4) { Serial.println("Starting transmit"); Serial.print(MyParam); Serial.print(" byte payload"); prepareTestPayload(); delay(500); doTransmit(MyExtParam); ClearCMD(); MyState=1; } else { Serial.println("Invalid command type"); ClearCMD(); MyState=1; } } void prepareEEPReadPayload() { unsigned char Payload1=EEPROM.read(MyParam); unsigned char Payload2=EEPROM.read(MyParam+MyExtParam); unsigned char oldcsc=((MyAddress&0xF0)>>4)^(MyAddress&0x0F)^(0x0F)^(0x02)^((MyParam&0xF0)>>4)^(MyParam&0x0F)^(MyExtParam&0x0F); txrxbuffer[0]=MyAddress; txrxbuffer[1]=EEPROM.read(MyParam); txrxbuffer[2]=EEPROM.read(MyParam+MyExtParam); unsigned char csc=((MyAddress&0xF0)>>4)^(MyAddress&0x0F)^((MyCmd&0xF0)>>4)^(MyCmd&0x0F)^((MyParam&0xF0)>>4)^(MyParam&0x0F)^(oldcsc&0x0F); txrxbuffer[3]=oldcsc<<4+(csc&0x0F); TXLength=4; } void prepareTestPayload() { Serial.println("prepareTestPayload called..."); for (byte i=0;i<MyParam;i++) { txrxbuffer[i]=100+i; Serial.print("B"); Serial.print(i); Serial.print(": "); Serial.println(txrxbuffer[i]); } Serial.println("Payload generated."); TXLength=MyParam; } void doTransmit(int rep) { for (byte r=0;r<rep;r++) { //now we start sending; //Serial.print("Sending round "); //Serial.println(r); //delay(10); for (byte j=0; j < 30; j++) { delayMicroseconds(400); digitalWrite(txpin, 1); delayMicroseconds(400); digitalWrite(txpin, 0); } delayMicroseconds(2000); for (byte k=0;k<TXLength;k++) { //send a byte for (int m=7;m>=0;m--) { digitalWrite(txpin, 1); if ((txrxbuffer[k]>>m)&1) { delayMicroseconds(1100); } else { delayMicroseconds(600); } digitalWrite(txpin, 0); delayMicroseconds(650); } //done with that byte } //done with sending this packet; digitalWrite(txpin, 0); //make sure it's off; delayMicroseconds(2000); //wait 2ms before doing the next round. } Serial.println("Transmit done"); TXLength=0; } void ClearCMD() { MyParam=0; MyExtParam=0; MyCmd=0; } void onListenST() { byte pinState=digitalRead(rxpin); if (pinState==lastPinState) { return; } else { lastPinState=pinState; } if (pinState==0) { lastPinLowTime=curTime; unsigned long bitlength=lastPinLowTime-lastPinHighTime; if (bitlength > 1500) { resetListen(); return; } else if (rxing==1) { if (bitlength > 475 && bitlength < 650) { rxdata=rxdata<<1; } else if (bitlength > 1000 && bitlength < 1150 ) { rxdata=(rxdata<<1)+1; } else { resetListen(); return; } bitsrx++; if (bitsrx==2) { pksize=32<<rxdata; } else if (bitsrx==8*(1+rxaridx)) { txrxbuffer[rxaridx]=rxdata; rxdata=0; rxaridx++; if (rxaridx*8==pksize) { Serial.println(bitsrx); Serial.println("Receive done"); Serial.println(pksize); if (pksize==32) { parseRx(txrxbuffer[0],txrxbuffer[1],txrxbuffer[2],txrxbuffer[3]); } parseRx2(txrxbuffer,pksize/8); resetListen(); } } return; } } else { lastPinHighTime=curTime; if (lastPinHighTime-lastPinLowTime > 1900 && lastPinHighTime-lastPinLowTime <2100 && rxing==0) { rxing=1; return; } if (lastPinHighTime-lastPinLowTime > 800 && rxing==1) { Serial.println(bitsrx); resetListen(); return; } } } void resetListen() { //Serial.print("end"); bitsrx=0; rxdata=0; rxing=0; rxaridx=0; } //Just for test/debug purposes; void parseRx2(unsigned char rxd[],byte len) { Serial.println("Parsing long packet"); for (byte i=0;i<len;i++) { Serial.println(rxd[i]); } Serial.println("Done"); } void parseRx(unsigned char rcvB0,unsigned char rcvCmd,unsigned char rcvParam,unsigned char rcvB3) { Serial.println("Parsing: "); unsigned char rcvAdd=rcvB0&0x3F; unsigned char rcvExtParam=(rcvB3>>4); unsigned char calccsc=(rcvB0^rcvCmd^rcvParam); calccsc=(calccsc&15)^(calccsc>>4)^rcvExtParam; rcvB3=rcvB3&15; if (calccsc==rcvB3) { if (rcvCmd==200) { Serial.print(count); Serial.println(" received."); count=0; Serial.print(badcsc); Serial.println(" ."); badcsc=0; } else { count++; MyCmd=rcvCmd; MyParam=rcvParam; MyExtParam=rcvExtParam; MyState=CommandST; Serial.println(rcvCmd); Serial.println(rcvParam); Serial.println(rcvExtParam); Serial.println(MyState); } Serial.println("Valid transmission received!"); } else { Serial.print(calccsc); Serial.println("No good!"); badcsc++; } }
As you can see, the Arduino code could still use some tidying.
The arduino side needs some serious tidying - I'd like to turn both sides into a generic skeleton that can just send and receive data.
Edit: Did a lot of that tidying. I need to put some thought into how I name variables, in general, because pulling them out of my ass as I need them like I've (obviously) been doing doesn't produce pleasing nor easy to maintain code. I also need to find a graceful solution to tabs vs spaces. I prefer tabs, but arduino IDE does 2 spaces.
And from there, extend my parsing to work on 8/16/32 byte packets, doing checksum, device address checking, etc, and then I can get down to making something with it.
-
• #31
On the JS side, you could do something like:
var names = ["foo","bar","..."]; var obj = {} names.forEach(function(n,i) { obj[n] = parseInt(rcv.substr(8*i,8),2); });
could be a really neat tidy way of making an object with your data?
-
• #32
Don't know if this is handy or not, but I have some really simple code online that will decode 433Mhz signals and then send the results up to Xively: http://forum.espruino.com/conversations/258645/#comment11985738
Could be pretty handy for doing cheap wireless sensors.
-
• #33
Finally got my 433s to not sit around anymore... but for a different project I'm looking into. A real project in the field - literally: sensors in fields around a agriculture utility building/ installation. The sensors are up to 500 feet away from a central node sitting on top of the utility building.
First thing is to get some hands-on with the wireless communication - in two parts:
- suitable antennas: 1/4 L ground planes for the transmitters and Slim Jim / J-pole for the receiver. None of them are directional. I may end up with directional ones for the transmitters.
- Explore software options to validate distance - first within 10s of feet - using simple (tuned) wire antennas.
Latter was so far doomed... I used the 433 Espruino modules but I got nothing across... with vaious pairs (3)... so I looked into what the receiver actually puts out... and from some base analysis I may get a few bps going... like: blink - on/off - the transmitter and see the same LED on/off pattern on the receiver side. I used 2 PICOS, transmitter on 5V USB for one models, 3.3V on the other models. With first model I could go up to 12V.
The disheartening experience already over short distance made me quickly forget the 433 ASK/OOK modulation and go for something real, like LoRa... Sure, I could pour over the various code options and use dedicated hardware on the receiver side... may be that I should be glad for the early failure...
Now I'm waiting for the arrival of the new hardware. The ground plane antennas I can reuse. They need just retrimning: cutting the wip and radials to the new, higher frequency. Same for the J-pole and adjusting its feed point.
- suitable antennas: 1/4 L ground planes for the transmitters and Slim Jim / J-pole for the receiver. None of them are directional. I may end up with directional ones for the transmitters.
Yep - especially where seconds/milliseconds are concerned, pretty much everything can be fractional.