文章程式碼顯示

2019年1月14日 星期一

《進階※應用篇》寫程式Arduino教學 -11:Lora 長距無線傳輸 SX1278 1W 433MHZ 繼電器同步應用

經過基礎篇與應用篇後,我實作了一個繼電器同步的應用

事實上這個實作應用的可用之處很廣泛
畢竟繼電器這東西在工控領域已經無所不在了


會做這個應用事實上還有一個故事
當時我剛拿到 Lora 模組,正想說要做什麼應用時
有人找我來幫他解決一個問題

問題是這樣的 :

在一個山區有上下兩個水塔,兩個水塔之間直線距離約 1.5km
當上水塔的水位過低時,下水塔會啟動幫浦把水打上去
本來上下水塔之間是走地下電纜靠兩個控制器來探測浮球與控制抽水馬達
但貌似是地下電纜的線斷了,但因為在地底下,根本無法查出線斷在哪裡
所以就委託我做一個無線訊號傳輸的應用



這問題正好可以使用 Lora 來解決(經我實測,我這個模組在都市的傳輸距離大約 2km左右,理論上在山區較無遮蔽物的狀況下可以達到更遠的傳輸距離)


知道問題點在哪後,我就著手開始寫程式了

目標是 Lora 發射端使用 4 個乾接點(連接至上水塔控制器的浮球訊號),以及可用來做為強制啟動的一組指撥開關

Lora 接收端使用含有 4 個繼電器的繼電器模組

將 Lora 發射端的 4 個乾接點訊號,直接與 Lora 接收端的 4 個繼電器模組同步
(例如 :  Lora 發射端的 1 號乾接點被短接,代表上水塔的浮球下降到某個水位,此時同步觸發 Lora 接收端的 1 號繼電器模組,啟動下水塔的抽水馬達 )


以下給出程式碼,其註解已經把該交代的都交代了,就不再贅述
(程式碼中實際上為 5 個訊號的同步,這是因為我做到一半才突然想到我只需要 4 個訊號同步即可,但電路都焊了,就這麼將錯就錯吧)

發射端 ( ID: EA01 ; 波段: 13 )

請至 github連結 觀看 (因程式碼中有些寫法導致在 Blogger 中無法顯示)

接收端 ( ID: EA00 ; 波段: 13 )

#include "SoftwareSerial.h"

#define LED 13
#define output_1 7
#define output_2 8
#define output_3 9
#define output_4 10
#define output_5 11
#define AUX 5

SoftwareSerial mySerial(2, 3); // RX, TX
void waitAUX();
byte incoming2Byte[2]={0xFF,0xFF}; /* buffer */

void setup() {
  Serial.begin(9600);
  mySerial.begin(9600);
  pinMode(AUX,INPUT);
  pinMode(LED,OUTPUT);
  pinMode(output_1,OUTPUT);
  pinMode(output_2,OUTPUT);
  pinMode(output_3,OUTPUT);
  pinMode(output_4,OUTPUT);
  pinMode(output_5,OUTPUT);
  /*因該繼電器模組為低電位觸發,為了不誤動作,在重開機時都先將繼電器關閉*/
  digitalWrite(output_1,HIGH);
  digitalWrite(output_2,HIGH);
  digitalWrite(output_3,HIGH);
  digitalWrite(output_4,HIGH);
  digitalWrite(output_5,HIGH);
  waitAUX();
  Serial.println("Start.");
}

void loop() {
  waitAUX();
  if (mySerial.available() > 0) {
    mySerial.readBytes(incoming2Byte, 2); /* 將 2bytes 資料餵入 buffer */   
    digitalWrite(LED,!digitalRead(LED));
    Serial.flush();
  }
  
  Serial.print("incoming2Byte[0] : ");
  Serial.print(incoming2Byte[0]); /* 第一個 byte 的數據 */
  Serial.print(" , incoming2Byte[1] : ");
  Serial.println(incoming2Byte[1]); /* 第二個 byte 的數據 */
  Serial.print("B1: "); Serial.println((~incoming2Byte[0]>>4)&0x01);
  Serial.print("B2: "); Serial.println((~incoming2Byte[0]>>3)&0x01);
  Serial.print("B3: "); Serial.println((~incoming2Byte[0]>>2)&0x01);
  Serial.print("B4: "); Serial.println((~incoming2Byte[0]>>1)&0x01);
  Serial.print("B5: "); Serial.println((~incoming2Byte[0]>>0)&0x01);
  digitalWrite(output_1, (~incoming2Byte[0]>>4)&0x01 );
  digitalWrite(output_2, (~incoming2Byte[0]>>3)&0x01 );
  digitalWrite(output_3, (~incoming2Byte[0]>>2)&0x01 );
  digitalWrite(output_4, (~incoming2Byte[0]>>1)&0x01 );
  digitalWrite(output_5, (~incoming2Byte[0]>>0)&0x01 );
}

// ===== 等待 Lora 晶片不繁忙 =====
void waitAUX(){
  while(!digitalRead(AUX));
  delay(10);
}






我的 Youtube 頻道,一定要訂閱
我將定期推出程式語言的新手教學影片


↓↓↓ 連結到部落格方針與索引 ↓↓↓

Blog 使用方針與索引