intermediate: actisense format on USB
This commit is contained in:
parent
dbadb6fb11
commit
284be741f5
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
void GwBuffer::lp(const char *fkt, int p)
|
void GwBuffer::lp(const char *fkt, int p)
|
||||||
{
|
{
|
||||||
LOG_DEBUG(GwLog::DEBUG + 1, "Buffer[%s]: buf=%p,wp=%d,rp=%d,used=%d,free=%d, p=%d",
|
LOG_DEBUG(GwLog::DEBUG+2 , "Buffer[%s]: buf=%p,wp=%d,rp=%d,used=%d,free=%d, p=%d",
|
||||||
fkt, buffer, offset(writePointer), offset(readPointer), usedSpace(), freeSpace(), p);
|
fkt, buffer, offset(writePointer), offset(readPointer), usedSpace(), freeSpace(), p);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -37,6 +37,19 @@ size_t GwBuffer::usedSpace()
|
||||||
return writePointer - readPointer;
|
return writePointer - readPointer;
|
||||||
return writePointer+bufferSize-readPointer;
|
return writePointer+bufferSize-readPointer;
|
||||||
}
|
}
|
||||||
|
int GwBuffer::read(){
|
||||||
|
if (! usedSpace()) return -1;
|
||||||
|
int rt=*readPointer;
|
||||||
|
readPointer++;
|
||||||
|
if (offset(readPointer) >= bufferSize)
|
||||||
|
readPointer -= bufferSize;
|
||||||
|
lp("read");
|
||||||
|
return rt;
|
||||||
|
}
|
||||||
|
int GwBuffer::peek(){
|
||||||
|
if (! usedSpace()) return -1;
|
||||||
|
return *readPointer;
|
||||||
|
}
|
||||||
size_t GwBuffer::addData(const uint8_t *data, size_t len, bool addPartial)
|
size_t GwBuffer::addData(const uint8_t *data, size_t len, bool addPartial)
|
||||||
{
|
{
|
||||||
lp("addDataE", len);
|
lp("addDataE", len);
|
||||||
|
|
|
@ -20,7 +20,7 @@ class GwBufferWriter{
|
||||||
class GwBuffer{
|
class GwBuffer{
|
||||||
public:
|
public:
|
||||||
static const size_t TX_BUFFER_SIZE=1620; // app. 20 NMEA messages
|
static const size_t TX_BUFFER_SIZE=1620; // app. 20 NMEA messages
|
||||||
static const size_t RX_BUFFER_SIZE=200; // enough for 1 NMEA message...
|
static const size_t RX_BUFFER_SIZE=400; // enough for 1 NMEA message or actisense message
|
||||||
typedef enum {
|
typedef enum {
|
||||||
OK,
|
OK,
|
||||||
ERROR,
|
ERROR,
|
||||||
|
@ -47,6 +47,8 @@ class GwBuffer{
|
||||||
size_t freeSpace();
|
size_t freeSpace();
|
||||||
size_t usedSpace();
|
size_t usedSpace();
|
||||||
size_t addData(const uint8_t *data,size_t len,bool addPartial=false);
|
size_t addData(const uint8_t *data,size_t len,bool addPartial=false);
|
||||||
|
int read();
|
||||||
|
int peek();
|
||||||
/**
|
/**
|
||||||
* write some data to the buffer writer
|
* write some data to the buffer writer
|
||||||
* return an error if the buffer writer returned < 0
|
* return an error if the buffer writer returned < 0
|
||||||
|
|
|
@ -1,4 +1,44 @@
|
||||||
#include "GwSerial.h"
|
#include "GwSerial.h"
|
||||||
|
|
||||||
|
class GwSerialStream: public Stream{
|
||||||
|
private:
|
||||||
|
GwSerial *serial;
|
||||||
|
bool partialWrites;
|
||||||
|
public:
|
||||||
|
GwSerialStream(GwSerial *serial,bool partialWrites=false){
|
||||||
|
this->serial=serial;
|
||||||
|
this->partialWrites=partialWrites;
|
||||||
|
}
|
||||||
|
virtual int available(){
|
||||||
|
if (! serial->isInitialized()) return 0;
|
||||||
|
if (! serial->readBuffer) return 0;
|
||||||
|
return serial->readBuffer->usedSpace();
|
||||||
|
}
|
||||||
|
virtual int read(){
|
||||||
|
if (! serial->isInitialized()) return -1;
|
||||||
|
if (! serial->readBuffer) return -1;
|
||||||
|
return serial->readBuffer->read();
|
||||||
|
}
|
||||||
|
virtual int peek(){
|
||||||
|
if (! serial->isInitialized()) return -1;
|
||||||
|
if (! serial->readBuffer) return -1;
|
||||||
|
return serial->readBuffer->peek();
|
||||||
|
}
|
||||||
|
virtual void flush() {};
|
||||||
|
virtual size_t write(uint8_t v){
|
||||||
|
if (! serial->isInitialized()) return 0;
|
||||||
|
size_t rt=serial->buffer->addData(&v,1,partialWrites);
|
||||||
|
return rt;
|
||||||
|
}
|
||||||
|
virtual size_t write(const uint8_t *buffer, size_t size){
|
||||||
|
if (! serial->isInitialized()) return 0;
|
||||||
|
size_t rt=serial->buffer->addData(buffer,size,partialWrites);
|
||||||
|
return rt;
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
class SerialWriter : public GwBufferWriter{
|
class SerialWriter : public GwBufferWriter{
|
||||||
private:
|
private:
|
||||||
HardwareSerial *serial;
|
HardwareSerial *serial;
|
||||||
|
@ -91,3 +131,6 @@ void GwSerial::flush(){
|
||||||
vTaskDelay(1);
|
vTaskDelay(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Stream * GwSerial::getStream(bool partialWrite){
|
||||||
|
return new GwSerialStream(this,partialWrite);
|
||||||
|
}
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
#include "GwLog.h"
|
#include "GwLog.h"
|
||||||
#include "GwBuffer.h"
|
#include "GwBuffer.h"
|
||||||
class SerialWriter;
|
class SerialWriter;
|
||||||
|
class GwSerialStream;
|
||||||
class GwSerial{
|
class GwSerial{
|
||||||
private:
|
private:
|
||||||
GwBuffer *buffer;
|
GwBuffer *buffer;
|
||||||
|
@ -28,5 +29,7 @@ class GwSerial{
|
||||||
void loop(bool handleRead=true);
|
void loop(bool handleRead=true);
|
||||||
bool readMessages(GwBufferWriter *writer);
|
bool readMessages(GwBufferWriter *writer);
|
||||||
void flush();
|
void flush();
|
||||||
|
Stream *getStream(bool partialWrites);
|
||||||
|
friend GwSerialStream;
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
42
src/main.cpp
42
src/main.cpp
|
@ -34,6 +34,7 @@ const unsigned long HEAP_REPORT_TIME=2000; //set to 0 to disable heap reporting
|
||||||
|
|
||||||
#include <Arduino.h>
|
#include <Arduino.h>
|
||||||
#include <NMEA2000_CAN.h> // This will automatically choose right CAN library and create suitable NMEA2000 object
|
#include <NMEA2000_CAN.h> // This will automatically choose right CAN library and create suitable NMEA2000 object
|
||||||
|
#include <ActisenseReader.h>
|
||||||
#include <Seasmart.h>
|
#include <Seasmart.h>
|
||||||
#include <N2kMessages.h>
|
#include <N2kMessages.h>
|
||||||
#include <WiFi.h>
|
#include <WiFi.h>
|
||||||
|
@ -94,6 +95,8 @@ int NodeAddress; // To store last Node Address
|
||||||
Preferences preferences; // Nonvolatile storage on ESP32 - To store LastDeviceAddress
|
Preferences preferences; // Nonvolatile storage on ESP32 - To store LastDeviceAddress
|
||||||
N2kDataToNMEA0183 *nmea0183Converter=NULL;
|
N2kDataToNMEA0183 *nmea0183Converter=NULL;
|
||||||
NMEA0183DataToN2K *toN2KConverter=NULL;
|
NMEA0183DataToN2K *toN2KConverter=NULL;
|
||||||
|
tActisenseReader *actisenseReader=NULL;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void SendNMEA0183Message(const tNMEA0183Msg &NMEA0183Msg,int id);
|
void SendNMEA0183Message(const tNMEA0183Msg &NMEA0183Msg,int id);
|
||||||
|
@ -140,6 +143,7 @@ void updateNMEACounter(int id,const char *msg,bool incoming,bool fail=false){
|
||||||
|
|
||||||
|
|
||||||
GwConfigInterface *sendUsb=config.getConfigItem(config.sendUsb,true);
|
GwConfigInterface *sendUsb=config.getConfigItem(config.sendUsb,true);
|
||||||
|
GwConfigInterface *usbActisense=config.getConfigItem(config.usbActisense,true);
|
||||||
GwConfigInterface *sendTCP=config.getConfigItem(config.sendTCP,true);
|
GwConfigInterface *sendTCP=config.getConfigItem(config.sendTCP,true);
|
||||||
GwConfigInterface *sendSeasmart=config.getConfigItem(config.sendSeasmart,true);
|
GwConfigInterface *sendSeasmart=config.getConfigItem(config.sendSeasmart,true);
|
||||||
GwConfigInterface *systemName=config.getConfigItem(config.systemName,true);
|
GwConfigInterface *systemName=config.getConfigItem(config.systemName,true);
|
||||||
|
@ -474,6 +478,16 @@ protected:
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
void handleN2kMessage(const tN2kMsg &n2kMsg){
|
||||||
|
if ( sendSeasmart->asBoolean() ) {
|
||||||
|
char buf[MAX_NMEA2000_MESSAGE_SEASMART_SIZE];
|
||||||
|
if ( N2kToSeasmart(n2kMsg, millis(), buf, MAX_NMEA2000_MESSAGE_SEASMART_SIZE) == 0 ) return;
|
||||||
|
socketServer.sendToClients(buf,N2K_CHANNEL_ID);
|
||||||
|
}
|
||||||
|
logger.logDebug(GwLog::DEBUG+1,"handling pgn %d",n2kMsg.PGN);
|
||||||
|
nmea0183Converter->HandleMsg(n2kMsg);
|
||||||
|
logger.logDebug(GwLog::DEBUG+1,"done pgn %d",n2kMsg.PGN);
|
||||||
|
};
|
||||||
void setup() {
|
void setup() {
|
||||||
|
|
||||||
uint8_t chipid[6];
|
uint8_t chipid[6];
|
||||||
|
@ -649,15 +663,20 @@ void setup() {
|
||||||
NMEA2000.ExtendReceiveMessages(nmea0183Converter->handledPgns());
|
NMEA2000.ExtendReceiveMessages(nmea0183Converter->handledPgns());
|
||||||
NMEA2000.SetMsgHandler([](const tN2kMsg &n2kMsg){
|
NMEA2000.SetMsgHandler([](const tN2kMsg &n2kMsg){
|
||||||
countNMEA2KIn.add(n2kMsg.PGN);
|
countNMEA2KIn.add(n2kMsg.PGN);
|
||||||
if ( sendSeasmart->asBoolean() ) {
|
handleN2kMessage(n2kMsg);
|
||||||
char buf[MAX_NMEA2000_MESSAGE_SEASMART_SIZE];
|
|
||||||
if ( N2kToSeasmart(n2kMsg, millis(), buf, MAX_NMEA2000_MESSAGE_SEASMART_SIZE) == 0 ) return;
|
|
||||||
socketServer.sendToClients(buf,N2K_CHANNEL_ID);
|
|
||||||
}
|
|
||||||
logger.logDebug(GwLog::DEBUG+1,"handling pgn %d",n2kMsg.PGN);
|
|
||||||
nmea0183Converter->HandleMsg(n2kMsg);
|
|
||||||
logger.logDebug(GwLog::DEBUG+1,"done pgn %d",n2kMsg.PGN);
|
|
||||||
});
|
});
|
||||||
|
if (usbActisense->asBoolean()){
|
||||||
|
actisenseReader=new tActisenseReader();
|
||||||
|
Stream *usbStream=usbSerial->getStream(false);
|
||||||
|
actisenseReader->SetReadStream(usbStream);
|
||||||
|
NMEA2000.SetForwardStream(usbStream);
|
||||||
|
NMEA2000.SetForwardType(tNMEA2000::fwdt_Actisense);
|
||||||
|
actisenseReader->SetMsgHandler([](const tN2kMsg &msg){
|
||||||
|
NMEA2000.SendMsg(msg);
|
||||||
|
handleN2kMessage(msg);
|
||||||
|
});
|
||||||
|
NMEA2000.SetForwardOwnMessages(true);
|
||||||
|
}
|
||||||
NMEA2000.Open();
|
NMEA2000.Open();
|
||||||
logger.logDebug(GwLog::LOG,"starting addon tasks");
|
logger.logDebug(GwLog::LOG,"starting addon tasks");
|
||||||
logger.flush();
|
logger.flush();
|
||||||
|
@ -680,7 +699,7 @@ void sendBufferToChannels(const char * buffer, int sourceId){
|
||||||
socketServer.sendToClients(buffer,sourceId);
|
socketServer.sendToClients(buffer,sourceId);
|
||||||
updateNMEACounter(MIN_TCP_CHANNEL_ID,buffer,false);
|
updateNMEACounter(MIN_TCP_CHANNEL_ID,buffer,false);
|
||||||
}
|
}
|
||||||
if (sendUsb->asBoolean() && checkFilter(buffer,USB_CHANNEL_ID,false)){
|
if (! actisenseReader && sendUsb->asBoolean() && checkFilter(buffer,USB_CHANNEL_ID,false)){
|
||||||
usbSerial->sendToClients(buffer,sourceId);
|
usbSerial->sendToClients(buffer,sourceId);
|
||||||
updateNMEACounter(USB_CHANNEL_ID,buffer,false);
|
updateNMEACounter(USB_CHANNEL_ID,buffer,false);
|
||||||
}
|
}
|
||||||
|
@ -791,9 +810,12 @@ void loop() {
|
||||||
//read channels
|
//read channels
|
||||||
socketServer.readMessages(&receiver);
|
socketServer.readMessages(&receiver);
|
||||||
receiver.id=USB_CHANNEL_ID;
|
receiver.id=USB_CHANNEL_ID;
|
||||||
usbSerial->readMessages(&receiver);
|
if (! actisenseReader) usbSerial->readMessages(&receiver);
|
||||||
receiver.id=SERIAL1_CHANNEL_ID;
|
receiver.id=SERIAL1_CHANNEL_ID;
|
||||||
if (serial1 && serCanRead ) serial1->readMessages(&receiver);
|
if (serial1 && serCanRead ) serial1->readMessages(&receiver);
|
||||||
|
if (actisenseReader){
|
||||||
|
actisenseReader->ParseMessages();
|
||||||
|
}
|
||||||
|
|
||||||
//handle message requests
|
//handle message requests
|
||||||
GwMessage *msg=mainQueue.fetchMessage(0);
|
GwMessage *msg=mainQueue.fetchMessage(0);
|
||||||
|
|
|
@ -123,6 +123,18 @@
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "usbActisense",
|
||||||
|
"label": "USB mode",
|
||||||
|
"type": "list",
|
||||||
|
"default": "false",
|
||||||
|
"description": "send/receive NMEA0183 or actisense format on USB",
|
||||||
|
"list": [
|
||||||
|
{"l":"actisense","v":"true"},
|
||||||
|
{"l":"nmea0183","v":"false"}
|
||||||
|
],
|
||||||
|
"category": "usb port"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "usbBaud",
|
"name": "usbBaud",
|
||||||
"label": "USB baud rate",
|
"label": "USB baud rate",
|
||||||
|
@ -151,7 +163,8 @@
|
||||||
"type": "boolean",
|
"type": "boolean",
|
||||||
"default": "true",
|
"default": "true",
|
||||||
"description": "send out NMEA data on the USB port",
|
"description": "send out NMEA data on the USB port",
|
||||||
"category": "usb port"
|
"category": "usb port",
|
||||||
|
"condition":{"usbActisense":"false"}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "receiveUsb",
|
"name": "receiveUsb",
|
||||||
|
@ -159,7 +172,8 @@
|
||||||
"type": "boolean",
|
"type": "boolean",
|
||||||
"default": "true",
|
"default": "true",
|
||||||
"description": "receive NMEA data on the USB port",
|
"description": "receive NMEA data on the USB port",
|
||||||
"category": "usb port"
|
"category": "usb port",
|
||||||
|
"condition":{"usbActisense":"false"}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "usbToN2k",
|
"name": "usbToN2k",
|
||||||
|
@ -167,7 +181,8 @@
|
||||||
"type": "boolean",
|
"type": "boolean",
|
||||||
"default": "true",
|
"default": "true",
|
||||||
"description": "convert NMEA0183 from the USB port to NMEA2000",
|
"description": "convert NMEA0183 from the USB port to NMEA2000",
|
||||||
"category": "usb port"
|
"category": "usb port",
|
||||||
|
"condition":{"usbActisense":"false"}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "usbReadFilter",
|
"name": "usbReadFilter",
|
||||||
|
@ -175,7 +190,8 @@
|
||||||
"type": "filter",
|
"type": "filter",
|
||||||
"default": "",
|
"default": "",
|
||||||
"description": "filter for NMEA0183 data when reading from USB\nselect aison|aisoff, set a whitelist or a blacklist with NMEA sentences like RMC,RMB",
|
"description": "filter for NMEA0183 data when reading from USB\nselect aison|aisoff, set a whitelist or a blacklist with NMEA sentences like RMC,RMB",
|
||||||
"category": "usb port"
|
"category": "usb port",
|
||||||
|
"condition":{"usbActisense":"false"}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "usbWriteFilter",
|
"name": "usbWriteFilter",
|
||||||
|
@ -183,7 +199,8 @@
|
||||||
"type": "filter",
|
"type": "filter",
|
||||||
"default": "",
|
"default": "",
|
||||||
"description": "filter for NMEA0183 data when writing to USB\nselect aison|aisoff, set a whitelist or a blacklist with NMEA sentences like RMC,RMB",
|
"description": "filter for NMEA0183 data when writing to USB\nselect aison|aisoff, set a whitelist or a blacklist with NMEA sentences like RMC,RMB",
|
||||||
"category": "usb port"
|
"category": "usb port",
|
||||||
|
"condition":{"usbActisense":"false"}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "serialDirection",
|
"name": "serialDirection",
|
||||||
|
|
Loading…
Reference in New Issue