SSI OpComms 3CM Board RX
Dependencies: mbed
Fork of Optical3cmRX by
main.cpp
- Committer:
- Aaditya Shidham
- Date:
- 2015-11-15
- Revision:
- 8:20d405a03cb9
- Parent:
- 7:41b22e5a1d8d
File content as of revision 8:20d405a03cb9:
#include "mbed.h" #include <sstream> #include <string> #include <queue> 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 const int EOM = N_PPM; static int PULSE_TIME; // microseconds static int SAMPLE_RATE; // must be a divisor of PULSE_TIME; static int SAMPLE_GAP; static int HALF_SAMPLE; static double THRESH; // threshold for 1 vs 0. Must adjust in the field by testing. queue<int> sbuf; 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; 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); pc.printf("Parameters: PULSE_TIME=%d, SAMPLE_RATE=%d, THRESH=%f\r\n", PULSE_TIME, SAMPLE_RATE, THRESH); SAMPLE_GAP = PULSE_TIME / SAMPLE_RATE; HALF_SAMPLE = SAMPLE_RATE / 2; } //http://stackoverflow.com/questions/8845178/c-programming-tcp-checksum char checkSum(char *buffer, int size) { unsigned long cksum=0; while(size) { cksum+=*buffer++; size--; } cksum = (cksum >> 16) + (cksum & 0xffff); cksum += (cksum >>16); return (char)(~cksum); } void printDecodeBuf() { char cur = 0; int k = 0; string data; //pc.printf("\r\nsbuf: "); while(!sbuf.empty()) { int c = sbuf.front(); sbuf.pop(); if(c == EOM) break; //pc.printf("%d ", c); if(sbuf.empty()) { pc.printf("\r\nWarning: reached end of buffer\r\n"); } 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; cur |= bit << (7 - k%8); k++; if(k%8 == 0) { data += cur; cur = 0; } } } int rcv_checksum = data[data.size()-2]; int rcv_checksum2 = data[data.size()-1]; data.erase(data.size()-2, data.size()); pc.printf("Received: \""); pc.printf(data.c_str()); pc.printf("\"\r\n"); int checksum = 0; for(int i = 0; i < data.size(); i++) checksum ^= data[i]; pc.printf("Received: %d | Computed: %d\r\n", rcv_checksum, checksum); pc.printf("Received2: %d | Computed2: %d\r\n", rcv_checksum2, checkSum(data.c_str(),data.size())); } // 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); sbuf.push(offPulses); } 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"); offCount = 0; offCount = 0; //*/ Ticker sampler; sampler.attach_us(&sample, SAMPLE_GAP); while(true){ if((offCount + HALF_SAMPLE) / SAMPLE_RATE > N_PPM && !sbuf.empty()){ // synchronize pc.printf("\r\n"); sbuf.push(EOM); printDecodeBuf(); } wait_us(PULSE_TIME); } }