SSI OpComms 3CM Board RX
Dependencies: mbed
Fork of Optical3cmRX by
main.cpp@7:41b22e5a1d8d, 2015-11-16 (annotated)
- Committer:
- bhz
- Date:
- Mon Nov 16 00:08:19 2015 +0000
- Revision:
- 7:41b22e5a1d8d
- Parent:
- 6:6c996fb7a742
- Child:
- 8:20d405a03cb9
Implemented basic checksum
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 | 6:6c996fb7a742 | 19 | static double THRESH; // threshold for 1 vs 0. Must adjust in the field by testing. |
bhz | 2:eb447fcd8284 | 20 | |
bhz | 6:6c996fb7a742 | 21 | queue<int> sbuf; |
bhz | 2:eb447fcd8284 | 22 | bool sample_lock = false; |
bhz | 2:eb447fcd8284 | 23 | int offCount, onCount; |
tteisberg | 1:b446f401a861 | 24 | |
bhz | 5:fc3ce1c5db88 | 25 | string getLine(string prompt) |
bhz | 5:fc3ce1c5db88 | 26 | { |
bhz | 5:fc3ce1c5db88 | 27 | while(pc.readable()) pc.getc(); |
bhz | 5:fc3ce1c5db88 | 28 | pc.printf(prompt.c_str()); |
bhz | 5:fc3ce1c5db88 | 29 | string out; |
bhz | 5:fc3ce1c5db88 | 30 | char c; |
bhz | 5:fc3ce1c5db88 | 31 | while((c = pc.getc()) != '\n') |
bhz | 5:fc3ce1c5db88 | 32 | { |
bhz | 5:fc3ce1c5db88 | 33 | out += c; |
bhz | 5:fc3ce1c5db88 | 34 | } |
bhz | 5:fc3ce1c5db88 | 35 | pc.printf((out + "\r\n").c_str()); |
bhz | 5:fc3ce1c5db88 | 36 | return out; |
bhz | 5:fc3ce1c5db88 | 37 | } |
bhz | 5:fc3ce1c5db88 | 38 | |
bhz | 5:fc3ce1c5db88 | 39 | double getNumber(string prompt, double def) |
bhz | 5:fc3ce1c5db88 | 40 | { |
bhz | 5:fc3ce1c5db88 | 41 | string s = getLine(prompt); |
bhz | 5:fc3ce1c5db88 | 42 | istringstream ints(s); |
bhz | 5:fc3ce1c5db88 | 43 | double out; |
bhz | 5:fc3ce1c5db88 | 44 | if(!(ints >> out)) out = def; |
bhz | 5:fc3ce1c5db88 | 45 | return out; |
bhz | 5:fc3ce1c5db88 | 46 | } |
bhz | 5:fc3ce1c5db88 | 47 | |
bhz | 5:fc3ce1c5db88 | 48 | void set_constants() |
bhz | 5:fc3ce1c5db88 | 49 | { |
bhz | 5:fc3ce1c5db88 | 50 | PULSE_TIME = (int) getNumber("Input pulse time (us; blank for 1000): ", 1000); |
bhz | 5:fc3ce1c5db88 | 51 | SAMPLE_RATE = (int) getNumber("Input sample rate (blank for 10): ", 10); |
bhz | 5:fc3ce1c5db88 | 52 | THRESH = getNumber("Input threshold (blank for 0.005): ", 0.005); |
bhz | 6:6c996fb7a742 | 53 | pc.printf("Parameters: PULSE_TIME=%d, SAMPLE_RATE=%d, THRESH=%f\r\n", PULSE_TIME, SAMPLE_RATE, THRESH); |
bhz | 5:fc3ce1c5db88 | 54 | SAMPLE_GAP = PULSE_TIME / SAMPLE_RATE; |
bhz | 5:fc3ce1c5db88 | 55 | HALF_SAMPLE = SAMPLE_RATE / 2; |
bhz | 5:fc3ce1c5db88 | 56 | } |
bhz | 5:fc3ce1c5db88 | 57 | |
bhz | 6:6c996fb7a742 | 58 | void printDecodeBuf() |
bhz | 6:6c996fb7a742 | 59 | { |
bhz | 6:6c996fb7a742 | 60 | char cur = 0; |
bhz | 6:6c996fb7a742 | 61 | int k = 0; |
bhz | 6:6c996fb7a742 | 62 | string data; |
bhz | 7:41b22e5a1d8d | 63 | //pc.printf("\r\nsbuf: "); |
bhz | 6:6c996fb7a742 | 64 | while(!sbuf.empty()) |
bhz | 6:6c996fb7a742 | 65 | { |
bhz | 6:6c996fb7a742 | 66 | int c = sbuf.front(); |
bhz | 6:6c996fb7a742 | 67 | sbuf.pop(); |
bhz | 6:6c996fb7a742 | 68 | if(c == EOM) break; |
bhz | 7:41b22e5a1d8d | 69 | //pc.printf("%d ", c); |
bhz | 6:6c996fb7a742 | 70 | if(sbuf.empty()) |
bhz | 6:6c996fb7a742 | 71 | { |
bhz | 6:6c996fb7a742 | 72 | pc.printf("\r\nWarning: reached end of buffer\r\n"); |
bhz | 6:6c996fb7a742 | 73 | } |
bhz | 6:6c996fb7a742 | 74 | for(int j = 0; j < PPM_BITS; j++) |
bhz | 6:6c996fb7a742 | 75 | { |
bhz | 6:6c996fb7a742 | 76 | // do some bit hacking to put the bit into the proper character in the output array |
bhz | 6:6c996fb7a742 | 77 | bool bit = (c >> (PPM_BITS - j - 1)) & 1; |
bhz | 6:6c996fb7a742 | 78 | cur |= bit << (7 - k%8); |
bhz | 6:6c996fb7a742 | 79 | k++; |
bhz | 6:6c996fb7a742 | 80 | if(k%8 == 0) |
bhz | 6:6c996fb7a742 | 81 | { |
bhz | 6:6c996fb7a742 | 82 | data += cur; |
bhz | 6:6c996fb7a742 | 83 | cur = 0; |
bhz | 6:6c996fb7a742 | 84 | } |
bhz | 6:6c996fb7a742 | 85 | } |
bhz | 6:6c996fb7a742 | 86 | } |
bhz | 7:41b22e5a1d8d | 87 | int rcv_checksum = data[data.size()-1]; |
bhz | 7:41b22e5a1d8d | 88 | data.erase(data.size()-1, data.size()); |
bhz | 7:41b22e5a1d8d | 89 | pc.printf("Received: \""); |
bhz | 6:6c996fb7a742 | 90 | pc.printf(data.c_str()); |
bhz | 6:6c996fb7a742 | 91 | pc.printf("\"\r\n"); |
bhz | 7:41b22e5a1d8d | 92 | |
bhz | 7:41b22e5a1d8d | 93 | int checksum = 0; |
bhz | 7:41b22e5a1d8d | 94 | for(int i = 0; i < data.size(); i++) checksum ^= data[i]; |
bhz | 7:41b22e5a1d8d | 95 | |
bhz | 7:41b22e5a1d8d | 96 | pc.printf("Received: %d | Computed: %d\r\n", rcv_checksum, checksum); |
bhz | 6:6c996fb7a742 | 97 | } |
bhz | 6:6c996fb7a742 | 98 | |
tteisberg | 1:b446f401a861 | 99 | |
bhz | 5:fc3ce1c5db88 | 100 | // Samples once, and writes to the buffer if necessary. |
bhz | 2:eb447fcd8284 | 101 | void sample() |
bhz | 2:eb447fcd8284 | 102 | { |
bhz | 2:eb447fcd8284 | 103 | if(sample_lock) pc.printf("\r\nWarning: Sampling too fast\r\n"); |
bhz | 2:eb447fcd8284 | 104 | sample_lock = true; |
bhz | 2:eb447fcd8284 | 105 | float v = rx.read(); |
bhz | 3:1235cbe67ec9 | 106 | if(v < THRESH){ |
bhz | 2:eb447fcd8284 | 107 | offCount++; |
bhz | 3:1235cbe67ec9 | 108 | if(onCount > HALF_SAMPLE) |
bhz | 3:1235cbe67ec9 | 109 | { |
bhz | 3:1235cbe67ec9 | 110 | onCount = 0; |
bhz | 3:1235cbe67ec9 | 111 | } |
bhz | 2:eb447fcd8284 | 112 | }else{ // Pulse |
bhz | 3:1235cbe67ec9 | 113 | if(offCount > HALF_SAMPLE) |
bhz | 2:eb447fcd8284 | 114 | { |
bhz | 3:1235cbe67ec9 | 115 | int offPulses = (offCount + HALF_SAMPLE) / SAMPLE_RATE - 1; |
bhz | 6:6c996fb7a742 | 116 | if(offPulses < N_PPM) |
bhz | 2:eb447fcd8284 | 117 | { |
bhz | 7:41b22e5a1d8d | 118 | pc.printf("%d ", offPulses); |
bhz | 6:6c996fb7a742 | 119 | sbuf.push(offPulses); |
bhz | 2:eb447fcd8284 | 120 | } |
bhz | 2:eb447fcd8284 | 121 | offCount = 0; |
bhz | 2:eb447fcd8284 | 122 | } |
bhz | 2:eb447fcd8284 | 123 | onCount++; |
tteisberg | 1:b446f401a861 | 124 | } |
bhz | 2:eb447fcd8284 | 125 | sample_lock = false; |
tteisberg | 1:b446f401a861 | 126 | } |
tteisberg | 1:b446f401a861 | 127 | |
tteisberg | 1:b446f401a861 | 128 | int main() |
tteisberg | 1:b446f401a861 | 129 | { |
bhz | 2:eb447fcd8284 | 130 | pc.printf("3 CM Link Board - Recieve\r\n"); |
bhz | 5:fc3ce1c5db88 | 131 | //* |
tteisberg | 1:b446f401a861 | 132 | bool calib = true; |
tteisberg | 1:b446f401a861 | 133 | if(calib){ |
tteisberg | 1:b446f401a861 | 134 | while(true){ |
bhz | 5:fc3ce1c5db88 | 135 | // Just prints raw values until the user gives some input |
bhz | 2:eb447fcd8284 | 136 | pc.printf("%f\r\r\n", rx.read()); |
tteisberg | 1:b446f401a861 | 137 | wait_ms(100); |
bhz | 5:fc3ce1c5db88 | 138 | if(pc.readable()) { |
bhz | 5:fc3ce1c5db88 | 139 | break; |
bhz | 5:fc3ce1c5db88 | 140 | } |
tteisberg | 1:b446f401a861 | 141 | } |
tteisberg | 1:b446f401a861 | 142 | } |
bhz | 5:fc3ce1c5db88 | 143 | set_constants(); |
bhz | 5:fc3ce1c5db88 | 144 | pc.printf("Ready! \r\n"); |
bhz | 2:eb447fcd8284 | 145 | offCount = 0; |
tteisberg | 1:b446f401a861 | 146 | offCount = 0; |
bhz | 4:037345932888 | 147 | //*/ |
bhz | 2:eb447fcd8284 | 148 | Ticker sampler; |
bhz | 2:eb447fcd8284 | 149 | sampler.attach_us(&sample, SAMPLE_GAP); |
bhz | 2:eb447fcd8284 | 150 | |
tteisberg | 1:b446f401a861 | 151 | while(true){ |
bhz | 7:41b22e5a1d8d | 152 | if((offCount + HALF_SAMPLE) / SAMPLE_RATE > N_PPM && !sbuf.empty()){ // synchronize |
bhz | 6:6c996fb7a742 | 153 | pc.printf("\r\n"); |
bhz | 6:6c996fb7a742 | 154 | sbuf.push(EOM); |
bhz | 6:6c996fb7a742 | 155 | printDecodeBuf(); |
tteisberg | 1:b446f401a861 | 156 | } |
bhz | 4:037345932888 | 157 | wait_us(PULSE_TIME); |
mbed_official | 0:879aa9d0247b | 158 | } |
mbed_official | 0:879aa9d0247b | 159 | } |