SSI OpComms 3CM Board RX

Dependencies:   mbed

Fork of Optical3cmRX by Thomas Teisberg

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);
    }
}