diff --git a/lib/nmea2kto0183/N2kDataToNMEA0183.h b/lib/nmea2kto0183/N2kDataToNMEA0183.h index 559ab88..445f2e5 100644 --- a/lib/nmea2kto0183/N2kDataToNMEA0183.h +++ b/lib/nmea2kto0183/N2kDataToNMEA0183.h @@ -56,5 +56,6 @@ public: } virtual void loop(); virtual ~N2kDataToNMEA0183(){} + virtual const unsigned long* handledPgns()=0; }; #endif \ No newline at end of file diff --git a/lib/nmea2kto0183/N2kToNMEA0183Functions.h b/lib/nmea2kto0183/N2kToNMEA0183Functions.h index 3d3fa2e..8e2f26f 100644 --- a/lib/nmea2kto0183/N2kToNMEA0183Functions.h +++ b/lib/nmea2kto0183/N2kToNMEA0183Functions.h @@ -10,8 +10,10 @@ #include #include #include "N2kDataToNMEA0183.h" +#include class N2kToNMEA0183Functions : public N2kDataToNMEA0183 { + typedef void (N2kToNMEA0183Functions::*N2KConverter)(const tN2kMsg &N2kMsg); private: static const unsigned long RMCPeriod = 500; static void setMax(GwBoatItem *maxItem, GwBoatItem *item) @@ -88,6 +90,28 @@ private: unsigned long LastPosSend; unsigned long NextRMCSend; unsigned long lastLoopTime; + + std::map converters; + + /** + * register a n2k message converter + * each of the converter functions must be registered in the constructor + **/ + void registerConverter(long pgn,N2KConverter converter){ + converters[pgn]=converter; + } + virtual const unsigned long * handledPgns(){ + logger->logString("CONV: # %d handled PGNS",(int)converters.size()); + unsigned long *rt=new unsigned long[converters.size()+1]; + int idx=0; + for (std::map::iterator it=converters.begin(); + it != converters.end();it++){ + rt[idx]=it->first; + idx++; + } + rt[idx]=0; + return rt; + } void SetNextRMCSend() { NextRMCSend = millis() + RMCPeriod; } //*************** the converters *********************** @@ -458,6 +482,23 @@ public: tripLog = boatData->getUint32Item(F("TripLog"), true, 0, mtr2nm); daysSince1970 = boatData->getUint32Item(F("DaysSince1970"), true, 4000); secondsSinceMidnight = boatData->getDoubleItem(F("SecondsSinceMidnight"), true, 4000); + + //register all converter functions + //for each vonverter you should have a member with the N2KMsg as parameter + //and register it here + //with this approach we easily have a list of all handled + //pgns + registerConverter(127250UL,&N2kToNMEA0183Functions::HandleMsg); + registerConverter(127258UL,&N2kToNMEA0183Functions::HandleVariation); + registerConverter(128259UL,&N2kToNMEA0183Functions::HandleBoatSpeed); + registerConverter(128267UL,&N2kToNMEA0183Functions::HandleDepth); + registerConverter(129025UL,&N2kToNMEA0183Functions::HandlePosition); + registerConverter(129026UL,&N2kToNMEA0183Functions::HandleCOGSOG); + registerConverter(129029UL,&N2kToNMEA0183Functions::HandleGNSS); + registerConverter(130306UL,&N2kToNMEA0183Functions::HandleWind); + registerConverter(128275UL,&N2kToNMEA0183Functions::HandleLog); + registerConverter(127245UL,&N2kToNMEA0183Functions::HandleRudder); + registerConverter(130310UL,&N2kToNMEA0183Functions::HandleWaterTemp); } virtual void loop() { @@ -470,33 +511,14 @@ public: } virtual void HandleMsg(const tN2kMsg &N2kMsg) { - switch (N2kMsg.PGN) - { - case 127250UL: - HandleHeading(N2kMsg); - case 127258UL: - HandleVariation(N2kMsg); - case 128259UL: - HandleBoatSpeed(N2kMsg); - case 128267UL: - HandleDepth(N2kMsg); - case 129025UL: - HandlePosition(N2kMsg); - case 129026UL: - HandleCOGSOG(N2kMsg); - case 129029UL: - HandleGNSS(N2kMsg); - case 130306UL: - HandleWind(N2kMsg); - case 128275UL: - HandleLog(N2kMsg); - case 127245UL: - HandleRudder(N2kMsg); - case 130310UL: - HandleWaterTemp(N2kMsg); + std::map::iterator it; + it = converters.find(N2kMsg.PGN); + if (it != converters.end()){ + //logger->logString("CONV: handle PGN %ld",N2kMsg.PGN); + //call to member function - see e.g. https://isocpp.org/wiki/faq/pointers-to-members + ((*this).*(it->second))(N2kMsg); + return; } } - -private: }; #endif \ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp index a717dab..30a68a3 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -59,21 +59,7 @@ N2kDataToNMEA0183 *nmea0183Converter=N2kDataToNMEA0183::create(&logger, &boatDat // Set the information for other bus devices, which messages we support const unsigned long TransmitMessages[] PROGMEM = {127489L, // Engine dynamic 0 - }; -const unsigned long ReceiveMessages[] PROGMEM = {/*126992L,*/ // System time - 127250L, // Heading - 127258L, // Magnetic variation - 128259UL,// Boat speed - 128267UL,// Depth - 129025UL,// Position - 129026L, // COG and SOG - 129029L, // GNSS - 130306L, // Wind - 128275UL,// Log - 127245UL,// Rudder - 0 - }; - +}; // Forward declarations void HandleNMEA2000Msg(const tN2kMsg &N2kMsg); void SendNMEA0183Message(const tNMEA0183Msg &NMEA0183Msg); @@ -249,7 +235,7 @@ void setup() { NMEA2000.SetMode(tNMEA2000::N2km_ListenAndNode, NodeAddress); NMEA2000.ExtendTransmitMessages(TransmitMessages); - NMEA2000.ExtendReceiveMessages(ReceiveMessages); + NMEA2000.ExtendReceiveMessages(nmea0183Converter->handledPgns()); NMEA2000.AttachMsgHandler(nmea0183Converter); // NMEA 2000 -> NMEA 0183 conversion NMEA2000.SetMsgHandler(HandleNMEA2000Msg); // Also send all NMEA2000 messages in SeaSmart format