SSI OpComms 3CM Board RX

Dependencies:   mbed

Fork of Optical3cmRX by Thomas Teisberg

Committer:
bhz
Date:
Sun Nov 15 00:21:59 2015 +0000
Revision:
5:fc3ce1c5db88
Parent:
4:037345932888
Child:
6:6c996fb7a742
Allows user to specify pulse time, sample rate, threshold.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
mbed_official 0:879aa9d0247b 1 #include "mbed.h"
bhz 5:fc3ce1c5db88 2 #include <string>
bhz 5:fc3ce1c5db88 3 #include <sstream>
bhz 5:fc3ce1c5db88 4 using namespace std;
tteisberg 1:b446f401a861 5
tteisberg 1:b446f401a861 6 AnalogIn rx(p20);
tteisberg 1:b446f401a861 7
mbed_official 0:879aa9d0247b 8 Serial pc(USBTX, USBRX); // tx, rx
tteisberg 1:b446f401a861 9
bhz 5:fc3ce1c5db88 10 // e.g. PPM_BITS = 2 --> 4-PPM; PPM_BITS = 3 --> 8-PPM, etc.
bhz 4:037345932888 11 static const int PPM_BITS = 2;
bhz 4:037345932888 12 static const int N_PPM = 1 << PPM_BITS;
bhz 5:fc3ce1c5db88 13 static int PULSE_TIME = 1000; // microseconds
bhz 5:fc3ce1c5db88 14 static int SAMPLE_RATE = 10; // must be a divisor of PULSE_TIME;
bhz 5:fc3ce1c5db88 15 static int SAMPLE_GAP = PULSE_TIME / SAMPLE_RATE;
bhz 5:fc3ce1c5db88 16 static int HALF_SAMPLE = SAMPLE_RATE / 2;
bhz 5:fc3ce1c5db88 17 static const int BUF_SIZE = 1024; // Size of buffer. Each element of buffer represents PPM_BITS bits of information, so
bhz 5:fc3ce1c5db88 18 // e.g. BUF_SIZE = 1024 and PPM_BITS = 2 gives 2 Kbit buffer.
bhz 5:fc3ce1c5db88 19 static double THRESH = 0.005; // threshold for 1 vs 0. Must adjust in the field by testing.
bhz 2:eb447fcd8284 20
bhz 2:eb447fcd8284 21 int buf[BUF_SIZE];
tteisberg 1:b446f401a861 22 int idx = 0;
tteisberg 1:b446f401a861 23 int nzeros = 0;
bhz 2:eb447fcd8284 24 int start = 0;
bhz 2:eb447fcd8284 25 bool sample_lock = false;
bhz 2:eb447fcd8284 26 int offCount, onCount;
tteisberg 1:b446f401a861 27
bhz 5:fc3ce1c5db88 28 string getLine(string prompt)
bhz 5:fc3ce1c5db88 29 {
bhz 5:fc3ce1c5db88 30 while(pc.readable()) pc.getc();
bhz 5:fc3ce1c5db88 31 pc.printf(prompt.c_str());
bhz 5:fc3ce1c5db88 32 string out;
bhz 5:fc3ce1c5db88 33 char c;
bhz 5:fc3ce1c5db88 34 while((c = pc.getc()) != '\n')
bhz 5:fc3ce1c5db88 35 {
bhz 5:fc3ce1c5db88 36 out += c;
bhz 5:fc3ce1c5db88 37 }
bhz 5:fc3ce1c5db88 38 pc.printf((out + "\r\n").c_str());
bhz 5:fc3ce1c5db88 39 return out;
bhz 5:fc3ce1c5db88 40 }
bhz 5:fc3ce1c5db88 41
bhz 5:fc3ce1c5db88 42 double getNumber(string prompt, double def)
bhz 5:fc3ce1c5db88 43 {
bhz 5:fc3ce1c5db88 44 string s = getLine(prompt);
bhz 5:fc3ce1c5db88 45 istringstream ints(s);
bhz 5:fc3ce1c5db88 46 double out;
bhz 5:fc3ce1c5db88 47 if(!(ints >> out)) out = def;
bhz 5:fc3ce1c5db88 48 pc.printf("Value set: %f\r\n", out);
bhz 5:fc3ce1c5db88 49 return out;
bhz 5:fc3ce1c5db88 50 }
bhz 5:fc3ce1c5db88 51
bhz 5:fc3ce1c5db88 52 void set_constants()
bhz 5:fc3ce1c5db88 53 {
bhz 5:fc3ce1c5db88 54 PULSE_TIME = (int) getNumber("Input pulse time (us; blank for 1000): ", 1000);
bhz 5:fc3ce1c5db88 55 SAMPLE_RATE = (int) getNumber("Input sample rate (blank for 10): ", 10);
bhz 5:fc3ce1c5db88 56 THRESH = getNumber("Input threshold (blank for 0.005): ", 0.005);
bhz 5:fc3ce1c5db88 57 SAMPLE_GAP = PULSE_TIME / SAMPLE_RATE;
bhz 5:fc3ce1c5db88 58 HALF_SAMPLE = SAMPLE_RATE / 2;
bhz 5:fc3ce1c5db88 59 }
bhz 5:fc3ce1c5db88 60
bhz 5:fc3ce1c5db88 61 // Decodes from the buffer, from start (above) to the provided stop index. Wraps around the end of the buffer.
bhz 5:fc3ce1c5db88 62 // Prints the decoded string.
bhz 4:037345932888 63 void printDecode(int stopIdx){
bhz 4:037345932888 64
bhz 2:eb447fcd8284 65 int len = (stopIdx - start + BUF_SIZE) % BUF_SIZE;
bhz 4:037345932888 66 int size = PPM_BITS * len / 8 + 1;
bhz 4:037345932888 67 char data[size];
bhz 4:037345932888 68 for(int i = 0; i < size; i++) data[i] = 0;
bhz 4:037345932888 69 //pc.printf("\r\nDecode: ");
bhz 4:037345932888 70 int k = 0;
bhz 2:eb447fcd8284 71 for(int i = 0; i < len; i++)
bhz 2:eb447fcd8284 72 {
bhz 2:eb447fcd8284 73 int c = buf[start++];
bhz 2:eb447fcd8284 74 if(start == BUF_SIZE) start = 0;
bhz 4:037345932888 75 for(int j = 0; j < PPM_BITS; j++)
bhz 2:eb447fcd8284 76 {
bhz 5:fc3ce1c5db88 77 // do some bit hacking to put the bit into the proper character in the output array
bhz 4:037345932888 78 bool bit = (c >> (PPM_BITS - j - 1)) & 1;
bhz 4:037345932888 79 if(k%8 == 0) data[k/8] = 0;
bhz 4:037345932888 80 data[k/8] |= bit << (7 - k%8);
bhz 4:037345932888 81 k++;
bhz 2:eb447fcd8284 82 }
bhz 2:eb447fcd8284 83 }
bhz 5:fc3ce1c5db88 84 pc.printf("\r\nReceived: \"");
bhz 4:037345932888 85 pc.printf(data);
bhz 4:037345932888 86 pc.printf("\"\r\n");
bhz 4:037345932888 87 if(start != stopIdx)
bhz 4:037345932888 88 {
bhz 4:037345932888 89 pc.printf("\r\nWarning: Incomplete byte\r\n");
bhz 4:037345932888 90 }
bhz 5:fc3ce1c5db88 91 start = stopIdx;
bhz 2:eb447fcd8284 92 }
tteisberg 1:b446f401a861 93
bhz 5:fc3ce1c5db88 94 // Samples once, and writes to the buffer if necessary.
bhz 2:eb447fcd8284 95 void sample()
bhz 2:eb447fcd8284 96 {
bhz 2:eb447fcd8284 97 if(sample_lock) pc.printf("\r\nWarning: Sampling too fast\r\n");
bhz 2:eb447fcd8284 98 sample_lock = true;
bhz 2:eb447fcd8284 99 float v = rx.read();
bhz 3:1235cbe67ec9 100 if(v < THRESH){
bhz 2:eb447fcd8284 101 offCount++;
bhz 3:1235cbe67ec9 102 if(onCount > HALF_SAMPLE)
bhz 3:1235cbe67ec9 103 {
bhz 3:1235cbe67ec9 104 onCount = 0;
bhz 3:1235cbe67ec9 105 }
bhz 2:eb447fcd8284 106 }else{ // Pulse
bhz 3:1235cbe67ec9 107 if(offCount > HALF_SAMPLE)
bhz 2:eb447fcd8284 108 {
bhz 3:1235cbe67ec9 109 int offPulses = (offCount + HALF_SAMPLE) / SAMPLE_RATE - 1;
bhz 2:eb447fcd8284 110 if(offPulses <= N_PPM)
bhz 2:eb447fcd8284 111 {
bhz 5:fc3ce1c5db88 112 pc.printf("%d ", offPulses);
bhz 3:1235cbe67ec9 113 buf[idx] = offPulses;
bhz 2:eb447fcd8284 114 idx++;
bhz 2:eb447fcd8284 115 if(idx == BUF_SIZE) idx = 0;
bhz 2:eb447fcd8284 116 if(idx == start) pc.printf("\r\nWarning: Buffer too small\r\n");
bhz 2:eb447fcd8284 117 }
bhz 2:eb447fcd8284 118 offCount = 0;
bhz 2:eb447fcd8284 119 }
bhz 2:eb447fcd8284 120 onCount++;
tteisberg 1:b446f401a861 121 }
bhz 2:eb447fcd8284 122 sample_lock = false;
tteisberg 1:b446f401a861 123 }
tteisberg 1:b446f401a861 124
tteisberg 1:b446f401a861 125 int main()
tteisberg 1:b446f401a861 126 {
bhz 2:eb447fcd8284 127 pc.printf("3 CM Link Board - Recieve\r\n");
bhz 5:fc3ce1c5db88 128 //*
tteisberg 1:b446f401a861 129 bool calib = true;
tteisberg 1:b446f401a861 130 if(calib){
tteisberg 1:b446f401a861 131 while(true){
bhz 5:fc3ce1c5db88 132 // Just prints raw values until the user gives some input
bhz 2:eb447fcd8284 133 pc.printf("%f\r\r\n", rx.read());
tteisberg 1:b446f401a861 134 wait_ms(100);
bhz 5:fc3ce1c5db88 135 if(pc.readable()) {
bhz 5:fc3ce1c5db88 136 break;
bhz 5:fc3ce1c5db88 137 }
tteisberg 1:b446f401a861 138 }
tteisberg 1:b446f401a861 139 }
bhz 5:fc3ce1c5db88 140 set_constants();
bhz 5:fc3ce1c5db88 141 pc.printf("Ready! \r\n");
tteisberg 1:b446f401a861 142 idx = 0;
bhz 2:eb447fcd8284 143 offCount = 0;
tteisberg 1:b446f401a861 144 offCount = 0;
bhz 4:037345932888 145 //*/
bhz 2:eb447fcd8284 146 Ticker sampler;
bhz 2:eb447fcd8284 147 sampler.attach_us(&sample, SAMPLE_GAP);
bhz 2:eb447fcd8284 148
tteisberg 1:b446f401a861 149 while(true){
bhz 4:037345932888 150 if((offCount + HALF_SAMPLE) / SAMPLE_RATE > N_PPM && start != idx){ // synchronize
bhz 4:037345932888 151 printDecode(idx);
tteisberg 1:b446f401a861 152 }
bhz 4:037345932888 153 wait_us(PULSE_TIME);
mbed_official 0:879aa9d0247b 154 }
mbed_official 0:879aa9d0247b 155 }