#ifdef BOARD_NODEMCU32S_OBP60 #include #include "SunRise.h" // Lib for sunrise and sunset calculation #include "Pagedata.h" #include "OBP60Hardware.h" #include "OBP60Extensions.h" // Please dont forget to declarate the fonts in OBP60ExtensionPort.h #include "Ubuntu_Bold8pt7b.h" #include "Ubuntu_Bold12pt7b.h" #include "Ubuntu_Bold16pt7b.h" #include "Ubuntu_Bold20pt7b.h" #include "Ubuntu_Bold32pt7b.h" #include "DSEG7Classic-BoldItalic16pt7b.h" #include "DSEG7Classic-BoldItalic20pt7b.h" #include "DSEG7Classic-BoldItalic30pt7b.h" #include "DSEG7Classic-BoldItalic42pt7b.h" #include "DSEG7Classic-BoldItalic60pt7b.h" MCP23017 mcp = MCP23017(MCP23017_I2C_ADDR); // SPI pin definitions for E-Ink display GxIO_Class io(SPI, OBP_SPI_CS, OBP_SPI_DC, OBP_SPI_RST); // SPI, CS, DC, RST GxEPD_Class display(io, OBP_SPI_RST, OBP_SPI_BUSY); // io, RST, BUSY // Global vars int outA = 0; // Outport Byte A int outB = 0; // Outport Byte B bool blinkingLED = false; // Enable / disable blinking flash LED int uvDuration = 0; // Under voltage duration in n x 100ms void MCP23017Init() { mcp.init(); mcp.portMode(MCP23017Port::A, 0b00110000); // Port A, 0 = out, 1 = in mcp.portMode(MCP23017Port::B, 0b11110000); // Port B, 0 = out, 1 = in // Extension Port A set defaults setPortPin(OBP_DIGITAL_OUT1, false); // PA0 setPortPin(OBP_DIGITAL_OUT2, false); // PA1 setPortPin(OBP_FLASH_LED, false); // PA2 setPortPin(OBP_BACKLIGHT_LED, false); // PA3 setPortPin(OBP_POWER_50, true); // PA6 setPortPin(OBP_POWER_33, true); // PA7 // Extension Port B set defaults setPortPin(PB0, false); // PB0 setPortPin(PB1, false); // PB1 setPortPin(PB2, false); // PB2 setPortPin(PB3, false); // PB3 } void setPortPin(uint pin, bool value){ if(pin <=7){ outA &= ~(1 << pin); // Clear bit outA |= (value << pin); // Set bit mcp.writeRegister(MCP23017Register::GPIO_A, outA); } else{ pin = pin - 8; outB &= ~(1 << pin); // Clear bit outB |= (value << pin); // Set bit mcp.writeRegister(MCP23017Register::GPIO_B, outB); } } void togglePortPin(uint pin){ if(pin <=7){ outA ^= (1 << pin); // Set bit mcp.writeRegister(MCP23017Register::GPIO_A, outA); } else{ pin = pin - 8; outB ^= (1 << pin); // Set bit mcp.writeRegister(MCP23017Register::GPIO_B, outB); } } void blinkingFlashLED(){ if(blinkingLED == true){ togglePortPin(OBP_FLASH_LED); } } void setBlinkingLED(bool on){ blinkingLED = on; } uint buzzerpower = 50; void buzzer(uint frequency, uint duration){ if(frequency > 8000){ // Max 8000Hz frequency = 8000; } if(buzzerpower > 100){ // Max 100% buzzerpower = 100; } if(duration > 1000){ // Max 1000ms duration = 1000; } pinMode(OBP_BUZZER, OUTPUT); ledcSetup(0, frequency, 8); // Ch 0, ferquency in Hz, 8 Bit resolution of PWM ledcAttachPin(OBP_BUZZER, 0); ledcWrite(0, uint(buzzerpower * 1.28)); // 50% duty cycle are 100% delay(duration); ledcWrite(0, 0); // 0% duty cycle are 0% } void setBuzzerPower(uint power){ buzzerpower = power; } // Show a triangle for trend direction high (x, y is the left edge) void displayTrendHigh(int16_t x, int16_t y, uint16_t size, uint16_t color){ display.fillTriangle(x, y, x+size*2, y, x+size, y-size*2, color); } // Show a triangle for trend direction low (x, y is the left edge) void displayTrendLow(int16_t x, int16_t y, uint16_t size, uint16_t color){ display.fillTriangle(x, y, x+size*2, y, x+size, y+size*2, color); } // Show header informations void displayHeader(CommonData &commonData, GwApi::BoatValue *date, GwApi::BoatValue *time){ static bool heartbeat = false; static unsigned long usbRxOld = 0; static unsigned long usbTxOld = 0; static unsigned long serRxOld = 0; static unsigned long serTxOld = 0; static unsigned long tcpSerRxOld = 0; static unsigned long tcpSerTxOld = 0; static unsigned long tcpClRxOld = 0; static unsigned long tcpClTxOld = 0; static unsigned long n2kRxOld = 0; static unsigned long n2kTxOld = 0; int textcolor = GxEPD_BLACK; if(commonData.config->getBool(commonData.config->statusLine) == true){ if(commonData.config->getString(commonData.config->displaycolor) == "Normal"){ textcolor = GxEPD_BLACK; } else{ textcolor = GxEPD_WHITE; } // Show status info display.setTextColor(textcolor); display.setFont(&Ubuntu_Bold8pt7b); display.setCursor(0, 15); if(commonData.status.wifiApOn){ display.print(" AP "); } // If receive new telegram data then display bus name if(commonData.status.tcpClRx != tcpClRxOld || commonData.status.tcpClTx != tcpClTxOld || commonData.status.tcpSerRx != tcpSerRxOld || commonData.status.tcpSerTx != tcpSerTxOld){ display.print("TCP "); } if(commonData.status.n2kRx != n2kRxOld || commonData.status.n2kTx != n2kTxOld){ display.print("N2K "); } if(commonData.status.serRx != serRxOld || commonData.status.serTx != serTxOld){ display.print("183 "); } if(commonData.status.usbRx != usbRxOld || commonData.status.usbTx != usbTxOld){ display.print("USB "); } if(commonData.config->getBool(commonData.config->useGPS) == true && date->valid == true){ display.print("GPS"); } // Save old telegram counter tcpClRxOld = commonData.status.tcpClRx; tcpClTxOld = commonData.status.tcpClTx; tcpSerRxOld = commonData.status.tcpSerRx; tcpSerTxOld = commonData.status.tcpSerTx; n2kRxOld = commonData.status.n2kRx; n2kTxOld = commonData.status.n2kTx; serRxOld = commonData.status.serRx; serTxOld = commonData.status.serTx; usbRxOld = commonData.status.usbRx; usbTxOld = commonData.status.usbTx; // Heartbeat as dot display.setTextColor(textcolor); display.setFont(&Ubuntu_Bold32pt7b); display.setCursor(205, 14); if(heartbeat == true){ display.print("."); } else{ display.print(" "); } heartbeat = !heartbeat; // Date and time display.setTextColor(textcolor); display.setFont(&Ubuntu_Bold8pt7b); display.setCursor(230, 15); if(date->valid == true){ String acttime = formatValue(time, commonData).svalue; acttime = acttime.substring(0, 5); String actdate = formatValue(date, commonData).svalue; display.print(acttime); display.print(" "); display.print(actdate); display.print(" "); if(commonData.config->getInt(commonData.config->timeZone) == 0){ display.print("UTC"); } else{ display.print("LOT"); } } else{ display.print("No GPS data"); } } } // Sunset und sunrise calculation SensorData calcSunsetSunrise(double time, double date, double latitude, double longitude, double timezone){ SensorData returnset; SunRise sr; int secPerHour = 3600; int secPerYear = 86400; sr.hasRise = false; sr.hasSet = false; time_t sunR = 0; time_t sunS = 0; int inthrSR = 0; int intminSR = 0; int inthrSS = 0; int intminSS = 0; bool sunDown = true; <<<<<<< HEAD if (!isnan(time) && !isnan(date) && !isnan(latitude) && !isnan(longitude) && !isnan(timezone)) { ======= // api->getLogger()->logDebug(GwLog::DEBUG,"... calcSun: Lat %f, Lon %f, at: %d, next SR: %d (%s), next SS: %d (%s)", latitude, longitude, t, sunR, sSunR, sunS, sSunS); if (!isnan(time) && !isnan(date) && !isnan(latitude) && !isnan(longitude) && !isnan(timezone)) { // Calculate local time time_t t = (date * secPerYear) + (time + int(timezone * secPerHour)); >>>>>>> sunset sr.calculate(latitude, longitude, t); // LAT, LON, EPOCH // Sunrise if (sr.hasRise) { sunR = (sr.riseTime + int(timezone * secPerHour) + 30) % secPerYear; // add 30 seconds: round to minutes inthrSR = int (sunR / secPerHour); intminSR = int((sunR - inthrSR * secPerHour)/60); } // Sunset if (sr.hasSet) { sunS = (sr.setTime + int(timezone * secPerHour) + 30) % secPerYear; // add 30 seconds: round to minutes inthrSS = int (sunS / secPerHour); intminSS = int((sunS - inthrSS * secPerHour)/60); } // Sun control (return value by sun on sky = false, sun down = true) if ((t >= (sr.riseTime + int(timezone * secPerHour))) && (t <= (sr.setTime + int(timezone * secPerHour)))) sunDown = false; else sunDown = true; } // Return values returnset.sunsetHour = inthrSS; returnset.sunsetMinute = intminSS; returnset.sunriseHour = inthrSR; returnset.sunriseMinute = intminSR; <<<<<<< HEAD returnset.sunControl = false; ======= returnset.sunDown = sunDown; // api->getLogger()->logDebug(GwLog::DEBUG,"... calcSun: at t: %d, hasRise: %d, next SR: %d '%s', hasSet: %d, next SS: %d '%s'\n", t, sr.hasRise, sr.riseTime, sSunR, sr.hasSet, sr.setTime, sSunS); >>>>>>> sunset return returnset; } #endif