From a97a69c3f7bc8a816be08e6b5d95cdc84ad34ef3 Mon Sep 17 00:00:00 2001 From: norbert-walter Date: Sat, 6 Jan 2024 14:17:56 +0100 Subject: [PATCH] New hardware setup for OBP60 V2 --- lib/obp60task/OBP60Extensions.cpp | 97 +++-- lib/obp60task/OBP60Extensions.h | 10 +- lib/obp60task/OBP60Hardware.h | 94 ++--- lib/obp60task/OBP60Keypad.h | 74 ++-- lib/obp60task/OBPSensorTask.cpp | 5 +- lib/obp60task/PageApparentWind.cpp | 2 +- lib/obp60task/PageBME280.cpp | 2 +- lib/obp60task/PageBattery.cpp | 2 +- lib/obp60task/PageBattery2.cpp | 8 +- lib/obp60task/PageClock.cpp | 2 +- lib/obp60task/PageDST810.cpp | 2 +- lib/obp60task/PageFourValues.cpp | 2 +- lib/obp60task/PageFourValues2.cpp | 2 +- lib/obp60task/PageGenerator.cpp | 2 +- lib/obp60task/PageKeelPosition.cpp | 2 +- lib/obp60task/PageOneValue.cpp | 2 +- lib/obp60task/PageRollPitch.cpp | 2 +- lib/obp60task/PageRudderPosition.cpp | 2 +- lib/obp60task/PageSolar.cpp | 2 +- lib/obp60task/PageThreeValues.cpp | 2 +- lib/obp60task/PageTwoValues.cpp | 2 +- lib/obp60task/PageVoltage.cpp | 8 +- lib/obp60task/PageWhite.cpp | 2 +- lib/obp60task/PageWindRose.cpp | 2 +- lib/obp60task/RTClib.cpp | 516 +++++++++++++++++++++++++++ lib/obp60task/RTClib.h | 201 +++++++++++ lib/obp60task/obp60task.cpp | 73 ++-- lib/obp60task/obp60task.h | 8 +- lib/obp60task/platformio.ini | 1 + 29 files changed, 940 insertions(+), 189 deletions(-) create mode 100644 lib/obp60task/RTClib.cpp create mode 100644 lib/obp60task/RTClib.h diff --git a/lib/obp60task/OBP60Extensions.cpp b/lib/obp60task/OBP60Extensions.cpp index e8b3fd6..559bab2 100644 --- a/lib/obp60task/OBP60Extensions.cpp +++ b/lib/obp60task/OBP60Extensions.cpp @@ -1,6 +1,10 @@ #ifdef BOARD_OBP60S3 #include +#include // Driver for WS2812 RGB LED +#include // Driver for PCF8574 output modul from Horter +#include // I2C +#include // Driver for DS1388 RTC #include "SunRise.h" // Lib for sunrise and sunset calculation #include "Pagedata.h" #include "OBP60Hardware.h" @@ -18,68 +22,85 @@ #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 +// Horter I2C moduls +PCF8574 pcf8574_Out(PCF8574_I2C_ADDR1); // First digital output modul PCF8574 from Horter + +// RTC DS1388 +RTC_DS1388 ds1388; + +// Define the array of leds +CRGB fled[NUM_FLASH_LED]; // Flash LED +CRGB backlight[NUM_BACKLIGHT_LED]; // Backlight + // Global vars -int outA = 0; // Outport Byte A -int outB = 0; // Outport Byte B bool blinkingLED = false; // Enable / disable blinking flash LED +bool statusLED = false; // Actual status of flash LED on/off int uvDuration = 0; // Under voltage duration in n x 100ms -void MCP23017Init() +void hardwareInit() { - mcp.init(); - mcp.portMode(MCP23017Port::A, 0b00110000); // Port A, 0 = out, 1 = in - mcp.portMode(MCP23017Port::B, 0b11110000); // Port B, 0 = out, 1 = in + // Init power rail 5.0V + setPortPin(OBP_POWER_50, true); - // 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 + // Init RGB LEDs + FastLED.addLeds(fled, NUM_FLASH_LED); + FastLED.addLeds(backlight, NUM_BACKLIGHT_LED); + FastLED.setBrightness(255); + fled[0] = CRGB::Red; + FastLED.show(); - // Extension Port B set defaults - setPortPin(PB0, false); // PB0 - setPortPin(PB1, false); // PB1 - setPortPin(PB2, false); // PB2 - setPortPin(PB3, false); // PB3 + // Init PCF8574 digital outputs + Wire.setClock(I2C_SPEED); // Set I2C clock on 10 kHz + if(pcf8574_Out.begin()){ // Initialize PCF8574 + pcf8574_Out.write8(255); // Clear all outputs + } + + // Init DS1388 RTC + if(ds1388.begin()){ + uint year = ds1388.now().year(); + if(year < 2023){ + ds1388.adjust(DateTime(__DATE__, __TIME__)); // Set date and time from PC file time + } + } } 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); - } + pinMode(pin, OUTPUT); + digitalWrite(pin, value); } void togglePortPin(uint pin){ - if(pin <=7){ - outA ^= (1 << pin); // Set bit - mcp.writeRegister(MCP23017Register::GPIO_A, outA); + pinMode(pin, OUTPUT); + digitalWrite(pin, !digitalRead(pin)); +} + +void setFlashLED(bool status){ + statusLED = status; + FastLED.setBrightness(255); // Brightness for flash LED + if(statusLED == true){ + fled[0] = CRGB::Red; // Backlight LED on in red } else{ - pin = pin - 8; - outB ^= (1 << pin); // Set bit - mcp.writeRegister(MCP23017Register::GPIO_B, outB); + fled[0] = CRGB::Black; // Backlight LED off } + FastLED.show(); } void blinkingFlashLED(){ if(blinkingLED == true){ - togglePortPin(OBP_FLASH_LED); + statusLED != statusLED; + FastLED.setBrightness(255); // Brightness for flash LED + if(statusLED == true){ + fled[0] = CRGB::Red; // Backlight LED on in red + } + else{ + fled[0] = CRGB::Black; // Backlight LED off + } + FastLED.show(); } } diff --git a/lib/obp60task/OBP60Extensions.h b/lib/obp60task/OBP60Extensions.h index f6c04f9..7f59220 100644 --- a/lib/obp60task/OBP60Extensions.h +++ b/lib/obp60task/OBP60Extensions.h @@ -8,9 +8,6 @@ #include // GxEPD lip for SPI display communikation #include // GxEPD lip for SPI -// Extension port -void MCP23017Init(); - // E-Ink display extern GxEPD_Class display; // E-Ink display functions @@ -27,12 +24,15 @@ extern const GFXfont DSEG7Classic_BoldItalic42pt7b; extern const GFXfont DSEG7Classic_BoldItalic60pt7b; // Gloabl functions +void hardwareInit(); + void setPortPin(uint pin, bool value); // Set port pin for extension port void togglePortPin(uint pin); // Toggle extension port pin -void blinkingFlashLED(); // Blinking function for LED on extension port -void setBlinkingLED(bool on); // Set blinking LED active +void setFlashLED(bool status); // Set flash LED +void blinkingFlashLED(); // Blinking function for flash LED +void setBlinkingLED(bool on); // Set blinking flash LED active void buzzer(uint frequency, uint duration); // Buzzer function void setBuzzerPower(uint power); // Set buzzer power diff --git a/lib/obp60task/OBP60Hardware.h b/lib/obp60task/OBP60Hardware.h index ee2dc6f..179af3d 100644 --- a/lib/obp60task/OBP60Hardware.h +++ b/lib/obp60task/OBP60Hardware.h @@ -1,16 +1,14 @@ // General hardware definitions - // CAN bus pin definitions see obp60task.h + // CAN and RS485 bus pin definitions see obp60task.h // Direction pin for RS485 NMEA0183 - #define OBP_DIRECTION_PIN 27 - // SeaTalk - #define OBP_SEATALK_TX 2 - #define OBP_SEATALK_RX 15 - // I2C (MCP23017, BME280, BMP280, SHT21) - #define OBP_I2C_SDA 21 - #define OBP_I2C_SCL 22 - // Extension Port MCP23017 - #define MCP23017_I2C_ADDR 0x20 // Addr. 0 is 0x20 + #define OBP_DIRECTION_PIN 18 + // I2C + #define I2C_SPEED 10000UL // 10kHz clock speed on I2C bus + #define OBP_I2C_SDA 47 + #define OBP_I2C_SCL 21 + // DS1388 RTC + #define DS1388_I2C_ADDR 0xD0 // Addr. 0xD0 // BME280 #define BME280_I2C_ADDR 0x76 // Addr. 0x76 (0x77) // BMP280 @@ -26,13 +24,15 @@ #define INA226_I2C_ADDR1 0x41 // Addr. 0x41 (fix A0 = 5V, A1 = GND) for battery #define INA226_I2C_ADDR2 0x44 // Addr. 0x44 (fix A0 = GND, A1 = 5V) for solar panels #define INA226_I2C_ADDR3 0x45 // Addr. 0x45 (fix A0 = 5V, A1 = 5V) for generator + // Horter modules + #define PCF8574_I2C_ADDR1 0x20 // First digital out module // SPI (E-Ink display, Extern Bus) - #define OBP_SPI_CS 5 - #define OBP_SPI_DC 17 - #define OBP_SPI_RST 16 - #define OBP_SPI_BUSY 4 - #define OBP_SPI_CLK 18 - #define OBP_SPI_DIN 23 + #define OBP_SPI_CS 39 + #define OBP_SPI_DC 40 + #define OBP_SPI_RST 41 + #define OBP_SPI_BUSY 42 + #define OBP_SPI_CLK 38 + #define OBP_SPI_DIN 48 #define SHOW_TIME 6000 // Show time for logo and WiFi QR code #define FULL_REFRESH_TIME 600 // Refresh cycle time in [s][600...3600] for full display update (very important healcy function) #define MAX_PAGE_NUMBER 10 // Max number of pages for show data @@ -42,54 +42,36 @@ #define FONT4 "DSEG7Classic_BoldItalic80pt7b" // GPS (NEO-6M, NEO-M8N) - #define OBP_GPS_TX 35 // Read only GPS data - // TTP229 Touch Pad Controller (!!No I2C!!) - #define TTP_SDO 25 - #define TTP_SCL 33 + #define OBP_GPS_RX 2 + #define OBP_GPS_TX 1 // 1Wire (DS18B20) - #define OBP_1WIRE 32 // External 1Wire + #define OBP_1WIRE 6 // External 1Wire // Buzzer - #define OBP_BUZZER 19 + #define OBP_BUZZER 16 #define TONE1 1500 // 1500Hz #define TONE2 2500 // 2500Hz #define TONE3 3500 // 3500Hz #define TONE4 4000 // 4000Hz // Analog Input - #define OBP_ANALOG0 34 // Voltage power supplay - #define OBP_ANALOG1 36 // Analog In 1 - #define OBP_ANALOG2 39 // Analog In 2 + #define OBP_ANALOG0 4 // Voltage power supplay #define MIN_VOLTAGE 9.0 // Min voltage for under voltage detection (then goto deep sleep) #define POWER_FAIL_TIME 2 // in [ms] Accept min voltage until 2 x 1ms (for under voltage gaps by engine start) - // Extension Port PA - #define PA0 0 // Digital Out 1 - #define PA1 1 // Digital Out 2 - #define PA2 2 // Flash LED - #define PA3 3 // Backlight LEDs - #define PA4 4 // Digital In 1 - #define PA5 5 // Digital In 2 - #define PA6 6 // Power Rail 5.0V - #define PA7 7 // Power Rail 3.3V - // Extension Port PB - #define PB0 8 // Extension Connector - #define PB1 9 // Extension Connector - #define PB2 10 // Extension Connector - #define PB3 11 // Extension Connector - #define PB4 12 // Extension Connector - #define PB5 13 // Extension Connector - #define PB6 14 // Extension Connector - #define PB7 15 // Extension Connector + // Touch buttons + #define TOUCHTHRESHOLD 50000// Touch sensitivity, lower values more sensitiv + #define TP1 14 // Left outside + #define TP2 13 + #define TP3 12 + #define TP4 11 + #define TP5 10 + #define TP6 9 // Right ouside + + // Flash LED (1x WS2812B) + #define NUM_FLASH_LED 1 // Number of flash LED + #define OBP_FLASH_LED 7 // GPIO port + // Backlight LEDs (6x WS2812B) + #define NUM_BACKLIGHT_LED 6 // Numebr of Backlight LEDs + #define OBP_BACKLIGHT_LED 15 // GPIO port + // Power Rail + #define OBP_POWER_50 5 - // Extension Port Digital Out - #define OBP_DIGITAL_OUT1 PA0 - #define OBP_DIGITAL_OUT2 PA1 - // Extension Port LED - #define OBP_FLASH_LED PA2 - // Extension Port Backlight LEDs - #define OBP_BACKLIGHT_LED PA3 - // Extension Port Digital In - #define OBP_DIGITAL_IN1 PA4 - #define OBP_DIGITAL_IN2 PA5 - // Extension Port Power Rails - #define OBP_POWER_50 PA6 - #define OBP_POWER_33 PA7 diff --git a/lib/obp60task/OBP60Keypad.h b/lib/obp60task/OBP60Keypad.h index 2079dc5..0d6fa71 100644 --- a/lib/obp60task/OBP60Keypad.h +++ b/lib/obp60task/OBP60Keypad.h @@ -6,13 +6,8 @@ // Global vars -// Routine for TTP229-BSF (!!! IC use not a I2C bus !!!) -// -// 8 Key Mode -// -// Key number {0, 1, 2, 3, 4, 5, 6, 7, 8} -// Scan code {0, 8, 7, 1, 6, 2, 5, 3, 4} -int keyposition[9] = {0, 3, 5, 7, 8, 6, 4, 2, 1}; // Position of key in raw data, 0 = nothing touched +// Touch keypad over ESP32 touch sensor inputs + int keypad[9]; // Raw data array from TTP229 int key; // Value of key [0|1], 0 = touched, 1 = not touched int keycode = 0; // Keycode of pressed key [0...8], 0 = nothing touched @@ -27,32 +22,65 @@ long starttime = 0; // Start time point for pressed key int readKeypad() { int keystatus = 0; // Status of key [0...11], 0 = processed, 1...8 = key 1..8, 9 = right swipe , 10 = left swipe, 11 keys disabled - - pinMode(TTP_SDO, INPUT); - pinMode(TTP_SCL, OUTPUT); keycode = 0; - // Read key code from raw data + + // Read key code + if(touchRead(14) > TOUCHTHRESHOLD){ // Touch pad 1 + keypad[1] = 1; + } + else{ + keypad[1] = 0; + } + if(touchRead(13) > TOUCHTHRESHOLD){ // Touch pad 2 + keypad[2] = 1; + } + else{ + keypad[2] = 0; + } + if(touchRead(12) > TOUCHTHRESHOLD){ // Touch pad 3 + keypad[3] = 1; + } + else{ + keypad[3] = 0; + } + if(touchRead(11) > TOUCHTHRESHOLD){ // Touch pad 4 + keypad[4] = 1; + } + else{ + keypad[4] = 0; + } + if(touchRead(10) > TOUCHTHRESHOLD){ // Touch pad 5 + keypad[5] = 1; + } + else{ + keypad[5] = 0; + } + if(touchRead(9) > TOUCHTHRESHOLD){ // Touch pad 6 + keypad[6] = 1; + } + else{ + keypad[6] = 0; + } + // Nothing touched + if(keypad[1] == 0 && keypad[2] == 0 && keypad[3] == 0 && keypad[4] == 0 && keypad[5] == 0 && keypad[6] == 0){ + keypad[0] = 1; + } + else{ + keypad[0] = 0; + } + for (int i = 0; i < 9; i++) { - digitalWrite(TTP_SCL, LOW); -// delay(1); // 0ms clock - delayMicroseconds(100); - keypad[i] = digitalRead(TTP_SDO); if(i > 0){ - // Invert keypad + // Convert keypad to keycode if(keypad[i] == 1){ - key = 0; + key = 1; } else{ - key = 1; + key = 0; } keycode += key * i; } - digitalWrite(TTP_SCL, HIGH); -// delay(1); // 0ms clock - delayMicroseconds(100); } - // Remapping keycode - keycode = keyposition[keycode]; // Detect short keynumber if (keycode > 0 ){ diff --git a/lib/obp60task/OBPSensorTask.cpp b/lib/obp60task/OBPSensorTask.cpp index 97f5c53..6d2cbed 100644 --- a/lib/obp60task/OBPSensorTask.cpp +++ b/lib/obp60task/OBPSensorTask.cpp @@ -33,9 +33,10 @@ void underVoltageDetection(){ } if(millis() > starttime + POWER_FAIL_TIME){ Timer1.stop(); // Stop Timer1 +/* setPortPin(OBP_BACKLIGHT_LED, false); // Backlight Off - setPortPin(OBP_FLASH_LED, false); // Flash LED Off - setPortPin(OBP_POWER_33, false); // Power rail 3.3V Off + setFlashLED(false); // Flash LED Off +*/ buzzer(TONE4, 20); // Buzzer tone 4kHz 20ms setPortPin(OBP_POWER_50, false); // Power rail 5.0V Off // Shutdown EInk display diff --git a/lib/obp60task/PageApparentWind.cpp b/lib/obp60task/PageApparentWind.cpp index cc82d2f..dfaf747 100644 --- a/lib/obp60task/PageApparentWind.cpp +++ b/lib/obp60task/PageApparentWind.cpp @@ -80,7 +80,7 @@ public: // Optical warning by limit violation (unused) if(String(flashLED) == "Limit Violation"){ setBlinkingLED(false); - setPortPin(OBP_FLASH_LED, false); + setFlashLED(false); } // Logging boat values diff --git a/lib/obp60task/PageBME280.cpp b/lib/obp60task/PageBME280.cpp index 677b64a..1ed2009 100644 --- a/lib/obp60task/PageBME280.cpp +++ b/lib/obp60task/PageBME280.cpp @@ -96,7 +96,7 @@ class PageBME280 : public Page // Optical warning by limit violation (unused) if(String(flashLED) == "Limit Violation"){ setBlinkingLED(false); - setPortPin(OBP_FLASH_LED, false); + setFlashLED(false); } // Logging boat values diff --git a/lib/obp60task/PageBattery.cpp b/lib/obp60task/PageBattery.cpp index e9743db..1766cb8 100644 --- a/lib/obp60task/PageBattery.cpp +++ b/lib/obp60task/PageBattery.cpp @@ -144,7 +144,7 @@ class PageBattery : public Page // Optical warning by limit violation (unused) if(String(flashLED) == "Limit Violation"){ setBlinkingLED(false); - setPortPin(OBP_FLASH_LED, false); + setFlashLED(false); } // Logging boat values diff --git a/lib/obp60task/PageBattery2.cpp b/lib/obp60task/PageBattery2.cpp index 13b4c7d..2da8329 100644 --- a/lib/obp60task/PageBattery2.cpp +++ b/lib/obp60task/PageBattery2.cpp @@ -144,7 +144,7 @@ public: } if(String(batType) == "Pb" && (raw >= 11.8 && raw <= 14.8)){ setBlinkingLED(false); - setPortPin(OBP_FLASH_LED, false); + setFlashLED(false); } // Limits for Gel battery if(String(batType) == "Gel" && (raw < 11.8 || raw > 14.4)){ @@ -152,7 +152,7 @@ public: } if(String(batType) == "Gel" && (raw >= 11.8 && raw <= 14.4)){ setBlinkingLED(false); - setPortPin(OBP_FLASH_LED, false); + setFlashLED(false); } // Limits for AGM battery if(String(batType) == "AGM" && (raw < 11.8 || raw > 14.7)){ @@ -160,7 +160,7 @@ public: } if(String(batType) == "AGM" && (raw >= 11.8 && raw <= 14.7)){ setBlinkingLED(false); - setPortPin(OBP_FLASH_LED, false); + setFlashLED(false); } // Limits for LiFePo4 battery if(String(batType) == "LiFePo4" && (raw < 12.0 || raw > 14.6)){ @@ -168,7 +168,7 @@ public: } if(String(batType) == "LiFePo4" && (raw >= 12.0 && raw <= 14.6)){ setBlinkingLED(false); - setPortPin(OBP_FLASH_LED, false); + setFlashLED(false); } } diff --git a/lib/obp60task/PageClock.cpp b/lib/obp60task/PageClock.cpp index 903ad73..b5dd21c 100644 --- a/lib/obp60task/PageClock.cpp +++ b/lib/obp60task/PageClock.cpp @@ -81,7 +81,7 @@ public: // Optical warning by limit violation (unused) if(String(flashLED) == "Limit Violation"){ setBlinkingLED(false); - setPortPin(OBP_FLASH_LED, false); + setFlashLED(false); } // Logging boat values diff --git a/lib/obp60task/PageDST810.cpp b/lib/obp60task/PageDST810.cpp index 831e792..65455bf 100644 --- a/lib/obp60task/PageDST810.cpp +++ b/lib/obp60task/PageDST810.cpp @@ -81,7 +81,7 @@ class PageDST810 : public Page // Optical warning by limit violation (unused) if(String(flashLED) == "Limit Violation"){ setBlinkingLED(false); - setPortPin(OBP_FLASH_LED, false); + setFlashLED(false); } // Logging boat values diff --git a/lib/obp60task/PageFourValues.cpp b/lib/obp60task/PageFourValues.cpp index e48b203..4dd076f 100644 --- a/lib/obp60task/PageFourValues.cpp +++ b/lib/obp60task/PageFourValues.cpp @@ -81,7 +81,7 @@ class PageFourValues : public Page // Optical warning by limit violation (unused) if(String(flashLED) == "Limit Violation"){ setBlinkingLED(false); - setPortPin(OBP_FLASH_LED, false); + setFlashLED(false); } // Logging boat values diff --git a/lib/obp60task/PageFourValues2.cpp b/lib/obp60task/PageFourValues2.cpp index 4283fc7..5c4a38c 100644 --- a/lib/obp60task/PageFourValues2.cpp +++ b/lib/obp60task/PageFourValues2.cpp @@ -81,7 +81,7 @@ class PageFourValues2 : public Page // Optical warning by limit violation (unused) if(String(flashLED) == "Limit Violation"){ setBlinkingLED(false); - setPortPin(OBP_FLASH_LED, false); + setFlashLED(false); } // Logging boat values diff --git a/lib/obp60task/PageGenerator.cpp b/lib/obp60task/PageGenerator.cpp index 71618e0..ffacc23 100644 --- a/lib/obp60task/PageGenerator.cpp +++ b/lib/obp60task/PageGenerator.cpp @@ -57,7 +57,7 @@ public: // Optical warning by limit violation (unused) if(String(flashLED) == "Limit Violation"){ setBlinkingLED(false); - setPortPin(OBP_FLASH_LED, false); + setFlashLED(false); } // Logging voltage value diff --git a/lib/obp60task/PageKeelPosition.cpp b/lib/obp60task/PageKeelPosition.cpp index 5c8d816..e75bbd4 100644 --- a/lib/obp60task/PageKeelPosition.cpp +++ b/lib/obp60task/PageKeelPosition.cpp @@ -60,7 +60,7 @@ public: // Optical warning by limit violation (unused) if(String(flashLED) == "Limit Violation"){ setBlinkingLED(false); - setPortPin(OBP_FLASH_LED, false); + setFlashLED(false); } // Logging boat values diff --git a/lib/obp60task/PageOneValue.cpp b/lib/obp60task/PageOneValue.cpp index 8981a40..1c16bc3 100644 --- a/lib/obp60task/PageOneValue.cpp +++ b/lib/obp60task/PageOneValue.cpp @@ -47,7 +47,7 @@ class PageOneValue : public Page{ // Optical warning by limit violation (unused) if(String(flashLED) == "Limit Violation"){ setBlinkingLED(false); - setPortPin(OBP_FLASH_LED, false); + setFlashLED(false); } // Logging boat values diff --git a/lib/obp60task/PageRollPitch.cpp b/lib/obp60task/PageRollPitch.cpp index 3c757c1..341ff80 100644 --- a/lib/obp60task/PageRollPitch.cpp +++ b/lib/obp60task/PageRollPitch.cpp @@ -115,7 +115,7 @@ public: // Limits for roll if(value1*360/(2*PI) > -1*rolllimit && value1*360/(2*PI) < rolllimit){ setBlinkingLED(false); - setPortPin(OBP_FLASH_LED, false); + setFlashLED(false); } else{ setBlinkingLED(true); diff --git a/lib/obp60task/PageRudderPosition.cpp b/lib/obp60task/PageRudderPosition.cpp index 87da033..6221cdf 100644 --- a/lib/obp60task/PageRudderPosition.cpp +++ b/lib/obp60task/PageRudderPosition.cpp @@ -55,7 +55,7 @@ public: // Optical warning by limit violation (unused) if(String(flashLED) == "Limit Violation"){ setBlinkingLED(false); - setPortPin(OBP_FLASH_LED, false); + setFlashLED(false); } // Logging boat values diff --git a/lib/obp60task/PageSolar.cpp b/lib/obp60task/PageSolar.cpp index 2144b29..96731bf 100644 --- a/lib/obp60task/PageSolar.cpp +++ b/lib/obp60task/PageSolar.cpp @@ -57,7 +57,7 @@ public: // Optical warning by limit violation (unused) if(String(flashLED) == "Limit Violation"){ setBlinkingLED(false); - setPortPin(OBP_FLASH_LED, false); + setFlashLED(false); } // Logging voltage value diff --git a/lib/obp60task/PageThreeValues.cpp b/lib/obp60task/PageThreeValues.cpp index 8fb3485..5e01650 100644 --- a/lib/obp60task/PageThreeValues.cpp +++ b/lib/obp60task/PageThreeValues.cpp @@ -70,7 +70,7 @@ class PageThreeValues : public Page // Optical warning by limit violation (unused) if(String(flashLED) == "Limit Violation"){ setBlinkingLED(false); - setPortPin(OBP_FLASH_LED, false); + setFlashLED(false); } // Logging boat values diff --git a/lib/obp60task/PageTwoValues.cpp b/lib/obp60task/PageTwoValues.cpp index de7b8ca..35ca097 100644 --- a/lib/obp60task/PageTwoValues.cpp +++ b/lib/obp60task/PageTwoValues.cpp @@ -59,7 +59,7 @@ class PageTwoValues : public Page // Optical warning by limit violation (unused) if(String(flashLED) == "Limit Violation"){ setBlinkingLED(false); - setPortPin(OBP_FLASH_LED, false); + setFlashLED(false); } // Logging boat values diff --git a/lib/obp60task/PageVoltage.cpp b/lib/obp60task/PageVoltage.cpp index 708be2c..83f8a8d 100644 --- a/lib/obp60task/PageVoltage.cpp +++ b/lib/obp60task/PageVoltage.cpp @@ -98,7 +98,7 @@ public: } if(String(batType) == "Pb" && (raw >= 11.8 && raw <= 14.8)){ setBlinkingLED(false); - setPortPin(OBP_FLASH_LED, false); + setFlashLED(false); } // Limits for Gel battery if(String(batType) == "Gel" && (raw < 11.8 || raw > 14.4)){ @@ -106,7 +106,7 @@ public: } if(String(batType) == "Gel" && (raw >= 11.8 && raw <= 14.4)){ setBlinkingLED(false); - setPortPin(OBP_FLASH_LED, false); + setFlashLED(false); } // Limits for AGM battery if(String(batType) == "AGM" && (raw < 11.8 || raw > 14.7)){ @@ -114,7 +114,7 @@ public: } if(String(batType) == "AGM" && (raw >= 11.8 && raw <= 14.7)){ setBlinkingLED(false); - setPortPin(OBP_FLASH_LED, false); + setFlashLED(false); } // Limits for LiFePo4 battery if(String(batType) == "LiFePo4" && (raw < 12.0 || raw > 14.6)){ @@ -122,7 +122,7 @@ public: } if(String(batType) == "LiFePo4" && (raw >= 12.0 && raw <= 14.6)){ setBlinkingLED(false); - setPortPin(OBP_FLASH_LED, false); + setFlashLED(false); } } diff --git a/lib/obp60task/PageWhite.cpp b/lib/obp60task/PageWhite.cpp index 9243f12..e68ea69 100644 --- a/lib/obp60task/PageWhite.cpp +++ b/lib/obp60task/PageWhite.cpp @@ -21,7 +21,7 @@ class PageWhite : public Page{ // Optical warning by limit violation (unused) if(String(flashLED) == "Limit Violation"){ setBlinkingLED(false); - setPortPin(OBP_FLASH_LED, false); + setFlashLED(false); } // Logging boat values diff --git a/lib/obp60task/PageWindRose.cpp b/lib/obp60task/PageWindRose.cpp index 8e78572..d25ada9 100644 --- a/lib/obp60task/PageWindRose.cpp +++ b/lib/obp60task/PageWindRose.cpp @@ -130,7 +130,7 @@ public: // Optical warning by limit violation (unused) if(String(flashLED) == "Limit Violation"){ setBlinkingLED(false); - setPortPin(OBP_FLASH_LED, false); + setFlashLED(false); } // Logging boat values diff --git a/lib/obp60task/RTClib.cpp b/lib/obp60task/RTClib.cpp new file mode 100644 index 0000000..8c5429c --- /dev/null +++ b/lib/obp60task/RTClib.cpp @@ -0,0 +1,516 @@ +// A library for handling real-time clocks, dates, etc. +// 2010-02-04 http://opensource.org/licenses/mit-license.php +// 2012-11-08 RAM methods - idreammicro.com +// 2012-11-14 SQW/OUT methods - idreammicro.com +// 2012-01-12 DS1388 support +// 2013-08-29 ENERGIA MSP430 support +// 2023-11-24 Return value for begin() to RTC presence check - NoWa + +#include +// Energia support +#ifndef ENERGIA +// #include +#else +#define pgm_read_word(data) *data +#define pgm_read_byte(data) *data +#define PROGMEM +#endif +#include "RTClib.h" +#include + + +//////////////////////////////////////////////////////////////////////////////// +// utility code, some of this could be exposed in the DateTime API if needed + +static const uint8_t daysInMonth [] PROGMEM = { + 31,28,31,30,31,30,31,31,30,31,30,31 +}; + +// number of days since 2000/01/01, valid for 2001..2099 +static uint16_t date2days(uint16_t y, uint8_t m, uint8_t d) { + if (y >= 2000) + y -= 2000; + uint16_t days = d; + for (uint8_t i = 1; i < m; ++i) + days += pgm_read_byte(daysInMonth + i - 1); + if (m > 2 && y % 4 == 0) + ++days; + return days + 365 * y + (y + 3) / 4 - 1; +} + +static long time2long(uint16_t days, uint8_t h, uint8_t m, uint8_t s) { + return ((days * 24L + h) * 60 + m) * 60 + s; +} + +//////////////////////////////////////////////////////////////////////////////// +// DateTime implementation - ignores time zones and DST changes +// NOTE: also ignores leap seconds, see http://en.wikipedia.org/wiki/Leap_second + +DateTime::DateTime (long t) { + ss = t % 60; + t /= 60; + mm = t % 60; + t /= 60; + hh = t % 24; + uint16_t days = t / 24; + uint8_t leap; + for (yOff = 0; ; ++yOff) { + leap = yOff % 4 == 0; + if (days < 365 + leap) + break; + days -= 365 + leap; + } + for (m = 1; ; ++m) { + uint8_t daysPerMonth = pgm_read_byte(daysInMonth + m - 1); + if (leap && m == 2) + ++daysPerMonth; + if (days < daysPerMonth) + break; + days -= daysPerMonth; + } + d = days + 1; +} + +DateTime::DateTime (uint16_t year, uint8_t month, uint8_t day, uint8_t hour, uint8_t min, uint8_t sec) { + if (year >= 2000) + year -= 2000; + yOff = year; + m = month; + d = day; + hh = hour; + mm = min; + ss = sec; +} + +static uint8_t conv2d(const char* p) { + uint8_t v = 0; + if ('0' <= *p && *p <= '9') + v = *p - '0'; + return 10 * v + *++p - '0'; +} + +// A convenient constructor for using "the compiler's time": +// DateTime now (__DATE__, __TIME__); +// NOTE: using PSTR would further reduce the RAM footprint +DateTime::DateTime (const char* date, const char* time) { + // sample input: date = "Dec 26 2009", time = "12:34:56" + yOff = conv2d(date + 9); + // Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec + switch (date[0]) { + case 'J': m = date[1] == 'a' ? 1 : m = date[2] == 'n' ? 6 : 7; break; + case 'F': m = 2; break; + case 'A': m = date[2] == 'r' ? 4 : 8; break; + case 'M': m = date[2] == 'r' ? 3 : 5; break; + case 'S': m = 9; break; + case 'O': m = 10; break; + case 'N': m = 11; break; + case 'D': m = 12; break; + } + d = conv2d(date + 4); + hh = conv2d(time); + mm = conv2d(time + 3); + ss = conv2d(time + 6); +} + +uint8_t DateTime::dayOfWeek() const { + uint16_t day = get() / SECONDS_PER_DAY; + return (day + 6) % 7; // Jan 1, 2000 is a Saturday, i.e. returns 6 +} + +long DateTime::get() const { + uint16_t days = date2days(yOff, m, d); + return time2long(days, hh, mm, ss); +} + +//////////////////////////////////////////////////////////////////////////////// +// RTC_DS1307 implementation + +void RTC_DS1307::adjust(const DateTime& dt) { + Wire.beginTransmission(DS1307_ADDRESS); + Wire.write((byte) 0); + Wire.write(bin2bcd(dt.second())); + Wire.write(bin2bcd(dt.minute())); + Wire.write(bin2bcd(dt.hour())); + Wire.write(bin2bcd(0)); + Wire.write(bin2bcd(dt.day())); + Wire.write(bin2bcd(dt.month())); + Wire.write(bin2bcd(dt.year() - 2000)); + Wire.write((byte) 0); + Wire.endTransmission(); +} + +DateTime RTC_DS1307::now() { + Wire.beginTransmission(DS1307_ADDRESS); + Wire.write((byte) 0); + Wire.endTransmission(); + + Wire.requestFrom(DS1307_ADDRESS, 7); + uint8_t ss = bcd2bin(Wire.read()); + uint8_t mm = bcd2bin(Wire.read()); + uint8_t hh = bcd2bin(Wire.read()); + Wire.read(); + uint8_t d = bcd2bin(Wire.read()); + uint8_t m = bcd2bin(Wire.read()); + uint16_t y = bcd2bin(Wire.read()) + 2000; + + return DateTime (y, m, d, hh, mm, ss); +} + +void RTC_DS1307::setSqwOutLevel(uint8_t level) { + uint8_t value = (level == LOW) ? 0x00 : (1 << RTC_DS1307__OUT); + Wire.beginTransmission(DS1307_ADDRESS); + Wire.write(DS1307_CONTROL_REGISTER); + Wire.write(value); + Wire.endTransmission(); +} + +void RTC_DS1307::setSqwOutSignal(Frequencies frequency) { + uint8_t value = (1 << RTC_DS1307__SQWE); + switch (frequency) + { + case Frequency_1Hz: + // Nothing to do. + break; + case Frequency_4096Hz: + value |= (1 << RTC_DS1307__RS0); + break; + case Frequency_8192Hz: + value |= (1 << RTC_DS1307__RS1); + break; + case Frequency_32768Hz: + default: + value |= (1 << RTC_DS1307__RS1) | (1 << RTC_DS1307__RS0); + break; + } + Wire.beginTransmission(DS1307_ADDRESS); + Wire.write(DS1307_CONTROL_REGISTER); + Wire.write(value); + Wire.endTransmission(); +} + +uint8_t RTC_DS1307::readByteInRam(uint8_t address) { + Wire.beginTransmission(DS1307_ADDRESS); + Wire.write(address); + Wire.endTransmission(); + + Wire.requestFrom(DS1307_ADDRESS, 1); + uint8_t data = Wire.read(); + Wire.endTransmission(); + + return data; +} + +void RTC_DS1307::readBytesInRam(uint8_t address, uint8_t length, uint8_t* p_data) { + Wire.beginTransmission(DS1307_ADDRESS); + Wire.write(address); + Wire.endTransmission(); + + Wire.requestFrom(DS1307_ADDRESS, (int)length); + for (uint8_t i = 0; i < length; i++) { + p_data[i] = Wire.read(); + } + Wire.endTransmission(); +} + +void RTC_DS1307::writeByteInRam(uint8_t address, uint8_t data) { + Wire.beginTransmission(DS1307_ADDRESS); + Wire.write(address); + Wire.write(data); + Wire.endTransmission(); +} + +void RTC_DS1307::writeBytesInRam(uint8_t address, uint8_t length, uint8_t* p_data) { + Wire.beginTransmission(DS1307_ADDRESS); + Wire.write(address); + for (uint8_t i = 0; i < length; i++) { + Wire.write(p_data[i]); + } + Wire.endTransmission(); +} + +uint8_t RTC_DS1307::isrunning(void) { + Wire.beginTransmission(DS1307_ADDRESS); + Wire.write((byte) 0); + Wire.endTransmission(); + + Wire.requestFrom(DS1307_ADDRESS, 1); + uint8_t ss = Wire.read(); + return !(ss>>7); +} + +//////////////////////////////////////////////////////////////////////////////// +// DS 1388 implementation + +void RTC_DS1388::adjust(const DateTime& dt) { + Wire.beginTransmission(DS1388_ADDRESS); + Wire.write((byte) 0); + Wire.write(bin2bcd(0)); // hundreds of seconds 0x00 + Wire.write(bin2bcd(dt.second())); // 0x01 + Wire.write(bin2bcd(dt.minute())); // 0x02 + Wire.write(bin2bcd(dt.hour())); // 0x03 + Wire.write(bin2bcd(0)); // 0x04 + Wire.write(bin2bcd(dt.day())); // 0x05 + Wire.write(bin2bcd(dt.month())); // 0x06 + Wire.write(bin2bcd(dt.year() - 2000)); // 0x07 + Wire.endTransmission(); + + Wire.beginTransmission(DS1388_ADDRESS); + Wire.write((byte) 0x0b); + Wire.write((byte) 0x00); //clear the 'time is invalid ' flag bit (OSF) + Wire.endTransmission(); +} + +DateTime RTC_DS1388::now() { + Wire.beginTransmission(DS1388_ADDRESS); + Wire.write((byte) 0); + Wire.endTransmission(); + + Wire.requestFrom(DS1388_ADDRESS, 8); + uint8_t hs = bcd2bin(Wire.read() & 0x7F); // hundreds of seconds + uint8_t ss = bcd2bin(Wire.read() & 0x7F); + uint8_t mm = bcd2bin(Wire.read()); + uint8_t hh = bcd2bin(Wire.read()); + Wire.read(); + uint8_t d = bcd2bin(Wire.read()); + uint8_t m = bcd2bin(Wire.read()); + uint16_t y = bcd2bin(Wire.read()) + 2000; + + return DateTime (y, m, d, hh, mm, ss); +} + +uint8_t RTC_DS1388::isrunning() { + Wire.beginTransmission(DS1388_ADDRESS); + Wire.write((byte)0x0b); + Wire.endTransmission(); + + Wire.requestFrom(DS1388_ADDRESS, 1); + uint8_t ss = Wire.read(); + return !(ss>>7); //OSF flag bit +} + + +void RTC_DS1388::EEPROMWrite(int pos, uint8_t c) { + uint8_t rel_pos = pos % 256; + if(pos > 255){ + Wire.beginTransmission(DS1388_ADDRESS | DS1388_EEPROM_1); + } else { + Wire.beginTransmission(DS1388_ADDRESS | DS1388_EEPROM_0); + } + // Set address + Wire.write((byte)rel_pos); + // Wite data + Wire.write((byte)c); + Wire.endTransmission(); +#if defined(__MSP430G2553__) + delay(10); // Needed on MSP430 !! +#endif +} + + +uint8_t RTC_DS1388::EEPROMRead(int pos) { + uint8_t rel_pos = pos % 256; + if(pos > 255){ + Wire.beginTransmission(DS1388_ADDRESS | DS1388_EEPROM_1); + } else { + Wire.beginTransmission(DS1388_ADDRESS | DS1388_EEPROM_0); + } + // Set address + Wire.write((byte)rel_pos); + Wire.endTransmission(true); // Stay open + // Request one byte + if(pos > 255){ + Wire.requestFrom(DS1388_ADDRESS | DS1388_EEPROM_1, 1); + } else { + Wire.requestFrom(DS1388_ADDRESS | DS1388_EEPROM_0, 1); + } + uint8_t c = Wire.read(); +#if defined(__MSP430G2553__) + delay(10); // Needed on MSP430 !! +#endif + return c; +} + + +/////////////////////////////////////////////////////////////////////////////// +// RTC_PCF8563 implementation +// contributed by @mariusster, see http://forum.jeelabs.net/comment/1902 + +void RTC_PCF8563::adjust(const DateTime& dt) { + Wire.beginTransmission(PCF8563_ADDRESS); + Wire.write((byte) 0); + Wire.write((byte) 0x0); // control/status1 + Wire.write((byte) 0x0); // control/status2 + Wire.write(bin2bcd(dt.second())); // set seconds + Wire.write(bin2bcd(dt.minute())); // set minutes + Wire.write(bin2bcd(dt.hour())); // set hour + Wire.write(bin2bcd(dt.day())); // set day + Wire.write((byte) 0x01); // set weekday + Wire.write(bin2bcd(dt.month())); // set month, century to 1 + Wire.write(bin2bcd(dt.year() - 2000)); // set year to 00-99 + Wire.write((byte) 0x80); // minute alarm value reset to 00 + Wire.write((byte) 0x80); // hour alarm value reset to 00 + Wire.write((byte) 0x80); // day alarm value reset to 00 + Wire.write((byte) 0x80); // weekday alarm value reset to 00 + Wire.write((byte) 0x0); // set freqout 0= 32768khz, 1= 1hz + Wire.write((byte) 0x0); // timer off + Wire.endTransmission(); +} + +DateTime RTC_PCF8563::now() { + Wire.beginTransmission(PCF8563_ADDRESS); + Wire.write(PCF8563_SEC_ADDR); + Wire.endTransmission(); + + Wire.requestFrom(PCF8563_ADDRESS, 7); + uint8_t ss = bcd2bin(Wire.read() & 0x7F); + uint8_t mm = bcd2bin(Wire.read() & 0x7F); + uint8_t hh = bcd2bin(Wire.read() & 0x3F); + uint8_t d = bcd2bin(Wire.read() & 0x3F); + Wire.read(); + uint8_t m = bcd2bin(Wire.read()& 0x1F); + uint16_t y = bcd2bin(Wire.read()) + 2000; + + return DateTime (y, m, d, hh, mm, ss); +} + + +/////////////////////////////////////////////////////////////////////////////// +// RTC_BQ32000 implementation + +void RTC_BQ32000::adjust(const DateTime& dt) { + Wire.beginTransmission(BQ32000_ADDRESS); + Wire.write((byte) 0); + Wire.write(bin2bcd(dt.second())); + Wire.write(bin2bcd(dt.minute())); + Wire.write(bin2bcd(dt.hour())); + Wire.write(bin2bcd(0)); + Wire.write(bin2bcd(dt.day())); + Wire.write(bin2bcd(dt.month())); + Wire.write(bin2bcd(dt.year() - 2000)); + Wire.endTransmission(); +} + +DateTime RTC_BQ32000::now() { + Wire.beginTransmission(BQ32000_ADDRESS); + Wire.write((byte) 0); + Wire.endTransmission(); + + Wire.requestFrom(DS1307_ADDRESS, 7); + uint8_t ss = bcd2bin(Wire.read()); + uint8_t mm = bcd2bin(Wire.read()); + uint8_t hh = bcd2bin(Wire.read()); + Wire.read(); + uint8_t d = bcd2bin(Wire.read()); + uint8_t m = bcd2bin(Wire.read()); + uint16_t y = bcd2bin(Wire.read()) + 2000; + + return DateTime (y, m, d, hh, mm, ss); +} + +void RTC_BQ32000::setIRQ(uint8_t state) { + /* Set IRQ square wave output state: 0=disabled, 1=1Hz, 2=512Hz. + */ + uint8_t reg, value; + if (state) { + // Setting the frequency is a bit complicated on the BQ32000: + Wire.beginTransmission(BQ32000_ADDRESS); + Wire.write(BQ32000_SFKEY1); + Wire.write(BQ32000_SFKEY1_VAL); + Wire.write(BQ32000_SFKEY2_VAL); + Wire.write((state == 1) ? BQ32000_FTF_1HZ : BQ32000_FTF_512HZ); + Wire.endTransmission(); + } + value = readRegister(BQ32000_CAL_CFG1); + value = (!state) ? value & ~(1< 31) value = 31; + if (value < -31) value = -31; + val = (uint8_t) (value < 0) ? -value | (1< 2) return; + value = BQ32000_CHARGE_ENABLE; + if (state == 2) { + // High voltage charge enable: + value |= (1 << BQ32000__TCFE); + } + writeRegister(BQ32000_CFG2, value); + // Now enable charger: + writeRegister(BQ32000_TCH2, 1 << BQ32000__TCH2_BIT); +} + + +uint8_t RTC_BQ32000::readRegister(uint8_t address) { + /* Read and return the value in the register at the given address. + */ + Wire.beginTransmission(BQ32000_ADDRESS); + Wire.write((byte) address); + Wire.endTransmission(); + Wire.requestFrom(DS1307_ADDRESS, 1); + // Get register state: + return Wire.read(); +} + +uint8_t RTC_BQ32000::writeRegister(uint8_t address, uint8_t value) { + /* Write the given value to the register at the given address. + */ + Wire.beginTransmission(BQ32000_ADDRESS); + Wire.write(address); + Wire.write(value); + Wire.endTransmission(); +} + +uint8_t RTC_BQ32000::isrunning() { + return !(readRegister(0x0)>>7); +} + + +//////////////////////////////////////////////////////////////////////////////// +// RTC_Millis implementation + +long RTC_Millis::offset = 0; + +void RTC_Millis::adjust(const DateTime& dt) { + offset = dt.get() - millis() / 1000; +} + +DateTime RTC_Millis::now() { + return offset + millis() / 1000; +} + +//////////////////////////////////////////////////////////////////////////////// \ No newline at end of file diff --git a/lib/obp60task/RTClib.h b/lib/obp60task/RTClib.h new file mode 100644 index 0000000..a99e791 --- /dev/null +++ b/lib/obp60task/RTClib.h @@ -0,0 +1,201 @@ +// A library for handling real-time clocks, dates, etc. +// 2010-02-04 http://opensource.org/licenses/mit-license.php +// 2012-11-08 RAM methods - idreammicro.com +// 2012-11-14 SQW/OUT methods - idreammicro.com +// 2023-11-24 Return value for begin() to RTC presence check - NoWa + +// DS1307 +#define DS1307_ADDRESS 0x68 +#define DS1307_CONTROL_REGISTER 0x07 +#define DS1307_RAM_REGISTER 0x08 + +// DS1307 Control register bits. +#define RTC_DS1307__RS0 0x00 +#define RTC_DS1307__RS1 0x01 +#define RTC_DS1307__SQWE 0x04 +#define RTC_DS1307__OUT 0x07 + +// DS1388 +#define DS1388_ADDRESS 0x68 + +// DS1388 Control register bits +#define DS1388_EEPROM_0 0x01 +#define DS1388_EEPROM_1 0x02 + +// PCF8563 +#define PCF8563_ADDRESS 0x51 +#define PCF8563_SEC_ADDR 0x02 + +// BQ32000 +#define BQ32000_ADDRESS 0x68 +// BQ32000 register addresses: +#define BQ32000_CAL_CFG1 0x07 +#define BQ32000_TCH2 0x08 +#define BQ32000_CFG2 0x09 +#define BQ32000_SFKEY1 0x20 +#define BQ32000_SFKEY2 0x21 +#define BQ32000_SFR 0x22 +// BQ32000 config bits: +#define BQ32000__OUT 0x07 // CAL_CFG1 - IRQ active state +#define BQ32000__FT 0x06 // CAL_CFG1 - IRQ square wave enable +#define BQ32000__CAL_S 0x05 // CAL_CFG1 - Calibration sign +#define BQ32000__TCH2_BIT 0x05 // TCH2 - Trickle charger switch 2 +#define BQ32000__TCFE 0x06 // CFG2 - Trickle FET control +// BQ32000 config values: +#define BQ32000_CHARGE_ENABLE 0x05 // CFG2 - Trickle charger switch 1 enable +#define BQ32000_SFKEY1_VAL 0x5E +#define BQ32000_SFKEY2_VAL 0xC7 +#define BQ32000_FTF_1HZ 0x01 +#define BQ32000_FTF_512HZ 0x00 + +#define SECONDS_PER_DAY 86400L + +// Simple general-purpose date/time class (no TZ / DST / leap second handling!) +class DateTime { +public: + DateTime (long t =0); + DateTime (uint16_t year, uint8_t month, uint8_t day, + uint8_t hour =0, uint8_t min =0, uint8_t sec =0); + DateTime (const char* date, const char* time); + + uint16_t year() const { return 2000 + yOff; } + uint8_t month() const { return m; } + uint8_t day() const { return d; } + uint8_t hour() const { return hh; } + uint8_t minute() const { return mm; } + uint8_t second() const { return ss; } + uint8_t dayOfWeek() const; + + // 32-bit times as seconds since 1/1/2000 + long get() const; + +protected: + uint8_t yOff, m, d, hh, mm, ss; +}; + +// RTC based on the DS1307 chip connected via I2C and the Wire library +class RTC_DS1307 { +public: + + // SQW/OUT frequencies. + enum Frequencies + { + Frequency_1Hz, + Frequency_4096Hz, + Frequency_8192Hz, + Frequency_32768Hz + }; + + static bool begin() { + Wire.beginTransmission(DS1307_ADDRESS); + return (Wire.endTransmission() == 0); + } + static void adjust(const DateTime& dt); + static DateTime now(); + static uint8_t isrunning(); + + // SQW/OUT functions. + void setSqwOutLevel(uint8_t level); + void setSqwOutSignal(Frequencies frequency); + + // RAM registers read/write functions. Address locations 08h to 3Fh. + // Max length = 56 bytes. + static uint8_t readByteInRam(uint8_t address); + static void readBytesInRam(uint8_t address, uint8_t length, uint8_t* p_data); + static void writeByteInRam(uint8_t address, uint8_t data); + static void writeBytesInRam(uint8_t address, uint8_t length, uint8_t* p_data); + + // utility functions + static uint8_t bcd2bin (uint8_t val) { return val - 6 * (val >> 4); } + static uint8_t bin2bcd (uint8_t val) { return val + 6 * (val / 10); } +}; + + +// DS1388 version +class RTC_DS1388 { +public: + static bool begin() { + Wire.beginTransmission(DS1388_ADDRESS); + return (Wire.endTransmission() == 0); + }; + static void adjust(const DateTime& dt); + static DateTime now(); + static uint8_t isrunning(); + + // EEPROM + static void EEPROMWrite(int pos, uint8_t c); + static uint8_t EEPROMRead(int pos); + + // utility functions + static uint8_t bcd2bin (uint8_t val) { return val - 6 * (val >> 4); } + static uint8_t bin2bcd (uint8_t val) { return val + 6 * (val / 10); } +}; + + + +// RTC based on the PCF8563 chip connected via I2C and the Wire library +// contributed by @mariusster, see http://forum.jeelabs.net/comment/1902 +class RTC_PCF8563 { +public: + static bool begin() { + Wire.beginTransmission(PCF8563_ADDRESS); + return (Wire.endTransmission() == 0); + } + static void adjust(const DateTime& dt); + static DateTime now(); + + // utility functions + static uint8_t bcd2bin (uint8_t val) { return val - 6 * (val >> 4); } + static uint8_t bin2bcd (uint8_t val) { return val + 6 * (val / 10); } +}; + + +// TI BQ32000 I2C RTC +class RTC_BQ32000 { +public: + static bool begin() { + Wire.beginTransmission(BQ32000_ADDRESS); + return (Wire.endTransmission() == 0); + } + static void adjust(const DateTime& dt); + static DateTime now(); + static uint8_t isrunning(); + + static void setIRQ(uint8_t state); + /* Set IRQ output state: 0=disabled, 1=1Hz, 2=512Hz. + */ + static void setIRQLevel(uint8_t level); + /* Set IRQ output active state to LOW or HIGH. + */ + static void setCalibration(int8_t value); + /* Sets the calibration value to given value in the range -31 - 31, which + * corresponds to -126ppm - +63ppm; see table 13 in th BQ32000 datasheet. + */ + static void setCharger(int state); + /* If using a super capacitor instead of a battery for backup power, use this + method to set the state of the trickle charger: 0=disabled, 1=low-voltage + charge, 2=high-voltage charge. In low-voltage charge mode, the super cap is + charged through a diode with a voltage drop of about 0.5V, so it will charge + up to VCC-0.5V. In high-voltage charge mode the diode is bypassed and the super + cap will be charged up to VCC (make sure the charge voltage does not exceed your + super cap's voltage rating!!). */ + + // utility functions: + static uint8_t readRegister(uint8_t address); + static uint8_t writeRegister(uint8_t address, uint8_t value); + static uint8_t bcd2bin (uint8_t val) { return val - 6 * (val >> 4); } + static uint8_t bin2bcd (uint8_t val) { return val + 6 * (val / 10); } +}; + + +// RTC using the internal millis() clock, has to be initialized before use +// NOTE: this clock won't be correct once the millis() timer rolls over (>49d?) +class RTC_Millis { +public: + static void begin(const DateTime& dt) { adjust(dt); } + static void adjust(const DateTime& dt); + static DateTime now(); + +protected: + static long offset; +}; diff --git a/lib/obp60task/obp60task.cpp b/lib/obp60task/obp60task.cpp index 4573669..fe09a1d 100644 --- a/lib/obp60task/obp60task.cpp +++ b/lib/obp60task/obp60task.cpp @@ -32,47 +32,48 @@ int taskRunCounter = 0; // Task couter for loop section void OBP60Init(GwApi *api){ api->getLogger()->logDebug(GwLog::LOG,"obp60init running"); - // Extension port MCP23017 - // Check I2C devices MCP23017 + // Check I2C devices Wire.begin(OBP_I2C_SDA, OBP_I2C_SCL); - Wire.beginTransmission(MCP23017_I2C_ADDR); + Wire.beginTransmission(DS1388_I2C_ADDR); if (Wire.endTransmission() != 0) { - api->getLogger()->logDebug(GwLog::ERROR,"MCP23017 not found, check wiring"); + api->getLogger()->logDebug(GwLog::ERROR,"DS1388 not found, check wiring"); initComplete = false; } - else{ - // Init extension port - MCP23017Init(); - - // Settings for backlight - String backlightMode = api->getConfig()->getConfigItem(api->getConfig()->backlight,true)->asString(); - api->getLogger()->logDebug(GwLog::DEBUG,"Backlight Mode is: %s", backlightMode); - if(String(backlightMode) == "On"){ - setPortPin(OBP_BACKLIGHT_LED, true); - } - if(String(backlightMode) == "Off"){ - setPortPin(OBP_BACKLIGHT_LED, false); - } - if(String(backlightMode) == "Control by Key"){ - setPortPin(OBP_BACKLIGHT_LED, false); - } - - // Settings flash LED mode - String ledMode = api->getConfig()->getConfigItem(api->getConfig()->flashLED,true)->asString(); - api->getLogger()->logDebug(GwLog::DEBUG,"Backlight Mode is: %s", ledMode); - if(String(ledMode) == "Off"){ - setBlinkingLED(false); - } - - // Marker for init complete - // Used in OBP60Task() - initComplete = true; - - // Buzzer tone for initialization finish - setBuzzerPower(uint(api->getConfig()->getConfigItem(api->getConfig()->buzzerPower,true)->asInt())); - buzzer(TONE4, 500); - + else{ + // Init code for DS1388 } + + // Init hardware + hardwareInit(); + + // Settings for backlight + String backlightMode = api->getConfig()->getConfigItem(api->getConfig()->backlight,true)->asString(); + api->getLogger()->logDebug(GwLog::DEBUG,"Backlight Mode is: %s", backlightMode); + if(String(backlightMode) == "On"){ +// setPortPin(OBP_BACKLIGHT_LED, true); + } + if(String(backlightMode) == "Off"){ +// setPortPin(OBP_BACKLIGHT_LED, false); + } + if(String(backlightMode) == "Control by Key"){ +// setPortPin(OBP_BACKLIGHT_LED, false); + } + + // Settings flash LED mode + String ledMode = api->getConfig()->getConfigItem(api->getConfig()->flashLED,true)->asString(); + api->getLogger()->logDebug(GwLog::DEBUG,"Backlight Mode is: %s", ledMode); + if(String(ledMode) == "Off"){ + setBlinkingLED(false); + } + + // Marker for init complete + // Used in OBP60Task() + initComplete = true; + + // Buzzer tone for initialization finish + setBuzzerPower(uint(api->getConfig()->getConfigItem(api->getConfig()->buzzerPower,true)->asInt())); + buzzer(TONE4, 500); + } typedef struct { diff --git a/lib/obp60task/obp60task.h b/lib/obp60task/obp60task.h index 4c7715e..19775a1 100644 --- a/lib/obp60task/obp60task.h +++ b/lib/obp60task/obp60task.h @@ -4,13 +4,13 @@ #ifdef BOARD_OBP60S3 #define USBSerial Serial // CAN NMEA2000 - #define ESP32_CAN_TX_PIN GPIO_NUM_13 - #define ESP32_CAN_RX_PIN GPIO_NUM_12 + #define ESP32_CAN_TX_PIN 46 + #define ESP32_CAN_RX_PIN 3 // Bus load in 50mA steps #define N2K_LOAD_LEVEL 5 // 5x50mA = 250mA max bus load with back light on // RS485 NMEA0183 - #define GWSERIAL_TX 26 - #define GWSERIAL_RX 14 + #define GWSERIAL_TX 17 + #define GWSERIAL_RX 8 #define GWSERIAL_MODE "UNI" // Allowed to set a new password for access point #define FORCE_AP_PWCHANGE diff --git a/lib/obp60task/platformio.ini b/lib/obp60task/platformio.ini index eda77d5..c33efdd 100644 --- a/lib/obp60task/platformio.ini +++ b/lib/obp60task/platformio.ini @@ -33,4 +33,5 @@ build_flags= ${env.build_flags} upload_port = /dev/ttyACM0 upload_protocol = esptool +upload_speed = 230400 monitor_speed = 115200 \ No newline at end of file