RS232 communication beween PLC & Arduino UNO

I'm using an Automation Direct Click PLC with an Arduino UNO. I have connected them together using a RS232 shield using Software Serial on pins 2 & 3. I am only using the PLC to transmit integers to the Arduino and everything works fine in a stand alone routine. Using Serial. available captures the data sent from the PLC but when I insert the routine into the larger process of Arduino the data isn't captured.

All the information I find on the web has to with hardware configuring and not so much with the handshaking between devices .I thought that the sent data would stay in the buffer until read. So a call to the function that reads the Software serial port should find the data but it doesn't. How is the serial buffer emptied if it has not been cleared by reading?

Attached is the read routine that works as a stand alone program. How can I insert it into the main program to capture an output from the PLC? Do I need to use an interrupt?

#include <SoftwareSerial.h>
// software serial #1: RX = digital pin 2, TX = digital pin 3
SoftwareSerial portOne(2, 3);

// software serial #2: RX = digital pin 8, TX = digital pin 9
// on the Mega, use other pins instead, since 8 and 9 don't work on the Mega
SoftwareSerial portTwo(8, 9);

void setup() {
  // Open serial communications and wait for port to open:
  Serial.begin(9600);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB port only
  }
  // request encoder values


  // Start each software serial port
  portOne.begin(9600);

  while (portOne.available() > 0) {

    int Heigth = portOne.parseInt();
    int Width = portOne.parseInt();
    int ErrorCheck = portOne.parseInt();


  }
}

void loop() {
  // By default, the last intialized port is listening.
  // when you want to listen on a port, explicitly select it:
  portOne.listen();
  delay(2000);
  while (portOne.available() > 0) {
    int Heigth = portOne.parseInt();
    int Width = portOne.parseInt();
    int ErrorCheck = portOne.parseInt();
    Serial.print("Heigth  ");
    Serial.println(Heigth);
    Serial.print("Width  ");
    Serial.println(Width);
    Serial.print("ErrorCheck  ");
    Serial.println(ErrorCheck);
    if (Heigth + Width != ErrorCheck) { // Do something besides Print Error
      Serial.println("++++++++++++++ Error  ++++++++++++++++++");
    }
  }
  delay(100);

}

The result from the above code running alone:

Heigth 21200.00
Width 480.00
ErrorCheck 21680.00

Its kind of hard to diagnose problems in software without seeing the actual software.. Suggest you also post the non-working code.

Here is part of the code. The Function GetSetPoint (at the bottom here) is where I'm trying to get the output from the PLC. Even when I have the PLC send multiple outputs nothing is captured.

Thanks for the help.

/
                      

#include <SoftwareSerial.h>

SoftwareSerial portOne(2, 3); // RX, TX

#include <SPI.h>
// Slave Select pins for encoders 1 and 2
// Feel free to reallocate these pins to best suit your circuit
const int Mark5_Select = 10;
const int Brake_Select = 9;

// These hold the current encoder count.
signed long encoder1count = 0;
signed long encoder2count = 0;
int value = 0x88;



/********************************************************************************************************
                      VARIABLES DEFINITION
********************************************************************************************************/
#include <Wire.h>
// Expansion Board Definitions  Labeling on board appears to be inverted for Port A 
const byte  mcp_address=0x20;      // I2C Address of MCP23017 Chip
const byte  GPIOA=0x12;            // Register Address of Port A
const byte  GPIOB=0x13;            // Register Address of Port B
const byte  IODIRA=0x00;            // IODIRA register
const byte  IODIRB=0x01;            // IODIRB register

const byte  PinDA[]={0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01};//Pin DA0,1,2,3,4,5,6,7
const byte  PinDB[]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};//Pin DB0,1,2,3,4,5,6,7

// Mark 5 Definitions
int Mark5Encoder = 1;
const int Mark5_HomeSensor = A0;
byte Mark5_JogIn = PinDB[3];
byte Mark5_JogOut = PinDB[2];
const int Mark5_DriveEnable = 6; //Output to PLC to Start Drive Motor
const int Mark5_DriveIn = 5; //Output to PLC to Drive motor in(DriveIn = LOW is DriveOut)
byte Mark5_StartDrive = PinDB[1]; // Input pin from PLC to start Drive positioning
byte Mark5_DriveSet = PinDB[6]; // Drive Set output (Stop Drive)
const int Mark5_Speed = 7; // Speed output to PLC
int Mark5_HomeOffset = 423; // offset that the proximity sensor is away from actual zero position
int Mark5_SpeedChange = 2000; // Variable to change from High Speed to Low Speed
int Mark5_Offset_Err = 10; // # Pulses that encoder error is acceptable +/- 9 =
boolean Mark5_Set = false;// false is Drive is not in position
boolean Mark5_Home = true; // Home true = Drive has not homed, sensor is high when no proximity present
boolean Mark5_SpeedHigh = false; //false = low speed
boolean Mark5_JogChange = false;// Flag to reset DriveEnable when Jog buttons released

// *******Brake Definitions***********
int BrakeEncoder = 2;
const int Brake_HomeSensor = A1;
byte Brake_JogIn = PinDB[4];
byte Brake_JogOut = PinDB[5];
const int Brake_DriveEnable = 3; //Output to PLC to Start Drive Motor
const int Brake_DriveIn = 2; //Output to PLC to Drive motor in(DriveIn = LOW is DriveOut)
byte Brake_StartDrive = PinDB[0]; // Input pin from PLC to start Drive positioning
byte Brake_DriveSet = PinDB[7]; // Drive Set output (Stop Drive)
const int Brake_Speed = 4; // Speed output to PLC
int Brake_HomeOffset = 456; // offset that the proximity sensor is away from actual zero position
int Brake_SpeedChange = 1000; // Variable to change from High Speed to Low Speed
int Brake_Offset_Err = 5; // # Pulses that encoder error is exceptable +/- 4 =
boolean Brake_Set = false;// false is Drive is not in position
boolean Brake_JogChange = false;// false is Drive is not in position
boolean Brake_Home = true; // Home true = Drive has not homed, sensor is high when no proximity present
boolean Brake_SpeedHigh = false; //false = low speed

long int newPos = 0;
long SetPointMark5 = Mark5_HomeOffset;// Set start Position
long SetPointBrake = Brake_HomeOffset;// Set start Position

void setup()
{
  Serial.begin(57600);
  portOne.begin(9600);

 /* while (!Serial)
  {
    ; // wait for serial port to connect. Needed for Leonardo only
  }
 */
 initEncoders();       Serial.println("Encoders Initialized...");  
 clearEncoderCount();  Serial.println("Encoders Cleared...");

//Send settings to MCP device
  Wire.begin();              // join i2c bus (address optional for master)
  Wire.beginTransmission(mcp_address);
  Wire.write((byte)IODIRB); // IODIRB register
  Wire.write((byte)0x3F); // set GPIOB-0-5 to inputs
  Wire.endTransmission();
  Wire.beginTransmission(mcp_address);
  Wire.write((byte)0x0D); // Pull up Register (GPPUA)
  Wire.write((byte)0x3F); // set 0-5 bits
  Wire.endTransmission();

  pinMode(Mark5_DriveEnable, OUTPUT);// 
  pinMode(Mark5_DriveIn, OUTPUT); // 
  pinMode(Mark5_DriveSet, OUTPUT);// 
  pinMode(Mark5_Speed, OUTPUT);
 // pinMode(Mark5_StartDrive, INPUT_PULLUP);// Input to start process( PLC is a sink only output so reverse the logic)
    //digitalWrite(Mark5_DriveSet, LOW);// Drive not in position
  pinMode(Brake_DriveEnable, OUTPUT);// 
  pinMode(Brake_DriveIn, OUTPUT); // 
  pinMode(Brake_DriveSet, OUTPUT);// 
  pinMode(Brake_Speed, OUTPUT);
  pinMode(Brake_StartDrive, INPUT_PULLUP);// Input to start process( PLC is a sink only output so reverse the logic
}// end setup()

void loop() // run over and over
{ 
  //Read_IOExpand();   // Check Expansion Ports
  int Mark5_SetPoint_Pulses = GetSetPoint(Mark5Encoder);// Get Encoder Count for Mark5
  Mark5Process(Mark5_SetPoint_Pulses);// Position Mark5 Drive to Setpoint
  //BrakeProcess();// Position Brake Drive to Setpoint
  
}//end loop
int  GetSetPoint(int Machine){//Select which Machine Pulse Count is needed
  // and return that Count
  portOne.listen();
while (portOne.available() > 0) {
    int Mark5 = portOne.parseInt();
   int Brake = portOne.parseInt();
   long ErrorCheck = portOne.parseInt();
    Serial.print("Mark5  ");
    Serial.println(Mark5);
    Serial.print("Brake  ");
    Serial.println(Brake);
    Serial.print("ErrorCheck  ");
    Serial.println(ErrorCheck);
    if(Mark5+Brake != ErrorCheck){
      Serial.println("++++++++++++++ Error  ++++++++++++++++++"); //do something besides printing
    }
    if(Machine==1){
      return Mark5;
    }else{
        return Brake;
      
    }
  }
delay(100);
 

  
} // end

You're using the Software Serial library.

Check whether it conflicts with the other libraries (Wire and SPI) you are using.

It is baffling why people cheap out and don't buy an Mega when they clearly need a hardware serial port!

.

Have you tried using rs485 Modbus?