当前位置:首页Arduino > 正文

Arduino用modbus通讯和硬石模块进行通讯,设置电压及获取电压值

作者:野牛程序员:2024-01-31 17:42:44Arduino阅读 2682

用modbus通讯和硬石模块进行通讯,设置电压及获取电压值

#include <SoftwareSerial.h>
#include <ModbusMaster.h>
#include <TimerOne.h>

// 定义虚拟串口对象并指定引脚
SoftwareSerial mySerial(2, 3); // RX, TX

// 定义ModbusMaster对象
//读电压
ModbusMaster modbus1; // 设备1
ModbusMaster modbus2; // 设备2
//写电压
ModbusMaster modbus3; // 设备3
ModbusMaster modbus4; // 设备4
ModbusMaster modbus5; // 设备5

// 定义常量
const unsigned long DAC_UPDATE_INTERVAL = 10000; // DAC更新间隔,单位:毫秒(10秒)
const unsigned long ADC_READ_INTERVAL = 20000;   // ADC读取间隔,单位:毫秒(15秒)
unsigned long currentMillis;
// 定义变量
unsigned long previousDACMillis = 0;
unsigned long previousADCMillis = 0;
uint16_t dacValues[6] = {0, 0, 0, 0, 0, 0}; // 示例的DAC值
uint16_t dac1=7777,dac2=7777,dac3=7777,dac4=7777,dac5=7777,dac6=7777; // 示例的DAC值
uint8_t result;   //创建接收缓冲区

// 定时器中断服务程序声明
void timerISR();

void setup() {
  // 初始化串口通信
  Serial.begin(115200,SERIAL_8E1);
  // 初始化虚拟串口
  mySerial.begin(115200);

  // 设置定时器1
  Timer1.initialize(10000); // 初始化定时器1,周期为10毫秒
  Timer1.attachInterrupt(timerISR); // 将中断服务程序与定时器1关联

  // 初始化Modbus通信,使用虚拟串口
 
  modbus1.begin(1, Serial); // 读电压值1号地址
  modbus2.begin(2, Serial); // 读电压值2号地址

  modbus3.begin(3, Serial); // 写电压值3  
  modbus4.begin(4, Serial); // 写电压值  4
  modbus5.begin(5, Serial); // 写电压值  5

}

void loop() {
  // 主循环为空,因为我们使用定时器中断进行定时
 
 // Serial.println("...");
  if (currentMillis - previousDACMillis >= DAC_UPDATE_INTERVAL) {
    // 更新previousDACMillis
    previousDACMillis = currentMillis;
   // Serial.println("Updating DAC...");
    // 设置DAC寄存器值
    // 示例代码,实际需要根据你的DAC模块寄存器映射进行修改
   // uint16_t dacValues[6] = {0, 0, 0, 0, 0, 0}; // 示例的DAC值
    uint16_t n=0;
    for (int i = 0; i < 2; i++) {
      // 设置第i个通道的DAC寄存器值
       //uint8_t res1 = modbus3.writeSingleRegister(0x03EE + i, dacValues[n++]++);
       uint8_t res1;
       if(i==0){
           res1 = modbus3.writeSingleRegister(0x03EE + i, dac1++);
       }
       if(i==1){
           res1 = modbus3.writeSingleRegister(0x03EE + i, dac2++);
       }
       

        delay(1100);

        // 检查返回的状态码
        if (res1 == modbus3.ku8MBSuccess) {
            Serial.println("writeSingleRegister 3成功!");
            Serial.println(dac1,DEC);
            Serial.println(dac2,DEC);
        } else {
            Serial.print("writeSingleRegister 3失败,错误码为: ");
            Serial.println(res1, HEX);
        }
        delay(1100); // 等待一段时间,确保Modbus通信完成
    }

   for (int i = 0; i < 2; i++) {
      // 设置第i个通道的DAC寄存器值
      // uint8_t res1 = modbus4.writeSingleRegister(0x03EE + i, dacValues[n++]++);
      uint8_t res1;
       if(i==0){
           res1 = modbus4.writeSingleRegister(0x03EE + i, dac3++);
       }
       if(i==1){
           res1 = modbus4.writeSingleRegister(0x03EE + i, dac4++);
       }

        delay(1100);

        // 检查返回的状态码
        if (res1 == modbus4.ku8MBSuccess) {
            Serial.println("writeSingleRegister 4成功!");
            Serial.println(dac3,DEC);
            Serial.println(dac4,DEC);
        } else {
            Serial.print("writeSingleRegister 4失败,错误码为: ");
            Serial.println(res1, HEX);
        }
        delay(1100); // 等待一段时间,确保Modbus通信完成
    }

   for (int i = 0; i < 2; i++) {
      // 设置第i个通道的DAC寄存器值
      // uint8_t res1 = modbus5.writeSingleRegister(0x03EE + i, dacValues[n++]++);
       uint8_t res1;
       if(i==0){
           res1 = modbus5.writeSingleRegister(0x03EE + i, dac5++);
       }
       if(i==1){
           res1 = modbus5.writeSingleRegister(0x03EE + i, dac6++);
       }

        delay(1100);

        // 检查返回的状态码
        if (res1 == modbus5.ku8MBSuccess) {
            Serial.println("writeSingleRegister 5成功!");
            Serial.println(dac5,DEC);
            Serial.println(dac6,DEC);
        } else {
            Serial.print("writeSingleRegister 5失败,错误码为: ");
            Serial.println(res1, HEX);
        }
        delay(1100); // 等待一段时间,确保Modbus通信完成
    }


 
   
  }

  // 检查是否到达读取ADC的时间间隔
  if (currentMillis - previousADCMillis >= ADC_READ_INTERVAL) {
   // Serial.println("Reading ADC...");
    // 读取ADC寄存器值
    uint8_t result;
    uint16_t adcValue2;

     // 更新previousADCMillis
    previousADCMillis = currentMillis;

    for (int i = 0; i < 4; i++) 
    {
      // 读取第i个通道的ADC寄存器值  
   
      result = modbus1.readHoldingRegisters(0x51B+i, 1);  
       delay(1000); // 等待一段时间,确保Modbus通信完成
      // 检查通信是否成功
      if (result == modbus1.ku8MBSuccess) {
        // 获取读取到的寄存器值
        adcValue2 = modbus1.getResponseBuffer(0);

        // 打印读取到的寄存器值
        Serial.print("设备地址 1号, ADC通道 ");
        Serial.print(i);
        Serial.print(" 的的值为: ");
     
        Serial.println(adcValue2, DEC);
        delay(1000);
      } else {
        // 打印错误信息
        Serial.print("设备地址 1号Error: ");
        Serial.println(result, HEX);
      }
    }
    delay(1000);

    for (int i = 0; i < 4; i++) 
    {
      // 读取第i个通道的ADC寄存器值  
   
      result = modbus2.readHoldingRegisters(0x51B+i, 1);  
       delay(1000); // 等待一段时间,确保Modbus通信完成
      // 检查通信是否成功
      if (result == modbus2.ku8MBSuccess) {
        // 获取读取到的寄存器值
        adcValue2 = modbus2.getResponseBuffer(0);

        // 打印读取到的寄存器值
        Serial.print("设备地址 2号, ADC通道 ");
        Serial.print(i);
        Serial.print(" 的值为: ");
     
        Serial.println(adcValue2, DEC);
        delay(1000);
      } else {
        // 打印错误信息
        Serial.print("设备地址 2号Error: ");
        Serial.println(result, HEX);
      }
    }
    delay(1000);
   
  }



}

// 定时器1中断服务程序
void timerISR() {
  // 获取当前时间
  currentMillis = millis();

  // 检查是否到达更新DAC的时间间隔
 
}


野牛程序员教少儿编程与信息学奥赛-微信|电话:15892516892
野牛程序员教少儿编程与信息学竞赛-微信|电话:15892516892
相关推荐

最新推荐

热门点击