posilani dat
Dependencies: FatFileSystemCpp mbed PowerControl USBHostLite
main.cpp@15:baa2672a9b38, 2015-10-22 (annotated)
- Committer:
- legwinskij
- Date:
- Thu Oct 22 17:16:52 2015 +0000
- Revision:
- 15:baa2672a9b38
- Parent:
- 14:6bd7d1fff6af
- Child:
- 17:ca53e6d36163
Completely refactored fw, changelog in main
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
legwinskij | 15:baa2672a9b38 | 1 | /* BRIEF: |
jkaderka | 9:8839ecc02e0e | 2 | * Connects to wifi and listen on ip given by dhcp on port 2000 |
jkaderka | 9:8839ecc02e0e | 3 | * |
jkaderka | 9:8839ecc02e0e | 4 | * Commands are send in for #X where X is from {S,E,T,R}, all commands are |
jkaderka | 9:8839ecc02e0e | 5 | * confirmed by mbed by sending #A |
jkaderka | 9:8839ecc02e0e | 6 | * |
jkaderka | 9:8839ecc02e0e | 7 | * Use #S to start saving data, #E to stop saving. This can be done repeatedly, |
jkaderka | 9:8839ecc02e0e | 8 | * mbed saves the data into separated files and generates new swimmer id |
jkaderka | 9:8839ecc02e0e | 9 | * At the end, use #T to start data transfer, the format of transmitted data is: |
jkaderka | 9:8839ecc02e0e | 10 | * |
jkaderka | 9:8839ecc02e0e | 11 | * Header for each swimmer: |
jkaderka | 9:8839ecc02e0e | 12 | * (int) -1 (int) -1 (int) swimmer_id |
jkaderka | 9:8839ecc02e0e | 13 | * Data itself |
jkaderka | 9:8839ecc02e0e | 14 | * (char) 0xAA (int) count 3*(short) acc 3*(float) gyro |
jkaderka | 9:8839ecc02e0e | 15 | * End of swimmer block |
jkaderka | 9:8839ecc02e0e | 16 | * (int) -1 (int) -1 |
jkaderka | 9:8839ecc02e0e | 17 | * |
jkaderka | 9:8839ecc02e0e | 18 | * where count is number starting on 0, incremented on every packet |
jkaderka | 9:8839ecc02e0e | 19 | * 0xAA is a sync byte used to avoid confusion when some bytes are lost during |
jkaderka | 9:8839ecc02e0e | 20 | * transmission (UART on faster reates seems to be unstable) |
legwinskij | 15:baa2672a9b38 | 21 | * |
legwinskij | 15:baa2672a9b38 | 22 | * CHANGELOG 22/10/2015 |
legwinskij | 15:baa2672a9b38 | 23 | * - Refactored code |
legwinskij | 15:baa2672a9b38 | 24 | * - Now using USB flash instead of SD card |
legwinskij | 15:baa2672a9b38 | 25 | * - SIZE of packets to be saved at once changed to 32 (from 1000, saving took too much time, effectively loosing measurements) |
legwinskij | 15:baa2672a9b38 | 26 | * - Using fwrite to write 32 packets at once (packet size = 16 bytes -> 32*16 = 512 bytes -> USB flash sector size is 512 bytes, thus maximizing fwrite effectivity |
legwinskij | 15:baa2672a9b38 | 27 | * - Saving of 32 packets takes about 3,5 ms |
legwinskij | 15:baa2672a9b38 | 28 | * KNOWN ISSUES: |
legwinskij | 15:baa2672a9b38 | 29 | * - Opening USB disk takes some time, couple first measurements not valid (perhaps open next file right when saving stops ?) |
jkaderka | 9:8839ecc02e0e | 30 | */ |
legwinskij | 15:baa2672a9b38 | 31 | |
legwinskij | 15:baa2672a9b38 | 32 | // Includes ==================================================================== |
legwinskij | 15:baa2672a9b38 | 33 | |
jkaderka | 0:16fd37cf4a7c | 34 | #include "mbed.h" |
legwinskij | 14:6bd7d1fff6af | 35 | #include "PowerControl.h" |
legwinskij | 14:6bd7d1fff6af | 36 | #include "EthernetPowerControl.h" |
jkaderka | 0:16fd37cf4a7c | 37 | #include "L3GD20_init.h" |
jkaderka | 0:16fd37cf4a7c | 38 | #include "math.h" |
jkaderka | 0:16fd37cf4a7c | 39 | #include "stdint.h" |
jkaderka | 0:16fd37cf4a7c | 40 | #include "DirHandle.h" |
legwinskij | 15:baa2672a9b38 | 41 | #include "MSCFileSystem.h" |
jkaderka | 0:16fd37cf4a7c | 42 | #include "L3GD20.h" |
jkaderka | 0:16fd37cf4a7c | 43 | #include "adc.h" |
jkaderka | 2:f623d1815dc4 | 44 | #include "utils.h" |
jkaderka | 4:030c7726c7dc | 45 | #include "wifi.h" |
jkaderka | 0:16fd37cf4a7c | 46 | #include <stdio.h> |
jkaderka | 0:16fd37cf4a7c | 47 | |
legwinskij | 15:baa2672a9b38 | 48 | // Defines ===================================================================== |
legwinskij | 15:baa2672a9b38 | 49 | |
jkaderka | 9:8839ecc02e0e | 50 | /* credentials for wifi */ |
jkaderka | 8:ae5319de2c33 | 51 | #define SSID "BRNET" |
jkaderka | 8:ae5319de2c33 | 52 | #define PASS "Fuhu27che9" |
jkaderka | 4:030c7726c7dc | 53 | #define SECURITY WPA |
jkaderka | 9:8839ecc02e0e | 54 | |
legwinskij | 15:baa2672a9b38 | 55 | /* ADC & data acquisition related stuff */ |
legwinskij | 15:baa2672a9b38 | 56 | #define SAMPLE_RATE 700000 // Sample rate for ADC conversion |
legwinskij | 15:baa2672a9b38 | 57 | #define PERIOD 0.01 // Setting the period of measuring, 0.01 menas 100 times per second |
legwinskij | 15:baa2672a9b38 | 58 | #define SIZE 32 // Setting number of instance in array - for saving to SD card |
legwinskij | 15:baa2672a9b38 | 59 | #define BUFFER_SIZE (sizeof(int) + sizeof(short)*6) //size of one data block |
jkaderka | 2:f623d1815dc4 | 60 | |
legwinskij | 15:baa2672a9b38 | 61 | /* mass storage disk name */ |
legwinskij | 15:baa2672a9b38 | 62 | #define FSNAME "usb" |
jkaderka | 1:3ec5f7df2410 | 63 | |
legwinskij | 15:baa2672a9b38 | 64 | /* Commands mbed understands */ |
legwinskij | 15:baa2672a9b38 | 65 | #define SAVING_START 'S' |
legwinskij | 15:baa2672a9b38 | 66 | #define SAVING_STOP 'E' |
legwinskij | 15:baa2672a9b38 | 67 | #define TRANSFER_START 'T' |
legwinskij | 15:baa2672a9b38 | 68 | #define CHECK_READY 'R' |
legwinskij | 15:baa2672a9b38 | 69 | |
legwinskij | 15:baa2672a9b38 | 70 | /* Function like macros for leds (bleh) */ |
jkaderka | 1:3ec5f7df2410 | 71 | #define leds_off() { led_measuring = led_sending = led_working = led_saving = 0; } |
jkaderka | 1:3ec5f7df2410 | 72 | #define leds_error() { led_measuring = led_sending = led_working = led_saving = 1; } |
jkaderka | 0:16fd37cf4a7c | 73 | |
legwinskij | 15:baa2672a9b38 | 74 | // Watchdog class ============================================================== |
jkaderka | 0:16fd37cf4a7c | 75 | |
jkaderka | 0:16fd37cf4a7c | 76 | class Watchdog { |
jkaderka | 0:16fd37cf4a7c | 77 | public: |
legwinskij | 15:baa2672a9b38 | 78 | /* Kick the watchdog with time period setting */ |
jkaderka | 0:16fd37cf4a7c | 79 | void kick(float s) { |
legwinskij | 15:baa2672a9b38 | 80 | LPC_WDT->WDCLKSEL = 0x1; // Set CLK src to PCLK |
legwinskij | 15:baa2672a9b38 | 81 | uint32_t clk = SystemCoreClock / 16; // WD has a fixed /4 prescaler, PCLK default is /4 |
legwinskij | 15:baa2672a9b38 | 82 | LPC_WDT->WDTC = s * (float)clk; |
legwinskij | 15:baa2672a9b38 | 83 | LPC_WDT->WDMOD = 0x3; // Enabled and Reset |
jkaderka | 0:16fd37cf4a7c | 84 | kick(); |
jkaderka | 0:16fd37cf4a7c | 85 | } |
legwinskij | 15:baa2672a9b38 | 86 | |
legwinskij | 15:baa2672a9b38 | 87 | /* Kick the watchdog */ |
jkaderka | 0:16fd37cf4a7c | 88 | void kick() { |
jkaderka | 0:16fd37cf4a7c | 89 | LPC_WDT->WDFEED = 0xAA; |
jkaderka | 0:16fd37cf4a7c | 90 | LPC_WDT->WDFEED = 0x55; |
jkaderka | 0:16fd37cf4a7c | 91 | } |
jkaderka | 0:16fd37cf4a7c | 92 | }; |
jkaderka | 0:16fd37cf4a7c | 93 | |
legwinskij | 15:baa2672a9b38 | 94 | // Objects & vars ============================================================== |
legwinskij | 15:baa2672a9b38 | 95 | |
legwinskij | 15:baa2672a9b38 | 96 | Watchdog w; // Initialize watchdogs |
legwinskij | 15:baa2672a9b38 | 97 | Ticker Saving_Ticker; // Tickers for interrupts on measuring |
legwinskij | 15:baa2672a9b38 | 98 | ADC adc(SAMPLE_RATE, 1); // Initialize ADC to maximum SAMPLE_RATE and cclk divide set to 1 originally MMA7361L |
legwinskij | 15:baa2672a9b38 | 99 | Wifi wifi(p13, p14, p11, p12, p23); // Wifly module |
legwinskij | 15:baa2672a9b38 | 100 | I2C i2c(p28, p27); // NEW function GYRO connection originally L3G4200D |
jkaderka | 0:16fd37cf4a7c | 101 | |
legwinskij | 15:baa2672a9b38 | 102 | /* LED indicators */ |
legwinskij | 15:baa2672a9b38 | 103 | DigitalOut led_measuring(LED1); |
legwinskij | 15:baa2672a9b38 | 104 | DigitalOut led_sending(LED2); |
legwinskij | 15:baa2672a9b38 | 105 | DigitalOut led_working(LED3); |
legwinskij | 15:baa2672a9b38 | 106 | DigitalOut led_saving(LED4); |
jkaderka | 0:16fd37cf4a7c | 107 | |
legwinskij | 15:baa2672a9b38 | 108 | // Added for test purposes |
legwinskij | 15:baa2672a9b38 | 109 | DigitalOut flagSetNotify(p9); |
legwinskij | 15:baa2672a9b38 | 110 | DigitalOut measureNotify(p10); |
legwinskij | 15:baa2672a9b38 | 111 | |
legwinskij | 15:baa2672a9b38 | 112 | /* USB & saving related stuffs */ |
legwinskij | 15:baa2672a9b38 | 113 | FILE *gfp; // Global file pointer |
legwinskij | 15:baa2672a9b38 | 114 | MSCFileSystem logger(FSNAME); // Initialize USB flash disk |
legwinskij | 15:baa2672a9b38 | 115 | char fname[40]; // Variable for name of Text file saved on USB flash disk |
legwinskij | 15:baa2672a9b38 | 116 | static volatile uint64_t absolute = 0; // Variable for numbering saved data |
jkaderka | 1:3ec5f7df2410 | 117 | volatile int relative = 0; |
jkaderka | 1:3ec5f7df2410 | 118 | volatile short swimmer_id = 0; |
jkaderka | 11:137108e3403e | 119 | volatile short last_send = 0; |
legwinskij | 15:baa2672a9b38 | 120 | volatile bool measuringFlag = 0; // Flag that is set with interrupt |
jkaderka | 0:16fd37cf4a7c | 121 | |
legwinskij | 15:baa2672a9b38 | 122 | /* Accelerometer buffers */ |
jkaderka | 5:83f69916e571 | 123 | short int acc_x[SIZE]; |
jkaderka | 5:83f69916e571 | 124 | short int acc_y[SIZE]; |
jkaderka | 5:83f69916e571 | 125 | short int acc_z[SIZE]; |
jkaderka | 0:16fd37cf4a7c | 126 | |
legwinskij | 15:baa2672a9b38 | 127 | /* Gyroscope buffers */ |
jkaderka | 13:d00c8a6a2e8c | 128 | short int gyro_x[SIZE]; |
jkaderka | 13:d00c8a6a2e8c | 129 | short int gyro_y[SIZE]; |
jkaderka | 13:d00c8a6a2e8c | 130 | short int gyro_z[SIZE]; |
jkaderka | 0:16fd37cf4a7c | 131 | |
legwinskij | 15:baa2672a9b38 | 132 | // Functions -> I2C ============================================================ |
legwinskij | 15:baa2672a9b38 | 133 | |
legwinskij | 15:baa2672a9b38 | 134 | /* Reads byte from given address */ |
jkaderka | 0:16fd37cf4a7c | 135 | char readByte(char address, char reg) |
jkaderka | 0:16fd37cf4a7c | 136 | { |
legwinskij | 15:baa2672a9b38 | 137 | char result; // Buffer for returning byte |
legwinskij | 15:baa2672a9b38 | 138 | i2c.start(); // Start i2c transfer |
legwinskij | 15:baa2672a9b38 | 139 | i2c.write(address); // Slave address with direction=write |
legwinskij | 15:baa2672a9b38 | 140 | i2c.write(reg); // Register address |
legwinskij | 15:baa2672a9b38 | 141 | i2c.start(); // Break transmission to change bus direction |
legwinskij | 15:baa2672a9b38 | 142 | i2c.write(address + 1); // Slave address with direction=read [bit0=1] |
legwinskij | 15:baa2672a9b38 | 143 | result = i2c.read(0); // Byte we want to read |
legwinskij | 15:baa2672a9b38 | 144 | i2c.stop(); // Stop i2c operation |
legwinskij | 15:baa2672a9b38 | 145 | return (result); // Return byte |
legwinskij | 15:baa2672a9b38 | 146 | } |
legwinskij | 15:baa2672a9b38 | 147 | |
legwinskij | 15:baa2672a9b38 | 148 | /* Sends 1 byte to an I2C address */ |
legwinskij | 15:baa2672a9b38 | 149 | void writeByte(char address, char reg,char value) |
legwinskij | 15:baa2672a9b38 | 150 | { |
legwinskij | 15:baa2672a9b38 | 151 | i2c.start(); // Start i2c transfer |
legwinskij | 15:baa2672a9b38 | 152 | i2c.write(address); // Slave address |
legwinskij | 15:baa2672a9b38 | 153 | i2c.write(reg); // Register address |
legwinskij | 15:baa2672a9b38 | 154 | i2c.write(value); // Value to be written |
legwinskij | 15:baa2672a9b38 | 155 | i2c.stop(); // Stop i2c operation |
jkaderka | 0:16fd37cf4a7c | 156 | } |
legwinskij | 15:baa2672a9b38 | 157 | |
legwinskij | 15:baa2672a9b38 | 158 | // Functions -> Init =========================================================== |
legwinskij | 15:baa2672a9b38 | 159 | |
legwinskij | 15:baa2672a9b38 | 160 | /* Prepares board for operation (adc's, gyroscope etc.) */ |
legwinskij | 15:baa2672a9b38 | 161 | void boardInit (void) |
jkaderka | 0:16fd37cf4a7c | 162 | { |
legwinskij | 15:baa2672a9b38 | 163 | /* L3GD20 Gyroscope init */ |
legwinskij | 15:baa2672a9b38 | 164 | writeByte(L3GD20_ADDR,gCTRL_REG1,0x0F); // Set ODR to 95Hz, BW to 12.5Hz, enable axes and turn on device |
legwinskij | 15:baa2672a9b38 | 165 | writeByte(L3GD20_ADDR,gCTRL_REG4,0x10); // Full scale selected at 500dps (degrees per second) |
legwinskij | 15:baa2672a9b38 | 166 | wait(1); // Wait for settings to stabilize |
jkaderka | 0:16fd37cf4a7c | 167 | |
legwinskij | 15:baa2672a9b38 | 168 | /* Accelerometer init */ |
legwinskij | 15:baa2672a9b38 | 169 | adc.setup(p18,1); // Set up ADC on pin 18 |
legwinskij | 15:baa2672a9b38 | 170 | adc.setup(p19,1); // Set up ADC on pin 19 |
legwinskij | 15:baa2672a9b38 | 171 | adc.setup(p20,1); // Set up ADC on pin 20 |
jkaderka | 0:16fd37cf4a7c | 172 | |
legwinskij | 15:baa2672a9b38 | 173 | /* Rest of the init */ |
legwinskij | 15:baa2672a9b38 | 174 | PHY_PowerDown(); // Disable ETH PHY to conserve power (about 40mA) |
legwinskij | 15:baa2672a9b38 | 175 | leds_off(); // Turn off all leds |
legwinskij | 15:baa2672a9b38 | 176 | } |
legwinskij | 15:baa2672a9b38 | 177 | |
legwinskij | 15:baa2672a9b38 | 178 | // Functions -> Measuring ====================================================== |
legwinskij | 15:baa2672a9b38 | 179 | |
legwinskij | 15:baa2672a9b38 | 180 | /* Main measuring function */ |
jkaderka | 1:3ec5f7df2410 | 181 | void measuring(void) |
jkaderka | 0:16fd37cf4a7c | 182 | { |
legwinskij | 15:baa2672a9b38 | 183 | /* Vars */ |
legwinskij | 15:baa2672a9b38 | 184 | char xL, xH, yL, yH, zL, zH; // Gyro high/low bytes |
legwinskij | 15:baa2672a9b38 | 185 | char buffer[SIZE][BUFFER_SIZE]; // Buffer |
legwinskij | 15:baa2672a9b38 | 186 | int pos = 0; // Position |
legwinskij | 15:baa2672a9b38 | 187 | |
legwinskij | 15:baa2672a9b38 | 188 | /* Read ACC_X */ |
legwinskij | 15:baa2672a9b38 | 189 | adc.start(); // Starting ADC conversion |
legwinskij | 15:baa2672a9b38 | 190 | adc.select(p18); // Measure pin 18 |
legwinskij | 15:baa2672a9b38 | 191 | while(!adc.done(p18)); // Wait for it to complete |
legwinskij | 15:baa2672a9b38 | 192 | acc_x[relative] = (short) adc.read(p18); // Read ACC_X value |
legwinskij | 15:baa2672a9b38 | 193 | /* Read ACC_Y */ |
legwinskij | 15:baa2672a9b38 | 194 | adc.start(); // Again |
legwinskij | 15:baa2672a9b38 | 195 | adc.select(p19); // Measure pin 19 |
legwinskij | 15:baa2672a9b38 | 196 | while(!adc.done(p19)); // Wait for it to complete |
legwinskij | 15:baa2672a9b38 | 197 | acc_y[relative] = (short) adc.read(p19); // Read ACC_Y value |
legwinskij | 15:baa2672a9b38 | 198 | /* Read ACC_Z */ |
legwinskij | 15:baa2672a9b38 | 199 | adc.start(); // Again |
legwinskij | 15:baa2672a9b38 | 200 | adc.select(p20); // Measure pin 20 |
legwinskij | 15:baa2672a9b38 | 201 | while(!adc.done(p20)); // Wait for it to complete |
legwinskij | 15:baa2672a9b38 | 202 | acc_z[relative] = (short) adc.read(p20); // Read ACC_Z value |
jkaderka | 0:16fd37cf4a7c | 203 | |
legwinskij | 15:baa2672a9b38 | 204 | /* Read Gyro_X */ |
legwinskij | 15:baa2672a9b38 | 205 | xL=readByte(L3GD20_ADDR,gOUT_X_L); // Read GYRO_X Low byte |
legwinskij | 15:baa2672a9b38 | 206 | xH=readByte(L3GD20_ADDR,gOUT_X_H); // Read GYRO_X High byte |
legwinskij | 15:baa2672a9b38 | 207 | /* Read Gyro_X */ |
legwinskij | 15:baa2672a9b38 | 208 | yL=readByte(L3GD20_ADDR,gOUT_Y_L); // Read GYRO_Y Low byte |
legwinskij | 15:baa2672a9b38 | 209 | yH=readByte(L3GD20_ADDR,gOUT_Y_H); // Read GYRO_Y High byte |
legwinskij | 15:baa2672a9b38 | 210 | /* Read Gyro_X */ |
legwinskij | 15:baa2672a9b38 | 211 | zL=readByte(L3GD20_ADDR,gOUT_Z_L); // Read GYRO_Z Low byte |
legwinskij | 15:baa2672a9b38 | 212 | zH=readByte(L3GD20_ADDR,gOUT_Z_H); // Read GYRO_Z High byte |
legwinskij | 15:baa2672a9b38 | 213 | /* Add Gyroscope values to global buffer */ |
legwinskij | 15:baa2672a9b38 | 214 | gyro_x[relative] = (xH<<8) | (xL); // 16-bit 2's complement GYRO_X |
legwinskij | 15:baa2672a9b38 | 215 | gyro_y[relative] = (yH<<8) | (yL); // 16-bit 2's complement GYRO_Y |
legwinskij | 15:baa2672a9b38 | 216 | gyro_z[relative] = (zH<<8) | (zL); // 16-bit 2's complement GYRO_Z |
jkaderka | 0:16fd37cf4a7c | 217 | |
legwinskij | 15:baa2672a9b38 | 218 | /* Increment counters */ |
legwinskij | 15:baa2672a9b38 | 219 | absolute++; // Increment absolute counter |
legwinskij | 15:baa2672a9b38 | 220 | relative++; // Increment relative counter |
legwinskij | 15:baa2672a9b38 | 221 | |
legwinskij | 15:baa2672a9b38 | 222 | /* After our buffers are full save the data */ |
legwinskij | 15:baa2672a9b38 | 223 | if ( absolute % SIZE == 0 ) |
legwinskij | 15:baa2672a9b38 | 224 | { |
legwinskij | 15:baa2672a9b38 | 225 | /* Flip led_saving state */ |
jkaderka | 1:3ec5f7df2410 | 226 | led_saving = !led_saving; |
legwinskij | 15:baa2672a9b38 | 227 | |
legwinskij | 15:baa2672a9b38 | 228 | /* Handle file error */ |
legwinskij | 15:baa2672a9b38 | 229 | if (gfp == NULL) { |
legwinskij | 15:baa2672a9b38 | 230 | printf("\r\nUnable to append data to file %s", fname); // Notify user |
legwinskij | 15:baa2672a9b38 | 231 | return; // Return |
jkaderka | 1:3ec5f7df2410 | 232 | } |
jkaderka | 1:3ec5f7df2410 | 233 | |
legwinskij | 15:baa2672a9b38 | 234 | /* Iterate all buffer elements */ |
legwinskij | 15:baa2672a9b38 | 235 | for (int k = 0; k < SIZE; k++) |
legwinskij | 15:baa2672a9b38 | 236 | { |
legwinskij | 15:baa2672a9b38 | 237 | pos = absolute-SIZE+k; // Increment position |
legwinskij | 15:baa2672a9b38 | 238 | toBytes(buffer[k], &pos, sizeof(int)); // Append data to buffer in byte form |
legwinskij | 15:baa2672a9b38 | 239 | toBytes(buffer[k]+sizeof(int), &acc_x[k], sizeof(short)); |
legwinskij | 15:baa2672a9b38 | 240 | toBytes(buffer[k]+sizeof(int) + sizeof(short), &acc_y[k], sizeof(short)); |
legwinskij | 15:baa2672a9b38 | 241 | toBytes(buffer[k]+sizeof(int) + sizeof(short)*2, &acc_z[k], sizeof(short)); |
legwinskij | 15:baa2672a9b38 | 242 | toBytes(buffer[k]+sizeof(int) + sizeof(short)*3, &gyro_x[k], sizeof(short)); |
legwinskij | 15:baa2672a9b38 | 243 | toBytes(buffer[k]+sizeof(int) + sizeof(short)*4, &gyro_y[k], sizeof(short)); |
legwinskij | 15:baa2672a9b38 | 244 | toBytes(buffer[k]+sizeof(int) + sizeof(short)*5, &gyro_z[k], sizeof(short)); |
jkaderka | 0:16fd37cf4a7c | 245 | } |
legwinskij | 15:baa2672a9b38 | 246 | |
legwinskij | 15:baa2672a9b38 | 247 | //measureNotify = 1; // Used for saving debug |
legwinskij | 15:baa2672a9b38 | 248 | /* Write 32 buffer lines (16 bytes) to file (512 bytes total -> one block) */ |
legwinskij | 15:baa2672a9b38 | 249 | fwrite(buffer, SIZE, BUFFER_SIZE, gfp); |
legwinskij | 15:baa2672a9b38 | 250 | //measureNotify = 0; // Used for saving debug |
legwinskij | 15:baa2672a9b38 | 251 | |
legwinskij | 15:baa2672a9b38 | 252 | /* Reset relative counter */ |
legwinskij | 15:baa2672a9b38 | 253 | relative = 0; |
jkaderka | 0:16fd37cf4a7c | 254 | } |
legwinskij | 15:baa2672a9b38 | 255 | } |
legwinskij | 15:baa2672a9b38 | 256 | |
legwinskij | 15:baa2672a9b38 | 257 | /* Sets the measuring flag */ |
legwinskij | 15:baa2672a9b38 | 258 | void setMeasuringFlag(void) |
legwinskij | 15:baa2672a9b38 | 259 | { |
legwinskij | 15:baa2672a9b38 | 260 | //flagSetNotify = 1; // Used for saving debug |
legwinskij | 15:baa2672a9b38 | 261 | measuringFlag = 1; // Set measuring flag |
legwinskij | 15:baa2672a9b38 | 262 | //flagSetNotify = 0; // Used for saving debug |
legwinskij | 15:baa2672a9b38 | 263 | } |
legwinskij | 15:baa2672a9b38 | 264 | |
legwinskij | 15:baa2672a9b38 | 265 | /* Starts to acquire data from sensors */ |
legwinskij | 15:baa2672a9b38 | 266 | void startSaving(void) |
legwinskij | 15:baa2672a9b38 | 267 | { |
legwinskij | 15:baa2672a9b38 | 268 | /* Open global file with current swimmer ID */ |
legwinskij | 15:baa2672a9b38 | 269 | gfp = fopen(fname, "wb"); // Try to open that file |
legwinskij | 15:baa2672a9b38 | 270 | if(gfp == NULL) { |
legwinskij | 15:baa2672a9b38 | 271 | leds_error(); // Turn on all leds |
legwinskij | 15:baa2672a9b38 | 272 | printf("\r\nUnable to open file %s for writing", fname); // Notify user |
legwinskij | 15:baa2672a9b38 | 273 | return; // Exit function |
legwinskij | 15:baa2672a9b38 | 274 | } |
legwinskij | 15:baa2672a9b38 | 275 | |
legwinskij | 15:baa2672a9b38 | 276 | /* Prepare file & vars for data acquisition */ |
legwinskij | 15:baa2672a9b38 | 277 | fprintf(gfp, "%c%c%c", -1, -1, swimmer_id); // Append header to current swimmer output file |
legwinskij | 15:baa2672a9b38 | 278 | |
legwinskij | 15:baa2672a9b38 | 279 | /* Reset counters */ |
legwinskij | 15:baa2672a9b38 | 280 | absolute = 0; // Reset absolute counter |
legwinskij | 15:baa2672a9b38 | 281 | relative = 0; // Reset relative counter |
legwinskij | 15:baa2672a9b38 | 282 | |
legwinskij | 15:baa2672a9b38 | 283 | /* Set timer */ |
legwinskij | 15:baa2672a9b38 | 284 | Saving_Ticker.attach(&setMeasuringFlag, PERIOD); // Attach function that periodically sets the flag |
legwinskij | 15:baa2672a9b38 | 285 | } |
legwinskij | 15:baa2672a9b38 | 286 | |
legwinskij | 15:baa2672a9b38 | 287 | /* Sends acquired data to USB flash */ |
legwinskij | 15:baa2672a9b38 | 288 | void stopSaving(void) |
legwinskij | 15:baa2672a9b38 | 289 | { |
legwinskij | 15:baa2672a9b38 | 290 | /* Stop saving */ |
legwinskij | 15:baa2672a9b38 | 291 | Saving_Ticker.detach(); // Stop setting measuring flag |
jkaderka | 1:3ec5f7df2410 | 292 | |
legwinskij | 15:baa2672a9b38 | 293 | /* Try to append data left in buffers */ |
legwinskij | 15:baa2672a9b38 | 294 | if(gfp == NULL) { |
legwinskij | 15:baa2672a9b38 | 295 | leds_error(); // Turn on all leds |
legwinskij | 15:baa2672a9b38 | 296 | printf("\r\nUnable to open file %s before sending data", fname); // Notify user |
legwinskij | 15:baa2672a9b38 | 297 | return; // Exit function |
legwinskij | 15:baa2672a9b38 | 298 | } |
legwinskij | 15:baa2672a9b38 | 299 | |
legwinskij | 15:baa2672a9b38 | 300 | /* Append data left to buffer */ |
legwinskij | 15:baa2672a9b38 | 301 | int base = ((absolute - (absolute%SIZE)) < 0) ? 0 : absolute - (absolute%SIZE); |
legwinskij | 15:baa2672a9b38 | 302 | char buffer[relative][BUFFER_SIZE]; // packet array |
legwinskij | 15:baa2672a9b38 | 303 | |
legwinskij | 15:baa2672a9b38 | 304 | /* Iterate all array elements */ |
legwinskij | 15:baa2672a9b38 | 305 | for (int k = 0; k < relative; k++) { |
legwinskij | 15:baa2672a9b38 | 306 | int pos = base+k; |
legwinskij | 15:baa2672a9b38 | 307 | toBytes(buffer[k], &pos, sizeof(int)); |
legwinskij | 15:baa2672a9b38 | 308 | toBytes(buffer[k]+sizeof(int), &acc_x[k], sizeof(short)); |
legwinskij | 15:baa2672a9b38 | 309 | toBytes(buffer[k]+sizeof(int) + sizeof(short), &acc_y[k], sizeof(short)); |
legwinskij | 15:baa2672a9b38 | 310 | toBytes(buffer[k]+sizeof(int) + sizeof(short)*2, &acc_z[k], sizeof(short)); |
legwinskij | 15:baa2672a9b38 | 311 | toBytes(buffer[k]+sizeof(int) + sizeof(short)*3, &gyro_x[k], sizeof(short)); |
legwinskij | 15:baa2672a9b38 | 312 | toBytes(buffer[k]+sizeof(int) + sizeof(short)*4, &gyro_y[k], sizeof(short)); |
legwinskij | 15:baa2672a9b38 | 313 | toBytes(buffer[k]+sizeof(int) + sizeof(short)*5, &gyro_z[k], sizeof(short)); |
legwinskij | 15:baa2672a9b38 | 314 | } |
legwinskij | 15:baa2672a9b38 | 315 | |
legwinskij | 15:baa2672a9b38 | 316 | /* Write what's left */ |
legwinskij | 15:baa2672a9b38 | 317 | fwrite(buffer, relative, BUFFER_SIZE, gfp); // Write all data at once |
legwinskij | 15:baa2672a9b38 | 318 | |
legwinskij | 15:baa2672a9b38 | 319 | /* Append EOF and close file */ |
legwinskij | 15:baa2672a9b38 | 320 | fprintf(gfp, "%c%c", -1,-1); // Write EOF characters |
legwinskij | 15:baa2672a9b38 | 321 | fclose(gfp); // Close file |
jkaderka | 1:3ec5f7df2410 | 322 | |
legwinskij | 15:baa2672a9b38 | 323 | /* Prepare for next swimmer */ |
legwinskij | 15:baa2672a9b38 | 324 | swimmer_id++; // Increment swimmer ID |
legwinskij | 15:baa2672a9b38 | 325 | sprintf(fname, "/usb/swimmer%d.txt", swimmer_id); // Update current file name |
legwinskij | 15:baa2672a9b38 | 326 | remove(fname); // If file with such ID exists remove it to avoid reading old data |
legwinskij | 15:baa2672a9b38 | 327 | } |
legwinskij | 15:baa2672a9b38 | 328 | |
legwinskij | 15:baa2672a9b38 | 329 | /* Sends acquired data via Wi-Fi */ |
legwinskij | 15:baa2672a9b38 | 330 | void transfer(void) |
legwinskij | 15:baa2672a9b38 | 331 | { |
legwinskij | 15:baa2672a9b38 | 332 | /* Timeout (to make sure C# app gets ready) */ |
legwinskij | 15:baa2672a9b38 | 333 | wait_ms(100); |
legwinskij | 15:baa2672a9b38 | 334 | |
legwinskij | 15:baa2672a9b38 | 335 | /* Vars */ |
legwinskij | 15:baa2672a9b38 | 336 | int i; // Iterator |
legwinskij | 15:baa2672a9b38 | 337 | char name[30]; // File name buffer |
legwinskij | 15:baa2672a9b38 | 338 | |
legwinskij | 15:baa2672a9b38 | 339 | /* Iterate all captured swimmers */ |
legwinskij | 15:baa2672a9b38 | 340 | for (i = 0; i < swimmer_id; i++) // Iterate all available swimmer files |
legwinskij | 15:baa2672a9b38 | 341 | { |
legwinskij | 15:baa2672a9b38 | 342 | sprintf(name, "/usb/swimmer%d.txt", i); // Create file name based on current swimmer ID |
legwinskij | 15:baa2672a9b38 | 343 | fclose(gfp); |
legwinskij | 15:baa2672a9b38 | 344 | printf("\r\nSending %s", name); // Notify user which user is being sent |
legwinskij | 15:baa2672a9b38 | 345 | if (wifi.sendFile(gfp ,name, i)) // Send ! |
legwinskij | 15:baa2672a9b38 | 346 | { |
legwinskij | 15:baa2672a9b38 | 347 | leds_error(); // Handle error |
legwinskij | 15:baa2672a9b38 | 348 | printf("\r\nUnable to send data"); // Notify user via text also |
legwinskij | 15:baa2672a9b38 | 349 | } |
legwinskij | 15:baa2672a9b38 | 350 | else |
legwinskij | 15:baa2672a9b38 | 351 | { |
legwinskij | 15:baa2672a9b38 | 352 | printf("\r\nSwimmer %d finished", i); // Otherwise all is AOK |
jkaderka | 10:fdf9ca254549 | 353 | } |
jkaderka | 0:16fd37cf4a7c | 354 | } |
jkaderka | 0:16fd37cf4a7c | 355 | } |
jkaderka | 0:16fd37cf4a7c | 356 | |
legwinskij | 15:baa2672a9b38 | 357 | // Main ======================================================================== |
legwinskij | 15:baa2672a9b38 | 358 | |
jkaderka | 0:16fd37cf4a7c | 359 | int main() |
jkaderka | 0:16fd37cf4a7c | 360 | { |
legwinskij | 15:baa2672a9b38 | 361 | /* Begin by initialization */ |
legwinskij | 15:baa2672a9b38 | 362 | printf("\r\nBoot..."); // Notify user that board is booting |
legwinskij | 15:baa2672a9b38 | 363 | boardInit(); // Initialize board |
legwinskij | 15:baa2672a9b38 | 364 | printf("\r\nReady..."); // Notify user that board is ready |
jkaderka | 0:16fd37cf4a7c | 365 | |
legwinskij | 15:baa2672a9b38 | 366 | /* Set zeroth swimmer name */ |
legwinskij | 15:baa2672a9b38 | 367 | sprintf(fname, "/usb/swimmer%d.txt", swimmer_id); // Prepare zeroth swimmer filename |
jkaderka | 10:fdf9ca254549 | 368 | |
legwinskij | 15:baa2672a9b38 | 369 | /* Main while */ |
legwinskij | 15:baa2672a9b38 | 370 | while (1) |
legwinskij | 15:baa2672a9b38 | 371 | { |
legwinskij | 15:baa2672a9b38 | 372 | /* Read command from wifly */ |
jkaderka | 4:030c7726c7dc | 373 | char cmd = wifi.getCmd(); |
jkaderka | 1:3ec5f7df2410 | 374 | |
legwinskij | 15:baa2672a9b38 | 375 | /* Master switch */ |
jkaderka | 1:3ec5f7df2410 | 376 | switch (cmd) { |
legwinskij | 15:baa2672a9b38 | 377 | /* start measuring data periodically and save them info file */ |
legwinskij | 15:baa2672a9b38 | 378 | case SAVING_START: |
legwinskij | 15:baa2672a9b38 | 379 | { |
legwinskij | 15:baa2672a9b38 | 380 | leds_off(); // Turn off all leds |
legwinskij | 15:baa2672a9b38 | 381 | startSaving(); // Actually start saving |
legwinskij | 15:baa2672a9b38 | 382 | printf("\r\nSaving swimmer %d...", swimmer_id); // Notify user |
legwinskij | 15:baa2672a9b38 | 383 | led_measuring = 1; // Turn on led_measuring |
legwinskij | 15:baa2672a9b38 | 384 | break; // Break from switch |
jkaderka | 1:3ec5f7df2410 | 385 | } |
jkaderka | 1:3ec5f7df2410 | 386 | |
legwinskij | 15:baa2672a9b38 | 387 | /* stop saving data */ |
legwinskij | 15:baa2672a9b38 | 388 | case SAVING_STOP: |
legwinskij | 15:baa2672a9b38 | 389 | { |
legwinskij | 15:baa2672a9b38 | 390 | leds_off(); // Turn off all leds |
legwinskij | 15:baa2672a9b38 | 391 | stopSaving(); // Actually stop saving |
legwinskij | 15:baa2672a9b38 | 392 | printf("\r\nStopped..."); // Notify user |
legwinskij | 15:baa2672a9b38 | 393 | break; // Break from switch |
jkaderka | 1:3ec5f7df2410 | 394 | } |
legwinskij | 15:baa2672a9b38 | 395 | |
legwinskij | 15:baa2672a9b38 | 396 | /* Send all data */ |
legwinskij | 15:baa2672a9b38 | 397 | case TRANSFER_START: |
legwinskij | 15:baa2672a9b38 | 398 | { |
legwinskij | 15:baa2672a9b38 | 399 | leds_off(); // Turn off all leds |
legwinskij | 15:baa2672a9b38 | 400 | led_sending = 1; // Turn on led_sending |
legwinskij | 15:baa2672a9b38 | 401 | printf("\r\nSending data..."); // Notify user that data is being sent |
legwinskij | 15:baa2672a9b38 | 402 | transfer(); // Actually transfer data |
legwinskij | 15:baa2672a9b38 | 403 | printf("\r\nSending finished..."); // Notify user that data was sent successfully |
legwinskij | 15:baa2672a9b38 | 404 | leds_off(); // Turn off all leds again |
legwinskij | 15:baa2672a9b38 | 405 | break; // Break from switch |
jkaderka | 1:3ec5f7df2410 | 406 | } |
jkaderka | 1:3ec5f7df2410 | 407 | |
legwinskij | 15:baa2672a9b38 | 408 | /* Ready || Nothing on serial */ |
legwinskij | 15:baa2672a9b38 | 409 | case 'R': |
legwinskij | 15:baa2672a9b38 | 410 | case 'N': |
legwinskij | 15:baa2672a9b38 | 411 | { |
legwinskij | 15:baa2672a9b38 | 412 | /* Handle data measuring */ |
legwinskij | 15:baa2672a9b38 | 413 | if(measuringFlag) // Wait for timer to set the flag again and again |
legwinskij | 15:baa2672a9b38 | 414 | { |
legwinskij | 15:baa2672a9b38 | 415 | measuring(); // Measure ! |
legwinskij | 15:baa2672a9b38 | 416 | measuringFlag = 0; // Reset flag |
legwinskij | 15:baa2672a9b38 | 417 | } |
legwinskij | 15:baa2672a9b38 | 418 | |
legwinskij | 15:baa2672a9b38 | 419 | break; // Break from switch |
legwinskij | 15:baa2672a9b38 | 420 | } |
legwinskij | 15:baa2672a9b38 | 421 | |
legwinskij | 15:baa2672a9b38 | 422 | /* Everything else is ballast */ |
legwinskij | 15:baa2672a9b38 | 423 | default : |
legwinskij | 15:baa2672a9b38 | 424 | { |
legwinskij | 15:baa2672a9b38 | 425 | leds_error(); // Turn on all leds |
legwinskij | 15:baa2672a9b38 | 426 | printf("\r\nCommand %c is unknown!", cmd); // Notify user |
legwinskij | 15:baa2672a9b38 | 427 | break; // Break from switch |
legwinskij | 15:baa2672a9b38 | 428 | } |
jkaderka | 0:16fd37cf4a7c | 429 | } |
jkaderka | 0:16fd37cf4a7c | 430 | } |
jkaderka | 0:16fd37cf4a7c | 431 | } |