Yun communicate via modbus RTU while writing to SD card.

Hi.

I have a Arduino Yun. I am presently communicating to a modbus RTU device, using a MAX485 chip and the modbus RTU slave library. My question is, am I able to write over the micro SD card without any communication lost. The goal is to write over SD card directly from my Modbus device.

I tryed to include both libraries, SD card and modbus RTU, but I am losing connection as soon as I try to write on the card. Maybe there is a way to manage both library, not at the same time ?

Thanks for your help !

Plan B:

Do every thing at Linux side:

USB to RS485 Max485 Converter Adapter, connect it at Linux side.

Ok and do I need something special to call the modbus RTU via USB? or it will automaticly pass through it. Because right now I am using Rx and Tx for my modbus communication.

Also, are you sur it would work? Does anyone have tryed this yet?

firefrench999:
...
Also, are you sur it would work? Does anyone have tryed this yet?

It costs few $, might be $2.

The code is free!

#include <modbus.h>
modbus_t *ctx;
uint16_t tab_reg[64];
int rc;
int i;
// create your modbus device object
/*modbus_t *modbus_new_rtu(
    const char *device, int baud, char parity, int data_bit, int stop_bit);*/
ctx = modbus_new_rtu("/dev/ttyUSB0", 115200, 'N', 8, 1);
// check if object was created successfully
if (ctx == NULL) {
    fprintf(stderr, "Unable to create the libmodbus context\n");
    return -1;
}
//int modbus_read_registers(modbus_t *ctx, int addr, int nb, uint16_t *dest);
// read a register value from modbus object into value 'rc'
rc = modbus_read_registers(ctx, 2, 3, tab_reg);
// check to make sure read was successful
if (rc == -1) {
    fprintf(stderr, "%s\n", modbus_strerror(errno));
    return -1;
}
// i'm guessing on this one, but convert a bytes vale into an integer... probably?
for (i=0; i < rc; i++) {
    printf("reg[%d]=%d (0x%X)\n", i, tab_reg[i], tab_reg[i]);
}
// close port and free memory
modbus_close(ctx);
modbus_free(ctx);

I have to admit that I don't understand the code, consider that I am new to C++. My present code is :

''
#include <SimpleModbusSlave.h>

//Définition du LED comme étant la PIN 9.

#define LED 9

///////////////////////////////////////////////////////////////////

//Énumération des registres du Arduino
//Le premier registre commence à 0.
//Voir plus bas pour le format exact des registres.
//ADC = Réservé pour les pin 0 et 1
//INDIG = Input Digital
//OUTD = Output Digital
//AOUT = Analog Write

enum
{
ADC0,
ADC1,
INDIG0,
INDIG1,
INDIG2,
INDIG3,
OUTD0,
OUTD1,
OUTD2,
OUTD3,
AOUT0, //

HOLDING_REGS_SIZE
};

//////////////////////////////////////////////////////////////////////

// Assignation de la structure des Holding Registers

unsigned int holdingRegs[HOLDING_REGS_SIZE];

/////////////////////////////////////////////////////////////////////

//Setup de départ

void setup()
{

// Initialize the Bridge and the Serial

// COnfiguration du réseau Modbus.
//&Serial1 = Réseau série, disponible aussi en 2 et 3 mais je n'ai jamais testé
//19200 = Baud rate
//SERIAL_8N2 = 1 start bit, 8 data bits, 2 stop bitset none parity.Aussi disponible en SERIAL_8E1 et SERIAL_8O1
//1 = Adresse modbus
//2 = Modbus Enable PIN, à utilisé pour la chip MAX485

modbus_configure(&Serial1, 19200, SERIAL_8N2, 1, 2, HOLDING_REGS_SIZE, holdingRegs);

// Update de la configuration réseau

modbus_update_comms(19200, SERIAL_8N2, 1);

//Assignation des différentes entrées et sorties.
//Définition du LED en sortie.

pinMode(LED, OUTPUT);

//DÉfinition des PIN pour les entrées digitales

pinMode(10, INPUT_PULLUP);
pinMode(11, INPUT_PULLUP);
pinMode(12, INPUT_PULLUP);
pinMode(13, INPUT_PULLUP);

//DÉfinition des PIN pour les sortie digitales.

pinMode(3,OUTPUT);
pinMode(4,OUTPUT);
pinMode(5,OUTPUT);
pinMode(6,OUTPUT);

//Définition des PIN pour les sorties digitales.

pinMode(8,OUTPUT);
pinMode(9,OUTPUT);

//Initialisation des Holding Regs.

holdingRegs[0] = 0;
holdingRegs[1] = 0;
holdingRegs[2] = 0;
holdingRegs[3] = 0;
holdingRegs[4] = 0;
holdingRegs[5] = 0;
holdingRegs[6] = 0;
holdingRegs[7] = 0;
holdingRegs[8] = 0;
holdingRegs[9] = 0;
holdingRegs[10] = 0;

}

///////////////////////////////////////////////////////////////////

//Loop à l'infini

void loop()
{

//Update de la configuration modbus

modbus_update();

//Update de chacun des registres

holdingRegs[0] = analogRead(0);
holdingRegs[1] = analogRead(1);

holdingRegs[2] = digitalRead(10);
holdingRegs[3] = digitalRead(11);
holdingRegs[4] = digitalRead(12);
holdingRegs[5] = digitalRead(13);

digitalWrite(3,holdingRegs[6]);
digitalWrite(4,holdingRegs[7]);
digitalWrite(5,holdingRegs[8]);
digitalWrite(6,holdingRegs[9]);

analogWrite(9,holdingRegs[10]);

if (holdingRegs[10] == 69)
{
digitalWrite(LED, LOW);

}
else
{
digitalWrite(LED,HIGH);
}

if (holdingRegs[10] == 1)
{
holdingRegs[6] = 1 ;
Serial.println(" LED ON");
}
else
{
holdingRegs[6] = 0 ;
Serial.println(" LED OFF");
}

}
''

As soon as I add a '' File dataFile2 = FileSystem.open("/mnt/sd/arduino/HMI.CSV", FILE_APPEND);'' command, I lose modbus communication.

I finally succeed to write on the card and keep my modbus communication, eventhough I am stoping the modbus update while writing to the card. Here is my new code:


#include <SimpleModbusSlave.h>
#include <FileIO.h>

//Définition du LED comme étant la PIN 9.

#define LED 9

///////////////////////////////////////////////////////////////////

//Énumération des registres du Arduino
//Le premier registre commence à 0.
//Voir plus bas pour le format exact des registres.
//ADC = Réservé pour les pin 0 et 1
//INDIG = Input Digital
//OUTD = Output Digital
//AOUT = Analog Write

enum
{
ADC0,
ADC1,
INDIG0,
INDIG1,
INDIG2,
INDIG3,
OUTD0,
OUTD1,
OUTD2,
OUTD3,
AOUT0, //

HOLDING_REGS_SIZE
};

//////////////////////////////////////////////////////////////////////

// Assignation de la structure des Holding Registers

unsigned int holdingRegs[HOLDING_REGS_SIZE];

/////////////////////////////////////////////////////////////////////

//Setup de départ

void setup()
{

// Initialize the Bridge and the Serial
Bridge.begin();
Serial.begin(9600);
FileSystem.begin();

// COnfiguration du réseau Modbus.
//&Serial1 = Réseau série, disponible aussi en 2 et 3 mais je n'ai jamais testé
//19200 = Baud rate
//SERIAL_8N2 = 1 start bit, 8 data bits, 2 stop bitset none parity.Aussi disponible en SERIAL_8E1 et SERIAL_8O1
//1 = Adresse modbus
//2 = Modbus Enable PIN, à utilisé pour la chip MAX485

modbus_configure(&Serial1, 19200, SERIAL_8N2, 1, 2, HOLDING_REGS_SIZE, holdingRegs);

// Update de la configuration réseau

modbus_update_comms(19200, SERIAL_8N2, 1);

//Assignation des différentes entrées et sorties.
//Définition du LED en sortie.

pinMode(LED, OUTPUT);

//DÉfinition des PIN pour les entrées digitales

pinMode(10, INPUT_PULLUP);
pinMode(11, INPUT_PULLUP);
pinMode(12, INPUT_PULLUP);
pinMode(13, INPUT_PULLUP);

//DÉfinition des PIN pour les sortie digitales.

pinMode(3,OUTPUT);
pinMode(4,OUTPUT);
pinMode(5,OUTPUT);
pinMode(6,OUTPUT);

//Définition des PIN pour les sorties digitales.

pinMode(8,OUTPUT);
pinMode(9,OUTPUT);

//Initialisation des Holding Regs.

holdingRegs[0] = 0;
holdingRegs[1] = 0;
holdingRegs[2] = 0;
holdingRegs[3] = 0;
holdingRegs[4] = 0;
holdingRegs[5] = 0;
holdingRegs[6] = 0;
holdingRegs[7] = 0;
holdingRegs[8] = 0;
holdingRegs[9] = 0;
holdingRegs[10] = 0;

}

///////////////////////////////////////////////////////////////////

//Loop à l'infini

void loop()
{

//Update de la configuration modbus

modbus_update();

//Update de chacun des registres

holdingRegs[0] = analogRead(0);
holdingRegs[1] = analogRead(1);

holdingRegs[2] = digitalRead(10);
holdingRegs[3] = digitalRead(11);
holdingRegs[4] = digitalRead(12);
holdingRegs[5] = digitalRead(13);

digitalWrite(3,holdingRegs[6]);
digitalWrite(4,holdingRegs[7]);
digitalWrite(5,holdingRegs[8]);
digitalWrite(6,holdingRegs[9]);

analogWrite(9,holdingRegs[10]);

if (holdingRegs[10] == 69)
{
digitalWrite(LED, LOW);

}
else
{
digitalWrite(LED,HIGH);
}

if (holdingRegs[10] == 1)
{
holdingRegs[6] = 1 ;
Serial.println(" LED ON");
Bridge.begin();
Serial.begin(9600);
FileSystem.begin();
File dataFile = FileSystem.open("/mnt/sd/arduino/HMI.CSV", FILE_APPEND);
if (dataFile) {
dataFile.println(holdingRegs[9]);
dataFile.close();
holdingRegs[10]=0;
modbus_configure(&Serial1, 19200, SERIAL_8N2, 1, 2, HOLDING_REGS_SIZE, holdingRegs);
modbus_update_comms(19200, SERIAL_8N2, 1);

Serial.println("Enregistrement O.K.");
}
else { Serial.println("OUverture de fichier Echec.");
holdingRegs[10] = 0;
modbus_configure(&Serial1, 19200, SERIAL_8N2, 1, 2, HOLDING_REGS_SIZE, holdingRegs);
modbus_update_comms(19200, SERIAL_8N2, 1);
}
}
else
{
holdingRegs[6] = 0 ;
Serial.println(" LED OFF");

}

// delay(1000);
}

You are using Serial1 to talk to your modbus adapter. This is using pins D0 and D1, which are the same pins that are connected to the serial port of the Linux processor. Even if you ignore the Linux processor and don't use any of the Bridge library communications features, you are bound to have conflicts: anything you transmit to the modbus adapter will also be sent to the Linux command line, and it's bound to be confused by it. Furthermore, anything transmitted by the Linux command line (like the error messages when it doesn't understand what you are sending) will combine with and conflict with whatever you receive from the modbus adapter.

Furthermore, as soon as you initialize the Bridge library and use any if its functions, like FileIO, it will take over the Serial1 port and use it for the sketch to Linux communications. That is the reason you are having trouble.

The short version: on the Yun, you need to pretend that Serial1, D0, and D1 do not exist: they are dedicated to communications with the Linux processor.

@firefrench999,
please use markup when posting code. See attached image.

Jesse

arduino_markup.png