SSI OpComms 3CM Board RX

Dependencies:   mbed

Fork of Optical3cmRX by Thomas Teisberg

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

00001 #include "mbed.h"
00002 #include <sstream>
00003 #include <string>
00004 #include <queue>
00005 using namespace std;
00006 
00007 AnalogIn rx(p20);
00008 
00009 Serial pc(USBTX, USBRX); // tx, rx
00010 
00011 // e.g. PPM_BITS = 2 --> 4-PPM; PPM_BITS = 3 --> 8-PPM, etc.
00012 static const int PPM_BITS = 2;
00013 static const int N_PPM = 1 << PPM_BITS;
00014 static const int EOM = N_PPM;
00015 static int PULSE_TIME; // microseconds
00016 static int SAMPLE_RATE; // must be a divisor of PULSE_TIME; 
00017 static int SAMPLE_GAP;
00018 static int HALF_SAMPLE;
00019 static double THRESH; // threshold for 1 vs 0. Must adjust in the field by testing.
00020 
00021 queue<int> sbuf;
00022 bool sample_lock = false;
00023 int offCount, onCount;
00024 
00025 string getLine(string prompt)
00026 {
00027     while(pc.readable()) pc.getc();
00028     pc.printf(prompt.c_str());
00029     string out;
00030     char c;
00031     while((c = pc.getc()) != '\n')
00032     {
00033         out += c;
00034     }
00035     pc.printf((out + "\r\n").c_str());
00036     return out;
00037 }
00038 
00039 double getNumber(string prompt, double def)
00040 {
00041     string s = getLine(prompt);
00042     istringstream ints(s);
00043     double out;
00044     if(!(ints >> out)) out = def;
00045     return out;
00046 }
00047 
00048 void set_constants()
00049 {
00050     PULSE_TIME = (int) getNumber("Input pulse time (us; blank for 1000): ", 1000);
00051     SAMPLE_RATE = (int) getNumber("Input sample rate (blank for 10): ", 10);
00052     THRESH = getNumber("Input threshold (blank for 0.005): ", 0.005);
00053     pc.printf("Parameters: PULSE_TIME=%d, SAMPLE_RATE=%d, THRESH=%f\r\n", PULSE_TIME, SAMPLE_RATE, THRESH);
00054     SAMPLE_GAP = PULSE_TIME / SAMPLE_RATE;
00055     HALF_SAMPLE = SAMPLE_RATE / 2;
00056 }
00057 
00058 //http://stackoverflow.com/questions/8845178/c-programming-tcp-checksum
00059 char checkSum(char *buffer, int size)
00060 {
00061     unsigned long cksum=0;
00062     while(size)
00063     {
00064         cksum+=*buffer++;
00065         size--;
00066     }
00067 
00068     cksum = (cksum >> 16) + (cksum & 0xffff);
00069     cksum += (cksum >>16);
00070     return (char)(~cksum);
00071 }
00072 
00073 void printDecodeBuf()
00074 {
00075     char cur = 0;
00076     int k = 0;
00077     string data;
00078     //pc.printf("\r\nsbuf: ");
00079     while(!sbuf.empty())
00080     {
00081         int c = sbuf.front();
00082         sbuf.pop();
00083         if(c == EOM) break;
00084         //pc.printf("%d ", c);
00085         if(sbuf.empty())
00086         {
00087             pc.printf("\r\nWarning: reached end of buffer\r\n");
00088         }
00089         for(int j = 0; j < PPM_BITS; j++)
00090         {
00091             // do some bit hacking to put the bit into the proper character in the output array
00092             bool bit = (c >> (PPM_BITS - j - 1)) & 1;
00093             cur |= bit << (7 - k%8);
00094             k++;
00095             if(k%8 == 0)
00096             {
00097                 data += cur;
00098                 cur = 0;
00099             }
00100         }
00101     }
00102     int rcv_checksum = data[data.size()-2];
00103     int rcv_checksum2 = data[data.size()-1];
00104     data.erase(data.size()-2, data.size());
00105     pc.printf("Received: \"");
00106     pc.printf(data.c_str());
00107     pc.printf("\"\r\n");
00108     
00109     int checksum = 0;
00110     for(int i = 0; i < data.size(); i++) checksum ^= data[i];
00111     
00112     pc.printf("Received: %d | Computed: %d\r\n", rcv_checksum, checksum);
00113     pc.printf("Received2: %d | Computed2: %d\r\n", rcv_checksum2, checkSum(data.c_str(),data.size()));
00114 }
00115 
00116 
00117 // Samples once, and writes to the buffer if necessary.
00118 void sample()
00119 {
00120     if(sample_lock) pc.printf("\r\nWarning: Sampling too fast\r\n");
00121     sample_lock = true;
00122     float v = rx.read();
00123     if(v < THRESH){
00124         offCount++;
00125         if(onCount > HALF_SAMPLE)
00126         {
00127             onCount = 0;
00128         }
00129     }else{ // Pulse
00130         if(offCount > HALF_SAMPLE)
00131         {
00132             int offPulses = (offCount + HALF_SAMPLE) / SAMPLE_RATE - 1;
00133             if(offPulses < N_PPM)
00134             {
00135                 pc.printf("%d ", offPulses);
00136                 sbuf.push(offPulses);
00137             }
00138             offCount = 0;
00139         }
00140         onCount++;
00141     }
00142     sample_lock = false;
00143 }
00144 
00145 int main()
00146 {
00147     pc.printf("3 CM Link Board - Recieve\r\n");
00148     //*
00149     bool calib = true;
00150     if(calib){
00151         while(true){
00152             // Just prints raw values until the user gives some input
00153             pc.printf("%f\r\r\n", rx.read());
00154             wait_ms(100);
00155             if(pc.readable()) {
00156                 break;
00157             }
00158         }
00159     }
00160     set_constants();
00161     pc.printf("Ready! \r\n");
00162     offCount = 0;
00163     offCount = 0;
00164     //*/
00165     Ticker sampler;
00166     sampler.attach_us(&sample, SAMPLE_GAP);
00167     
00168     while(true){
00169         if((offCount + HALF_SAMPLE) / SAMPLE_RATE > N_PPM && !sbuf.empty()){ // synchronize
00170             pc.printf("\r\n");
00171             sbuf.push(EOM);
00172             printDecodeBuf();
00173         }
00174         wait_us(PULSE_TIME);
00175     }
00176 }