SSI OpComms 3CM Board RX
Dependencies: mbed
Fork of Optical3cmRX by
main.cpp@6:6c996fb7a742, 2015-11-15 (annotated)
- 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?
User | Revision | Line number | New 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 | } |