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));
}
}
}