From 09d48f659ebe535c71a17f37ca6e1125496fbd1d Mon Sep 17 00:00:00 2001 From: Ben Meadors Date: Sat, 6 May 2023 07:17:40 -0500 Subject: [PATCH 1/4] RAK14001 RGB LED support (#2464) * WIP * WIP * Moved it * More random strobey behavior * Guard to RAK4630 devices for now * Oops * Ship it --- src/configuration.h | 5 +++ src/detect/ScanI2C.h | 1 + src/detect/ScanI2CTwoWire.cpp | 1 + src/main.cpp | 4 ++ src/main.h | 1 + src/modules/ExternalNotificationModule.cpp | 42 ++++++++++++++++++- variants/rak4631/platformio.ini | 1 + variants/rak4631_epaper/platformio.ini | 1 + variants/rak4631_epaper_onrxtx/platformio.ini | 1 + 9 files changed, 56 insertions(+), 1 deletion(-) diff --git a/src/configuration.h b/src/configuration.h index 58e41877d..e1420c8db 100644 --- a/src/configuration.h +++ b/src/configuration.h @@ -124,6 +124,11 @@ along with this program. If not, see . #define MPU6050_ADDR 0x68 #define LIS3DH_ADR 0x18 +// ----------------------------------------------------------------------------- +// LED +// ----------------------------------------------------------------------------- +#define NCP5623_ADDR 0x38 + // ----------------------------------------------------------------------------- // Security // ----------------------------------------------------------------------------- diff --git a/src/detect/ScanI2C.h b/src/detect/ScanI2C.h index 01b300c10..a56ce86fe 100644 --- a/src/detect/ScanI2C.h +++ b/src/detect/ScanI2C.h @@ -33,6 +33,7 @@ class ScanI2C PMSA0031, MPU6050, LIS3DH, + NCP5623, } DeviceType; // typedef uint8_t DeviceAddress; diff --git a/src/detect/ScanI2CTwoWire.cpp b/src/detect/ScanI2CTwoWire.cpp index fb568b552..b7f16734f 100644 --- a/src/detect/ScanI2CTwoWire.cpp +++ b/src/detect/ScanI2CTwoWire.cpp @@ -213,6 +213,7 @@ void ScanI2CTwoWire::scanPort(I2CPort port) break; SCAN_SIMPLE_CASE(ST7567_ADDRESS, SCREEN_ST7567, "st7567 display found\n") + SCAN_SIMPLE_CASE(NCP5623_ADDR, NCP5623, "NCP5623 RGB LED found\n"); #ifdef HAS_PMU SCAN_SIMPLE_CASE(XPOWERS_AXP192_AXP2101_ADDRESS, PMU_AXP192_AXP2101, "axp192/axp2101 PMU found\n") diff --git a/src/main.cpp b/src/main.cpp index e42c190df..b1a21e942 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -100,6 +100,8 @@ uint8_t kb_model; ScanI2C::DeviceAddress rtc_found = ScanI2C::ADDRESS_NONE; // The I2C address of the Accelerometer (if found) ScanI2C::DeviceAddress accelerometer_found = ScanI2C::ADDRESS_NONE; +// The I2C address of the RGB LED (if found) +ScanI2C::FoundDevice rgb_found = ScanI2C::FoundDevice(ScanI2C::DeviceType::NONE, ScanI2C::ADDRESS_NONE); #if !defined(ARCH_PORTDUINO) && !defined(ARCH_STM32WL) ATECCX08A atecc; @@ -344,6 +346,8 @@ void setup() * nodeTelemetrySensorsMap singleton. This wraps that logic in a temporary scope to declare the temporary field * "found". */ + // Only one supported RGB LED currently + rgb_found = i2cScanner->find(ScanI2C::DeviceType::NCP5623); #if !defined(ARCH_PORTDUINO) auto acc_info = i2cScanner->firstAccelerometer(); diff --git a/src/main.h b/src/main.h index 645ba2ee2..5707e3bc5 100644 --- a/src/main.h +++ b/src/main.h @@ -26,6 +26,7 @@ extern ScanI2C::DeviceAddress cardkb_found; extern uint8_t kb_model; extern ScanI2C::DeviceAddress rtc_found; extern ScanI2C::DeviceAddress accelerometer_found; +extern ScanI2C::FoundDevice rgb_found; extern bool eink_found; extern bool pmu_found; diff --git a/src/modules/ExternalNotificationModule.cpp b/src/modules/ExternalNotificationModule.cpp index 3c931f3e2..7dbf78a08 100644 --- a/src/modules/ExternalNotificationModule.cpp +++ b/src/modules/ExternalNotificationModule.cpp @@ -8,6 +8,17 @@ #include "mesh/generated/meshtastic/rtttl.pb.h" #include +#include "main.h" + +#ifdef RAK4630 +#include +NCP5623 rgb; + +uint8_t red = 0; +uint8_t green = 0; +uint8_t blue = 0; +#endif + #ifndef PIN_BUZZER #define PIN_BUZZER false #endif @@ -73,6 +84,15 @@ int32_t ExternalNotificationModule::runOnce() millis()) { getExternal(2) ? setExternalOff(2) : setExternalOn(2); } +#ifdef RAK4630 + if (rgb_found.type == ScanI2C::NCP5623) { + green = (green + 50) % 255; + red = abs(red - green) % 255; + blue = abs(blue / red) % 255; + + rgb.setColor(red, green, blue); + } +#endif } // now let the PWM buzzer play @@ -84,6 +104,7 @@ int32_t ExternalNotificationModule::runOnce() rtttl::begin(config.device.buzzer_gpio, rtttlConfig.ringtone); } } + return 25; } } @@ -106,6 +127,11 @@ void ExternalNotificationModule::setExternalOn(uint8_t index) digitalWrite(output, (moduleConfig.external_notification.active ? true : false)); break; } +#ifdef RAK4630 + if (rgb_found.type == ScanI2C::NCP5623) { + rgb.setColor(red, green, blue); + } +#endif } void ExternalNotificationModule::setExternalOff(uint8_t index) @@ -126,6 +152,15 @@ void ExternalNotificationModule::setExternalOff(uint8_t index) digitalWrite(output, (moduleConfig.external_notification.active ? false : true)); break; } + +#ifdef RAK4630 + if (rgb_found.type == ScanI2C::NCP5623) { + red = 0; + green = 0; + blue = 0; + rgb.setColor(red, green, blue); + } +#endif } bool ExternalNotificationModule::getExternal(uint8_t index) @@ -200,6 +235,12 @@ ExternalNotificationModule::ExternalNotificationModule() LOG_INFO("Using Pin %i in PWM mode\n", config.device.buzzer_gpio); } } +#ifdef RAK4630 + if (rgb_found.type == ScanI2C::NCP5623) { + rgb.begin(); + rgb.setCurrent(10); + } +#endif } else { LOG_INFO("External Notification Module Disabled\n"); disable(); @@ -300,7 +341,6 @@ ProcessMessage ExternalNotificationModule::handleReceived(const meshtastic_MeshP nagCycleCutoff = millis() + moduleConfig.external_notification.output_ms; } } - setIntervalFromNow(0); // run once so we know if we should do something } diff --git a/variants/rak4631/platformio.ini b/variants/rak4631/platformio.ini index a0928605f..0d1f17d91 100644 --- a/variants/rak4631/platformio.ini +++ b/variants/rak4631/platformio.ini @@ -9,6 +9,7 @@ lib_deps = ${networking_base.lib_deps} melopero/Melopero RV3028@^1.1.0 https://github.com/RAKWireless/RAK13800-W5100S.git#1.0.2 + rakwireless/RAKwireless NCP5623 RGB LED library@^1.0.2 debug_tool = jlink ; If not set we will default to uploading over serial (first it forces bootloader entry by talking 1200bps to cdcacm) ;upload_protocol = jlink \ No newline at end of file diff --git a/variants/rak4631_epaper/platformio.ini b/variants/rak4631_epaper/platformio.ini index fd266c07f..e9c3e8723 100644 --- a/variants/rak4631_epaper/platformio.ini +++ b/variants/rak4631_epaper/platformio.ini @@ -8,6 +8,7 @@ lib_deps = ${nrf52840_base.lib_deps} zinggjm/GxEPD2@^1.4.9 melopero/Melopero RV3028@^1.1.0 + rakwireless/RAKwireless NCP5623 RGB LED library@^1.0.2 debug_tool = jlink ; If not set we will default to uploading over serial (first it forces bootloader entry by talking 1200bps to cdcacm) ;upload_protocol = jlink \ No newline at end of file diff --git a/variants/rak4631_epaper_onrxtx/platformio.ini b/variants/rak4631_epaper_onrxtx/platformio.ini index 920380011..6e922b841 100644 --- a/variants/rak4631_epaper_onrxtx/platformio.ini +++ b/variants/rak4631_epaper_onrxtx/platformio.ini @@ -10,6 +10,7 @@ lib_deps = ${nrf52840_base.lib_deps} zinggjm/GxEPD2@^1.5.1 melopero/Melopero RV3028@^1.1.0 + rakwireless/RAKwireless NCP5623 RGB LED library@^1.0.2 debug_tool = jlink ; If not set we will default to uploading over serial (first it forces bootloader entry by talking 1200bps to cdcacm) ;upload_protocol = jlink From 694fd04367c0fc0aa4c8f67669047d8d8b361d11 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20G=C3=B6ttgens?= Date: Thu, 4 May 2023 11:04:43 +0200 Subject: [PATCH 2/4] probably fixes #2451 - please test --- src/gps/NMEAWPL.cpp | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/src/gps/NMEAWPL.cpp b/src/gps/NMEAWPL.cpp index 6ab2c85bf..41ebab72c 100644 --- a/src/gps/NMEAWPL.cpp +++ b/src/gps/NMEAWPL.cpp @@ -1,5 +1,6 @@ #include "NMEAWPL.h" #include "GeoCoord.h" +#include /* ------------------------------------------- * 1 2 3 4 5 6 @@ -56,12 +57,14 @@ uint32_t printWPL(char *buf, size_t bufsz, const meshtastic_Position &pos, const uint32_t printGGA(char *buf, size_t bufsz, const meshtastic_Position &pos) { GeoCoord geoCoord(pos.latitude_i, pos.longitude_i, pos.altitude); - uint32_t len = - snprintf(buf, bufsz, "$GNGGA,%06u.%03u,%02d%07.4f,%c,%03d%07.4f,%c,%u,%02u,%04u,%04d,%c,%04d,%c,%d,%04d", pos.time / 1000, - pos.time % 1000, geoCoord.getDMSLatDeg(), (abs(geoCoord.getLatitude()) - geoCoord.getDMSLatDeg() * 1e+7) * 6e-6, - geoCoord.getDMSLatCP(), geoCoord.getDMSLonDeg(), - (abs(geoCoord.getLongitude()) - geoCoord.getDMSLonDeg() * 1e+7) * 6e-6, geoCoord.getDMSLonCP(), pos.fix_type, - pos.sats_in_view, pos.HDOP, geoCoord.getAltitude(), 'M', pos.altitude_geoidal_separation, 'M', 0, 0); + tm *t = localtime((time_t *)&pos.timestamp); + + uint32_t len = snprintf( + buf, bufsz, "$GNGGA,%02d%02d%02d.%02d,%02d%07.4f,%c,%03d%07.4f,%c,%u,%02u,%04u,%04d,%c,%04d,%c,%d,%04d", t->tm_hour, + t->tm_min, t->tm_sec, pos.timestamp_millis_adjust, geoCoord.getDMSLatDeg(), + (abs(geoCoord.getLatitude()) - geoCoord.getDMSLatDeg() * 1e+7) * 6e-6, geoCoord.getDMSLatCP(), geoCoord.getDMSLonDeg(), + (abs(geoCoord.getLongitude()) - geoCoord.getDMSLonDeg() * 1e+7) * 6e-6, geoCoord.getDMSLonCP(), pos.fix_type, + pos.sats_in_view, pos.HDOP, geoCoord.getAltitude(), 'M', pos.altitude_geoidal_separation, 'M', 0, 0); uint32_t chk = 0; for (uint32_t i = 1; i < len; i++) { From e1c4968c58e60cdf20d4023972b0f0bb16e3c68a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20G=C3=B6ttgens?= Date: Fri, 5 May 2023 09:44:18 +0200 Subject: [PATCH 3/4] wrong datapoint --- src/gps/NMEAWPL.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gps/NMEAWPL.cpp b/src/gps/NMEAWPL.cpp index 41ebab72c..70d3d22cb 100644 --- a/src/gps/NMEAWPL.cpp +++ b/src/gps/NMEAWPL.cpp @@ -63,7 +63,7 @@ uint32_t printGGA(char *buf, size_t bufsz, const meshtastic_Position &pos) buf, bufsz, "$GNGGA,%02d%02d%02d.%02d,%02d%07.4f,%c,%03d%07.4f,%c,%u,%02u,%04u,%04d,%c,%04d,%c,%d,%04d", t->tm_hour, t->tm_min, t->tm_sec, pos.timestamp_millis_adjust, geoCoord.getDMSLatDeg(), (abs(geoCoord.getLatitude()) - geoCoord.getDMSLatDeg() * 1e+7) * 6e-6, geoCoord.getDMSLatCP(), geoCoord.getDMSLonDeg(), - (abs(geoCoord.getLongitude()) - geoCoord.getDMSLonDeg() * 1e+7) * 6e-6, geoCoord.getDMSLonCP(), pos.fix_type, + (abs(geoCoord.getLongitude()) - geoCoord.getDMSLonDeg() * 1e+7) * 6e-6, geoCoord.getDMSLonCP(), pos.fix_quality, pos.sats_in_view, pos.HDOP, geoCoord.getAltitude(), 'M', pos.altitude_geoidal_separation, 'M', 0, 0); uint32_t chk = 0; From 9b6ac98ae0d41023e1d8ccb517098d0fa601cdaa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20G=C3=B6ttgens?= Date: Sat, 6 May 2023 18:10:00 +0200 Subject: [PATCH 4/4] use the device time, only use gps timestamp as a fallback. --- src/gps/NMEAWPL.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/gps/NMEAWPL.cpp b/src/gps/NMEAWPL.cpp index 70d3d22cb..902ba4c95 100644 --- a/src/gps/NMEAWPL.cpp +++ b/src/gps/NMEAWPL.cpp @@ -1,6 +1,7 @@ #include "NMEAWPL.h" #include "GeoCoord.h" #include +#include "RTC.h" /* ------------------------------------------- * 1 2 3 4 5 6 @@ -58,6 +59,9 @@ uint32_t printGGA(char *buf, size_t bufsz, const meshtastic_Position &pos) { GeoCoord geoCoord(pos.latitude_i, pos.longitude_i, pos.altitude); tm *t = localtime((time_t *)&pos.timestamp); + if (getRTCQuality() > 0) // use the device clock if we got time from somewhere. If not, use the GPS timestamp. + t = localtime((time_t *)getValidTime(RTCQuality::RTCQualityDevice)); + uint32_t len = snprintf( buf, bufsz, "$GNGGA,%02d%02d%02d.%02d,%02d%07.4f,%c,%03d%07.4f,%c,%u,%02u,%04u,%04d,%c,%04d,%c,%d,%04d", t->tm_hour,