This is some program for air quality monitoring device. Its capabilities span quite a broad range: -read sensor (selection of 2 kinds - both worthless actually) -store measurements on SD card (nice formatting included ®) -display current measurement on LCD -sleep between measurement (but on my Nucleo platform power draw was still unacceptably high) -change measurement interval with on-board keys
Dependencies: DS1307 DS1820 DSM501 GP2Y1010AU0F I2CEeprom SDFileSystem TextLCD_YWROBOT WakeUp keypad_ADC mbed
The device has no upload capabilities. It logs data onto local SD card if one is present. It displays current measurement nevertheless.
I used some libraries: some purpose-made, rest forked public libraries. main.cpp file contains the program. First it initializes modules (EEPROM, RTC, thermometer, dust sensor, LCD, SDcard), then enters endless loop of following sequence:
- take a measurement
- display measurement and save it to the SD card
- enter sleep for *sleep* period
- repeat
main.cpp@0:41f9e684d87e, 2018-01-31 (annotated)
- Committer:
- amateusz
- Date:
- Wed Jan 31 12:13:30 2018 +0000
- Revision:
- 0:41f9e684d87e
last working version the program.; RTC broke before deployment, so it is non functional in program
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
amateusz | 0:41f9e684d87e | 1 | #include "mbed.h" |
amateusz | 0:41f9e684d87e | 2 | //#include <errno.h> |
amateusz | 0:41f9e684d87e | 3 | //#include <stdio.h> |
amateusz | 0:41f9e684d87e | 4 | #include "SDFileSystem.h" // sd card |
amateusz | 0:41f9e684d87e | 5 | #include "I2CEeprom.h" // eeprom present on the tinyRTC module |
amateusz | 0:41f9e684d87e | 6 | #include "DS1307.h" |
amateusz | 0:41f9e684d87e | 7 | #include "DS1820.h" // thermometer present on the tinyRTC module |
amateusz | 0:41f9e684d87e | 8 | #include "TextLCD.h" // D1 robot LCD & keypad shield |
amateusz | 0:41f9e684d87e | 9 | #include <string> |
amateusz | 0:41f9e684d87e | 10 | #include <iomanip> // setprecision |
amateusz | 0:41f9e684d87e | 11 | #include <sstream> // stringstream |
amateusz | 0:41f9e684d87e | 12 | #include <algorithm> // replace |
amateusz | 0:41f9e684d87e | 13 | //#include "DSM501.cpp" // dust sensor |
amateusz | 0:41f9e684d87e | 14 | #include "GP2Y1010AU0F.cpp" |
amateusz | 0:41f9e684d87e | 15 | #include "keypad_ADC.cpp" // keys on the shield |
amateusz | 0:41f9e684d87e | 16 | #include "WakeUp.h" |
amateusz | 0:41f9e684d87e | 17 | |
amateusz | 0:41f9e684d87e | 18 | LowPowerTimeout oneSecondTimeout; |
amateusz | 0:41f9e684d87e | 19 | bool oneSecondTimeoutExpired = false; |
amateusz | 0:41f9e684d87e | 20 | |
amateusz | 0:41f9e684d87e | 21 | DS1820 thermometer(PC_9); // rom: wlutowany w płytkę z RTC 0x28ff2b0586160356 |
amateusz | 0:41f9e684d87e | 22 | Serial pc(USBTX, USBRX, 57600); // tx, rx for debug and usb pc comunications |
amateusz | 0:41f9e684d87e | 23 | I2C i2c(PB_9, PB_8); |
amateusz | 0:41f9e684d87e | 24 | I2CEeprom eeprom(&i2c, 0xA0, 1, 4096); // memory map: 0 - interval is [s] for measurement, 1 - file number. auto incremented, 2 - same file (0) or new everytime (1), 9 - measureTime upper byte |
amateusz | 0:41f9e684d87e | 25 | //DS1307 rtc(&i2c); // start DS1307 class and give it pins for connections of the DS1307 device |
amateusz | 0:41f9e684d87e | 26 | TextLCD lcd(D8, D9, D4, D5, D6, D7, TextLCD::LCD16x2, D10); |
amateusz | 0:41f9e684d87e | 27 | SDFileSystem sd(PC_12, PC_11, PC_10, PD_2, "sd", NC, SDFileSystem::SWITCH_NONE, 5000000); |
amateusz | 0:41f9e684d87e | 28 | //DSM501 dust(PC_1, PC_0); // vout2, vout1 | blue , yellow od góry |
amateusz | 0:41f9e684d87e | 29 | GP2Y1010AU0F dust(A1, PA_4); |
amateusz | 0:41f9e684d87e | 30 | DigitalOut led(LED1); |
amateusz | 0:41f9e684d87e | 31 | keypad_ADC keys(A0); |
amateusz | 0:41f9e684d87e | 32 | DigitalIn button(USER_BUTTON, PullUp); |
amateusz | 0:41f9e684d87e | 33 | LowPowerTimeout lcdBacklightTimeout; |
amateusz | 0:41f9e684d87e | 34 | |
amateusz | 0:41f9e684d87e | 35 | int lcd_mount(int passthrough) |
amateusz | 0:41f9e684d87e | 36 | { |
amateusz | 0:41f9e684d87e | 37 | if (passthrough == 0) { |
amateusz | 0:41f9e684d87e | 38 | lcd.locate(14,0); |
amateusz | 0:41f9e684d87e | 39 | lcd.putc(7); |
amateusz | 0:41f9e684d87e | 40 | led = 1; |
amateusz | 0:41f9e684d87e | 41 | } |
amateusz | 0:41f9e684d87e | 42 | return passthrough; |
amateusz | 0:41f9e684d87e | 43 | } |
amateusz | 0:41f9e684d87e | 44 | |
amateusz | 0:41f9e684d87e | 45 | int lcd_unmount(int passthrough) |
amateusz | 0:41f9e684d87e | 46 | { |
amateusz | 0:41f9e684d87e | 47 | if (passthrough == 0) { |
amateusz | 0:41f9e684d87e | 48 | lcd.locate(14,0); |
amateusz | 0:41f9e684d87e | 49 | lcd.putc(' '); |
amateusz | 0:41f9e684d87e | 50 | led = 0; |
amateusz | 0:41f9e684d87e | 51 | } |
amateusz | 0:41f9e684d87e | 52 | return passthrough; |
amateusz | 0:41f9e684d87e | 53 | } |
amateusz | 0:41f9e684d87e | 54 | |
amateusz | 0:41f9e684d87e | 55 | void lcdBacklightOff() |
amateusz | 0:41f9e684d87e | 56 | { |
amateusz | 0:41f9e684d87e | 57 | lcd.setBacklight(TextLCD::LightOff); |
amateusz | 0:41f9e684d87e | 58 | } |
amateusz | 0:41f9e684d87e | 59 | void lcdBacklightOn() |
amateusz | 0:41f9e684d87e | 60 | { |
amateusz | 0:41f9e684d87e | 61 | lcd.setBacklight(TextLCD::LightOn); |
amateusz | 0:41f9e684d87e | 62 | } |
amateusz | 0:41f9e684d87e | 63 | string floatToString(float value, bool dotToComma, char precision = 2) |
amateusz | 0:41f9e684d87e | 64 | { |
amateusz | 0:41f9e684d87e | 65 | // nice temperature foramting |
amateusz | 0:41f9e684d87e | 66 | std::ostringstream temperature_str_dot; |
amateusz | 0:41f9e684d87e | 67 | temperature_str_dot << fixed << setprecision(precision) << value;//thermometer.temperature(); |
amateusz | 0:41f9e684d87e | 68 | std::string temperature_str_comma(temperature_str_dot.str()); |
amateusz | 0:41f9e684d87e | 69 | if (dotToComma) std::replace( temperature_str_comma.begin(), temperature_str_comma.end(), '.', ','); // replace all 'x' to 'y' |
amateusz | 0:41f9e684d87e | 70 | return temperature_str_comma; |
amateusz | 0:41f9e684d87e | 71 | // end of temperature |
amateusz | 0:41f9e684d87e | 72 | } |
amateusz | 0:41f9e684d87e | 73 | string intToString(int value, int fillWithZeros = 0) |
amateusz | 0:41f9e684d87e | 74 | { |
amateusz | 0:41f9e684d87e | 75 | std::ostringstream ss; |
amateusz | 0:41f9e684d87e | 76 | if (fillWithZeros > 0) ss << setfill('0') << setw(fillWithZeros); |
amateusz | 0:41f9e684d87e | 77 | ss << value; |
amateusz | 0:41f9e684d87e | 78 | return ss.str(); |
amateusz | 0:41f9e684d87e | 79 | } |
amateusz | 0:41f9e684d87e | 80 | bool write_with_progress_bar(FileHandle* file, const void * buffer, size_t len, void (*everytick)(char) = NULL) |
amateusz | 0:41f9e684d87e | 81 | { |
amateusz | 0:41f9e684d87e | 82 | char parts=4; |
amateusz | 0:41f9e684d87e | 83 | char * write_buffer = new char[len]; |
amateusz | 0:41f9e684d87e | 84 | for (unsigned int i = 0; i < len; i++) |
amateusz | 0:41f9e684d87e | 85 | write_buffer[i] = ((char*)buffer)[i]; |
amateusz | 0:41f9e684d87e | 86 | const size_t chunk_at_once = len/parts; |
amateusz | 0:41f9e684d87e | 87 | unsigned int data_written = 0; |
amateusz | 0:41f9e684d87e | 88 | char counter = 0; |
amateusz | 0:41f9e684d87e | 89 | while (data_written < len) { |
amateusz | 0:41f9e684d87e | 90 | data_written += file->write(write_buffer + data_written, min(len-data_written, chunk_at_once)); |
amateusz | 0:41f9e684d87e | 91 | // pc.printf("count: %d", counter); |
amateusz | 0:41f9e684d87e | 92 | if (everytick != NULL) |
amateusz | 0:41f9e684d87e | 93 | (*everytick)(counter++); |
amateusz | 0:41f9e684d87e | 94 | } |
amateusz | 0:41f9e684d87e | 95 | delete write_buffer; |
amateusz | 0:41f9e684d87e | 96 | if (everytick != NULL) |
amateusz | 0:41f9e684d87e | 97 | (*everytick)(0); // success, zero it |
amateusz | 0:41f9e684d87e | 98 | return true; |
amateusz | 0:41f9e684d87e | 99 | } |
amateusz | 0:41f9e684d87e | 100 | |
amateusz | 0:41f9e684d87e | 101 | void showProgress(char value) |
amateusz | 0:41f9e684d87e | 102 | { |
amateusz | 0:41f9e684d87e | 103 | char posX = 15, posY = 0; |
amateusz | 0:41f9e684d87e | 104 | lcd.locate(posX, posY); |
amateusz | 0:41f9e684d87e | 105 | char charToPut = ' '; |
amateusz | 0:41f9e684d87e | 106 | if (value > 0) { |
amateusz | 0:41f9e684d87e | 107 | charToPut = value-1 > 3 ? 3 : value -1; |
amateusz | 0:41f9e684d87e | 108 | // if (value >= 8) |
amateusz | 0:41f9e684d87e | 109 | // charToPut = 0xFF; |
amateusz | 0:41f9e684d87e | 110 | } |
amateusz | 0:41f9e684d87e | 111 | lcd.putc(charToPut); |
amateusz | 0:41f9e684d87e | 112 | wait(.015); |
amateusz | 0:41f9e684d87e | 113 | } |
amateusz | 0:41f9e684d87e | 114 | void sdInit() |
amateusz | 0:41f9e684d87e | 115 | { |
amateusz | 0:41f9e684d87e | 116 | sd.crc(true); |
amateusz | 0:41f9e684d87e | 117 | // sd.large_frames(true); |
amateusz | 0:41f9e684d87e | 118 | sd.write_validation(false); |
amateusz | 0:41f9e684d87e | 119 | } |
amateusz | 0:41f9e684d87e | 120 | |
amateusz | 0:41f9e684d87e | 121 | void thermometerInit() |
amateusz | 0:41f9e684d87e | 122 | { |
amateusz | 0:41f9e684d87e | 123 | thermometer.search_ROM_setup(); |
amateusz | 0:41f9e684d87e | 124 | thermometer.search_ROM(); |
amateusz | 0:41f9e684d87e | 125 | thermometer.set_configuration_bits(12); |
amateusz | 0:41f9e684d87e | 126 | } |
amateusz | 0:41f9e684d87e | 127 | void lcdInit() |
amateusz | 0:41f9e684d87e | 128 | { |
amateusz | 0:41f9e684d87e | 129 | lcd.setCursor(TextLCD::CurOff_BlkOff); |
amateusz | 0:41f9e684d87e | 130 | lcd.cls(); |
amateusz | 0:41f9e684d87e | 131 | lcd.setBacklight(TextLCD::LightOn); |
amateusz | 0:41f9e684d87e | 132 | char progress[][8] = { |
amateusz | 0:41f9e684d87e | 133 | {0x0, 0x0,0x0,0x0,0x0,0x0,0x0,0x7}, |
amateusz | 0:41f9e684d87e | 134 | {0x0, 0x0,0x0,0x0,0x0,0x7,0x7,0x7}, |
amateusz | 0:41f9e684d87e | 135 | {0x0, 0x0,0x0,0x7,0x7,0x7,0x7,0x7}, |
amateusz | 0:41f9e684d87e | 136 | {0x0, 0x7,0x7,0x7,0x7,0x7,0x7,0x7} |
amateusz | 0:41f9e684d87e | 137 | }; |
amateusz | 0:41f9e684d87e | 138 | for (unsigned int i=0; i <4; i++) |
amateusz | 0:41f9e684d87e | 139 | lcd.setUDC(i, (char *) progress[i] ); |
amateusz | 0:41f9e684d87e | 140 | |
amateusz | 0:41f9e684d87e | 141 | char microSign[] = { 0b01001, 0b01001, 0b01001, 0b01110, 0b01000, 0b01000, 0b00000, 0b00000}; |
amateusz | 0:41f9e684d87e | 142 | lcd.setUDC(4, (char*) microSign); |
amateusz | 0:41f9e684d87e | 143 | char gChar[] = { 0b01111, 0b10001, 0b10001, 0b01111, 0b00001, 0b01110, 0b00000, 0b00000}; |
amateusz | 0:41f9e684d87e | 144 | lcd.setUDC(5, (char*) gChar); |
amateusz | 0:41f9e684d87e | 145 | char m_pow_3[] = { 0b11000, 0b00100, 0b11000, 0b00100, 0b11000, 0b00000, 0b00000, 0b00000}; |
amateusz | 0:41f9e684d87e | 146 | lcd.setUDC(6, (char*) m_pow_3); |
amateusz | 0:41f9e684d87e | 147 | char microSD[] = {0x1c,0x1c,0x1e,0x1c,0x1e,0x1f,0x1f}; |
amateusz | 0:41f9e684d87e | 148 | lcd.setUDC(7, (char*) microSD); |
amateusz | 0:41f9e684d87e | 149 | } |
amateusz | 0:41f9e684d87e | 150 | //#define USR_POWERDOWN (0x104) |
amateusz | 0:41f9e684d87e | 151 | //int semihost_powerdown() |
amateusz | 0:41f9e684d87e | 152 | //{ |
amateusz | 0:41f9e684d87e | 153 | // uint32_t arg; |
amateusz | 0:41f9e684d87e | 154 | // return __semihost(USR_POWERDOWN, &arg); |
amateusz | 0:41f9e684d87e | 155 | //} |
amateusz | 0:41f9e684d87e | 156 | void oneSecondTimeoutCallback(void) |
amateusz | 0:41f9e684d87e | 157 | { |
amateusz | 0:41f9e684d87e | 158 | oneSecondTimeoutExpired = true; |
amateusz | 0:41f9e684d87e | 159 | } |
amateusz | 0:41f9e684d87e | 160 | |
amateusz | 0:41f9e684d87e | 161 | int main() |
amateusz | 0:41f9e684d87e | 162 | { |
amateusz | 0:41f9e684d87e | 163 | // semihost_powerdown(); |
amateusz | 0:41f9e684d87e | 164 | sdInit(); |
amateusz | 0:41f9e684d87e | 165 | thermometerInit(); |
amateusz | 0:41f9e684d87e | 166 | lcdInit(); |
amateusz | 0:41f9e684d87e | 167 | // eeprom.write(1, 0); // zero index couter |
amateusz | 0:41f9e684d87e | 168 | unsigned short measureTime; |
amateusz | 0:41f9e684d87e | 169 | char temp; |
amateusz | 0:41f9e684d87e | 170 | eeprom.read(0, temp); |
amateusz | 0:41f9e684d87e | 171 | eeprom.read(9, measureTime); |
amateusz | 0:41f9e684d87e | 172 | measureTime <<= 8; |
amateusz | 0:41f9e684d87e | 173 | measureTime |= temp; |
amateusz | 0:41f9e684d87e | 174 | if (measureTime < 1) measureTime = 1; |
amateusz | 0:41f9e684d87e | 175 | // |
amateusz | 0:41f9e684d87e | 176 | // DS1307::Time_rtc time_now; |
amateusz | 0:41f9e684d87e | 177 | // rtc.getTime(time_now); |
amateusz | 0:41f9e684d87e | 178 | lcd.locate(4,1); |
amateusz | 0:41f9e684d87e | 179 | //if (time_now.hour <= 9) |
amateusz | 0:41f9e684d87e | 180 | // lcd.printf(" "); |
amateusz | 0:41f9e684d87e | 181 | // else lcd.printf("%.1D", (time_now.hour/10)); |
amateusz | 0:41f9e684d87e | 182 | // lcd.printf("%.1D:%.2D:%.2D", time_now.hour%10, time_now.min, time_now.sec); |
amateusz | 0:41f9e684d87e | 183 | lcd.printf("RTC FAIL!"); |
amateusz | 0:41f9e684d87e | 184 | wait(1.0); |
amateusz | 0:41f9e684d87e | 185 | // |
amateusz | 0:41f9e684d87e | 186 | lcd.locate(0,0); |
amateusz | 0:41f9e684d87e | 187 | lcd.printf("karta: "); |
amateusz | 0:41f9e684d87e | 188 | wait(.7); |
amateusz | 0:41f9e684d87e | 189 | if (lcd_mount(sd.mount()) == 0) { //Perform a write test |
amateusz | 0:41f9e684d87e | 190 | pc.printf("Capacity: %.1fMB\r\n", sd.disk_sectors() / 2048.0); |
amateusz | 0:41f9e684d87e | 191 | lcd.locate(6,0); |
amateusz | 0:41f9e684d87e | 192 | lcd.printf("%5dMB",sd.disk_sectors() / 2048); |
amateusz | 0:41f9e684d87e | 193 | wait(.3); |
amateusz | 0:41f9e684d87e | 194 | lcd_unmount(sd.unmount()); |
amateusz | 0:41f9e684d87e | 195 | } else lcd.printf("!klops!"); |
amateusz | 0:41f9e684d87e | 196 | wait(1.2); |
amateusz | 0:41f9e684d87e | 197 | lcdBacklightTimeout.attach(&lcdBacklightOff, 2.0f); |
amateusz | 0:41f9e684d87e | 198 | lcd.cls(); |
amateusz | 0:41f9e684d87e | 199 | // pc.printf("hello!\r\npress button to start\r\n"); |
amateusz | 0:41f9e684d87e | 200 | // lcd.printf("gotowy. nacisnij"); |
amateusz | 0:41f9e684d87e | 201 | char index; |
amateusz | 0:41f9e684d87e | 202 | wait(.1); |
amateusz | 0:41f9e684d87e | 203 | if (eeprom.read(1, index) != 0) { |
amateusz | 0:41f9e684d87e | 204 | eeprom.write(1, index+1); |
amateusz | 0:41f9e684d87e | 205 | } |
amateusz | 0:41f9e684d87e | 206 | else index = 254; |
amateusz | 0:41f9e684d87e | 207 | std::string filename = intToString(index, 4); |
amateusz | 0:41f9e684d87e | 208 | filename = filename.substr(1,3); |
amateusz | 0:41f9e684d87e | 209 | filename += ".txt"; |
amateusz | 0:41f9e684d87e | 210 | filename = "pomiary.txt"; |
amateusz | 0:41f9e684d87e | 211 | |
amateusz | 0:41f9e684d87e | 212 | while(true) { |
amateusz | 0:41f9e684d87e | 213 | // while(button); |
amateusz | 0:41f9e684d87e | 214 | // rtc.setLocalTime(); // RTC fail |
amateusz | 0:41f9e684d87e | 215 | time_t current = time(NULL); |
amateusz | 0:41f9e684d87e | 216 | printf("Time as a basic string = %s\r\n", ctime(¤t)); |
amateusz | 0:41f9e684d87e | 217 | // measure dust level |
amateusz | 0:41f9e684d87e | 218 | // dust.measure(measureTime); |
amateusz | 0:41f9e684d87e | 219 | unsigned int pm1, pm2_5 = 0; |
amateusz | 0:41f9e684d87e | 220 | unsigned long epoch_now = time(NULL); |
amateusz | 0:41f9e684d87e | 221 | thermometer.convert_temperature(false); |
amateusz | 0:41f9e684d87e | 222 | // while(!dust.getMeasurement(pm1, pm2_5)) { |
amateusz | 0:41f9e684d87e | 223 | |
amateusz | 0:41f9e684d87e | 224 | while( (signed short) (measureTime - (time(NULL) - epoch_now)) > 0) { |
amateusz | 0:41f9e684d87e | 225 | |
amateusz | 0:41f9e684d87e | 226 | oneSecondTimeoutExpired = false; |
amateusz | 0:41f9e684d87e | 227 | oneSecondTimeout.attach(oneSecondTimeoutCallback, 1.0f); |
amateusz | 0:41f9e684d87e | 228 | //Ensure that we only continue the program flow here after the timeout expired. |
amateusz | 0:41f9e684d87e | 229 | lcd.locate(15,0); |
amateusz | 0:41f9e684d87e | 230 | lcd.printf("S"); |
amateusz | 0:41f9e684d87e | 231 | while(!oneSecondTimeoutExpired) sleep(); |
amateusz | 0:41f9e684d87e | 232 | lcd.locate(15,0); |
amateusz | 0:41f9e684d87e | 233 | lcd.printf(" "); |
amateusz | 0:41f9e684d87e | 234 | // WakeUp::set_ms(2000); |
amateusz | 0:41f9e684d87e | 235 | // lcd.locate(15,0); |
amateusz | 0:41f9e684d87e | 236 | // lcd.printf("S"); |
amateusz | 0:41f9e684d87e | 237 | //Enter deepsleep, the program won't go beyond this point until it is woken up |
amateusz | 0:41f9e684d87e | 238 | // deepsleep(); |
amateusz | 0:41f9e684d87e | 239 | // lcd.locate(15,0); |
amateusz | 0:41f9e684d87e | 240 | // lcd.printf(" "); |
amateusz | 0:41f9e684d87e | 241 | |
amateusz | 0:41f9e684d87e | 242 | keypad_ADC::keys keyPress = keys.read(); // read |
amateusz | 0:41f9e684d87e | 243 | if (keyPress != keypad_ADC::none) { |
amateusz | 0:41f9e684d87e | 244 | lcdBacklightOn(); |
amateusz | 0:41f9e684d87e | 245 | // printf("key: %d\r\n", keyPress); |
amateusz | 0:41f9e684d87e | 246 | if (keyPress == keypad_ADC::right) { |
amateusz | 0:41f9e684d87e | 247 | // edit measureTime |
amateusz | 0:41f9e684d87e | 248 | lcd.cls(); |
amateusz | 0:41f9e684d87e | 249 | lcd.locate(8,0); |
amateusz | 0:41f9e684d87e | 250 | lcd.printf("%5d?", measureTime); |
amateusz | 0:41f9e684d87e | 251 | while (keys.read() != keypad_ADC::none); |
amateusz | 0:41f9e684d87e | 252 | keyPress = keys.read(); |
amateusz | 0:41f9e684d87e | 253 | bool minutesNotSeconds = false; |
amateusz | 0:41f9e684d87e | 254 | while (keyPress != keypad_ADC::right) { |
amateusz | 0:41f9e684d87e | 255 | lcdBacklightOn(); |
amateusz | 0:41f9e684d87e | 256 | printf("key: %d\r\n", keyPress); |
amateusz | 0:41f9e684d87e | 257 | switch (keyPress) { |
amateusz | 0:41f9e684d87e | 258 | case keypad_ADC::left: |
amateusz | 0:41f9e684d87e | 259 | minutesNotSeconds = ! minutesNotSeconds; |
amateusz | 0:41f9e684d87e | 260 | if(minutesNotSeconds) measureTime /= 60; |
amateusz | 0:41f9e684d87e | 261 | else measureTime *= 60; |
amateusz | 0:41f9e684d87e | 262 | lcd.locate(8,0); |
amateusz | 0:41f9e684d87e | 263 | lcd.printf("%5d", measureTime); |
amateusz | 0:41f9e684d87e | 264 | lcd.locate(10,1); |
amateusz | 0:41f9e684d87e | 265 | lcd.printf("%s", (minutesNotSeconds)?"min":"sek"); |
amateusz | 0:41f9e684d87e | 266 | while (keys.read() != keypad_ADC::none); |
amateusz | 0:41f9e684d87e | 267 | break; |
amateusz | 0:41f9e684d87e | 268 | case keypad_ADC::up: |
amateusz | 0:41f9e684d87e | 269 | measureTime++; |
amateusz | 0:41f9e684d87e | 270 | if(minutesNotSeconds && measureTime > 1091) measureTime = 0; |
amateusz | 0:41f9e684d87e | 271 | lcd.cls(); |
amateusz | 0:41f9e684d87e | 272 | lcd.locate(8,0); |
amateusz | 0:41f9e684d87e | 273 | lcd.printf("%5d", measureTime); |
amateusz | 0:41f9e684d87e | 274 | lcd.locate(10,1); |
amateusz | 0:41f9e684d87e | 275 | lcd.printf("%s", (minutesNotSeconds)?"min":"sek"); |
amateusz | 0:41f9e684d87e | 276 | while (keys.read() != keypad_ADC::none); |
amateusz | 0:41f9e684d87e | 277 | break; |
amateusz | 0:41f9e684d87e | 278 | case keypad_ADC::down: |
amateusz | 0:41f9e684d87e | 279 | measureTime--; |
amateusz | 0:41f9e684d87e | 280 | if(minutesNotSeconds && measureTime > 1091) measureTime = 1091; |
amateusz | 0:41f9e684d87e | 281 | lcd.cls(); |
amateusz | 0:41f9e684d87e | 282 | lcd.locate(8,0); |
amateusz | 0:41f9e684d87e | 283 | lcd.printf("%5d", measureTime); |
amateusz | 0:41f9e684d87e | 284 | lcd.locate(10,1); |
amateusz | 0:41f9e684d87e | 285 | lcd.printf("%s", (minutesNotSeconds)?"min":"sek"); |
amateusz | 0:41f9e684d87e | 286 | while (keys.read() != keypad_ADC::none); |
amateusz | 0:41f9e684d87e | 287 | break; |
amateusz | 0:41f9e684d87e | 288 | default: |
amateusz | 0:41f9e684d87e | 289 | break; |
amateusz | 0:41f9e684d87e | 290 | } |
amateusz | 0:41f9e684d87e | 291 | keyPress = keys.read(); |
amateusz | 0:41f9e684d87e | 292 | } |
amateusz | 0:41f9e684d87e | 293 | if (minutesNotSeconds) measureTime *= 60; |
amateusz | 0:41f9e684d87e | 294 | lcd.locate(13,0); |
amateusz | 0:41f9e684d87e | 295 | lcd.printf(" "); |
amateusz | 0:41f9e684d87e | 296 | eeprom.write(0, measureTime & 0xFF); |
amateusz | 0:41f9e684d87e | 297 | eeprom.write(9, measureTime >> 8); |
amateusz | 0:41f9e684d87e | 298 | epoch_now = time(NULL); |
amateusz | 0:41f9e684d87e | 299 | // dust.measure(measureTime); |
amateusz | 0:41f9e684d87e | 300 | } |
amateusz | 0:41f9e684d87e | 301 | while (keys.read() != keypad_ADC::none); |
amateusz | 0:41f9e684d87e | 302 | lcdBacklightTimeout.attach(&lcdBacklightOff, 2.4); |
amateusz | 0:41f9e684d87e | 303 | } |
amateusz | 0:41f9e684d87e | 304 | // display counter |
amateusz | 0:41f9e684d87e | 305 | lcd.locate(8,0); |
amateusz | 0:41f9e684d87e | 306 | lcd.printf("%5d", measureTime - (time(NULL) - epoch_now)); |
amateusz | 0:41f9e684d87e | 307 | // print temperature |
amateusz | 0:41f9e684d87e | 308 | lcd.locate(10,1);// |
amateusz | 0:41f9e684d87e | 309 | lcd.printf("%s", floatToString(thermometer.temperature(), true).substr(0,4).c_str()); |
amateusz | 0:41f9e684d87e | 310 | lcd.putc(223); // degree sign |
amateusz | 0:41f9e684d87e | 311 | lcd.putc('C'); |
amateusz | 0:41f9e684d87e | 312 | } |
amateusz | 0:41f9e684d87e | 313 | lcd.locate(11,0); |
amateusz | 0:41f9e684d87e | 314 | lcd.printf(" "); |
amateusz | 0:41f9e684d87e | 315 | |
amateusz | 0:41f9e684d87e | 316 | double result; |
amateusz | 0:41f9e684d87e | 317 | const unsigned short resultCounter = 100; |
amateusz | 0:41f9e684d87e | 318 | unsigned short counterAll = 0; |
amateusz | 0:41f9e684d87e | 319 | unsigned short counterValid = 0; |
amateusz | 0:41f9e684d87e | 320 | double sum = 0; |
amateusz | 0:41f9e684d87e | 321 | |
amateusz | 0:41f9e684d87e | 322 | while (counterAll++ < resultCounter) { |
amateusz | 0:41f9e684d87e | 323 | dust.measure(); |
amateusz | 0:41f9e684d87e | 324 | float resultInterm; |
amateusz | 0:41f9e684d87e | 325 | while(!dust.getVoltage(resultInterm)) |
amateusz | 0:41f9e684d87e | 326 | pc.printf("%d\r", counterAll); |
amateusz | 0:41f9e684d87e | 327 | if (dust.convertVoltageToMg(resultInterm) > 0) { |
amateusz | 0:41f9e684d87e | 328 | sum += resultInterm; |
amateusz | 0:41f9e684d87e | 329 | counterValid++; |
amateusz | 0:41f9e684d87e | 330 | } |
amateusz | 0:41f9e684d87e | 331 | dust.tryTosetAoutAtNoDust(resultInterm); |
amateusz | 0:41f9e684d87e | 332 | lcd.locate( ((counterAll/48)%2)?1:0 ,0); |
amateusz | 0:41f9e684d87e | 333 | lcd.printf(" <pomiar> ", result); |
amateusz | 0:41f9e684d87e | 334 | } |
amateusz | 0:41f9e684d87e | 335 | pc.printf("%d/%d\r\n", counterAll, counterValid); |
amateusz | 0:41f9e684d87e | 336 | result = sum/counterValid; |
amateusz | 0:41f9e684d87e | 337 | result = dust.convertVoltageToMg(result); |
amateusz | 0:41f9e684d87e | 338 | lcd.cls(); |
amateusz | 0:41f9e684d87e | 339 | lcd.locate(0,0); |
amateusz | 0:41f9e684d87e | 340 | lcd.printf("%s\n \x04\x05/m\x06", floatToString(result, true, 3)); |
amateusz | 0:41f9e684d87e | 341 | // lcd.printf("pm1: %2d%%", pm1); |
amateusz | 0:41f9e684d87e | 342 | // lcd.locate(0,1); |
amateusz | 0:41f9e684d87e | 343 | // lcd.printf("pm2,5:%2d%%", pm2_5); |
amateusz | 0:41f9e684d87e | 344 | |
amateusz | 0:41f9e684d87e | 345 | //Mount the filesystem |
amateusz | 0:41f9e684d87e | 346 | if (lcd_mount(sd.mount()) == 0) { //Perform a write test |
amateusz | 0:41f9e684d87e | 347 | printf("\r\nWriting to SD card..."); |
amateusz | 0:41f9e684d87e | 348 | // get global index from eeprom |
amateusz | 0:41f9e684d87e | 349 | FileHandle* file = sd.open(filename.c_str(), O_WRONLY | O_CREAT ); // | O_TRUNC |
amateusz | 0:41f9e684d87e | 350 | if (file != NULL) { // write |
amateusz | 0:41f9e684d87e | 351 | std::string toWrite = ctime(¤t); |
amateusz | 0:41f9e684d87e | 352 | toWrite = toWrite.substr(0, toWrite.size()-1); // cut last char of ctime, because it is \r |
amateusz | 0:41f9e684d87e | 353 | // toWrite += ", pm1:, "; |
amateusz | 0:41f9e684d87e | 354 | // toWrite += intToString(pm1).c_str(); |
amateusz | 0:41f9e684d87e | 355 | // toWrite += ", pm2.5:, "; |
amateusz | 0:41f9e684d87e | 356 | // toWrite += intToString(pm2_5).c_str(); |
amateusz | 0:41f9e684d87e | 357 | toWrite += ", "; |
amateusz | 0:41f9e684d87e | 358 | toWrite += floatToString(result, false, 4); |
amateusz | 0:41f9e684d87e | 359 | toWrite += ", "; |
amateusz | 0:41f9e684d87e | 360 | toWrite += floatToString(dust.getAoutAtNoDust(), false, 5); |
amateusz | 0:41f9e684d87e | 361 | toWrite += ", "; |
amateusz | 0:41f9e684d87e | 362 | toWrite += floatToString(thermometer.temperature(), false, 3); |
amateusz | 0:41f9e684d87e | 363 | toWrite += ", C, "; |
amateusz | 0:41f9e684d87e | 364 | toWrite += intToString(measureTime); |
amateusz | 0:41f9e684d87e | 365 | toWrite += ", "; |
amateusz | 0:41f9e684d87e | 366 | toWrite += intToString(index); |
amateusz | 0:41f9e684d87e | 367 | toWrite += "\r\n"; |
amateusz | 0:41f9e684d87e | 368 | // pc.printf("tell: %d\tsize: %d\r\n", file->tell(), file->size()); |
amateusz | 0:41f9e684d87e | 369 | pc.printf("Writing to file \"%s\": %s\r\n", filename.c_str(), toWrite.c_str()); |
amateusz | 0:41f9e684d87e | 370 | file->seek(0, SEEK_END); |
amateusz | 0:41f9e684d87e | 371 | write_with_progress_bar(file, toWrite.c_str(), toWrite.length(), showProgress); |
amateusz | 0:41f9e684d87e | 372 | // file->write(toWrite.c_str(), toWrite.length()); // strlen(toWrite) |
amateusz | 0:41f9e684d87e | 373 | file->close(); |
amateusz | 0:41f9e684d87e | 374 | printf("success writing!\r\n"); |
amateusz | 0:41f9e684d87e | 375 | } else { |
amateusz | 0:41f9e684d87e | 376 | printf("failed to write!\r\n"); |
amateusz | 0:41f9e684d87e | 377 | } |
amateusz | 0:41f9e684d87e | 378 | //Unmount the filesystem |
amateusz | 0:41f9e684d87e | 379 | lcd_unmount(sd.unmount()); |
amateusz | 0:41f9e684d87e | 380 | |
amateusz | 0:41f9e684d87e | 381 | pc.printf("all done.\r\n"); |
amateusz | 0:41f9e684d87e | 382 | } else { // unable to mount |
amateusz | 0:41f9e684d87e | 383 | lcd.locate(0,0); |
amateusz | 0:41f9e684d87e | 384 | lcd.printf("brak karty!"); |
amateusz | 0:41f9e684d87e | 385 | pc.printf("unable to mount! what a failure!\r\n"); |
amateusz | 0:41f9e684d87e | 386 | } |
amateusz | 0:41f9e684d87e | 387 | } |
amateusz | 0:41f9e684d87e | 388 | } |