SSI OpComms 3CM Board RX

Dependencies:   mbed

Fork of Optical3cmRX by Thomas Teisberg

Committer:
bhz
Date:
Sun Nov 15 23:20:38 2015 +0000
Revision:
6:6c996fb7a742
Parent:
5:fc3ce1c5db88
Child:
7:41b22e5a1d8d
Changed int[] buffer to queue<char>

Who changed what in which revision?

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