上一篇我購買了Arduino Uno板子,並且安裝設定好Arduino軟體開發環境,成功編譯、上傳到板子上,讓標示著L的LED燈不停閃爍。
這一篇要說明Arduino的sketch基本架構,並且以序列埠輸出文字到電腦上。所謂的sketch(程式碼、草稿碼),就是Arduino的程式啦。
開啟Arduino軟體開發環境後,選「File」-「Examples」-「1.Basics」-「BareMinimum」,這支範例程式含有最基本的架構,如下:
void setup() {
// put your setup code here, to run once:
}
void loop() {
// put your main code here, to run repeatedly:
}
在整支程式啟動時,會呼叫setup()這支函式,只會執行一次。然後就會不斷地呼叫loop()、不斷地一再執行。
現在,讓我們寫些程式碼,將一些文字輸出到序列埠,並在電腦上觀看。
void setup() {
// put your setup code here, to run once:
Serial.begin(115200);
Serial.println("Hello World!");
}
首先利用Serial.begin(115200)開啟序列傳輸並設定傳輸鮑率,會以0、1針腳進行接收與傳送,我在這裡只示範傳送。
以Serial.println("Hello World!")輸出Hello World!字串。
static int g_counter = 0;
void loop() {
// put your main code here, to run repeatedly:
Serial.println(g_counter);
g_counter++;
delay(1000);
}
設定全域靜態變數g_counter,初始為0。
每次執行loop()時,以Serial.println(g_counter)輸出g_counter的數值、並且加1,以delay(1000)暫停一秒(單位為千分之一秒),然後程式會再次執行loop()。
編譯成功並上傳板子後,以「Tools」-「Serial Monitor」打開序列埠輸出監控視窗觀看,把右下角的傳輸鮑率設定成跟Serial.begin(115200)所設定的數值一樣。(若115200不行的話,可以試試看9600。)
然後就應該看到如下的畫面了。
每當以針腳1傳出資料時,板子上標示著TX的LED都會閃一下。
每次開啟Serial Monitor時,板子都會重置(重新開機),所以會從頭從0開始數。
不過Arduino內建的函式print與println不強,沒辦法像一般C語言的printf,底下有個簡易型的函式,可以輸出格式字串。
void pf(const char *fmt, ... ){
char tmp[128]; // resulting string limited to 128 chars
va_list args;
va_start (args, fmt );
vsnprintf(tmp, 128, fmt, args);
va_end (args);
Serial.print(tmp);
}
不過, 最後輸出的字串必須少於128個字元。
有了這個函式後,就可以這麼寫了:
static int g_counter = 0;
void loop() {
pf("g_counter is %d, %s\n", g_counter, g_counter%2 == 0 ? "even" : "odd");
g_counter++;
delay(1000);
}
2012/02/08
Arduino Sketch基本架構與序列埠輸出
Subscribe to:
Post Comments (Atom)
各種基本的電路連接,淺顯易懂。
ReplyDeletehttp://www.pighixxx.com/abc-english-version/
連結須更新。:)
Delete你好 您的文章給對於剛入門的有我很大的幫助
ReplyDelete但想請問pinMode() 這個內建的副函式放在Arduino資料夾的哪裡?我去找只有在Arduino.h中看到pinMode()的函式宣告,卻無法找到pinMode它是如何撰寫的。因為想知道底層AVR是如何做設定,所以有這個疑問,可否請您替我解答。
在\hardware\arduino\cores\arduino\wiring_digital.c裡。需知道AVR的register的用法,才能寫出pinMode()。
Delete謝謝,我照您提供的路徑找到了,我再去翻DATASHEET對照看一下,再次感謝。
Delete想用較低階的方式撰寫AVR程式的話,可參考Arduino Internals這本書。我個人都是用Arduino提供的程式庫,沒辦法跟你討論。
Delete謝謝你提供參考的書籍。我想還是會先摸熟Arduino提供的程式庫再往低階研究。(繼續參考你的分享 XD)
ReplyDelete除了我的部落格,也可以參閱Cooper Maa寫的入門文章http://coopermaa2nd.blogspot.tw/2011/05/arduino.html
DeleteArduino的書很多,中文的可看「超圖解Arduino互動設計入門」。
你好,想請問一下,小弟最近再用一塊血壓量測用的模組,那塊模組是uart的,不知道arduino要來控制那塊模組,然後接收他的量測值,我的作法是跟這篇範例依樣嗎??求解 ,以下附上了那塊量測模組的完整資料,還有那塊模組他已經自己做完類比轉數位了
ReplyDeletehttps://drive.google.com/uc?id=0B64QFv8eVz7DdGw4UFFqS1RsbWs&export=download
目前已經下單要購買擬推薦的超圖解arduino,不過還是先問問看
Delete通訊介面是UART,然後必須知道通訊內容的格式,在生理訊號量測平台使用手冊V2.0.pdf只有模組傳出的封包格式,在最後面幾頁。
Delete至於從主機(電腦、Arduino等)傳給模組的封包格式,似乎沒有記載在文件中,須自行參考範例裡的程式碼,範例裡以類似下列的程式碼傳出指令,代表切斷連線:
cData[0] = 0x41; // A
cData[1] = 0x54; // T
cData[2] = 0x23; // #
cData[3] = 0x44; // D
cData[4] = 0x53; // S
cData[5] = 0x43; // C
cData[6] = 0x0D; // CR
cData[7] = 0x0A; // LF
pSerial->SendData(cData , 8);
另外由類似底下的程式碼在接收後抽取出需要的資料(心跳、血壓等),
iBreath_Data = ucData[i+1];
iBreath_Data = iBreath_Data * 256 + ucData[i+2];
iBreath_Data = iBreath_Data * 256 + ucData[i+3];
iBreath_Data /= 6710 * 4;
使用Arduino的話,也是差不多的動作,但要改用Arduino的API。
另外,關於Arduino的入門書,也請參考拙作 Arduino輕鬆入門:範例分析與實作設計(http://yehnan.blogspot.tw/2014/02/arduino_21.html)。
比較不知道改由arduino控制該怎麼打程式,會跟原本差很多嗎
Delete準備欲傳送資料的部份、抽取接受到的資料的部份,應該都可套用範例裡的程式碼。
Delete其他部分,應該都不能用吧,必須改為Arduino的API。
大概了解 感謝你
Delete< 你好,想請問一下,小弟最近再用一塊血壓量測用的模組 >
Delete請問 蔡緯豫 前輩
我想找到血壓量測模組
但我google keyword 功力太差
在網路商店也找不到
所以想問到底 血壓模組的名稱
感謝你~
大大您好~方便留個連絡方式嗎 因為我寫了一個藍芽遙控俱紅外線避碰的程式,但是發現一啟動 它好像會跑一個退後停止的迴圈,且無法用藍芽操控
ReplyDelete有問題請留言,盡量回答。
Delete那我是不是可以把程式po上來給你看看是不是哪裡不恰當呢?
ReplyDelete請。
Delete另外也放到http://pastebin.com/,比較容易閱讀。
#include
ReplyDelete#include
Servo servoRight;
Servo servoLeft;
SoftwareSerial BTSerial(0, 1); // RX, TX
//byte dis[6]; //distance package
//int t,i;
int val; //temp value
int BTControl = 1;
void setup(){
pinMode(10,INPUT);pinMode(9,OUTPUT); //左邊紅外線發射接收器
pinMode(3,INPUT);pinMode(2,OUTPUT); //右邊紅外線發射接收器
tone(4,3000,1000); //蜂鳴器響起一秒
delay(1000);
Serial.begin(9600);
BTSerial.begin(57600); //BTSerial 9600,19200,38400,57600
servoRight.attach(12); //伺服馬達分別連接12與13腳位
servoLeft.attach(13);
//dis[0] = 65; //check value
}
void loop()
{
int irLeft=irDetect(9,10,38000); //呼叫紅外線副程式(左)
int irRight=irDetect(2,3,38000); //呼叫紅外線副程式(右)
if(irLeft == 0){ //左方有障礙物
Down(); //後退一秒
Stop();
BTControl=0;}
if(irRight == 0){ //右方有障礙物
Down(); //後退一步
Stop();
BTControl=0;}
//else{
//if(Serial.available()>0)
//{
val = Serial.read(); //藍芽讀值
if(BTControl == 0){ //避碰程式作用後,BTControl值為0
val = 's'; //將藍芽控制變數設為s
BTControl = 1; //更改BTControl變數為1(藍芽控制模式)
}
else if(BTControl == 2){ //藍芽程式左右轉後進入此迴圈
val = 'f'; //將藍芽控制變數設為f,轉彎後繼續直走
BTControl = 1; //更改BTControl變數為1(藍芽控制模式)
}
else{
switch(val)
{
case 'f': // 前進
Up();
break;
case 'b': // 後退
Down();
break;
case 'l': // 左轉後前進
Left();
Up();
BTControl=2; //下次迴圈將val變數更改為f,繼續向前走
break;
case 'r': // 右轉後前進
Right();
Up();
BTControl=2; //下次迴圈將val變數更改為f,繼續向前走
break;
case 's': // 停止
Stop();
break;
}
}
//}
//}
}
int irDetect(int irLedPin,int irReceiverPin,long frequency){ //從主程式讀取各參數值
tone(irLedPin,frequency,8); //紅外線發射器頻率38000
delay(1); //持續1ms
int ir=digitalRead(irReceiverPin); //偵測紅外線接收器狀態
delay(1); //持續1ms
return ir; //回傳感測器狀態(1or0)
}
int Up(void){
servoRight.writeMicroseconds(1300);
servoLeft.writeMicroseconds(1700);
delay(1000);
}
int Down(void){
servoRight.writeMicroseconds(1700);
servoLeft.writeMicroseconds(1300);
delay(1000); //視情況調整
}
int Right(void){
servoRight.writeMicroseconds(1700);
servoLeft.writeMicroseconds(1700);
delay(1000); //視情況調整
}
int Left(void){
servoRight.writeMicroseconds(1300);
servoLeft.writeMicroseconds(1300);
delay(1000); //視情況調整
}
int Stop(void){
servoRight.writeMicroseconds(1500);
servoLeft.writeMicroseconds(1500);
delay(1000); //視情況調整
}
你藍牙連接的腳位是0跟1,這不就是內建的序列埠嗎?
DeleteSoftwareSerial BTSerial(0, 1); // RX, TX
可是兩者的傳輸速率又不一樣?
Serial.begin(9600);
BTSerial.begin(57600);
然後卻又不使用BTSerial讀值?
val = Serial.read(); //藍芽讀值
> 但是發現一啟動 它好像會跑一個退後停止的迴圈,且無法用藍芽操控
請詳細說明執行時的情況。
建議你把Serial跟BTSerial分開,
當BTSerial收到東西時,也可以送到Serial,便可從序列埠監控視窗查看。
請問點選Tools(工具),確認Serial Port時, 沒辦法點選。編譯好的程式無法上傳到板子。檢查裝置管理員, Arduino Uno (COM3), 出現 "這個裝置無法啟動。 (代碼 10)" 自行更換Serial Port也不work, 請問該怎麼辦? 謝謝。
ReplyDelete應該是驅動程式沒安裝成功,到裝置管理員裡,在該裝置上頭按滑鼠右鍵,更新驅動程式,路徑指向Arduino軟體的子資料夾drivers。
DeleteThis comment has been removed by the author.
ReplyDelete請問
ReplyDeleteArduino每次儲存接收一個數、兩個ASC2碼、一個空格,共四位(連續的4個),但只有單個輸入(串列端口),大概需要哪些指令呢? 有沒有儲存後再拿出來合併用的程序嗎?是哪樣子?? 感謝
試試這套程式庫
Deletehttps://github.com/kroimon/Arduino-SerialCommand
自行定義指令,當收到某指令,就呼叫相對應的函式。
你好請問
ReplyDelete你知道哪裡可以有人為人解釋arduino code的嗎, 付費諮詢的也可以 ,
有一組手電同程式很想做來實驗 ,但看不懂程式 ,國外公開的網站的分享沒有版權問題
麻煩你 無限感激
聯絡:eddie5492001t@yahoo.com.tw
不知道耶。去接案的網站找找囉。
Delete你好我是arduino初學者,我想請問有辦法按鈕持續按壓led亮起,放開時led熄滅換另一個led亮起
ReplyDelete有。
Delete你想要的行為,還不夠清楚,一開始的LED狀態是什麼,都熄滅嗎?
另一個led亮起後,若再按按鈕,會怎樣?
程式先寫寫看吧。
一開始2個燈都沒亮,按下按鈕一直按著的狀態Led1亮led2一就暗,放開按鈕led1暗led2亮
Delete嗯,加油。
Delete葉難大大你好
ReplyDelete我最近在嘗試FIRMATA協定 組合上 感測器
在反反覆覆的燒錄後 突然我的ARDUINO板無法燒錄了
IDE的序列阜 還是有讀取到 &ARDUINO板上的燈依然亮著
以下是錯誤訊息
avrdude: stk500_paged_load(): (a) protocol error, expect=0x10, resp=0x86
avrdude: stk500_cmd(): programmer is out of sync
avr_read(): error reading address 0x0000
read operation not supported for memory "flash"
avrdude: failed to read all of flash memory, rc=-2
avrdude: stk500_disable(): protocol error, expect=0x14, resp=0x00
avrdude: stk500_disable(): protocol error, expect=0x14, resp=0x00
第一行的resp=0x86 的0x86有跑過很多其他數字0x18 0x1c等等
想請問葉難大大有沒有甚麼方式能確認是否哪邊出問題
> 突然我的ARDUINO板無法燒錄了
Delete原本好的,後來出問題,嗯,中間改了什麼?
我沒遇過你的錯誤訊息,看字面上的意思,
應該是Arduino IDE的燒錄程式,無法跟Arduino板子溝通了,
所以出現「programmer is out of sync」字樣。
1. 可能線壞了、品質不好。
2. 換USB埠。
3. 板子拿到別台電腦試試看。
4. 其他...
> 有沒有甚麼方式能確認是否哪邊出問題
其他方式都需要特別的儀器吧。