Arduino Nano 33 iot not outputting serial via USB automatically

I have an Arduino Nano 33 iot that outputs data via Serial at 38400 baud, connected via USB. Setup starts with Serial.Begin. The Raspberry Pi 4, running Raspian buster is set up to receive the data. It can see the correct port, /dev/ttyACM0, but nothing comes in.

I even installed the correct Arduino IDE, latest stable version, 1.8.13 and SAMD board package on the Raspberry Pi. It still does not find it until after the IDE uploads the replacement sketch and the CPU is reset. The IDE can grab the serial number and board type though before this. I can then exit out of the IDE and the Arduino is still pumping out serial to the Raspberry Pi.

The only other way to make it work is by pressing the reset button on the Arduino every time a reboot is done on the Raspberry Pi. Serial was tested on the Pi using screen.
Neither of these options are convenient. What am I missing?

Before anybody mentions it, no it is not convenient to run another wire from the Raspberry Pi GPIO to the Arduino’s reset pin. There has to be a way to do this other than that.

/*
Connects via I2C to a CMPS14, outputs NMEA0183 HDM sentences via Serial (38400 baud)
   By James Henderson, 2014, adapted to output NMEA sentences by Ian Van Schaick
*/
#include <Keyboard.h>
#include <Wire.h>

#define CMPS14_ADDRESS 0x60  // Address of CMPS14 shifted right one bit for arduino wire library
#define ANGLE_8  1           // Register to read 8bit angle from


unsigned char high_byte, low_byte, angle8;
signed char pitch, roll;
float angle16;
int fine;
float bearingH; // Holds whole degrees of bearing
float bearingL; // Holds decimal digits of bearing
int bearing;
char nbsp;
char mystring[25];
char mystring2[25];
char mystring3[25];
int software;
int cal;
unsigned int _last_status;

uint8_t checksum(char *s)
{
  uint8_t c = 0;

  while (*s)
    c ^= *s++;
  return c;
}

void CMPS14_eraseProfil()
{
  Wire.beginTransmission(CMPS14_ADDRESS);
  Wire.write(0x00);
  Wire.write(0xE0);
  _last_status = Wire.endTransmission();

  delay(20); //  20ms delay after each of the three bytes send
  Wire.beginTransmission(CMPS14_ADDRESS);
  Wire.write(0x00);
  Wire.write(0xE5);
  _last_status = Wire.endTransmission();

  delay(20); //  20ms delay after each of the three bytes send
  Wire.beginTransmission(CMPS14_ADDRESS);
  Wire.write(0x00);
  Wire.write(0xE2);
  _last_status = Wire.endTransmission();

  delay(20); //  20ms delay after each of the three bytes send
}

//Correct heading for known deviation
int DeviationCorrect(int Head)
{
   return 0;
}

void setup() {
  Serial.begin(38400);  // Start serial port
  Wire.begin();
  nbsp = 32;
  //  CMPS14_eraseProfil();
}

void loop() {
  Wire.beginTransmission(CMPS14_ADDRESS);  //starts communication with CMPS14
  Wire.write(ANGLE_8);                     //Sends the register we wish to start reading from
  Wire.endTransmission();

  // Request 5 bytes from the CMPS14
  // this will give us the 8 bit bearing,
  // both bytes of the 16 bit bearing, pitch and roll
  Wire.requestFrom(CMPS14_ADDRESS, 26);

  while (Wire.available() < 26);       // Wait for all bytes to come back
  //  software = Wire.read();
  //  Serial.print("Version: ");
  //  Serial.println(software);
  angle8 = Wire.read();               // Read back the 5 bytes
  high_byte = Wire.read();
  low_byte = Wire.read();
  pitch = Wire.read();
  roll = Wire.read();

  //  int i = 6;
  //  while (i <= 25) {
  //    Wire.read();
  //    i++;
  //  }
  //
  //  cal = Wire.read();
  //  Serial.print("Cal: ");
  //  Serial.println(cal);

  bearing = ((high_byte << 8) + low_byte) / 10;
  fine = ((high_byte << 8) + low_byte) % 10;
  byte data[128] = "$HCHDM,";
  data[8] = bearing;
  //  int deviation = 0;
  //DeviationCorrect(bearing);
  //  bearing = bearing;
  //+ deviation;

  //Print out NMEA 0183 string HDM
  snprintf(mystring, sizeof(mystring), "$HCHDM,%d.%d,M", bearing , fine);
  uint8_t crc = checksum(mystring + 1);
  Serial.print(mystring);
  Serial.print("*");
  if (crc < 16) Serial.print("0");
  Serial.println(crc, HEX);

    //Print out NMEA 0183 string XDR for Pitch
    snprintf(mystring2, sizeof(mystring2), "$HCXDR,A,%d,D,PITCH", pitch);
    uint8_t crc2 = checksum(mystring2 + 1);
    Serial.print(mystring2);
    Serial.print("*");
    if(crc2 < 16) Serial.print("0");
    Serial.println(crc2, HEX);
  
    //Print out NMEA 0183 string XDR for Roll/Heel
    snprintf(mystring3, sizeof(mystring3), "$HCXDR,A,%d,D,ROLL", roll);
    uint8_t crc3 = checksum(mystring3 + 1);
    Serial.print(mystring3);
    Serial.print("*");
    if(crc3 < 16) Serial.print("0");
    Serial.println(crc3, HEX);
  delay(100);
}

I think your sketch may be more complex than what is needed for a minimal demonstration of the issue. If so, that extra complexity will make it less likely for you to get effective help with your problem.

Does the same issue occur with this sketch?:

void setup() {
  Serial.begin(38400);
}

void loop() {
  Serial.println("hello");
  delay(1000);
}

I actually just tested that. The answer is no, the simple code works fine. So at least I know the problem is with my sketch. Now the question is where.

Thanks.

I would add some additional serial prints in the code at strategic places.

E.g. one at the end of setup() , one after Wire.endTransmission(), one after Wire.requestFrom() and one after while (Wire.available() < 26).

And this does not make sense; compare the comment with the actual statement.

  // Request 5 bytes from the CMPS14
  // this will give us the 8 bit bearing,
  // both bytes of the 16 bit bearing, pitch and roll
  Wire.requestFrom(CMPS14_ADDRESS, 26);

I will try adding more print statements.

Ignore the comments then. I was testing code and did not update the comments every time. I was trying to see if the calibration was working and its status, needed more bits.

Thanks,
Ian

OK.
I added print statements at all of those locations. At the end of setup, I also added a blink for the built-in LED.

In order for it to show my print statement in setup, I have to unplug the Arduino and plug it back in. Computer can't find the port until that happens. Clicking the reset button once does not restart the Serial terminal, no COM port on the computer shows up. Double pressing the reset, puts it in bootloader mode and then it shows up as a COM port. I can then upload a new sketch.

On power on, or after uploading a new sketch, I can see the Arduino leaves setup because the built-in LED blinks.

The other Print statements print out in order, once Serial is available again.

I should note that one running this sketch, I have 2 Arduino Nano 33 iot devices listed in Device Manager. Both under COM ports, 2 different port numbers. One with a little yellow ! warning, This device cannot start. (Code 10). I have tried fixing it by uninstalling Arduino IDE, SAMD Board package, etc. No change.

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.