mirror of
https://github.com/meshtastic/firmware.git
synced 2025-04-29 02:51:17 +00:00
commit
8eb492d356
@ -1,3 +1,3 @@
|
|||||||
|
|
||||||
|
|
||||||
export VERSION=0.9.2
|
export VERSION=0.9.3
|
BIN
docs/hardware/DS_SX1261-2_V1.2.pdf
Normal file
BIN
docs/hardware/DS_SX1261-2_V1.2.pdf
Normal file
Binary file not shown.
BIN
docs/hardware/T-SX1262.pdf
Normal file
BIN
docs/hardware/T-SX1262.pdf
Normal file
Binary file not shown.
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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, */
|
||||||
|
Loading…
Reference in New Issue
Block a user