Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add RAKwireless WisMesh Hub (RAK2560/RAK9154) #4117

Merged
merged 10 commits into from
Jun 16, 2024
7 changes: 4 additions & 3 deletions .vscode/extensions.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@
// See http://go.microsoft.com/fwlink/?LinkId=827846
// for the documentation about the extensions.json format
"recommendations": [
"ms-vscode.cpptools",
"platformio.platformio-ide",
"trunk.io"
"platformio.platformio-ide"
],
"unwantedRecommendations": [
"ms-vscode.cpptools-extension-pack"
]
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please don't check in the vscode files. This will cause merge conflicts all over the place.

1 change: 1 addition & 0 deletions platformio.ini
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ default_envs = tbeam
;default_envs = meshtastic-dr-dev
;default_envs = m5stack-coreink
;default_envs = rak4631
;default_envs = rak2560
;default_envs = rak10701
;default_envs = wio-e5
;default_envs = radiomaster_900_bandit_nano
Expand Down
33 changes: 33 additions & 0 deletions src/Power.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,10 @@ INA219Sensor ina219Sensor;
INA3221Sensor ina3221Sensor;
#endif

#if HAS_RAKPROT && !defined(ARCH_PORTDUINO)
RAK9154Sensor rak9154Sensor;
#endif

#ifdef HAS_PMU
#include "XPowersAXP192.tpp"
#include "XPowersAXP2101.tpp"
Expand Down Expand Up @@ -145,6 +149,12 @@ class AnalogBatteryLevel : public HasBatteryLevel
*/
virtual int getBatteryPercent() override
{
#if defined(HAS_RAKPROT) && !defined(ARCH_PORTDUINO) && !defined(HAS_PMU)
if (hasRAK()) {
return rak9154Sensor.getBusBatteryPercent();
}
#endif

float v = getBattVoltage();

if (v < noBatVolt)
Expand Down Expand Up @@ -184,6 +194,12 @@ class AnalogBatteryLevel : public HasBatteryLevel
virtual uint16_t getBattVoltage() override
{

#if defined(HAS_RAKPROT) && !defined(ARCH_PORTDUINO) && !defined(HAS_PMU)
if (hasRAK()) {
return getRAKVoltage();
}
#endif

#if HAS_TELEMETRY && !defined(ARCH_PORTDUINO) && !defined(HAS_PMU) && !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR
if (hasINA()) {
LOG_DEBUG("Using INA on I2C addr 0x%x for device battery voltage\n", config.power.device_battery_ina_address);
Expand Down Expand Up @@ -356,6 +372,11 @@ class AnalogBatteryLevel : public HasBatteryLevel
/// we can't be smart enough to say 'full'?
virtual bool isCharging() override
{
#if defined(HAS_RAKPROT) && !defined(ARCH_PORTDUINO) && !defined(HAS_PMU)
if (hasRAK()) {
return (rak9154Sensor.isCharging()) ? OptTrue : OptFalse;
}
#endif
#ifdef EXT_CHRG_DETECT
return digitalRead(EXT_CHRG_DETECT) == ext_chrg_detect_value;
#else
Expand All @@ -379,6 +400,18 @@ class AnalogBatteryLevel : public HasBatteryLevel
float last_read_value = (OCV[NUM_OCV_POINTS - 1] * NUM_CELLS);
uint32_t last_read_time_ms = 0;

#if defined(HAS_RAKPROT)

uint16_t getRAKVoltage() { return rak9154Sensor.getBusVoltageMv(); }

bool hasRAK()
{
if (!rak9154Sensor.isInitialized())
return rak9154Sensor.runOnce() > 0;
return rak9154Sensor.isRunning();
}
#endif

#if HAS_TELEMETRY && !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR && !defined(ARCH_PORTDUINO)
uint16_t getINAVoltage()
{
Expand Down
191 changes: 191 additions & 0 deletions src/modules/Telemetry/Sensor/RAK9154Sensor.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,191 @@
#ifdef HAS_RAKPROT
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think the RAK9154 support is places correctly. The Telemetry folder is for devices that actually transmit values over Lora. This looks more like gathering values for internal processing. If this is only ever used once for this particular device, you can as well put it in the variant folder and skip deriving it from TelemetryModule. If you add the OSThread class to inheritance you can use the runOnce model without having to define it as a sensor (which it isn't in the meshtastic sense)

#include "RAK9154Sensor.h"
#include "../mesh/generated/meshtastic/telemetry.pb.h"
#include "TelemetrySensor.h"
#include "configuration.h"

#include <RAK-OneWireSerial.h>
#include "concurrency/Periodic.h"

using namespace concurrency;

#define BOOT_DATA_REQ

RAK9154Sensor::RAK9154Sensor() : TelemetrySensor(meshtastic_TelemetrySensorType_SENSOR_UNSET, "RAK1954") {}

static Periodic *onewirePeriodic;

static SoftwareHalfSerial mySerial(HALF_UART_PIN); // Wire pin P0.15

static uint8_t buff[0x100];
static uint16_t bufflen = 0;

static int16_t dc_cur = 0;
static uint16_t dc_vol = 0;
static uint8_t dc_prec = 0;
static uint8_t provision = 0;

static void onewire_evt(const uint8_t pid, const uint8_t sid, const SNHUBAPI_EVT_E eid, uint8_t *msg, uint16_t len)
{
switch (eid)
{
case SNHUBAPI_EVT_RECV_REQ:
case SNHUBAPI_EVT_RECV_RSP:
break;

case SNHUBAPI_EVT_QSEND:
mySerial.write(msg, len);
break;

case SNHUBAPI_EVT_ADD_SID:
// LOG_INFO("+ADD:SID:[%02x]\r\n", msg[0]);
break;

case SNHUBAPI_EVT_ADD_PID:
// LOG_INFO("+ADD:PID:[%02x]\r\n", msg[0]);
#ifdef BOOT_DATA_REQ
provision = msg[0];
#endif
break;

case SNHUBAPI_EVT_GET_INTV:
break;

case SNHUBAPI_EVT_GET_ENABLE:
break;

case SNHUBAPI_EVT_SDATA_REQ:

// LOG_INFO("+EVT:PID[%02x],IPSO[%02x]\r\n",pid,msg[0]);
// for( uint16_t i=1; i<len; i++)
// {
// LOG_INFO("%02x,", msg[i]);
// }
// LOG_INFO("\r\n");
switch (msg[0])
{
case RAK_IPSO_CAPACITY:
dc_prec = msg[1];
if (dc_prec > 100)
{
dc_prec = 100;
}
break;
case RAK_IPSO_DC_CURRENT:
dc_cur = (msg[2] << 8) + msg[1];
break;
case RAK_IPSO_DC_VOLTAGE:
dc_vol = (msg[2] << 8) + msg[1];
dc_vol *= 10;
break;
default:
break;
}

break;
case SNHUBAPI_EVT_REPORT:

// LOG_INFO("+EVT:PID[%02x],IPSO[%02x]\r\n",pid,msg[0]);
// for( uint16_t i=1; i<len; i++)
// {
// LOG_INFO("%02x,", msg[i]);
// }
// LOG_INFO("\r\n");

switch (msg[0])
{
case RAK_IPSO_CAPACITY:
dc_prec = msg[1];
if (dc_prec > 100)
{
dc_prec = 100;
}
break;
case RAK_IPSO_DC_CURRENT:
dc_cur = (msg[1] << 8) + msg[2];
break;
case RAK_IPSO_DC_VOLTAGE:
dc_vol = (msg[1] << 8) + msg[2];
dc_vol *= 10;
break;
default:
break;
}

break;

case SNHUBAPI_EVT_CHKSUM_ERR:
LOG_INFO("+ERR:CHKSUM\r\n");
break;

case SNHUBAPI_EVT_SEQ_ERR:
LOG_INFO("+ERR:SEQUCE\r\n");
break;

default:
break;
}
}

static int32_t onewireHandle()
{
if (provision != 0)
{
RakSNHub_Protocl_API.get.data(provision);
provision = 0;
}

while (mySerial.available())
{
char a = mySerial.read();
buff[bufflen++] = a;
delay(2); // continue data, timeout=2ms
}

if (bufflen != 0)
{
RakSNHub_Protocl_API.process((uint8_t *)buff, bufflen);
bufflen = 0;
}

return 50;
}

int32_t RAK9154Sensor::runOnce()
{
onewirePeriodic = new Periodic("onewireHandle", onewireHandle);

mySerial.begin(9600);

RakSNHub_Protocl_API.init(onewire_evt);

status = true;
initialized = true;
return 0;
}

void RAK9154Sensor::setup()
{
// Set up oversampling and filter initialization
}

bool RAK9154Sensor::getMetrics(meshtastic_Telemetry *measurement)
{
return true;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Alternatively if the values really should be able to go out over the mesh, you need to implementthese functions :-)

}

uint16_t RAK9154Sensor::getBusVoltageMv()
{
return dc_vol;
}

int RAK9154Sensor::getBusBatteryPercent()
{
return (int)dc_prec;
}

bool RAK9154Sensor::isCharging()
{
return (dc_cur > 0) ? true : false;
}
#endif // HAS_RAKPROT
20 changes: 20 additions & 0 deletions src/modules/Telemetry/Sensor/RAK9154Sensor.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#ifdef HAS_RAKPROT
#include "../mesh/generated/meshtastic/telemetry.pb.h"
#include "TelemetrySensor.h"
#include "VoltageSensor.h"

class RAK9154Sensor : public TelemetrySensor, VoltageSensor
{
private:
protected:
virtual void setup() override;

public:
RAK9154Sensor();
virtual int32_t runOnce() override;
virtual bool getMetrics(meshtastic_Telemetry *measurement) override;
virtual uint16_t getBusVoltageMv() override;
int getBusBatteryPercent();
bool isCharging();
};
#endif // HAS_RAKPROT
5 changes: 5 additions & 0 deletions src/power.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,11 @@ extern INA219Sensor ina219Sensor;
extern INA3221Sensor ina3221Sensor;
#endif

#if HAS_RAKPROT && !defined(ARCH_PORTDUINO)
#include "modules/Telemetry/Sensor/RAK9154Sensor.h"
extern RAK9154Sensor rak9154Sensor;
#endif

class Power : private concurrency::OSThread
{

Expand Down
Loading
Loading