SSI OpComms 3CM Board RX

Dependencies:   mbed

Fork of Optical3cmRX by Thomas Teisberg

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