Test sending code on Espruino side - this was what I was using for testing different training bursts. Can also just be used to benchmark signal integrity. Sends 32-bit packets - 28 bits data, 4 bits checksum. Bad checksums are rare, but not unheardof.
var txpin=A1;
function sendCmd(add,cmd,param,ext) {
ext=ext?ext&15:0;
var csc=add^cmd^param;
csc=(csc&15)^(csc>>4)^ext;
var b=(add<<20)+(cmd<<12)+(param<<4)+ext;
var d = digitalPulse;
var p=txpin;
for (i = 0; i < tp; i++) {
d(p,1,op);
d(p,0,zp);
}
d(p,1,0.5); //end training burst
d(p,0,2);
//send 1s or 0s, and pause
for (j=27;j>-1;j--) {
d(p,1,((b>>j)&1)?1.1:0.6);
d(p,0,0.65);
}
for (j=3;j>-1;j--) {
d(p,1,((csc>>j)&1)?1.1:0.6);
d(p,0,0.65);
}
// wait for finish
d(p,0,0);
digitalWrite(p,0);
}
function testRun(train,opp,zpp,number,interval) {
tp=train;
op=opp;
zp=zpp;
var ad=Math.round(255*Math.random());
var pr=Math.round(255*Math.random());
var cm=Math.round(198*Math.random());
var ex=Math.round(16*Math.random());
inter=setInterval("sendCmd(ad,cm,pr,ex);ad=pr=Math.round(255*Math.random());cm=Math.round(198*Math.random());ex=Math.round(16*Math.random());",interval);
setTimeout("clearInterval(inter);",number*interval);
setTimeout("sendCmd(31,200,150,10);console.log('done')",(number+5)*interval);
}
Test receiving code on Arduino side:
[#define](https://forum.espruino.com/search/?q=%23define) rxpin 19
int lastPinState;
unsigned long lastPinHighTime;
unsigned long lastPinLowTime;;
unsigned long lastTempHighTime=0;
unsigned long lastTempLowTime=0;
unsigned long rxdata;
int lastTempPinState;
int bitsrx;
int rxing;
int MyState;
unsigned long curTime;
int count=0;
int badcsc=0;
void setup() {
lastPinState=0;
lastPinLowTime=0;
lastPinHighTime=0;
rxdata=0;
bitsrx=0;
rxing=0;
MyState=2;
Serial.begin(9600);
}
void loop() {
curTime=micros();
onListenST();
}
void onListenST() {
int 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;
//Serial.print("F");
//Serial.println(bitlength);
} else if (bitlength > 1000 && bitlength < 1150 ) {
rxdata=(rxdata<<1)+1;
//Serial.print("T");
//Serial.println(bitlength);
} else {
resetListen();
return;
}
bitsrx++;
if (bitsrx==32) {
Serial.print("Got 32 bits ");
Serial.print((rxdata>>24)&0xFF);
Serial.print(":");
Serial.print((rxdata>>16)&0xFF);
Serial.print(":");
Serial.print((rxdata>>8)&0xFF);
Serial.print(":");
Serial.println((rxdata)&0xFF);
Serial.println(rxdata);
parseRx(rxdata);
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;
}
void parseRx(unsigned long rxd) {
Serial.println("Parsing: ");
unsigned char rcvB0=(rxd>>24)&0xFF;
unsigned char rcvCmd=(rxd>>16)&0xFF;
unsigned char rcvParam=(rxd>>8)&0xFF;
unsigned char rcvB3=(rxd)&0xFF;
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++;
}
Serial.println("Valid transmission received!");
} else {
Serial.print(calccsc);
Serial.println("No good!");
badcsc++;
}
}
I settled on a 20ms training burst with 0.4ms up 0.4ms down. Bit lengths were adjusted a bit from earlier to better balance the duty cycle, which might become more relevant if i was sending longer packets. I decided to structure the command as:
var txpin=A1;
function sendCmd(add,cmd,param,ext) {
ext=ext?ext&15:0;
var csc=add^cmd^param;
csc=(csc&15)^(csc>>4)^ext;
var b=(add<<20)+(cmd<<12)+(param<<4)+ext;
var d = digitalPulse;
var p=txpin;
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);
//send 1s or 0s, and pause
for (j=27;j>-1;j--) {
d(p,1,((b>>j)&1)?1.1:0.6);
d(p,0,0.65);
}
for (j=3;j>-1;j--) {
d(p,1,((csc>>j)&1)?1.1:0.6);
d(p,0,0.65);
}
// wait for finish
d(p,0,0);
digitalWrite(p,0);
}
Also - what a difference an antenna makes. Just poking a dupont male jumper into that hole (no solder or anything) and letting it dangle has a huge effect on packet loss...
Espruino is a JavaScript interpreter for low-power Microcontrollers. This site is both a support community for Espruino and a place to share what you are working on.
Test sending code on Espruino side - this was what I was using for testing different training bursts. Can also just be used to benchmark signal integrity. Sends 32-bit packets - 28 bits data, 4 bits checksum. Bad checksums are rare, but not unheardof.
Test receiving code on Arduino side:
I settled on a 20ms training burst with 0.4ms up 0.4ms down. Bit lengths were adjusted a bit from earlier to better balance the duty cycle, which might become more relevant if i was sending longer packets. I decided to structure the command as:
2 bits (reserved)
6 bits (device address)
8 bits (command)
8 bits (params)
4 bits (extended params)
4 bits (checksum)
And the parserx will be:
Also - what a difference an antenna makes. Just poking a dupont male jumper into that hole (no solder or anything) and letting it dangle has a huge effect on packet loss...