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:
- A NMEA 2000 backbone from Garmin
- An M4 running the code below
- A Garmin GNX-20 Display
- 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:
- 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.
- The GNX-20 doesn't like something about how the packet is being sent. This might be timing or electrical levels.
- 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);
}