You are reading a single comment by @DrAzzy and its replies. Click here to read the full conversation.
  • 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.

About

Avatar for DrAzzy @DrAzzy started