你好,我是愛吃魚香ROS的小魚。這一節(jié)我們正式在MicroROS開發(fā)板上編寫代碼,輸出HelloWorld到電腦上。在正式開始編寫代碼前,我們先了解下開發(fā)流程。
一、Arduino開發(fā)流程
Arduino和其他單片機開發(fā),一共分為四步。
- 編寫代碼,根據相關的API和SDK進行代碼的編寫。
- 編譯工程,將工程的代碼文件編譯成二進制文件。
- 燒錄二進制文件,將上一步生成的二進制文件通過工具燒錄到開發(fā)板中。
- 運行測試,重啟開發(fā)板,觀察硬件執(zhí)行情況(數據打印一般通過串口查看)
接下來小魚就按照上面總結的幾個步驟來嘗試編寫HelloWorld!
二、編寫代碼
2.1 Arduino函數介紹
前面有介紹,Ardunio平臺的一大特點就是簡單易用,而Ardunio使用的開發(fā)語言是C/C++,從工程生成的默認代碼就可以看出來。
#include < Arduino.h >
void setup() {
// put your setup code here, to run once:
}
void loop() {
// put your main code here, to run repeatedly:
}
整個代碼可以分為三個部分
- 頭文件
#include
setup()
函數,該函數只會在啟動時被系統調用一次loop()
函數,該函數會被系統循環(huán)調用,直到重啟或者斷電
2.2 為什么沒有入口函數main函數?
在學習C語言和C++時你應該學過,程序的入口文件是main函數,但在這個Arduino中卻沒有main函數的存在,這是為什么?
Arduino其實是有main函數的,Arduino的main函數長這樣(ESP32-Arduino庫有所不同,但原理一樣:https://github.com/espressif/arduino-esp32/blob/master/cores/esp32/main.cpp)
#include < Arduino.h >
// Declared weak in Arduino.h to allow user redefinitions.
int atexit(void (* /*func*/ )()) { return 0; }
// Weak empty variant initialization function.
// May be redefined by variant files.
void initVariant() __attribute__((weak));
void initVariant() { }
void setupUSB() __attribute__((weak));
void setupUSB() { }
int main(void)
{
init();
initVariant();
#if defined(USBCON)
USBDevice.attach();
#endif
setup();
for (;;) {
loop();
if (serialEventRun) serialEventRun();
}
return 0;
}
核心的代碼就這一段
setup();
for (;;) {
loop();
if (serialEventRun) serialEventRun();
}
從這里就可以看出來,setup和loop函數之間的關系,在main函數中先調用一次setup函數,再使用for死循環(huán)調用loop函數。
2.3 串口輸出HelloWorld
要實現將HelloWorld!
從開發(fā)板輸出到電腦上,我們需要了解一個常用的通信協議Serial
,常稱串口通信。
關于串口通信的原理可以到B站搜索相關視頻,但在這里使用時你只需要了解如何使用即可。
這里我們了解三個函數,串口初始化、串口打印、串口讀取。
函數原型 | 參數 | 返回值 | 描述 |
---|---|---|---|
void begin(unsigned long baud) | baud:串口波特率 | void | 該函數用于初始化串口,主要配置串口波特率,波特率類似于頻道號,串口收發(fā)雙方保持相同的波特率才能進行正常通信。常見的波特率有9600,115200等,波特率其實代表每秒數據收發(fā)的頻率,波特率越高,速度越快。 |
size_t printf(const char *format, ...) | format:格式化字符串 | size_t 打印的字符數量 | 該函數和我們常見的printf函數一致,eg:Serial.printf("Hello World!"); |
int read(void) | void | int 讀取的字符值,ASSIC表示 | 該函數用于讀取一個字節(jié)的數據,返回值就是這個字節(jié)的值,如果沒有數據則返回-1 |
基于上面的函數,我們可以這樣輸出HelloWorld!
#include < Arduino.h >
void setup() {
Serial.begin(115200);
}
void loop() {
Serial.printf("Hello World!\\n");
}
在setup()函數里進行串口的初始化, 波特率設置成了115200 ,在loop函數中不斷的輸出Hello World!
。
三、編譯代碼
點擊對號,或者使用快捷鍵Ctrl+Alt+B
,即可編譯。
看到Building .pio/build/featheresp32/firmware.bin
和Successfully created esp32 image.
就代表已經成功生成了二進制文件,下一步我們就開始燒錄二進制文件。
四、燒錄二進制文件
4.1 連接開發(fā)板到電腦
MicroROS學習板采用TypeC接口,你需要一個USB數據線將開發(fā)板連接到你的電腦。連接電腦后,Linux系統驅動會被自動搜索和加載,查看是否有正確驅動,可以使用lsusb進行測試。
lsusb
輸入后,如果可以看到CP210x這個設備,就代表驅動加載成功了
驅動加載成功后在/dev目錄下會多出一個ttyUSBx的設備,比如小魚這里就是/dev/ttyUSB0
使用ls /dev/ttyUSB*
指令可以將其列出
4.2 設置設備權限
我們想讓開發(fā)板和電腦通過串口進行通信,電腦端只需對這個串口進行讀寫就行了。因為設備默認的生成目錄是在/dev目錄下,普通用戶是沒有讀寫權限的,所以在使用之前我們可以修改下該設備的權限。
臨時修改
sudo chmod 666 /dev/ttyUSBx
也可以永久修改,將用戶添加到dialout和plugdev組(重啟后方生效)
sudo usermod -a -G dialout $USER
sudo usermod -a -G plugdev $USER
4.3 燒錄二進制文件
點擊左下角的上傳燒錄按鈕,或者使用快捷鍵Ctrl+Alt+U
進行燒錄。
看到上面四部分打印代表燒錄成功,可以看到PIO可以自動檢測串口并進行連接,接著上傳文件到開發(fā)板,最后自動重啟。
五、運行測試
因為在下載完成后,下載程序幫我們自動重啟了,所以這里我們不需要進行重啟。接著我們使用串口Monitor打開串口看看有沒有數據。
點擊Serial Monitor按鈕,或者使用快捷鍵Ctrl+Alt+S
,如果沒有出錯,你將看到下面的亂碼。
原因是終端的波特率不對,開發(fā)板發(fā)送給電腦數據的波特率是115200,而電腦接收的波特率是9600,不匹配就會造成亂碼。
通過修改配置文件,可以修改Serial Monitor的默認波特率。
在platformio.ini
中添加一行代碼
monitor_speed = 115200
接著關閉剛剛的終端,再重新打開,接著我們就可以看到嗖嗖嗖的Hello World!
六、總結
本節(jié)我們成功將自己的代碼上傳到開發(fā)板上了,然后通過串口成功的和單片機建立了單向連接(開發(fā)板向電腦發(fā)送數據),下一節(jié)我們學習下電腦向單片機發(fā)送消息。
最后還有幾個小作業(yè)
1.上面我們輸出Hello World!
在不斷的輸出,如果想要改成只輸出一次,代碼該怎么寫?
答案:
#include < Arduino.h >
void setup() {
Serial.begin(115200);
Serial.printf("Hello World!\\n");
}
void loop() {
}
2.上面我們輸出Hello World!
在快速的輸出,如果想要改成每秒輸出一次,代碼該怎么寫?
提示函數:void delay(uint32_t ms)
延時指定ms。
答案:
#include < Arduino.h >
void setup() {
Serial.begin(115200);
}
void loop() {
delay(1000);
Serial.printf("Hello World!\\n");
}
-
單片機
+關注
關注
6037文章
44558瀏覽量
635397 -
開發(fā)板
+關注
關注
25文章
5052瀏覽量
97494 -
代碼
+關注
關注
30文章
4788瀏覽量
68625 -
Arduino
+關注
關注
188文章
6469瀏覽量
187108 -
ROS
+關注
關注
1文章
278瀏覽量
17010
發(fā)布評論請先 登錄
相關推薦
評論