Go Down

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

autopilotNOR

#540
Sep 15, 2018, 10:21 am Last Edit: Sep 15, 2018, 10:23 am by autopilotNOR
It is a part of the NMEA2000_teensy.cpp. There this is defined:
Code: [Select]
#if NMEA2000_TEENSY_VER == 1 
  CANbus = new FlexCAN(250000);
#else
 
#if NMEA2000_TEENSY_MAX_CAN_BUSSES == 2 && NMEA2000_TEENSY_VER>1
  if ( CANBusIndex>1 ) CANBusIndex=1;
  if ( CANBusIndex==0 ) {
    CANbus = &Can0;
  } else {
    CANbus = &Can1;
  }
#else
  (void)CANBusIndex; // just avoid warning
  CANbus = &Can0;
#endif

#endif
  DefTimeOut=_DefTimeOut;
}


This doesn`t say that it is changeable between can1 & can2 but I thought it could be a hint that it is possible. If I understand that right than it is about the 3.2 version.

I think this file is from your repo. I usually just use your files.

All this is because I wanted to use the freqMeasure library for rpm. There the input pin is fixed to pin 3.

The rpm thing is really annoying... One of the last thing I just do not get any working solution done.

autopilotNOR

Regarding engine torque (PGN 127489 EngineTorque), this is part of engine dynamic parameters. Since this is calculated from EngineSpeed (PGN 127488 EngineSpeed) and the airflow into the engine, shouldn´t this be part of Engine parameters rapid (PGN 127488) instead of Engine parameters dynamic?

Just a thought..

timolappalainen

You select CAN bus on contructor second parameter - not with any define. And As I mentioned, only Teensy 3.6 has two CAN bus.

For RMP you could use FreqMeasureMulti library, which is on Teensy framework. See. https://github.com/PaulStoffregen/FreqMeasureMulti It supports pins 5, 6, 9, 10, 20, 21, 22, 23 for Teensy 3.1-3.6 as in readme.

For frequency you need to use lowpass filter with very high filtering, which depends of scaling. I have scaling 1/11 from my altenator W and I get reasonably steady readings with FilterWeight 0.005. Note that with too small FilterWeight RMP gets very slow.

I have not tested code below, but it should work if you fill other necessary code for ...

Code: [Select]

#include "FreqMeasureMulti.h"

class tFilteredRPM {
protected:
  double Frequency;
  double FilterWeight;
  double Scale;
  uint32_t Pin;
  bool Started;
  FreqMeasureMulti FreqMeasure;
public:
  tFilteredRPM(uint32_t _Pin, double _FilterWeight, double _Scale=1) :
    Frequency(-1), FilterWeight(_FilterWeight), Scale(_Scale), Pin(_Pin), Started(false) {}
    
  // Call this in loop as often as possible
  void Update() {
    if ( Started ) {
      if ( FreqMeasure.available() ) {
        if ( Frequency<0 ) { // Reset at first read
          Frequency=FreqMeasure.read();
        } else {
          Frequency = (FilterWeight * FreqMeasure.read() + (1 - FilterWeight) * Frequency );
        }
        while ( FreqMeasure.available() ) {
          Frequency = (FilterWeight * FreqMeasure.read() + (1 - FilterWeight) * Frequency );
        }
      }
    } else {
      FreqMeasure.begin(Pin);
      Started=true;
    }
  }

  // Call this to read current RPM
  double Read() const {
    double RPM=0;
    if ( Frequency>=0 ) RPM=FreqMeasureMulti::countToFrequency(Frequency)*60*Scale;
    return RPM;
  }
};

tFilteredRPM RPM(22,0.005,1.0/11.0);

void setup() {
...
}

#define RPMSendPeriod 100

void SendRPM() {
  static unsigned long NextRPMSendTime=millis()+RPMSendPeriod;
  if ( NextRPMSendTime<millis() {
    NextRPMSendTime+=RPMSendPeriod;
    ... RPM.Read()...
  }
}

void loop() {
  ...
  RPM.Update();
  SendRPM();
  ...
}

timolappalainen

...shouldn´t this be part of Engine parameters rapid (PGN 127488) instead of Engine parameters dynamic?

Just a thought..
Do not think too much what NMEA organization has been desided. NMEA2000 content is their thoughts and not allways logic.

autopilotNOR

Thank you Timo!

If I write that something is defined doesn't mean the command #define, this just to clarify.

I`ll try to get that code running. Some things from this sketch I have never seen before like this "public:" & "protected". But I will figure that out I guess! The filtering thing looks also like a new thing for me, special this with FilterWeight. Do you know a place where this method is described since I would like to now how this is working and in which cases I could uses this functionality.

timolappalainen

"public:" & "protected" belongs to classes. With classes you can define, which functions or properties are public so that they can be called outside from class. And which are just for internal or inherited use.

The filter method works with many noise data. I use it also for analog. FilterWeight depends of incoming data noice and speed. I use a bit different class and wrote that for example, but it does the main thing - low pass filtering.

See. e.g. https://kiritchatterjee.wordpress.com/2014/11/10/a-simple-digital-low-pass-filter-in-c/

autopilotNOR

"public:" & "protected" belongs to classes. With classes you can define, which functions or properties are public so that they can be called outside from class. And which are just for internal or inherited use.

The filter method works with many noise data. I use it also for analog. FilterWeight depends of incoming data noice and speed. I use a bit different class and wrote that for example, but it does the main thing - low pass filtering.

See. e.g. https://kiritchatterjee.wordpress.com/2014/11/10/a-simple-digital-low-pass-filter-in-c/
Very, very good! Thank you, this pushes me a lot forward! I have looked for months now for the different filtering types but haven´t seen this site yet.

autopilotNOR

Schematic question regarding resistive sensor in automotive (delivering current instead).

Almost every engine I know has the sensors connected to ground on one side and the other side to the gauges. This gives an voltage divider ( + gauge -> sensor -> ground).

There are very many solutions out there how to connect this to the Arduino.
What is the best practice here if I don't want or can't measure each resistive working area of the sensors?

Another thing, I could stabilize the supply voltage to the sensors by putting an LDO in series to the power supply of the gauges since the supply voltage varies from 12 to 14,2 volt. This is a variation of approx 15% and if I think about the fuel level sensor 15% is a lot in my 300L tank.

What is the best practice for this both questions?

sunnycoastgreg

i have a similar issue (albeit my engines/guages are 24V)
and whilst mine seems to be better regulated, there is still some variation in the "positive rail" of the guage - voltage divider - ground.

aside from your suggestion of using a regulated supply to the guages,
one idea I had was to use a second analog input on the arduino to read the "positive rail" voltage
(once again using a voltage divider) - however in this case the voltage divider is fixed, and the
rail voltage changes (a little) .. thus at any given time the arduino knows the actual positive rail voltage and you can then appropriately compensate this in your computation for
measuring the "unknown" voltage divider input.

hopefully my explanation is clear ..

autopilotNOR

i have a similar issue (albeit my engines/guages are 24V)
and whilst mine seems to be better regulated, there is still some variation in the "positive rail" of the guage - voltage divider - ground.

aside from your suggestion of using a regulated supply to the guages,
one idea I had was to use a second analog input on the arduino to read the "positive rail" voltage
(once again using a voltage divider) - however in this case the voltage divider is fixed, and the
rail voltage changes (a little) .. thus at any given time the arduino knows the actual positive rail voltage and you can then appropriately compensate this in your computation for
measuring the "unknown" voltage divider input.

hopefully my explanation is clear ..
Now based on your idea I remember that I anyway measure the system voltage! There I have then the reference of course!

timolappalainen

There are several errors in system.
- reference voltage
- noise from sensors to measuring system
- measuring system own noice

So I am bit afraid that if you measure system voltage as own input and then sensor value, you may have noice between measurements and you do not actually get exact measure time difference. If required accuracy is not high, it should give reasonable values.

If it is poosible, I would rather stabilize sensor voltage first. If engine own gauges does not have any differential correction, also them would be stabilized.

For resistive measurement I do not know good way, if you do not know the range of measured sensor. That would require some auto-range system. It is far more easier to measure somehow the range and use suitable constant current source or voltage source+divider resistor. E.g. for tank sensor 30-240 ohm I simply use 3.3 V regulator and 330 resistor. Then I will get range appr. 1.4 - 0.3 V to input.

autopilotNOR

#551
Sep 21, 2018, 03:31 pm Last Edit: Sep 21, 2018, 03:38 pm by autopilotNOR
Hey Timo,

I had the plan to measure the system voltage, by that the charging voltage so I can display it as well.
Currently, I am reading and learning about Aref but I am not sure how that can help with the moving supply voltage for the sensors.
The thing is that the existing gauges should, of course, still be functional. So I thought I could grab the values from the gauges and use them with the Teensy. But I didn't think about that almost all sensor is grounded on one side. This is destroying my whole plan of course.

So if I see the oil pressure sensor for example connected to the gauge as voltage divider then I could grab the voltage supplied to the sensor and break it down with another voltage divider connected to the ground where the middle point connection should give the x - 3.3 V for the teensy.

Regarding using the measured system voltage to use as reference I meant that I could calculate the difference between current system voltage and the 12 V basic voltage of the batteries in %. In max it would be than ~17% (difference between 12 and 14,5 volt). So if the system voltage is currently 14.5 V I could subtract 17% from the measured value before I send it out to the NME2K bus.

This would not fix the problem with lost resolution but I think the resolution is still good enough without working with aref.

This all is just what I think what could work, I am not sure about this is the correct way or that it even would work!

Another thought I had was to use the teensy to power the gauges. By that, I get always shown the correct values on both, MFD and the gauges since the supply voltage is stabilized for the sensors.
This is an old Volvo Penta AQAD40B engine (1986), there are now intelligent sensors at all which correct themselves I guess.
El schema from engine attached.

sunnycoastgreg

one thing to be careful of when using a "further voltage divider" to reduce the voltage from existing guage & sensor network.
the additional voltage divider across the sensor adds some additional resistance in the lower leg
of the "guage voltage divider".
so ideally you want to keep the overall resistance of the voltage divider high,
however there are practical limits given the input impedance of the arduino analog IO .
(i read somewhere that the voltage divider should not be higher than 10k (need to confirm this).

and hence with 10k across a typical tank guage sender unit, it does impact the reading a little.
i did some measurements on my guages (VDO fuel and water ... with resistive sender units.. eg 0-180ohm) and the additinal voltage divider adds a few % error ... not enough to detect
on the analog guage ... but if you plan to keep existing guage - you need to ensure
that you calibrate AFTER adding the extra voltage divider

autopilotNOR

one thing to be careful of when using a "further voltage divider" to reduce the voltage from existing guage & sensor network.
the additional voltage divider across the sensor adds some additional resistance in the lower leg
of the "guage voltage divider".
so ideally you want to keep the overall resistance of the voltage divider high,
however there are practical limits given the input impedance of the arduino analog IO .
(i read somewhere that the voltage divider should not be higher than 10k (need to confirm this).

and hence with 10k across a typical tank guage sender unit, it does impact the reading a little.
i did some measurements on my guages (VDO fuel and water ... with resistive sender units.. eg 0-180ohm) and the additinal voltage divider adds a few % error ... not enough to detect
on the analog guage ... but if you plan to keep existing guage - you need to ensure
that you calibrate AFTER adding the extra voltage divider
The tank sensor has about max 200 ohm (180 nominal) the others are in the same range. I have an overview from Faria where all this are written down. So if I use the dividers in KOhm area it should not be any problem or causing high error values. Thought to use 9.1K & 24K. This is a lot comparing to the 650 Ohm total the fuel sensor/gauge have. On the gauges, even they are high quality expensive once, there is nothing to adjust, unfortunately. BUT, If this really matter and an error is recognizable than a resistor in parallel to the gauge can compensate I guess.

sunnycoastgreg

i was chasing accuracy in fuel tank measurement (I have 2 large tanks that are coupled together)
with only one sender... and a few % is a LOT of litres in my case :)
however i quickly realised that the resistive sender unit appears to have quantisation (it doesnt appear to be
a continuous resistance?) .. so given all the errors (inc those mentioned by timo)
and also the effect of boat movement etc ... i realised that a 20 step readout
(ie showing fuel level in 5% increments was the best i could expect ... and realistically
the overall accuracy is probably worse than 5%)

remember that the additional voltage divider you add (is not across the 650ohm ... its across the
voltage output from the sender unit (the lower leg of the voltage divider formed by sender unit( 0-180)

Go Up