Merge pull request #345 from geeksville/post1

update from master
This commit is contained in:
Kevin Hester 2020-08-27 14:56:28 -07:00 committed by GitHub
commit 8eb492d356
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 172 additions and 160 deletions

View File

@ -1,3 +1,3 @@
export VERSION=0.9.2 export VERSION=0.9.3

Binary file not shown.

BIN
docs/hardware/T-SX1262.pdf Normal file

Binary file not shown.

View File

@ -16,6 +16,8 @@ bool pmu_irq = false;
Power *power; Power *power;
using namespace meshtastic;
/** /**
* If this board has a battery level sensor, set this to a valid implementation * If this board has a battery level sensor, set this to a valid implementation
*/ */
@ -36,7 +38,7 @@ class AnalogBatteryLevel : public HasBatteryLevel
float v = getBattVoltage() / 1000; float v = getBattVoltage() / 1000;
if (v < 2.1) if (v < 2.1)
return -1; return -1; // If voltage is super low assume no battery installed
return 100 * (v - 3.27) / (4.2 - 3.27); return 100 * (v - 3.27) / (4.2 - 3.27);
} }
@ -57,7 +59,7 @@ class AnalogBatteryLevel : public HasBatteryLevel
/** /**
* return true if there is a battery installed in this unit * return true if there is a battery installed in this unit
*/ */
virtual bool isBatteryConnect() { return true; } virtual bool isBatteryConnect() { return getBattVoltage() != -1; }
} analogLevel; } analogLevel;
bool Power::analogInit() bool Power::analogInit()
@ -97,7 +99,7 @@ void Power::readPowerStatus()
if (batteryLevel) { if (batteryLevel) {
bool hasBattery = batteryLevel->isBatteryConnect(); bool hasBattery = batteryLevel->isBatteryConnect();
int batteryVoltageMv = 0; int batteryVoltageMv = 0;
uint8_t batteryChargePercent = 0; int8_t batteryChargePercent = 0;
if (hasBattery) { if (hasBattery) {
batteryVoltageMv = batteryLevel->getBattVoltage(); batteryVoltageMv = batteryLevel->getBattVoltage();
// If the AXP192 returns a valid battery percentage, use it // If the AXP192 returns a valid battery percentage, use it
@ -114,13 +116,18 @@ void Power::readPowerStatus()
} }
// Notify any status instances that are observing us // Notify any status instances that are observing us
const meshtastic::PowerStatus powerStatus = meshtastic::PowerStatus( const PowerStatus powerStatus =
hasBattery, batteryLevel->isVBUSPlug(), batteryLevel->isChargeing(), batteryVoltageMv, batteryChargePercent); PowerStatus(hasBattery ? OptTrue : OptFalse, batteryLevel->isVBUSPlug() ? OptTrue : OptFalse,
batteryLevel->isChargeing() ? OptTrue : OptFalse, batteryVoltageMv, batteryChargePercent);
newStatus.notifyObservers(&powerStatus); newStatus.notifyObservers(&powerStatus);
// If we have a battery at all and it is less than 10% full, force deep sleep // If we have a battery at all and it is less than 10% full, force deep sleep
if (powerStatus.getHasBattery() && !powerStatus.getHasUSB() && batteryLevel->getBattVoltage() < MIN_BAT_MILLIVOLTS) if (powerStatus.getHasBattery() && !powerStatus.getHasUSB() && batteryLevel->getBattVoltage() < MIN_BAT_MILLIVOLTS)
powerFSM.trigger(EVENT_LOW_BATTERY); powerFSM.trigger(EVENT_LOW_BATTERY);
} else {
// No power sensing on this board - tell everyone else we have no idea what is happening
const PowerStatus powerStatus = PowerStatus(OptUnknown, OptUnknown, OptUnknown, -1, -1);
newStatus.notifyObservers(&powerStatus);
} }
} }

View File

@ -1,34 +1,40 @@
#pragma once #pragma once
#include <Arduino.h>
#include "Status.h" #include "Status.h"
#include "configuration.h" #include "configuration.h"
#include <Arduino.h>
namespace meshtastic { namespace meshtastic
{
/// Describes the state of the GPS system. /**
class PowerStatus : public Status * A boolean where we have a third state of Unknown
{ */
enum OptionalBool { OptFalse = 0, OptTrue = 1, OptUnknown = 2 };
/// Describes the state of the GPS system.
class PowerStatus : public Status
{
private: private:
CallbackObserver<PowerStatus, const PowerStatus *> statusObserver = CallbackObserver<PowerStatus, const PowerStatus *>(this, &PowerStatus::updateStatus); CallbackObserver<PowerStatus, const PowerStatus *> statusObserver =
CallbackObserver<PowerStatus, const PowerStatus *>(this, &PowerStatus::updateStatus);
/// Whether we have a battery connected /// Whether we have a battery connected
bool hasBattery; OptionalBool hasBattery = OptUnknown;
/// Battery voltage in mV, valid if haveBattery is true /// Battery voltage in mV, valid if haveBattery is true
int batteryVoltageMv; int batteryVoltageMv = 0;
/// Battery charge percentage, either read directly or estimated /// Battery charge percentage, either read directly or estimated
uint8_t batteryChargePercent; int8_t batteryChargePercent = 0;
/// Whether USB is connected /// Whether USB is connected
bool hasUSB; OptionalBool hasUSB = OptUnknown;
/// Whether we are charging the battery /// Whether we are charging the battery
bool isCharging; OptionalBool isCharging = OptUnknown;
public: public:
PowerStatus() { statusType = STATUS_TYPE_POWER; }
PowerStatus() { PowerStatus(OptionalBool hasBattery, OptionalBool hasUSB, OptionalBool isCharging, int batteryVoltageMv = -1,
statusType = STATUS_TYPE_POWER; int8_t batteryChargePercent = 0)
} : Status()
PowerStatus( bool hasBattery, bool hasUSB, bool isCharging, int batteryVoltageMv, uint8_t batteryChargePercent ) : Status()
{ {
this->hasBattery = hasBattery; this->hasBattery = hasBattery;
this->hasUSB = hasUSB; this->hasUSB = hasUSB;
@ -39,65 +45,50 @@ namespace meshtastic {
PowerStatus(const PowerStatus &); PowerStatus(const PowerStatus &);
PowerStatus &operator=(const PowerStatus &); PowerStatus &operator=(const PowerStatus &);
void observe(Observable<const PowerStatus *> *source) void observe(Observable<const PowerStatus *> *source) { statusObserver.observe(source); }
{
statusObserver.observe(source);
}
bool getHasBattery() const bool getHasBattery() const { return hasBattery == OptTrue; }
{
return hasBattery;
}
bool getHasUSB() const bool getHasUSB() const { return hasUSB == OptTrue; }
{
return hasUSB;
}
bool getIsCharging() const /// Can we even know if this board has USB power or not
{ bool knowsUSB() const { return hasUSB != OptUnknown; }
return isCharging;
}
int getBatteryVoltageMv() const bool getIsCharging() const { return isCharging == OptTrue; }
{
return batteryVoltageMv;
}
uint8_t getBatteryChargePercent() const int getBatteryVoltageMv() const { return batteryVoltageMv; }
{
return batteryChargePercent; /**
} * Note: 0% battery means 'unknown/this board doesn't have a battery installed'
*/
uint8_t getBatteryChargePercent() const { return getHasBattery() ? batteryChargePercent : 0; }
bool matches(const PowerStatus *newStatus) const bool matches(const PowerStatus *newStatus) const
{ {
return ( return (newStatus->getHasBattery() != hasBattery || newStatus->getHasUSB() != hasUSB ||
newStatus->getHasBattery() != hasBattery || newStatus->getBatteryVoltageMv() != batteryVoltageMv);
newStatus->getHasUSB() != hasUSB ||
newStatus->getBatteryVoltageMv() != batteryVoltageMv
);
} }
int updateStatus(const PowerStatus *newStatus) { int updateStatus(const PowerStatus *newStatus)
{
// Only update the status if values have actually changed // Only update the status if values have actually changed
bool isDirty; bool isDirty;
{ {
isDirty = matches(newStatus); isDirty = matches(newStatus);
initialized = true; initialized = true;
hasBattery = newStatus->getHasBattery(); hasBattery = newStatus->hasBattery;
batteryVoltageMv = newStatus->getBatteryVoltageMv(); batteryVoltageMv = newStatus->getBatteryVoltageMv();
batteryChargePercent = newStatus->getBatteryChargePercent(); batteryChargePercent = newStatus->getBatteryChargePercent();
hasUSB = newStatus->getHasUSB(); hasUSB = newStatus->hasUSB;
isCharging = newStatus->getIsCharging(); isCharging = newStatus->isCharging;
} }
if(isDirty) { if (isDirty) {
DEBUG_MSG("Battery %dmV %d%%\n", batteryVoltageMv, batteryChargePercent); DEBUG_MSG("Battery %dmV %d%%\n", batteryVoltageMv, batteryChargePercent);
onNewStatus.notifyObservers(this); onNewStatus.notifyObservers(this);
} }
return 0; return 0;
} }
};
}; } // namespace meshtastic
}
extern meshtastic::PowerStatus *powerStatus; extern meshtastic::PowerStatus *powerStatus;

View File

@ -20,7 +20,7 @@ namespace meshtastic
CallbackObserver<Status, const Status *> statusObserver = CallbackObserver<Status, const Status *>(this, &Status::updateStatus); CallbackObserver<Status, const Status *> statusObserver = CallbackObserver<Status, const Status *>(this, &Status::updateStatus);
bool initialized = false; bool initialized = false;
// Workaround for no typeid support // Workaround for no typeid support
int statusType; int statusType = 0;
public: public:
// Allows us to generate observable events // Allows us to generate observable events

View File

@ -309,6 +309,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#define BUTTON_PIN \ #define BUTTON_PIN \
12 // If defined, this will be used for user button presses, if your board doesn't have a physical switch, you can wire one 12 // If defined, this will be used for user button presses, if your board doesn't have a physical switch, you can wire one
// between this pin and ground // between this pin and ground
#define BUTTON_NEED_PULLUP
#define USE_RF95 #define USE_RF95
#define LORA_DIO0 26 // a No connect on the SX1262 module #define LORA_DIO0 26 // a No connect on the SX1262 module

View File

@ -102,8 +102,13 @@ bool UBloxGPS::factoryReset()
// It is useful to force back into factory defaults (9600baud, NEMA to test the behavior of boards that don't have // It is useful to force back into factory defaults (9600baud, NEMA to test the behavior of boards that don't have
// GPS_TX connected) // GPS_TX connected)
ublox.factoryReset(); ublox.factoryReset();
delay(3000); delay(5000);
tryConnect(); // sets isConnected tryConnect(); // sets isConnected
// try a second time, the ublox lib serial parsing is buggy?
if (!tryConnect())
tryConnect();
DEBUG_MSG("GPS Factory reset success=%d\n", isConnected); DEBUG_MSG("GPS Factory reset success=%d\n", isConnected);
if (isConnected) if (isConnected)
ok = setUBXMode(); ok = setUBXMode();
@ -122,12 +127,11 @@ int UBloxGPS::prepareSleep(void *unused)
void UBloxGPS::doTask() void UBloxGPS::doTask()
{ {
uint8_t fixtype = 3; // If we are only using the RX pin, assume we have a 3d fix if (isConnected) {
assert(isConnected);
// Consume all characters that have arrived // Consume all characters that have arrived
uint8_t fixtype = 3; // If we are only using the RX pin, assume we have a 3d fix
// if using i2c or serial look too see if any chars are ready // if using i2c or serial look too see if any chars are ready
ublox.checkUblox(); // See if new data is available. Process bytes as they come in. ublox.checkUblox(); // See if new data is available. Process bytes as they come in.
@ -145,9 +149,9 @@ void UBloxGPS::doTask()
if (ublox.getT(maxWait)) { if (ublox.getT(maxWait)) {
/* Convert to unix time /* 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 The Unix epoch (or Unix time or POSIX time or Unix timestamp) is the number of seconds that have elapsed since January
(midnight UTC/GMT), not counting leap seconds (in ISO 8601: 1970-01-01T00:00:00Z). 1, 1970 (midnight UTC/GMT), not counting leap seconds (in ISO 8601: 1970-01-01T00:00:00Z).
*/ */
struct tm t; struct tm t;
t.tm_sec = ublox.getSecond(0); t.tm_sec = ublox.getSecond(0);
t.tm_min = ublox.getMinute(0); t.tm_min = ublox.getMinute(0);
@ -185,9 +189,10 @@ The Unix epoch (or Unix time or POSIX time or Unix timestamp) is the number of s
const meshtastic::GPSStatus status = const meshtastic::GPSStatus status =
meshtastic::GPSStatus(hasLock(), isConnected, latitude, longitude, altitude, dop, heading, numSatellites); meshtastic::GPSStatus(hasLock(), isConnected, latitude, longitude, altitude, dop, heading, numSatellites);
newStatus.notifyObservers(&status); newStatus.notifyObservers(&status);
}
// Once we have sent a location once we only poll the GPS rarely, otherwise check back every 1s until we have something over // Once we have sent a location once we only poll the GPS rarely, otherwise check back every 10s until we have something
// the serial // over the serial
setPeriod(hasValidLocation && !wantNewLocation ? 30 * 1000 : 10 * 1000); setPeriod(hasValidLocation && !wantNewLocation ? 30 * 1000 : 10 * 1000);
} }

View File

@ -774,7 +774,7 @@ void DebugInfo::drawFrame(OLEDDisplay *display, OLEDDisplayUiState *state, int16
// Display power status // Display power status
if (powerStatus->getHasBattery()) if (powerStatus->getHasBattery())
drawBattery(display, x, y + 2, imgBattery, powerStatus); drawBattery(display, x, y + 2, imgBattery, powerStatus);
else else if (powerStatus->knowsUSB())
display->drawFastImage(x, y + 2, 16, 8, powerStatus->getHasUSB() ? imgUSB : imgPower); display->drawFastImage(x, y + 2, 16, 8, powerStatus->getHasUSB() ? imgUSB : imgPower);
// Display nodes status // Display nodes status
drawNodes(display, x + (SCREEN_WIDTH * 0.25), y + 2, nodeStatus); drawNodes(display, x + (SCREEN_WIDTH * 0.25), y + 2, nodeStatus);
@ -819,14 +819,16 @@ int Screen::handleStatusUpdate(const meshtastic::Status *arg)
// DEBUG_MSG("Screen got status update %d\n", arg->getStatusType()); // DEBUG_MSG("Screen got status update %d\n", arg->getStatusType());
switch (arg->getStatusType()) { switch (arg->getStatusType()) {
case STATUS_TYPE_NODE: case STATUS_TYPE_NODE:
if (nodeDB.updateTextMessage || nodeStatus->getLastNumTotal() != nodeStatus->getNumTotal()) if (nodeDB.updateTextMessage || nodeStatus->getLastNumTotal() != nodeStatus->getNumTotal()) {
setFrames(); setFrames(); // Regen the list of screens
prevFrame = -1; prevFrame = -1; // Force a GUI update
setPeriod(1); // Update the screen right away
}
nodeDB.updateGUI = false; nodeDB.updateGUI = false;
nodeDB.updateTextMessage = false; nodeDB.updateTextMessage = false;
break; break;
} }
setPeriod(1); // Update the screen right away
return 0; return 0;
} }
} // namespace graphics } // namespace graphics

View File

@ -68,6 +68,9 @@ void printPacket(const char *prefix, const MeshPacket *p)
if (p->rx_time != 0) { if (p->rx_time != 0) {
DEBUG_MSG(" rxtime=%u", p->rx_time); DEBUG_MSG(" rxtime=%u", p->rx_time);
} }
if (p->rx_snr != 0.0) {
DEBUG_MSG(" rxSNR=%g", p->rx_snr);
}
DEBUG_MSG(")\n"); DEBUG_MSG(")\n");
} }
@ -115,8 +118,6 @@ unsigned long hash(char *str)
return hash; return hash;
} }
#define POWER_DEFAULT 17 #define POWER_DEFAULT 17
/** /**

View File

@ -74,6 +74,10 @@ bool SX1262Interface::reconfigure()
err = lora.setCodingRate(cr); err = lora.setCodingRate(cr);
assert(err == ERR_NONE); assert(err == ERR_NONE);
// Hmm - seems to lower SNR when the signal levels are high. Leaving off for now...
//err = lora.setRxGain(true);
//assert(err == ERR_NONE);
err = lora.setSyncWord(syncWord); err = lora.setSyncWord(syncWord);
assert(err == ERR_NONE); assert(err == ERR_NONE);
@ -123,6 +127,7 @@ void SX1262Interface::setStandby()
*/ */
void SX1262Interface::addReceiveMetadata(MeshPacket *mp) void SX1262Interface::addReceiveMetadata(MeshPacket *mp)
{ {
// DEBUG_MSG("PacketStatus %x\n", lora.getPacketStatus());
mp->rx_snr = lora.getSNR(); mp->rx_snr = lora.getSNR();
} }

View File

@ -197,7 +197,7 @@ void doDeepSleep(uint64_t msecToWake)
static const uint8_t rtcGpios[] = {/* 0, */ 2, static const uint8_t rtcGpios[] = {/* 0, */ 2,
/* 4, */ /* 4, */
#ifndef USE_JTAG #ifndef USE_JTAG
12, 13, 13,
/* 14, */ /* 15, */ /* 14, */ /* 15, */
#endif #endif
/* 25, */ 26, /* 27, */ /* 25, */ 26, /* 27, */