mirror of
https://github.com/thooge/esp32-nmea2000-obp60.git
synced 2025-12-13 05:53:06 +01:00
add timer class for periodic runs
This commit is contained in:
@@ -1,16 +1,16 @@
|
||||
#include "Nmea2kTwai.h"
|
||||
#include "driver/gpio.h"
|
||||
#include "driver/twai.h"
|
||||
#include "GwLog.h"
|
||||
|
||||
#define LOGID(id) ((id >> 8) & 0x1ffff)
|
||||
|
||||
static const int TIMEOUT_OFFLINE=256; //# of timeouts to consider offline
|
||||
|
||||
Nmea2kTwai::Nmea2kTwai(gpio_num_t _TxPin, gpio_num_t _RxPin, unsigned long recP):
|
||||
tNMEA2000(),RxPin(_RxPin),TxPin(_TxPin),recoveryPeriod(recP)
|
||||
Nmea2kTwai::Nmea2kTwai(gpio_num_t _TxPin, gpio_num_t _RxPin, unsigned long recP, unsigned long logP):
|
||||
tNMEA2000(),RxPin(_RxPin),TxPin(_TxPin)
|
||||
{
|
||||
lastRecoveryCheck=millis();
|
||||
timers.addAction(logP,[this](){logStatus();});
|
||||
timers.addAction(recP,[this](){checkRecovery();});
|
||||
}
|
||||
|
||||
bool Nmea2kTwai::CANSendFrame(unsigned long id, unsigned char len, const unsigned char *buf, bool wait_sent)
|
||||
@@ -120,26 +120,42 @@ Nmea2kTwai::Status Nmea2kTwai::getStatus(){
|
||||
return rt;
|
||||
}
|
||||
bool Nmea2kTwai::checkRecovery(){
|
||||
if (recoveryPeriod == 0) return false; //no check
|
||||
unsigned long now=millis();
|
||||
if ((lastRecoveryCheck+recoveryPeriod) > now) return false;
|
||||
lastRecoveryCheck=now;
|
||||
Status canState=getStatus();
|
||||
bool strt=false;
|
||||
if (canState.state != Nmea2kTwai::ST_RUNNING){
|
||||
if (canState.state == Nmea2kTwai::ST_BUS_OFF){
|
||||
strt=true;
|
||||
bool rt=startRecovery();
|
||||
logDebug(LOG_INFO,"start can recovery - result %d",(int)rt);
|
||||
}
|
||||
if (canState.state == Nmea2kTwai::ST_STOPPED){
|
||||
bool rt=CANOpen();
|
||||
logDebug(LOG_INFO,"restart can driver - result %d",(int)rt);
|
||||
}
|
||||
if (canState.state != Nmea2kTwai::ST_RUNNING)
|
||||
{
|
||||
if (canState.state == Nmea2kTwai::ST_BUS_OFF)
|
||||
{
|
||||
strt = true;
|
||||
bool rt = startRecovery();
|
||||
logDebug(LOG_INFO, "twai BUS_OFF: start can recovery - result %d", (int)rt);
|
||||
}
|
||||
if (canState.state == Nmea2kTwai::ST_STOPPED)
|
||||
{
|
||||
bool rt = CANOpen();
|
||||
logDebug(LOG_INFO, "twai STOPPED: restart can driver - result %d", (int)rt);
|
||||
}
|
||||
}
|
||||
return strt;
|
||||
}
|
||||
|
||||
void Nmea2kTwai::loop(){
|
||||
timers.loop();
|
||||
}
|
||||
|
||||
Nmea2kTwai::Status Nmea2kTwai::logStatus(){
|
||||
Status canState=getStatus();
|
||||
logDebug(LOG_INFO, "twai state %s, rxerr %d, txerr %d, txfail %d, txtimeout %d, rxmiss %d, rxoverrun %d",
|
||||
stateStr(canState.state),
|
||||
canState.rx_errors,
|
||||
canState.tx_errors,
|
||||
canState.tx_failed,
|
||||
canState.tx_timeouts,
|
||||
canState.rx_missed,
|
||||
canState.rx_overrun);
|
||||
return canState;
|
||||
}
|
||||
|
||||
bool Nmea2kTwai::startRecovery(){
|
||||
esp_err_t rt=twai_driver_uninstall();
|
||||
if (rt != ESP_OK){
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
#ifndef _NMEA2KTWAI_H
|
||||
#define _NMEA2KTWAI_H
|
||||
#include "NMEA2000.h"
|
||||
#include "GwLog.h"
|
||||
#include "GwTimer.h"
|
||||
|
||||
class Nmea2kTwai : public tNMEA2000{
|
||||
public:
|
||||
Nmea2kTwai(gpio_num_t _TxPin, gpio_num_t _RxPin, unsigned long recP=0);
|
||||
Nmea2kTwai(gpio_num_t _TxPin, gpio_num_t _RxPin, unsigned long recP=0, unsigned long logPeriod=0);
|
||||
typedef enum{
|
||||
ST_STOPPED,
|
||||
ST_RUNNING,
|
||||
@@ -25,7 +25,7 @@ class Nmea2kTwai : public tNMEA2000{
|
||||
STATE state=ST_ERROR;
|
||||
} Status;
|
||||
Status getStatus();
|
||||
bool checkRecovery();
|
||||
void loop();
|
||||
static const char * stateStr(const STATE &st);
|
||||
virtual bool CANOpen();
|
||||
virtual ~Nmea2kTwai(){};
|
||||
@@ -48,11 +48,12 @@ class Nmea2kTwai : public tNMEA2000{
|
||||
private:
|
||||
void initDriver();
|
||||
bool startRecovery();
|
||||
bool checkRecovery();
|
||||
Status logStatus();
|
||||
gpio_num_t TxPin;
|
||||
gpio_num_t RxPin;
|
||||
uint32_t txTimeouts=0;
|
||||
unsigned long recoveryPeriod=0;
|
||||
unsigned long lastRecoveryCheck=0;
|
||||
GwIntervalRunner timers;
|
||||
};
|
||||
|
||||
#endif
|
||||
48
lib/timer/GwTimer.h
Normal file
48
lib/timer/GwTimer.h
Normal file
@@ -0,0 +1,48 @@
|
||||
#ifndef _GWTIMER_H
|
||||
#define _GWTIMER_H
|
||||
#include <vector>
|
||||
#include <functional>
|
||||
#include <Arduino.h>
|
||||
class GwIntervalRunner{
|
||||
public:
|
||||
using RunFunction=std::function<void(void)>;
|
||||
private:
|
||||
class Run{
|
||||
public:
|
||||
unsigned long interval=0;
|
||||
RunFunction runner;
|
||||
unsigned long last=0;
|
||||
Run(RunFunction r,unsigned long iv,unsigned long l=0):
|
||||
runner(r),interval(iv),last(l){}
|
||||
bool shouldRun(unsigned long now){
|
||||
if ((last+interval) > now) return false;
|
||||
last=now;
|
||||
return true;
|
||||
}
|
||||
bool runIf(unsigned long now){
|
||||
if (shouldRun(now)) {
|
||||
runner();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
};
|
||||
std::vector<Run> runners;
|
||||
unsigned long startTime=0;
|
||||
public:
|
||||
GwIntervalRunner(unsigned long now=millis()){
|
||||
startTime=now;
|
||||
}
|
||||
void addAction(unsigned long interval,RunFunction run,unsigned long start=0){
|
||||
if (start=0) start=startTime;
|
||||
runners.push_back(Run(run,interval,start));
|
||||
}
|
||||
bool loop(unsigned long now=millis()){
|
||||
bool rt=false;
|
||||
for (auto it=runners.begin();it!=runners.end();it++){
|
||||
if (it->runIf(now)) rt=true;
|
||||
}
|
||||
return rt;
|
||||
}
|
||||
};
|
||||
#endif
|
||||
Reference in New Issue
Block a user