Help

Welcome!

This community is for professionals and enthusiasts of our products and services. Share and discuss the best content and new marketing ideas, build your professional profile and become a better marketer together.

0

No data received on RS485 port

Avatar
Ian Campbell-Kelly

I'm sending data from an Allen-Bradley PLC to an Ardbox Analog HF+ MODBUS at 9600baud (8 data bits, no parity, one stop bit)

Each second, the A-B PLC sends a packet of 20 bytes plus CR and LF. I am using a RS485-USB adapter and Hyperterminal to show that the data is being sent. The link is connected to A+ and B-. Half duplex is selected.

When the program starts, the message <Arduino is ready> is correctly displayed on the Serial Monitor (COM21). The problem is that no further data is displayed, so we assume that the Arduino is not receiving any data. (Is the problem related to the Ardbox expecting Modbus protocol?)

Can you see any problem with this?

The code from "//Leading bogie onwards" works fine. It should write to digital outputs at up to 3kHz, in a sequence Set1-Set2-Clear1-Clear2. I am using the PORT command rather than digitalOutput for extra speed.

When the communications problem is solved, I will set the speed and direction of the sequence using data sent via RS485.

Thanks for any help you can give

The code looks like this:

// Include Industrial Shields libraries

#include <RS485.h>

long interval_0 = 250000;

long count_0 = 0;

unsigned long phase_0 = 0;

long interval_1 = 150000;

long count_1 = 0;

unsigned long phase_1 = 0;

bool DMA_forwards = 0;  // 1 for DMA forwards, 2 for DMB forwards

char RxBuffer[24];     // 22-character buffer, 5 DINTs and CR LF with a couple to spare

int test_available; 

const int serialConfig = SERIAL_8N1;


void setup() {

  // put your setup code here, to run once:

Serial.begin(9600);

delay(2000);

SerialUSB.println("<Arduino is ready>");


// Begin RS485 port

RS485.begin(9600);

//RS485.setTimeout(90);  //set serial read timeout to 90ms

}


void loop() {

// Main code 



if (RS485.available()) {    

  byte rx = RS485.read();

    // Hexadecimal representation

// byte rx=0; 

//    SerialUSB.write(rx);

    SerialUSB.print("HEX: ");

    SerialUSB.println(rx, HEX);


    // Decimal representation

    SerialUSB.print(", DEC: ");

    SerialUSB.println(rx, DEC);

  test_available = RS485.available();

  SerialUSB.println("Chars available");

  SerialUSB.println(test_available);

}

// Leading bogie
if (DMA_forwards = 1) {
  if (micros()>(count_0 + interval_0) or micros() > 4294950000)
    {
    count_0 = micros();
    switch (phase_0){
      case 0:
      PORTB = PORTB & B10011111; // clear Q0_2, Q0_3
      break;
      case 1:
      PORTB = PORTB | B01000000; // set Q0_2
      break;
      case 2:
      PORTB = PORTB | B01100000; // set Q0_2, Q0_3
      break;
      case 3:
      PORTB = PORTB & B00100000; // clear Q0_2
      break;
      }
    phase_0 = phase_0+1;
    if (phase_0 > 3) {phase_0 = 0;}
    }
  // Trailing bogie - 
  if (micros()>(count_1 + interval_1) or micros() > 4294950000)
    {
    count_1 = micros();
    switch (phase_1){
      case 0:
      PORTD = PORTD & B01111110; // clear Q0_4, Q0_6
      break;
      case 1:
      PORTD = PORTD | B10000000; // set Q0_4
      break;
      case 2:
      PORTD = PORTD | B10000001; //set Q0_4, Q0_6
      break;
      case 3:
      PORTD = PORTD & B01111111; // clear Q0_4 (leave Q0_6 set)
      break;
      }
    phase_1 = phase_1+1;
    if (phase_1 > 3) {phase_1 = 0;}
    }
  }
else {
  if (micros()>(count_0 + interval_0) or micros() > 4294950000)
    {
    count_0 = micros();
    switch (phase_0){
      case 0:
      PORTB = PORTB & B10011111; // clear Q0_2, Q0_3
      break;
      case 1:
      PORTB = PORTB | B00100000; // set Q0_3
      break;
      case 2:
      PORTB = PORTB | B01100000; // set Q0_2, Q0_3
      break;
      case 3:
      PORTB = PORTB & B01000000; // clear Q0_3
      break;
      }
    phase_0 = phase_0+1;
    if (phase_0 > 3) {phase_0 = 0;}
    }
  // Trailing bogie - 
  if (micros()>(count_1 + interval_1) or micros() > 4294950000)
    {
    count_1 = micros();
    switch (phase_1){
      case 0:
      PORTD = PORTD & B01111110; // clear Q0_4, Q0_6
      break;
      case 1:
      PORTD = PORTD | B00000001; // set Q0_6
      break;
      case 2:
      PORTD = PORTD | B10000001; //set Q0_4, Q0_6
      break;
      case 3:
      PORTD = PORTD & B11111110; // clear Q0_6 (leave Q0_4 set)
      break;
      }
    phase_1 = phase_1+1;
    if (phase_1 > 3) {phase_1 = 0;}
    }
  }
}

2 Comments
Avatar
Discard
Avatar
Ian Campbell-Kelly
-

The port settings are unchanged from the original:

DDRB is B11100001

DDRC is B11000000

DDRD is B10101101

Selecting Full Duplex on the HD/FD selector switch makes no difference

Avatar
Ian Campbell-Kelly
-

Another odd thing: Including the RS485.begin(9600); line in the setup{} routine sets output Q0.9 (looking at the LEDs on the module).

3 Answers
0
Avatar
Marti Guillem Cura
Best Answer

First of all, check if the RS485 is working properly. On the following blog is explained how to work with the RS485, please check all the configurations required as it and try the example codes provided.

Avatar
Discard