2015/03/03

Raspberry Pi釋放主控台序列埠(GPIO14,GPIO15)

之前曾透過序列埠登入Raspberry Pi主控台,但若序列埠想移做他用,譬如與別塊板子、別顆晶片溝通,該怎麼釋放掉呢?

我的環境是Raspberry Pi Model B+,作業系統Raspbian(2014-12-24-wheezy-raspbian.zip),先確定可從另一台電腦(Windows)透過序列埠登入主控台,看到如下畫面,有著ttyAMA0的字樣。
底下步驟可釋放掉rpi的序列埠:

編輯/etc/inittab檔,
$ sudo nano /etc/inittab

內容大概如下:

...省略...
# Example how to put a getty on a serial line (for a terminal)
#
#T0:23:respawn:/sbin/getty -L ttyS0 9600 vt100
#T1:23:respawn:/sbin/getty -L ttyS1 9600 vt100

# Example how to put a getty on a modem line.
#
#T3:23:respawn:/sbin/mgetty -x0 -s 57600 ttyS3


#Spawn a getty on Raspberry Pi serial line
T0:23:respawn:/sbin/getty -L ttyAMA0 115200 vt100


請在藍色那一行前頭加個「#」,代表註解掉,使其無作用。存檔離開。

另外,rpi開機時會把除錯訊息送往序列埠,若想關掉須修改另一支檔案/boot/cmdline.txt,
$ sudo nano /boot/cmdline.txt

其內容只有一行,但很長:
dwc_otg.lpm_enable=0 console=ttyAMA0,115200 console=tty1 root=/dev/mmcblk0p2 rootfstype=ext4 elevator=deadline rootwait

刪除其中的「console=ttyAMA0,115200」,其餘不動。存檔離開。舊版Raspbian若有「kgdboc=ttyAMA0,115200」,也一併刪除。

然後重開機,如此即可。接下來測試。讓個人電腦(Windows)與rpi透過序列埠溝通,互相傳送,傳輸設定如下:
  • Speed (baud rate): 9600
  • Bits: 8
  • Parity: None
  • Stop Bits: 1
  • Flow Control: None
rpi端執行minicom:
$ minicom -b 9600 -o -D /dev/ttyAMA0

離開minicom的按鍵是先按「Ctrl-a」再按「x」。

Windows端執行PieTTY或PuTTY,Serial line填入COM8(請查詢),Speed填入9600,
然後切換到「Serial」分頁,確認傳輸設定,便可開啟連線。
底下是minicom的畫面,看到從PieTTY傳來的字樣「hello how are you?」。
底下是PieTTY的畫面,看到從minicom傳來的字樣「I'm fine. Thank you.」。
另外,在Windows上除了PieTTY,也可使用Tera Term,記得到選單「Setup-Serial port...」設定。
在rpi端除了minicom,也可使用screen,指令是「$ screen /dev/ttyAMA0 9600」,離開的按鍵是「Ctrl-a」再按「k」。


參考資料:

7 comments:

  1. Anonymous25/8/15 01:55

    你好!

    不好意思,想請教關於raspberry pi 和arduino 透過USB 連接,傳送資料的問題。

    我想利用python-serial 透過USB傳送命令給 arduino ,並接收傳回的回應,可是我的程式在使用ser.write('1'),這樣的命令執行時,卻無法正確的將資料傳給 arduino。

    必須要在raspberry pi的桌面將arduino的IDE 上的序列埠監控視窗打開,才能正確傳送資料給 arduino,或是執行minicom之後,raspberry pi才能正確的傳送資料。相同的程式在PC 上是沒有問題的。

    我有修改過/boot/cmdline.txt ,也修了inittab ,還有用minicom修改了arduino所在的ttyUSB0,可是只要重新開機,raspberry pi的serial port 就無法正確開啟,又要打開序列埠監控視窗或是執行minicom才能傳送資料。這樣有點困擾,可是別人好像並沒有這樣的問題。

    如果是要執行minicom,才能打開raspberry pi的serial port ,這樣我就把minicom設成開機自動執行,也能解決問題,可是如果在raspberry pi接上2個arduino的裝置,執行minicom來開啟raspberry pi 的serial port,好像也只會打啟最後使用的那個arduino 裝置,無法將2個arduino的裝置都開啟,這就有點奇怪,不知道是不是我有搞錯什麼地方。

    ReplyDelete
    Replies
    1. 你是要透過USB線的serial介面,不是透過GPIO的serial埠,沒錯吧?

      1. baudrate,兩邊設為相同了嗎?
      2. 你開啟的裝置名應該是/dev/ttyACM0或/dev/ttyUSB0吧?利用 'ls /dev/tty*'並拔除、重插線,來找出裝置名。
      3. 修改/boot/cmdline.txt 、inittab?這應該跟你的問題沒關係。
      4. 以root身分執行你的Python程式。

      Delete
  2. 請問我想用AMA0序列埠用藍牙接收Android手機的資料,我也是要做最前面部分的註解掉根刪除的修改嗎?
    然後在RPI上用minicom修改的Baudrate是修改藍牙裝置(HC-05)的Baudrate嗎?還是改RPI該序列埠本身的呢
    因為我在網路找很多方法幾乎都是用Arduino 透過AT mode去改HC05的Baudrate 但RPI好像不能用AT mode那我該怎麼用RPI去改呢?

    ReplyDelete
    Replies
    1. > 最前面部分的註解掉根刪除的修改嗎?
      既然你要把序列埠移作他用,yes。
      ps: rpi 3已經內建藍牙。

      > Baudrate
      序列介面兩端的baudrate必須相同,都要設定。
      HC-05會有個預設baudrate,需透過minicom把rpi的序列埠設為該baudrate,然後可依你的意思修改。

      > 但RPI好像不能用AT mode
      可以吧,為什麼不行?

      Delete
    2. 謝謝,了解了。
      這邊遇到一些問題,我是用python寫的:prot=serial.Serial("/dev/ttyAMA0",baudrate=9600)
      請問這段指令是否就是設定rpi序列埠的baudrate呢,就是我有這段程式就不用進去minicom設定了對嗎?
      這指令是否也就是開啟序列埠呢?那如果我要用rpi修改HC-05的baudrate該怎麼進入他的AT模式設定?

      因為我現在是改rpi到HC05的預設baudrate:9600,用cmd window執行是沒問題,但因為我目標是設定成rpi開機自動執行程式,每次自動開機執行後,手機一傳值都會失敗出現錯誤訊息:
      line = port.read()
      File "/usr/local/lib/python3/dist-packages/serial/serialposix.py", line 470, in read
      raise SerialException('device reports readiness to read but returned no data (device disconnected or multiple access on port?)')
      serial.serialutil.SerialException: device reports readiness to read but returned no data (device disconnected or multiple access on port?)

      如果用command window執行程式,就多半不會有問題(有時也會失敗出現此訊息),想說是否是baudrate跟手機的問題
      我們檢查過接線是沒問題,搞了一個禮拜怎麼嘗試都還是一樣...請問這是甚麼原因呢?
      (PS:我的python 主程式)
      import serial
      import time
      from Movement import *

      reset()
      time.sleep(0.5)
      while 1:
      port=serial.Serial("/dev/ttyAMA0",baudrate=9600)
      data=port.read()
      if data[0]==70:
      forward()
      elif data[0]==76:
      TurnLeft()
      elif data[0]==82:
      TurnRight()
      else:
      print("input error")

      Delete
    3. > 我是用python寫的:prot=serial.Serial("/dev/ttyAMA0",baudrate=9600)
      > 請問這段指令是否就是設定rpi序列埠的baudrate呢,
      > 就是我有這段程式就不用進去minicom設定了對嗎?
      minicom是別人寫好的程式,可連接序列埠,
      要連接序列埠需設定baudrate,
      正確地說,是設定你想以多少baudrate進行傳輸。

      你用python使用pySerial程式庫連接序列埠,
      也就是你自己寫出類似minicom的程式,可連接序列埠。
      自然不用再去管minicom。

      > 這指令是否也就是開啟序列埠呢?
      yes

      > 那如果我要用rpi修改HC-05的baudrate該怎麼進入他的AT模式設定?
      HC-05的baudrate,工廠預設值可能是9600或38400,看啟動模式而定。

      HC-05若快速閃爍(一秒閃兩次),代表未連線;
      升高WAKEUP(有可能標示為key或其他文字)腳位的電壓,可進入at模式。詳情請見HC-05的手冊。

      Delete
    4. > 請問這是甚麼原因呢?
      不知道。

      如果你是rpi 3,
      因為pi3的UART被拿去給藍牙使用,需要做點設定、修改,請到網路上找找。

      恩,把
      port=serial.Serial("/dev/ttyAMA0",baudrate=9600)
      移到while之外,
      試試吧。

      Delete