Go Down

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

timolappalainen

You must have old library installed. If you check from https://github.com/ttlappalainen/NMEA2000/blob/master/src/NMEA2000.cpp, definition is on line 878 and is
unsigned char CanIdPF = (unsigned char) (id >> 16);

Check also that will not have library more than once. Scan you hd: dir /s c:\NMEA2000.h

Marten_83

Okay, thank you again for helping me. I thought I did update it last week, but unfortunately I didn't perform the update procedure right...

Now this is okay, but I have to deal with some upload errors now. I will give an information when this is solved...

Best regards, Martin

skyjumper

Is there a recommended CAN transceiver chip that meets the NMEA2000 isolation requirements?

seamaster

ISO1050 from Texas Instruments is the transceiver that is isolated and designed for NMEA2000. I believe that even mentions NMEA2000 in the data sheet. http://www.ti.com/lit/ds/symlink/iso1050.pdf

skyjumper

#844
Dec 12, 2019, 11:51 pm Last Edit: Dec 12, 2019, 11:58 pm by skyjumper
ISO1050 from Texas Instruments is the transceiver that is isolated and designed for NMEA2000. I believe that even mentions NMEA2000 in the data sheet. http://www.ti.com/lit/ds/symlink/iso1050.pdf

Thanks I'll check it out!

Yes that takes care of the signal isolation thanks. What about isolating 12VDC from the N2K bus if I want to use it to power my device?

keith-i

Hi Timo

Thanks to you I'm making some progress with my engine gateway to get VW Marine canbus data onto the plotter. However, I'm struggling with the fuel consumption part. With some help off a boating forum I can get a fuel consumption rate displayed on the plotter but it's stuck at -0.1 litres/hour and doesn't vary at all.

My engine ECU outputs incremental fuel consumption in microlitres which rolls back to zero every 32767 ul. I need to obtain the difference between two readings and convert it to litres/hr for the plotter. Can you see anything out of place in my code?

Code: [Select]
case 0x480:
          fuel_now = ((( inMsg.buf[3]&0b01111111)<<8)+inMsg.buf[2]);      // get current fuel reading
          time_now = millis();                  // get curent time
            if(fuel_now > fuel_last){           // to allow for roll over
              fuel_used = fuel_now - fuel_last;}
            else{
              fuel_used = (fuel_now + (32767 - fuel_last));}
              fuel_last = fuel_now;
 

              time_elapsed = time_now - time_last;

              time_last = time_now;
 
              fuel_rate = (fuel_used / time_elapsed)*3600;    // ul/ms x 3600 = litres per hour.
     
           
          fuel_buffer[fuel_pointer] = fuel_rate;      // store latest reading in buffer (10 deep).
          fuel_pointer++;                             // increment buffer pointer ready for next time
        if(fuel_pointer > 9)fuel_pointer = 0;         // if end of buffer reached, point to start
        for(x = 0;x < 10;x++){                        // do this 10 times
          fuel_average += fuel_buffer[x];}            // add all 10 numbers stored in buffer
          fuel = fuel_average / 10;           
          break;


My declarations are:
Code: [Select]

  double fuel_last = 0;
  double fuel_now;
  double fuel_used;
  double time_now;
  double time_last = millis();
  double time_elapsed;
  double fuel_rate;
  double fuel_average;
  double fuel_buffer[10];    // buffer locations will be 0 - 9
  char fuel_pointer = 0;
  char x;
  double fuel = N2kDoubleNA;


Thanks in advance
Keith

timolappalainen

First,wouldthisbeeasytoreadtojustsavespaces?

I prefere to use spaces and indents right. Always set indent setting on editor to "convert tabs to spaces" and use tab size 2 or 4. I think 4 is unnecessary big.

You do not reset fuel_average. I also think your calculation is wrong - see comments.

Code: [Select]
  uint16_t fuel_last = 0;
  unsigned long time_last = 0;
  #define FUEL_AVG_BUFFER 10
  double fuel_buffer[FUEL_AVG_BUFFER];    // buffer locations will be 0 - 9
  size_t fuel_pointer = 0;
  double fuel_consumption = N2kDoubleNA;


case 0x480:
    double fuel_used;
    uint16_t fuel_now = ( ( (inMsg.buf[3]&0b01111111)<<8 ) + inMsg.buf[2] );      // get current fuel reading
    unsigned long time_now = millis();                  // get curent time

    if ( time_last!=0 ) {
      if ( fuel_now > fuel_last ) {           // to allow for roll over
        fuel_used = fuel_now - fuel_last;
      } else {
        fuel_used = ( fuel_now + (32767 - fuel_last) );
      }

      double time_elapsed = time_now - time_last;

      // fuel_used is in ul, so we need devide it with 1e6 to get litres.
      // time_elapsed is ms, so devide it with 3.6e6 to get hours.
      // fuel_rate = ( (fuel_used / 1e6) / ( time_elapsed/3.6e6 ) );
      double fuel_rate = (fuel_used / time_elapsed)*3.6;
       
      fuel_buffer[fuel_pointer] = fuel_rate;      // store latest reading in buffer (10 deep).
      fuel_pointer++;                             // increment buffer pointer ready for next time

      if ( fuel_pointer == FUEL_AVG_BUFFER ) fuel_pointer = 0;         // if end of buffer reached, point to start

      double fuel_average=0;
      for ( size_t i = 0; i < FUEL_AVG_BUFFER; i++ ) {                        // do this 10 times
        fuel_average += fuel_buffer[i];
      }            // add all 10 numbers stored in buffer
      fuel_consumption = fuel_average / FUEL_AVG_BUFFER;           
    }
    time_last = time_now;
    fuel_last = fuel_now;
  break;

keith-i

Thank you Timo, you are very generous with your help. I will read your suggestions and also note your comments about spacing and indents  :)

timolappalainen

Those not resetting fuel_average and too big value does not explain why value is stuck in 0.1 l/h. Have you tried to simulate code by calling it with some period and buffer data?

Go Up