空調溫度控制
Arduino 讀取溫度感測器 DS18B20數值,根據溫度-頻率控制法則改變變頻器頻率
系統架構
|
PLC系統
|
|
Arduino 系統
|
線路
DS18B20配線参考 DS18B20溫度寫入PLC
控制要求
溫度 0 ~ 19 ,變頻器頻率為 15 Hz。
溫度 20 ~ 24,變頻器頻率為 20 Hz。
溫度 25 ~ 29 ,變頻器頻率為 25 Hz。
溫度 30 ~ 34 ,變頻器頻率為 30 Hz。
溫度 35 ~ 39 ,變頻器頻率為 35 Hz。
溫度 40 ~ 99 ,變頻器頻率為 40 Hz。
VFD-M 變頻器參數設定
參數
|
設定值
|
說明
|
00-20
|
1
|
頻率由 RS-485 通信界面操作(RJ-11)
|
00-21
|
0
|
由鍵盤操作
|
09-00
|
1
|
VFD-M 變頻器的通訊位址 01
|
09-01
|
9.6
|
通訊傳送速度
Baud rate 9600
|
09-04
|
14
|
RTU 模式,資料格式<8,E,1>
|
通訊位址
程式
// DS18B20-Arduino-VFD
// Include the libraries we need
#include <OneWire.h>
#include <DallasTemperature.h>
#define MB_IDEL 0
#define MB_SEND 1
#define MB_RECV 2
byte mb_state;
int result = -1;
void rtuRequest(byte id, byte fc, word address, word len, HardwareSerial& port );
byte rtuResopnse(byte id, HardwareSerial& port);
word CRC(byte* buf, byte len);
byte mb_frame[50]; //request / response messages
word mb_data[20]={32,20}; //request / response datas
#define POLLING_TIME 4000 // ms
unsigned long last_polling = 0;
bool polling = false;
#define ONE_WIRE_BUS 2
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
void setup() {
Serial.begin(115200);
Serial1.begin(9600,SERIAL_8E1); // Modbus RTU 9600,8,E,1
sensors.begin();
delay(100);
}
void loop() {
if(millis() - last_polling > 4000) {
polling = true;
last_polling = millis();
}
switch(mb_state) {
case MB_IDEL: if(polling) {
sensors.requestTemperatures();
float tempC = sensors.getTempCByIndex(0);
// Check if reading was successful
if(tempC != DEVICE_DISCONNECTED_C) {
Serial.print("Temperature for the device 1 (index 0) is: ");
Serial.println(tempC);
int temp = (int)tempC;
switch(temp){
case 0 ... 19: mb_data[0] = 1500; break; //15Hz
case 20 ... 24: mb_data[0] = 2000; break; //20Hz
case 25 ... 29: mb_data[0] = 2500; break; //25Hz
case 30 ... 34: mb_data[0] = 3000; break; //30Hz
case 35 ... 39: mb_data[0] = 3500; break; //35Hz
case 40 ... 99: mb_data[0] = 4000; break; //40Hz
default: mb_data[0] = 1000; break; //10Hz
}
Serial.println(mb_data[0]);
mb_state = MB_SEND;
}
else{
Serial.println("Error: Could not read temperature data");
mb_state = MB_IDEL; // do nothing
}
}
polling = false;
break;
case MB_SEND: rtuRequest(1,16,0x2001,1,Serial1);
delay(50); //wait 50ms
mb_state = MB_RECV;
break;
case MB_RECV: result = rtuResponse(1,Serial1);
if(result != -1) { //receive message finished
if(result == 0) { //response message correct
//do somthing
}
else if(result > 0) { //error occure
Serial.print("error code -->"); // print error code
Serial.println(result);
}
mb_state = MB_IDEL; //reset
result = -1; //reset
}
break;
}
}
//slave response parse
byte rtuResponse(byte id, HardwareSerial& port) {
if(port.available()) {
byte len = 0;
while (port.available())
mb_frame[len++] = port.read();
if(len > 7){ // message ok
if(mb_frame[0] == id){ //step 1: check id
if(word(mb_frame[len-1],mb_frame[len-2]) == CRC(mb_frame,len-2)) { //step 2: check crc
switch(mb_frame[1]) { //step 3: get datas or comfirm
case 3: for(int i=0 , j=0 ; i<mb_frame[2]; i+=2)
mb_data[j++] = word(mb_frame[3+i],mb_frame[4+i]);
return 0;
break;
case 16: return 0; // write success
break;
deafult:break;
}//end switch //step 3: parse mb_frame message
} //crc
else {
; //Serial.println(" crc error ");
}
} //if(mb_frame[0] == id)
else {
; //Serial.println(" id error ");
}
}
else {
return mb_frame[3];
}
}
}
void rtuRequest(byte id, byte fc, word address, word reg_len, HardwareSerial& port) {
word crc=0;
byte len=0;
mb_frame[0] = id; //unit id
mb_frame[1] = fc; //function code
mb_frame[2] = highByte(address); //start address high byte
mb_frame[3] = lowByte(address); //start address low byte
mb_frame[4] = highByte(reg_len); //register length high byte
mb_frame[5] = lowByte(reg_len); //register length low byte
switch(fc) {
case 3: crc = CRC(mb_frame,6);
// Serial.print("CRC :");
// Serial.println(crc,HEX);
mb_frame[6] = lowByte(crc); //crc low byte
mb_frame[7] = highByte(crc); //crc high byte
len = 8;
break;
case 16:len = reg_len*2; //data byte count = register length*2
mb_frame[6] = len; //data byte count = register length*2
for(int i = 0 ; i < reg_len ; i++) {
mb_frame[7+i*2] = highByte(mb_data[i]); //data[0+i*2] high byte
mb_frame[7+i*2+1] = lowByte(mb_data[i]); //data[1+i*2] low byte
}
crc = CRC(mb_frame,len+7);
// Serial.print("CRC :");
// Serial.println(crc,HEX);
mb_frame[len+7] = lowByte(crc); //crc low byte
mb_frame[len+8] = highByte(crc); //crc high byte
len = len+9;
break;
deafult:break;
}
port.write(mb_frame,len);
// return len;
}
word CRC(byte* buf, byte len) {
word crc = 0xFFFF;
for (byte i = 0; i < len; i++) {
crc = crc ^ (word) buf[i];
for (byte j = 0; j < 8; j++)
crc = (crc & 0x0001)?(crc >> 1) ^ 0xA001:(crc >> 1);
}
return crc;
}
結果