SSI OpComms 3CM Board RX
Dependencies: mbed
Fork of Optical3cmRX by
main.cpp
- Committer:
- bhz
- Date:
- 2015-11-15
- Revision:
- 5:fc3ce1c5db88
- Parent:
- 4:037345932888
- Child:
- 6:6c996fb7a742
File content as of revision 5:fc3ce1c5db88:
#include "mbed.h" #include <string> #include <sstream> using namespace std; AnalogIn rx(p20); Serial pc(USBTX, USBRX); // tx, rx // e.g. PPM_BITS = 2 --> 4-PPM; PPM_BITS = 3 --> 8-PPM, etc. static const int PPM_BITS = 2; static const int N_PPM = 1 << PPM_BITS; static int PULSE_TIME = 1000; // microseconds static int SAMPLE_RATE = 10; // must be a divisor of PULSE_TIME; static int SAMPLE_GAP = PULSE_TIME / SAMPLE_RATE; static int HALF_SAMPLE = SAMPLE_RATE / 2; static const int BUF_SIZE = 1024; // Size of buffer. Each element of buffer represents PPM_BITS bits of information, so // e.g. BUF_SIZE = 1024 and PPM_BITS = 2 gives 2 Kbit buffer. static double THRESH = 0.005; // threshold for 1 vs 0. Must adjust in the field by testing. int buf[BUF_SIZE]; int idx = 0; int nzeros = 0; int start = 0; bool sample_lock = false; int offCount, onCount; string getLine(string prompt) { while(pc.readable()) pc.getc(); pc.printf(prompt.c_str()); string out; char c; while((c = pc.getc()) != '\n') { out += c; } pc.printf((out + "\r\n").c_str()); return out; } double getNumber(string prompt, double def) { string s = getLine(prompt); istringstream ints(s); double out; if(!(ints >> out)) out = def; pc.printf("Value set: %f\r\n", out); return out; } void set_constants() { PULSE_TIME = (int) getNumber("Input pulse time (us; blank for 1000): ", 1000); SAMPLE_RATE = (int) getNumber("Input sample rate (blank for 10): ", 10); THRESH = getNumber("Input threshold (blank for 0.005): ", 0.005); SAMPLE_GAP = PULSE_TIME / SAMPLE_RATE; HALF_SAMPLE = SAMPLE_RATE / 2; } // Decodes from the buffer, from start (above) to the provided stop index. Wraps around the end of the buffer. // Prints the decoded string. void printDecode(int stopIdx){ int len = (stopIdx - start + BUF_SIZE) % BUF_SIZE; int size = PPM_BITS * len / 8 + 1; char data[size]; for(int i = 0; i < size; i++) data[i] = 0; //pc.printf("\r\nDecode: "); int k = 0; for(int i = 0; i < len; i++) { int c = buf[start++]; if(start == BUF_SIZE) start = 0; for(int j = 0; j < PPM_BITS; j++) { // do some bit hacking to put the bit into the proper character in the output array bool bit = (c >> (PPM_BITS - j - 1)) & 1; if(k%8 == 0) data[k/8] = 0; data[k/8] |= bit << (7 - k%8); k++; } } pc.printf("\r\nReceived: \""); pc.printf(data); pc.printf("\"\r\n"); if(start != stopIdx) { pc.printf("\r\nWarning: Incomplete byte\r\n"); } start = stopIdx; } // Samples once, and writes to the buffer if necessary. void sample() { if(sample_lock) pc.printf("\r\nWarning: Sampling too fast\r\n"); sample_lock = true; float v = rx.read(); if(v < THRESH){ offCount++; if(onCount > HALF_SAMPLE) { onCount = 0; } }else{ // Pulse if(offCount > HALF_SAMPLE) { int offPulses = (offCount + HALF_SAMPLE) / SAMPLE_RATE - 1; if(offPulses <= N_PPM) { pc.printf("%d ", offPulses); buf[idx] = offPulses; idx++; if(idx == BUF_SIZE) idx = 0; if(idx == start) pc.printf("\r\nWarning: Buffer too small\r\n"); } offCount = 0; } onCount++; } sample_lock = false; } int main() { pc.printf("3 CM Link Board - Recieve\r\n"); //* bool calib = true; if(calib){ while(true){ // Just prints raw values until the user gives some input pc.printf("%f\r\r\n", rx.read()); wait_ms(100); if(pc.readable()) { break; } } } set_constants(); pc.printf("Ready! \r\n"); idx = 0; offCount = 0; offCount = 0; //*/ Ticker sampler; sampler.attach_us(&sample, SAMPLE_GAP); while(true){ if((offCount + HALF_SAMPLE) / SAMPLE_RATE > N_PPM && start != idx){ // synchronize printDecode(idx); } wait_us(PULSE_TIME); } }