I am using the Rs232 shield from DFROBOT and I'm trying to get data from a Device using Arduino uno..I always get the first message complatly but when I try to get a message again ,I get partial of the masssage.
Whould you I do/write to get the fully messgae everytime?
Post the current sketch in code tags to see how we can help.
Which device? Link to a document that describes the protocol (user manual / datasheet) would be useful.
this is part of the code that handle Rs232
void processRS232Data() {
unsigned long now = millis();
while (rs232.available()) {
char c = rs232.read();
lastRS232CharTime = now;
if (c == '\n' || c == '\r') {
if (rs232BufferIndex > 0) {
rs232Buffer[rs232BufferIndex] = '\0';
totalMessagesReceived++;
processdeviceMessage(rs232Buffer);
rs232BufferIndex = 0;
rs232BufferOverflow = false;
}
}
else if (c >= 32 && c <= 126) {
if (rs232BufferIndex < RS232_BUFFER_SIZE - 1) {
rs232Buffer[rs232BufferIndex++] = c;
} else {
if (!rs232BufferOverflow) {
rs232BufferOverflow = true;
Serial.println(F("RS232: BUFFER OVERFLOW"));
}
}
}
}
if (rs232BufferIndex > 0 && (now - lastRS232CharTime > RS232_TIMEOUT_MS)) {
rs232Buffer[rs232BufferIndex] = '\0';
Serial.print(F("RS232 TIMEOUT ("));
Serial.print(rs232BufferIndex);
Serial.print(F(" bytes): "));
Serial.println(rs232Buffer);
rs232BufferIndex = 0;
rs232BufferOverflow = false;
}
}
void processdeviceMessage(const char* message) {
Serial.print(F("RS232: Received ("));
Serial.print(strlen(message));
Serial.print(F(" bytes) <- "));
Serial.println(message);
else {
Serial.println(F("RS232: Unknown message type"));
}
}
What is the baud rate of Serial and rs232? If you are spending too much time sending the message over Serial you will overflow the rs232 port receive buffer.
Post the entire code, too many unknowns such as baud rates, buffer sizes, constant values, etc.
Did you check compiler warnings ?
#define _SS_MAX_RX_BUFF 256
#include <SoftwareSerial.h>
#define PIN_START 13
#define PIN_RESET 12
#define PIN_PS01 8
#define PIN_PS02 7
#define PIN_READY 6
#define PIN_OK 5
#define PIN_NG 4
#define PIN_OPEN 3
#define PIN_E02 2
#define PIN_RS232_RX 10
#define PIN_RS232_TX 11
SoftwareSerial rs232(PIN_RS232_RX, PIN_RS232_TX);
int ps01 = 0;
int ps02 = 0;
unsigned int resetPulseMs = 1000;
String rs232Buffer = "";
unsigned long lastRS232Char = 0;
void setup() {
Serial.begin(9600);
rs232.begin(9600);
pinMode(PIN_PS01, OUTPUT);
pinMode(PIN_PS02, OUTPUT);
pinMode(PIN_START, OUTPUT);
pinMode(PIN_RESET, OUTPUT);
pinMode(PIN_READY, INPUT_PULLUP);
pinMode(PIN_OK, INPUT_PULLUP);
pinMode(PIN_NG, INPUT_PULLUP);
pinMode(PIN_OPEN, INPUT_PULLUP);
pinMode(PIN_E02, INPUT_PULLUP);
digitalWrite(PIN_PS01, LOW);
digitalWrite(PIN_PS02, LOW);
digitalWrite(PIN_START, LOW);
digitalWrite(PIN_RESET, LOW);
printPS();
sendPresetStatus();
}
void loop() {
if (Serial.available()) {
String cmd = Serial.readStringUntil('\n');
cmd.trim();
cmd.toUpperCase();
if (cmd.startsWith("PS01 ")) {
handlePS01(cmd);
}
else if (cmd.startsWith("PS02 ")) {
handlePS02(cmd);
}
else if (cmd.startsWith("SET ")) {
handleSet(cmd);
}
else if (cmd == "START") {
sendStartPulse();
}
else if (cmd.startsWith("RESET")) {
handleReset(cmd);
}
else if (cmd == "STATUS") {
printStatus();
}
else if (cmd.startsWith("RS232 SEND ")) {
String payload = cmd.substring(11);
payload.trim();
rs232.println(payload);
Serial.println("RS232: Sent -> " + payload);
}
else {
Serial.println("ERROR: Invalid command");
}
}
handleRS232Data();
monitorInputs();
delay(10);
}
void handleRS232Data() {
while (rs232.available()) {
char c = rs232.read();
lastRS232Char = millis();
if ((c >= 32 && c <= 126) || c == '\t') {
rs232Buffer += c;
}
else if (c == '\n' || c == '\r') {
if (rs232Buffer.length() > 0) {
Serial.println("RS232: Received <- " + rs232Buffer);
rs232Buffer = "";
lastRS232Char = 0;
}
}
delayMicroseconds(500);
}
if (rs232Buffer.length() > 0 && lastRS232Char > 0) {
if (millis() - lastRS232Char > 200) {
Serial.println("RS232: Received <- " + rs232Buffer);
rs232Buffer = "";
lastRS232Char = 0;
}
}
if (rs232Buffer.length() > 250) {
Serial.println("RS232: Received <- " + rs232Buffer);
Serial.println("WARNING: Buffer overflow protection triggered");
rs232Buffer = "";
lastRS232Char = 0;
}
}
void handlePS01(String cmd) {
if (cmd.length() >= 6) {
String value = cmd.substring(5);
value.trim();
if (value == "0" || value == "1") {
ps01 = value.toInt();
digitalWrite(PIN_PS01, ps01);
Serial.println("OK: PS01=" + String(ps01));
printPS();
sendPresetStatus();
delay(100);
checkResponse();
} else {
Serial.println("ERROR: Value must be 0 or 1");
}
}
}
void handlePS02(String cmd) {
if (cmd.length() >= 6) {
String value = cmd.substring(5);
value.trim();
if (value == "0" || value == "1") {
ps02 = value.toInt();
digitalWrite(PIN_PS02, ps02);
Serial.println("OK: PS02=" + String(ps02));
printPS();
sendPresetStatus();
delay(100);
checkResponse();
} else {
Serial.println("ERROR: Value must be 0 or 1");
}
}
}
void handleSet(String cmd) {
String values = cmd.substring(4);
values.trim();
int v1 = 0, v2 = 0;
int count = 0;
int start = 0;
for (int i = 0; i <= values.length() && count < 2; i++) {
if (i == values.length() || values[i] == ' ') {
if (i > start) {
String val = values.substring(start, i);
val.trim();
if (val == "0" || val == "1") {
if (count == 0) v1 = val.toInt();
else if (count == 1) v2 = val.toInt();
count++;
} else {
Serial.println("ERROR: All values must be 0 or 1");
return;
}
}
start = i + 1;
}
}
if (count == 2) {
ps01 = v1;
ps02 = v2;
digitalWrite(PIN_PS01, v1);
digitalWrite(PIN_PS02, v2);
Serial.println("OK: Both PS values set");
printPS();
sendPresetStatus();
delay(100);
checkResponse();
} else {
Serial.println("ERROR: Need 2 values. Example: SET 1 0");
}
}
void sendStartPulse() {
Serial.println("SENDING: START pulse");
printPS();
sendPresetStatus();
digitalWrite(PIN_START, HIGH);
delay(100);
digitalWrite(PIN_START, LOW);
Serial.println("OK: START sent");
delay(300);
checkResponse();
}
void handleReset(String cmd) {
unsigned int pulseMs = resetPulseMs;
if (cmd.length() > 5) {
String arg = cmd.substring(5);
arg.trim();
if (arg.length() > 0) {
int val = arg.toInt();
if (val > 0 && val <= 60000) {
pulseMs = val;
} else {
Serial.println("ERROR: RESET pulse ms out of range (1-60000)");
return;
}
}
}
sendResetPulse(pulseMs);
}
void sendResetPulse(unsigned int pulseMs) {
Serial.print("SENDING: RESET pulse (");
Serial.print(pulseMs);
Serial.println("ms)");
digitalWrite(PIN_RESET, HIGH);
delay(pulseMs);
digitalWrite(PIN_RESET, LOW);
Serial.println("OK: RESET sent");
printPS();
sendPresetStatus();
delay(100);
checkResponse();
}
void printPS() {
Serial.println("CURRENT: PS01=" + String(ps01) +
", PS02=" + String(ps02));
}
void sendPresetStatus() {
Serial.print("PRESET: PS01=");
Serial.print(ps01);
Serial.print(" PS02=");
Serial.println(ps02);
}
void checkResponse() {
Serial.println("RESPONSE IMP: READY=" + String(digitalRead(PIN_READY)) +
", OK=" + String(digitalRead(PIN_OK)) +
", NG=" + String(digitalRead(PIN_NG)) +
", OPEN=" + String(digitalRead(PIN_OPEN)) +
", E02=" + String(digitalRead(PIN_E02)));
}
void monitorInputs() {
static bool lastReady = false;
static bool lastOK = false;
static bool lastNG = false;
static bool lastOpen = false;
static bool lastE02 = false;
bool ready = digitalRead(PIN_READY);
bool ok = digitalRead(PIN_OK);
bool ng = digitalRead(PIN_NG);
bool open = digitalRead(PIN_OPEN);
bool e02 = digitalRead(PIN_E02);
if (ready != lastReady) {
Serial.println(ready ? "EVENT: READY HIGH" : "EVENT: READY LOW");
lastReady = ready;
}
if (ok != lastOK) {
Serial.println(ok ? "EVENT: OK HIGH" : "EVENT: OK LOW");
lastOK = ok;
}
if (ng != lastNG) {
Serial.println(ng ? "EVENT: NG HIGH" : "EVENT: NG LOW");
lastNG = ng;
}
if (open != lastOpen) {
Serial.println(open ? "EVENT: OPEN HIGH" : "EVENT: OPEN LOW");
lastOpen = open;
}
if (e02 != lastE02) {
Serial.println(e02 ? "EVENT: E02 HIGH" : "EVENT: E02 LOW");
lastE02 = e02;
}
}
void printStatus() {
Serial.println("=== STATUS ===");
printPS();
sendPresetStatus();
checkResponse();
Serial.println("==============");
}
This is the whole code
Not sure how you transferred that, but the double lines make it unwieldy. Please go back to the IDE, press ctrl-t to standardize the formatting, then shft-ctrl-c to "copy for forum", then modify your post, replacing the code block by selecting it, then pressing ctrl-v. That should correct the formatting features, I hope.
Then, we can explore the code.
avoid using the String class on low power/low memory microcontrollers such as the UNO - memory can become fragmented, corrupting information or even crashing the program
also recommend you move to microcontroller with hardware serial ports
if you only have a UNO maybe worth trying altsoftserial
First thing I would do is increase the baud rate of Serial as high as practical.
Not sure under what conditions the rs232 data is sent, but there are a few delay() statements in your code that could cause problems. At 9600 baud, one character takes slightly over 1mS to receive, a delay of 100mS is enough time to accumulate 96 characters in the receive buffer, the sendStartPulse() function has a total of 400mS of delays, well over the 256 bytes in your receive buffer.
#define _SS_MAX_RX_BUFF 256
#include <SoftwareSerial.h>
Did you modify _SS_MAX_RX_BUFF in the SoftwareSerial.h file itself? Placing the #define in your sketch will have no effect on the library.
I would avoid using String in Serial.print() statements, the text literals are stored in ram, taking up a considerable amount of memory, and as far as I know String cannot concatenate text stored in PROGMEM. Using a series of print() statements would let you use the F() macro to store text literals in PROGMEM, freeing up memory and delaying any problems caused by String consuming all available ram.
@david_2018
Hmm. From SoftwareSerial.h:
#ifndef _SS_MAX_RX_BUFF
#define _SS_MAX_RX_BUFF 64 // RX buffer size
#endif
So I think it can be overridden, correct me if I'm wrong.
Agree fully with your other comments, in particular, String used as the OP is using it will lead to difficult-to-diagnose crashes at some point, may be minutes, hours, or days later. Better to repeatedly manipulate a local char buffer using classic string methods - or rewrite the sketch to process incoming data live, avoiding buffering completely.
A #define in the sketch will not be seen by the library. You can test by compiling any of the example sketches for SoftwareSerial and inserting the #define for _SS_MAX_RX_BUFF, regardless of how large you make the buffer the amount of ram used will not change unless you modify the header file itself. The only way to pre-define _SS_MAX_RX_BUFF would be to specify it in an argument to the command that calls the compiler.