I am attempting to send command packets between a control board and a peripheral. Unfortunately, when I attempt to read the packet on the peripheral device, the message is improperly truncated.
Hardware:
Command board - Custom 3.3V variant using ATMEGA2560
Peripheral board - Arduino Nano
I2C connection:
Since I am going from a 3.3V logic board to a 5V logic board, I have to adjust the signal. The command board includes through a PCA9517 level shifter with 10k pullups on each end. The longest wire in my test is ~20cm (8 in).
On the command board, I do not have access to the standard I2C ports, so I am using a SoftWire.h
.
Minimal code:
The minimal code is attempting to send a 25-byte string, and the string is read out to the serial.
On the command board -
#include <SoftwareSerial.h>
#include "SoftEasyTransfer.h"
#define I2C_TIMEOUT 1000
#define I2C_PULLUP 1
#define SDA_PORT PORTC
#define SDA_PIN 3 // = 34 on mega
#define SCL_PORT PORTC
#define SCL_PIN 5 // = 32 on mega
#include <SoftWire.h>
struct CMD_DATA_STRUCTURE {
char msg[25] = "";
};
CMD_DATA_STRUCTURE cmddata;
const bool DEBUG = true;
void xon_cmd(int unit) {
/*
* Command the peripheral to turn on things
*/
for (size_t i = 0; i < 25; i++) {
cmddata.msg[i] = 0x00;
}
// Add SOH, address, NACK, and EOT
cmddata.msg[0] = 0x01; // SOH
cmddata.msg[1] = 0x30 + unit; // ASCII "0" is master node
cmddata.msg[2] = 0x11; // XON
cmddata.msg[24] = 0x04; // EOT
return;
}
void issue_cmd() {
/*
* Issue the command we made to the peripheral
*/
if (DEBUG) {
Serial.println("issuing cmd:");
for (size_t i=0; i < 25; i++) {
Serial.print(cmddata.msg[i], HEX);
Serial.print(" ");
}
Serial.println("");
}
Wire.beginTransmission(8);
for (size_t i=0; i < 25; i++) {
if (DEBUG) {
Serial.print(cmddata.msg[i], HEX);
}
Wire.write(cmddata.msg[i]);
if (DEBUG) {
Serial.print(" ");
}
}
Wire.endTransmission(false);
Serial.println("");
}
void setup() {
// Power up 5v lines (required for custom board)
pinMode(A1, OUTPUT);
pinMode(A7, OUTPUT);
digitalWrite(A1, HIGH);
digitalWrite(A7, HIGH);
// Empty command message
for (size_t i = 0; i < 25; i++) {
cmddata.msg[i] = 0xff;
}
if (DEBUG) {
// Init serial comms for debugging
Serial.begin(9600);
Serial.print("Debugging: ");
Serial.println(__FILE__);
}
Wire.begin();
}
void loop() {
if (DEBUG) {
Serial.println("XON attempt");
}
xon_cmd(2);
issue_cmd();
delay(1000);
}
On the peripheral board -
#include <Wire.h>
#include "SoftEasyTransfer.h"
const bool DEBUG = true;
struct CMD_DATA_STRUCTURE {
char msg[25] = "";
};
CMD_DATA_STRUCTURE cmddata;
void receiveEvent(int howMany) {
int cnt = 0;
while (Wire.available()) {
if (DEBUG) {
Serial.print("Wire.available() = ");
Serial.println(Wire.available());
}
// receive byte as a character into the command struct
cmddata.msg[cnt] = Wire.read();
cnt++;
}
for (size_t i = 0; i < 25; i++) {
Serial.print(cmddata.msg[i], HEX);
Serial.print(" ");
}
Serial.println("");
return;
}
void setup() {
if (DEBUG) {
// Init serial comms for debugging
Serial.begin(9600);
Serial.print("Debugging: ");
Serial.println(__FILE__);
}
Wire.begin(8);
Wire.onReceive(receiveEvent);
}
void loop() {
}
Debugging Output:
Command board -
Debugging: /home/wes/sketchbook/test_sensorboard_rs485_command/test_sensorboard_rs485_command.ino
XON attempt
issuing cmd:
1 32 11 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 4
1 32 11 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 4
Peripheral board -
Debugging: /home/wes/sketchbook/test_sensorboard_rs485_net/test_sensorboard_rs485_net.ino
Wire.available() = 25
Wire.available() = 24
Wire.available() = 23
Wire.available() = 22
Wire.available() = 21
Wire.available() = 20
Wire.available() = 19
Wire.available() = 18
Wire.available() = 17
Wire.available() = 16
Wire.available() = 15
Wire.available() = 14
Wire.available() = 13
Wire.available() = 12
Wire.available() = 11
Wire.available() = 10
Wire.available() = 9
Wire.available() = 8
Wire.available() = 7
Wire.available() = 6
Wire.available() = 5
Wire.available() = 4
Wire.available() = 3
Wire.available() = 2
Wire.available() = 1
1 32 11 0 0 0 0 0 0 0 0 0 0 0 ⸮
If each byte of the expected 25 length Wire.available
is being read, why does it truncate part way through? Note, if I do NOT use while (Wire.available())
for the read loop and instead force a length while (size_t i=0; i<25; i++)
I get the same problem. HOWEVER, if I increase the loop length to something like i<30
, I get more of the message (although it still truncates imrpoperly). What have I done wrong here?