mirror of
https://github.com/meshtastic/firmware.git
synced 2025-08-06 13:44:46 +00:00
Merge pull request #55 from mc-hamster/serial
Update for SerialPlugin and Airtime
This commit is contained in:
commit
b963216764
@ -5,10 +5,6 @@
|
|||||||
|
|
||||||
AirTime *airTime;
|
AirTime *airTime;
|
||||||
|
|
||||||
// A reminder that there are 3600 seconds in an hour so I don't have
|
|
||||||
// to keep googling it.
|
|
||||||
// This can be changed to a smaller number to speed up testing.
|
|
||||||
//
|
|
||||||
uint32_t secondsPerPeriod = 3600;
|
uint32_t secondsPerPeriod = 3600;
|
||||||
uint32_t lastMillis = 0;
|
uint32_t lastMillis = 0;
|
||||||
uint32_t secSinceBoot = 0;
|
uint32_t secSinceBoot = 0;
|
||||||
@ -17,25 +13,23 @@ uint32_t secSinceBoot = 0;
|
|||||||
|
|
||||||
// Don't read out of this directly. Use the helper functions.
|
// Don't read out of this directly. Use the helper functions.
|
||||||
struct airtimeStruct {
|
struct airtimeStruct {
|
||||||
uint16_t periodTX[periodsToLog]; // AirTime transmitted
|
uint32_t periodTX[periodsToLog]; // AirTime transmitted
|
||||||
uint16_t periodRX[periodsToLog]; // AirTime received and repeated (Only valid mesh packets)
|
uint32_t periodRX[periodsToLog]; // AirTime received and repeated (Only valid mesh packets)
|
||||||
uint16_t periodRX_ALL[periodsToLog]; // AirTime received regardless of valid mesh packet. Could include noise.
|
uint32_t periodRX_ALL[periodsToLog]; // AirTime received regardless of valid mesh packet. Could include noise.
|
||||||
uint8_t lastPeriodIndex;
|
uint8_t lastPeriodIndex;
|
||||||
} airtimes;
|
} airtimes;
|
||||||
|
|
||||||
void AirTime::logAirtime(reportTypes reportType, uint32_t airtime_ms)
|
void AirTime::logAirtime(reportTypes reportType, uint32_t airtime_ms)
|
||||||
{
|
{
|
||||||
// DEBUG_MSG("Packet - logAirtime()\n");
|
|
||||||
|
|
||||||
if (reportType == TX_LOG) {
|
if (reportType == TX_LOG) {
|
||||||
DEBUG_MSG("AirTime - Packet transmitted : %us %ums\n", (uint32_t)round((float)airtime_ms / (float)1000), airtime_ms);
|
DEBUG_MSG("AirTime - Packet transmitted : %ums\n", airtime_ms);
|
||||||
airtimes.periodTX[0] = airtimes.periodTX[0] + round(airtime_ms / 1000);
|
airtimes.periodTX[0] = airtimes.periodTX[0] + airtime_ms;
|
||||||
} else if (reportType == RX_LOG) {
|
} else if (reportType == RX_LOG) {
|
||||||
DEBUG_MSG("AirTime - Packet received : %us %ums\n", (uint32_t)round((float)airtime_ms / (float)1000), airtime_ms);
|
DEBUG_MSG("AirTime - Packet received : %ums\n", airtime_ms);
|
||||||
airtimes.periodRX[0] = airtimes.periodRX[0] + round(airtime_ms / 1000);
|
airtimes.periodRX[0] = airtimes.periodRX[0] + airtime_ms;
|
||||||
} else if (reportType == RX_ALL_LOG) {
|
} else if (reportType == RX_ALL_LOG) {
|
||||||
DEBUG_MSG("AirTime - Packet received (noise?) : %us %ums\n", (uint32_t)round((float)airtime_ms / (float)1000), airtime_ms);
|
DEBUG_MSG("AirTime - Packet received (noise?) : %ums\n", airtime_ms);
|
||||||
airtimes.periodRX_ALL[0] = airtimes.periodRX_ALL[0] + round(airtime_ms / 1000);
|
airtimes.periodRX_ALL[0] = airtimes.periodRX_ALL[0] + airtime_ms;
|
||||||
} else {
|
} else {
|
||||||
DEBUG_MSG("AirTime - Unknown report time. This should never happen!!\n");
|
DEBUG_MSG("AirTime - Unknown report time. This should never happen!!\n");
|
||||||
}
|
}
|
||||||
@ -65,7 +59,7 @@ void airtimeRotatePeriod()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t *airtimeReport(reportTypes reportType)
|
uint32_t *airtimeReport(reportTypes reportType)
|
||||||
{
|
{
|
||||||
|
|
||||||
if (reportType == TX_LOG) {
|
if (reportType == TX_LOG) {
|
||||||
|
@ -34,7 +34,7 @@ uint8_t getPeriodsToLog();
|
|||||||
|
|
||||||
uint32_t getSecondsSinceBoot();
|
uint32_t getSecondsSinceBoot();
|
||||||
|
|
||||||
uint16_t *airtimeReport(reportTypes reportType);
|
uint32_t *airtimeReport(reportTypes reportType);
|
||||||
|
|
||||||
uint32_t getSecondsPerPeriod();
|
uint32_t getSecondsPerPeriod();
|
||||||
|
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
#include "plugins/NodeInfoPlugin.h"
|
#include "plugins/NodeInfoPlugin.h"
|
||||||
#include "plugins/PositionPlugin.h"
|
#include "plugins/PositionPlugin.h"
|
||||||
#include "plugins/ReplyPlugin.h"
|
#include "plugins/ReplyPlugin.h"
|
||||||
|
#include "plugins/SerialPlugin.h"
|
||||||
#include "plugins/RemoteHardwarePlugin.h"
|
#include "plugins/RemoteHardwarePlugin.h"
|
||||||
#include "plugins/TextMessagePlugin.h"
|
#include "plugins/TextMessagePlugin.h"
|
||||||
|
|
||||||
@ -17,4 +18,5 @@ void setupPlugins() {
|
|||||||
|
|
||||||
new RemoteHardwarePlugin();
|
new RemoteHardwarePlugin();
|
||||||
new ReplyPlugin();
|
new ReplyPlugin();
|
||||||
|
new SerialPlugin(); // Maintained by MC Hamster (Jm Casler) jm@casler.org
|
||||||
}
|
}
|
161
src/plugins/SerialPlugin.cpp
Normal file
161
src/plugins/SerialPlugin.cpp
Normal file
@ -0,0 +1,161 @@
|
|||||||
|
#include "SerialPlugin.h"
|
||||||
|
#include "MeshService.h"
|
||||||
|
#include "NodeDB.h"
|
||||||
|
#include "RTC.h"
|
||||||
|
#include "Router.h"
|
||||||
|
#include "configuration.h"
|
||||||
|
#include <Arduino.h>
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
SerialPlugin
|
||||||
|
An overly simplistic interface to send messages over the mesh network by sending strings
|
||||||
|
over a serial port.
|
||||||
|
|
||||||
|
Originally designed for lora32 v1.0
|
||||||
|
Manufacture Info: http://www.lilygo.cn/prod_view.aspx?TypeId=50003&Id=1133&FId=t3:50003:3
|
||||||
|
Pin Mapping: http://ae01.alicdn.com/kf/HTB1fLBcxkSWBuNjSszdq6zeSpXaJ.jpg
|
||||||
|
|
||||||
|
This will probably and most likely work on other esp32 devices, given possible change the RX/TX
|
||||||
|
selection.
|
||||||
|
|
||||||
|
Need help with this plugin? Post your question on the Meshtastic Discourse:
|
||||||
|
https://meshtastic.discourse.group
|
||||||
|
|
||||||
|
Basic Usage:
|
||||||
|
|
||||||
|
1) Enable the plugin by setting SERIALPLUGIN_ENABLED to 1.
|
||||||
|
2) Set the pins (RXD2 / TXD2) for your preferred RX and TX GPIO pins.
|
||||||
|
3) Set SERIALPLUGIN_TIMEOUT to the amount of time to wait before we consider
|
||||||
|
your packet as "done".
|
||||||
|
4) (Optional) In SerialPlugin.h set the port to PortNum_TEXT_MESSAGE_APP if you want to
|
||||||
|
send messages to/from the general text message channel.
|
||||||
|
5) Connect to your device over the serial interface at 38400 8N1.
|
||||||
|
6) Send a packet up to 240 bytes in length. This will get relayed over the mesh network.
|
||||||
|
7) (Optional) Set SERIALPLUGIN_ECHO to 1 and any message you send out will be echoed back
|
||||||
|
to your device.
|
||||||
|
|
||||||
|
TODO (in this order):
|
||||||
|
* Once protobufs regenerated with the new port, update SerialPlugin.h
|
||||||
|
* Ensure this works on a tbeam
|
||||||
|
* Define a verbose RX mode to report on mesh and packet infomration.
|
||||||
|
- This won't happen any time soon.
|
||||||
|
|
||||||
|
KNOWN PROBLEMS
|
||||||
|
* Until the plugin is initilized by the startup sequence, the TX pin is in a floating
|
||||||
|
state. Device connected to that pin may see this as "noise".
|
||||||
|
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define RXD2 16
|
||||||
|
#define TXD2 17
|
||||||
|
#define SERIALPLUGIN_RX_BUFFER 128
|
||||||
|
#define SERIALPLUGIN_STRING_MAX Constants_DATA_PAYLOAD_LEN
|
||||||
|
#define SERIALPLUGIN_TIMEOUT 250
|
||||||
|
#define SERIALPLUGIN_BAUD 38400
|
||||||
|
#define SERIALPLUGIN_ENABLED 1
|
||||||
|
#define SERIALPLUGIN_ECHO 0
|
||||||
|
#define SERIALPLUGIN_ACK 0
|
||||||
|
|
||||||
|
SerialPlugin *serialPlugin;
|
||||||
|
SerialPluginRadio *serialPluginRadio;
|
||||||
|
|
||||||
|
SerialPlugin::SerialPlugin() : concurrency::OSThread("SerialPlugin") {}
|
||||||
|
|
||||||
|
char serialStringChar[Constants_DATA_PAYLOAD_LEN];
|
||||||
|
|
||||||
|
int32_t SerialPlugin::runOnce()
|
||||||
|
{
|
||||||
|
|
||||||
|
#if SERIALPLUGIN_ENABLED == 1
|
||||||
|
|
||||||
|
if (firstTime) {
|
||||||
|
|
||||||
|
// Interface with the serial peripheral from in here.
|
||||||
|
DEBUG_MSG("Initilizing serial peripheral interface\n");
|
||||||
|
|
||||||
|
Serial2.begin(SERIALPLUGIN_BAUD, SERIAL_8N1, RXD2, TXD2);
|
||||||
|
Serial2.setTimeout(SERIALPLUGIN_TIMEOUT); // Number of MS to wait to set the timeout for the string.
|
||||||
|
Serial2.setRxBufferSize(SERIALPLUGIN_RX_BUFFER);
|
||||||
|
|
||||||
|
serialPluginRadio = new SerialPluginRadio();
|
||||||
|
|
||||||
|
firstTime = 0;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
String serialString;
|
||||||
|
|
||||||
|
while (Serial2.available()) {
|
||||||
|
serialString = Serial2.readString();
|
||||||
|
serialString.toCharArray(serialStringChar, Constants_DATA_PAYLOAD_LEN);
|
||||||
|
|
||||||
|
serialPluginRadio->sendPayload();
|
||||||
|
|
||||||
|
DEBUG_MSG("Received: %s\n", serialStringChar);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return (10);
|
||||||
|
#else
|
||||||
|
DEBUG_MSG("Serial Plugin Disabled\n");
|
||||||
|
|
||||||
|
return (INT32_MAX);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
MeshPacket *SerialPluginRadio::allocReply()
|
||||||
|
{
|
||||||
|
|
||||||
|
auto reply = allocDataPacket(); // Allocate a packet for sending
|
||||||
|
|
||||||
|
return reply;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SerialPluginRadio::sendPayload(NodeNum dest, bool wantReplies)
|
||||||
|
{
|
||||||
|
MeshPacket *p = allocReply();
|
||||||
|
p->to = dest;
|
||||||
|
p->decoded.want_response = wantReplies;
|
||||||
|
|
||||||
|
p->want_ack = SERIALPLUGIN_ACK;
|
||||||
|
|
||||||
|
p->decoded.data.payload.size = strlen(serialStringChar); // You must specify how many bytes are in the reply
|
||||||
|
memcpy(p->decoded.data.payload.bytes, serialStringChar, p->decoded.data.payload.size);
|
||||||
|
|
||||||
|
service.sendToMesh(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SerialPluginRadio::handleReceived(const MeshPacket &mp)
|
||||||
|
{
|
||||||
|
auto &p = mp.decoded.data;
|
||||||
|
// DEBUG_MSG("Received text msg self=0x%0x, from=0x%0x, to=0x%0x, id=%d, msg=%.*s\n", nodeDB.getNodeNum(),
|
||||||
|
// mp.from, mp.to, mp.id, p.payload.size, p.payload.bytes);
|
||||||
|
|
||||||
|
if (mp.from == nodeDB.getNodeNum()) {
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If SERIALPLUGIN_ECHO is true, then echo the packets that are sent out back to the TX
|
||||||
|
* of the serial interface.
|
||||||
|
*/
|
||||||
|
if (SERIALPLUGIN_ECHO) {
|
||||||
|
|
||||||
|
// For some reason, we get the packet back twice when we send out of the radio.
|
||||||
|
// TODO: need to find out why.
|
||||||
|
if (lastRxID != mp.id) {
|
||||||
|
lastRxID = mp.id;
|
||||||
|
// DEBUG_MSG("* * Message came this device\n");
|
||||||
|
// Serial2.println("* * Message came this device");
|
||||||
|
Serial2.printf("%s", p.payload.bytes);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// DEBUG_MSG("* * Message came from the mesh\n");
|
||||||
|
// Serial2.println("* * Message came from the mesh");
|
||||||
|
Serial2.printf("%s", p.payload.bytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true; // Let others look at this message also if they want
|
||||||
|
}
|
54
src/plugins/SerialPlugin.h
Normal file
54
src/plugins/SerialPlugin.h
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "SinglePortPlugin.h"
|
||||||
|
#include "concurrency/OSThread.h"
|
||||||
|
#include "configuration.h"
|
||||||
|
#include <Arduino.h>
|
||||||
|
#include <functional>
|
||||||
|
|
||||||
|
class SerialPlugin : private concurrency::OSThread
|
||||||
|
{
|
||||||
|
bool firstTime = 1;
|
||||||
|
|
||||||
|
public:
|
||||||
|
SerialPlugin();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual int32_t runOnce();
|
||||||
|
};
|
||||||
|
|
||||||
|
extern SerialPlugin *serialPlugin;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Radio interface for SerialPlugin
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
class SerialPluginRadio : public SinglePortPlugin
|
||||||
|
{
|
||||||
|
uint32_t lastRxID;
|
||||||
|
|
||||||
|
public:
|
||||||
|
/*
|
||||||
|
TODO: Switch this to PortNum_SERIAL_APP once the change is able to be merged back here
|
||||||
|
from the main code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
SerialPluginRadio() : SinglePortPlugin("SerialPluginRadio", PortNum_TEXT_MESSAGE_APP) {}
|
||||||
|
// SerialPluginRadio() : SinglePortPlugin("SerialPluginRadio", PortNum_SERIAL_APP) {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send our payload into the mesh
|
||||||
|
*/
|
||||||
|
void sendPayload(NodeNum dest = NODENUM_BROADCAST, bool wantReplies = false);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual MeshPacket *allocReply();
|
||||||
|
|
||||||
|
/** Called to handle a particular incoming message
|
||||||
|
|
||||||
|
@return true if you've guaranteed you've handled this message and no other handlers should be considered for it
|
||||||
|
*/
|
||||||
|
virtual bool handleReceived(const MeshPacket &mp);
|
||||||
|
};
|
||||||
|
|
||||||
|
extern SerialPluginRadio *serialPluginRadio;
|
Loading…
Reference in New Issue
Block a user