Adafruit M4 CAN Express - NMEA 2000 Sensor

I'm trying to use Adafruit's M4 CAN Express to talk to a Garmin GNX-20 display. The long term goal will be to write the hardware dependant files to use Timo Lappalainen's NMEA 2000 library. The short term goal is to hack something that the Garmin accepts and displays. I'm trying to emulate a water temperature sensor for this.

The hardware setup:

  1. A NMEA 2000 backbone from Garmin
  2. An M4 running the code below
  3. A Garmin GNX-20 Display
  4. An M4 running a version of Adafruit's feather_m4can_rx

The listening M4 receives the packets from the emulated sensor, as well as packets from the GNX-20. The GNX-20 doesn't display the water temperature. I believe the hardware is working fine.

Paths to investigate:

  1. The code below has a critical mistake. I've tried several PGNs and various settings. I chose the sea water temp for this write up because it's a simple one.
  2. The GNX-20 doesn't like something about how the packet is being sent. This might be timing or electrical levels.
  3. I can't simply send the water temperature packet. I need to send some other packets. Note: I'm using a fixed source address, as the display always seems to grab 0x00. I don't believe I have an address collision.

Please take a look and all suggestions are welcome. I've been looking at using hardware dependant files for AVR as an example. Is that a good place to start or should I use a different set of files?

Thanks,

Greg

/* This code is based on Adafruit's feather_m4can_tx example.
/  It is intended to emulate a seawater temperature sensor.
/  It is not meant to be compliant. It is a stepping stone
/  towards generating hardware dependant files for the M4 CAN
/  Express to be used with Timo Lappalainen's NMEA 2000 library.
*/

#include <CANSAME5x.h>

CANSAME5x CAN;

void setup() {

  pinMode(PIN_CAN_STANDBY, OUTPUT);
  digitalWrite(PIN_CAN_STANDBY, false); // turn off STANDBY
  pinMode(PIN_CAN_BOOSTEN, OUTPUT);
  digitalWrite(PIN_CAN_BOOSTEN, true); // turn on booster

  Serial.begin(115200);
  delay(5000);  // I give a long delay and then continue. I don't want it to hang if it's running stand alone.
  Serial.println("Dummy NMEA2000 message transmit");

  // start the CAN bus at 250 kbps
  if (!CAN.begin(250000)) {
    Serial.println("Starting CAN failed!");
    while (1) delay(10);
  }

   Serial.println("Starting CAN!");
}

void loop() {
  uint32_t i = 0;
  uint32_t priority = 5;
  uint32_t pgn = 130312;
  uint32_t source_addr = 55;
  uint32_t packet_id = 0;

  packet_id += (priority<<26);
  packet_id += (pgn<<8);
  packet_id += source_addr;

  // SID 0x05
  // Instance 0x00
  // Source is sea temp LUT 0x00
  // 85F = 302.59K 302.59 / 0.01 = 30259 = 0x7633
  // Setpoint = 0x0000
  // Reserved = 0x00
  uint8_t payload[8] = {0x05,0x00,0x00,0x33,0x76,0x00,0x00,0x00};

  // print to the serial monitor what we plan to send
  Serial.print("ID: ");
  Serial.print(packet_id,HEX);
  Serial.print(" Data:");
  for(i=0;i<8;i++)
  {
    Serial.printf(" %02X",payload[i]);
  }

  // send it
  CAN.beginExtendedPacket(packet_id);
  for(i=0;i<8;i++)
  {
    CAN.write(payload[i]);
  }
  CAN.endPacket();

  Serial.println("  done");

  delay(500);
}

Post your Annotated schematic showing exactly how you have connected everything. Also post a link to the CAN subsystem, I did not see anything on CAN. If I have missed anything post links to it as well.

Hi Gil,

Please, don't be so patronizing. I'm systems engineer with 30+ years of experience. I'm also sitting on a 30' sailboat off the coast of Mexico in a little place called Bahia Tortuga. I don't have my normal resources available "To solve the problem myself." NMEA 2000 is a closed protocol, as I guess you know. That means all of us playing with it are working blind and making our best guesses. My post is simply asking the community if they see some stupid mistake in my code or to point me in the right direction. Something like "Oh, you need to transmit x PGN every 2 seconds so the GNX will recognize your device." Not re-inventing the wheel is how we all help each other move forward.

Regards,

Greg

No way of knowing that. Your question appeared as a class project to me.

NMEA 2000, the open standard for marine electronics communication

This might help: file:///home/gil/Downloads/Complete-Guide-to-NMEA-2000_Revision_4_2021.pdf

As I understand it, Not all NEMA standards are published and available to the public. You may have to purchase or subscription for access. Note many standards are available at no charge on the NEMA website, allowing users to view their scopes and contents.

Hi Gil,

Understood. Thanks for adding the links. I have all that stuff but didn't think to add them to the post for other folks.

The document you linked is great for the cabling part of the system. Unfortunately, the communication protocol is closed and would cost me $4600 to buy a copy. NMEA 2000 Standard

Regards,

Greg