สอบถามเรื่อง ทศนิยม กับ Modbus

  • 3 Replies
  • 1942 Views
*

Offline kira

  • **
  • 40
    • View Profile
    • ดีดบ้าน
 นำโค๊ดมาทดสอบ การส่งรับค่าArduino กับ HMI modbus ของ samkoon
รับส่งข้อมูล ได้ทั้ง analog และ digital แต่ติดปัญหาตรง เรื่องการส่งทศนิยม ไปยัง HMI ปรากฎว่าค่าไม่ขึ้น

Code: [Select]
//====== DHT =======
#include "DHT.h"
#define DHTPIN 4     // what digital pin we're connected to
#define DHTTYPE DHT11   // DHT 11
DHT dht(DHTPIN, DHTTYPE);
//-------DHT--------

//====== MODBUS =======
#include <modbus.h>
#include <modbusDevice.h>
#include <modbusRegBank.h>
#include <modbusSlave.h>

modbusDevice regBank;
//Create the modbus slave protocol handler
modbusSlave slave;
//-------MODBUS--------
int sensorPin = A0;
int sensorPin1 = A1;
float sensorValue = 0;  // variable to store the value coming from the sensor
const float sa  = 204.6;
int sensorValue1 = 0;
void setup() {
  // put your setup code here, to run once:
  pinMode (14,INPUT);
  pinMode (15,INPUT);
  pinMode (16,INPUT);
  pinMode (17,INPUT);
  pinMode (2,INPUT);

  pinMode (3,OUTPUT);
  pinMode (5,OUTPUT);
  pinMode (6,OUTPUT);
  pinMode (7,OUTPUT);
  pinMode (9,OUTPUT);
 
  //====== DHT =======
  dht.begin();
  //-------DHT--------
 
  //====== MODBUS =======
  //Assign the modbus device ID. 
  regBank.setId(1);
  //Add Digital Output registers 00001-00016 to the register bank
  regBank.add(1);
  regBank.add(2);
  regBank.add(3);
  regBank.add(4);
  regBank.add(5);
  //Add Digital Input registers 10001-10008 to the register bank
  regBank.add(10001); 
  regBank.add(10002);
  //Add Analog Output registers 40001-40020 to the register bank
  regBank.add(40001);
 regBank.add(40002);
  regBank.add(40003);
  slave._device = &regBank; 
  // Initialize the serial port for coms at 9600 baud 
  slave.setBaud(9600);
  //-------MODBUS--------
}





void loop() {
    // put your main code here, to run repeatedly:
  //====== DHT =======
  // Read temperature as Celsius (the default)
  float t = dht.readTemperature();
  //-------DHT--------
 
 
  //====== INPUT ======
  if (digitalRead(14) == HIGH) // WATER LEVEL MAX
  {
    regBank.set(10001,1);   
  }
  else
  {
    regBank.set(10001,0);
  }
  if (digitalRead(15) == HIGH) // WATER LEVEL MAX
  {
    regBank.set(10002,1);   
  }
  else
  {
    regBank.set(10002,0);
  }
  //------- INPUT --------

  //====== OUTPUT ======

  if(regBank.get(1)== 0)
  {
    digitalWrite(3,LOW); 
  }
  else
  {
    digitalWrite(3,HIGH);
  }
  if(regBank.get(2)== 0)
  {
    digitalWrite(5,LOW); 
  }
  else
  {
    digitalWrite(5,HIGH);
  }
  if(regBank.get(3)== 0)
  {
    digitalWrite(6,LOW); 
  }
  else
  {
    digitalWrite(6,HIGH);
  }
  if(regBank.get(4)== 0)
  {
    digitalWrite(9,LOW); 
  }
  else
  {
    digitalWrite(9,HIGH);
  }
  if(regBank.get(5)== 0)
  {
    digitalWrite(7,LOW); 
  }
  else
  {
    digitalWrite(7,HIGH);
  }
  //------- OUTPUT --------
 
  sensorValue = analogRead(sensorPin);
         float Volt0 = sensorValue/sa;
  regBank.set(40002,Volt0);  ///=======>>> ค่าตัวนี้ไม่สามารถแสดงเป็นทศนิยมได้
 
    sensorValue1 = analogRead(sensorPin1);
  regBank.set(40003,sensorValue1);
 
  //====== MODBUS =======
  regBank.set(40001,t);
 
  slave.run();
  //-------MODBUS--------




 
}







รับดีดบ้าน สร้างบ้าน ยกบ้าน ด้วยช่างมืออาชีพกว่า20ปีในราคาชาวบ้าน
http://www.d-karnchang.com

มันส่งแบบ Floating. ไม่ได้ครับ ลองส่งแบบจำนวนเต้มก่อนจุดทศนิยม และจำนวนเต้มหลังจุดทศนิยมไป จากนั้นที่จอ HMI ก้อเขียนให้มันดึง มาต่อกัน เช่น

จะส่งค่า 22.59
40000 ส่ง 20
40001 ส่ง59

ที่หน้าจอก้อเขียน 40000.40001 ไป ให้มันต่อกัน

มันส่งแบบ Floating. ไม่ได้ครับ ลองส่งแบบจำนวนเต้มก่อนจุดทศนิยม และจำนวนเต้มหลังจุดทศนิยมไป จากนั้นที่จอ HMI ก้อเขียนให้มันดึง มาต่อกัน เช่น

จะส่งค่า 22.59
40000 ส่ง 20
40001 ส่ง59

ที่หน้าจอก้อเขียน 40000.40001 ไป ให้มันต่อกัน

แปลงค่า Float ของคุณเป็น  4 byte data ก่อนครับจากนั้นค่อย ส่งค่ากลับไปที่ HMI
Code: [Select]

void floatToArray(float data,uint8_t *ar)
{
uint8_t *p = (uint8_t*) &data;
for (uint8_t i=0;i<4;i++)
{
*ar++ = *p++;
}
}


วิธีการใช้งานครับ
Code: [Select]
floatToArray(10.3,&modbusf03Register[0]);
หลังจากนั้นเราจะได้ค่า IEEE754 floating point ขนาด 4 byte เก็บอยู่ใน modbus03Register ซึ่งสามารถส่งค่า 4 byte ไปที่ HMI ได้เลยครับ

ปล.เพิ่มเติมอีกนิดครับ ถ้าค่าที่ส่งไปไม่ถูกต้อง ให้ทำการสลับ word ที่ 0 กับ word ที่ 1 นะครับ เรื่องนี้ผมโดนมาแล้วจากประสบกาณ์ตรงครับ เนื่องจาก PLC ,HMI ,เครื่องมือวัดต่างๆสามารถส่งค่าแบบ Float inverse ได้ครับ
รับทำระบบบำบัดน้ำเสีย ,ตู้ควบคุม ,PLC ,SCADA
จำหน่ายอุปกรณ์ในระบบบำบัดน้ำเสีย