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

Started by kira, December 03, 2017, 10:49:33 PM

Previous topic - Next topic

kira

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


//====== 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

empirejrz

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

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

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

empirejrz

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

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

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


forkee

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


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



วิธีการใช้งานครับ

floatToArray(10.3,&modbusf03Register[0]);

หลังจากนั้นเราจะได้ค่า IEEE754 floating point ขนาด 4 byte เก็บอยู่ใน modbus03Register ซึ่งสามารถส่งค่า 4 byte ไปที่ HMI ได้เลยครับ

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

moneyp1000

ดูตัวอย่างการใช้งาน การขยาย port arduino เบื้องต้น และควรเข้าใจเรื่อง UART คืออะไร TTL คืออะไร RS232 คืออะไร และ RS485 คืออะไร ด้วยครับ เพราะมันจะเป็นพื้นฐานการสื่อสารกับ Arduino ทั้งหมด