Go Down

Topic: NMEA 2000 Shield (Read 168082 times) previous topic - next topic

timolappalainen

What do you mean by "if I set the temp sensor to Water"? Is there some switch to define what sensor is for?

It is very strange, if they would use some proprietary. Anyway if you listen bus at the same time with Actisense NR, while showing data on HDS, you should see the traffic. Actisense NR may show them unknown messages from source 10. There is one possiblity that data will be sent as no extended format. I do not know does library actually handle those messages and forward them to the USB.

seamaster

#256
Aug 01, 2017, 10:47 pm Last Edit: Aug 01, 2017, 11:54 pm by seamaster
Quote
Timo, I installed the ActisenseListener and ran Actisense NR -- if I set the temp sensor to Water I get the values showing up under Name: Temperature and Name: Environmental Parameters -- if the sensor is set to anything else, there is no active data under those items that were updating when set to Water in Actisense NR -- but, the weird bit -- the data showing correctly on the Lowrance HDS and data under the Lowrance Device List.   Are they doing something non-standard?
If you are using Loweance temp sensor please pay attention to the data sheet of the product.  All Lawrence temp sensors output proprietary PGN
**************
Specifications
Temperature Range between -20 and 80 degrees Celsius.
PGNs transmitted
59392 - ISO Acknowledgment
60928 - ISO Address Claim
126996 - Product Information
65285 - Temperature with Instance  //this is the one that's proprietary
**************
I went through this with my Furuno MFD showing the temp sensor, but not reading the data. I was unpleasantly surprised that wasn't the configuration of the sensor for water, engine room  temp, etc., that was screwing up the reading, but rather the Lowrance proprietary PGN.
Maybe if you can capture the raw data from the sensor, Timo can add this PGN to the library if possible to easy interpret what is what...
Cheers!

seamaster

#257
Aug 01, 2017, 10:57 pm Last Edit: Aug 01, 2017, 11:11 pm by seamaster
What do you mean by "if I set the temp sensor to Water"? Is there some switch to define what sensor is for?

Timo,
Lawrance uses their MF Displays to configure their sensors. Here is default sensor configurations -
 an extract from the installation manual:
**********
Fluid Level Sensor - tank levels for fuel*, water, gray water, live well, oil, and black water
• Fuel Flow Sensor - flow rate measurements of fuel for gasoline powered boats
• Fuel Data Manager - fuel used data from fuel flow messages it receives from up to three
NMEA 2000 compatible engines
• Temperature Sensor - temperatures for water*, outside, inside, engine room, cabin, live well,
bait well, refrigeration, and heating system
• Thru-Hull Temperature Sensor - temperatures for water*, outside, inside, engine room, cabin,
live well, bait well, refrigeration, and heating system
• Speed Sensor - boat speed
• Pressure Sensor - pressure data: Engine Boost Pressure, Engine Oil Pressure, Engine Water
Pressure*, Transmission Oil Pressure and Pitot Speed
* Sensor is pre-configured to display this information.

**********
Cheers,

mavromatis

What do you mean by "if I set the temp sensor to Water"? Is there some switch to define what sensor is for?

It is very strange, if they would use some proprietary. Anyway if you listen bus at the same time with Actisense NR, while showing data on HDS, you should see the traffic. Actisense NR may show them unknown messages from source 10. There is one possiblity that data will be sent as no extended format. I do not know does library actually handle those messages and forward them to the USB.
Hi Timo -- like Seamaster stated, Lowrance allows you to setup the sensor via their MFD, I guess that is why they do some proprietary stuff?  Do you want me to ship you one of these sensors setup as Engine Rm or is it easier for me to capture the raw data so we can try to add the functionality to the library?


If you are using Loweance temp sensor please pay attention to the data sheet of the product.  All Lawrence temp sensors output proprietary PGN
**************
Specifications
Temperature Range between -20 and 80 degrees Celsius.
PGNs transmitted
59392 - ISO Acknowledgment
60928 - ISO Address Claim
126996 - Product Information
65285 - Temperature with Instance  //this is the one that's proprietary
**************
I went through this with my Furuno MFD showing the temp sensor, but not reading the data. I was unpleasantly surprised that wasn't the configuration of the sensor for water, engine room  temp, etc., that was screwing up the reading, but rather the Lowrance proprietary PGN.
Maybe if you can capture the raw data from the sensor, Timo can add this PGN to the library if possible to easy interpret what is what...
Cheers!
Bummer!  So are we out of luck? Or do you think there is a way I can capture the raw data from the sensor and share with the group -- just let me know how best to do this?

timolappalainen

We seem to have information for PGN 65285 for Lowrance proprietary data.
{ "Lowrance: Temperature", 65285, false, 8, 0,
  { { "Manufacturer Code", 11, RES_MANUFACTURER, false, "=140", "Lowrance" }
  , { "Reserved", 2, RES_NOTUSED, false, 0, "" }
  , { "Industry Code", 3, RES_LOOKUP, false, "=4", "Marine Industry" }
  , { "Temperature Instance", 4, 1, false, 0, "" }
  , { "Temperature Source", 4, 1, false, 0, "" }
  , { "Actual Temperature", BYTES(2), RES_TEMPERATURE, false, "K", "" }
  , { 0 }
  }
}

So write handler for PGN 65285 and try code:
bool ParseN2kLowranceTempPGN65285(const tN2kMsg &N2kMsg, unsigned char &TempInstance, tN2kTempSource &TempSource,
                     double &ActualTemperature) {
  ActualTemperature=N2kDoubleNA;
  TempInstance=0;
  TempSource=N2kts_SeaTemperature;
  if (N2kMsg.PGN!=65285L) return false;
  int Index=0;
  uint16_t Manufacturer=(N2kMsg.Get2ByteUInt(Index) & 0x7ff);
  if ( Manufacturer != 140 ) return false; // Not Lowrance proprietary PGN
  uint8_t b=N2kMsg.GetByte(Index);
  TempInstance=(b & 0x0f);
  TempSource=(tN2kTempSource)( (b & 0xf0) >> 4 );
  ActualTemperature=N2kMsg.Get2ByteUDouble(0.01,Index);
 
  return true;
}

seamaster

Quote
if ( Manufacturer != 140 ) return false; // Not Lowrance proprietary PGN
Timo,
don't forget that all of their sensors could be sold and go by either Lowrance, B&G or Simrad names. I think they have different manufacturer numbers/codes.
I found:
SIMRAD 1857;
Lowrance 140;
B&G ??; // I couldnt find one for them in the document here

http://www.nmea.org/Assets/20160116%20_%20jan%202016%20manu%20code%20and%20product%20code.pdf

My point is: these 3 manufactures need to be included in the code not just Lawrance.

timolappalainen

B&G is 381 - on list "NMEA 2000 registration list". So change rule to:
  if ( !(Manufacturer == 140 ||
         Manufacturer == 1857 ||
         Manufacturer == 381) ) return false; // Not Lowrance, Simrad or B&G proprietary PGN

Rinkelein

I just tested WindMonitor with my own DUE and it works OK. I made tests with old NMEA2000_due/due_can and new version of both (just released on my GitHub few minutes ago). So I think the problem is not with library.

If you can read, but TX fails, there is some problem with your TX side. Have you checked TX pin is connected? Are terminal resistors OK? Maybe tranceiver does not work on TX?
Just to let you know that we have tested the TX side but weren't successfull. Several fora stated that this could be caused by the chip SN65HVD230. I've ordered a MCP2551 instead and will let you know later on. Thanks so far.

Rinkelein

I just tested WindMonitor with my own DUE and it works OK. I made tests with old NMEA2000_due/due_can and new version of both (just released on my GitHub few minutes ago). So I think the problem is not with library.

If you can read, but TX fails, there is some problem with your TX side. Have you checked TX pin is connected? Are terminal resistors OK? Maybe tranceiver does not work on TX?
Just to let you know that we weren't able to get the TX side working. From other fora we learned that this could be caused by the SN65HVD230 chip. We have ordered a MCP2551 and let you know the results later on. Many thanks so far.

timolappalainen

With DUE you need to remember to power MCP2551 with 3.3V only. I prefer MCP2562, since you can power it with 5V and provide 3.3V to pin 5 for defining IO levels.

mavromatis

#265
Aug 02, 2017, 04:54 pm Last Edit: Aug 02, 2017, 05:31 pm by mavromatis
We seem to have information for PGN 65285 for Lowrance proprietary data.
{ "Lowrance: Temperature", 65285, false, 8, 0,
  { { "Manufacturer Code", 11, RES_MANUFACTURER, false, "=140", "Lowrance" }
  , { "Reserved", 2, RES_NOTUSED, false, 0, "" }
  , { "Industry Code", 3, RES_LOOKUP, false, "=4", "Marine Industry" }
  , { "Temperature Instance", 4, 1, false, 0, "" }
  , { "Temperature Source", 4, 1, false, 0, "" }
  , { "Actual Temperature", BYTES(2), RES_TEMPERATURE, false, "K", "" }
  , { 0 }
  }
}

So write handler for PGN 65285 and try code:
bool ParseN2kLowranceTempPGN65285(const tN2kMsg &N2kMsg, unsigned char &TempInstance, tN2kTempSource &TempSource,
                     double &ActualTemperature) {
  ActualTemperature=N2kDoubleNA;
  TempInstance=0;
  TempSource=N2kts_SeaTemperature;
  if (N2kMsg.PGN!=65285L) return false;
  int Index=0;
  uint16_t Manufacturer=(N2kMsg.Get2ByteUInt(Index) & 0x7ff);
  if ( Manufacturer != 140 ) return false; // Not Lowrance proprietary PGN
  uint8_t b=N2kMsg.GetByte(Index);
  TempInstance=(b & 0x0f);
  TempSource=(tN2kTempSource)( (b & 0xf0) >> 4 );
  ActualTemperature=N2kMsg.Get2ByteUDouble(0.01,Index);
 
  return true;
}

That's great Timo!  I guess I should have looked under the covers deeper -- Will add this method to my code and test at the boat today... will let you know.  My sensor is branded Lowrance with a manufacture code of 140 so we should be good.

Just to be clear, for the handler I'm adding:
Code: [Select]

...
{130314L,&Pressure},
  {130316L,&TemperatureExt},
  {65285,&LowranceTemp},
  {0,0}

mavromatis

#266
Aug 03, 2017, 02:26 am Last Edit: Aug 03, 2017, 03:56 am by mavromatis
That worked!  However, the source is "sea" not "engine room" -- I can live with that but not sure if you want to correct that in the library if you want to officially support this sensor.

This code:
Code: [Select]

void LowranceTemp(const tN2kMsg &N2kMsg) {
    unsigned char TempInstance;
    tN2kTempSource TempSource;
    double ActualTemperature;
   
    if (ParseN2kLowranceTempPGN65285(N2kMsg,TempInstance,TempSource,ActualTemperature) ) {
        OutputStream->print("Lowrance Temperature source: "); PrintN2kEnumType(TempSource,OutputStream,false);
        PrintLabelValWithConversionCheckUnDef(", actual temperature (F): ",ActualTemperature,&KelvinToF);
    } else {
      OutputStream->print("Failed to parse PGN: ");  OutputStream->println(N2kMsg.PGN);
    }
}

bool ParseN2kLowranceTempPGN65285(const tN2kMsg &N2kMsg, unsigned char &TempInstance, tN2kTempSource &TempSource,
                     double &ActualTemperature) {
  ActualTemperature=N2kDoubleNA;
  TempInstance=0;
  TempSource=N2kts_SeaTemperature;
  if (N2kMsg.PGN!=65285L) return false;
  int Index=0;
  uint16_t Manufacturer=(N2kMsg.Get2ByteUInt(Index) & 0x7ff);
  if ( Manufacturer != 140 ) return false; // Not Lowrance proprietary PGN
  uint8_t b=N2kMsg.GetByte(Index);
  TempInstance=(b & 0x0f);
  TempSource=(tN2kTempSource)( (b & 0xf0) >> 4 );
  ActualTemperature=N2kMsg.Get2ByteUDouble(0.01,Index);
 
  return true;
}


Produces:
Code: [Select]
Lowrance Temperature source: sea, actual temperature (F): 88.88

timolappalainen

Are you sure it is returning everything right and my code was right? Did you test output with different temp source - does it change? If the enum tN2kTempSource does not match to Lowrance, we need to define own:
Code: [Select]
enum tN2kLowranceTempSource {
                            N2kLts_EngineRoomTemperature=0
                            };

const char* tN2kLowranceTempSourceStrs[] = { "engine room" };

and solve what enum values are.

mavromatis

Are you sure it is returning everything right and my code was right? Did you test output with different temp source - does it change? If the enum tN2kTempSource does not match to Lowrance, we need to define own:
Code: [Select]
enum tN2kLowranceTempSource {
                            N2kLts_EngineRoomTemperature=0
                            };

const char* tN2kLowranceTempSourceStrs[] = { "engine room" };

and solve what enum values are.
I didn't try changing the TempSource -- but the TempInstance returned should have been 3 (as shown on my Lowrance HDS) which is "Engine Room", not 0 and Sea Temp as passed in the handler.  

Code: [Select]

bool ParseN2kLowranceTempPGN65285(const tN2kMsg &N2kMsg, unsigned char &TempInstance, tN2kTempSource &TempSource,
                     double &ActualTemperature) {
  ActualTemperature=N2kDoubleNA;
  >>>> TempInstance=0;
  >>>> TempSource=N2kts_SeaTemperature;
  if (N2kMsg.PGN!=65285L) return false;
  int Index=0;
  uint16_t Manufacturer=(N2kMsg.Get2ByteUInt(Index) & 0x7ff);
  if ( Manufacturer != 140 ) return false; // Not Lowrance proprietary PGN
  uint8_t b=N2kMsg.GetByte(Index);
  >>>> TempInstance=(b & 0x0f);
  >>>> TempSource=(tN2kTempSource)( (b & 0xf0) >> 4 );
  ActualTemperature=N2kMsg.Get2ByteUDouble(0.01,Index);
 
  return true;
}


But the code you provided didn't seem to get that  from the message data?

The Lowrance PGN I used in the handler was "65285", not "65285L" -- not sure if that matters?
Code: [Select]

...
 {130316L,&TemperatureExt},
 {65285,&LowranceTemp},


Interestingly, the Actual Temperature was correct value.


timolappalainen

Change your printing code to:
Code: [Select]

OutputStream->print("Lowrance Temperature (");
OutputStream->print(TempInstance);
OutputStream->print(") source: ");
OutputStream->print((unsigned char)TempSource);

and try with different sources (engine, water, cabin) and report the results.

L is integer literal and defines value to be treated as long. Actually for PGNs should have been UL

Go Up