星期一, 4月 17, 2017

Arduino筆記(二十二):LM393 光電對射式計數器模組測馬達轉速

[2017/04/16]
趁著今天休假,將小車的壓克力板切割出一塊約1cm * 3cm的區域,可以放置 20 柵格的測速轉輪,讓它不會卡在車板上。我買這個智慧小車模組時,沒有留意不能安裝測速的模組,連安裝 20柵格的輪子也不行,只好自己動手加以改造 (如下圖)。

智慧小車安裝完成後,因不確定使用兩個 18650電池 (7.4V) 的電壓可跑多快,只好加裝以 LM393 這顆 IC 為主的光電對射式測速模組,來測得輪子的轉速。以下是我用Arduino Mega安裝 L293D 馬達驅動擴展板,來驅動四個輪子,再用Arduino nano接 LM393測速模組,從監控視窗上得知目前輪子每分鐘轉幾圈,以下是執行的過程與結果:



[材料]

• Arduino Nano  x 1
• LM393 光電對射式計數器模組   x1
• 連接線 x 3
• 智慧小車模組 x1
• Arduino Mega x1
• L293D 馬達驅動擴展板 x1
• 18650 電池盒及電池 x2

[接線圖]

• LM393 光電對射式計數器模組連接線路
LM393 光電對射式計數器模組
Arduino
1 - VCC
VCC
2 - GND
GND
3 - D0
Pin 2
4 - A0
-


[程式]

unsigned int count=0;
int counterPin = 2;
unsigned long time2;
unsigned int rpm;      
unsigned int grid_num = 20;

void counter() {
   count++;
}

void setup() {
   Serial.begin(9600);
   pinMode(counterPin, INPUT);
   attachInterrupt(0, counter, FALLING);
   count = 0;
   rpm = 0;
   time2 = 0;
}

void loop() {
 if (millis() - time2 >= 1000){   /* 每秒更新 */
 
     // 計算 rpm 時,停止計時
     detachInterrupt(0);

     // 偵測的格數count * (60 * 1000 / 一圈網格數20)/ 時間差) 
     rpm = (60 * 1000 / grid_num )/ (millis() - time2)* count;
     time2 = millis();
     count = 0;
 
     // 輸出至Console
     Serial.print("RPM = ");
     Serial.println(rpm,DEC);
     //Restart the interrupt processing
     attachInterrupt(0, counter, FALLING);
  }
}

[執行結果]


[參考資料]

TAIWANIOT:LM393 光電對射式計數感測器模組 10mm槽寬

Share:

星期六, 4月 15, 2017

Raspberry Pi 筆記(四十):LCD 觸控螢幕開關

[2017/04/15]
自從買了微雪的LCD螢幕後,一直說要找時間學習如何在 Python 上撰寫 LCD 畫面觸控程式,一直到最近看Simon Monk的 Raspberry Pi Cookbook 第二版,才決定將 LCD裝上去,撰寫畫面程式來當作 LED 的開關,另外使用 Tkinter 的物件 Silder ,畫出一個拉桿的圖樣,透過數值的變化,改變 PWM 的數值,伺服馬達的角度也會隨著改變。


[材料]

• Raspberry Pi 2  x 1
• LCD  x 1
• LED  x 1
• 4.7K 電阻 x 1
• 伺服馬達 MG996R x 1
• 連接線 x 4
• 麵包板 x 1

[接線圖]

• LED燈正極接電阻,電阻再接 Pi 的 Pin 40
• LED燈負極接地,Pi 的 Pin 39 也接地
• 伺服馬達紅色線接電池正極,棕色線接地,橘色線接 Pi的 Pin 37

* 註:LCD是3.5吋的,上圖以2.4吋表示

[程式]

# -*- coding: utf-8 -*-
# 使用utf-8 編碼,這樣程式執行時才不會產生錯誤

from Tkinter import *
import tkFont
import RPi.GPIO as GPIO

GPIO.setmode(GPIO.BOARD)
GPIO.setup(40, GPIO.OUT)
GPIO.output(40, GPIO.LOW)

GPIO.setup(37, GPIO.OUT)
pwm = GPIO.PWM(37, 100)
pwm.start(5)

win = Tk()

# 使用仿宋體字型
myFont = tkFont.Font(family = 'fangsongti', size = 24)      

# 定義函數,當作開關,讓 LED明滅
def ledBtn():
        if GPIO.input(40) :
                GPIO.output(40,GPIO.LOW)
                ledButton["text"] = "LED 開"
        else:
                GPIO.output(40,GPIO.HIGH)
                ledButton["text"] = "LED 關"
# 結束程式
def exitBtn():
        GPIO.cleanup()
        win.quit()

# 依據Slider變更的值,傳給PWM當作 Frequency 的值
def rotate(angle):
        duty = float(angle) / 10.0 + 2.5
        pwm.ChangeDutyCycle(duty)

# 建立視窗
win.title("第一個 GUI 程式")
win.geometry('480x320')

# 建立離開按鍵
exitButton  = Button(win, text = "離開", font = myFont, command = exitBtn, height =1 , width = 6)
exitButton.pack(side = BOTTOM)

# 建立LED按鍵
ledButton = Button(win, text = "LED 開", font = myFont, command = ledBtn, height = 1, width = 6 )
ledButton.pack()

# 建立Slider Bar
scale = Scale(win, from_=0, to=180, orient=HORIZONTAL, command=rotate, length = 240)
scale.pack()

mainloop()


註:伺服馬達的位置是依據脈衝的長度而定的,伺服馬達期望每20毫秒收到一個脈衝,假使脈衝高於1毫秒,伺服機的角度就會為零,假使高於1.5毫秒,會停在中間位置,如果是高於2毫秒,就會在180度位置。本範例的PWM頻率為 100 Hz,亦即會每10毫秒送給伺服機一個脈衝,變數angle 轉換成介於 0 跟 100之間的值。

[結果]


[參考資料]

• Simon Monk:Raspberry Pi Cookbook 第二版
• Raspberry Pi  GUI Tutorial:Create your own GUI (Graphical User Interface) with TkInter and Python

Share:

星期一, 4月 10, 2017

Arduino筆記(二十一):電子羅盤 GY-273 / HMC5883L透過vPython 呈現立體圖

[2017/04/10]
最近在研究 Arduino 讀取電子羅盤 GY-273 / HMC5883L的座標,將讀取的座標顯示在Console上,只要使用Serial.print()就可以簡單做到,可是如果要呈現一個 3D的圖像,經由 GY-273座標值的改變,讓畫面上的3D圖樣也跟著轉動。在Arduino 的環境下,我不確定圖形介面的Scratch for Arduino (簡稱S4A)是否可以完成?

先前寫過一篇:「Arduino筆記(十三):使用Firmata 協定,Arduino 也可以執行 Python」,如果將 Arduino測得的資料,透過 PyMata 及 Python 的3D 函式庫,將結果呈現在螢幕上,應該是一個很不錯的想法。

另一個作法是將Arduino 測得的資料,透過 Serial Port單向傳給 Python,再由 Python根據接收的資料,改變圖形的形狀或角度。

在搜尋Python 繪圖庫的文件時,找到一個很容易就可以畫出3D圖形的程式: VPython,我試著用 Python 接收來自 Serial Port 的資料,結合座標軸,畫出立體的影像。以下就是在 Vpython畫出一個地球的畫面。


[vPython]

Vpython 是 Python 的一個套裝軟體,可以在螢幕上呈現出 3D 的圖形,包括球形體、長方體、彈簧、金字塔體、箭號等形狀,所有的圖形都以 3 維座標表示,並以向量控制位置或方向。
如有興趣可到以下 vPython 的文件網站,查詢相關指令:

網址是:http://vpython.org/contents/docs/

[pySerial]

pyserial程式的功能,是要讓 Python 程式透過 Serial Port (RS232) 來進行通訊傳輸。傳輸前需進行速率()設定程式下載位置及相關文件,可參考 pyserial 的網站:

網址是:https://pypi.python.org/pypi/pyserial/2.7

[材料]

• Arduino Nano  x 1
• GY-273 / HMC5883L   x1
• 連接線 x 4條

[接線圖]

•GY-273 / HMC5883L 電子羅盤模組連接線路
GY-273 / HMC5883L模組
Arduino
1 - VCC
VCC
2 - GND
GND
3 - SCL
Pin A5
4 - SDA
Pin A4
5- DRDY
-


[Arduino程式一]

以下是修改自Korneliusz Jarzebski的程式,產生一列X,Y,Z座標的數字,以逗號隔開。

#include <Wire.h>
#include <HMC5883L.h>

HMC5883L compass;

void setup()
{
  Serial.begin(38400);

  // Initialize HMC5883L
  while (!compass.begin())
  {
    delay(500);
  }
  
  // +/- 1.30 Ga: HMC5883L_RANGE_1_3GA (default)
  compass.setRange(HMC5883L_RANGE_1_3GA);

  // Set measurement mode
  // Continuous-Measurement: HMC5883L_CONTINOUS (default)
  compass.setMeasurementMode(HMC5883L_CONTINOUS);
 
  // Set data rate
  // 15.00Hz: HMC5883L_DATARATE_15HZ (default)
  compass.setDataRate(HMC5883L_DATARATE_15HZ);

  // Set number of samples averaged
  // 1 sample:  HMC5883L_SAMPLES_1 (default)
  compass.setSamples(HMC5883L_SAMPLES_1);
}


void loop()
{
  Vector raw = compass.readRaw();
  Vector norm = compass.readNormalize();

//  Serial.print(" Xraw = ");
//  Serial.print(raw.XAxis);
//  Serial.print(", ");
//  Serial.print(raw.YAxis);
//  Serial.print(", ");
//  Serial.println(raw.ZAxis);
//  Serial.print(" Xnorm = ");
  Serial.print(norm.XAxis);
  Serial.print(", ");
  Serial.print(norm.YAxis);
  Serial.print(", ");
  Serial.print(norm.ZAxis);
  Serial.println();  

  delay(100);
}

[Arduino程式二]

以下是修改自 Henry's Bench的 HMC5883 Arduino 程式,使用I2C讀取 HMC5883的暫存器,再利用位移的方式計算X,Y,Z座標的值。

#include <Wire.h>:        //I2C Arduino Library
#define addr 0x1E         //I2C Address for The HMC5883

void setup(){
  
  Serial.begin(38400);
  Wire.begin();
 
  Wire.beginTransmission(addr); //start talking
  Wire.write(0x02);             // Set the Register
  Wire.write(0x00);             // Tell the HMC5883 to Continuously Measure
  Wire.endTransmission();
}

void loop(){
  
  int x,y,z;      //triple axis data

  //Tell the HMC what regist to begin writing data into
  Wire.beginTransmission(addr);
  Wire.write(0x03);       //start with register 3.
  Wire.endTransmission();
 
  //Read the data.. 2 bytes for each axis.. 6 total bytes
  Wire.requestFrom(addr, 6);

  if(6 <= Wire.available()){
  
    x = Wire.read() <<8;    //MSB  x 
    x |= Wire.read();      //LSB  x
    z = Wire.read() <<8;   //MSB  z
    z |= Wire.read();      //LSB z
    y = Wire.read() <<8;   //MSB y
    y |= Wire.read();      //LSB y
  }
  
  // Show Values
  Serial.print(x);
  Serial.print(", ");
  Serial.print(y);
  Serial.print(", ");
  Serial.println(z);
  
  delay(10);
}   


打開Serial串列的視窗,已經可以看到座標值,如上圖。

接下來要在電腦端安裝 Python所需的軟體,包括 Serial 跟 vPython兩種。 vPython 分成32跟64位元兩種,且分為Python 2.7 跟3.2兩個版本,安裝時要對應 Python 安裝的版本,否則會產生錯誤。我是採用比較傳統的作法,安裝 Python 2.7.13 版,vPython安裝2.7-6.11,執行時沒有發生問題。以下是軟體取得的位址與安裝方式(略) :

(1) 下載安裝 Python 2.7.x 版 32位元程式 (目前最新是2.7.13) 。 下載後執行接著按「下一步」即可完成安裝。

(2) 下載安裝 PySerial 2.7 版 。下載後執行接著按「下一步」即可完成安裝。

(3) 下載安裝 VPython-Win-32-Py2.7-6.11 。下載後執行,會詢問Python 2.7的目錄,接著按「下一步」即可完成安裝。

完成上述安裝後,開啟「VIDLE for python」視覺化的開發環境(Python's Integrated DeveLopment Environment),輸入以下程式,按「F5」(Run Module)或是從視窗選單「Run」➔ 「Run Module」。

• 以下是Python 程式:

import serial         #import serial library
from visual import *  #import vPython library

scene2 = display(title='Examples of HMC5883L Triple Axis Digital Compass', x=0, y=0, width=600, height=600, center=(5,0,0), background=(0,0,0))
scene2.fullscreen = True

Earth = sphere(raduis = 100, material = materials.earth)      # print Earth
PosLabel = label(text='Position is: ', box=false, height=15)  # print position

sensorData= serial.Serial('com4',38400)    # Get data from serial port

while True:
    rate(50)    # Delay
    if (sensorData.inWaiting()>0):     

        textline = sensorData.readline()
        str2 = 'Position is: ' + textline
        Pos = textline.split(',')     

        xPos = float(Pos[0]) /100   
        yPos = float(Pos[1]) /100       
        zPos = float(Pos[2]) /100         
 
        Earth.pos = vector(xPos, yPos, zPos)
        PosLabel.text= str2


程式中有幾個要注意的地方:
•  我的 Arduino Serial 通訊埠是 COM4,如果不同時,記得要修改。
•  傳輸速率 38400 是我試過比較剛好的,在畫面上顯示3D的圖時,不會因畫面顯示來不及,而造成資料在背景儲存多筆在緩衝區。
•  xPos、yPos及zPos各除以100,是因為該數字常超過座標的值,造成程式錯誤中斷,除以100,可套用於目前座標中。

[執行結果]

看到一個地球及座標的畫面,會隨著HCM5883L的轉動而改變位置。


[後記]

在執行 Python 的過程中,使用 vPython 的 函數 sphere 畫一個地球,只要一行指令即可。但執行的過程中,都沒有改變地球的半徑 raduis 的值,可是在畫面上的地球,會忽大忽小的改變,一直讓我找不出原因。其次是地球只是在座標平移,而非真的做到 3D 的旋轉。還有座標的位置,我也常無法有效的控制物件所在位置,這些小地方還不熟悉,後續還有很大的努力空間。下次有些研究的心得再跟各位分享。

[參考資料]

• Henry's Bench:Arduino GY-273 HMC5883L Magnetometer Compass Tutorial
• github:jarzebski/Arduino-HMC5883L
• Palma Quarter:Using Python with Arduino
Share:

星期三, 4月 05, 2017

Arduino筆記(二十):DHT11、LM35 及DS18B20 的溫度值哪個比較準確?

[2017/04/05]
我一共有三個溫度感測元件,分別是DHT11 (可測溫度跟濕度)、LM35及 DB18B20。如果在同一地點測這三個元件的溫度,不知測得的溫度會一樣嗎?如果跟家裡有顯示溫度量測的時鐘或溫濕度計比較,不知哪個比較準?

以下是我們家有溫度顯示的時鐘、溫濕度計及三個元件讀取數值的照片。我們來看一下比較的結果如何?


[材料]

• Arduino Uno  x 1
• DS18B20 IC   x1
• TM35 IC  x1
• DHT11 x1
• 4.7K 電阻 x1
• 麵包板 x1
• 連接線 x n條
• 不同廠牌時鐘或溫濕度計 x3個

[接線圖]

本次檢測的主角照片:最左邊為DHT11、中間為LM35,最右邊為 DB18B20。

[LM35]

在執行程式時,我們使用 analogReference() INTERNAL的方法,來設定 Arduino 的參考電壓 (即用作輸入範圍最高的值)。使用這個設定的原因是 LM35只產生 0 到+ 1V的電壓,而將參考電壓設置為INTERNAL會將其設置為1.1V,也顯著提高了精確度。

在 loop() 中,從LM35讀取數值開始,然後將該讀數除以 9.31。除以 9.31的原因是類比讀數範圍為1024,參考電壓設定為1.1V,計算每一刻度的電壓值為 1.1/1024 = 0.001074V,即1.0742毫V。

LM35的技術規格中提到壓差每10毫V為1攝氏度,若將 10毫V / 1.0742毫V =  9.31,亦即將LM35 讀取的數值除以9.31,就是我們要的攝氏溫度讀數。

LM35有多種不同封裝型式。在常溫下,LM35 不需要額外的校準處理即可達到 ±1/4℃的準確率。靈敏度:10mV/℃,精度:0.5℃ (在+25℃時),測量溫度範圍:0℃ ~ 100℃。

[程式]

註:程式參考Onewire DS18x20 範例進行修改,加入LM35及DHT11測得的結果。
#include <onewire.h>
#include <dht11.h>

int DHTPin=5;
float DHT11temp, DHT11humi, LM35temp;
int LM35Pin  = 0;
int reading;

DHT11 dht11(DHTPin); 
OneWire  ds(4);         // Pin 4 連接 DS18B20 (4.7K resistor is necessary)

void setup(void) {
  Serial.begin(9600);
  analogReference(INTERNAL);   
  Serial.println("DHT11      LM35        DS18B20  ");
  Serial.println("================================");
}

void loop(void) {
  byte i;
  byte present = 0;
  byte type_s;
  byte data[12];
  byte addr[8];
  float DS18B20temp, fahrenheit;
  
  if ( !ds.search(addr)) {
    ds.reset_search();
    delay(250);
    return;
  }

  ds.reset();
  ds.select(addr);
  ds.write(0x44, 1);        // start conversion, with parasite power on at the end
  delay(1000);   

  // we might do a ds.depower() here, but the reset will take care of it.
  present = ds.reset();
  ds.select(addr);    
  ds.write(0xBE);         // Read Scratchpad

  for ( i = 0; i < 9; i++) {    // we need 9 bytes
    data[i] = ds.read();
  }

  // Convert the data to actual temperature
  // because the result is a 16 bit signed integer, it should
  // be stored to an "int16_t" type, which is always 16 bits
  // even when compiled on a 32 bit processor.

  int16_t raw = (data[1] << 8) | data[0];

  if (type_s) {
    raw = raw << 3;            // 9 bit resolution default
    if (data[7] == 0x10) {

      // "count remain" gives full 12 bit resolution
      raw = (raw & 0xFFF0) + 12 - data[6];
    }
  } else {
    byte cfg = (data[4] & 0x60);

    // at lower res, the low bits are undefined, so let's zero them
    if (cfg == 0x00) raw = raw & ~7;      // 9 bit resolution, 93.75 ms
    else if (cfg == 0x20) raw = raw & ~3; // 10 bit res, 187.5 ms
    else if (cfg == 0x40) raw = raw & ~1; // 11 bit res, 375 ms
    // default is 12 bit resolution, 750 ms conversion time
  }
  DS18B20temp = (float)raw / 16.0;

  // DHT11 
  int chk =  dht11.read(DHT11humi, DHT11temp);
  Serial.print(DHT11temp, 2);
  Serial.print(" C    ");   

  //LM35
  reading = analogRead(LM35Pin);
  LM35temp = reading / 9.31;   
  Serial.print(LM35temp);
  Serial.print(" C    ");
  
  // DS18B20
  Serial.print(DS18B20temp);
  Serial.println(" C  ");
}

[執行結果]

紅色鬧鐘:維持在 23.9 - 24.0度
白色溫濕度計:22.8 ~ 23.0 度
指針式溫濕度計:大約 23度
DHT11、LM35及DB18B20執行結果畫面如下:

由以上結果可以得到以下結論:

• 沒有傳統水銀式的溫度計做比較,無法得知傳統溫度計跟數位溫度計的比較。

• 白色溫濕度計跟指針式的結果比較接近。但與其他四個數值差異較大,無法得知其採用的晶片,就將該值當作參考。

• 看一下DHT11的規格表,溫度測量精度:±2℃、濕度測量精度:±5%RH、溫濕靈敏度:1℃ / 1%RH,從程式測得的結果,無法精確到小數點1至2位數。

• LM35從類比訊號取得溫度值,經過 analogReference() 換算後,提高溫度的精確度,結果跟DS18B20差不多,因為是類比數值換算,不會像DS18B20幾乎是固定的溫度值。

• DS18B20 測溫度穩且精確度高。

[參考資料]

• DHT11 library:Arduino Playground
• LM35:Arduino Playground
• PJRC:OneWire Library & DS18x20 Temperature Example
Share:

星期二, 4月 04, 2017

Raspberry Pi 筆記(三十九):使用 Docker 執行 python 的 gpio 控制 LED 燈

[2017/04/03]
由於硬體的發展迅速,如果在一部伺服主機上只安裝一套作業系統,會有點浪費資源。如果在該伺服主機的作業系統上再建立虛擬化主機,就可以充分應用硬體資源。常見的虛擬化系統,如VMWare、Hyper-V等都是虛擬化的應用。

安裝虛擬化系統之後,要啟動每個虛擬主機,需要分別安裝作業系統,分別執行不同的應用程式。這樣一來,每個虛擬化系統都會重複安裝作業系統,不僅浪費硬碟空間外,在效能上也是大打折扣。

Docker的技術,就是為了解決重複存放的作業系統及提升效能而產生的一種技術,將作業系統從每個虛擬化抽離出來,分別使用容器放置所需執行的服務或程式。

Docker在這幾年成為非常熱門的技術,到底跟虛擬化有什麼不同,以下圖表可瞭解兩者之間的差異:

圖片來源:Docker

Containers 跟 Virtual Machines兩者最明顯的差異是,虛擬機需要安裝作業系統 (Guest OS) 才能執行應用程式,而 Container 不需要安裝作業系統就能執行應用程式。Container 的技術透過共用 Host OS 的作法,取代虛擬化的 Guest OS,讓所需的硬碟空間小,執行的速度也比虛擬機快速。

要學習 Docker ,有三個重要的名稱一定要瞭解,包括:Image、Container及Repository。

• 映像檔(Image):就是一個唯讀的模板。Docker 執行容器前需要本地存在對應的映像檔,如果映像檔不存在本地,Docker 會從映像檔倉庫下載。

• 容器(Container):容器是獨立執行的一個或一組應用,以及它們的執行態環境,對應到虛擬機,類比執行一整套作業系統。Docker 的容器是從映像檔建立的執行實例,它可以被啟動、開始、停止、刪除。每個容器都是相互隔離的、保證安全的平台。

• 倉庫(Repository):是集中存放映像檔檔案的場所。倉庫分為公開倉庫(Public)和私有倉庫(Private)兩種形式。官方提供 Docker Hub 作為映像檔登錄及註冊(Registry),這是類似 Github 程式碼儲存服務。一個 Docker Registry 中可以包含多個倉庫(Repository);每個倉庫可以包含多個標籤(Tag);每個標籤對應一個映像檔。

[安裝Docker]

安裝Docker 很簡單,只要一行指令就可完成:
$ curl -sSL https://get.docker.com | sh
安裝完成的畫面:

安裝完成後,要將使用者 pi 加到 docker 群組:
$ sudo usermod -aG docker pi

• 開機時,自動執行 Docker:
$ sudo systemctl enable docker

• 重新開機後,手動執行 Docker daemon:
$ sudo systemctl start docker

$ sudo /etc/init.d/docker start

[Docker 指令]

• 搜尋 Docker Hub上可用的映像檔:
$ sudo docker search armhf

• 查詢 Docker上可用的映像檔:
$ sudo docker images

• 從倉庫取得所需要的映像檔。
$ sudo docker pull resin/rpi-raspbian

• 執行安裝映像檔
$ sudo docker run -ti resin/rpi-raspbian
-i 開啟標準輸出入(STDIN)
-t 配置一個虛擬終端機

• 移除本地端映像檔
$ sudo docker rmi -f resin/rpi-raspbian
  ** 注意 docker rm 命令是移除容器。

[在Docker 使用 gpio 控制 LED 燈]

先依照下圖,連接 LED 的兩隻接腳到 Pi的 Pin 9 跟 Pin 11。

[方法一]

(1) 先下載 hypriot/rpi-gpio 映像檔到容器內
$ sudo docker pull hypriot/rpi-gpio

(2) 確認一下gpio 是否正常被執行
$ sudo docker run --rm --cap-add SYS_RAWIO --device /dev/mem hypriot/rpi-gpio readall

(3) 設定 GPIO 0 為輸出 (上圖紅色框)
$ sudo docker run --rm --cap-add SYS_RAWIO --device /dev/mem hypriot/rpi-gpio mode 0 out

(4) 設定 GPIO 0,點亮 LED 燈
$ sudo docker run --rm --cap-add SYS_RAWIO --device /dev/mem hypriot/rpi-gpio write 0 on

(5) 設定 GPIO 0,讓 LED 燈熄滅
$ sudo docker run --rm --cap-add SYS_RAWIO --device /dev/mem hypriot/rpi-gpio write 0 off

[方法二]

使用 resin/rpi-raspbian的映像檔,安裝完成 python 及 gpio等程式後,再建立一個新的映像檔,再將閃爍 Led 的 Python 程式,包在另一個映像檔中執行。

(1) 在Docker中建立一個映像檔,需先建立一個目錄,在該目錄下建立一個檔名為 Dockerfile 的文字檔
$ mkdir gpio
$ cd gpio
$ nano Dockerfile

(2) 輸入文字檔內容:
FROM resin/rpi-raspbian:latest  
ENTRYPOINT []

RUN apt-get -q update && \  
    apt-get -qy install python python-pip \
        python-dev python-rpi.gpio
上述意義是要以 resin/rpi-raspbian 最後版本作為進入點,再繼續執行系統更新、安裝 python、python-rpi.gpio 等程式。

(3) 執行 Dockerfile 的安裝程式後,建立新的映像檔 gpio-test:
$ sudo docker build -t gpio-test .

(4) 編輯一個名為 led.py 的 Python 程式:
import RPi.GPIO as GPIO  
import time  
GPIO.setmode(GPIO.BCM)  
led_pin = 17  
GPIO.setup(led_pin, GPIO.OUT)

while(True):  
    GPIO.output(led_pin, GPIO.HIGH)
    time.sleep(1)
    GPIO.output(led_pin, GPIO.LOW)
    time.sleep(1)

(5) 再將 Dockerfile 的內容修改為:
FROM gpio-test:latest  
ADD ./led.py ./led.py

CMD ["python", "led.py"]

(6)再次執行 build,建立一個名為 blink 的映像檔:
$ sudo docker build -t blink .

(7) 執行 led.py 程式,給予 root 的權限:
$ docker run --privileged blink

此時,會看到 Led燈,每格一秒閃爍一次。

↺ 回到 Arduino & Raspberry pi 筆記目錄 ↺ 

[參考資料]

• GitBook / philipzheng:Docker -- 從入門到實踐
• Explosive stuff:Getting started with Docker on your Raspberry Pi
                               Let's get physical with Docker on the Raspberry Pi
• Alex Ellis Blog:Get Started with Docker on Raspberry Pi
Share:

星期日, 4月 02, 2017

Arduino & Raspberry Pi 筆記目錄

[2017/4/2]
天花板隨記原先是紀錄我生活的點點滴滴,擔心將來記憶力不好時,可以回顧一下過去的記錄。在偶然間遇到我喜愛的電子自動控制主題,開始了學習之旅,為了累積相關知識,我將 Raspberry Pi 樹莓派及 Arduino實做的過程及經驗紀錄下來,放在部落格上,一來當作筆記,二來與大家分享。

為了方便快速找到相關的章節,將所有目錄及連結整理在這篇文章,方便快速參閱。

[Raspberry Pi]

Raspberry Pi 筆記(四十三):Pi 也能當作Airplay音效輸出,安裝 Shairport Sync

Raspberry Pi 筆記(四十二):iPhone 雲端列印 AirPrint 

Raspberry Pi 筆記(四十一):安裝 Monitorix 監控工具

Raspberry Pi 筆記(四十):使用觸控螢幕當作 LED 開關及控制伺服馬達

Raspberry Pi 筆記(三十九):使用 Docker 執行 python 的 gpio 控制 LED 燈

Raspberry Pi 筆記(三十八):系統語系與中文輸入法

Raspberry Pi 筆記(三十七):遠端桌面 VNC、Teamviewer 及RDP

Raspberry Pi 筆記(三十六):光照度感測模組- 模擬特雷門

Raspberry Pi筆記(三十五):DS18B20 溫度紀錄- 使用 Cayenee 及 ThingSpeak

Raspberry Pi 筆記(三十四):ZBar 讀取二維條碼

Raspberry Pi 筆記(三十三):USB 音效卡如何進行錄音

Raspberry Pi 筆記(三十二):4路 TTP224 電容式觸控模組

Raspberry Pi 筆記(三十一):建立個人雲端儲存系統 (二) Owncloud

Raspberry Pi 筆記(三十):建立個人雲端儲存系統 (一) Tonido

Raspberry Pi 筆記(二十九):MCP3008 讀取搖桿值

Raspberry Pi 筆記(二十八):架設無線基地台 Wireless Access Point

Raspberry Pi 筆記(二十七):監測 Pi & Arduino 及其感測器的雲端系統 Cayenne

Raspberry Pi 筆記(二十六):MPU-6050 加速度計與陀螺儀感測器

Raspberry Pi 筆記(二十五):RFID 無線射頻辨識控制 LED

Raspberry Pi 筆記(二十四):安裝微雪 Waveshare 3.5(A) LCD螢幕

Raspberry Pi 筆記(二十三):安裝版本管理系統 Subversion

Raspberry Pi 筆記(二十二):安裝Icinga監控工具及PhpMyAdmin

Raspberry Pi 筆記(二十一):安裝OpenCV

Raspberry Pi 筆記(二十):MCP3008 讀取類比訊號測溫度與光度

Raspberry Pi 筆記(十九): Webcam 拍照與瀏覽串流媒體

Raspberry Pi 筆記(十八):模擬DOS環境

Raspberry Pi 筆記(十七):使用MAX7219 控制 8x8 LED Matrix

Raspberry Pi 筆記(十六):製作多媒體伺服機:使用 Samba 及 minidlna

Raspberry Pi 筆記(十五):超音波測距離

Raspberry Pi 筆記(十四):用鍵盤透過無線網路控制智能車

Raspberry Pi 筆記(十三):使用藍牙USB連接GPS

Raspberry Pi 筆記(十二):控制步進馬達

Raspberry Pi 筆記(十一):音效設定與播放器

Raspberry Pi 筆記(十):使用PIR (Passive Infrared)偵測物體移動

Raspberry Pi 筆記(九):使用Keypad

Raspberry Pi 筆記(八):安裝Webmin、FTP、Web、Web伺服器及無線網路

Raspberry Pi 筆記(七):使用L293D驅動馬達

Raspberry Pi 筆記(六):使用WiringPi 控制GPIO

Raspberry Pi 筆記(五):2x16 LCD顯示字元

Raspberry Pi 筆記(四):WebIOPi讓瀏覽器控制樹莓派

Raspberry Pi 筆記(三):Python控制LED

Raspberry Pi 筆記(二):GPIO接腳與 I2C 及 SPI 安裝

Raspberry Pi 筆記(一):螢幕無法呈現及HDMI轉接線忽黑忽亮問題



[Arduino]

Arduino筆記(二十七):土壤濕度檢測YL-38 + YL-69Arduino

Arduino筆記(二十六):控制圓形16位元5050全彩LEDArduino

Arduino筆記(二十五):Mini DVD 繪圖機

Arduino筆記(二十四):回收商的42型步進馬達

Arduino筆記(二十三):無線射頻 RFID 控制電磁閥開關


Arduino筆記(二十一):電子羅盤 GY-273 / HMC5883L透過vPython 呈現立體圖

Arduino筆記(二十):DHT11、LM35 及DS18B20 的溫度值哪個比較準確?

Arduino筆記(十九):超音波測距模組

Arduino筆記(十八):Nokia 5510 單色顯示器

Arduino筆記(十七):即時時鐘 RTC 與 TM1637 四位數顯示器

Arduino筆記(十六):讀取/寫入 SD 卡資料

Arduino筆記(十五):控制伺服馬達 SERVO

Arduino筆記(十四):使用MAX7219 控制 8X8 LED MATRIX

Arduino筆記(十三):使用FIRMATA 協定,ARDUINO 也可以執行 PYTHON

Arduino筆記(十二):使用Cayenne控制 LED

Arduino筆記(十一):繼電器控制風扇

Arduino筆記(十):製作ATMega328燒錄器

Arduino筆記(九):DHT11溫濕度感應偵測與LCD顯示

Arduino筆記(八):控制步進馬達

Arduino筆記(七):3x4 Keypad 控制蜂鳴器發聲

Arduino筆記(六):紅綠燈號誌

Arduino筆記(五):使用可變電阻控制伺服馬達

Arduino筆記(四):在2x16 LCD上顯示 Hello World訊息

Arduino筆記(三 ):Arduino主程式與電路繪圖軟體

Arduino筆記(二):Arduino介紹

Arduino筆記(一):緣起-- 巧遇Arduino







Share: