machines/shredder/asterix-pp/firmware/ModbusBridge.cpp
2023-11-12 21:43:05 +01:00

148 lines
5.2 KiB
C++
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include <Streaming.h>
#include "./Addon.h"
#include "ModbusRtu.h"
#include "ModbusBridge.h"
#define RS485Serial 3
#define MasterModbusAdd 0
#define SlaveModbusAdd 1
#define ku8MBReadCoils 0x01 ///< Modbus function 0x01 Read Coils
#define ku8MBReadDiscreteInputs 0x02 ///< Modbus function 0x02 Read Discrete Inputs
#define ku8MBWriteSingleCoil 0x05 ///< Modbus function 0x05 Write Single Coil
#define ku8MBWriteMultipleCoils 0x0F ///< Modbus function 0x0F Write Multiple Coils
// Modbus function codes for 16 bit access
#define ku8MBReadHoldingRegisters 0x03 ///< Modbus function 0x03 Read Holding Registers
#define ku8MBReadInputRegisters 0x04 ///< Modbus function 0x04 Read Input Registers
#define ku8MBWriteSingleRegister 0x06 ///< Modbus function 0x06 Write Single Register
#define ku8MBWriteMultipleRegisters 0x10 ///< Modbus function 0x10 Write Multiple Registers
#define ku8MBMaskWriteRegister 0x16 ///< Modbus function 0x16 Mask Write Register
#define ku8MBReadWriteMultipleRegisters 0x17 ///< Modbus function 0x17 Read Write Multiple Registers
Modbus master(MasterModbusAdd, RS485Serial, 0);
modbus_t ModbusQuery[1];
uint16_t ModbusSlaveRegisters[8];
millis_t WaitingTime;
enum MBB_STATE
{
WAITING = 0,
QUERY = 1,
RESPONSE = 2
};
int _state = 0;
#define MX2_STATE 0x0003 // (2 bytes) Status of the inverter: [0: Initial state, 2: Stop 3: Turn 4: Coast stop 5: Jog 6: DC braking]
#define MX2_DIR 0x1004 // (2 bytes) Status of the inverter: [0: Initial state, 2: Stop 3: Turn 4: Coast stop 5: Jog 6: DC braking]
#define MX2_AMPERAGE 0x1003 // (2 bytes) Output current monitoring (0,01 [A])
#define MX2_START 0x0001 // (bit) Run command 1: Run, 0: Stop (valid with A002 = 03)
#define MX2_SET_DIR 0x0002 // (bit) Command of direction of rotation 1: Reverse rotation, 0: Rotation in the forward direction (valid with A002 = 03)
#define MX2_RESET 0x0004 // (bit) Reset emergency shutdown (RS) 1: Reset
#define MX2_READY 0x0011 // (bit) Ready IF 1: Ready, 0: Not ready
#define MX2_DIRECTION 0x0010 // (bit) Direction of rotation 1: Reverse rotation, 0: Rotation in the forward direction (deadlock with "d003")
#define TEST_NUMBER 1234 // Verification code for function 0x08
#define ku8MBLinkTestOmronMX2Only 0x08 ///< Modbus function 0x08 Тест связи с инвертром Omron MX2 функция только для него ku8MBLinkTestOmronMX2Only
short ModbusBridge::setup()
{
// Serial.println("---------- setup ----");
master.begin(19200); // baud-rate at 19200
master.setTimeOut(5000); // if there is no answer in 5000 ms, roll over
WaitingTime = millis() + 400;
/*
fn = MX2_STATE;
addr = MB_FC_READ_REGISTERS;
*/
fn = ku8MBLinkTestOmronMX2Only;
addr = 0;
nb = 4;
}
short ModbusBridge::run(short val){
fn = ku8MBWriteSingleCoil;
addr = MX2_START;
// _u16WriteQty = (u8State ? 0xFF00 : 0x0000);
ModbusQuery[0].au16reg = 0xFF00;
ModbusQuery[0].u16CoilsNo = 1;
}
short ModbusBridge::setFn(short val)
{
// fn = val;
run(0);
}
short ModbusBridge::setAddr(short val)
{
addr = val;
}
short ModbusBridge::setNb(short val)
{
nb = val;
}
short ModbusBridge::loop()
{
switch (_state)
{
case WAITING:
{
if (millis() > WaitingTime)
{
_state++; // wait state
}
break;
}
case QUERY:
{
/*ModbusQuery[0].u8id = SlaveModbusAdd; // slave address
ModbusQuery[0].u8fct = MB_FC::MB_FC_READ_REGISTERS; // function code (this one is registers read)
ModbusQuery[0].u16RegAdd = MX2_AMPERAGE; // start address in slave
ModbusQuery[0].u16CoilsNo = 4; // number of elements (coils or registers) to read
ModbusQuery[0].au16reg = ModbusSlaveRegisters; // pointer to a memory array in the CONTROLLINO
*/
ModbusQuery[0].u8id = SlaveModbusAdd; // slave address
ModbusQuery[0].u8fct = fn; // function code (this one is registers read)
ModbusQuery[0].u16RegAdd = addr; // start address in slave
ModbusQuery[0].u16CoilsNo = nb; // number of elements (coils or registers) to read
ModbusQuery[0].au16reg = ModbusSlaveRegisters; // pointer to a memory array in the CONTROLLINO
master.query(ModbusQuery[0]); // send query (only once)
_state++;
break;
}
case RESPONSE:
{
master.poll(); // check incoming messages
if (master.getState() == COM_IDLE)
{
// response from the slave was received
_state = 0;
WaitingTime = millis() + 300;
// registers read was proceed
Serial.println("---------- READ RESPONSE RECEIVED ----");
Serial.print(" ADC0: 0x");
Serial.print(ModbusSlaveRegisters[0], HEX);
Serial.print(" , Digital0: ");
Serial.print(ModbusSlaveRegisters[1], HEX);
Serial.print(" , nb in ");
Serial.print(ModbusSlaveRegisters[2], DEC);
Serial.print(" , nb out ");
Serial.println(ModbusSlaveRegisters[3], DEC);
Serial.println("");
}
break;
}
}
}
void ModbusBridge::debug(Stream *stream)
{
// *stream << this->name << ":";
}
void ModbusBridge::info(Stream *stream)
{
// *stream << this->name << "\n\t";
}