hi ive attached a larger view of the data from the logic anaylyser it clearly shows the state of things before and after transmision.
Attachment
Good pic, it tells all.
I’ve marked it up as I did before, with a logic 1/0 determination at the end of each bit shown … for the bits clocked. I’ve super-imposed a constant clock, as shown in red. Obviously some 0 bits at the tail end never get clocked and so must be assumed and added until the message length of 70 bits is reached.
(click on to opan and enlarge)
My datastream from the above agrees w/yours. Yea!
1111111110 01 11101000 01 01100001 01 01110101 01 00111110 01 00010001 01 11110000
…E8…61…75…3E…11…F0
You can also get a ‘high’ pulse count/measurement from the above bitstream. Time how long each logic level 1 pulse lasts btw the zero levels. Let’s assume you measure a pulsewidth of 500 usec for all of the first few bits. You could then measure all the PWs in the stream and express them as a ratio to the 500 usec nominal PW. That’s also shown above (2nd line for PWs > 1). Those normalized PWs, for the pic above, would be ;
11111111151113931933113335111157731111?? (the last PW (??) is the ‘time out’ PW for the pulseIn() function (>>> any normal PW).
It can be seen that for any measured PW ~= to a nominal PW, you should translate that into a bit = logic 1. For a longer measured PW, divide the measured PW by the nominal PW, round/truncate, subtract 1, then divide by 2. That result is the number of 0’s you should have/append. Then append one logic 1 to the end of that. For example a measured PW = 9nPWs = (9-1)/2 = 4 zeros plus 1 one = 00001.
A sequence of PWs, normalized to a 500 usec PW, might be 1,1,1,3,9. That would be translated, using the above rules, from those normalized PWs into a datastream, = 11101000 01. That’s your decoded E8 plus 2 bits of separator.
So now you need code to do the above … and then some.
Hi thanks for the help, im beginning to think its too complicated for me to tackle, I think i will try to find someone else to carry on with this project or forget it.
Just remembered another Arduino code example that would be useful to study to read and decode this data stream. It is the VirtualWire for using those OOK transmitter/receivers. Details are here:
Decoding that message is really a pretty simple task and ideal for the Arduino environment, but it would require access to the data stream for testing. If you post this problem on the very active Arduino forum http://forum.arduino.cc, you might even find someone in your area to help. The forum also has a “gigs and collaborations” section where you can hire help.
See if you (or your someone else) can follow the code below. It's written for an Uno-like Arduino, using an external interrupt (on pin 2) for the data input. It's one possible way to decode the message. I had thought that I could use the existing pulseIn() function to measure the bitstream's pulsewidths (PWs) and then get the 1's and 0's from those PWs, per my prior diagram (above). Turned out to be a bit more of a head-scratcher than I had estimated but still do-able. I did find out that the existing pulseIn() function doesn't timeout as I expected, so I had to make my own function to measure PWs. Perhaps the alternate technique of timing and clocking the bits in directly would have been easier afterall. :doh:Sparky99:
Hi thanks for the help, im beginning to think its too complicated for me to tackle, I think i will try to find someone else to carry on with this project or forget it.
In any case the code is what it is. No doubt it could be made more efficient. There are validity checks and timing wrapover code I’d add to make it less error prone and more ‘finished’. I did test it w/simulated measured PWs, those parts to turn PWs into printed hex data work. I’ve yet to check that my PW measuring code works as intended. I’m very unsure I can attach 2 ISRs as I’ve have. I am sure that could be fixed using a single ISR and a CHANGE condition. But if you have the telescope and an Uno … :mrgreen:
EDIT: Why not just make it use a single ISR and avoid any problem ? DONE !
baseline, ver 0.1
//declare the constants
const byte INpin = 2; //input pin that receives signal from telescope
const int startPos[] = {
12, 22, 32, 42, 52, 62}; //position of 1st data bits in zero indexed array
const unsigned long timeout = 20000; //longest valid data pulse ~11 msec
//declare the variables
boolean printed = false;
byte temp = 0;
byte normPW[70];
byte bitstream[70];
byte pulseCNT = 0;
byte bitCNT = 0;
byte databyte[6];
unsigned int loopCNT = 0;
unsigned long pulseWidth[70];
unsigned long avePW = 0;
volatile boolean running = false;
volatile boolean MSGincoming = false;
volatile unsigned long stime = 0;
volatile unsigned long PWmicros = 0;
void setup(){
Serial.begin(9600);
pinMode(INpin, INPUT_PULLUP);
attachInterrupt(0, ISR_changing, CHANGING);
reset();
}
void loop(){
//measure the high PW
//trap code in loop until end of transmission
measurePW();
//Exit the above while after pulse times out, end of message
//now figure out the average pulsewidth
//add up first 8 PWs
if(printed == false){
for(int i = 0; i < 8; i++){
avePW += pulseWidth[i];
}
//now divide by 8
avePW = avePW / 8;
avePW = avePW - 40; //shorten avePW a little so truncation works
//now construct an array of normalized PWs
for(int i = 0; i < pulseCNT; i++){
normPW[i] = pulseWidth[i]/avePW; //stick with integer math
}
//now reconstruct bitstream content of 1's and 0's
for(int i = 0; i < pulseCNT; i++){
if(normPW[i] == 1){ //if normPW = 1, a logic 1 was sent
bitstream[bitCNT] = 1;
bitCNT ++;
}
else{ //if normPW > 1, some # of 0's and one 1 was sent
temp = (normPW[i]-1)/2; //normPW = #0's x 2 + 1
for(int z = 0; z < temp; z++){
bitstream[bitCNT] = 0; //insert 0's into reconstructed bitstream
bitCNT ++;
}
bitstream[bitCNT] = 1; //add that one logic 1 after 0's
bitCNT ++;
}
}
//now pick out the desired data bytes and fill them
//shift in a 1 or a 0
for(int j = 0; j < 6; j++){
for(int i = startPos[j]; i < (startPos[j] + 8); i++){
if(bitstream[i] == 1){
databyte[j] = databyte[j] | 0x01;
}
if(i != (startPos[j] + 7)){
databyte[j] = databyte[j] << 1;
}
}
}
//now print the results to the serial monitor
Serial.print("Message counter = ");
Serial.println(loopCNT);
for(int i = 0; i < 6; i++){
Serial.print("Byte");
Serial.print(i);
Serial.print(" = 0x");
Serial.println(databyte[i], HEX);
}
printed = true;
//now reset everything for the next transmission
reset();
loopCNT++;
}
}
void measurePW(){
while(MSGincoming == true){
if(INpin == LOW && running == true){
delayMicroseconds(50); //make sure ISR runs 1st
pulseWidth[pulseCNT] = PWmicros; //store PW in array
pulseCNT ++; //increment counter
running = false; //PW timer not running
}
if(INpin == HIGH){ //look for stop bit, end of message
if(micros() - stime > timeout){ //PW is longer than longest valid data
MSGincoming = false; //signal message rcvd, get out of while loop
running = false;
}
}
}
}
void reset(){
for(int i = 0; i < 70; i++){
normPW[i] = 0;
bitstream[i] = 0;
pulseWidth[i] = 0;
}
for(int i = 0; i < 6; i++){
databyte[i] = 0;
}
pulseCNT = 0;
bitCNT = 0;
avePW = 0;
PWmicros = 0;
temp = 0;
}
void ISR_changing(){
if(INpin == HIGH){ //this is rising edge logic
//set timer flag
running = true;
//store pulse start time
stime = micros();
}
else{ //falling edge
//set message being received flag
MSGincoming = true;
//calculate pulsewidth but not for 1st falling edge
if(running == true){
PWmicros = micros() - stime;
}
}
}
Comments, corrections welcomed.