Modbus浮点转换

时间:2015-01-28 05:24:20

标签: arduino communication modbus

我正在使用Arduino modbus库来测量使用霍尔传感器的串电流。下载了这个库。Modbus library 。我有浮动值的传感器数据&库以整数格式存储值。

问题:

  1. 如何将传感器值保存为整数格式
  2. 如何分配用户定义的地址。起始地址如4000h而不是0000H
  3. #include <avr/wdt.h>
    #include"glob.h"
    //#define ID   1
    void Device_ID_Reading()
    {
      for(row=0;row<9;row++)
      {
        digitalWrite(SO_enable,array1[row][0]);
        digitalWrite(S1_enable,array1[row][1]);
        digitalWrite(S2_enable,array1[row][2]); 
        Status_Out[row]=digitalRead(Read_IDstatus);
        Device_ID =1*Status_Out[0]+2*Status_Out[1]+4*Status_Out[2]+8*Status_Out[3]+16*Status_Out[4]+32*Status_Out[5]+64*Status_Out[6]+128*Status_Out[7];
        Serial.print("Device_ID"); 
        Serial.print(row); 
        Serial.print(":\t");
        Serial.println(Device_ID);
    
      }
    }
    
    
    int8_t state = 0;
    Modbus slave(Device_ID, 0, 0);
    unsigned long tempus;
    // data array for modbus network sharing
    uint16_t au16data[30];
    
    void Take_Reading()
    {
      for(row=0;row<9;row++)
      {
        //  int k=(8*array[row][0]+4*array[row][1]+2*array[row][2]+1*array[row][3]);
        //   digitalWrite(Enablepin,array[row][0]);
        digitalWrite(SO_enable,array1[row][1]);
        digitalWrite(S1_enable,array1[row][2]);
        digitalWrite(S2_enable,array1[row][3]); 
        //delay(100); 
        Sensor_Value0=analogRead(A0);
        Sensor_Value1=analogRead(A5);
        Mux1_array[row]=(Sensor_Value0 * ARDUINO_ANALOG_SCALING);
        Mux2_array[row]=(Sensor_Value1 * ARDUINO_ANALOG_SCALING);
    
        Current_Value1[row]=  (Mux1_array[row]*35.1428571429)-87.6571428571;
        Current_Value2[row]=  (Mux2_array[row]*35.1428571429)-87.6571428571;
        Current_Value3[row]=(Mux3_array[row]*35.1428571429)-87.6571428571;
    
      }
    }
    void setup()
    {
      wdt_enable(WDTO_8S);
      slave.begin( 9600 );
      tempus = millis() + 100;
      pinMode(3,OUTPUT);
      pinMode(SO_enable, OUTPUT) ;// pin can enable/disable using digital IO 7 of arduino
      pinMode(S1_enable, OUTPUT) ;// pin can enable/disable using digital IO 6 of arduino
      pinMode(S2_enable, OUTPUT) ;// pin can enable/disable using digital IO 5 of arduino
      //  pinMode(Enablepin, OUTPUT) ;// pin can enable/disable using digital IO 4 of arduino
      pinMode(A0, INPUT) ;
      pinMode(A1, INPUT) ;
      pinMode(A2,INPUT);
      //  Serial.begin(9600);
    }
    void loop()
    {
      digitalWrite(3,HIGH);
      // wdt_reset();
      Take_Reading();
      Device_ID_Reading(); 
      state = slave.poll( au16data,30 );
      if (state > 4) {
        tempus = millis() + 50;
        digitalWrite(13, HIGH);
      }
      if (millis() > tempus) digitalWrite(13, LOW );
    
      Modbus_call();
    
    }
    void Modbus_call()
    {
    
      /*reading of coil where i can succefully read value*/
      au16data[1]=(int)(100*Current_Value1[0]);
      au16data[2]=(int)(100*Current_Value1[1]);
      au16data[3]=(int)(100*Current_Value1[3]);
      au16data[4]=(int)(100*Current_Value1[4]);
      au16data[5]=(int)(100*Current_Value1[5]);
      au16data[6]=(int)(100*Current_Value1[6]);
      au16data[7]=(int)(100*Current_Value1[7]);
      au16data[8]=(int)(100*Current_Value1[8]); 
      au16data[9]=(int)(100*Current_Value2[0]);
      au16data[10]=(int)(100*Current_Value2[1]);  
      au16data[11]=(int)(100*Current_Value2[2]);
      au16data[12]=(int)(100*Current_Value2[3]);
      au16data[16]=(int)(100*Current_Value2[4]);
      au16data[17]=(int)(100*Current_Value2[5]);
      au16data[18]=(int)(100*Current_Value2[6]);
      au16data[19]=(int)(100*Current_Value2[7]);
      uint16_t calcCRC( au16data[15]);
      au16data[13] = slave.getInCnt();
      au16data[14] = slave.getOutCnt();
      au16data[15] = slave.getErrCnt(); 
    
    }
    

    还有其他库我可以直接使用浮点。

1 个答案:

答案 0 :(得分:0)

作为协议的Modbus不直接支持浮点数。但是,您可以将浮点数据放入相邻寄存器中。使用type punning将浮动数据放入寄存器并将其拉出另一端。

union Pun {float f; uint32_t u;};

void encodeFloat(uint16_t *regs, float x)
{
    union Pun pun;

    pun.f = x;
    regs[0] = (pun.u >> 16) & 0xFFFFU;
    regs[1] = pun.u & 0xFFFFU;
}

float decodeFloat(const uint16_t *regs)
{
    union Pun pun;

    pun.u = ((uint32_t)regs[0] << 16) | regs[1];
    return pun.f;
}

你会像这样使用它:

void Modbus_call()
{
    /*reading of coil where i can succefully read value*/
    encodeFloat(&au16data[ 0],  Current_Value1[0]);
    encodeFloat(&au16data[ 2],  Current_Value1[1]);
    encodeFloat(&au16data[ 4],  Current_Value1[2]);
    /* And so on... */
}