UART code not working/running at higher baud rates

Hello everyone,

I am using an Arduino Mega with the latest Arduino IDE and am trying to interface with an DVSI AMBE 3000 vocoder HDK over UART. I wrote some code that receives the packet via UART, stores the received bytes into a struct, and then transmits the received packets from the vocoder back to the vocoder (think of a loop) once the first field byte is received.

I wrote some code and it seems to work fine on any baud rate under 115200. When using a higher baud rate, I don't get anything printed to the serial monitor. In addition to this, the transmitted bits from the Arduino seem slightly off when viewed with an oscilloscope. I need a baud rate of 460800 to work with certain modes of the vocoder.

Is this a limitation of the Arduino Mega itself or is it something with my code? Thanks and I apologize if the formatting is wonky, as this is my first post here!

#define HEADER 0x61

#define CONTROL_PACKET  0x00
#define CHANNEL_PACKET  0x01
#define SPEECH_PACKET   0x02

typedef struct {
  uint8_t start_byte;
  uint16_t length;
  uint8_t type;
  uint8_t *field_bytes;
} Packet;

uint8_t PKT_PRODID[] = { 0x61, 0x00, 0x01, 0x00, 0x30 };
uint8_t PKT_VERSTRING[] = { 0x61, 0x00, 0x01, 0x00, 0x31 };
uint8_t PKT_INIT[] = { 0x61, 0x00, 0x02, 0x00, 0x0B, 0x03 };
uint8_t PKT_CODECCFG[] = { 0x61, 0x00, 0x0C, 0x00, 0x38, 0x05, 0x01, 0x41, 0x02, 0xA0, 0x04, 0x83, 0x05, 0xBB, 0x06, 0x04 };
uint8_t PKT_CHANFMT[] = { 0x61, 0x00, 0x03, 0x00, 0x15, 0x00, 0x10 };
uint8_t PKT_SPCHFMT[] = { 0x61, 0x00, 0x03, 0x00, 0x16, 0x00, 0x05 };
uint8_t PKT_CODECSTART[] = { 0x61, 0x00, 0x02, 0x00, 0x2A, 0x00 };
uint8_t PKT_RATET[] = { 0x61, 0x00, 0x02, 0x00, 0x09, 0x21 };
uint8_t PKT_CODECSTOP[] = { 0x61, 0x00, 0x01, 0x00, 0x2B };
uint8_t PKT_CHANNEL0[] = { 0x61, 0x00, 0x01, 0x00, 0x40 };
uint8_t PKT_ECMODE_IN[] = { 0x61, 0x00, 0x03, 0x00, 0x05, 0x00, 0x00 };
uint8_t PKT_DCMODE_IN[] = { 0x61, 0x00, 0x03, 0x00, 0x06, 0x00, 0x00 };
uint8_t PKT_DISCARDCODEC[] = { 0x61, 0x00, 0x02, 0x00, 0x48, 0x80 };
uint8_t PKT_RTSTHRESH[] = {0x61, 0x00, 0x05, 0x00, 0x4E, 0x00, 0x28, 0x00, 0x1E };
uint8_t PKT_LOWPOWER[] = {0x61, 0x00, 0x02, 0x00, 0x10, 0x00 };
uint8_t PKT_RESETSOFTCFG[] = {0x61, 0x00, 0x07, 0x00, 0x34, 0x00, 0x24, 0x01, 0xFF, 0xFF, 0xFF};


int index = 0;
int fieldCounter = 0;
int complete = 0;
int codecStartState = 0;

Packet packet = {0};

void setup() {

  Serial.begin(115200);
  Serial3.begin(115200);

}

void loop() {


  inputCommand();
  receivePacket();

  if (complete == 1) {
    printPacket();
    index = fieldCounter = complete = 0;
    delete[] packet.field_bytes;
  }
}

void receivePacket() {

  while (Serial3.available()) {

    uint8_t vocoderByte = Serial3.read();

    if (index == 0 && vocoderByte == HEADER) {
      packet.start_byte = vocoderByte;
      index++;
    } else {
      switch (index) {
        case 1:
          packet.length = vocoderByte << 8;
          index++;
          break;        
        case 2:
          packet.length |= vocoderByte;
          packet.field_bytes = new uint8_t[packet.length];
          index++;
          break;
        case 3:
          packet.type = vocoderByte;
          index++;
          break;
        
        default:
          packet.field_bytes[index - 4] = vocoderByte;
          index++;
          fieldCounter++;
          if (fieldCounter == packet.length) {
            complete = 1;
          }
          break;
      }
    }

    // Start sending the packet as soon as the first field byte is received
    if (codecStartState == 1 && packet.type == CHANNEL_PACKET && index >= 5) {
      sendPacket();
    }
  }
}

void sendPacket() {
  if (index == 5) {
    Serial3.write(packet.start_byte);
    Serial3.write((packet.length >> 8) & 0xFF);
    Serial3.write((packet.length & 0xFF));
    Serial3.write(packet.type);
  }

  if (index >= 6) {
    // Send field bytes one by one
    Serial3.write(packet.field_bytes[index - 6]);
  }
}

void printPacket() {
  Serial.println();
  Serial.print("0x");
  Serial.print(packet.start_byte, HEX);
  Serial.print(" ");

  Serial.print("0x");
  Serial.print(((packet.length >> 8) & 0xFF), HEX);
  Serial.print(" ");

  Serial.print("0x");
  Serial.print((packet.length & 0xFF), HEX);
  Serial.print(" ");

  Serial.print("0x");
  Serial.print(packet.type, HEX);
  Serial.print(" ");

  for (int i = 0; i < packet.length; i++) {
    Serial.print("0x");
    Serial.print(packet.field_bytes[i], HEX);
    Serial.print(" ");
  }
}

void inputCommand() {
  if (Serial.available() > 0) {
    String typedCOMMAND = Serial.readString();
    
    if (typedCOMMAND == "PKT_CODECCFG") {
      Serial3.write(PKT_CODECCFG, sizeof(PKT_CODECCFG));
    }
    if (typedCOMMAND == "PKT_INIT") {
      Serial3.write(PKT_INIT, sizeof(PKT_INIT));
    }
    if (typedCOMMAND == "PKT_CHANFMT") {
      Serial3.write(PKT_CHANFMT, sizeof(PKT_CHANFMT));
    }
    if (typedCOMMAND == "PKT_SPCHFMT") {
      Serial3.write(PKT_SPCHFMT, sizeof(PKT_SPCHFMT));
    }
    if (typedCOMMAND == "PKT_CODECSTART") {
      Serial3.write(PKT_CODECSTART, sizeof(PKT_CODECSTART));
      codecStartState = 1;
    }
    if (typedCOMMAND == "PKT_PRODID") {
      Serial3.write(PKT_PRODID, sizeof(PKT_PRODID));
    }
    if (typedCOMMAND == "PKT_VERSTRING") {
      Serial3.write(PKT_VERSTRING, sizeof(PKT_VERSTRING));
    }
    if (typedCOMMAND == "PKT_RATET") {
      Serial3.write(PKT_RATET, sizeof(PKT_RATET));
    }
    if (typedCOMMAND == "PKT_CODECSTOP") {
      Serial3.write(PKT_CODECSTOP, sizeof(PKT_CODECSTOP));
      codecStartState = 0;
    }
    if (typedCOMMAND == "PKT_LOWPOWER") {
      Serial3.write(PKT_LOWPOWER, sizeof(PKT_LOWPOWER));
    }
    if (typedCOMMAND == "PKT_ECMODE_IN") {
      Serial3.write(PKT_ECMODE_IN, sizeof(PKT_ECMODE_IN));
    }
    if (typedCOMMAND == "PKT_DCMODE_IN") {
      Serial3.write(PKT_DCMODE_IN, sizeof(PKT_DCMODE_IN));
    }
    if (typedCOMMAND == "PKT_CHANNEL0") {
      Serial3.write(PKT_CHANNEL0, sizeof(PKT_CHANNEL0));
    }
    if (typedCOMMAND == "PKT_DISCARDCODEC") {
      Serial3.write(PKT_DISCARDCODEC, sizeof(PKT_DISCARDCODEC));
    }
    if (typedCOMMAND == "PKT_RTSTHRESH") {
      Serial3.write(PKT_RTSTHRESH, sizeof(PKT_RTSTHRESH));
    }
    if (typedCOMMAND == "PKT_RESETSOFTCFG"){
      Serial3.write(PKT_RESETSOFTCFG, sizeof(PKT_RESETSOFTCFG));
    }
    if (typedCOMMAND == "PKT_INITIALIZE") {
      Serial3.write(PKT_CHANNEL0, sizeof(PKT_CHANNEL0));
      Serial3.write(PKT_ECMODE_IN, sizeof(PKT_ECMODE_IN));
      Serial3.write(PKT_DCMODE_IN, sizeof(PKT_DCMODE_IN));
      Serial3.write(PKT_RATET, sizeof(PKT_RATET));
      Serial3.write(PKT_CHANFMT, sizeof(PKT_CHANFMT));
      Serial3.write(PKT_SPCHFMT, sizeof(PKT_SPCHFMT));
      Serial3.write(PKT_DISCARDCODEC, sizeof(PKT_DISCARDCODEC));
      Serial3.write(PKT_CODECCFG, sizeof(PKT_CODECCFG));
      Serial3.write(PKT_INIT, sizeof(PKT_INIT));
    }
  }
}

Let's find out... error for that baud with a 16 MHz AVR processor ...8.5%. That's not going to work.

At first guess I would say it is a hardware problem. How fast is your terminal operating, it generally needs to be faster then your target.

Post an annotated schematic showing how all of this is interconnected and note any leads over 10"/25cm. Include all power sources, grounds etc.

It's a limitation of the mega itself.
At 16MHz, high bitrates become very quantized at divisors of cpuclk/8.
You you can get 2Mhz, 1MHz, 666.555kHz, 500kHz, 400kHz, ... But no 460800...

1 Like

You can use an external UART (Universal Asynchronous Receiver Transmitter) and run at that baud. The Arduino may not be able to keep up depending on how much data is coming. Have you considered one of the ESP devices?

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