Estoy jugando con Modbus en Arduino e hice una pequeña aplicación en C para leer datos del arduino conectado por USB.
Del lado server o slave hay que descargar Libreria para el Arduino e instalarla
El código del arduino es una modificación del ejemplo que viene con la librería, solo agregue una señal analógica de un potenciómetro.
#include <modbus.h>
#include <modbusDevice.h>
#include <modbusRegBank.h>
#include <modbusSlave.h>
//Setup the brewtrollers register bank
//All of the data accumulated will be stored here
modbusDevice regBank;
//Create the modbus slave protocol handler
modbusSlave slave;
const int analogInPin = A0; // Analog input pin that the potentiometer is attached to
int sensorValue = 0; // value read from the pot
void setup()
{
//Assign the modbus device ID.
regBank.setId(1);
//Add Analog Output registers 40001-40020 to the register bank
regBank.add(40001);
regBank.add(40002);
slave._device = ®Bank;
// Initialize the serial port for coms at 9600 baud
slave.setBaud(9600);
}
void loop()
{
while(1)
{
sensorValue = analogRead(analogInPin);
regBank.set(40001, (word) sensorValue);
slave.run();
}
}
En el lado del cliente o master (PC) hay que descargarse la Libreria libmodbus e instalarla (depende del sistema operativo y compilador que se use)
#include <stdio.h>
#include <modbus.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <termios.h>
uint16_t tab_reg[32];// array global donde se almacenan los datos obtenidos por modbus
int main()
{
int i;
/* Se abre el puero y se setea (no necesario en windows */
open("/dev/ttyACM0", O_RDWR | O_NOCTTY);
/* Setup estructura de control */
struct termios toptions;
/* Wait for the Arduino to reset */
usleep(1000*1000);
for(i=1;i<200;i++){
//creacion de contexto modbus.En windows hay que colocar COM1, COM2 o donde se encuentre el Arduino
modbus_t *mb;
mb = modbus_new_rtu("/dev/ttyACM0",9600 , 'N', 8, 1);
if (mb == NULL) {
fprintf(stderr, "imposible crear contexto modbus\n");
return -1;
}
modbus_set_slave(mb,1); //setea el numero de esclavo a consultar. El arduino tiene que estar seteado igual
modbus_connect(mb);//Conecta al contexto creado
modbus_read_registers(mb,0,2, tab_reg);// lee 2 registros a partir del registro "0"y los almacena en tab_reg
printf(" Registro potenciometro %u\n ",tab_reg[0]);// imprime en pantalla el valor leído
modbus_free(mb);// libera el contexto
modbus_close(mb);// cierra la coneccion
}
return 1;
}
Moviendo el potenciómetro se obtendría la siguiente salida
Registro potenciometro 354
Registro potenciometro 390
Registro potenciometro 444
Registro potenciometro 481
Registro potenciometro 524
Registro potenciometro 563
Registro potenciometro 595
Registro potenciometro 630
Registro potenciometro 651
Registro potenciometro 679
Registro potenciometro 705
Registro potenciometro 735
Registro potenciometro 758
Registro potenciometro 783
Registro potenciometro 795
Registro potenciometro 817
Registro potenciometro 826
Registro potenciometro 841
Registro potenciometro 835
Registro potenciometro 839
Registro potenciometro 838
Registro potenciometro 841
Registro potenciometro 839
Registro potenciometro 843
Registro potenciometro 843
Registro potenciometro 836
Registro potenciometro 831
Registro potenciometro 834
Registro potenciometro 831
Registro potenciometro 831
Registro potenciometro 831
Registro potenciometro 831
Registro potenciometro 830
Registro potenciometro 839
Registro potenciometro 829
Registro potenciometro 827
Registro potenciometro 831
Registro potenciometro 832
Registro potenciometro 830
Registro potenciometro 833
martin@casa:~/Escritorio$