第四章 系統設計與實作
4.3 韌體系統實作
將開發板的驅動程式安裝好之後,打開 Arduino 開發板的開發工具:Sketch IDE 整合開發軟體(軟體下載:https://www.arduino.cc/en/Main/Software),撰 寫如表 8、表 9、表 10、表 11、表 12 所示之 PID 控制器系統程式[11, 33],並 透過開發工具將整個程式編譯後,上傳燒錄到 NodeMCU-32S Lua WiFi 開發板,
進行測試。
表 8 PID 控制器系統程式 PID 控制器系統程式(PID 控制器系統程式)
//---
- 39 -
PID 控制器系統程式(PID 控制器系統程式)
#include "initPins.h"
#include "comlib.h"
#include "command.h"
#include "crc16.h"
WiFiMulti wifiMulti;
WiFiClient pvclient;
///////////////////////////////////////////////////////
//http://140.127.205.165/lab203_iot/fy_900/dataadd.php?t=01asda01ds asd01
void sendNAS() {
// connectstr = "t="+d;
Serial.println(connectstr) ;
if (client.connect(iotserver, iotport)) {
Serial.println("Make a HTTP request ... ");
String strHttpGet = strGet + connectstr + strHttp;
Serial.println(strHttpGet);
//### Send to Server client.println(strHttpGet);
client.println();
} }
void initAll()
- 40 -
PID 控制器系統程式(PID 控制器系統程式) {
Serial.begin(9600);
Serial2.begin(9600, SERIAL_8N1, RXD2, TXD2);
Serial.println("System Start") ;
}
void ShowInternet() {
ShowMAC() ; ShowIP() ; }
void ShowAP(String apname) {
}
void ClearShow() {
}
void ShowMAC() {
}
void ShowIP() {
}
- 41 -
PID 控制器系統程式(PID 控制器系統程式)
void ShowString(String ss) {
}
void setup() {
//Initialize serial and wait for port to open:
initAll() ;
WiFi.disconnect(true);
WiFi.setSleep(false);
// --- wifi connection start wifiMulti.addAP("Brucetsao", "12345678");
wifiMulti.addAP("IOT", "0123456789");
wifiMulti.addAP("Brucetsao2", "12345678");
Serial.println("Connecting Wifi...");
wifiMulti.run() ;
while (WiFi.status() != WL_CONNECTED) //WiFi.status() ==網路狀 態,WL_CONNECTED ==連線狀態成功
Serial.println("WiFi connected");
Serial.print("Access AP: ");
Serial.println(WiFi.SSID());
- 42 -
PID 控制器系統程式(PID 控制器系統程式) Serial.print("IP address: ");
Serial.println(WiFi.localIP());
printWiFiStatus();
MacData = GetMacAddress() ; Serial.print("MAC is :(") ; Serial.print(MacData) ; Serial.print(")\n") ; ShowInternet() ;
mqttclient.begin("broker.shiftr.io", mqclient);
mqttclient.onMessage(messageReceived);
fillCID(MacData); // generate a random clientid based MAC Serial.print("MQTT ClientID is :(") ;
Serial.print(clintid) ; Serial.print(")\n") ;
connectMQTT();
requestdata(&Read_PV[0],8);
delay(200);
if (Serial2.available()>0) {
Serial.println("Controler Respones") ; cmmstatus = Get_PV(&retdata) ;
- 43 -
requestdata(&Read_SV[0],8);
delay(200);
if (Serial2.available()>0) {
- 44 -
//void sendPV(Word pvvalue) void sendPV()
Serial.println(connectstr) ;
if (pvclient.connect(iotserver, iotport)) {
- 45 -
void fillCID(String mm) {
// generate a random clientid based MAC //compose clientid with "tw"+MAC
clintid[0]= 't' ; clintid[1]= 'w' ;
mm.toCharArray(&clintid[2],mm.length()+1) ; clintid[2+mm.length()+1] = '\n' ;
}
//---
void messageReceived(String &topic, String &payload) { //CarNumber = payload ;
Serial.println("Msg:"+payload) ; Serial.println("MSG:" +payload);
// msgDecode(payload) ; /*
if (ValueDecode(payloadcount,rfidnum)==CarNumber) {
ShowString("Para Count:"+String(payloadcount)) ; }
*/
}
void connectMQTT() {
Serial.print("MQTT ClientID is :(") ; Serial.print(clintid) ;
Serial.print(")\n") ;
- 46 -
PID 控制器系統程式(PID 控制器系統程式)
while (!mqttclient.connect(clintid, "try", "try")) { Serial.print("-");
delay(1000);
}
Serial.print("\n");
mqttclient.subscribe("/nuk/pid/#");
Serial.println("\n MQTT connected!");
// client.unsubscribe("/hello");
}
表 9 PID 控制器系統程式(comlib.h) PID 控制器系統程式(comlib.h)
long POW(long num, int expo) ; String SPACE(int sp) ;
String strzero(long num, int len, int base) ; unsigned long unstrzero(String hexstr, int base) ; String print2HEX(int number) ;
//---
long POW(long num, int expo) {
- 47 -
PID 控制器系統程式(comlib.h)
String SPACE(int sp) {
String strzero(long num, int len, int base) {
String retstring = String("");
int ln = 1 ;
- 48 -
PID 控制器系統程式(comlib.h) retstring.concat(tmp[i]);
}
return retstring;
}
unsigned long unstrzero(String hexstr, int base) {
String hexcode = String("0123456789ABCDEF") ; for (i = 0 ; i < (len ) ; i++)
String print2HEX(int number) {
String hhh ;
- 49 - void printWiFiStatus() {
// print the SSID of the network you're attached to:
Serial.print("SSID: ");
Serial.println(WiFi.SSID());
// print your WiFi shield's IP address:
ip = WiFi.localIP();
Serial.print("IP Address: ");
Serial.println(ip);
// print the received signal strength:
rssi = WiFi.RSSI();
- 50 -
PID 控制器系統程式(comlib.h)
Serial.print("signal strength (RSSI):");
Serial.print(rssi);
Serial.println(" dBm");
}
String GetMacAddress() {
// the MAC address of your WiFi shield String Tmp = "" ;
byte mac[6];
// print your MAC address:
WiFi.macAddress(mac);
for (int i=0; i<6; i++)
long POW(long num, int expo) ; String SPACE(int sp) ;
String strzero(long num, int len, int base) ; unsigned long unstrzero(String hexstr, int base) ; String print2HEX(int number) ;
//--- boolean pvflag = false ; boolean svflag = false ; long temp , humid ; byte cmd ;
byte receiveddata[250] ;
- 51 -
PID 控制器系統程式(command.h) int receivedlen = 0 ;
byte StrTemp[] = {0x01,0x04,0x00,0x01,0x00,0x02,0x20,0x0B} ;
byte Str1[] = {0x01,0x03,0x00,0x8A,0x00,0x01,0xA5,0xE0} ; //讀取單 筆參數資料:Master 送出資料(讀取 PV 現在資料)
byte Str2[] = {0x01,0x04,0x00,0x02,0x00,0x01,0x90,0x0A} ;
//---SV
byte Read_PV[8] = {0x01,0x03,0x00,0x8A,0x00,0x01,0xA5,0xE0} ; //讀 取單筆參數資料:Master 送出資料(讀取 PV 現在資料)
byte Read_SV[8] = {0x01,0x03,0x00,0x00,0x00,0x01,0x84,0x0A} ; //讀 取單筆參數資料:Master 送出資料(讀取 SV 現在資料
typedef struct Word DATA;
typedef struct ANSData {
typedef struct ANSData pvdata;
ANSData retdata ;
//---
void requestdata(byte *sendstr, int len) ; void requesttemperature() ;
void requesthumidity() ; int GetDHTdata(byte *dd) ;
- 52 -
PID 控制器系統程式(command.h) int Get_PV(ANSData *devdata) ; int Get_SV(ANSData *devdata) ;
void DisplayPVData(ANSData *devdata) ; void DisplaySVData(ANSData *devdata) ; unsigned int WordValue(Word *twobyte) ; String WordHex(Word *twobyte) ;
float GETPV() ; float GETSV() ; //---
unsigned int WordValue(Word *twobyte) {
return ((*twobyte).HI *256+(*twobyte).LO) ; }
String WordHex(Word *twobyte) {
return (print2HEX((byte)(*twobyte).HI)+
print2HEX((byte)(*twobyte).LO)) ; }
void requestdata(byte *sendstr, int len) {
Serial.println("now send data to device") ; Serial2.write(sendstr,len);
Serial.println("end sending") ; }
void requesttemperature() {
Serial.println("now send data to device") ; Serial2.write(Str1,8);
Serial.println("end sending") ; }
void requesthumidity() {
Serial.println("now send data to device") ; Serial2.write(Str2,8);
- 53 -
PID 控制器系統程式(command.h)
Serial.println("end sending") ; }
int GetDHTdata(byte *dd) {
int count = 0 ;
long strtime= millis() ;
while ((millis() -strtime) < 2000) {
if (Serial2.available()>0) {
int Get_PV(ANSData *devdata) {
int stage = 0 ;
Serial.println("Enter Get_PV--While") ; while (Serial2.available()>0)
{
if (stage == 0) {
- 54 -
- 55 -
void DisplayPVData(ANSData *devdata) {
Serial.print(WordValue(&(*devdata).Data)) ; Serial.print(")\n") ;
Serial.print("CRC:(") ;
Serial.print(WordHex(&(*devdata).CRC16)) ; Serial.print(")\n") ;
- 56 -
PID 控制器系統程式(command.h) }
int Get_SV(ANSData *devdata) {
int stage = 0 ;
Serial.println("Enter Get_SV--While") ; while (Serial2.available()>0)
{
- 57 -
void DisplaySVData(ANSData *devdata) {
- 58 -
PID 控制器系統程式(command.h)
Serial.print("Data:(") ;
Serial.print(WordValue(&(*devdata).Data)) ; Serial.print(")\n") ;
Serial.print("CRC:(") ;
Serial.print(WordHex(&(*devdata).CRC16)) ; Serial.print(")\n") ;
}
float GETPV() {
long gg = WordValue(&retdata.Data) ; return gg/10+0.1*(gg%10) ;
}
float GETSV() {
long gg = WordValue(&retdata.Data) ; return gg/10+0.1*(gg%10) ;
}
表 11 PID 控制器系統程式(initPins.h) PID 控制器系統程式(initPins.h)
#include <String.h>
#include <WiFi.h> // WIFI NEED THIS
#include <WiFiMulti.h> //設定多 AP 資料與密碼
//WiFiMulti wifiMulti; //設定多 AP 資料與密碼 物件
#include <String.h>
#include <MQTT.h>
- 59 -
PID 控制器系統程式(initPins.h)
#define RXD2 16
#define TXD2 17 int cmmstatus = 0 ; char clintid[20];
char Oledchar[30] ;
#define maxfeekbacktime 5000
int phasestage=1 ; boolean flag1 = false ; boolean flag2 = false ; String d,s;
//////////////////////////////////////////////////////
// control parameter
boolean systemstatus = false ; boolean Reading = false ; boolean Readok = false ; // int trycount = 0 ; int wifierror = 0 ;
boolean btnflag = false ; //---
int keyIndex = 0; // your network key Index number (needed only for WEP)
IPAddress ip ; long rssi ;
int status = WL_IDLE_STATUS;
- 60 -
PID 控制器系統程式(initPins.h)
char iotserver[] = "nuk.arduino.org.tw" ; // name address for Google (using DNS)
int iotport = 8888 ;
// Initialize the Ethernet client library // with the IP address and port of the server
// that you want to connect to (port 80 is default for HTTP):
String strPVGet="GET /pid/dataadd.php";
String strGet="GET /pid/dataadd.php";
String strHttp=" HTTP/1.1";
String strHost="Host: nuk.arduino.org.tw"; //OK String connectstr ;
String MacData ; WiFiClient client;
WiFiClient mqclient;
MQTTClient mqttclient;
int deviceid=1 ; float PV = 0.0 ;
void requestdata(byte *sendstr, int len) ; void requesttemperature() ;
void requesthumidity() ; int GetDHTdata(byte *dd) ; int Parsing_PV(byte idno) ;
unsigned int WordValue(Word *twobyte) ; //---
static const unsigned int wCRCTable[] = {
- 61 -
- 62 -
unsigned int ModbusCRC16 (byte *nData, int wLength) {
byte nTemp;
unsigned int wCRCWord = 0xFFFF;
- 63 -
boolean CompareCRC16(unsigned int stdvalue, uint8_t Hi, uint8_t Lo) {
boolean CRC16Compare(Word *srcvalue, Word *cmpvalue) {
//long aa = WordValue(srcvalue);
// long bb = WordValue(cmpvalue);
if (WordValue(srcvalue) == WordValue(cmpvalue)) {
- 64 -
PID 控制器系統程式(crc16.h) }