Se ha realizado sobre un arduino-barebones con la librería SimpleModbus y se ha empleado el siguiente sketch:
#include <SimpleModbusSlave_DUE.h> /* SimpleModbusSlaveV10_DUE supports function 3, 6 & 16. This example code will receive the adc ch0 value from the arduino master. It will then use this value to adjust the brightness of the led on pin 9. The value received from the master will be stored in address 1 in its own address space namely holdingRegs[]. In addition to this the slaves own adc ch0 value will be stored in address 0 in its own address space holdingRegs[] for the master to be read. The master will use this value to alter the brightness of its own led connected to pin 9. The modbus_update() method updates the holdingRegs register array and checks communication. Note: The Arduino serial ring buffer is 64 bytes or 32 registers. Most of the time you will connect the arduino to a master via serial using a MAX485 or similar. In a function 3 request the master will attempt to read from your slave and since 5 bytes is already used for ID, FUNCTION, NO OF BYTES and two BYTES CRC the master can only request 58 bytes or 29 registers. In a function 16 request the master will attempt to write to your slave and since a 9 bytes is already used for ID, FUNCTION, ADDRESS, NO OF REGISTERS, NO OF BYTES and two BYTES CRC the master can only write 54 bytes or 27 registers. Using a USB to Serial converter the maximum bytes you can send is limited to its internal buffer which differs between manufactures. */ #define LED 13 // Using the enum instruction allows for an easy method for adding and // removing registers. Doing it this way saves you #defining the size // of your slaves register array each time you want to add more registers // and at a glimpse informs you of your slaves register layout. //////////////// registers of your slave /////////////////// enum { // just add or remove registers and your good to go... // The first register starts at address 0 analog0, analog1, T, PWM_VAL, HOLDING_REGS_SIZE // leave this one // total number of registers for function 3 and 16 share the same register array // i.e. the same address space }; unsigned int holdingRegs[HOLDING_REGS_SIZE]; // function 3 and 16 register array //////////////////////////////////////////////////////////// float tmp=0.0; float Vout=0.0; float f=0.0; int value=0; int R1=1000; int Vin=5; void setup() { /* parameters(HardwareSerial* SerialPort, long baudrate, unsigned char ID, unsigned char transmit enable pin, unsigned int holding registers size, unsigned int* holding register array) */ modbus_configure(&Serial, 9600, 1, 2, HOLDING_REGS_SIZE, holdingRegs); // modbus_update_comms(baud, id) is not needed but allows for easy update of the // port variables and slave id dynamically in any function. modbus_update_comms(9600, 1); pinMode(LED, OUTPUT); } void loop() { // modbus_update() is the only method used in loop(). It returns the total error // count since the slave started. You don't have to use it but it's useful // for fault finding by the modbus master. modbus_update(); // lectura temperatura y luminosidad: Vout=1023-analogRead(A0); // Invert the number because of setup Vout=(Vout/1024.0)*5; f=1000*exp(-3500/298.15); // 298.15K = 25C, 3500 seems to be the B value for a standard 1kOhm NTC tmp=(R1*Vin)/Vout-R1; value=(3500/log(tmp/f))-273.15; holdingRegs[analog0] = analogRead(A0); holdingRegs[analog1] = analogRead(A1); holdingRegs[T] = (unsigned int)value; // update data to be read by the master to adjust the PWM analogWrite(LED, holdingRegs[PWM_VAL]>>2); // constrain adc value from the arduino master to 255 /* Note: The use of the enum instruction is not needed. You could set a maximum allowable size for holdinRegs[] by defining HOLDING_REGS_SIZE using a constant and then access holdingRegs[] by "Index" addressing. I.e. holdingRegs[0] = analogRead(A0); analogWrite(LED, holdingRegs[1]/4); */ }