RP2040 vs ESP32

I have my CAN code running on the ESP32 and an ESP8266 and they work perfectly. I can see it in RealDash using my custom.xml

I then compile it on the rp2040 and I get nothing. All I get on the CAN Monitoring is failed to connect.

I’m confused as it is literally the same code. They are all 3 32bit architectures, Arduino, etc. I just change the target board for compiling and a different serial port in RealDash. Any ideas?

thanks
david

I fell back to using the Arduion example on the github page. I changed the unsigned int to uint16_t and same results.

Works for ESP32 and Wroom 8266, but not the rp2040 (rpi pico).

I even explicitly set the serial to 8n1.

Hopefully someone will have ideas.

I reduced the testcase down as far as I can. Any suggestions? I’m beginning to wonder if it has something to do with the waveshare board I’m using.

/**
 * ============================================================================
 *  Name        : RealDash_CAN.ino
 *  Part of     : RealDash
 *  Author      : Jani Immonen
 *  Created     : 15.10.2017
 *
 * Arduino example sketch of how to use RealDash CAN protocol.
 * 
 * This example code is free for any use.
 * 
 * www.realdash.net
 * ============================================================================
**/

uint16_t rpm = 0;
uint16_t spd = 0;
uint16_t kpa = 992; // 99.2
uint16_t tps = 965; // 96.5
uint16_t clt = 80;  // 80 - 100

void setup()
{
  // init serialc:\Users\davep\OneDrive\Desktop\RealDash\Arduino\RealDash_CAN\realdash_can_example.xml
  Serial.begin(115200);
  delay(100);
}


void loop()
{

  // SendToSerial();

  // just some dummy values for simulated engine parameters
  if (spd++ > 100)
  {
    spd = 50;
  }  
  if (rpm++ > 8000)
  {
    rpm = 500;
  }
  if (kpa++ > 2500)
  {
    kpa = 10;
  }
  if (tps++ > 1000)
  {
    tps = 0;
  }
  if (clt++ > 230)
  {
    // all values in frame are handled as unsigned values. To have negative values,
    // offset actual value and write corresponding conversion to xml file imported to RealDash
    clt = 0;
  }
  SendCANFramesToSerial();
  delay(50);
}


void SendCANFramesToSerial()
{
  byte buf[8];

  // build & send CAN frames to RealDash.
  // a CAN frame payload is always 8 bytes containing data in a manner
  // described by the RealDash custom channel description XML file
  // all multibyte values are handled as little endian by default.
  // endianess of the values can be specified in XML file if it is required to use big endian values

  // build 1st CAN frame, RPM, MAP, CLT, TPS (just example data)
  memcpy(buf, &rpm, 2);
  memcpy(buf + 2, &kpa, 2);
  memcpy(buf + 4, &clt, 2);
  //memcpy(buf + 6, &tps, 2);
  memcpy(buf + 6, &spd, 2);

  // write first CAN frame to serial
 SendCANFrameToSerial(3200, buf);

}


void SendCANFrameToSerial(unsigned long canFrameId, const byte* frameData)
{
  // the 4 byte identifier at the beginning of each CAN frame
  // this is required for RealDash to 'catch-up' on ongoing stream of CAN frames
  const byte serialBlockTag[4] = { 0x44, 0x33, 0x22, 0x11 };
  Serial.write(serialBlockTag, 4);

  // the CAN frame id number (as 32bit little endian value)
  Serial.write((const byte*)&canFrameId, 4);

  // CAN frame payload
  Serial.write(frameData, 8);
}




Is your rp2040 device big or little endian architecture?

It is the same as the ESP32, little endian, uses an ARM Corex-M0

What triggers the timeout message? Does that happen if the 44,33,22,11 identifier doesn’t get identified? Or could it happen later?

Just trying to debug this issue.

thanks

Timeout is triggered if there is no identifiable data coming in for couple of seconds.

Warning: lots of data.

Well I broke down and installed wireshark to see what was happening.

A snippet of my reduced testcase based on the Arduino example.

  rpm = 1;
  kpa = 2;
  clt = 3;
  spd = 4;
  SendCANFramesToSerial();
  delay(1000);
}


void SendCANFramesToSerial()
{
  byte buf[8];

  // build & send CAN frames to RealDash.
  // a CAN frame payload is always 8 bytes containing data in a manner
  // described by the RealDash custom channel description XML file
  // all multibyte values are handled as little endian by default.
  // endianess of the values can be specified in XML file if it is required to use big endian values

  // build 1st CAN frame, RPM, MAP, CLT, TPS (just example data)
  memcpy(buf, &rpm, 2);
  memcpy(buf + 2, &kpa, 2);
  memcpy(buf + 4, &clt, 2);
  //memcpy(buf + 6, &tps, 2);
  memcpy(buf + 6, &spd, 2);

  // write first CAN frame to serial
 SendCANFrameToSerial(3200, buf);

I see that with the rp2040 (broken) the header and data are shown by wireshark as “Leftover Capture Data”: data that it doesn’t know what to do with.

Header Packet: You can see the data on the last line of 44332211

Frame 149: 31 bytes on wire (248 bits), 31 bytes captured (248 bits) on interface \\.\USBPcap1, id 0
USB URB
    [Source: 1.21.2]
    [Destination: host]
    USBPcap pseudoheader length: 27
    IRP ID: 0xffff8c86d87e2aa0
    IRP USBD_STATUS: USBD_STATUS_SUCCESS (0x00000000)
    URB Function: URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER (0x0009)
    IRP information: 0x01, Direction: PDO -> FDO
    URB bus id: 1
    Device address: 21
    Endpoint: 0x82, Direction: IN
    URB transfer type: URB_BULK (0x03)
    Packet Data Length: 4
    [Request in: 148]
    [Time from request: 0.999383000 seconds]
    [bInterfaceClass: CDC-Data (0x0a)]
Leftover Capture Data: 44332211

Data Packet last line shows the data. 4 packets with increasing values 1,2,3,4 with a frameID of 3200

Frame 361: 39 bytes on wire (312 bits), 39 bytes captured (312 bits) on interface \\.\USBPcap1, id 0
USB URB
    [Source: 1.21.2]
    [Destination: host]
    USBPcap pseudoheader length: 27
    IRP ID: 0xffff8c86d87e2aa0
    IRP USBD_STATUS: USBD_STATUS_SUCCESS (0x00000000)
    URB Function: URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER (0x0009)
    IRP information: 0x01, Direction: PDO -> FDO
    URB bus id: 1
    Device address: 21
    Endpoint: 0x82, Direction: IN
    URB transfer type: URB_BULK (0x03)
    Packet Data Length: 12
    [Request in: 360]
    [Time from request: 0.000959000 seconds]
    [bInterfaceClass: CDC-Data (0x0a)]
Leftover Capture Data: 800c00000100020003000400

I then hooked up my esp32 (that does work with realdash) and get completely different data. Same sketch, but with esp32 instead. No leftover data. And it works.

Frame 506: 28 bytes on wire (224 bits), 28 bytes captured (224 bits) on interface \\.\USBPcap1, id 0
USB URB
    [Source: 1.26.1]
    [Destination: host]
    USBPcap pseudoheader length: 27
    IRP ID: 0xffff8c86cdcdf010
    IRP USBD_STATUS: USBD_STATUS_SUCCESS (0x00000000)
    URB Function: URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER (0x0009)
    IRP information: 0x01, Direction: PDO -> FDO
    URB bus id: 1
    Device address: 26
    Endpoint: 0x81, Direction: IN
    URB transfer type: URB_BULK (0x03)
    Packet Data Length: 1
    [Request in: 505]
    [Time from request: 0.000059000 seconds]
    [bInterfaceClass: Vendor Specific (0xff)]
Leftover Capture Data: 00

I’m hoping someone can help guide me on what next steps should be. From my reading there shouldn’t be any Leftover Capture Data.

thanks
david

I think there is a bug in the Arduino serial driver for the USB controller on this board.

I hooked up a UART to serial converter, sent the data via Serial1 and it all works fine. WireShark and RealDash are happy.

I can finally get all my sensor data sent over to RealDash.

david

1 Like