02-11-2021, 11:00
Zrobiłem to tak:
Odczyt działa ale :
jak odpytuje adres 30001 z długością 1 to zwraca zmierzoną odległość .
jak odpytuje adres 30001 z długością 2 to dostaje dwa parametry odległość i temp.
Jak odpytam adres 30002 z długością 1 to dostaje odległość zamiast temperatury.
Odczyt działa ale :
jak odpytuje adres 30001 z długością 1 to zwraca zmierzoną odległość .
jak odpytuje adres 30001 z długością 2 to dostaje dwa parametry odległość i temp.
Jak odpytam adres 30002 z długością 1 to dostaje odległość zamiast temperatury.
Kod:
#include <ModbusSlave.h>
#include <Wire.h>
#include <OneWire.h>
#include <DallasTemperature.h>
#include <VL53L1X.h>
#define SLAVE_ID 2 // slave id modbus // (do dopisania) mam na pcb zamontowany dipswitch 4 do zmiany adresu (ID 1 lub 2) oraz do zmiany predkości transmisji (19200/9600/115200/38400/57600)
#define SERIAL_BAUDRATE 9600 // predkosc modbus jak wyżej do dopisania mozliwosc konfiguracji predkosci
#define SERIAL_PORT mySerial // port programowy dla modbus
#include <SoftwareSerial.h>
SoftwareSerial mySerial(11, 10); // RX, TX
VL53L1X sensor;
uint16_t analog_pins[] = {0,1}; // Add the pins you want to read as a Input register.
uint8_t output_pins[] = {3,13}; //piny wyjsciowe przekaznik i led
uint16_t analog_pins_size = sizeof(analog_pins) / sizeof(analog_pins[0]); // Get the size of the analog_pins array
uint8_t output_pins_size = sizeof(output_pins) / sizeof(output_pins[0]); // Get the size of the output_pins array
Modbus slave(SERIAL_PORT, SLAVE_ID);
#define ONE_WIRE_BUS 2
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
void setup()
{
sensors.begin();
Serial.begin(115200);//debug
mySerial.begin(9600);//modbus
Wire.begin();
Wire.setClock(400000); // use 400 kHz I2C
sensor.setTimeout(500);
if (!sensor.init())
{
Serial.println("Failed to detect and initialize sensor!");
while (1);
}
sensor.setDistanceMode(VL53L1X::Long);
sensor.setMeasurementTimingBudget(100);
sensor.startContinuous(100);
// Set the defined output pins to output mode.
pinMode(3, OUTPUT); //przekaznik
pinMode(13, OUTPUT); //led wbudowana
// Register functions to call when a certain function code is received.
slave.cbVector[CB_READ_INPUT_REGISTERS] = readAnalogIn; //odczyt rej
slave.cbVector[CB_WRITE_COILS] = writeDigitalOut; //zapis rejestrow
// Set the serial port and slave to the given baudrate.
SERIAL_PORT.begin(SERIAL_BAUDRATE); //inicjalizacja debug
slave.begin(SERIAL_BAUDRATE); //inicjalizacja portu modbus (uart programowy)
}
void loop()
{
slave.poll();
}
// 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;
}
sensors.requestTemperatures();
for (int i = 0; i < length; i++)
{
// Write the state of the analog pin to the response buffer.
slave.writeRegisterToBuffer(0, sensor.read( )) ; //odczyt odleglosci
slave.writeRegisterToBuffer(1, sensors.getTempCByIndex(0)); //odczyt temperatury
//Serial.println(sensors.getTempCByIndex(0));
//slave.writeRegisterToBuffer(i, sensor.read( )) ;
}
return STATUS_OK;
}
uint8_t writeDigitalOut(uint8_t fc, uint16_t address, uint16_t length) //sterowanie przekaznikiem dziala jak wysle po modbus 0x0000 dla 05 force single coil
{
// 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)); //zalaczenie przekaznika i led
return STATUS_OK;
}