2 Arduino UNOs RS485 SimpleModBus PRESET_MULTIPLE_REGISTERS problem [SOLVED]

SOLVED - this weird behavior was a symptom of not having the two 470ohm RS485 bus resistors in place (from A to 5V and from B to GND). Mistakenly thought they were part of the RS485 board itself.

Hi. I have 2 Arduino UNO R3s wired up for RS485 and using the SimpleModBus protocol (SimpleModbusMasterV2rev2 and SimpleModbusSlaveV10). Each Arduino has a pot on A0 and the intent is to use the pot to control the LED blink rate on the other Arduino's board over the RS485/SimpleModBus link.

Two packets are defined for the Master - one for function 3 READ_HOLDING_REGISTERS and one for function 16 PRESET_MULTIPLE_REGISTERS.

Function 3 is working fine - the slave is getting the function 3 packet, processing, returning the slave pot value from its register SLAVE_POT, and master is controlling its LED from that value just as designed.
However, the function 16 is not working at all. The data is always received by the slave as 0. I think I've ruled out a problem associated with the master_regs[MASTER_POT] = map(potValue, 380, 630, 0, 1000); line - I can hardcode master_regs[MASTER_POT] to a nonzero value like 500 and the data is still received as 0 by the slave. I've also looked at the data stream in the serial monitor and the function 16 data is not changing when moving the master pot around. (For the function 3 I can see the values moving as I play with the slave pot.) So it seems like an issue with the assembly of the packet but I can't figure it out. I'm hoping someone here can spot the issue.

Thanks

Master:

#include <SimpleModbusMaster.h>

#define baud 9600
#define timeout 1000
#define polling 200
#define retry_count 10
#define TxEnablePin 2

enum
{
  PACKET1,
  PACKET2,
  TOTAL_NO_OF_PACKETS
};
Packet packets[TOTAL_NO_OF_PACKETS];

enum
{
  MASTER_POT,
  SLAVE_POT,
  NO_OF_REGS
};
unsigned int master_regs[NO_OF_REGS];
unsigned int potPin = A0;
unsigned int ledPin = 13;
unsigned int potValue = 0;
unsigned int ledDelay = 0;
unsigned int currentMillis;
unsigned int previousMillis;
unsigned int slave_pot;

void setup()
{
  pinMode(ledPin,OUTPUT);
  digitalWrite(ledPin,LOW);
  previousMillis = millis();

  //Packet1: slave 1, read, from slave register SLAVE_POT, length 1, put into master register SLAVE_POT
  modbus_construct(&packets[PACKET1], 1, READ_HOLDING_REGISTERS, SLAVE_POT, 1, SLAVE_POT);
  //Packet2: slave 1, write, to slave register MASTER_POT, length 1, put into slave register MASTER_POT
  modbus_construct(&packets[PACKET2], 1, PRESET_MULTIPLE_REGISTERS, MASTER_POT, 1, MASTER_POT);
  
  // Initialize the Modbus Finite State Machine
  modbus_configure(&Serial, baud, SERIAL_8N2, timeout, polling, retry_count, TxEnablePin, packets, TOTAL_NO_OF_PACKETS, master_regs);
}

void loop()
{
  modbus_update();

// Read master pot and store in master_regs[MASTER_POT] for writing to slave
  potValue = analogRead(potPin);  
  master_regs[MASTER_POT] = map(potValue, 380, 630, 0, 1000);

// Get slave pot value from master_regs[SLAVE_POT] and blink LED based on value
  slave_pot = master_regs[SLAVE_POT];
  currentMillis = millis();
  if (currentMillis - previousMillis >= slave_pot){
    previousMillis = millis();
    if(digitalRead(ledPin) == HIGH){
      digitalWrite(ledPin,LOW);
    } else {
      digitalWrite(ledPin,HIGH);
    }
  }
}

Slave:

#include <SimpleModbusSlave.h>

#define baud 9600
#define TxEnablePin 2
#define slaveid 1

enum 
{
  MASTER_POT,
  SLAVE_POT,
  NO_OF_REGS
};

unsigned int slave_regs[NO_OF_REGS];
unsigned int potPin = A0;
unsigned int ledPin = 13;
unsigned int potValue = 0;
unsigned int ledDelay = 0;
unsigned int currentMillis;
unsigned int previousMillis;
unsigned int master_pot;

void setup()
{
  pinMode(ledPin,OUTPUT);
  digitalWrite(ledPin,LOW);
  previousMillis = millis();
  
  modbus_configure(&Serial, baud, SERIAL_8N2, slaveid, TxEnablePin, NO_OF_REGS, slave_regs);
//  modbus_update_comms(9600, SERIAL_8N2, 1);  not necessary
}

void loop()
{
  modbus_update();

// Read slave pot and store in slave_regs[SLAVE_POT] for reading by master
  potValue = analogRead(potPin);
  slave_regs[SLAVE_POT] = map(potValue, 380, 630, 0, 1000);
  
// Get master pot value from slave_regs[MASTER_POT] and blink LED based on value
  master_pot = slave_regs[MASTER_POT];
  currentMillis = millis();
  if (currentMillis - previousMillis >= master_pot){
    previousMillis = millis();
    if(digitalRead(ledPin) == HIGH){
      digitalWrite(ledPin,LOW);
    } else {
      digitalWrite(ledPin,HIGH);
    }
  }
}

Welcome to the forum Marlow,

A quick look and I see in your slave code the master_pot time is not initialised to a value, except zero by default, which will not be what you want.

if (currentMillis - previousMillis >= master_pot){

Paul