Firmware tested on Adafruit M0 Metro Express does not work properly on Wacc board

Hello,

Thanks again for the UART sensor tutorial, it was very helpful with getting started setting up our robot hand. After much testing with an Adafruit Metro M0 Express emulating the wrist board at home, I uploaded the edited firmware code to the wrist board today to try it out on the robot. However, there seemed to be some serial-related issues that were causing the status messages to not unpack properly into self.status[‘serial_ext’]. The hand is running at 19200 baudrate.

I can go into more detail but wanted to first ask, are there any significant hardware/spec differences between the Adafruit board and the wrist board that might cause the firmware to work well on one but not the other? I’m still in the process of debugging this myself.

Thanks,
Lionel

Hi Lionel, there should not be any significant hardware differences between the two. I’d suggest decoupling the HW and SW. First confirm that you can transmit the additional status data using dummy data (and any polling of the hand HW serial turned off). This should work so long as your code is correct and you’re not attempting to send large amounts of data (100s of bytes).

Then stuff the status struct with real HW data.

Hi Aaron, thanks for the suggestion. I will try that out at the lab later today. Before I start playing with the Wacc board more, I wanted to ask about the warning in the firmware overview “It is possible to brick the Wacc board by incorrectly configuring the hardware peripherals of the SAMD uC”. What sort of errors might brick the board? Would you recommend testing everything on the Adafruit board first, even for the serial loopback tutorial?

In don’t have specific details as its always been a bit opaque when it happens.

In general the bootloader on the SAMD allows flashing of new firmware. So long as the bootloader mode can run then you can always reflash the firmware during development. It should be the case (in theory) that your firmware isn’t able to mangle the bootloader. Also, the bootloader mode can be entered by double clicking the reset button.

What we’ve seen is that incorrectly configuring an SPI or serial device can, in some cases, cause the board to be unable to enter the bootloader mode. Once basic comms between the SAMD and the SPI or serial device are established (indicating that it is correctly configured) then you should be out of the ‘danger zone’.

This is why we recommend doing the initial development on the M0 as a proxy for the Wacc.

If you do brick your Wacc we can always send you a new one.

Note: One way to avoid the bricking risk is to only initialize your SPI/serial peripheral after some user event (like a button push). This allows the program to run the risky code only when you request it.

1 Like

Thanks for the additional info regarding the Wacc board. I’ll keep these in mind when testing the Wacc.

I first tested the firmware in a loopback config on the Wacc using a dummy packet (22 bytes: first 4 fixed, next 17 incrementing once each pass, ending with a checksum). It seemed to work with no problems (screenshot below).

I then wired the hand to the Wacc while using the same firmware and replaced the dummy command with a status request (expecting 22 byte response that should be the same each time). It seemed that I was only getting the proper response about 20% of the time, with the majority of responses containing repeated and/or missing bytes (screenshot below).

Using the same firmware, I then switched over to the M0 and was getting the proper responses every time (screenshot below).

I’m a bit stumped as to what the problem might be. Do you an idea of what may cause this?
I’ve added some code snippets below in case they are helpful. Thanks so much for your help.


//simplified version used for the above testing
void serial_comms()
{
  char * data_down=(char*)&(cmd.serial.data[0]);
  char * data_up=(char*)(stat.serial.data);
  int length = cmd.serial.data[3];
  for(int i=0;i<length;i++)
  {
    SerialExt.write(data_down+i,1);
  }
  for(int i=0;i<22;i++) // fixing number of bytes to read because expecting status response
  {
    if (SerialExt.available())
    {
      data_up[i]=SerialExt.read();
    }
  }
}
def ext_unpack_status(self,s):
        """
        s: byte array to unpack
        return: number of bytes unpacked
        """
        sidx=0
        for i in range(4):
            self.status['serial_ext'][i] = unpack_uint8_t(s[sidx:])
            sidx+=1
        length = np.amin([self.n_float, self.status['serial_ext'][3]])
        for i in range(4,length):
            self.status['serial_ext'][i] = unpack_uint8_t(s[sidx:])
            sidx+=1
        # return sidx
        return self.n_float
struct __attribute__ ((packed)) SerialExtCommand{
  uint8_t data[40];
};
struct __attribute__ ((packed)) SerialExtStatus{
  uint8_t data[40];
};

A quick update on this for other readers: The issue was resolved with Hello Robot support by commenting out the I2C comms with the Wacc accelerometer as they were in conflict with the use of the serial port.

2 Likes