I've got a strange problem communicating between an Arduino Uno ATMEGA328P and PICAXE08M. I'm trying to figure out where the problem, hope you can help. I suspect NewSoftSerial because I'm creating two NewSoftSerial instances each with a different baud rate.
For debugging I've been doing the following, which works...I'm sending commands to the Arduino from my laptop, the Arduino then sends a command to the PICAXE which send a response via serial out back to the laptop.
Laptop <---> Arduino Uno ---> PICAXE ---> Laptop
Example:
send command 'GetVersion' to Arudio...Arudio sends 'V' to PICAXE, PICAXE send the string '001+' to Laptop. I've verified this works correctly and reliably. If the PICAXE receives a bad command from the Arduino it replies with the string '' where XXX is the decimal value of the character it received.
It stops working when I physically connect the PICAXE's Tx line to the Arduino's Rx.
Laptop <---> Arduino Uno <---> PICAXE
In this configuration the Arudio always receives the string '<254>' from the PICAXE. This shows the Arduino can receive from the PICAXE (because the received string is correctly framed) but is no longer sending correctly. Once complicating factor is the baud rates for Tx and Rx are different. From the Arduino's perspective Tx is 4800 and Rx is 9600. I'm suspecting the interrupts from two different baud rates on the Arduino aren't playing nice. Any ideas?
#include <NewSoftSerial.h>
static unsigned int PA_txBaudRate = 4800;
static unsigned int PA_rxBaudRate = 9600;
#define rxPin1 4
#define txPin1 5
#define rxPin2 12
#define txPin2 13
// set up a new serial port
NewSoftSerial mySerial1 = NewSoftSerial(rxPin1, txPin1, true);
NewSoftSerial mySerial2 = NewSoftSerial(rxPin2, txPin2, true);
byte pinState = 0;
char
PICAXE08M_MC_Init()
{
pinMode(rxPin1, INPUT);
pinMode(txPin1, OUTPUT);
pinMode(rxPin2, INPUT);
pinMode(txPin2, OUTPUT);
mySerial1.begin(PA_rxBaudRate);
mySerial2.begin(PA_txBaudRate);
return 1;
}
static void
PICAXE08M_MC_Print(const char* str)
{
char c = 0;
// Pulse the txPin high to generate an interrupt on the PICAXE
digitalWrite(txPin2, HIGH);
digitalWrite(txPin2, LOW);
// Wait for the PICAXE to be ready to read the data
delay(8);
int len = strlen(str);
for(int ii=0; ii<len; ii++) {
c = *(str+ii);
mySerial2.print(c);
if(ii + 1 < len) {
delay(2);
}
}
}
int
PICAXE08M_MC_GetVersion(const char* inData, int dataLength, char* outBuffer, int outBufLength)
{
uint8_t cnt = 0;
const int VERSION_LEN = 3;
char c = 0;
int retry = 0;
snprintf(outBuffer, 4, "123\0");
PICAXE08M_MC_Print("V");
while (cnt < VERSION_LEN && retry < 500) {
// read the incoming byte:
if(mySerial1.available() > 0) {
outBuffer[cnt] = mySerial1.read();
cnt++;
}
else {
retry++;
delay(1);
}
}
retry = 0;
while(retry < 100) {
if(mySerial1.available() > 0) {
c = mySerial1.read();
if(c == '+') {
outBuffer[cnt++] = c;
return cnt;
}
outBuffer[cnt++] = c;
}
else {
retry++;
delay(1);
}
}
outBuffer[cnt++] = 'E';
outBuffer[cnt++] = 'r';
outBuffer[cnt++] = 'r';
outBuffer[cnt++] = 'o';
outBuffer[cnt++] = 'r';
return cnt;
}