Arduino 使用 BC26/BC35 連接至阿里雲平台


一、前言

本人最近參加的項目需要使用到NB-IoT模塊,在網上尋找了一圈之后,發現Arduino常用的NB-IoT模塊如下:
請添加圖片描述

請添加圖片描述

這兩個模塊均來自DFRobot,還有一些獨立的模塊。網上有關於這些通信模塊的資料,大多數都是跟Arduino UNO或者STM32做的調試,沒有見過有人使用Arduino Mega 2560與這些模塊連接。

因為本次的項目需要使用到非常多的針腳,UNO的針腳數無法滿足需求,而Mac電腦沒辦法對32芯片進行燒寫,故只能選擇Mega2560。

這就有了一個新的問題,模塊的兼容性能否滿足需求?

二、開始調試前的准備工作

1.通信模塊的選擇與軟件版本

本次選擇的模塊是BC260YBC35
請添加圖片描述

請添加圖片描述

軟件版本使用的是

請添加圖片描述

2.固件的燒錄

因為原廠的固件是不支持MQTT協議的,這塊需要到手后專門燒錄支持MQTT的AT固件,具體的燒錄辦法需要向商家詢問,由於固件和參考資料屬於官方的限制性文檔,故在這里不再公布。

只是燒錄時有幾個要點需要注意
1)燒錄軟件盡量放在系統的根目錄,且路徑上不要出現中文或者空格,因為會增加燒錄失敗的可能性;
2)要燒錄的固件的文件層次不要太深,盡量放在系統根目錄下,且路徑上不要出現中文或者空格,同樣也會增加燒錄失敗的風險;、
3)使用的USB轉TTL下載器一定要在電腦上裝驅動,例如我的USB TTL下載器是CH340C的芯片,那么我就需要在電腦上安裝對應芯片的驅動程序;

PS:本人燒錄固件的前幾次都是因為這樣的原因而失敗的,還有中間需要手動復位,就是說RESET針腳需要手動短暫接地。

3.調試前需要一個干凈的桌面

這一點很重要很重要很重要!!!!!!!!!!!!!!!!!!!!

本人在調試的時候在這方面剛剛吃過虧,一定要有一個整潔的桌面。

因為一個非常離譜的錯誤導致一下午都耗在調試上了。

起因是這樣的,在調試程序的時候,突然就跑通了一次,然后就再沒跑通了,無論怎樣改程序、改接線,都沒用,單獨測2560和通信模塊都沒問題,合在了一起就不行,並且在這過程中還排除了庫文件不兼容的問題。那么問題就出在了模塊與2560的接線上了,因為我測試的時候,因為杜邦線太長了,就團成了一團,並且線的周圍有一個揚聲器和一團高頻信號線和一團交流電線。直到我清理了一下桌面,順直了杜邦線之后,突然程序就再沒報過錯了。說明了這些環境對信號的傳輸造成了影響,估計是信號串擾吧。

請添加圖片描述

圖片中可以清晰的看到有一根HDMI線、一根雷電3的線、兩根交流電供電線、若干USB數據線,左邊和右邊還有揚聲器。長出來的杜邦線就被我團成了一團放在了這堆線上面(類似的場景,我沒拍,就拿這張圖還原個情景再現)然后調試就出Bug了。

所以調試前一定要有一個干凈整潔的桌面!!!!!

三、開始調試硬件

直接上程序,這個程序是店家提供的,我們來做個逐步的分析

#include <Arduino.h>
#include <SoftwareSerial.h>
#include <ArduinoJson.h>

DynamicJsonDocument json(200);

SoftwareSerial mySerial(50,52) ;//RX  TX

void CommandtoNBIOT (String cmd, char *res)
{
  while (1)
  {
    mySerial.println(cmd);
    delay(300);
    while (mySerial.available() > 0)
    {
      if (mySerial.find(res))
      {
        digitalWrite(7, HIGH);   // turn the LED on (HIGH is the voltage level)
        delay(100);              // wait for a second
        digitalWrite(7, LOW);    // turn the LED off by making the voltage LOW
        delay(100);
        Serial.println(res);
        return;
      }
      else
      {
        Serial.print(cmd);
        Serial.println("  Return ERROR!");
      }
    }
    delay(200);
  }
}

void MQTT_PubData(void)//發布數據到平台
{ //"/sys/a1qmGxDM8cd/mzhtest001/thing/event/property/post","{"id":"26","version":"1.0","params":{"CurrentTemperature":{"value":23},"RelativeHumidity":{"value":58}},"method":"thing.event.property.post"}"
  char sendjson[] = "{\"id\":\"26\",\"version\":\"1.0\",\"sys\":{\"ack\":0},\"params\":{\"CurrentTemperature\":{\"value\":50},\"CurrentHumidity\":{\"value\":10}},\"method\":\"thing.event.property.post\"}";
  char T_json[200];
  sprintf(T_json, sendjson); //,humidata
  mySerial.println("AT+QMTPUB=0,0,0,0,\"/sys/gbruRYswLWR/WEATHER/thing/event/property/post\""); //send message,主題更改
  delay(100);
  mySerial.println(T_json);
  mySerial.write(0x1A);
  delay(300);
  // wait for a second
  while (mySerial.available() > 0)
  {
  //  char inByte = mySerial.read();
  //  Serial.print(inByte);
  if (mySerial.find("+QMTPUB: 0,0,0"))
   {
   Serial.println("+QMTPUB: 0,0,0");
   break;
  }
  }
}



void BC260Y_init(void)//初始化MQTT連接
{
  Serial.println("1");
  // prints title with ending line break
  CommandtoNBIOT("AT", "OK");
  mySerial.println("ATE0&W");//關閉回顯
  delay(300);
  CommandtoNBIOT("AT+CPIN?", "+CPIN: READY"); //返+CPIN:READY,表明識別到卡了
  Serial.println("2");
  CommandtoNBIOT("AT+CGATT?", "+CGATT: 1"); //返+CGACT: 1,就能正常工作了
  Serial.println("3");
  mySerial.println("AT+QMTCLOSE=0");//關閉上一次socekt連接
  delay(300);
  mySerial.println("at+qmtcfg=\"aliauth\",0, \"gbruRYswLWR\",\"WEATHER\",\"d9661e128b5590cf5b7f880d991c7f7e\"");//配置三元素
  delay(300);
  CommandtoNBIOT("AT+QMTOPEN=0,\"iot-as-mqtt.cn-shanghai.aliyuncs.com\",1883", "+QMTOPEN: 0,0"); //建立服務器的IP和端口連接
  delay(300);
  CommandtoNBIOT("AT+QMTCONN=0,\"WEATHER\"", "+QMTCONN: 0,0,0"); //建立服務器的IP和端口連接
  delay(300);
}


void setup() {
  // put your setup code here, to run once:
  // initialize digital pin 13 as an output.
  pinMode(7, OUTPUT);
  Serial.begin(9600); //
  mySerial.begin(9600);
  delay(2000);
  
  BC260Y_init();
}

void loop() {
  
  // put your main code here, to run repeatedly:
  MQTT_PubData();//發布數據
  Serial.println("Data_Pub_Success");
  delay(4000);
}

首先來說第一部分,定一個軟串口

SoftwareSerial mySerial(50,52) ;//RX  TX

我個人更建議使用如下的方式

SoftwareSerial mySerial = SoftwareSerial(50,52) ;//RX  TX

這里定義了50號數字口是RX,52號數字口是TX

接線的方法如下:

BC260/BC35                              Arduino

   TX0         ------------------>        D50 
   
   RX0         ------------------>        D52
   
   GND         ------------------>        GND 
   
   VIN         ------------------>        5 V 
   

接着讓軟串口在9600波特率上運行着

void setup() {
	pinMode(7, OUTPUT);		//我在7針腳上接了一個燈
	Serial.begin(9600); 	//讓串口在9600波特率上運行
	mySerial.begin(9600);	//讓軟串口在9600波特率上運行
	delay(2000);
	BC260Y_init();			//初始化BC260/BC35
}

這段程序展示了如何將AT指令發送到通信模塊上

void CommandtoNBIOT (String cmd, char *res)
{
	while (1)
	{
		mySerial.println(cmd);
		delay(300);
		while (mySerial.available() > 0)
		{
			if (mySerial.find(res))
			{
				digitalWrite(7, HIGH);   
			    delay(100);              
			    digitalWrite(7, LOW);    
			    delay(100);
			    Serial.println(res);
			    return;
			}
			else
			{
			    Serial.print(cmd);
			    Serial.println("  Return ERROR!");
			}
		}
		delay(200);
	}
}

使用mySerial.println(cmd)發送AT指令。切記,必須使用println來發送,若沒有換行符,通信模塊不執行該指令。
等待一段時間后用find在通信模塊串口返回的值中尋找有沒有我要的返回值。

例如,我輸入AT后應該返回OK,那么里面的 cmd 對應 AT,res 對應 OK。

若沒有得到想要的返回值,該模塊會一直循環發送指令。

初始部分代碼如下:

void BC260Y_init(void)//初始化MQTT連接
{
	Serial.println("1");
	// prints title with ending line break
	CommandtoNBIOT("AT", "OK");
	mySerial.println("ATE0&W");//關閉回顯
	delay(300);
	CommandtoNBIOT("AT+CPIN?", "+CPIN: READY"); //返+CPIN:READY,表明識別到卡了
	Serial.println("2");
	CommandtoNBIOT("AT+CGATT?", "+CGATT: 1"); //返+CGACT: 1,就能正常工作了
	Serial.println("3");
	mySerial.println("AT+QMTCLOSE=0");//關閉上一次socekt連接
	delay(300);
	mySerial.println("at+qmtcfg=\"aliauth\",0, \"${ProductKey}\",\"${deviceName}\",\"${DeviceSecret}\"");//配置三元素
	delay(300);
	CommandtoNBIOT("AT+QMTOPEN=0,\"iot-as-mqtt.cn-shanghai.aliyuncs.com\",1883", "+QMTOPEN: 0,0"); //建立服務器的IP和端口連接
	delay(300);
	CommandtoNBIOT("AT+QMTCONN=0,\"${deviceName}\"", "+QMTCONN: 0,0,0"); //建立服務器的IP和端口連接
	delay(300);
}

數據發送部分的代碼參考

void MQTT_PubData(void)//發布數據到平台
{ 
	char sendjson[] = "{\"id\":\"26\",\"version\":\"1.0\",\"sys\":{\"ack\":0},\"params\":{\"CurrentTemperature\":{\"value\":50},\"CurrentHumidity\":{\"value\":10}},\"method\":\"thing.event.property.post\"}";
    char T_json[200];
    sprintf(T_json, sendjson); //,humidata
    mySerial.println("AT+QMTPUB=0,0,0,0,\"/sys/${ProductKey}/${deviceName}/thing/event/property/post\""); //send message,主題更改
    //具體的請參考阿里雲的topic相關文檔
    delay(100);
    mySerial.println(T_json);
    mySerial.write(0x1A);
    delay(300);
    // wait for a second
    while (mySerial.available() > 0)
    {
    //  char inByte = mySerial.read();
    //  Serial.print(inByte);
        if (mySerial.find("+QMTPUB: 0,0,0"))
         {
             Serial.println("+QMTPUB: 0,0,0");
             break;
         }
    }
}

那么如何快速判斷模塊是否能夠使用呢?

#include <SoftwareSerial.h>

SoftwareSerial bcserial = SoftwareSerial(50,52); //rx tx

void setup() {
  // put your setup code here, to run once:
  pinMode(13, OUTPUT);
  Serial.begin(9600);
  bcserial.begin(9600);
  delay(100);
  while (1)
  {
      Serial.print("AT\r\n");
      bcserial.println("AT");
      delay(300);
      Serial.println(bcserial.read());
      while (bcserial.available() > 0)
      {
          if (bcserial.find("OK"))
          {
              digitalWrite(13, HIGH);   // turn the LED on (HIGH is the voltage level)
              delay(100);              // wait for a second
              digitalWrite(13, LOW);    // turn the LED off by making the voltage LOW
              delay(100);
              Serial.println('OK');
              return;
           }
           else
           {
              Serial.print("AT");
              Serial.println("  Return ERROR!");
           }
        }
        delay(200);
    }
  
}

void loop() {
    // put your main code here, to run repeatedly:
    Serial.println("OKKKKKK");
}

如果返回的像是這樣的信息,就說明該模塊與Arduino之間連接良好
請添加圖片描述

四、阿里雲平台的設置

首先得要開通阿里雲的物聯網平台,測試的話就使用公共實例即可

1.添加產品並添加功能

在左邊的設備管理里面的產品,創建產品:

請添加圖片描述
產品名稱自定

請添加圖片描述
點擊 查看 之后選擇功能定義然后點擊添加自定義功能(我這個是已經添加過並發布的了請添加圖片描述

請添加圖片描述
請添加圖片描述
然后點擊發布上線即可。

2.添加設備

請添加圖片描述
點擊設備管理,然后點擊添加設備,出現如下的畫面,設備名字自己定義即可
請添加圖片描述
然后將設備的三要素填寫的Arduino的程序中的對應位置上,然后燒錄進Arduino,等待設備的激活連接。
請添加圖片描述
請添加圖片描述

激活成功之后在物理型數據里就能看到剛剛添加的功能的數據了。

五、小結

第一次折騰NB-IoT,踩了好些的坑,更多的坑則是讓我的搭檔踩了(我倆都第一次接觸這個)。

把這個發出來僅僅是記錄了一下能成功運行的整個流程。

Arduino的程序在使用起來還是過於的麻煩,后續有計划打算封裝一個兼容BC260Y和BC35 NB-IoT模塊的庫,使用起來能相對的方便不少。不過我也得學不少的東西。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM