前言
開發的過程中,用A39C-T400A22D1aLora模塊作無線傳輸。這個項目之前的人都是用廠商的ASDS上位機軟件,直接配置Lora模塊,也確實能運作。
但是文檔中還記載了直接給模塊發送指令進行配置的方式,我打算試試。
| 配置方法 | 優勢 | 劣勢 |
|---|---|---|
| 上位機 | 界面直觀,操作簡單 | 部署前需為模塊單獨費時間,參數難以保證無誤 |
| 指令配置 | 快速部署,無須額外操作 | 佔用程序體積 |
未來要是程序邏輯逐漸複雜,硬件裝不下的話,沒準兒得砍了指令配置這部分。
鑑於開發時一直沒找到能抄的代碼,也沒什麼思路(我是嵌入式新手)。
寫這篇,一來記錄,二來則算是填補網上資料的空缺吧。
(本文不會詳細講解的邏輯大概律在文檔中説了,算是文檔的補充與實現示例,文檔還得自己讀RTFM!)
乾貨
本文不會提關於接線、收發等。
參考資料:
- 模塊文檔下載(個人感覺這裏最主要且有用的文檔是
a39c_t400a22d1a/A39C-T400A22D1a資料包/產品規格書/a39ct400a22d1acn.pdf) - 我的代碼倉庫(僅供參考,lora相關文件與本文有關)
代碼在Arduino上測試,但主要在於命令的構造,因為是類C語言,STM32什麼的應該改改Serial相關的就行。
基本思路是依據文檔第六部分,直接給模塊發送配置等指令。
命令具體推導由上位機所發的命令依據文檔逐位解析,參考圖(很亂,僅參考):

構造通過宏定義實現,方便更改。預留寄存器部分直接抄的上位機軟件發送到樣本(不知道為什麼預留寄存器好像對配置成敗也有影響,沒仔細測試過,待定)。
主命令定義:
const byte configCmd[] = {
0x80, 0x04, 0x1E, //cmd, 0x80 write local success, return if error
LORA_BAUDRATE, //0x04
LORA_SERIALARGS, //0x05
LORA_TRANSARGS, //0x06
LORA_WORKMODE, //0x07
0x05,0x03,0xE8, //0x08 to 0x09, preserved
LORA_MAINORFOLLOW,//0x0A
0x77, 0x77, 0x77, 0x2E, 0x61, 0x73, 0x68, 0x69, 0x6E, 0x69, 0x6E, 0x67, 0x2E, 0x63, 0x6F, 0x6D, //0x0B, default, AES key
0x7C,0x7C,0x7C,0x7C,0x7C,0x05, //0x0C to 0x0D, preserved
LORA_PACKSIZE, //0x0E
0x00,0x23,0x00,0x00,0x00,0x3C,0x3C, //0x0F to 0x13, preserved
LORA_SLEEPTIME, //0x14
0x0A,0x19, //0x15 to 0x16, preserved
0x00, 0x80, //0x17, default, which is enable wireless wake code
LORA_LOCGROUP, //0x18
LORA_LOCADDR, //0x19
LORA_TARGGROUP, //0x1A
LORA_TARGADDR, //0x1B
0x00,0x00,0x00,0x00,0x17,0x02 //0x1C to 0x21, related to relay mode
};
宏定義示範:
// Baud Rate
#define LORA_BAUDRATE 0x00, 0x00, 0x25, 0x80
// LoraSerial Arguments
#define LORA_SERIALARGS 0x00
// Transmission Arguments
#define LORA_CHANNEL 20
#define LORA_TRANSARGS LORA_CHANNEL >> 3, (byte)(LORA_CHANNEL << 5) + 0b11010
// Transmission Mode
#define LORA_WORKMODE 0x00, 0x01
// Main Mode or Follow Mode
#define LORA_MAINORFOLLOW 0x00
// Pack Size
#define LORA_PACKSIZE 0x40
// Sleep Time
#define LORA_SLEEPTIME 0
// Group & Addr
// the target_group and target_addr is used in transparent mode
#define LORA_LOCGROUP 0
#define LORA_LOCADDR 0
#define LORA_TARGGROUP 0
#define LORA_TARGADDR 1
發送命令實例(Arduino,LoraSerial預先定義了):
LoraSerial.write(buf, 61);
// 文檔第八部分有關於時序的,最好加上等待時間
delay(100);
// 然後檢測返回命令是否成功({128, 4, 61}即{0x80, 0x04, 0x1E}為配置成功返回)
const byte corrbuf[] = {0x80, 0x04, 0x1E};
loraCheckReturn(3, corrbuf);
檢測Lora返回的函數示例:
// LoraSerial是預定義的Lora串口
// critErrorAct是預定義的碰到錯誤時觸發的操作,如使機器陷入死循環或停機
void loraCheckReturn(int corrlenn, byte *corrbuf) {
int corrlen = corrlenn - 1;
int cnt = 0;
int correctcnt = 0;
while (true) {
if (LoraSerial.available() > 0) {
byte ret = LoraSerial.read();
DebugSerial.print(ret);
DebugSerial.print(", ");
if (correctcnt >= corrlen) {
break;
}
if (ret == corrbuf[cnt]) {
correctcnt++;
} else {
// Unknown return value
DebugSerial.print("(wrong byte)");
critErrorAct();
}
cnt++;
}
}
loraBufClear();
return;
}
這個遇到的問題(上位機軟件也有此問題)是發送後報配置失敗命令,經過實驗,在配置前重置出廠設置即可,同樣根據文檔發送命令{0x80, 0x23, 0x01}重置。最好在發送這兩個命令前再加一個握手命令{0, 0, 1}檢查模塊可用性。具體代碼不放這了,仍然是發送,等待,檢查的邏輯,示例可以看參考資料裏的代碼倉庫。
結語
嵌入式這種硬件活,給我最大印象就是玄學(機魂不悦)。純軟件環境(尤其高級編程語言)就像在温室裏,軟件轉硬件還是十分有挑戰性的(有一次調了半個小時連不上模塊,拿別的測試才發現模塊是壞的)。但是不要怕,多看文檔,多做實驗,用點AI,問題會解決的,經驗也就多了。