From 9ec8562ce7394ba7c4685d2a9790941b993d9ccd Mon Sep 17 00:00:00 2001 From: geeksville Date: Sat, 14 Mar 2020 21:21:45 -0700 Subject: [PATCH 1/6] fix old geeksville link (though github provides redirects) --- platformio.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platformio.ini b/platformio.ini index 7d4ad45ff..2ab626f1f 100644 --- a/platformio.ini +++ b/platformio.ini @@ -65,7 +65,7 @@ lib_deps = ; 1260 ; OneButton - not used yet 1202 ; CRC32, explicitly needed because dependency is missing in the ble ota update lib Wire ; explicitly needed here because the AXP202 library forgets to add it - https://github.com/geeksville/arduino-fsm.git + https://github.com/meshtastic/arduino-fsm.git https://github.com/meshtastic/SparkFun_Ublox_Arduino_Library.git ;[env:tbeam] From 74f7b7b622a6d9eab94100a855b7f6de315346dd Mon Sep 17 00:00:00 2001 From: geeksville Date: Sun, 15 Mar 2020 16:27:15 -0700 Subject: [PATCH 2/6] print extra info the next time this error occurs --- src/MeshService.cpp | 3 +++ src/mesh-pb-constants.cpp | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/MeshService.cpp b/src/MeshService.cpp index a09b80186..e874685bb 100644 --- a/src/MeshService.cpp +++ b/src/MeshService.cpp @@ -255,6 +255,9 @@ void MeshService::handleToRadio(std::string s) break; } } + else { + DEBUG_MSG("Error: ignoring malformed toradio\n"); + } } void MeshService::sendToMesh(MeshPacket *p) diff --git a/src/mesh-pb-constants.cpp b/src/mesh-pb-constants.cpp index 45a203b60..0b4f4647d 100644 --- a/src/mesh-pb-constants.cpp +++ b/src/mesh-pb-constants.cpp @@ -30,7 +30,7 @@ bool pb_decode_from_bytes(const uint8_t *srcbuf, size_t srcbufsize, const pb_msg pb_istream_t stream = pb_istream_from_buffer(srcbuf, srcbufsize); if (!pb_decode(&stream, fields, dest_struct)) { - DEBUG_MSG("Error: can't decode protobuf %s\n", PB_GET_ERROR(&stream)); + DEBUG_MSG("Error: can't decode protobuf %s, pb_msgdesc 0x%p\n", PB_GET_ERROR(&stream), fields); return false; } else From d0b8adab7509e8fadb8a981bddc58845e583e238 Mon Sep 17 00:00:00 2001 From: geeksville Date: Sun, 15 Mar 2020 16:46:28 -0700 Subject: [PATCH 3/6] In my work for #11 I accidentially created a serious bug on Heltec... devices. It caused bogus i2c transactions when device would go to sleep. Fixed now, also, I now treat GPS usage uniformly between TBEAM and HELTEC we always probe for and use the GPS if we find it. Which means for the extra nerds (someone requested this, I'm sorry - I don't remember who) you can now optionally attach an external GPS to HELTECs if you want. The pins are: #define GPS_RX_PIN 34 #define GPS_TX_PIN 12 (@girtsf, sorry about including formatting changes in this PR, apparently I had my IDE set to not autoreformat until just now --- src/GPS.cpp | 107 +++++++++++++++++++++++--------------------- src/configuration.h | 6 +-- 2 files changed, 57 insertions(+), 56 deletions(-) diff --git a/src/GPS.cpp b/src/GPS.cpp index db8418606..dd5ef82ce 100644 --- a/src/GPS.cpp +++ b/src/GPS.cpp @@ -137,72 +137,75 @@ bool GPS::canSleep() /// Prepare the GPS for the cpu entering deep or light sleep, expect to be gone for at least 100s of msecs void GPS::prepareSleep() { - ublox.powerOff(); + if (isConnected) + ublox.powerOff(); } void GPS::doTask() { #ifdef GPS_RX_PIN - // Consume all characters that have arrived - - // getPVT automatically calls checkUblox - ublox.checkUblox(); //See if new data is available. Process bytes as they come in. - - // DEBUG_MSG("sec %d\n", ublox.getSecond()); - // DEBUG_MSG("lat %d\n", ublox.getLatitude()); - - // If we don't have a fix (a quick check), don't try waiting for a solution) - uint8_t fixtype = ublox.getFixType(); - DEBUG_MSG("fix type %d\n", fixtype); - - // any fix that has time - if ((fixtype >= 2 && fixtype <= 5) && !timeSetFromGPS && ublox.getT()) + if (isConnected) { - struct timeval tv; + // Consume all characters that have arrived - isConnected = true; // We just received a packet, so we must have a GPS + // getPVT automatically calls checkUblox + ublox.checkUblox(); //See if new data is available. Process bytes as they come in. - /* Convert to unix time + // DEBUG_MSG("sec %d\n", ublox.getSecond()); + // DEBUG_MSG("lat %d\n", ublox.getLatitude()); + + // If we don't have a fix (a quick check), don't try waiting for a solution) + uint8_t fixtype = ublox.getFixType(); + DEBUG_MSG("fix type %d\n", fixtype); + + // any fix that has time + if ((fixtype >= 2 && fixtype <= 5) && !timeSetFromGPS && ublox.getT()) + { + struct timeval tv; + + isConnected = true; // We just received a packet, so we must have a GPS + + /* Convert to unix time The Unix epoch (or Unix time or POSIX time or Unix timestamp) is the number of seconds that have elapsed since January 1, 1970 (midnight UTC/GMT), not counting leap seconds (in ISO 8601: 1970-01-01T00:00:00Z). */ - struct tm t; - t.tm_sec = ublox.getSecond(); - t.tm_min = ublox.getMinute(); - t.tm_hour = ublox.getHour(); - t.tm_mday = ublox.getDay(); - t.tm_mon = ublox.getMonth() - 1; - t.tm_year = ublox.getYear() - 1900; - t.tm_isdst = false; - time_t res = mktime(&t); - tv.tv_sec = res; - tv.tv_usec = 0; // time.centisecond() * (10 / 1000); + struct tm t; + t.tm_sec = ublox.getSecond(); + t.tm_min = ublox.getMinute(); + t.tm_hour = ublox.getHour(); + t.tm_mday = ublox.getDay(); + t.tm_mon = ublox.getMonth() - 1; + t.tm_year = ublox.getYear() - 1900; + t.tm_isdst = false; + time_t res = mktime(&t); + tv.tv_sec = res; + tv.tv_usec = 0; // time.centisecond() * (10 / 1000); - DEBUG_MSG("Got time from GPS month=%d, year=%d, unixtime=%ld\n", t.tm_mon, t.tm_year, tv.tv_sec); + DEBUG_MSG("Got time from GPS month=%d, year=%d, unixtime=%ld\n", t.tm_mon, t.tm_year, tv.tv_sec); - perhapsSetRTC(&tv); - } - - if ((fixtype >= 3 && fixtype <= 4) && ublox.getP()) // rd fixes only - { - // we only notify if position has changed - isConnected = true; // We just received a packet, so we must have a GPS - - latitude = ublox.getLatitude() * 1e-7; - longitude = ublox.getLongitude() * 1e-7; - altitude = ublox.getAltitude() / 1000; // in mm convert to meters - DEBUG_MSG("new gps pos lat=%f, lon=%f, alt=%d\n", latitude, longitude, altitude); - - hasValidLocation = (latitude != 0) || (longitude != 0); // bogus lat lon is reported as 0,0 - if (hasValidLocation) - { - wantNewLocation = false; - notifyObservers(); - //ublox.powerOff(); + perhapsSetRTC(&tv); } - } - else // we didn't get a location update, go back to sleep and hope the characters show up - wantNewLocation = true; + if ((fixtype >= 3 && fixtype <= 4) && ublox.getP()) // rd fixes only + { + // we only notify if position has changed + isConnected = true; // We just received a packet, so we must have a GPS + + latitude = ublox.getLatitude() * 1e-7; + longitude = ublox.getLongitude() * 1e-7; + altitude = ublox.getAltitude() / 1000; // in mm convert to meters + DEBUG_MSG("new gps pos lat=%f, lon=%f, alt=%d\n", latitude, longitude, altitude); + + hasValidLocation = (latitude != 0) || (longitude != 0); // bogus lat lon is reported as 0,0 + if (hasValidLocation) + { + wantNewLocation = false; + notifyObservers(); + //ublox.powerOff(); + } + } + else // we didn't get a location update, go back to sleep and hope the characters show up + wantNewLocation = true; + } #endif // Once we have sent a location once we only poll the GPS rarely, otherwise check back every 1s until we have something over the serial diff --git a/src/configuration.h b/src/configuration.h index 93e3408a1..8f8286da7 100644 --- a/src/configuration.h +++ b/src/configuration.h @@ -41,8 +41,8 @@ along with this program. If not, see . // Select which board is being used. If the outside build environment has sent a choice, just use that #if !defined(T_BEAM_V10) && !defined(HELTEC_LORA32) -#define T_BEAM_V10 // AKA Rev1 (second board released) -// #define HELTEC_LORA32 +// #define T_BEAM_V10 // AKA Rev1 (second board released) +#define HELTEC_LORA32 #define HW_VERSION_US // We encode the hardware freq range in the hw version string, so sw update can eventually install the correct build #endif @@ -84,14 +84,12 @@ along with this program. If not, see . #define GPS_SERIAL_NUM 1 #define GPS_BAUDRATE 9600 -#if defined(T_BEAM_V10) #define GPS_RX_PIN 34 #ifdef USE_JTAG #define GPS_TX_PIN -1 #else #define GPS_TX_PIN 12 #endif -#endif // ----------------------------------------------------------------------------- // LoRa SPI From 30a431788d699c2dd0abecec07ee0298a15b2b98 Mon Sep 17 00:00:00 2001 From: geeksville Date: Sun, 15 Mar 2020 16:50:24 -0700 Subject: [PATCH 4/6] we now do bidirectional comms to GPS at startup, so we can always trust isConnected --- src/GPS.cpp | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/GPS.cpp b/src/GPS.cpp index dd5ef82ce..ce28f3d03 100644 --- a/src/GPS.cpp +++ b/src/GPS.cpp @@ -163,8 +163,6 @@ void GPS::doTask() { struct timeval tv; - isConnected = true; // We just received a packet, so we must have a GPS - /* Convert to unix time The Unix epoch (or Unix time or POSIX time or Unix timestamp) is the number of seconds that have elapsed since January 1, 1970 (midnight UTC/GMT), not counting leap seconds (in ISO 8601: 1970-01-01T00:00:00Z). */ @@ -188,8 +186,6 @@ void GPS::doTask() if ((fixtype >= 3 && fixtype <= 4) && ublox.getP()) // rd fixes only { // we only notify if position has changed - isConnected = true; // We just received a packet, so we must have a GPS - latitude = ublox.getLatitude() * 1e-7; longitude = ublox.getLongitude() * 1e-7; altitude = ublox.getAltitude() / 1000; // in mm convert to meters From 5037fb830ef9dc4c4792c08f61e1e583d722b912 Mon Sep 17 00:00:00 2001 From: geeksville Date: Sun, 15 Mar 2020 17:50:48 -0700 Subject: [PATCH 5/6] fix build (and autoformat in visual studio code) --- src/lock.h | 47 +++++++++++++++++++++++------------------------ 1 file changed, 23 insertions(+), 24 deletions(-) diff --git a/src/lock.h b/src/lock.h index bffaeee37..2d9c26a3b 100644 --- a/src/lock.h +++ b/src/lock.h @@ -1,7 +1,7 @@ #pragma once -#include -#include +#include +#include namespace meshtastic { @@ -9,39 +9,38 @@ namespace meshtastic // Simple wrapper around FreeRTOS API for implementing a mutex lock. class Lock { - public: - Lock(); +public: + Lock(); - Lock(const Lock&) = delete; - Lock& operator=(const Lock&) = delete; + Lock(const Lock &) = delete; + Lock &operator=(const Lock &) = delete; - /// Locks the lock. - // - // Must not be called from an ISR. - void lock(); + /// Locks the lock. + // + // Must not be called from an ISR. + void lock(); - // Unlocks the lock. - // - // Must not be called from an ISR. - void unlock(); + // Unlocks the lock. + // + // Must not be called from an ISR. + void unlock(); - private: - SemaphoreHandle_t handle; +private: + SemaphoreHandle_t handle; }; // RAII lock guard. class LockGuard { - public: - LockGuard(Lock *lock); - ~LockGuard(); +public: + LockGuard(Lock *lock); + ~LockGuard(); - LockGuard(const LockGuard&) = delete; - LockGuard& operator=(const LockGuard&) = delete; + LockGuard(const LockGuard &) = delete; + LockGuard &operator=(const LockGuard &) = delete; - private: - Lock* lock; +private: + Lock *lock; }; - } // namespace meshtastic From 24ac907780ddae6f8731756652c04739bda838d2 Mon Sep 17 00:00:00 2001 From: geeksville Date: Sun, 15 Mar 2020 17:51:57 -0700 Subject: [PATCH 6/6] auto generate channel numbers from name NOTE: All radios on a channel will need to be updated to this release before they can talk together again. --- proto | 2 +- src/MeshRadio.cpp | 26 +++++++++++++++++++------- src/mesh.pb.h | 13 +++++-------- 3 files changed, 25 insertions(+), 16 deletions(-) diff --git a/proto b/proto index 66e926740..398fdf362 160000 --- a/proto +++ b/proto @@ -1 +1 @@ -Subproject commit 66e926740acb30518d1fdcb901d1cc0b0d48122c +Subproject commit 398fdf362518e9d6869247cef09f2e071b715639 diff --git a/src/MeshRadio.cpp b/src/MeshRadio.cpp index 3c1d79fa9..c4d51d5d7 100644 --- a/src/MeshRadio.cpp +++ b/src/MeshRadio.cpp @@ -9,8 +9,6 @@ #include "configuration.h" #include "NodeDB.h" -#define DEFAULT_CHANNEL_NUM 3 // we randomly pick one - /// 16 bytes of random PSK for our _public_ default channel that all devices power up on static const uint8_t defaultpsk[] = {0xd4, 0xf1, 0xbb, 0x3a, 0x20, 0x29, 0x07, 0x59, 0xf0, 0xbc, 0xff, 0xab, 0xcf, 0x4e, 0x69, 0xbf}; @@ -39,7 +37,6 @@ MeshRadio::MeshRadio(MemoryPool &_pool, PointerQueue &_r channelSettings.modem_config = ChannelSettings_ModemConfig_Bw125Cr48Sf4096; // slow and long range channelSettings.tx_power = 23; - channelSettings.channel_num = DEFAULT_CHANNEL_NUM; memcpy(&channelSettings.psk, &defaultpsk, sizeof(channelSettings.psk)); strcpy(channelSettings.name, "Default"); // Can't print strings this early - serial not setup yet @@ -81,6 +78,22 @@ bool MeshRadio::init() return true; } +/** hash a string into an integer + * + * djb2 by Dan Bernstein. + * http://www.cse.yorku.ca/~oz/hash.html + */ +unsigned long hash(char *str) +{ + unsigned long hash = 5381; + int c; + + while ((c = *str++) != 0) + hash = ((hash << 5) + hash) + (unsigned char)c; /* hash * 33 + c */ + + return hash; +} + void MeshRadio::reloadConfig() { rf95.setModeIdle(); // Need to be idle before doing init @@ -91,10 +104,9 @@ void MeshRadio::reloadConfig() // setModemConfig(Bw125Cr48Sf4096); // slow and reliable? // rf95.setPreambleLength(8); // Default is 8 - assert(channelSettings.channel_num < NUM_CHANNELS); // If the phone tries to tell us to use an illegal channel then panic - // Defaults after init are 434.0MHz, modulation GFSK_Rb250Fd250, +13dbM - float center_freq = CH0 + CH_SPACING * channelSettings.channel_num; + int channel_num = hash(channelSettings.name) % NUM_CHANNELS; + float center_freq = CH0 + CH_SPACING * channel_num; if (!rf95.setFrequency(center_freq)) { DEBUG_MSG("setFrequency failed\n"); @@ -109,7 +121,7 @@ void MeshRadio::reloadConfig() // FIXME - can we do this? It seems to be in the Heltec board. rf95.setTxPower(channelSettings.tx_power, false); - DEBUG_MSG("Set radio: name=%s. config=%u, ch=%d, txpower=%d\n", channelSettings.name, channelSettings.modem_config, channelSettings.channel_num, channelSettings.tx_power); + DEBUG_MSG("Set radio: name=%s. config=%u, ch=%d, txpower=%d\n", channelSettings.name, channelSettings.modem_config, channel_num, channelSettings.tx_power); // Done with init tell radio to start receiving rf95.setModeRx(); diff --git a/src/mesh.pb.h b/src/mesh.pb.h index 2422659ef..d1a613ca3 100644 --- a/src/mesh.pb.h +++ b/src/mesh.pb.h @@ -34,7 +34,6 @@ typedef enum _ChannelSettings_ModemConfig { /* Struct definitions */ typedef struct _ChannelSettings { int32_t tx_power; - uint32_t channel_num; ChannelSettings_ModemConfig modem_config; pb_byte_t psk[16]; char name[12]; @@ -173,7 +172,7 @@ typedef struct _ToRadio { #define User_init_default {"", "", "", {0}} #define SubPacket_init_default {0, {Position_init_default}, 0} #define MeshPacket_init_default {0, 0, false, SubPacket_init_default, 0} -#define ChannelSettings_init_default {0, 0, _ChannelSettings_ModemConfig_MIN, {0}, ""} +#define ChannelSettings_init_default {0, _ChannelSettings_ModemConfig_MIN, {0}, ""} #define RadioConfig_init_default {false, RadioConfig_UserPreferences_init_default, false, ChannelSettings_init_default} #define RadioConfig_UserPreferences_init_default {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} #define NodeInfo_init_default {0, false, User_init_default, false, Position_init_default, 0, 0} @@ -186,7 +185,7 @@ typedef struct _ToRadio { #define User_init_zero {"", "", "", {0}} #define SubPacket_init_zero {0, {Position_init_zero}, 0} #define MeshPacket_init_zero {0, 0, false, SubPacket_init_zero, 0} -#define ChannelSettings_init_zero {0, 0, _ChannelSettings_ModemConfig_MIN, {0}, ""} +#define ChannelSettings_init_zero {0, _ChannelSettings_ModemConfig_MIN, {0}, ""} #define RadioConfig_init_zero {false, RadioConfig_UserPreferences_init_zero, false, ChannelSettings_init_zero} #define RadioConfig_UserPreferences_init_zero {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} #define NodeInfo_init_zero {0, false, User_init_zero, false, Position_init_zero, 0, 0} @@ -197,7 +196,6 @@ typedef struct _ToRadio { /* Field tags (for use in manual encoding/decoding) */ #define ChannelSettings_tx_power_tag 1 -#define ChannelSettings_channel_num_tag 2 #define ChannelSettings_modem_config_tag 3 #define ChannelSettings_psk_tag 4 #define ChannelSettings_name_tag 5 @@ -303,7 +301,6 @@ X(a, STATIC, SINGULAR, UINT32, rx_time, 4) #define ChannelSettings_FIELDLIST(X, a) \ X(a, STATIC, SINGULAR, INT32, tx_power, 1) \ -X(a, STATIC, SINGULAR, UINT32, channel_num, 2) \ X(a, STATIC, SINGULAR, UENUM, modem_config, 3) \ X(a, STATIC, SINGULAR, FIXED_LENGTH_BYTES, psk, 4) \ X(a, STATIC, SINGULAR, STRING, name, 5) @@ -421,12 +418,12 @@ extern const pb_msgdesc_t ToRadio_msg; #define User_size 72 #define SubPacket_size 261 #define MeshPacket_size 292 -#define ChannelSettings_size 50 -#define RadioConfig_size 126 +#define ChannelSettings_size 44 +#define RadioConfig_size 120 #define RadioConfig_UserPreferences_size 72 #define NodeInfo_size 155 #define MyNodeInfo_size 63 -#define DeviceState_size 15064 +#define DeviceState_size 15058 #define FromRadio_size 301 #define ToRadio_size 295