• Witaj na Forum Arduino Polska! Zapraszamy do rejestracji!
  • Znajdziesz tutaj wiele informacji na temat hardware / software.
Witaj! Logowanie Rejestracja


Ocena wątku:
  • 0 głosów - średnia: 0
  • 1
  • 2
  • 3
  • 4
  • 5
Arduino nano Modbus i czujnik VL53L1X
#3
(09-10-2021, 22:09)kaczakat napisał(a): To co pokazałeś to żaden modbus tylko komunikacja szeregowa po RS485. Jak chcesz mieć w tym urządzeniu modbus to musisz znaleźć bibliotekę albo ją sam wymyślić. Oczywiście żaden modbus nie jest do tego niezbędny, może być i tak jak jest że Arduino wysyła dane w stałej częstotliwości np. co 100ms aktualny pomiar, albo robi go tylko na zapytanie, albo robi co ile się da, a wysyła tylko na zapytanie ostatni dostępny.
W pokazanym przykładzie dwa razy odczytujesz czujnik i dwa razy wysyłasz, raczej bez sensu bo mogą to być różne wartości, ja bym robił raczej 1 odczyt i dwa wysłania w wybranym interwale czasowym zdolnym do obsłużenia przez czujnik. Jeśli czujnik jest dość wydajny to może nawet zapchać Ci magistralę na 9600, bo masz odczyty 400kHz a wysyłasz  9,6kHz.
W bibliotekach Arduino jest mnóstwo do wyboru, akurat ja nie korzystałem z  tej strony modbus, używam jednego Arduino do odczytu licznika i wysyłania danych do wizualizacji na Thinkspeak.
To czego szukasz to pewnie slave, zawiera to biblioteka np. Modbus-Master-Slave-for-Arduino @author Samuel Marco i Armengol. Większość bibliotek to Master do odczytu istniejących slave  z tym protokołem.


Mam zainstalowaną tą bibliotekę Modbus-Master-Slave-for-Arduino @author Samuel Marco i Armengol..
mam przykład w example.. ale nie potrafię podmienić zmiennej z AnalogRead na moją wstawioną...
Odczytuje dwa razy bo... za pierwszym razem wysyłam na konsole PC (debug) a drugi odczyt mySerial jest już fizycznym odczytem do wysłania w modbusie po zapytaniu o tą wartość oczywiście
Kod:
/*
    Modbus slave - simple RS485 example

    Control and Read Arduino I/Os using Modbus RTU.

    This sketch shows how you can use the callback vector for reading and
    controlling Arduino I/Os.

    * Maps digital outputs to modbus coils.
    * Maps digital inputs to discreet inputs.
    * Maps analog inputs to input registers.

    The circuit: ( see: ./extras/ModbusSchematic.png )
    * An Arduino.
    * 2x LEDs, with 220 ohm resistors in series.
    * A switch connected to a digital pin.
    * A potentiometer connected to an analog pin.
    * A RS485 module (Optional) connected to RX/TX and a digital pin.

    Created 08-12-2015
    By Yaacov Zamir

    Updated 31-03-2020
    By Yorick Smilda

    https://github.com/yaacov/ArduinoModbusSlave
*/

#include <ModbusSlave.h>

#define SLAVE_ID 1          // The Modbus slave ID, change to the ID you want to use.
#define SERIAL_BAUDRATE 9600 // Change to the baudrate you want to use for Modbus communication.
#define SERIAL_PORT mySerial  // Serial port to use for RS485 communication, change to the port you're using.
#include <SoftwareSerial.h>
SoftwareSerial mySerial(11, 10); // RX, TX
// Comment out the following line if your not using RS485
//#define RS485_CTRL_PIN 8 // Change to the pin the RE/DE pin of the RS485 controller is connected to.

// The position in the array determines the address. Position 0 will correspond to Coil, Discrete input or Input register 0.
uint8_t input_pins[] = {2, 3, 4};    // Add the pins you want to read as a Discrete input.
uint8_t output_pins[] = {8, 9, 10};  // Add the pins you want to control via a Coil.
uint8_t analog_pins[] = {A0, A1, A2}; // Add the pins you want to read as a Input register.

// You shouldn't have to change anything below this to get this example to work

uint8_t input_pins_size = sizeof(input_pins) / sizeof(input_pins[0]);    // Get the size of the input_pins array
uint8_t output_pins_size = sizeof(output_pins) / sizeof(output_pins[0]); // Get the size of the output_pins array
uint8_t analog_pins_size = sizeof(analog_pins) / sizeof(analog_pins[0]); // Get the size of the analog_pins array

#ifdef RS485_CTRL_PIN
// Modbus object declaration
Modbus slave(SERIAL_PORT, SLAVE_ID, RS485_CTRL_PIN);
#else
Modbus slave(SERIAL_PORT, SLAVE_ID);
#endif

void setup()
{
    // Set the defined input pins to input mode.
    for (int i = 0; i < input_pins_size; i++)
    {
        pinMode(input_pins[i], INPUT);
    }

    // Set the defined analog pins to input mode.
    for (int i = 0; i < analog_pins_size; i++)
    {
        pinMode(analog_pins[i], INPUT);
    }

    // Set the defined output pins to output mode.
    for (int i = 0; i < output_pins_size; i++)
    {
        pinMode(output_pins[i], OUTPUT);
    }

    // Register functions to call when a certain function code is received.
    slave.cbVector[CB_WRITE_COILS] = writeDigitalOut;
    slave.cbVector[CB_READ_DISCRETE_INPUTS] = readDigitalIn;
    slave.cbVector[CB_READ_INPUT_REGISTERS] = readAnalogIn;

    // Set the serial port and slave to the given baudrate.
    SERIAL_PORT.begin(SERIAL_BAUDRATE);
    slave.begin(SERIAL_BAUDRATE);
}

void loop()
{
    // Listen for modbus requests on the serial port.
    // When a request is received it's going to get validated.
    // And if there is a function registered to the received function code, this function will be executed.
    slave.poll();
}

// Modbus handler functions
// The handler functions must return an uint8_t and take the following parameters:
//    uint8_t  fc - function code
//    uint16_t address - first register/coil address
//    uint16_t length/status - length of data / coil status

// Handle the function codes Force Single Coil (FC=05) and Force Multiple Coils (FC=15) and set the corresponding digital output pins (coils).
uint8_t writeDigitalOut(uint8_t fc, uint16_t address, uint16_t length)
{
    // Check if the requested addresses exist in the array
    if (address > output_pins_size || (address + length) > output_pins_size)
    {
        return STATUS_ILLEGAL_DATA_ADDRESS;
    }

    // Set the output pins to the given state.
    for (int i = 0; i < length; i++)
    {
        // Write the value in the input buffer to the digital pin.
        digitalWrite(output_pins[address + i], slave.readCoilFromBuffer(i));
    }

    return STATUS_OK;
}

// Handle the function code Read Input Status (FC=02) and write back the values from the digital input pins (discreet input).
uint8_t readDigitalIn(uint8_t fc, uint16_t address, uint16_t length)
{
    // Check if the requested addresses exist in the array
    if (address > input_pins_size || (address + length) > input_pins_size)
    {
        return STATUS_ILLEGAL_DATA_ADDRESS;
    }

    // Read the digital inputs.
    for (int i = 0; i < length; i++)
    {
        // Write the state of the digital pin to the response buffer.
        slave.writeCoilToBuffer(i, digitalRead(input_pins[address + i]));
    }

    return STATUS_OK;
}

// Handle the function code Read Input Registers (FC=04) and write back the values from analog input pins (input registers).
uint8_t readAnalogIn(uint8_t fc, uint16_t address, uint16_t length)
{
    // Check if the requested addresses exist in the array
    if (address > analog_pins_size || (address + length) > analog_pins_size)
    {
        return STATUS_ILLEGAL_DATA_ADDRESS;
    }

    // Read the analog inputs
    for (int i = 0; i < length; i++)
    {
        // Write the state of the analog pin to the response buffer.
        slave.writeRegisterToBuffer(i, analogRead(analog_pins[address + i]));
    }

    return STATUS_OK;
}
 
Odpowiedź
  


Wiadomości w tym wątku
Arduino nano Modbus i czujnik VL53L1X - przez ukffun - 09-10-2021, 21:20
RE: Arduino nano Modbus i czujnik VL53L1X - przez ukffun - 09-10-2021, 22:57

Skocz do:


Przeglądający: 1 gości