在本篇文章,Arduino作為MODBUS主站(Master)與MODBUS從站(Slave)進(jìn)行通信。本文中將使用安裝MODBUS Slave Software的計(jì)算機(jī)用作MODBUS從站。那么,讓我們首先簡(jiǎn)要介紹一下RS-485和Modbus。
RS-485串行通信
RS-485是一種異步串行通信協(xié)議,不需要時(shí)鐘。它使用稱(chēng)為差分信號(hào)的技術(shù)將二進(jìn)制數(shù)據(jù)從一個(gè)設(shè)備傳輸?shù)搅硪粋€(gè)設(shè)備。當(dāng)使用兩根電線時(shí),它提供半雙工通信,而全雙工需要4條電線。
RS-485模塊可以連接到任何帶有串行端口的微控制器。微控制器使用RS-485模塊時(shí),需要一個(gè)基于Maxim MAX485的5V MAX485 TTL到RS485的模塊,因?yàn)樗试S1200米長(zhǎng)距離的串行通信。它是雙向和半雙工的,數(shù)據(jù)傳輸速率為2.5 Mbps。該模塊需要5V的電壓。
RS-485模塊的引腳輸出定義:
USB轉(zhuǎn)RS-485轉(zhuǎn)換模塊:
這是一個(gè)USB轉(zhuǎn)RS485轉(zhuǎn)換器適配器模塊,支持WIN7、XP、Linux、Mac OS,并通過(guò)使用計(jì)算機(jī)中的COM端口提供易于使用的RS485接口。該模塊是即插即用設(shè)備。沒(méi)有命令結(jié)構(gòu),發(fā)送到虛擬COM端口的任何內(nèi)容都會(huì)自動(dòng)轉(zhuǎn)換為RS485,反之亦然。該模塊完全由USB總線供電。因此,無(wú)需外部電源即可運(yùn)行。
它顯示為串行/ COM端口,可從應(yīng)用程序或超級(jí)終端訪問(wèn)。該轉(zhuǎn)換器提供半雙工RS-485通信。波特率范圍為75 bps至115200 bps,最高可達(dá)6 Mbps。
要使用此設(shè)備,互聯(lián)網(wǎng)上提供了各種Modbus軟件。在本教程中,使用了來(lái)自Witte Software的名為Modbus Slave軟件的軟件。該軟件可從www.modbustools.com網(wǎng)站下載。
Modbus Slave軟件
Modbus Slave應(yīng)用程序通過(guò)使用串行通信端口從任何Modbus主站設(shè)備接收值。它是一種數(shù)據(jù)通信測(cè)試軟件。在使用該軟件之前,必須了解以下事項(xiàng)。有關(guān)更多信息,請(qǐng)參閱軟件手冊(cè)。
SlaveID:網(wǎng)絡(luò)中的每個(gè)從站都分配有1到127的唯一單元地址。當(dāng)主站請(qǐng)求數(shù)據(jù)時(shí),它發(fā)送的第一個(gè)字節(jié)是從站地址。這樣,每個(gè)從設(shè)備在第一個(gè)字節(jié)之后知道是否忽略該消息。
Modbus寄存器:
離散輸出線圈:它是一個(gè)1位寄存器,用于控制離散輸出,可以讀取或?qū)懭搿K鼈兊募拇嫫骶幪?hào)為(1至9999)。
離散輸入:它是一個(gè)1位寄存器,用作輸入,只能讀取。他們有(10001年至19999年)的登記號(hào)碼。
輸入寄存器:用于輸入的16位寄存器,只能讀取。它們的寄存器編號(hào)為(30001至39999)。
保持寄存器:它是一個(gè)16位寄存器,可以讀寫(xiě)。它們的寄存器編號(hào)為(40001至49999)。
Modbus功能代碼:
CRC:CRC代表循環(huán)冗余校驗(yàn)。它是在每個(gè)Modbus消息的末尾添加兩個(gè)字節(jié)以進(jìn)行錯(cuò)誤檢測(cè)。
需要的組件
●? ? Arduino UNO開(kāi)發(fā)板
●? ? MAX-485 TTL轉(zhuǎn)RS-485轉(zhuǎn)換模塊
●? ? USB轉(zhuǎn)RS-485轉(zhuǎn)換模塊
●? ? 1602 LCD顯示屏
●? ? Modbus Slave
電路原理圖
MAX-485 TTL至RS-485轉(zhuǎn)換器模塊與Arduino UNO之間的電路連接:
帶有10k下拉電阻的兩個(gè)按鈕也連接到Arduino引腳4和5。10K電位器用于為Arduino引腳A0提供模擬輸入值。
電路連接后,完整設(shè)置如下所示。
編程Arduino Uno作為MODBUS Master
在本文中,Arduino Uno配置為Modbus Master,通過(guò)Modbus Master庫(kù)編寫(xiě)Master Modbus Arduino代碼。在這里,Arduino Uno有兩個(gè)按鈕和一個(gè)電位器,用于將Modbus Master Arduino的值發(fā)送到Modbus Slave軟件。
為了在Arduino UNO中使用Modbus,使用庫(kù)
本文末尾處給出了完整的代碼。這里我們解釋了下面的一些主要步驟。
首先,包括ModbusMaster和Liquid Crystal庫(kù):
#include
#include
接下來(lái)定義MAX485 TTL到RS-485轉(zhuǎn)換器模塊和Arduino UNO之間連接的引腳名稱(chēng)。
#define MAX485_DE? ?? ?3
#define MAX485_RE_NEG??2
初始化類(lèi)ModbusMaster的節(jié)點(diǎn)對(duì)象。
ModbusMaster node;
然后寫(xiě)入兩個(gè)函數(shù)preTrasnmission()和postTrasmission(),使Max485 TTL到RS-485轉(zhuǎn)換器模塊的引腳RE和DE高或低為發(fā)送或接收數(shù)據(jù)。
void preTransmission()
{
digitalWrite(MAX485_RE_NEG, 1);
digitalWrite(MAX485_DE, 1);
}
void postTransmission()
{
digitalWrite(MAX485_RE_NEG, 0);
digitalWrite(MAX485_DE, 0);
}
接下來(lái)在void setup()中,LCD設(shè)置為1602模式,并顯示歡迎信息。
lcd.begin(16,2);
lcd.print("CIRCUIT DIGEST");
delay(3000);
lcd.clear();
lcd.print("Arduino");
lcd.setCursor(0,1);
lcd.print("Modbus Master");
delay(3000);
lcd.clear();
然后將RE和DE引腳設(shè)置為OUTPUT引腳,將引腳4和5設(shè)置為INPUT引腳(按鈕)。
pinMode(MAX485_RE_NEG, OUTPUT);
pinMode(MAX485_DE, OUTPUT);
pinMode(4,INPUT);
pinMode(5,INPUT);
最初,MAX-485 TTL到RS-485轉(zhuǎn)換器模塊的DE和RE引腳設(shè)置為低電平
digitalWrite(MAX485_RE_NEG, 0);
digitalWrite(MAX485_DE, 0);
將波特率設(shè)置為115200,并通過(guò)從站ID 1通知Modbus主站。
Serial.begin(115200);
node.begin(1, Serial);
之后使用回?fù)苷Z(yǔ)句,以便正確配置RS-485收發(fā)器。
node.preTransmission(preTransmission);
node.postTransmission(postTransmission);
現(xiàn)在在void loop()函數(shù)中:
?? ? 首先,從與電位器連接的引腳A0讀取模擬值。
float value = analogRead(A0);
?? ? 然后將ADC值(0到1023)寫(xiě)入0x40000寄存器,使用以下語(yǔ)句將其發(fā)送到Modbus Slave。
node.writeSingleRegister(0x40000,value);
?? ? 然后該值也會(huì)顯示在16x2 LCD顯示屏上
lcd.setCursor(0,0);
lcd.print("POT Val :");
lcd.print(value);
?? ? 接下來(lái)讀取兩個(gè)按鈕的狀態(tài)。
int a= digitalRead(4);
int b= digitalRead(5);
?? ? 根據(jù)按鈕的狀態(tài),按鈕1的值0x40001和按鈕2的0x40002被寫(xiě)入Modbus從站,并顯示在LCD顯示屏上。
if (a == 1)
{
node.writeSingleRegister(0x40001,1);
lcd.setCursor(0,1);
lcd.print("S1: 1");
}
else
{
node.writeSingleRegister(0x40001,0);
lcd.setCursor(0,1);
lcd.print("S1: 0");
}
if (b == 1)
{
node.writeSingleRegister(0x40002,1);
lcd.setCursor(8,1);
lcd.print("S2: 1");
}
else
{
node.writeSingleRegister(0x40002,0);
lcd.setCursor(8,1);
lcd.print("S2: 0");
}
測(cè)試Arduino UNO作為RS485 MODBUS Master
電路連接完成后,將代碼上傳到Arduino Uno,現(xiàn)在可以將USB轉(zhuǎn)RS-485模塊連接到安裝了Modbus Slave軟件的計(jì)算機(jī)。
注意:打開(kāi)設(shè)備管理器,根據(jù)連接USB轉(zhuǎn)RS-485模塊的PC檢查COM端口,然后打開(kāi)Modbus Slave軟件。
1. Modbus Slave Tool如下所示,表示無(wú)連接。
2.下一步打開(kāi)Connection->Connect...,顯示如下。
3.它顯示以下對(duì)話框,因?yàn)樵撥浖窃囉冒妫虼苏?qǐng)單擊“稍后注冊(cè)”
4.??此試用軟件僅在打開(kāi)后運(yùn)行10分鐘。
5.??連接細(xì)節(jié)如下所示。將連接設(shè)置為串行端口,將串行設(shè)置設(shè)置為連接USB轉(zhuǎn)RS-485模塊的相應(yīng)COM端口。然后將波特率設(shè)置為115200,數(shù)據(jù)位為8,無(wú)奇偶校驗(yàn),1個(gè)停止位和模式為RTU,然后單擊“確定”。
6.??請(qǐng)注意,顯示No connection,現(xiàn)在打開(kāi)Setup-> Slave Definition。
7.現(xiàn)在Slave ID字段輸入1,F(xiàn)unction選擇03保持寄存器,以及地址設(shè)置為0,然后單擊OK。
8.??之后,將ID驗(yàn)證為1,將F為03.。在本文中,使用前三個(gè)寄存器(0-電位器ADC值,1-Push按鈕值,2-Push按鈕值)。
9.??現(xiàn)在按下按鈕2。注意第三行中的值1。當(dāng)沒(méi)有按下按鈕1時(shí),它在第二行中保持為0,在第一行中顯示電位器值。
10.??按下按鈕1時(shí)。注意第二行中的值1。并且由于沒(méi)有按下按鈕2所以它在第三行保持為0,第一行中顯示電位器值。
11.??現(xiàn)在當(dāng)按下兩個(gè)按鈕時(shí),在第二行和第三行中都有值1,并且還記下電位計(jì)值。
12.? ?當(dāng)電位計(jì)變化時(shí),Modbus從站軟件中的第1行也會(huì)發(fā)生變化。
以上就是Arduino UNO作為Master如何進(jìn)行RS-485 Modbus串行通信。
編輯:hfy
評(píng)論