void init_speedo(void) { Millis.init(); Serial.init(USART1, 115200L); Serial.init(USART2, 115200L); Serial.init(USART3, 115200L); Serial.puts_ln(USART1, "=== Speedoino ==="); Serial.puts(USART1, GIT_REV); // print Software release Serial.puts(USART1, " HW:"); Serial.puts_ln(USART1, Config.get_hw_version()); // print Hardware release // first, set all variables to a zero value Sensors.init(); Speedo.clear_vars(); // refresh cycle // read configuration file from sd card SD.init(); // try open SD Card SD.open(); Config.read(CONFIG_FOLDER, "BASE.TXT", READ_MODE_CONFIGFILE, ""); // load base config Config.read(CONFIG_FOLDER, "SPEEDO.TXT", READ_MODE_CONFIGFILE, ""); // speedovalues, avg,max,time Config.read(CONFIG_FOLDER, "GANG.TXT", READ_MODE_CONFIGFILE, ""); // gang Config.read(CONFIG_FOLDER, "TEMPER.TXT", READ_MODE_CONFIGFILE, ""); // Temperatur Config.read_skin(); // skinning // check if read SD read was okay, if not: load your default backup values Aktors.check_vars(); // check if color of outer LED are OK Sensors.check_vars(); // check if config read was successful Speedo.check_vars(); // rettet das Skinning wenn SD_failed von den sensoren auf true gesetzt wird Sensors.single_read(); // read all sensor values once to ensure we are ready to show them Aktors.init(); // Start outer LEDs // ausschlag des zeigers // Motorausschlag und block bis motor voll ausgeschlagen, solange das letzte intro bild halten TFT.init(); // SD.prefetched_animation(37); // 37 Menu.init(); // Start butons // adds the connection between pins and vars Menu.display(); // execute this AFTER pOLED.init_speedo!! this will show the menu and, if state==11, draws speedosymbols Speedo.reset_bak(); // reset all storages, to force the redraw of the speedo Config.ram_info(); Serial.puts_ln(USART1, "=== Setup finished ==="); }
// main entry point, go ahead, have fun! int main(void) { // hold the power button for 3 seconds or shutdown //_delay_ms(STARTUP_DELAY); // keep power pin High unless we want to shutdown powerControl = 1; // disable JTAG so we can use PF4,PF5,PF6,PF7 for ADC and GPIO MCUCSR |=(1<<JTD);MCUCSR |=(1<<JTD); // two times!! // init time RTC time.init(callback_timeSecond, callback_timeMinute); time.startInterval(); // microcontroller features adc.init(); // needed by gp2y10 and more spi_init(); // needed by ILI9341 i2c_init(); // needed by bmp180 and mics-vz-89t uart1.init(1, 9600, 1); // needed by esp8266 . Interrupts are hard on parsing, polling would be easier but blocking uart0.init(0, 9600, 1); // CONFIGURE INTERRUPT INT4 to count pulses from Geiger Counter EICRB |= (1<<ISC00) | (1<<ISC01); // Configure INT4 to trigger on RISING EDGE EIMSK |= (1<<INT4); // Configure INT4 to fire interrupts // CREATE Timer T1 PWM to drive inverter for regulated Geiger tube voltage inverter.initPWM(); // init display lcd.init(); lcd.setRotation(ILI9341::ROT0); //lcd.drawClear(BLACK); backlight(true); // init sensors bmp180.init(); dust.init(&dustFlash, &adc, PF1); beep(); // start UI // enter main menu // ## touchscreen calibration code /*while (1) { uint16_t x = 0, y = 0, z = 0; if (touch.read(&x, &y , &z)) { lcd.drawPixel(x,y, 2, RED); } lcd.drawStringF(0,0,2,WHITE, BLACK, "%4u %4u %4u", touch.readRawX(), touch.readRawY(), touch.readRawPressure()); }*/ // draw GUI first page with self check if (!gui.drawPage(PAGE_INIT)) shutdown(); _delay_ms(1000); gui.drawPage(PAGE_MAIN); // ## main code loop while (1) { // ## beep if (cmdBeep && !cmdAlarm && !isMuted) { beep(); cmdBeep = false; } // ## read sensors // read inverter voltage, via 10M/47K resistive divider, connected to pin ADC2 data.geiger_voltage = readTubeVoltage(); inverter.adjustDutyCycle(data.geiger_voltage); // do nothing on failure, we can't reset // read battery data.battery_voltage = readBatVoltage(); // turn backlight off when timeout is reached if (secTimeout > BACKLIGHT_TIMEOUT) { backlight(false); secTimeout = 0; } // ## draw titlebar and refresh data display if (cmdRefreshText) { // sensor BMP180 bmp180.readAll(&data.bmp180_temp, &data.bmp180_pressure, &data.bmp180_altitude); dust.readDust(&data.gp2y10_dust); // sensor MICS-VZ-89T uint8_t reactivity = 0; // repeat until successful read with timeout? //int timeout = 10; //while (!vz89.read(&data.vz89_co2, &reactivity, &data.vz89_voc) && timeout) { _delay_ms(1500); timeout--; } vz89.read(&data.vz89_co2, &reactivity, &data.vz89_voc); // geiger readings //float dose = aux_CPM2uSVh((uint8_t)DEV_RAD_DETECTOR, geigerCPM); data.geiger_cpm = geigerCPM; data.time_hour = time.getHour(); data.time_minute = time.getMin(); data.time_second = time.getSec(); data.setLimits(); // must be changed to proper OOP set/get for all fields gui.updateValues(); // ## alarm condition if (geigerCPM >= GEIGER_CPM_ALARM) { // threshold to sound alarm reached cmdAlarm = ALARM_RADIATION; } else if (cmdAlarm) { // alarm should be turned off cmdAlarm = 0; speaker = 0; } cmdRefreshText = false; } // ## every minute we can dispatch data over serial or over WLAN to uradmonitor if (cmdSend) { char tmp[200]; sprintf(tmp,"{\"data\":{ \"id\":\"%08lX\"," "\"type\":\"%X\",\"detector\":\"%s\"," "\"cpm\":%lu,\"temperature\":%.2f,\"uptime\": %lu," "\"pressure\":%lu,\"dust\":%.2f,\"co2\":%.2f,\"voc\":%.2f," "\"battery\":%.2f,\"tube\":%u}}", deviceID, DEV_MODEL, aux_detectorName(DEV_RAD_DETECTOR), geigerCPM, data.bmp180_temp, time.getTotalSec(), data.bmp180_pressure, data.gp2y10_dust,data.vz89_co2, data.vz89_voc, data.battery_voltage, data.geiger_voltage); data.serial_sent += strlen(tmp); uart0.send(tmp); // internet code here sprintf(tmp,"id=%08lX&ts=%ld&inv=%d&ind=%d&s1t=%2.2f&cpm=%ld&voc=%.2f&co2=%.2f", deviceID, time.getTotalSec(), data.geiger_voltage, data.geiger_duty, data.bmp180_temp, geigerCPM, data.vz89_voc, data.vz89_co2); wifi.sendData(tmp); cmdSend = false; } // ## act on the gui elements // read a new touch event only if we are done with previous: useful for handling confirmation "modal" "dialogs" if (uiResult == 0) { uiResult = gui.readTouchEvent(); // reset backlight timeout on valid touch if (uiResult > 0) { secTimeout = 0; backlight(true); // if screen is pressed while alarm is on, stop alarm if (cmdAlarm) { cmdAlarm = false; speaker = 0; } } } // handle special cases: click on wlan AP buttons if (uiResult >= ID_BUTTON_WLAN_START && uiResult < ID_BUTTON_WLAN_STOP) { uint8_t ap_index = uiResult - ID_BUTTON_WLAN_START; // connect and return to main screen wifi.connectWiFi(data.freeAPList[ap_index], ""); uiResult = 0; gui.drawPage(PAGE_MAIN); } // handle regular buttons switch (uiResult) { case ID_BUTTON_SHUTDOWN: { uint16_t result = gui.showYesNoPopup("Are you sure?"); if (result == ID_YES) shutdown(); else if (result == ID_NO) { uiResult = 0; gui.drawPage(PAGE_MAIN); } } break; case ID_BUTTON_MEASURE: { uiResult = 0; gui.drawPage(PAGE_MEASURE); } break; case ID_BUTTON_MONITOR: { uiResult = 0; gui.drawPage(PAGE_MONITOR); } break; case ID_BUTTON_SETTINGS: { uiResult = 0; gui.drawPage(PAGE_SETTINGS); } break; case ID_BUTTON_BACK: { uiResult = 0; gui.drawPage(PAGE_MAIN); } break; case ID_BUTTON_MUTE: { isMuted = !isMuted; if (!isMuted) beep(); // test beep that sound is on uiResult = 0; } break; case ID_BUTTON_CALIBRATE: { uiResult = 0; gui.drawPage(PAGE_CALIBRATE); } break; case ID_BUTTON_WLAN: { // request list of WLAN APs data.freeAPCount = 0; //wifi.setMode(); wifi.listAP(); uiResult = 0; gui.drawPage(PAGE_WLAN); } break; // other commands that don't require a popup so we consume asap default: uiResult = 0; } //uint16_t x, y,z; //gui.getLastTouch(&x, &y, &z); //lcd.drawStringF(0,288, 2, RED, BLACK,"%u %d,%d ", uiResult, x,y); } }