2013/01/17

Arduino撰寫自己的程式庫

不論是哪套軟體開發平台,一定會有程式庫(也可能以元件庫、類別庫、軟體開發框架的形式出現)的概念,其功用就是把某功能寫好包裝起來,隱藏細節,方便大家運用。

Arduino軟體開發環境內建了一些常用程式庫,諸如LiquidCrystal、Servo、SoftwareSerial、SPI、等等,有了它們,便只需在較抽象較上層的階級對該功能有所了解即可,不必完全知曉底層複雜的技術。

另外也有很多人將開發出來的Arduino程式包裝成程式庫開放給大家使用,譬如Dr. Monk的Timer、存取1-Wire匯流排協定的OneWire、讀取Dallas溫度感測器的DallasTemperature、解決按鈕訊號在高低電位之間彈跳Bounce、等等,

這篇的主題是撰寫自己的Arduino程式庫,將功能包裝後變成程式庫,隱藏底層細節、提供較簡易的介面,供別的專案使用,甚至供其他人使用。

首先以底下這份草稿碼,以PWM讓LED漸亮、漸暗、不斷循環,我稱之為呼吸燈。

詳情就不解說了,請參考我寫的Arduino練習:呼吸燈

int brightness = 0;
int fadeAmount = 5;
int delayDuration = 30;

void setup()  {
  pinMode(9, OUTPUT);
}

void loop()  {
  analogWrite(9, brightness);
  brightness = brightness + fadeAmount;
  if (brightness <= 0 || brightness >= 255) {
    fadeAmount = -fadeAmount ;
  }  

  delay(delayDuration);                          
}

好,那如果想要有三個呼吸燈呢,程式會變得很複雜吧。當然啦,其實可使用計時器的程式庫,譬如Dr. Monk的Timer,就能寫出簡單易懂的程式碼,不過這篇要介紹的是自行撰寫Arduino程式庫,所以讓我寫個程式庫,將以上的程式碼包起來,方便使用。

Arduino程式庫有兩個地方,一個是內建的,我們不動它,另一個是自己安裝的,這個程式庫的目錄在sketchbook底下的libraries(若無請自行建立)。

在libraries底下新增目錄,命名為PwmLed,這就是我將撰寫的程式庫的位置,裡面放進PwmLed.cpp與PwmLed.h,這是程式庫的主體,內容如下。

(咳咳,我就不解釋C++程式語言了。)

首先是PwmLed.h:

#ifndef PwmLed_h
#define PwmLed_h

#include <inttypes.h>

class PwmLed
{

public:
  unsigned long m_lastTime;
  uint8_t m_pin;
  int m_brightness;
  int m_fadeAmount;
  unsigned long m_delayDuration;
 
  PwmLed(void);
  void set(uint8_t pin, int initBrightness, int fadeAmount, unsigned long delayDuration);
  void update(void);
};

#endif

內容很普通,就是一般的C++標頭檔。接下來是PwmLed.cpp:

// For Arduino 1.0 and earlier
#if defined(ARDUINO) && ARDUINO >= 100
#include "Arduino.h"
#else
#include "WProgram.h"
#endif

#include "PwmLed.h"

PwmLed::PwmLed(void)
{
}

void PwmLed::set(uint8_t pin, int initBrightness, int fadeAmount, unsigned long delayDuration)
{
    m_pin = pin;
    m_brightness = initBrightness;
    m_fadeAmount = fadeAmount;
    m_delayDuration = delayDuration;
   
    pinMode(m_pin, OUTPUT);
    analogWrite(m_pin, m_brightness);
    m_lastTime = millis();
}


void PwmLed::update(void)
{
    unsigned long t = millis();
    if(t > m_lastTime + m_delayDuration){
        m_lastTime += m_delayDuration;
       
        analogWrite(m_pin, m_brightness);
        m_brightness = m_brightness + m_fadeAmount;
   
        if (m_brightness <= 0 || m_brightness >= 255) {
            m_fadeAmount = -m_fadeAmount;
        }
    }
}

還可以再加入keywords.txt,指定程式庫的關鍵字,這麼一來,Arduino軟體開發環境的編輯器就能以不同顏色顯示。如下:

#######################################
# Syntax Coloring Map For Timer Library
#######################################

#######################################
# Datatypes (KEYWORD1)
#######################################

PwmLed    KEYWORD1

#######################################
# Methods and Functions (KEYWORD2)
#######################################

set    KEYWORD2
update    KEYWORD2

#######################################
# Instances (KEYWORD2)
#######################################

#######################################
# Constants (LITERAL1)
#######################################

libraries/PwmLed底下還可以放個examples目錄,存放範例,我就不管了。

程式庫至此已經準備完畢,請重新開啟Arduino軟體開發環境,應該就能在Sketch-Import Library...下看到PwmLed。

接下來就是使用了。

電路圖如下:

Arduino腳位9、10、11(具有PWM功能),各自接到220 ohm電阻、再接到LED長腳,LED短腳接地。


然後,使用PwmLed程式庫,讓三個LED變成呼吸燈的草稿碼如下:

#include <PwmLed.h>

#define LED0 9
#define LED1 10
#define LED2 11

PwmLed led0;
PwmLed led1;
PwmLed led2;

void setup()  {
  led0.set(LED0, 0, 5, 30);
  led1.set(LED1, 0, 10, 60);
  led2.set(LED2, 0, 30, 300);
}

void loop()  {
  led0.update();  
  led1.update();  
  led2.update();
}

先以set設定,參數第一個是PWM腳位,第二個是初始亮度,0不亮、255全亮,第三個是每次更新亮度時的更新幅度,越小代表變化會越平順,第四個代表更新頻率,單位是千分之一秒,越小代表越快更新。聽起來很複雜,但換換數字看看結果就清楚了。

然後在loop()裡以update更新亮度。

很簡單吧!

原始碼可到這裡下載。


參考資料:

90 comments:

  1. 葉大,
    想請問一個問題,
    我將 include 的檔案修改了部份,
    但在重新 compile 的時候卻還是跑舊的 include 檔案
    請問我要如何修改?

    目前的改法是在 .h 和.cpp 檔案中,加入 #if WITH_AAA ... #endif
    照理說 compile 時應該會略過,
    第一次修改時有成功,於是我就想說改一下 WITH_AAA 的值讓它跑看看
    所以我就多加了 #define WITH_AAA true
    結果從此以後 compile 都會進入#if WITH_AAA ... #endif
    就算我把 #define 的部份拿掉都一樣,
    甚至我把 #if 區段裡的 Code 全刪了,結果還是一樣可以compile ...

    請問是否 Arduio 會把 #define 的值做記錄?
    還是會另外將 compile 的檔案做暫存並重覆使用??

    ReplyDelete
    Replies
    1. Arduino開發環境應該沒有預先編譯.h檔(precompiled header)的功能。所以不會把#define的值做記錄。

      當你多加了#define WITH_AAA true後,WITH_AAA就是有定義了(就算改成false也算是有定義),自然從此以後都會進入#if WITH_AAA ... #endif。
      但是為什麼你拿掉#define後還是一樣,從你給的資訊,我看不出來原因。

      還是請你再多給些資訊吧,檔案的內容?

      Delete
  2. 葉大
    不好意思,我找到原因了!

    原因是我在改 .h .cpp 檔之前,
    有先將arduino-1.0.5\libraries\下的要修改資料夾備份,
    所以第一次會成功是因為我將 Arduino 的 IDE 程式開啟後並沒有關閉,
    然後直接改arduino-1.0.5\libraries\下的資料夾檔案
    第一次 compile 成功,
    再來加入 #define XXXX 後也可以正常將 #if XXXX 的區段進行 Compile
    但後來 IDE 程式關閉後再重新 Compile 都無法跳過 #if 區段,
    因為我的arduino-1.0.5\libraries\資料夾下一直存在原來的資料夾,(雖然資料夾的命名不同,但還是會抓到舊的內容。)
    我將舊內容的資料夾刪除後,
    重新 Compile 後就又可以跳過 #if XXXX 區段了。
    目前測試都正常。

    不好意思,浪費了葉大的保貴時間。

    ReplyDelete
    Replies
    1. 不會,不用客氣。

      Arduino IDE會在背地裡作一些動作,它應該會去掃描arduino-1.0.5\libraries\裡的各個子資料夾。

      Delete
    2. Anonymous2/4/15 15:17

      ...

      Delete
    3. Anonymous2/4/15 15:18

      ...

      Delete
  3. 想請問葉大
    程式中的自行安裝的程式碼
    是要去哪裡下載安裝
    因為我參考葉大的程式碼
    有些標頭檔我沒有
    如果下載好了那要放在哪一個資料夾
    還有.cpp檔需要用visual studio跑過一次還是直接放在資料夾裡就好

    ReplyDelete
    Replies
    1. 哪個標頭檔?哪個程式庫?

      > 要放在哪一個資料夾
      Arduino程式庫的資料夾,通常是sketchbook資料夾的子目錄libraries。

      > .cpp, visual stduio
      不用,放進去即可。

      Delete
    2. 跟WProgram.h相關的標頭檔我都沒有

      Delete
    3. Arduino 1.0版以前有WProgram.h,後來改名為Arduino.h。
      我不是用#if #else #endif處理了嗎?

      Delete
  4. Anonymous17/9/15 11:16

    葉大您好:
    我想請問您有使用過DFPlayer_Mini_Mp3這個模組嗎?
    因為我想使用ARDUINO去控制兩塊DFPlayer_Mini_Mp3
    單一塊控制可,但卻無法同時使用兩塊,該如何撰寫程式解決這個問題呢?

    ReplyDelete
    Replies
    1. 沒有。

      但是看起來似乎可以。

      Delete
    2. Anonymous17/9/15 11:28

      http://www.dfrobot.com/wiki/index.php/DFPlayer_Mini_SKU:DFR0299
      那應該如何解決呢?

      Delete
    3. 可能電源不足?可能程式裡關於SoftwareSerial的部份沒寫對?可能因為delay而導致與模組間的通訊出錯?等等...

      我沒有該模組,建議你或許直接向原廠索要範例。

      Delete
    4. Anonymous17/9/15 13:45

      好,謝謝!!
      另外我想請問!!如何使用MEGA板控制兩組TX、RX??

      Delete
    5. mega版不是有很多硬體序列埠(RX與TX)?有什麼問題嗎?

      Delete
  5. 葉大你好~
    小弟有問題想請教大大
    我使用Arduino UNO版,配合L298n控制馬的達正反轉
    想把此功能像內文所說的一樣,把功能包裝起來,並在執行C++的程式中使用
    但很多東西並不知道在哪裡,我該如何創建一個這樣的功能,能讓C++把library掛進來,然後執行程式

    ReplyDelete
    Replies
    1. 我這篇有點舊了,雖然內容還是對的,但已經不算完整。
      建議參考官方文件https://www.arduino.cc/en/Hacking/LibraryTutorial

      > 但很多東西並不知道在哪裡
      什麼東西?

      > 我該如何創建一個這樣的功能,能讓C++把library掛進來,然後執行程式
      聽不太懂。

      Delete
    2. 比如說像大大所說的sketchbook及怎麼會跑出一個CPP檔
      內容很普通,就是一般的C++標頭檔。接下來是PwmLed.cpp:

      // For Arduino 1.0 and earlier
      #if defined(ARDUINO) && ARDUINO >= 100
      #include "Arduino.h"
      #else
      #include "WProgram.h"
      #endif

      #include "PwmLed.h"

      PwmLed::PwmLed(void)
      {
      }

      void PwmLed::set(uint8_t pin, int initBrightness, int fadeAmount, unsigned long delayDuration)
      {
      m_pin = pin;
      m_brightness = initBrightness;
      m_fadeAmount = fadeAmount;
      m_delayDuration = delayDuration;

      pinMode(m_pin, OUTPUT);
      analogWrite(m_pin, m_brightness);
      m_lastTime = millis();
      }

      大大所說的這個Cpp檔是怎麼出現的?
      .h檔還知道在哪邊,但Cpp檔要去哪找我就不清楚了
      因為我洗忘我能把驅動馬達的功能包裝起來visual C++可使用
      比如給他某些指令,那麼他就能相對給我在Arduino上包裝好的馬達正反轉的功能

      Delete
    3. > 這個Cpp檔是怎麼出現的?
      我寫的啊。

      > 包裝起來visual C++可使用...
      還是不懂你的問題。

      Arduino為什麼提到visual C++?
      你是要「撰寫C++程式在Windows上跑」,而且能夠跟「Arduino」溝通嗎?

      Delete
    4. 是的,誠如大大所說想撰寫C++程式在Windows上跑,而且能夠跟Arduino溝通,想讓C++去控制Arduino的功能

      Delete
    5. 你說的跟這篇文章(Arduino撰寫自己的程式庫)沒什麼關係吧。

      那麼你的Windows電腦跟Arduino之間,採取什麼連接方式呢?乙太網路、Wi-Fi、序列埠?

      若是序列埠的話,一般Arduino開發板使用USB線連接電腦。
      在Windows電腦上撰寫C++程式,需要能夠存取序列埠的程式庫,便能寫入、讀取資料。
      而Arduino端就跟平常一樣,使用Serial存取序列埠。

      能夠收發資料後,也就是能夠溝通了。

      Delete
    6. 是用序列埠,我分別兩有個程式,一個用C++開啟攝影機的,一個是用Arduino控制馬達的,想要把這兩者結合在一起,只需要執行C++那個開啟攝影機的程式碼,也能同時執行控制馬達的功能,想請問葉大,我是需要用什麼樣的方式,能夠達到此效果

      Delete
    7. 你需要一套Windows上的、C++語言的序列埠程式庫,
      譬如http://playground.arduino.cc/Interfacing/CPPWindows,

      讓C++程式與Arduino程式雙方能夠溝通。大概如下:

      你在Windows上的C++程式 - 該程式庫 - 存取Windows的序列埠 - 連接到Arduino的序列埠 - Arduino程式

      Delete
  6. 感謝葉大,您推薦的方法我已經嘗試且成功了,但是感覺跟我自己當初想的不太一樣,再請教大大,如果我想將arduino的功能,完全用c++程式編譯,像是把程式寫進去或掛進去,一旦編譯完成後可開啟鏡頭及控制馬達,且還能不需要透過serial port去連接,這想法是可行的嗎? 我要用什麼樣的方式可以完成這個想法

    ReplyDelete
  7. 感謝葉大,您推薦的方法我已經嘗試且成功了,但是感覺跟我自己當初想的不太一樣,再請教大大,如果我想將arduino的功能,完全用c++程式編譯,像是把程式寫進去或掛進去,一旦編譯完成後可開啟鏡頭及控制馬達,且還能不需要透過serial port去連接,這想法是可行的嗎? 我要用什麼樣的方式可以完成這個想法

    ReplyDelete
    Replies
    1. > 不需要透過serial port去連接
      那你要透過什麼連接?
      你的電腦跟Arduino板子,兩個裝置,要怎麼連接?

      Delete
    2. 了解~也就是說要使用arduino功能,依舊需要互相連接才能辦得到,還是說我們能將arduino的程式碼轉換成c++的,讓c++讀得懂? 那如果說我們一樣透過serial sport做連接,但是能一執行c++程式後,arduino控制馬達的功能能不透過手動方式開啟及控制,可以一旦程式執行後就自行啟動,這是否要先在把這功能寫在arduino都程式碼那,還是我們能寫在c++內,然後呼叫這功能?

      Delete
    3. arduino的程式碼就是C++程式碼。
      但arduino的CPU是AVR架構,你用virtual c++編譯出來的東西(如果可以編譯的話),arduino無法執行。

      > 這是否要先在把這功能寫在arduino都程式碼那,還是我們能寫在c++內
      都可以,由你決定。

      Delete
    4. 你的馬達連接到Arduino,也只有Arduino能控制它。

      你的C++程式在Windows電腦上,一定要透過某種連線,傳送指令給Arduino,叫Arduino控制馬達。

      我想你需要的是更高階的程式庫,譬如Firmata。

      Delete
    5. 恩恩,我照著葉大的建議去搜尋firmata但是載下來後,這幾天,爬了不少文,還是不知道怎麼用
      可否請葉大告訴我流程,如何用C++透過firmata控制Arduino的功能,東西要放在哪裡,或者要更改那些地方

      Delete
    6. 我只用過Python版本的Firmata,可參閱
      http://yehnan.blogspot.tw/2016/01/arduinowindowspythonfirmataarduino.html

      流程如下:
      Arduino端要燒錄能接收、解析Firmata訊息的草稿碼,例如內建範例草稿碼StandardFirmata。

      電腦端要下載安裝Firmata(假定你需要的是C++版),然後撰寫C++程式,使用Firmata的API,傳送訊息給Arduino、操控腳位。

      Delete
    7. 葉大python使用firmata一定要安裝pip嗎?

      Delete
    8. This comment has been removed by the author.

      Delete
    9. > python使用firmata一定要安裝pip嗎?
      使用pip最方便啊。

      pyFirmata已經包裝成Python模組,使用pip的話,就能輕鬆安裝,這也是正統的安裝方式。

      否則,請看https://github.com/tino/pyFirmata,
      你可以自己下載手動安裝。

      Delete
  8. 葉大,不好意思,我真的看不懂PIP安裝教學阿~~~~@@?
    到底在寫什麼,一點下去全部都是程式碼,東西要放哪要按哪真的不知道.........
    可否教一下到底怎麼安裝,網路上的不知道在寫什麼..........

    ReplyDelete
    Replies
    1. 現在的Python實作,不是都已經預設包含pip了嗎?

      若要自己安裝,請看https://pip.pypa.io/en/stable/installing/

      我就算寫,也不會超越官方文件。

      Delete
    2. > 您推薦的方法我已經嘗試且成功了
      你之前不是已經使用C++與序列埠的方式嗎,而且成功了。
      為什麼不使用C++版的Firmata?

      現在你要換成python嗎?

      Delete
    3. 是嘛? 我是安裝2.7.5版本,裡頭也已經有了? 如果有了 我接著只要照大大給我的網只安裝firmata即可?
      是阿~ 因為看不懂firmata如何安裝在C++,網路上找了好多文,完全都不知道他們在寫什麼
      要安裝也不知道放哪裡.....,然後有些又只有講一半=="結果就出來了,不詳細,照作她們給的流程安裝了也是錯誤......
      想說這樣還不如改成大大的python,大大懂,我也比較好問~

      Delete
    4. 2.7.5版沒有。自2.7.9或3.4版起才預設內建pip。

      > firmata如何安裝在C++
      嗯,我找了一下,的確不容易,可能要安裝openFrameworks吧。

      > 改成python
      是嗎?應該要選你會的語言吧。要不然怎麼開發?

      Delete
    5. 葉大,我重新安裝python,安裝2.7.11版本,裡頭已經安裝好PIP了
      也照著大大的說明安裝好pyfirmata了
      但後面的我就看不懂了
      然後進入Python shell,匯入模組: (這個是要開啟IDLE輸入的嗎?)後面這些程式碼我要輸入在哪邊?
      $ python
      >>> from pyfirmata import Arduino, util

      傳入埠號,開啟序列埠裝置。從Arduino IDE的選單裡,可看到我的UNO板連接到電腦的COM3,若是在Windows的命令提示字元底下,應傳入'COM3';而若是在Cygwin裡,會被命名為裝置/dev/ttyS2:
      >>> board = Arduino('COM3')

      然後運用API,傳出Firmata訊息,控制腳位13(LED):
      >>> board.digital[13].write(1)
      >>> board.digital[13].write(0)
      便可看到LED被點亮與熄滅。

      如果沒有安裝API的東西,大大有沒有推薦比較好用或淺顯易懂容易讓新手上手的?

      Delete
    6. 葉大,我重新安裝python,安裝2.7.11版本,裡頭已經安裝好PIP了
      也照著大大的說明安裝好pyfirmata了
      但後面的我就看不懂了
      然後進入Python shell,匯入模組: (這個是要開啟IDLE輸入的嗎?)後面這些程式碼我要輸入在哪邊?
      $ python
      >>> from pyfirmata import Arduino, util

      傳入埠號,開啟序列埠裝置。從Arduino IDE的選單裡,可看到我的UNO板連接到電腦的COM3,若是在Windows的命令提示字元底下,應傳入'COM3';而若是在Cygwin裡,會被命名為裝置/dev/ttyS2:
      >>> board = Arduino('COM3')

      然後運用API,傳出Firmata訊息,控制腳位13(LED):
      >>> board.digital[13].write(1)
      >>> board.digital[13].write(0)
      便可看到LED被點亮與熄滅。

      如果沒有安裝API的東西,大大有沒有推薦比較好用或淺顯易懂容易讓新手上手的?

      Delete
  9. 大大,我重新安裝python,版本2.7.11,裡面已經有PIP了
    也照著大大的流程安裝好pyfirmata,只是後面這邊看不太懂

    然後進入Python shell,匯入模組:(是要開啟python的IDLE,輸入進去嗎? 我輸入後顯示錯誤)
    $ python
    >>> from pyfirmata import Arduino, util

    傳入埠號,開啟序列埠裝置。從Arduino IDE的選單裡,可看到我的UNO板連接到電腦的COM3,若是在Windows的命令提示字元底下,應傳入'COM3';而若是在Cygwin裡,會被命名為裝置/dev/ttyS2:
    >>> board = Arduino('COM3')

    然後運用API,傳出Firmata訊息,控制腳位13(LED):
    >>> board.digital[13].write(1)
    >>> board.digital[13].write(0)

    便可看到LED被點亮與熄滅。
    以上那些程式碼要打在哪裡? 我沒有安裝任何API的東西還能啟動控制Arduino的機制嗎?
    大大有沒有比較推薦或是容易上手的API給我這新手學習?

    ReplyDelete
    Replies
    1. > 是要開啟python的IDLE,輸入進去嗎?
      呃,執行python指令進入Python的shell,然後便可輸入一行一行的程式碼。
      > 我輸入後顯示錯誤
      什麼錯誤?

      > 以上那些程式碼要打在哪裡?
      Python shell。

      > 我沒有安裝任何API的東西還能啟動控制Arduino的機制嗎?
      不透過軟體程式,你怎麼控制Arduino?

      > 大大有沒有比較推薦或是容易上手的API給我這新手學習?
      沒有。


      > 感謝葉大,您推薦的方法我已經嘗試且成功了,
      還沒使用Firmata之前,你不是已經成功了嗎?就使用那種方式不就好了。

      Firmata只是制定傳輸訊息的格式,如果你沒那麼多功能,簡簡單單地透過序列埠、使用一兩個byte當做指令傳過去,不就好了?

      Delete
    2. 葉大,經昨天實驗,我已經能像大大所說讓LED燈亮暗了,亦能用Python shell下達指令讓馬達正反轉
      想請教怎麼把這些功能寫進欲執行的程式中? 比如:我想開啟鏡頭後馬達也可以被控制著轉動,是否一樣要先用python程式透過serial port溝通然後再結合firmata下指令進而做到這效果,還是只需要用到serial port跟Arduino溝通就可以控制了?

      Delete
    3. > 能用Python shell下達指令讓馬達正反轉
      > 想請教怎麼把這些功能寫進欲執行的程式中?
      在Python shell裡下達的指令,都是Python程式碼。

      Delete
    4. > 就可以控制了?
      不懂你想問什麼。

      Delete
    5. 所以說 我只要把那些指另寫進成事當中就可讓控制馬達的?
      就是說,現在已經用firmata了,可以直接用python控制馬達,
      那在撰寫程式中我是否還是必須先透過serial port開啟跟Arduino溝通,然後才可以用firmata下達指令
      或者直接撰寫程式碼,不需要再透過serial port的溝通,直接就可以控制了

      Delete
    6. > 現在已經用firmata了,
      對。

      > 可以直接用python控制馬達,
      你不是已經
      > 亦能用Python shell下達指令讓馬達正反轉
      了嗎?

      Firmata自己會開啟serial port。

      Delete
  10. 請問
    .cpp及.h檔要用什麼程式寫在存檔,我用arduinoIDE不行
    謝謝

    ReplyDelete
  11. 請問
    .cpp及.h檔要用什麼程式寫在存檔,我用arduinoIDE不行
    謝謝

    ReplyDelete
    Replies
    1. > 我用arduinoIDE不行
      可以。

      點按IDE右邊的「向下箭頭」,選擇「新增標籤」,就可以新增檔案,副檔名由你自取。

      Delete
  12. 用arduino IDE直接存和新增的檔案只能用arduino IDE開啟才找的到檔案 從C:無法找到檔案這樣正常嗎
    謝謝

    ReplyDelete
    Replies
    1. 草稿碼都放在草稿碼簿裡,
      檔案-偏好設定-草稿碼簿的位置。

      Delete
  13. 葉大 不好意思 您有在教人怎麼撰寫Arduino的GPS程式嗎,因為看的不是很懂TinyGPS的函式庫,只需要入個門就好,因為我還是新手,
    網路上也比較少在教,我使用的是PAM-7Q GPS Module不知道跟其他GPS Module的程式差很多嗎
    我的e-mail : y1y1y1gv23@gmail.com 打擾了!

    ReplyDelete
    Replies
    1. > 教人
      沒有。

      TinyGPS函式庫有範例程式,找找關鍵字「PAM-7Q arduino」,也有一些示範用的程式,如parallax網站。雖然不多。


      Delete
  14. 葉大您好,

    請問我要使用一個現有市售的5相步進馬達及其驅動器, 有沒有其合適的Library 可以直接下pulse, 正反轉, 速度等, 或是我需要用現有的library 去改?

    ReplyDelete
    Replies
    1. 基本的程式庫,用Arduino內建的Stepper,
      https://www.arduino.cc/en/Reference/Stepper

      不行嗎?

      Delete
    2. 謝謝您的回覆, 我對這個很不熟, 我是直接用馬達的驅動器, 上面有 CW(PLS)+, CW(PLS)-, ccw(DIR)+,ccw(DIR)- , 這個也可以用嗎?

      Delete
    3. 沒用過。
      如果是他自製的驅動器,他應該有自己制訂的訊號規格吧。

      Delete
  15. Driver 是東方馬達CRD503-K.
    DRIVER 路徑: (為簡體, 繁體需要登入才能下載)
    http://fs1.gongyeku.com/data/usershare/2013-4/20130419122347.pdf
    麻煩您看一下, 謝謝!

    ReplyDelete
    Replies
    1. 呃,無法回答你的問題。雖然我有一點點經驗,但都是使用別人準備好的控制器(加上東方馬達的馬達與驅動器)。

      從你給的文件看來,裡面
      [ CW (脉冲)、 CCW (旋转方向)脉冲信号输入]
      的那一頁,
      看起來CW要輸入脈衝訊號,輸入一次,馬達就轉一步,
      CCW則是旋轉方向。

      至於CW-與CCW-,應該是要輸入代表負邏輯電位。不確定。

      文件裡還說,分為單脈衝輸入方式、雙脈衝輸入方式,呃,自己研究吧。呵呵。


      Delete
    2. const int cw = 13; // the number of the cw pin

      void setup() {
      pinMode(cw, OUTPUT); // initialize digital pin cw as an output.
      }

      void loop() {
      digitalWrite(cw, HIGH); // turn the cw on (HIGH is the voltage level)
      delay(5); // wait for a second
      digitalWrite(cw, LOW); // turn the cw off by making the voltage LOW
      delay(5); // wait for a second
      }
      您說的沒錯,只要給個脈衝他就會走一步了; 我也試了, 逆時鑵轉就是給ccw+ 送一個脈衝. cw- 我是接到 ARDUINO 的 GND.
      我用上面的程式可以下給馬達轉了,只是是用程式本身的迴圈連續轉動.

      只是可否教我, 若是要送 1000個 pulse 要怎麼下呢? 還有如何調整送出的 pulse 的頻率呢? 感謝!

      Delete
    3. void sendPulse(int count, int d){
      int i;
      for(i = 0; i < count; i++){
      digitalWrite(cw, HIGH);
      delay(5);
      digitalWrite(cw, LOW);
      delay(5);

      delay(d);
      }
      }

      void loop() {
      sendPulse(1000, 100);
      }

      大概是這樣吧,count代表要送幾個脈衝,
      100代表脈衝之間要相隔100毫秒。

      Delete
    4. This comment has been removed by the author.

      Delete
  16. const int cw = 13;
    void setup() {
    pinMode(cw, OUTPUT);
    }
    void sendPulse(int count, int d) {
    int i;
    for (i = 0; i < count; i++) {
    digitalWrite(cw, HIGH);
    digitalWrite(cw, LOW);
    delay(1);
    }
    }
    void loop() {
    sendPulse(1000, 1);
    delay(5000);
    }

    可以控制了, 太感謝您了!
    我用上面的程式 馬達順時鐘轉2圈(1000pulse),停5秒, 再轉2圈...

    我打算用這種方式作可以用IR遙控的電動門, 開,關,開1/4 & 2/4 & 3/4,Jog 到任何點等功能... 若是成功後再po出來, 但依我對程式的瞭解會再一段長時間...

    ReplyDelete
  17. 請問一份 .ino 代碼越寫越長有沒有辦法像 C++ 那樣拆檔,直接拆貌似不行會讀不到 arduino的語言(serial之類的)
    只是想要把副程式的定義移出來的而已,還沒到要封裝成函式庫的程度

    ReplyDelete
    Replies
    1. 拆的話,別支檔案應該要加上 #include 小於符號 Arduino.h 大於符號

      Delete
  18. 您好,依照您的文章我創了一個自己的library,想問您是否有方法將library包起來,如MPLAB的.a檔,將.c檔刪掉一樣可以呼叫裡面的函示,找了很久但完全找不到相關的資料…,或者是否可以利用Arduino呼叫別的編譯器產生的副檔名?實在求助無門,謝謝

    ReplyDelete
    Replies
    1. 理論上可以,實際上有困難,再加上Arduino為開源專案,鼓勵開放原始碼。

      我只有在沒用Arduino IDE的狀況下,放入已編譯好的.a或.o,
      若要用Arduino IDE的話,沒做過。

      Delete
    2. 您好,所以若使用其他IDE呼叫.a檔,編譯並進行燒錄是沒問題的嗎?想問您是用哪個IDE,謝謝

      Delete
    3. 沒有IDE,而是使用make。

      Delete
    4. 抱歉,可以問一下make是什麼嗎…?謝謝

      Delete
    5. 在命令列下,寫好Makefile檔,裡面註明專案的原始檔案,編譯的指令,連結的指令,需要連結哪些程式庫,然後下指令make就會執行建置工作。
      請參考http://yehnan.blogspot.tw/2012/02/arduinowindowscygwin.html
      不過那篇很久了,後來Arduino IDE有過大改版,
      增加了命令列的建置環境,請參考 https://github.com/arduino/arduino-builder

      Delete
    6. 摁好的,非常感謝您,我再試試看!

      Delete
    7. This comment has been removed by the author.

      Delete
  19. 您好,我照您的文章將路徑改好,下"make depend"指令後出現錯誤,只有修改路徑還有晶片的部分,想問您是否遇過…謝謝
    下面是出現的錯誤
    Makefile:288: warning: overriding recipe for target 'C:/Program'
    Makefile:284: warning: ignoring old recipe for target 'C:/Program'
    Makefile:288: warning: overriding recipe for target 'Files'
    Makefile:284: warning: ignoring old recipe for target 'Files'
    if grep '^# DO NOT DELETE' Makefile >/dev/null; \
    then \
    sed -e '/^# DO NOT DELETE/,$d' Makefile > \
    Makefile.$$ && \
    mv -f Makefile.$$ Makefile; \
    fi
    echo '# DO NOT DELETE THIS LINE -- make depend depends on it.' >> Makefile
    #avr-gcc -M -mmcu=atmega16U2 -DF_CPU=16000000L -DARDUINO=100 -I. -IC:/Program Files (x86)/Arduino/hardware/arduino/avr/cores/arduino -IC:/Program Files (x86)/Arduino/hardware/arduino/avr/cores/arduino/../../variants/standard >> Makefile
    #avr-g++ -M -mmcu=atmega16U2 -DF_CPU=16000000L -DARDUINO=100 -I. -IC:/Program Files (x86)/Arduino/hardware/arduino/avr/cores/arduino -IC:/Program Files (x86)/Arduino/hardware/arduino/avr/cores/arduino/../../variants/standard BlinkMakefile.cpp >> Makefile
    for F in ; do \
    D=`dirname $F | sed "s/^\.\///"`; \
    echo -n "$D/" >> Makefile; \
    avr-gcc -M -mmcu=atmega16U2 -DF_CPU=16000000L -DARDUINO=100 -I. -IC:/Program Files (x86)/Arduino/hardware/arduino/avr/cores/arduino -IC:/Program Files (x86)/Arduino/hardware/arduino/avr/cores/arduino/../../variants/standard $F \
    >> Makefile; \
    done
    /bin/sh: -c: 列 3: 未預期的字組「(」附近有語法錯誤
    /bin/sh: -c: 列 3: `avr-gcc -M -mmcu=atmega16U2 -DF_CPU=16000000L -DARDUINO=100 -I. -IC:/Program Files (x86)/Arduino/hardware/arduino/avr/cores/arduino -IC:/Program Files (x86)/Arduino/hardware/arduino/avr/cores/arduino/../../variants/standard $F \'
    make: *** [Makefile:338: depend] Error 1

    設定的部分我改了
    MCU := atmega16U2
    INSTALL_PATH
    CORE
    BUILTINLIB
    SKETCHBOOK
    THIRDPARTYLIB
    還有鮑率的部分而已…

    ReplyDelete
    Replies
    1. 我上次留言有說:
      > 不過那篇很久了,後來Arduino IDE有過大改版,
      不確定那篇的作法是否還能用於新版Arduino IDE。

      > Makefile:288: warning: overriding recipe for target 'C:/Program'
      可能是因為你Arduino IDE安裝的地方,有很長的目錄名、含有空白。

      > atmega16U2
      這是哪款arduino板子?

      Delete
    2. 您好,我將Arduino重新安裝在D槽,288: warning這個不見了,但其他錯誤碼還是一樣。我是使用Mega2560,去網路上查是使用這顆atmega16U2晶片。

      Delete
    3. Mega2560用的晶片是ATmega2560,atmega16U2也是微控制器,但燒錄適當的韌體,作為USB轉序列埠功能。

      如果你真的要用我那篇古老的文章與做法,建議使用舊版的Arduino IDE。

      Delete
    4. 感謝您的幫助,最後選擇直接燒錄HEX檔

      Delete
  20. 你好 : 想請問您hal庫要如何同時操作兩組usart?
    因為只能寫一個usart_msp,那我第二組該從哪裡開啟

    ReplyDelete
  21. 您好葉大,最近想寫個MS5611氣壓計的SPI函示庫,我是使用GY63這顆模組,我是看照上面撰寫LIBRARY就ok了嗎,有沒有甚麼需要注意呢

    ReplyDelete
    Replies
    1. 這篇稍嫌過時,
      到網路上找找比較新的介紹文吧。

      Delete
  22. 您好葉大,請問如何打開修改他人寫好的arduino函式庫,是否有依些範例或教學可以參考

    ReplyDelete
  23. https://www.arduino.cc/en/Hacking/LibraryTutorial

    可參考的文件很少。

    ReplyDelete