Go Down

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

autopilotNOR

That is simple linear conversion:

TempC = -20 + (x-0)*(150- -20)/(3.3-0); // , where x is your voltage.

For library function you have to provide values in Kelvin, so you use
...CToKelvin(TempC)...

Or better would be use SI in code inside and use conversion only for view values. Then your function would be:

TempK = 253.15 + (x-0)*(423.15-253.15)/(3.3-0);

Then you can just pass TempK to library function.
That looks good so far, just one thing:
It results in a negative value. I get shown -21.7 C and just multiplying it by -1 doesn't work for any reason.

Can this be used for any kind of temp value like oiltemp ?

timolappalainen

What shows -21.7 and why it should be multiplied with -1?

If your x is positive, the function returns allways >=-20 C!

Linear scaling works for any kind of sensor, which has linear scale.  E.g. tank sensors have often non linear scale due to irregural tank shape. Then one has to split it several smaller ranges, where linear scaling gives reasonably good result.

autopilotNOR

What shows -21.7 and why it should be multiplied with -1?

If your x is positive, the function returns allways >=-20 C!

Linear scaling works for any kind of sensor, which has linear scale.  E.g. tank sensors have often non linear scale due to irregural tank shape. Then one has to split it several smaller ranges, where linear scaling gives reasonably good result.
The MFD showed a temp of -21.7 C. The voltage is currently 1.151 V on the analog in. But now the engine is almost warm (~55 C)
In code I use the following:
Code: [Select]
double EngineCoolantTemp = 253.15 + (analogRead(coolantTempPin)-0)*(423.15-253.15)/(3.3-0);


and pass the EngineCoolantTemp through return back. In SendN2kMessagesDynamic I call the function by EngineCoolantTempRead() inside EngineCoolantTempRead() with all the others which have todo with Engine parameter dynamic.


timolappalainen

analogRead(coolantTempPin) does not return voltage. It return integer value depending of your analog resesolution. So e.g. with 10 bit resolution it will return value 0 - 1023 and for 12 bit resolution 0 - 4095. The resolution depends of device you are using and in some devices you can control it with analogReadResolution() function.

Then you need to scale value from analogRead with range it is using. That depends of analog reference voltage. E.g. on Teensy you can select internal analog reference with analogReference(0) and then it will use 3.3 V ref. In that case you you convert 10 bit analog pin data to voltage with function analogRead(coolantTempPin)/1023*3.3

So check which resolution and reference you have to get right conversion to voltage.

autopilotNOR

analogRead(coolantTempPin) does not return voltage. It return integer value depending of your analog resesolution. So e.g. with 10 bit resolution it will return value 0 - 1023 and for 12 bit resolution 0 - 4095. The resolution depends of device you are using and in some devices you can control it with analogReadResolution() function.

Then you need to scale value from analogRead with range it is using. That depends of analog reference voltage. E.g. on Teensy you can select internal analog reference with analogReference(0) and then it will use 3.3 V ref. In that case you you convert 10 bit analog pin data to voltage with function analogRead(coolantTempPin)/1023*3.3

So check which resolution and reference you have to get the right conversion to voltage.
That was actually my initial question. How to map the 0-1023 to the coolant temp value. This you wrote here I know about (would be very difficult without i guess)

The point I need to know here is what to do with the 0-1023? Usually, there is a range it can be mapped to like I do with the oil pressure. There I use the custom map function (you showed me once I tried my luck with the rudder position) to 0 - 10000 pascals.

In the example of rudder position, the drive I have and the MFD Axiom shows -50 - 0 + 50 degrees. So I map here the 0-1023 like this rudderposition=(analogRead(rudderPositionPin), 49, 1023, -50, 50).

So in case of temperature, I don't know the range I can map it on. I thought there are somewhere definitions or standards which tells me what to use.

Heikkif

Hi Timo,

Thanks for the prompt replies. Question of GPS compass has been discussed here:

https://forum.arduino.cc/index.php?topic=366167.0

So necessarily it does not work that way. Was not mentioned what kind of base was used.  Anyhow I want to have a GPS to the bus so I will get some receivers. This could be what I will buy:

 https://www.banggood.com/Radiolink-M8N-GPS-Module-UBX-M8030-for-Naze32-APM-CC3D-SP-F3-Naze32-Flip32-PX4-Flight-Controller-p-1051291.html?rmmds=search


It has freq. of 10 Hz.


I have rate of turn measured with a quite good gyro at autopilot. I could feed that to bus and use it on another Arduino to improve dynamics of filtered heading from calculations the same way that I did with roll and pitch calculated from accel signals.


Would it be all wrong if arduino would read GPS-position of the other sensor from bus and other would be connected to serial?

timolappalainen

Please do not quote everything as it is, since it does not make sense, since same can be read on previous post.

Do you mean dMap function example I wrote on post #351? map is just a simple function for making linear scaling I wrote. Arduino map uses long values and dMap doubles.

Anyway in principle you 0-1023 maps finally to your temperature values -20 - 150 C. You can also use direct mapping, if you know that it is right: tempK=dMap(analogRead(coolantTempPin),0,1023,253.15,423.15);
This is naturally fastest way to calculate it, since you do mapping only once. But now, if your reference changes e.g. by providing more accurate external 2.5V reference, you have to remember that then 0-1023 values are within 0 - 2.5 V, which means that 1023 does not map to 423.15 K anymore. So if you know your sensor mapping in voltages and you make it as commonly usable function, you need two mapping.
Code: [Select]

...
const double VRef=3.3;
const double AnalogMax=1023;
...
double ReadAnalogVoltage(int pin) {
  return dMap(analogRead(pin),0,AnalogMax,0,VRef);
}
...
double SensorMxyzToKelvin(double Vin) {
  return dMap(Vin,0,3.3,253.15,423.15);
}
...
double ReadTemp(coolantTempPin) {
  return SensorMxyzToKelvin(ReadAnalogVoltage());
}
...


This makes your code a bit more abstract, understantable and movable, but also unfortunately also slower depending of you processor. Teensy works rather well with double, but Mega lags much.

There is no standards, since sensors has different output. But the mapping range depends of sensor and you may find it from the specifig sensor data sheets.

timolappalainen

HeikkiF,

Interesting GPS module. Have you found any data sheets? Does it take 3.3 V or 5 V in? What are cummunication pin levels - TTL? Pin order etc.

As in discussion points, you still will have unsynchronized errors in GPS. I think that can work on land as in laser pointer, since the position can be filtered a lot, when antennas are not moving.

Note also that using single GPS for heading does not give right result. GPS returns your moving direction and compass (GPS, solid state or what ever) returns your heading. Depending of conditions - specially on currents they may differ a lot. So you can not use single GPS for calibrating magnetometer data.

Note also that my example 20 cm error may be far too optimistic. It is possible that two different GPS has 1 meter or even more error in different directions. On the other hand I have not tested accuracy of those and specially two sensor around same position. You can only byu two, put them to e.g. 10 m away of each other, plot positions of them and analyze data is it usable. Simulate boat movements by moving them up and down, but keeping direction same. I am interested to hear results.

From bus you get maximum 1 Hz position, so I think that is unusable and late.

Heikkif

Those GPS modules seem to be not so well documented.  If i buy I will try it with 3.3 V Vcc first.
http://radiolink.com.cn/doce/product-detail-115.html

Heikkif

The max. freq. for position via bus being 1Hz is it because #define TimeUpdatePeriod 1000 or is there other limitations in NMEA2000? If not what kind of delays is there in data transmission via bus?  I quess one could delay the position coming straight from GPS if time info is delayed on the bus.

timolappalainen

Sorry small mistake. I was thinking about 1 Hz PGN129029/GNSS, but there is also 10 Hz PGN129025/LatLonRapid. But not all GPS provide PGN129025. And specially if you have old NMEA0183 GPS with converter, there is only 1 Hz PGN129029.

And if you are planning to put other GPS to the bus by yourself, then you can provide PGN129025 with 10 Hz and PGN129029 1 Hz to the bus.

PGN129025 is single frame higher priority message. One frame transfer takes about 400 us. Since bus is multimaster bus, there may be others sending data at same time and our frame transfer may be delayed. Lower source address has higher priority. So you can try to set your device source address to 0, but then depending of other devices on the bus higher priority devices may rise your source address during address claiming procedure. But in normal boat bus I would expect that extra delay would be very rare.

So if you sending lat/lon in 100 ms period, the transfer delay should be less than 1 ms, which is <1/100

Heikkif

#581
Oct 02, 2018, 08:16 pm Last Edit: Oct 02, 2018, 08:49 pm by Heikkif
Is rate of turn rapid also? N2kMessages.h nor https://www.nmea.org/content/nmea_standards/messages_pgns.asp
 does not mention rapid. I have been thinking of trying this GPS compass thing on another Arduino than where autopilot is and where rate of turn is measured  already. It would be nice to have rate of turn via bus but 1 Hz feels slow.

timolappalainen

I do not have NMEA 2000 documentation and if I would I could not say anything due to agreement. So all information has to be digged from public docs.

NMEA 2000 defines default rates and rate limits for PGNs. Certified systems follow these rates. If you make system for your own boat, you can use different rates. Normally fast packet messages has max. 1 Hz rate. Single frame packest are up to 200 Hz. There is also limits for min. rate. E.g. if you send temperature 130316 with 0.1 Hz, MFDs thinks that as lost data between transmits.

But anyway I digged default rates for 127250 10 Hz, 127257 1 Hz, 127251 10 Hz

So no problem to use 10 Hz for rate of turn. And as I mentioned for your own system you can use 20 Hz, if you like.

autopilotNOR

Hey Timo,

regarding the Coolant temp in case of Raymarine Axiom. I have figured out that I have to map the sensor values from -20 to 150 C in Kelvin.

Code: [Select]
double EngineCoolantTemp = dMap(analogRead(coolantTempPin), coolantTempPin_Min, coolantTempPin_Max, 253, 423);
So this was showing the correct values in C on the MFD. I guess this is the case for all other temperaturs as well.

another thing regarding RPM. I could do this now with freqMulti library. Working good so far. To get the values back to 0 when the engine is not running I overwrite the RPM value with an if..else. If rpm available do measure every 500 ms and calculate and else is if rpm lower than 200 than set rpm to 0.

Working so far. But as soon as I try to push the values into a circular buffer I do get just strange stuff. So my question is how to smooth the RPM values?


Code: [Select]

double ReadEngineRpm() {
    if (freq1.available()) {
      sum1 = sum1 + freq1.read();
      count1 = count1 + 1;
    }

    if (timeout > 500) {
      if (count1 > 0) {
        EngineSpeed = (freq1.countToFrequency(sum1 / count1)*2);
      }

      sum1 = 0;
      count1 = 0;
      timeout = 0;
    }

    if (EngineSpeed >= 200)
    {
        EngineSpeed = EngineSpeed;
    }
    else
    {
        EngineSpeed = 0;
    }
        return EngineSpeed;

}


I am sure there are better ways to implement this right?

Heikkif

#584
Oct 03, 2018, 04:51 pm Last Edit: Oct 03, 2018, 05:28 pm by Heikkif
https://www.navilock.de/produkte/G_62571/merkmale.html
https://www.navilock.de/produkte/S_62586/merkmale.html

A better documented GPS with TTL serial.

Go Up