Try   HackMD

微電腦應用實習

By Tseng

圖片來源: raspberrypi.org

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

所需軟體

  1. mobaxterm下載
  2. VNC
  3. Notepad++
  4. Visual Studio Code

燒錄raspberry pi os

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

使用 raspberry pi imager

Image Not Showing Possible Reasons
  • The image was uploaded to a note which you don't have access to
  • The note which the image was originally uploaded to has been deleted
Learn More →

Image Not Showing Possible Reasons
  • The image was uploaded to a note which you don't have access to
  • The note which the image was originally uploaded to has been deleted
Learn More →

選擇樹梅派型號、OS版本以及micro SD卡(這裡以pi4、piOS(64bit Bookworm)與16G sd卡Demo

Image Not Showing Possible Reasons
  • The image was uploaded to a note which you don't have access to
  • The note which the image was originally uploaded to has been deleted
Learn More →

Image Not Showing Possible Reasons
  • The image was uploaded to a note which you don't have access to
  • The note which the image was originally uploaded to has been deleted
Learn More →

Image Not Showing Possible Reasons
  • The image was uploaded to a note which you don't have access to
  • The note which the image was originally uploaded to has been deleted
Learn More →

按下 NEXT

Image Not Showing Possible Reasons
  • The image was uploaded to a note which you don't have access to
  • The note which the image was originally uploaded to has been deleted
Learn More →

接著選擇 編輯設置後如下圖

Image Not Showing Possible Reasons
  • The image was uploaded to a note which you don't have access to
  • The note which the image was originally uploaded to has been deleted
Learn More →

設定主機名稱、使用者名稱、密碼、WiFi的ssid名稱、WiFi連線密碼、WiFi國家

接著切換到第2頁籤 SERVICES,並將SSH服務勾選(如下圖),並按下保存離開

Image Not Showing Possible Reasons
  • The image was uploaded to a note which you don't have access to
  • The note which the image was originally uploaded to has been deleted
Learn More →

接著按下是(如下圖)

Image Not Showing Possible Reasons
  • The image was uploaded to a note which you don't have access to
  • The note which the image was originally uploaded to has been deleted
Learn More →

Image Not Showing Possible Reasons
  • The image was uploaded to a note which you don't have access to
  • The note which the image was originally uploaded to has been deleted
Learn More →

開始下載並寫入micro sd卡

Image Not Showing Possible Reasons
  • The image was uploaded to a note which you don't have access to
  • The note which the image was originally uploaded to has been deleted
Learn More →

Image Not Showing Possible Reasons
  • The image was uploaded to a note which you don't have access to
  • The note which the image was originally uploaded to has been deleted
Learn More →


visual studio code 下載與安裝

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

線上python程式練習(Colab;使用學校google帳戶登入)

3D建模軟體onshape

樹梅派4b正面配置

圖片來源 BeginnersGuide-4thEd-Eng_v2.pdf

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

GPIO接腳 raspberrypy.org

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

GPIO各接腳 pull up 與 pull down 狀態

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

pull up 與 pull down(拉高、拉低電阻)

  • Multisim Live 模擬

  • Image Not Showing Possible Reasons
    • The image file may be corrupted
    • The server hosting the image is unavailable
    • The image path is incorrect
    • The image format is not supported
    Learn More →

  • 啟動上拉電阻 python 語法

import RPi.GPIO as gpio
gpio.setmode(gpio.BCM)
button=7

gpio.setup(button,gpio.IN,pull_up_down=gpio.PUD_UP)

  • 啟動下拉電阻 python 語法
import RPi.GPIO as gpio
gpio.setmode(gpio.BCM)
button=26

gpio.setup(button,gpio.IN,pull_up_down=gpio.PUD_DOWN)

BCM模式與Board模式差異

  • BOARD 選項是指定在電路版上接脚的號碼

  • python寫法

    ​​​​    import RPi.GPIO as gpio
    ​​​​    gpio.setmode(gpio.BOARD) #設定為BOARD模式
    
  • BCM 選項是指定GPIO後面的號碼

  • python寫法

    ​​​​    import RPi.GPIO as gpio
    ​​​​    gpio.setmode(gpio.BCM) #設定為BCM模式
    

Python 相關語法

  • 異常處理 try…except…finally…
    ​​​​try:
    ​​​​   ....
    ​​​​   ....
    ​​​​except KeyboardInterrupt:
    ​​​​   break
    ​​​​finally:
    ​​​​   ...
    ​​​​   ...
    

實驗

單顆LED on off

​​​​http://bit.ly/3tB2okQ
​​​​```
​​​​import RPi.GPIO as gpio
​​​​import time
​​​​gpio.setmode(gpio.BCM)
​​​​gpio.setup(17,gpio.OUT)
​​​​gpio.output(17,1)
​​​​time.sleep(1)
​​​​gpio.output(17,0)

​​​​gpio.cleanup()

​​​​```
​​​​![](https://i.imgur.com/VP6mxMj.png)

單顆LED 間隔1秒閃爍

​​​​http://bit.ly/3UE7EAk

​​​​```
​​​​import RPi.GPIO as io
​​​​import time
​​​​io.setmode(io.BCM)
​​​​io.setup(17,io.OUT)

​​​​while True:
​​​​    try:
​​​​        io.output(17,1)
​​​​        time.sleep(1)
​​​​        io.output(17,0)
​​​​        time.sleep(1)
​​​​    except KeyboardInterrupt:
​​​​        break
​​​​    pass
​​​​io.cleanup()
​​​​```

作業 單方向流水燈(8顆LED)

​​​​ 提示:使用串列list簡化程式
​​​​ http://bit.ly/3AgD9rP
​​​​ ![](https://i.imgur.com/fCJyH8W.png)



​​​​---

PWM測試

​​​​從暗到最亮,單向循環
​​​​http://bit.ly/3O5T16q
​​​​```
​​​​import RPi.GPIO as gpio
​​​​import time
​​​​led=17

​​​​gpio.setmode(gpio.BCM) 
​​​​gpio.setup(led,gpio.OUT)
​​​​led=gpio.PWM(led,100)  #設定pwm頻率100Hz

​​​​while True:
​​​​    try:
​​​​        for a in range(0,101,2):
​​​​            led.start(a)  # 啟動PWM DutyCycle,dutycycle從0~100,間隔2
​​​​            time.sleep(0.2)
​​​​    except KeyboardInterrupt:
​​​​        break
​​​​    pass
​​​​gpio.cleanup()
​​​​```

單按鈕測試(pull down)

​​​​http://bit.ly/3tyE0Ao
​​​​  按下按鈕時,終端機顯示 Button Pressed!!
​​​​  ![](https://i.imgur.com/TfHIBDU.png)


​​​​```
​​​​# pull down 測試
​​​​import RPi.GPIO as gpio
​​​​import time
​​​​button1=26
​​​​gpio.setmode(gpio.BCM)
​​​​gpio.setup(button1,gpio.IN,pull_up_down=gpio.PUD_DOWN)
​​​​while True:
​​​​    try:
​​​​        input_state=gpio.input(button1)
​​​​        if (input_state==True):
​​​​            print('Button Pressed!!')
​​​​            time.sleep(0.3)
​​​​    except KeyboardInterrupt:
​​​​        break		
​​​​    pass

​​​​gpio.cleanup()
​​​​```

三顆按鈕測試(pull down)

​​​​##### 開關彈跳問題未解
​​​​![](https://i.imgur.com/4dgZBdJ.png)
​​​​{%youtube VKR4m-85HVU %}


​​​​```
​​​​# pull down 測試
​​​​import RPi.GPIO as gpio
​​​​import time
​​​​button1=13
​​​​button2=19
​​​​button3=26
​​​​gpio.setmode(gpio.BCM)
​​​​gpio.setup(button1,gpio.IN,pull_up_down=gpio.PUD_DOWN)
​​​​gpio.setup(button2,gpio.IN,pull_up_down=gpio.PUD_DOWN)
​​​​gpio.setup(button3,gpio.IN,pull_up_down=gpio.PUD_DOWN)

​​​​while True:
​​​​   try:
​​​​      in_state1=gpio.input(button1)
​​​​      in_state2=gpio.input(button2)
​​​​      in_state3=gpio.input(button3)

​​​​      if in_state1==True:
​​​​         print('Button1 Pressed!')
​​​​      elif in_state2==True:
​​​​         print('Button2 Pressed!')
​​​​      elif in_state3==True:
​​​​         print('Button3 Pressed!')
​​​​      time.sleep(0.3)
​​​​   except KeyboardInterrupt:
​​​​      break
​​​​   pass
​​​​gpio.cleanup()
​​​​```

簡易Webcam相機應用-使用fswebcam

​​​​ 安裝fswebcam
​​​​```
​​​​sudo apt-get install fswebcam
​​​​```
​​​​{%youtube xO0SJ8wduG0 %} 

​​​​fswebcam用法可下指令查詢
​​​​```
​​​​fswebcam --help
​​​​```
​​​​![](https://i.imgur.com/4Qgsv8o.png)

​​​​最簡易的使用方式: fswebcam+ +檔名 即可透過webcam拍攝一張照片,並存放於當下目錄中
​​​​```
​​​​fswebcam test.jpg
​​​​```
​​​​{%youtube 5bMK6H2rCvE %}


​​​​---

練習:使用按鈕開關拍照呼叫外部程式(fswebcam)

​​​​![](https://i.imgur.com/DDCSVuZ.png)
​​​​
​​​​ 提示: python呼叫外部程式
​​​​``` 
​​​​import os
​​​​os.system('指令')
​​​​```
​​​​   
​​​​ {%youtube 6u6ET7vAqKk %} 
import RPi.GPIO as gpio
import time
import os

button=13
gpio.setmode(gpio.BCM)
gpio.setup(button,gpio.IN,pull_up_down=gpio.PUD_DOWN)

while True:
   button_state=gpio.input(button)
   try:
      if button_state==True:
         print('button pressed')
         os.system('fswebcam a.jpg')
         os.system('gpicview a.jpg')
      time.sleep(0.3)
   
   except KeyboardInterrupt:
      break
   pass
gpio.cleanup()

同上電路功能,增加line notify通知

Line Notify網站

import RPi.GPIO as gpio
import requests, os  #line notify用
import time
import os

bt1=13
gpio.setmode(gpio.BCM) 
gpio.setup(bt1,gpio.IN,pull_up_down=gpio.PUD_DOWN)  #啟動內建下拉電阻

def lineNotify(token, msg, picURI):     #定義linenotify函式
    url = "https://notify-api.line.me/api/notify"
    headers = {"Authorization": "Bearer " + token}
    payload = {'message': msg}
    files = {'imageFile': open(picURI, 'rb')}
    r = requests.post(url, headers = headers, params = payload, files = files)
    return r.status_code

while True:
   button_state=gpio.input(bt1)
   try:
      if button_state==True:
         print('BT_pressed!')
         os.system('fswebcam a.jpg')
         token='填入自己建立的line notify token'  #line notify token
         msg = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())  #lineNotify中傳送的文字訊息,這裡擷取系統時間來發送
         picURI = 'a.jpg'  #發送圖片的檔名
         lineNotify(token, msg, picURI)   #呼叫linenotify函式
   except KeyboardInterrupt:
      break
   pass
gpio.cleanup()
\

建立python虛擬環境

因為python程式常有版本和不同套件的需求,因此須針對版本建立不同的python環境,以便於開發

建立虛擬環境(使用venv)

首先須有python3-venv套件
安裝

sudo apt install python3-venv

建立虛擬環境

python -m venv 環境名稱

啟動環境

source 環境名稱/bin/activate

退出環境

deactivate

安裝ubuntu 20.04 server

燒錄img




燒錄完成後,將micro sd放回raspberry pi並開機
第一次開機預設帳密皆為ubuntu(登入後會要求變更)
檢視網卡狀態

ip a

啟動有線網卡

sudo ip link set eth0 up

修改有線網卡ip( /etc/netplan 下的yaml檔)


修改此yaml檔內容

完成ip設定

sudo netplan apply

修改無線網卡部分
修改同上yaml檔案


變更後重啟,wifi即可使用

安裝Desktop(檔案很大,需要一些時間)

sudo apt-get install ubuntu-desktop

安裝Node-RED 參考資料

  • 藉由官網提供的scrip來安裝
sudo apt install build-essential git curl
bash <(curl -sL https://raw.githubusercontent.com/node-red/linux-installers/master/deb/update-nodejs-and-nodered)

This script will:

  • remove the existing version of Node-RED if present.

  • if it detects Node.js is already installed, it will ensure it is at least v14. If less than v14 it will stop and let the user decide whether to stay with Node-RED version 1 - or upgrade Nodejs to a more recent LTS version. If nothing is found it will install the Node.js 16 LTS release using the NodeSource package.

  • install the latest version of Node-RED using npm.

  • optionally install a collection of useful Pi-specific nodes.

  • setup Node-RED to run as a service and provide a set of commands to work with the service.


  • 啟動Node-RED

node-red-start

  • 樹梅派啟動時,自動啟動node-red
sudo systemctl enable nodered.service

安裝OpenCV

  • Image Not Showing Possible Reasons
    • The image file may be corrupted
    • The server hosting the image is unavailable
    • The image path is incorrect
    • The image format is not supported
    Learn More →

使用script安裝

OS:32bit
GitHUB

OS:64bit
GitHUB

RaspOS Buster+opencv4.5.5+mediapipe 影像檔下載img

快速安裝 opencv與 FFmpeg

參考來源

sudo apt install ffmpeg python3-opencv python3-pip

安裝完後,opencv為4.6版

另一種安裝方式

pip install opencv-contrib-python

安裝相依套件 (libdc1394-22 libopenexr23這兩個找不到)

sudo apt install libxcb-shm0 libcdio-paranoia-dev libsdl2-2.0-0 libxv1  libtheora0 libva-drm2 libva-x11-2 libvdpau1 libharfbuzz0b libbluray2 libatlas-base-dev libhdf5-103 libgtk-3-0 libdc1394-22 libopenexr23

For rpi4

sudo pip3 install mediapipe-rpi4 

上面指令若無法安裝;改用;參考

python -m pip install mediapipe

安裝後,opencv會更新至4.9版(2024.02.16.)

解決 EXTERNALLY-MANAGED問題

參考
1.直接把 EXTERNALLY-MANAGED這個檔案刪除(變更檔名)
檔案位置 /usr/lib/python3.x/EXTERNALLY-MANAGED (x為python版本)
另兩種方式請參閱上述參考連結

2.使用python虛擬環境(參閱上面)

使用RC522及DHT22

  • 簡易環境溫溼度紀錄推播及mifare感應運用
  • 使用函式庫
  • 下圖GPIO12接紅色LED:無效卡片顯示燈號
  • GPIO16接 Relay,控制磁力鎖
  • 樹梅派GPIO與RC522連接如下表
RFID-RC522 Raspberry pi
3.3V 3.3V
RST GPIO25
GND GND
IRQ GPIO24
MISO GPIO9
MOSI GPIO10
SCK GPIO11
SDA GPIO8
import time
import board
import adafruit_dht

#======for ifttt=======
import urllib, json
import requests, time
from urllib import request
ifttturl="https://maker.ifttt.com/trigger/****"  #填寫申請的ifttt URL
#===================

#=========for google sheet=============
import gspread
from oauth2client.service_account import ServiceAccountCredentials
auth_json_path='****.json' #填寫申請的憑證檔檔名
gss_scopes=['https://spreadsheets.google.com/feeds']

credentials=ServiceAccountCredentials.from_json_keyfile_name(auth_json_path,gss_scopes)
gss_client=gspread.authorize(credentials)

spreadsheet_key='**************'  #填寫key值
sheet=gss_client.open_by_key(spreadsheet_key).sheet1
#listtile=["日期時間","溫度","濕度"]
#sheet.append_row(listtile)
#============================================


# Initial the dht device, with data pin connected to:
dhtDevice = adafruit_dht.DHT22(board.D18)

# you can pass DHT22 use_pulseio=False if you wouldn't like to use pulseio.
# This may be necessary on a Linux single board computer like the Raspberry Pi,
# but it will not work in CircuitPython.
# dhtDevice = adafruit_dht.DHT22(board.D18, use_pulseio=False)
list1=["溫度:","濕度:"]

while True:
    try:
        # Print the values to the serial port
        temperature_c = dhtDevice.temperature
        temperature_f = temperature_c * (9 / 5) + 32
        humidity = dhtDevice.humidity
       # print(
       #     "Temp: {:.1f} F / {:.1f} C    Humidity: {}% ".format(temperature_f, temperature_c, humidity)
       # )
        localtime=time.ctime()  #取得目前系統時間
        
        
        data={'value1':localtime ,'value2':list1[0]+str(temperature_c) ,'value3':list1[1]+str(humidity)}  # for ifttt use(呼叫line notify)
        requests.post(ifttturl, json=data)                                    # for ifttt use
        
        listdata=[localtime,temperature_c,humidity]
        sheet.append_row(listdata)

    except RuntimeError as error:
        # Errors happen fairly often, DHT's are hard to read, just keep going
        print(error.args[0])
        time.sleep(2.0)
        continue
    except Exception as error:
        dhtDevice.exit()
        raise error

    time.sleep(1800.0) #每隔30分鐘發送一次line notify


  • Mifare感應(RC522)
#!/usr/bin/env python

import signal
import time
import sys
import RPi.GPIO as GPIO
#======for ifttt=======
import urllib, json
import requests, time
from urllib import request
ifttturl="https://maker.ifttt.com/trigger/*****" #填寫申請的ifttt URL
#===================


from pirc522 import RFID

run = True
rdr = RFID()
util = rdr.util()
util.debug = True

Gled=36  #(Board mode pin)
Rled=32

def GBlink(speed):
    GPIO.setup(Gled,GPIO.OUT)
    GPIO.output(Gled,True)
    time.sleep(speed)
    GPIO.output(Gled,False)
    time.sleep(speed)
def RBlink(speed):
    GPIO.setup(Rled,GPIO.OUT)
    GPIO.output(Rled,True)
    time.sleep(speed)
    GPIO.output(Rled,False)
    time.sleep(speed)
    
def end_read(signal,frame):
    global run
    print("\nCtrl+C captured, ending read.")
    run = False
    rdr.cleanup()
    sys.exit()

signal.signal(signal.SIGINT, end_read)

print("Starting")
while run:
        
    rdr.wait_for_tag()

    (error, data) = rdr.request()
    if not error:
        print("\nDetected: " + format(data, "02x"))

    (error, uid) = rdr.anticoll()
    if not error:
        print("Card read UID: "+str(uid[0])+","+str(uid[1])+","+str(uid[2])+","+str(uid[3]))


        if (uid[0]==** and uid[1]==**):   #uid[0]與uid[1]請依據所使用的mifare card
            # print("Welcom!")
            GBlink(2)
            localtime=time.ctime()  #取得目前系統時間
            data={'value1':localtime ,'value2':"Welcom! John" }  #line notify通知資料
            requests.post(ifttturl, json=data)    # ifttt : line notify發送進入機房人員與時間通知
        else:
            print("Permission Deny!")
            RBlink(0.1)
            RBlink(0.1)
            RBlink(0.1)
            localtime=time.ctime()  #取得目前系統時間
            data={'value1':localtime ,'value2':"Warning! Jane Doe try to open door!!! " }  #line notify通知資料
            requests.post(ifttturl, json=data)  # ifttt : line notify發送異常刷卡時間通知           
        time.sleep(0.5)

113-1 上課資料

上課用程式碼

mediapipe程式碼

mediapipe操作

基本 IO Lab

參閱範例01-07


使用opencv拍照

1.先建立opencv用虛擬環境

python -m venv py-opencv

2.切換至虛擬環境

source py-opencv/bin/activate

3.進入虛擬環境後,類似下圖

image
4.安裝opencv套件

pip install opencv-contrib-python

image
image

5.程式碼請存放於py-opencv資料夾下

image