David DiCarlo
/
30848-KL25Z-AGGREGATOR
Code for a FRDM-KL25Z board with a 30848 aggregator plugged on top. For use with 30847 smart sensors.
aggregator-kl25z.cpp@0:b33aadc7cfad, 2019-05-24 (annotated)
- Committer:
- r14793
- Date:
- Fri May 24 15:37:43 2019 +0000
- Revision:
- 0:b33aadc7cfad
First commit.
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
r14793 | 0:b33aadc7cfad | 1 | /******************************************************************************* |
r14793 | 0:b33aadc7cfad | 2 | * |
r14793 | 0:b33aadc7cfad | 3 | * MIT License (https://spdx.org/licenses/MIT.html) |
r14793 | 0:b33aadc7cfad | 4 | * Copyright 2018-2019 NXP |
r14793 | 0:b33aadc7cfad | 5 | * |
r14793 | 0:b33aadc7cfad | 6 | * MBED code for FRDM-KL25Z aggregator. Configures and triggers "smart" sensors. |
r14793 | 0:b33aadc7cfad | 7 | * Aggregates data and sends up the line to a host computer over USB serial. |
r14793 | 0:b33aadc7cfad | 8 | * Other FRDM boards (K64F or K66F) may be used for ethernet connection or for |
r14793 | 0:b33aadc7cfad | 9 | * more local memory or faster processing speed. |
r14793 | 0:b33aadc7cfad | 10 | * |
r14793 | 0:b33aadc7cfad | 11 | * |
r14793 | 0:b33aadc7cfad | 12 | * !!! 22Apr19: seems fixed again with latest (Feb19 mbed lib)... |
r14793 | 0:b33aadc7cfad | 13 | * !!! 3Dec18: This now appears to be fixed with current version of library... |
r14793 | 0:b33aadc7cfad | 14 | * !!! must use mbed-2 from 20 Mar 2018 or serial port won't work !!! |
r14793 | 0:b33aadc7cfad | 15 | * !!! do not update mbed library... !!! |
r14793 | 0:b33aadc7cfad | 16 | * |
r14793 | 0:b33aadc7cfad | 17 | ********************************************************************************/ |
r14793 | 0:b33aadc7cfad | 18 | |
r14793 | 0:b33aadc7cfad | 19 | #include "mbed.h" |
r14793 | 0:b33aadc7cfad | 20 | |
r14793 | 0:b33aadc7cfad | 21 | char version_info[] = "24 May 2019"; // date info... |
r14793 | 0:b33aadc7cfad | 22 | |
r14793 | 0:b33aadc7cfad | 23 | Serial uart(USBTX, USBRX); // standard FRDM board USBx |
r14793 | 0:b33aadc7cfad | 24 | |
r14793 | 0:b33aadc7cfad | 25 | // set up GPIO connections... |
r14793 | 0:b33aadc7cfad | 26 | DigitalOut reset(PTB0); // PTA1 on smart sensor board |
r14793 | 0:b33aadc7cfad | 27 | DigitalOut interrupt(PTB1); // PTA0 on smart sensor board |
r14793 | 0:b33aadc7cfad | 28 | const int sensors = 14; // total number of sensor available... |
r14793 | 0:b33aadc7cfad | 29 | DigitalOut select[sensors] = // PTA2 on smart sensor board |
r14793 | 0:b33aadc7cfad | 30 | { (PTD4), (PTA12), (PTA4), (PTA5), (PTC8), (PTC9), (PTA13), |
r14793 | 0:b33aadc7cfad | 31 | (PTD5), (PTD0), (PTD2), (PTD3), (PTD1), (PTB3), (PTB2)}; |
r14793 | 0:b33aadc7cfad | 32 | I2C i2c(PTE0, PTE1); |
r14793 | 0:b33aadc7cfad | 33 | |
r14793 | 0:b33aadc7cfad | 34 | int addr8bit = 0x48 << 1; // default start addr for communication with sensors |
r14793 | 0:b33aadc7cfad | 35 | |
r14793 | 0:b33aadc7cfad | 36 | // multipliers of ten used for decompressing data... |
r14793 | 0:b33aadc7cfad | 37 | // *note* this array fails when it's not a const. index 4 returns zero for some |
r14793 | 0:b33aadc7cfad | 38 | // reason... maybe mbed, not sure... seems to be mbed-2 related... |
r14793 | 0:b33aadc7cfad | 39 | const float pow10[14] = {1.0, 1.0e-1, 1.0e-2, 1.0e-3, 1.0e-4, 1.0e-5, 1.0e-6, |
r14793 | 0:b33aadc7cfad | 40 | 1.0e-7, 1.0e-8, 1.0e-9, 1.0e-10, 1.0e-11, 1.0e-12, 1.0e-13}; |
r14793 | 0:b33aadc7cfad | 41 | |
r14793 | 0:b33aadc7cfad | 42 | // some more variables... |
r14793 | 0:b33aadc7cfad | 43 | int n, i, j, k, status, temp; |
r14793 | 0:b33aadc7cfad | 44 | short int chan, range; |
r14793 | 0:b33aadc7cfad | 45 | int delay=500000; // starting delay for measurement updates... |
r14793 | 0:b33aadc7cfad | 46 | long int count=0; |
r14793 | 0:b33aadc7cfad | 47 | char cmd[200]; // buffer for Ggholding data sent to/from sensor boards |
r14793 | 0:b33aadc7cfad | 48 | char params[sensors][20];// array to keep sensor parameter data... |
r14793 | 0:b33aadc7cfad | 49 | bool deebug=false; // flag to print extra stuff for debug... |
r14793 | 0:b33aadc7cfad | 50 | float v1, v2, i1, i2; // for holding full float vs. compressed 3-sigfig measurements |
r14793 | 0:b33aadc7cfad | 51 | bool full = false; // boolean to control whether full binary numbers sent |
r14793 | 0:b33aadc7cfad | 52 | bool gui = true; // flag to print data out in compressed format |
r14793 | 0:b33aadc7cfad | 53 | bool bargraph = true; // flag for bar graph... |
r14793 | 0:b33aadc7cfad | 54 | bool logging = false; |
r14793 | 0:b33aadc7cfad | 55 | bool flag; |
r14793 | 0:b33aadc7cfad | 56 | |
r14793 | 0:b33aadc7cfad | 57 | // timer so we can time how long things take... |
r14793 | 0:b33aadc7cfad | 58 | Timer t, l; |
r14793 | 0:b33aadc7cfad | 59 | |
r14793 | 0:b33aadc7cfad | 60 | // set up various arrays related to smart sensors... |
r14793 | 0:b33aadc7cfad | 61 | bool present[sensors] = { false, false }; // whether or not a sensor is present |
r14793 | 0:b33aadc7cfad | 62 | bool continuous = true; // flag for making continuous vs. triggered measurements... |
r14793 | 0:b33aadc7cfad | 63 | // this array of addresses also needed to be made a const array or |
r14793 | 0:b33aadc7cfad | 64 | // some values would inexplicably change and cause I2C errors |
r14793 | 0:b33aadc7cfad | 65 | // (because the address in the array gets changed somehow)... const fixes... |
r14793 | 0:b33aadc7cfad | 66 | // this seems to be mbed-2 related... |
r14793 | 0:b33aadc7cfad | 67 | const short int address[sensors] = // assigned address for each sensor |
r14793 | 0:b33aadc7cfad | 68 | { 0x50<<1, 0x51<<1, 0x52<<1, 0x53<<1, 0x54<<1, |
r14793 | 0:b33aadc7cfad | 69 | 0x55<<1, 0x56<<1, 0x57<<1, 0x58<<1, 0x59<<1, |
r14793 | 0:b33aadc7cfad | 70 | 0x5a<<1, 0x5b<<1, 0x5c<<1, 0x5d<<1 }; |
r14793 | 0:b33aadc7cfad | 71 | |
r14793 | 0:b33aadc7cfad | 72 | // this union allows easily converting float value to bare bytes and back again... |
r14793 | 0:b33aadc7cfad | 73 | union u_tag { |
r14793 | 0:b33aadc7cfad | 74 | char b[4]; |
r14793 | 0:b33aadc7cfad | 75 | float fval; |
r14793 | 0:b33aadc7cfad | 76 | int bobo; // just in case we want to see it as an int... |
r14793 | 0:b33aadc7cfad | 77 | } volt[2], curr[2]; // voltage and current value from sensor |
r14793 | 0:b33aadc7cfad | 78 | |
r14793 | 0:b33aadc7cfad | 79 | // these arrays are used for keeping track of the range status of each sensor... |
r14793 | 0:b33aadc7cfad | 80 | int rangeStatus[sensors] = {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', }; |
r14793 | 0:b33aadc7cfad | 81 | char rangesAvail[4] = {' ', 'H', 'M', 'L'}; |
r14793 | 0:b33aadc7cfad | 82 | |
r14793 | 0:b33aadc7cfad | 83 | |
r14793 | 0:b33aadc7cfad | 84 | // function that sends measurement trigger pulse to all sensors, singalling |
r14793 | 0:b33aadc7cfad | 85 | // them to take a measurement which will be subsequently and sequentially read... |
r14793 | 0:b33aadc7cfad | 86 | void send_trigger(){ |
r14793 | 0:b33aadc7cfad | 87 | interrupt = 1; |
r14793 | 0:b33aadc7cfad | 88 | wait_us(50); |
r14793 | 0:b33aadc7cfad | 89 | interrupt = 0; |
r14793 | 0:b33aadc7cfad | 90 | } |
r14793 | 0:b33aadc7cfad | 91 | |
r14793 | 0:b33aadc7cfad | 92 | |
r14793 | 0:b33aadc7cfad | 93 | |
r14793 | 0:b33aadc7cfad | 94 | // main code starts here... |
r14793 | 0:b33aadc7cfad | 95 | int main() { |
r14793 | 0:b33aadc7cfad | 96 | |
r14793 | 0:b33aadc7cfad | 97 | // set things up... |
r14793 | 0:b33aadc7cfad | 98 | reset = 0; // place sensors in reset |
r14793 | 0:b33aadc7cfad | 99 | interrupt = 0; // place trigger line low |
r14793 | 0:b33aadc7cfad | 100 | for (k=0; k<sensors; k++) select[k] = 1; // set each sensor's select line high |
r14793 | 0:b33aadc7cfad | 101 | |
r14793 | 0:b33aadc7cfad | 102 | i2c.frequency(200000); // set I2C frequency |
r14793 | 0:b33aadc7cfad | 103 | uart.baud(115200); // set UART baud rate |
r14793 | 0:b33aadc7cfad | 104 | uart.printf("\r\n\r\n\e[2J%s\r\nI'm here...\r\n ", version_info); // signal that we're off and running... |
r14793 | 0:b33aadc7cfad | 105 | // where \e[2J clears the screen... |
r14793 | 0:b33aadc7cfad | 106 | |
r14793 | 0:b33aadc7cfad | 107 | // loop forever (although, as code has evolved, this loop never completes...) |
r14793 | 0:b33aadc7cfad | 108 | while(1) { |
r14793 | 0:b33aadc7cfad | 109 | reset = 0; // issue a global reset |
r14793 | 0:b33aadc7cfad | 110 | wait(0.01); // wait a bit |
r14793 | 0:b33aadc7cfad | 111 | reset = 1; // release reset |
r14793 | 0:b33aadc7cfad | 112 | count++; // overall iteration count |
r14793 | 0:b33aadc7cfad | 113 | uart.printf("\r\n\r\nReleased reset... %d\r\n", count); |
r14793 | 0:b33aadc7cfad | 114 | |
r14793 | 0:b33aadc7cfad | 115 | wait(0.0005); // wait a little bit... |
r14793 | 0:b33aadc7cfad | 116 | |
r14793 | 0:b33aadc7cfad | 117 | // iterate to identify and configure each connected sensor... |
r14793 | 0:b33aadc7cfad | 118 | for (k=0; k<sensors; k++){ // loop over all sensors |
r14793 | 0:b33aadc7cfad | 119 | present[k] = false; // set presence to false before looking for sensor... |
r14793 | 0:b33aadc7cfad | 120 | |
r14793 | 0:b33aadc7cfad | 121 | select[k] = 0; // smake sensor select line low to start address reassignment |
r14793 | 0:b33aadc7cfad | 122 | uart.printf("Asserted select[%X] line low... \r\n", k); |
r14793 | 0:b33aadc7cfad | 123 | |
r14793 | 0:b33aadc7cfad | 124 | wait(0.001); // wait a bit... |
r14793 | 0:b33aadc7cfad | 125 | |
r14793 | 0:b33aadc7cfad | 126 | // write the new address to sensor and then read it back to verify... |
r14793 | 0:b33aadc7cfad | 127 | cmd[0] = address[k]; |
r14793 | 0:b33aadc7cfad | 128 | n = i2c.write( addr8bit, cmd, 1); |
r14793 | 0:b33aadc7cfad | 129 | uart.printf("Wrote: %x error %d \r\n", cmd[0], n); |
r14793 | 0:b33aadc7cfad | 130 | if (n==0) present[k] = true; // a sensor IS connected on this select line, since it ACKed |
r14793 | 0:b33aadc7cfad | 131 | if (present[k]){ |
r14793 | 0:b33aadc7cfad | 132 | cmd[0] = 0; // clear cmd... |
r14793 | 0:b33aadc7cfad | 133 | wait(0.0001); |
r14793 | 0:b33aadc7cfad | 134 | n = i2c.read( addr8bit, cmd, 1); |
r14793 | 0:b33aadc7cfad | 135 | uart.printf(" ===> Read back: %x error %d\r\n", cmd[0], n); |
r14793 | 0:b33aadc7cfad | 136 | // here we're reading it back but we're not actually checking the value... |
r14793 | 0:b33aadc7cfad | 137 | // just assuming that since we were able to write, we'll read the same |
r14793 | 0:b33aadc7cfad | 138 | // value back... |
r14793 | 0:b33aadc7cfad | 139 | } else i2c.stop(); // not present, error condition... |
r14793 | 0:b33aadc7cfad | 140 | |
r14793 | 0:b33aadc7cfad | 141 | wait(0.0001); |
r14793 | 0:b33aadc7cfad | 142 | select[k] = 1; // set sensor's select line high, telling it to change its I2C addr |
r14793 | 0:b33aadc7cfad | 143 | uart.printf("Sending select[%X] back high to change address... \r\n", k); |
r14793 | 0:b33aadc7cfad | 144 | |
r14793 | 0:b33aadc7cfad | 145 | if (present[k]) { |
r14793 | 0:b33aadc7cfad | 146 | // now check that the address change was successful... |
r14793 | 0:b33aadc7cfad | 147 | // write to the new address, there is currently no error out |
r14793 | 0:b33aadc7cfad | 148 | // if sensor does not respond... |
r14793 | 0:b33aadc7cfad | 149 | wait(0.0001); |
r14793 | 0:b33aadc7cfad | 150 | cmd[0]=0xff; |
r14793 | 0:b33aadc7cfad | 151 | n = i2c.write( address[k], cmd, 1); |
r14793 | 0:b33aadc7cfad | 152 | if (n==0) { uart.printf("\r\nSensor %X configured... now to test... \r\n\r\n", k); } |
r14793 | 0:b33aadc7cfad | 153 | else present[k]=false; |
r14793 | 0:b33aadc7cfad | 154 | } // endif |
r14793 | 0:b33aadc7cfad | 155 | |
r14793 | 0:b33aadc7cfad | 156 | if (present[k]) { |
r14793 | 0:b33aadc7cfad | 157 | // read parameters from sensor |
r14793 | 0:b33aadc7cfad | 158 | // Need to do this sequence without a trigger, since that'll cause an interrupt |
r14793 | 0:b33aadc7cfad | 159 | // and clobber any pre-loaded paramter data... |
r14793 | 0:b33aadc7cfad | 160 | cmd[0] = 99; // make a dummy write in order to pre-load parameter buffer... |
r14793 | 0:b33aadc7cfad | 161 | n = i2c.write( address[k], cmd, 2 ); |
r14793 | 0:b33aadc7cfad | 162 | wait(0.001); |
r14793 | 0:b33aadc7cfad | 163 | // here's where we actually read the parameters: |
r14793 | 0:b33aadc7cfad | 164 | n = i2c.read( address[k], params[k], 9 ); // select is already high from above, so we don't need to do it again... |
r14793 | 0:b33aadc7cfad | 165 | uart.printf("\r\n params %d %d %d %d %d %d \r\n", params[k][0], params[k][1]*8, params[k][2]*8, params[k][3]*8, params[k][4]*8, params[k][5]); |
r14793 | 0:b33aadc7cfad | 166 | |
r14793 | 0:b33aadc7cfad | 167 | // now add one to each parameter to make sure we can write them all... |
r14793 | 0:b33aadc7cfad | 168 | // will see below if it worked... (we'll see it down below) |
r14793 | 0:b33aadc7cfad | 169 | for (i=0; i<6; i++){ |
r14793 | 0:b33aadc7cfad | 170 | cmd[0] = i; |
r14793 | 0:b33aadc7cfad | 171 | cmd[1] = params[k][i]+1; |
r14793 | 0:b33aadc7cfad | 172 | uart.printf(" %d, %d, %d %d \r\n", k, i, cmd[0], cmd[1]); |
r14793 | 0:b33aadc7cfad | 173 | n = i2c.write( address[k], cmd, 2 ); |
r14793 | 0:b33aadc7cfad | 174 | wait(0.01); |
r14793 | 0:b33aadc7cfad | 175 | } |
r14793 | 0:b33aadc7cfad | 176 | |
r14793 | 0:b33aadc7cfad | 177 | } |
r14793 | 0:b33aadc7cfad | 178 | |
r14793 | 0:b33aadc7cfad | 179 | } // for k |
r14793 | 0:b33aadc7cfad | 180 | |
r14793 | 0:b33aadc7cfad | 181 | wait(0.0005); |
r14793 | 0:b33aadc7cfad | 182 | |
r14793 | 0:b33aadc7cfad | 183 | // ****************************************************************** |
r14793 | 0:b33aadc7cfad | 184 | // read data from all connected sensors... |
r14793 | 0:b33aadc7cfad | 185 | // ****************************************************************** |
r14793 | 0:b33aadc7cfad | 186 | while (1) { |
r14793 | 0:b33aadc7cfad | 187 | |
r14793 | 0:b33aadc7cfad | 188 | if (!logging) { |
r14793 | 0:b33aadc7cfad | 189 | if (!gui) uart.printf("\r\nTriggering measurement... \r\n"); |
r14793 | 0:b33aadc7cfad | 190 | else { |
r14793 | 0:b33aadc7cfad | 191 | uart.printf("\e[2J"); // clear screen |
r14793 | 0:b33aadc7cfad | 192 | uart.printf("\033[H"); // go to upper left corner of window |
r14793 | 0:b33aadc7cfad | 193 | uart.printf("\r\n\033[0;36mRail (V) (A)\033[0;37m\r\n"); |
r14793 | 0:b33aadc7cfad | 194 | } |
r14793 | 0:b33aadc7cfad | 195 | } |
r14793 | 0:b33aadc7cfad | 196 | |
r14793 | 0:b33aadc7cfad | 197 | /* // testing curr_range indicators... |
r14793 | 0:b33aadc7cfad | 198 | uart.printf("\r\n"); |
r14793 | 0:b33aadc7cfad | 199 | for (i=0; i<sensors; i++){ |
r14793 | 0:b33aadc7cfad | 200 | //if (present[i]) |
r14793 | 0:b33aadc7cfad | 201 | uart.printf("%X: .%d. ", i, rangeStatus[i]); |
r14793 | 0:b33aadc7cfad | 202 | } uart.printf("\r\n"); |
r14793 | 0:b33aadc7cfad | 203 | */ |
r14793 | 0:b33aadc7cfad | 204 | |
r14793 | 0:b33aadc7cfad | 205 | t.start(); |
r14793 | 0:b33aadc7cfad | 206 | send_trigger(); // trigger tells all connected sensors to make the measurements |
r14793 | 0:b33aadc7cfad | 207 | wait_ms(8.75); // need to give enough time to make them... |
r14793 | 0:b33aadc7cfad | 208 | if (logging) uart.printf("%6.2f ", l.read()); // print timestamp if logging... |
r14793 | 0:b33aadc7cfad | 209 | for (k=0; k<sensors; k++){ // iterate over all sensors |
r14793 | 0:b33aadc7cfad | 210 | if (present[k]){ // if a sensor is present, read its data |
r14793 | 0:b33aadc7cfad | 211 | |
r14793 | 0:b33aadc7cfad | 212 | if (full){ |
r14793 | 0:b33aadc7cfad | 213 | // full floating point data tranfer... |
r14793 | 0:b33aadc7cfad | 214 | n = i2c.read( address[k], cmd, 9 ); |
r14793 | 0:b33aadc7cfad | 215 | if (deebug && !gui && !logging) uart.printf(" I2C adddr: 0x%X %X\r\n", address[k], k); |
r14793 | 0:b33aadc7cfad | 216 | // unstuff the bytes back into floating point values... |
r14793 | 0:b33aadc7cfad | 217 | for (j=0; j<4; j++) curr[0].b[j] = cmd[j]; |
r14793 | 0:b33aadc7cfad | 218 | for (j=0; j<4; j++) volt[0].b[j] = cmd[j+4]; |
r14793 | 0:b33aadc7cfad | 219 | v1 = volt[0].fval; i1 = curr[0].fval; |
r14793 | 0:b33aadc7cfad | 220 | if (!gui && !logging) uart.printf(" Sensor %X: ===> %4.2e %4.2e 0x%x err %d\r\n", k, volt[0].fval, curr[0].fval, cmd[8], n); |
r14793 | 0:b33aadc7cfad | 221 | } // if (full) |
r14793 | 0:b33aadc7cfad | 222 | |
r14793 | 0:b33aadc7cfad | 223 | // compressed data transfer with status nibble: 2 float values of 3 sig figs each + status nibble: |
r14793 | 0:b33aadc7cfad | 224 | // where each value is 3 digits, single digit exponent, and two status bits packed into 2 bytes |
r14793 | 0:b33aadc7cfad | 225 | // four bytes in total... |
r14793 | 0:b33aadc7cfad | 226 | select[k] = 0; // indicate that we want to read compressed data from sensor... |
r14793 | 0:b33aadc7cfad | 227 | n = i2c.read( address[k], cmd, 4 ); |
r14793 | 0:b33aadc7cfad | 228 | select[k] = 1; |
r14793 | 0:b33aadc7cfad | 229 | // pull out status bits from the four received bytes... |
r14793 | 0:b33aadc7cfad | 230 | status = (cmd[0]&(1<<7))>>4 | (cmd[1]&(1<<7))>>5 | (cmd[2]&(1<<7))>>6 | (cmd[3]&(1<<7))>>7 ; |
r14793 | 0:b33aadc7cfad | 231 | if (deebug && !gui && !logging) uart.printf(" %02d %02d %02d %02d %8.6f %d %8.6f %d\r\n", cmd[0]&0x7f, cmd[1]&0x7f, cmd[2]&0x7f, cmd[3]&0x7f, |
r14793 | 0:b33aadc7cfad | 232 | pow10[(int)(((cmd[1]&(0x7f)) % 10)+2)], (int) (((cmd[1]&(0x7f)) % 10)+2), |
r14793 | 0:b33aadc7cfad | 233 | pow10[(int)(((cmd[3]&(0x7f)) % 10)+2)], (int) (((cmd[3]&(0x7f)) % 10)+2)); |
r14793 | 0:b33aadc7cfad | 234 | // now reconstruct the two float values... |
r14793 | 0:b33aadc7cfad | 235 | curr[1].fval = (float) ( (cmd[0]&(0x7f))*10 + (cmd[1]&(0x7f))/10 ) * pow10[((cmd[1]&(0x7f)) % 10)+2]; |
r14793 | 0:b33aadc7cfad | 236 | volt[1].fval = (float) ( (cmd[2]&(0x7f))*10 + (cmd[3]&(0x7f))/10 ) * pow10[((cmd[3]&(0x7f)) % 10)+2]; |
r14793 | 0:b33aadc7cfad | 237 | v2 = volt[1].fval; i2 = curr[1].fval; |
r14793 | 0:b33aadc7cfad | 238 | if (!gui && !logging) uart.printf(" compd %X: ===> %4.2e V %4.2e A %d err %d\r\n", k, volt[1].fval, curr[1].fval, status, n); |
r14793 | 0:b33aadc7cfad | 239 | if (deebug && !gui) printf(" volt? %s current? %s \r\n", |
r14793 | 0:b33aadc7cfad | 240 | (abs(v1-v2)/v1 <0.05) ? "true" : "false", |
r14793 | 0:b33aadc7cfad | 241 | (abs(i1-i2)/i1 <0.05) ? "true" : "false"); |
r14793 | 0:b33aadc7cfad | 242 | |
r14793 | 0:b33aadc7cfad | 243 | // if we're in gui mode, this is the only line that'll print out for each attached sensor... |
r14793 | 0:b33aadc7cfad | 244 | if (!logging){ |
r14793 | 0:b33aadc7cfad | 245 | if (gui && full) { // uart.printf(" %X %4.2e %4.2e %4.2e %4.2e \r\n", k, v1, v2, i1, i2); |
r14793 | 0:b33aadc7cfad | 246 | uart.printf(" \033[33m#%X\033[37m %3.2f %4.2e %c ", k , v1, i1, rangeStatus[k]); |
r14793 | 0:b33aadc7cfad | 247 | if ((i1>=0.25) && (bargraph)) { |
r14793 | 0:b33aadc7cfad | 248 | for (j=0; j<13*i1; j++) uart.printf("\033[31mA"); |
r14793 | 0:b33aadc7cfad | 249 | } |
r14793 | 0:b33aadc7cfad | 250 | if ((i1<0.25) && (i1>=0.001) && (bargraph)) { |
r14793 | 0:b33aadc7cfad | 251 | for (j=0; j<208*i1; j++) uart.printf("\033[32mm"); |
r14793 | 0:b33aadc7cfad | 252 | } |
r14793 | 0:b33aadc7cfad | 253 | if ((i1<0.001) && (bargraph)) { |
r14793 | 0:b33aadc7cfad | 254 | for (j=0; j<52000*i1; j++) uart.printf("\033[35mu"); |
r14793 | 0:b33aadc7cfad | 255 | } |
r14793 | 0:b33aadc7cfad | 256 | uart.printf("\033[37m\r\n"); |
r14793 | 0:b33aadc7cfad | 257 | } |
r14793 | 0:b33aadc7cfad | 258 | else { |
r14793 | 0:b33aadc7cfad | 259 | uart.printf(" \033[33m#%X\033[37m %3.2f %4.2e %c ", k , v2, i2, rangeStatus[k]); |
r14793 | 0:b33aadc7cfad | 260 | if ((i2>=0.25) && (bargraph)) { |
r14793 | 0:b33aadc7cfad | 261 | for (j=0; j<13*i2; j++) uart.printf("\033[31mA"); |
r14793 | 0:b33aadc7cfad | 262 | } |
r14793 | 0:b33aadc7cfad | 263 | if ((i2<0.25) && (i2>=0.001) && (bargraph)) { |
r14793 | 0:b33aadc7cfad | 264 | for (j=0; j<208*i2; j++) uart.printf("\033[32mm"); |
r14793 | 0:b33aadc7cfad | 265 | } |
r14793 | 0:b33aadc7cfad | 266 | if ((i2<0.001) && (bargraph)) { |
r14793 | 0:b33aadc7cfad | 267 | for (j=0; j<52000*i2; j++) uart.printf("\033[35mu"); |
r14793 | 0:b33aadc7cfad | 268 | } |
r14793 | 0:b33aadc7cfad | 269 | uart.printf("\033[37m\r\n"); |
r14793 | 0:b33aadc7cfad | 270 | |
r14793 | 0:b33aadc7cfad | 271 | /* // testing curr_range indicators... |
r14793 | 0:b33aadc7cfad | 272 | uart.printf(" "); |
r14793 | 0:b33aadc7cfad | 273 | for (i=0; i<sensors; i++){ |
r14793 | 0:b33aadc7cfad | 274 | //if (present[i]) |
r14793 | 0:b33aadc7cfad | 275 | uart.printf("%X: .%d. ", i, rangeStatus[i]); |
r14793 | 0:b33aadc7cfad | 276 | } uart.printf("\r\n"); |
r14793 | 0:b33aadc7cfad | 277 | */ |
r14793 | 0:b33aadc7cfad | 278 | |
r14793 | 0:b33aadc7cfad | 279 | } // else |
r14793 | 0:b33aadc7cfad | 280 | } else { |
r14793 | 0:b33aadc7cfad | 281 | uart.printf(" %3.2e %4.2e", v2, i2); |
r14793 | 0:b33aadc7cfad | 282 | } |
r14793 | 0:b33aadc7cfad | 283 | |
r14793 | 0:b33aadc7cfad | 284 | // parameter readback from sensor |
r14793 | 0:b33aadc7cfad | 285 | // !! Smart Sensor's selelct line needs to be high while doing this !! |
r14793 | 0:b33aadc7cfad | 286 | // Need to do this sequence without a trigger, since that'll cause an interrupt |
r14793 | 0:b33aadc7cfad | 287 | // and clobber any pre-loaded paramter data... |
r14793 | 0:b33aadc7cfad | 288 | if (deebug && !gui && !logging) { |
r14793 | 0:b33aadc7cfad | 289 | cmd[0] = 99; // dummy write to pre-load parameter buffer... |
r14793 | 0:b33aadc7cfad | 290 | n = i2c.write( address[k], cmd, 2 ); |
r14793 | 0:b33aadc7cfad | 291 | n = i2c.read( address[k], params[k], 9 ); // select is already high from above, so we don't need to do it again... |
r14793 | 0:b33aadc7cfad | 292 | uart.printf(" params %d %d %d %d %d %d \r\n", params[k][0], params[k][1]*8, params[k][2]*8, params[k][3]*8, params[k][4]*8, params[k][5]); |
r14793 | 0:b33aadc7cfad | 293 | } |
r14793 | 0:b33aadc7cfad | 294 | } |
r14793 | 0:b33aadc7cfad | 295 | else{ |
r14793 | 0:b33aadc7cfad | 296 | //uart.printf(" !!! device %d missing... \r\n", k); |
r14793 | 0:b33aadc7cfad | 297 | } //endif |
r14793 | 0:b33aadc7cfad | 298 | } // for k |
r14793 | 0:b33aadc7cfad | 299 | if (logging) uart.printf("\r\n"); |
r14793 | 0:b33aadc7cfad | 300 | // wait_ms(250); |
r14793 | 0:b33aadc7cfad | 301 | while (t.read_us()<delay){ |
r14793 | 0:b33aadc7cfad | 302 | // wait until delay worth of time has elapsed... |
r14793 | 0:b33aadc7cfad | 303 | } |
r14793 | 0:b33aadc7cfad | 304 | t.stop(); |
r14793 | 0:b33aadc7cfad | 305 | t.reset(); |
r14793 | 0:b33aadc7cfad | 306 | |
r14793 | 0:b33aadc7cfad | 307 | if (!continuous) while (!uart.readable()); // wait here until we get text, if in triggered mode... |
r14793 | 0:b33aadc7cfad | 308 | while (uart.readable()){ |
r14793 | 0:b33aadc7cfad | 309 | temp = uart.getc(); |
r14793 | 0:b33aadc7cfad | 310 | |
r14793 | 0:b33aadc7cfad | 311 | if (deebug) printf ("%d\r\n", temp); |
r14793 | 0:b33aadc7cfad | 312 | if (temp== '+') { |
r14793 | 0:b33aadc7cfad | 313 | delay += 100000; |
r14793 | 0:b33aadc7cfad | 314 | if (delay > 2000000) delay = 2000000; |
r14793 | 0:b33aadc7cfad | 315 | } |
r14793 | 0:b33aadc7cfad | 316 | if (temp== '-') { |
r14793 | 0:b33aadc7cfad | 317 | delay -=100000; |
r14793 | 0:b33aadc7cfad | 318 | if (delay < 14300) delay = 14300; |
r14793 | 0:b33aadc7cfad | 319 | } |
r14793 | 0:b33aadc7cfad | 320 | if (temp== 't') { |
r14793 | 0:b33aadc7cfad | 321 | uart.printf ("\r\nDelay value = %d\r\n", delay); |
r14793 | 0:b33aadc7cfad | 322 | } |
r14793 | 0:b33aadc7cfad | 323 | if (temp== '_') { |
r14793 | 0:b33aadc7cfad | 324 | delay = 500000; |
r14793 | 0:b33aadc7cfad | 325 | } |
r14793 | 0:b33aadc7cfad | 326 | if (temp== 'c') { |
r14793 | 0:b33aadc7cfad | 327 | continuous = !continuous; |
r14793 | 0:b33aadc7cfad | 328 | } |
r14793 | 0:b33aadc7cfad | 329 | if (temp== 'd') { |
r14793 | 0:b33aadc7cfad | 330 | deebug = !deebug; |
r14793 | 0:b33aadc7cfad | 331 | } |
r14793 | 0:b33aadc7cfad | 332 | if (temp== 'g') { |
r14793 | 0:b33aadc7cfad | 333 | gui = false; |
r14793 | 0:b33aadc7cfad | 334 | } |
r14793 | 0:b33aadc7cfad | 335 | if (temp== 'G') { |
r14793 | 0:b33aadc7cfad | 336 | gui = true; |
r14793 | 0:b33aadc7cfad | 337 | } |
r14793 | 0:b33aadc7cfad | 338 | |
r14793 | 0:b33aadc7cfad | 339 | if (temp==(int) 'b') { |
r14793 | 0:b33aadc7cfad | 340 | bargraph = !bargraph; |
r14793 | 0:b33aadc7cfad | 341 | } |
r14793 | 0:b33aadc7cfad | 342 | |
r14793 | 0:b33aadc7cfad | 343 | if ((temp== 'l')||(temp== 'L')) { |
r14793 | 0:b33aadc7cfad | 344 | if (!logging) { |
r14793 | 0:b33aadc7cfad | 345 | uart.printf("Enable logfile and then hit any key when ready...\r\n"); |
r14793 | 0:b33aadc7cfad | 346 | while (!uart.readable()); // only pause if we're already logging... |
r14793 | 0:b33aadc7cfad | 347 | temp = uart.getc(); // capture last character so we don't do it again... |
r14793 | 0:b33aadc7cfad | 348 | } |
r14793 | 0:b33aadc7cfad | 349 | logging = !logging; // toggle logging flag... |
r14793 | 0:b33aadc7cfad | 350 | // print a header if we're just starting to log... |
r14793 | 0:b33aadc7cfad | 351 | uart.printf("Time_S"); |
r14793 | 0:b33aadc7cfad | 352 | for (j=0; k<sensors; k++){ |
r14793 | 0:b33aadc7cfad | 353 | if (logging && present[j]) uart.printf(" Volts_%d Amps_%d", j, j); |
r14793 | 0:b33aadc7cfad | 354 | } |
r14793 | 0:b33aadc7cfad | 355 | if (logging) uart.printf("\r\n"); |
r14793 | 0:b33aadc7cfad | 356 | l.reset(); |
r14793 | 0:b33aadc7cfad | 357 | l.start(); // for timestamping the output... |
r14793 | 0:b33aadc7cfad | 358 | } |
r14793 | 0:b33aadc7cfad | 359 | |
r14793 | 0:b33aadc7cfad | 360 | if (temp=='f') { |
r14793 | 0:b33aadc7cfad | 361 | full = !full; |
r14793 | 0:b33aadc7cfad | 362 | uart.printf("\r\n\r\n"); |
r14793 | 0:b33aadc7cfad | 363 | if (full) uart.printf("Full data over I2C"); |
r14793 | 0:b33aadc7cfad | 364 | else uart.printf("Compressed data over I2C"); |
r14793 | 0:b33aadc7cfad | 365 | wait(2); |
r14793 | 0:b33aadc7cfad | 366 | } |
r14793 | 0:b33aadc7cfad | 367 | |
r14793 | 0:b33aadc7cfad | 368 | if (temp=='h') { |
r14793 | 0:b33aadc7cfad | 369 | uart.printf("\r\n\r\n"); |
r14793 | 0:b33aadc7cfad | 370 | uart.printf("+/- add/remove update time\r\n"); |
r14793 | 0:b33aadc7cfad | 371 | uart.printf("_ half second update rate\r\n"); |
r14793 | 0:b33aadc7cfad | 372 | uart.printf("b toggle bar graph in gui mode\r\n"); |
r14793 | 0:b33aadc7cfad | 373 | uart.printf("c toggle continuous/single trigger\r\n"); |
r14793 | 0:b33aadc7cfad | 374 | uart.printf("t trigger and print current delay value\r\n"); |
r14793 | 0:b33aadc7cfad | 375 | uart.printf("d toggle debug flag\r\n"); |
r14793 | 0:b33aadc7cfad | 376 | uart.printf("f toggke full data over I2C\r\n"); |
r14793 | 0:b33aadc7cfad | 377 | uart.printf("g turn off gui mode\r\n"); |
r14793 | 0:b33aadc7cfad | 378 | uart.printf("G turn on gui mode\r\n"); |
r14793 | 0:b33aadc7cfad | 379 | uart.printf("h print this help\r\n"); |
r14793 | 0:b33aadc7cfad | 380 | uart.printf("l toggle logging output\r\n"); |
r14793 | 0:b33aadc7cfad | 381 | uart.printf("R/r enter range selection menu\r\n"); |
r14793 | 0:b33aadc7cfad | 382 | uart.printf("\r\n"); |
r14793 | 0:b33aadc7cfad | 383 | wait(5); |
r14793 | 0:b33aadc7cfad | 384 | } |
r14793 | 0:b33aadc7cfad | 385 | |
r14793 | 0:b33aadc7cfad | 386 | if (temp=='R' || temp=='r') { |
r14793 | 0:b33aadc7cfad | 387 | // present range changing stuff... |
r14793 | 0:b33aadc7cfad | 388 | uart.printf("\r\nCAUTION: Selecting fixed range can damage sensor!\r\n\r\n"); |
r14793 | 0:b33aadc7cfad | 389 | uart.printf("Select a valid channel:\r\n"); |
r14793 | 0:b33aadc7cfad | 390 | for (j=0; j<sensors; j++){ // iterate over all sensors |
r14793 | 0:b33aadc7cfad | 391 | if (present[j]) uart.printf("%X ", j); |
r14793 | 0:b33aadc7cfad | 392 | } |
r14793 | 0:b33aadc7cfad | 393 | uart.printf("\r\n"); |
r14793 | 0:b33aadc7cfad | 394 | // Select which channel to change range... |
r14793 | 0:b33aadc7cfad | 395 | flag = true; |
r14793 | 0:b33aadc7cfad | 396 | while (flag){ |
r14793 | 0:b33aadc7cfad | 397 | while (!uart.readable()); |
r14793 | 0:b33aadc7cfad | 398 | temp = uart.getc(); // capture last character so we don't do it again... |
r14793 | 0:b33aadc7cfad | 399 | // test input validity... |
r14793 | 0:b33aadc7cfad | 400 | if ((int) '0'<=temp && temp<= (int) '9') chan = temp - (int) '0'; |
r14793 | 0:b33aadc7cfad | 401 | else if ((int) 'a'<=temp && temp<=(int) 'd') chan = temp - (int) 'a' + 10; |
r14793 | 0:b33aadc7cfad | 402 | else if ((int) 'A'<=temp && temp<=(int) 'D') chan = temp - (int) 'A' + 10; |
r14793 | 0:b33aadc7cfad | 403 | // then test that input is actually a valid channel... |
r14793 | 0:b33aadc7cfad | 404 | for (i=0; i<sensors; i++){ // iterate over all sensors |
r14793 | 0:b33aadc7cfad | 405 | if (present[i] && chan==i) { |
r14793 | 0:b33aadc7cfad | 406 | flag = false; // turn off flag so we leave the while loop... |
r14793 | 0:b33aadc7cfad | 407 | break; // break out of the for loop... |
r14793 | 0:b33aadc7cfad | 408 | } |
r14793 | 0:b33aadc7cfad | 409 | } |
r14793 | 0:b33aadc7cfad | 410 | } |
r14793 | 0:b33aadc7cfad | 411 | // present range choices... |
r14793 | 0:b33aadc7cfad | 412 | uart.printf("\r\n Selected: %X \r\n", chan); |
r14793 | 0:b33aadc7cfad | 413 | uart.printf("Select Current Range:\r\n"); |
r14793 | 0:b33aadc7cfad | 414 | uart.printf("A = Autorange\r\n"); |
r14793 | 0:b33aadc7cfad | 415 | uart.printf("H = High only\r\n"); |
r14793 | 0:b33aadc7cfad | 416 | uart.printf("M = Middle only\r\n"); |
r14793 | 0:b33aadc7cfad | 417 | uart.printf("L = Low only\r\n"); |
r14793 | 0:b33aadc7cfad | 418 | uart.printf("X = Exit, no change\r\n"); |
r14793 | 0:b33aadc7cfad | 419 | // select which range to use... |
r14793 | 0:b33aadc7cfad | 420 | flag = true; |
r14793 | 0:b33aadc7cfad | 421 | while (flag){ |
r14793 | 0:b33aadc7cfad | 422 | while (!uart.readable()); |
r14793 | 0:b33aadc7cfad | 423 | temp = (int) uart.getc(); // capture last character so we don't do it again... |
r14793 | 0:b33aadc7cfad | 424 | if ('A'==temp || 'a'==temp) {flag = false; range = 0;} |
r14793 | 0:b33aadc7cfad | 425 | if ('H'==temp || 'h'==temp) {flag = false; range = 1;} |
r14793 | 0:b33aadc7cfad | 426 | if ('M'==temp || 'm'==temp) {flag = false; range = 2;} |
r14793 | 0:b33aadc7cfad | 427 | if ('L'==temp || 'l'==temp) {flag = false; range = 3;} |
r14793 | 0:b33aadc7cfad | 428 | if ('X'==temp || 'x'==temp) {flag = false; range = 4;} |
r14793 | 0:b33aadc7cfad | 429 | } |
r14793 | 0:b33aadc7cfad | 430 | uart.printf(" Range %d \r\n", range); |
r14793 | 0:b33aadc7cfad | 431 | if (range<4) { |
r14793 | 0:b33aadc7cfad | 432 | cmd[0] = 127; |
r14793 | 0:b33aadc7cfad | 433 | cmd[1] = range; |
r14793 | 0:b33aadc7cfad | 434 | uart.printf(" %d, %d, %d \r\n", chan, cmd[0], cmd[1]); |
r14793 | 0:b33aadc7cfad | 435 | n = i2c.write( address[chan], cmd, 2 ); |
r14793 | 0:b33aadc7cfad | 436 | wait_ms(10); |
r14793 | 0:b33aadc7cfad | 437 | n = i2c.read( address[chan], cmd, 9 ); // read back to make sure... |
r14793 | 0:b33aadc7cfad | 438 | rangeStatus[chan] = rangesAvail[ cmd[8] ]; |
r14793 | 0:b33aadc7cfad | 439 | uart.printf(" reported range = %d ('%c')\r\n", params[chan][8], rangeStatus[chan]); |
r14793 | 0:b33aadc7cfad | 440 | wait(1); |
r14793 | 0:b33aadc7cfad | 441 | } |
r14793 | 0:b33aadc7cfad | 442 | } // range changing block... |
r14793 | 0:b33aadc7cfad | 443 | |
r14793 | 0:b33aadc7cfad | 444 | } // while uart.readable... |
r14793 | 0:b33aadc7cfad | 445 | |
r14793 | 0:b33aadc7cfad | 446 | } // while read from sensors... |
r14793 | 0:b33aadc7cfad | 447 | // ***************************************************************** |
r14793 | 0:b33aadc7cfad | 448 | // end data read |
r14793 | 0:b33aadc7cfad | 449 | // ***************************************************************** |
r14793 | 0:b33aadc7cfad | 450 | } // while main, should never actually fall out to here... |
r14793 | 0:b33aadc7cfad | 451 | |
r14793 | 0:b33aadc7cfad | 452 | } // main |