Raspberry Pi Pico W 初心者向け部品チュートリアル
このRaspberry Pi Pico W Beginners Components Tutorialでは、LEDや超音波センサーなど、初心者向けキットに含まれるシンプルなコンポーネントとマイクロコントローラーを連動させる方法を紹介します。
全くの初心者の方でも、このチュートリアルを読めば、MicroPythonを理解し、コードを読んだり、書いたり、修正したりできるようになります。この知識があれば、コードとコンポーネントを組み合わせて、実際のユースケースを持つものを作ることができます。
もしあなたがPicoから来たのであれば、このチュートリアルではPico Wをワイヤレスでコントロールする方法をお教えします。これまでは、スイッチやボタンなどの物理的なインタラクションデバイスを通してしかPicoとインタラクションできませんでした。しかし、今は違います!携帯電話やデスクトップでコンポーネントをコントロールできるようになりました。
チュートリアルの流れ
はじめに
ピコWのHello Worldチュートリアル
ワン・ステップ・アップ
センサーからのデータ送信の基本的な方法
ウェブ・ユーティリティへの接続
PiCockpitによるノーコードGPIO制御
MQTT
目次
チュートリアルの目標
- より大きなプロジェクトを構成する基本的なコンポーネントとの関わり方を学ぶ
- スイッチやボタンなどのインタラクション・デバイスを使わずに、これらすべてをワイヤレスでコントロールできる。
- ピコWの強みをより深く理解する
重要なリンク
Githubリポジトリ チュートリアルコード用(secrets.pyを除く)
エラー、提案、コメントは?下のコメント欄にコメントを残してください、 メールする または ツイートする.
OSError:[Errno 98] EADDRINUSE
このエラーが表示されたら、Raspberry Pi Picoのプラグを抜き差ししてください。
Thonny's Shellに以下のコマンドを入力することでも実行できる:
import machine
machine.reset()
結果
ヘッダーピンのはんだ付け
Raspberry Pi Pico Wを購入すると、Picoにコンポーネントを接続するためのヘッダーが付属していない場合があります。
本稿執筆時点では、ピコWH(ヘッダーのH)はリリースされていない。 私たちのピコWメガ記事は、そのリリースを追跡している。
しかし、もしヘッダーがハンダ付け済みのピコWがあれば、それを買うことをお勧めする。
とはいえ、それ以外の人にとっては、ピコWにヘッダーをハンダ付けするのは簡単なことだ。必要なのは
- ブレッドボード
- はんだごて、はんだ
- ヘッダー
Raspberry Pi Zeroシリーズのヘッダーとは異なり、Pico Wのヘッダーは横に並んでいません。基板の反対側にあります。
ピンには長い側と短い側があります。GPIOのラベル(GP0、GP1、GND、VBUS、VSYSなど)が見える側に長いピンを配置するとよい。
したがって、長い方のピンをブレッドボードに挿入する。4つの穴と溝1つ分の間隔が必要です。わからない場合は、ピコWでテストしてください。
ハンダ付けは簡単だ。はんだごてが熱くなっていることを確認し、はんだごての先端を使うようにしてください。
私が最も効果的だと感じたのは、はんだごての先端をピンに近づけ、はんだが先端に触れ、はんだがピンを流れて接続されるのを見ることだった。
はんだ付け後、2つのGPIOピンを接続している可能性のある余分なはんだや、ボード上に残っている無駄なはんだがないことを確認してください。
Thonnyをコードエディターとして使う
ThonnyはRaspberry Pi Pico Wをプログラムする最も簡単な方法です。
Raspberry Pi OSを使用しているのであれば、すでにインストールされているはずだ。
ただし、WindowsまたはMacをお使いの場合は、ダウンロードして設定する必要があります。
また、次のことも確認してほしい。 Pico Wにファイルをアップロードする方法を参照してください。.
最新のUF2をアップロードしてファームウェアをアップデートする。
Pico Wを購入したとき、すでに古いファームウェアを持っているかもしれない。
ピコWには多くの変更が加えられているので、今すぐファームウェアをアップデートするのが理想的だ。
発売日以降の変更点としては、WLANのアクセスポイント機能が改善され、将来のアップデートでBluetooth機能が搭載される可能性がある。
1.Hello World "というウェブページをPicoに表示する。
すべてのプログラミング・チュートリアルで最も基本的なプロジェクトのひとつが、"Hello World "プロジェクトです。
マイクロコントローラーの「Hello World」は通常、LEDを点滅させる。 超簡単だ。やり方はこうだ。
しかし、Pico Wはウェブ・ページを提供することができるので、「Hello World」メッセージを持つウェブ・ページを提供する方法から学びましょう。
ここで使用されるセットアップは、チュートリアルの残りの部分で最も基本的な構成要素となる。
Pico Wに接続するには2つの方法があります。 スマートフォンと同様のSoftAPホットスポットをブロードキャストする。.後者を試したいなら、 このリンクから.ただし、このチュートリアルの一貫性を保つため、Pico Wからブロードキャストするのではなく、常にWiFiネットワークに接続する。
つまり、基本的には、ウェブページを提供する手順には以下のようなものがある:
- WiFiに接続する
- Pico WのIPアドレスに接続した人にindex.htmlを提供するコードを書く。
いくつかのファイルを設定しましょう。これらを保存して、Raspberry Pi Pico Wにアップロードしてください。 念のため、ファイルのアップロード方法を説明しよう。
wifi.py
wifi.py は WiFi ネットワークに接続するためのボイラープレートです。別のファイルを作って main.py ファイルを後回しにすることで、乱雑なコードを減らすことができる。
以下の行の国コードを変更してください。 rp2.country('DE') あなたの国がドイツでない場合
import rp2
import network
import ubinascii
import machine
import urequests as requests
import time
from secrets import secrets
def init_wifi():
# Set country to avoid possible errors
rp2.country('DE')
wlan = network.WLAN(network.STA_IF)
wlan.active(True)
# Load login data from different file for safety reasons
ssid = secrets['ssid']
pw = secrets['pw']
wlan.connect(ssid, pw)
# Wait for connection with 10 second timeout
timeout = 10
while timeout > 0:
if wlan.status() < 0 or wlan.status() >= 3:
break
timeout -= 1
print('Waiting for connection...')
time.sleep(1)
# Define blinking function for onboard LED to indicate error codes
def blink_onboard_led(num_blinks):
led = machine.Pin('LED', machine.Pin.OUT)
for i in range(num_blinks):
led.on()
time.sleep(.2)
led.off()
time.sleep(.2)
wlan_status = wlan.status()
blink_onboard_led(wlan_status)
if wlan_status != 3:
raise RuntimeError('Wi-Fi connection failed')
else:
print('Connected')
status = wlan.ifconfig()
print('ip = ' + status[0])
秘密.py
wifi.py 輸入品 秘密.pyWiFiネットワークの情報を保存します。
秘密.py はあなたのWiFi SSIDとパスワードを含むシンプルなJSONファイルです。
secrets = {
'ssid': 'SM-A520W9371',
'pw': 'starting',
}
serve_webpage.py
その名の通り、このページはピコWに接続するユーザーにウェブサイトを提供する。
接続を受けると、Pico Wは以下のファイルを見つける。 索引.html という行にあるように、接続されたクライアントに送信する。 response = get_html('index.html').
import socket
def serve_webpage():
#Function to load in html page
def get_html(html_name):
# open html_name (index.html), 'r' = read-only as variable 'file'
with open(html_name, 'r') as file:
html = file.read()
return html
# HTTP server with socket
addr = socket.getaddrinfo('0.0.0.0', 80)[0][-1]
s = socket.socket()
s.bind(addr)
s.listen(1)
print('Listening on', addr)
# Listen for connections
while True:
try:
cl, addr = s.accept()
print('Client connected from', addr)
response = get_html('index.html')
cl.send('HTTP/1.0 200 OK\r\nContent-type: text/html\r\n\r\n')
cl.send(response)
cl.close()
except OSError as e:
cl.close()
print('Connection closed')
最後に 索引.html 接続されたクライアントに送信されるファイル。
<!DOCTYPE html>
<html>
<head>
<title>Pico W</title>
</head>
<body>
<h1>Hello World</h1>
</body>
</html>
これは単純なHTML定型文に2つの変更を加えたものである。 <title>タグはタイトルとして "Pico W "を出力し、<h1>タグは "Hello World "を出力する。
main.py
すべてのコードを別の場所に配置したので、私たちの main.py ファイルは、Hello Worldウェブページを提供するために、これらの関数をインポートして呼び出すだけでよい。
ご覧のように、ウェブページを提供する前にまずWiFiを初期化している。
from wifi import init_wifi
from serve_webpage import serve_webpage
init_wifi()
serve_webpage()
もう少しだ!
下のスクリーンショットを参照してください:
- Raspberry Pi Pico Wに5つのファイルをアップロードしました。
- インタプリタが MicroPython (Raspberry Pi Pico) (右下枠参照)
- をハイライトします。 main.py をコードエディタで開き、緑色の実行ボタン(左上の赤枠)をクリックします。
- これを実行すると、シェルにあなたのIPアドレスが表示されます。ブラウザでこのアドレスを入力すると、Hello Worldウェブページが表示されます。
- シェルが開かれていない場合は、「表示」→「シェル」と進んでください。
すべて成功すると、以下のページが表示されます。
2.ワイヤレスでLEDを制御する
さて、基本ができたところで、もう一歩前進しよう。
ラズベリーパイの最も基本的なプロジェクトのひとつに、LEDを点滅させるものがある。
LEDをワイヤレスでコントロールすることで、さらにレベルアップしよう。LEDを点滅させたり、点けたり消したりできるようにしたい。
そのためには、ON、OFF、BLINKの3つのボタンを備えた回路とウェブサーバーをセットアップする必要がある。
このプロジェクトには、LED、330Ωの抵抗、ジャンパー・ワイヤー1本、ブレッドボードが必要だ。
ほとんどのキットには赤色LEDが搭載されているため、ここでは赤色LEDを使用します。他の色のLEDを使用する場合は、抵抗を調整する必要があることに注意してください。
コンポーネントの接続方法は以下の通り。
- GPIO 2 -> LEDの長い足(アノード/ポジティブ)
- GND→330Ω抵抗→LEDの短い足(カソード/マイナス)
ピコWのLEDを制御するコード
前のチュートリアルでやったことをベースにしましょう。修正する必要があるのは、以下の2つのファイルだけです。 索引.html ボタンを追加し main.py からの入力に基づいてLEDと相互作用する。 索引.html.
太字になっている部分は、次のように追加された新しい行を示す。 index.html。 3つのボタンと「LEDをコントロールする」というパラグラフが追加されている。
<!DOCTYPE html>
<html>
<head>
<title>Pico W</title>
</head>
<body>
<h1>Pico W</h1>
<p>Control the LED</p>
<a href=\"?led=on\"><button>ON</button></a>
<a href=\"?led=off\"><button>OFF</button></a>
<a href=\"?led=blink\"><button>BLINK</button></a>
</body>
</html>
ボタンを押すと、Pico WのIPアドレスにパラメータが追加されます。 http://192.168.43.134/%22?led=blink\).これらのパラメータはPico Wのバックエンドによって取り込まれ、LEDを制御する。
我々は移動する serve_webpage.pyのコードを main.py ファイルを作成します。
以下は main.py:
from wifi import init_wifi
import socket
import machine
import time
init_wifi()
#LED controls
led = machine.Pin(2, machine.Pin.OUT)
def blink_led():
led.on()
time.sleep(0.2)
led.off()
time.sleep(0.2)
#Function to load in html page
def get_html(html_name):
# open html_name (index.html), 'r' = read-only as variable 'file'
with open(html_name, 'r') as file:
html = file.read()
return html
# HTTP server with socket
addr = socket.getaddrinfo('0.0.0.0', 80)[0][-1]
s = socket.socket()
s.bind(addr)
s.listen(1)
print('Listening on', addr)
# Listen for connections
while True:
try:
cl, addr = s.accept()
print('Client connected from', addr)
request = cl.recv(1024)
print(request)
request = str(request)
led_on = request.find('?led=on')
led_off = request.find('?led=off')
led_blink = request.find('?led=blink')
print('led_on = ', led_on)
print('led_off = ', led_off)
print('led_blink = ', led_blink)
if led_on > -1:
print('LED ON')
led.on()
if led_off > -1:
print('LED OFF')
led.off()
if led_blink > -1:
print('LED BLINK')
blink_led()
response = get_html('index.html')
cl.send('HTTP/1.0 200 OK\r\nContent-type: text/html\r\n\r\n')
cl.send(response)
cl.close()
except OSError as e:
cl.close()
print('Connection closed')
最初の、そして重要なセグメントは以下の通り:
request = cl.recv(1024)
print(request)
request = str(request)
led_on = request.find('?led=on')
led_off = request.find('?led=off')
led_blink = request.find('?led=blink')
print('led_on = ', led_on)
print('led_off = ', led_off)
print('led_blink = ', led_blink)
if led_on > -1:
print('LED ON')
led.on()
if led_off > -1:
print('LED OFF')
led.off()
if led_blink > -1:
print('LED BLINK')
blink_led()
変数 "request "がプリントされると、以下の最初のテキスト・ブロックが出力される。最後の3行は、LEDのオン、オフ、点滅をチェックするprint文である:
b'GET /%22?led=blink\\%22 HTTP/1.1\r\nHost: 192.168.43.134\r\nConnection: keep-alive\r\nCache-Control: max-age=0\r\nUpgrade-Insecure-Requests: 1\r\nUser-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36\r\nAccept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9\r\nReferer: http://192.168.43.134/%22?led=on\\%22\r\nAccept-Encoding: gzip, deflate\r\nAccept-Language: en-US,en;q=0.9,es;q=0.8,zh-TW;q=0.7,zh-CN;q=0.6,zh;q=0.5\r\n\r\n'
led_on = 456
led_off = -1
led_blink = 10
上記のコードは、" のような特定の文字列を検索しようとします。led=on".もしそれが存在すれば、値は-1以上になり、関連する もし という声明を発表した。
例えば、パラメータにled=onが存在する場合、変数led_onは-1より大きくなる。 もしled_on > -1 ステートメントがトリガーとなり実行される led.on();
ここで唯一複雑なのは リード・ブリンク 関数のトリガーとなる:
def blink_led():
led.on()
time.sleep(0.2)
led.off()
time.sleep(0.2)
最後に、LEDを操作するためにGPIO 2を初期化する方法を示します:
import machine
import time
#LED controls
led = machine.Pin(2, machine.Pin.OUT)
GPIOピンを操作するためにマシンをインポートする。変数 導かれるPico WからGPIO 2に電源を供給したい。
輸入 時間 で0.2秒の間を置くことができる。 blink_led()。
3.ピコWのRGB LED
RGB LEDを点灯させるには、以下のものが必要だ:
- 330Ω抵抗3本
- RGB LED 1個
- ジャンパー線1本
RGB LEDには4本の脚がある。1本の足が一番長くなります。それがカソード(マイナス)かアノード(プラス)です。私のRGB LEDはカソードを共有していたので、ここで接続します:
- GPIO 15 -> 330Ω抵抗 -> 赤色LED
- GPIO 17 -> 抵抗 -> 緑色LED
- GPIO 16 -> 抵抗 -> 青色LED
以下は、正しく配線できたかどうかを確認するためのコードです:
import machine
red_led = machine.PWM(machine.Pin(15))
green_led = machine.PWM(machine.Pin(17))
blue_led = machine.PWM(machine.Pin(16))
red_led.duty_u16(65534)
green_led.duty_u16(65534)
blue_led.duty_u16(65534)
この例では、R、G、B LEDの輝度を変化させることができるPWMを使用しています。
color].duty_u16に渡される値を0から65534の間の値に変更することができます。理論的には65535を渡すことができるはずだが、どういうわけか私の場合はうまくいかないようだ。
0」を渡すと、明るさが0パーセントになると考えてください。65534を渡せば、100パーセントの明るさが欲しいということだ。
つの色に65534、残りの色に0を使えば、正しいGPIOピンを正しいLEDの色に接続したかどうかがわかる。
では、なぜPWMを使うのか?それは、より多くの色を得るのに役立つからです。単に「オン・オフ」方式を使えば、赤、緑、青、白っぽい色、光のない色が得られます。PWMを使えば、R、G、BのLEDの強度を変化させることができ、想像できる限り多くの色を作り出すことができます。
では、ワイヤレスでコントロールできるものを作ってみよう!
索引.html
ここでの主な変更点は <form> には3つのスライダーがある。これらのスライダーの値は0から100の間である。
ゼロから100までの値を使うことで、明るさをパーセンテージで視覚化できる。また、パラメータから値を解析するのに必要なコードの量も減らすことができます。 main.py)
R、G、BのLEDの値を設定したら、submitを押すと、このデータがPico Wに取り込まれる。
<!DOCTYPE html>
<html>
<head>
<title>Pico W</title>
</head>
<body>
<h1>Pico W RGB LED</h1>
<form id="form">
<input type="range" min="0" max="100" value="slider_value" name="red" id="red">
<label for="red">R</p>
<input type="range" min="0" max="100" value="slider_value" name="green" id="green">
<label for="green">G</p>
<input type="range" min="0" max="100" value="slider_value" name="blue" id="blue">
<label for="blue">B</p>
<input type="submit" id="submit">
</form>
<script>
submit.addEventListener('click', function () {
form.submit();
}, false);
</script>
</html>
main.py
from wifi import init_wifi
import socket
import machine
import time
init_wifi()
#LED controls
red_led = machine.PWM(machine.Pin(15))
green_led = machine.PWM(machine.Pin(17))
blue_led = machine.PWM(machine.Pin(16))
#Function to load in html page
def get_html(html_name):
# open html_name (index.html), 'r' = read-only as variable 'file'
with open(html_name, 'r') as file:
html = file.read()
return html
def find_intensity(color, request_str):
index = request_str.find(color) + len(color)
offset = 0
if request_str[index].isdigit():
offset = 1
if request_str[index+1].isdigit():
offset = 2
if request_str[index+2].isdigit():
offset = 3
intensity = int(request_str[index:index+offset])
return intensity
# HTTP server with socket
addr = socket.getaddrinfo('0.0.0.0', 80)[0][-1]
s = socket.socket()
s.bind(addr)
s.listen(1)
print('Listening on', addr)
# Listen for connections
while True:
try:
cl, addr = s.accept()
print('Client connected from', addr)
request = cl.recv(1024)
request_str = str(request)
#find intensity ONLY if the params exist in request
if request_str.find('red') > -1 :
#int = get rid of decimal
#/100*65534 = find_intensity returns something 0 to 100,
# so x/100 = proportion of 65534 that you want to send to LED
# 65534 = max number you can use for PWM
red_intensity = int(find_intensity('red=', request_str) /100 * 65534)
green_intensity = int(find_intensity('green=', request_str) /100 * 65534)
blue_intensity = int(find_intensity('blue=', request_str) /100 * 65534)
#print('r=' + str(red_intensity))
#print('g=' + str(green_intensity))
#print('b=' + str(blue_intensity))
red_led.duty_u16(red_intensity)
green_led.duty_u16(green_intensity)
blue_led.duty_u16(blue_intensity)
response = get_html('index.html')
cl.send('HTTP/1.0 200 OK\r\nContent-type: text/html\r\n\r\n')
cl.send(response)
cl.close()
except OSError as e:
cl.close()
print('Connection closed')
で送信を押すと 索引.html ウェブページを開くと、Pico Wはパラメータを受け取って処理する。
上のコードブロックに太字で書かれている、コードの重要なポイントを見てみよう。
find_intensity関数
この関数は2つのパラメータを取る: カラー そして request_str. カラー は、"red"、"green"、"blue "のいずれかを入力し、等号(=)の後の値を見つける。
例えば、フォーム送信後のURLは "http://192.168.1.142/?red=89&green=50&blue=50 "となる。
find_intensityに "red "を渡すと、89を返す。
強度パーサー
2番目の太字のブロックは、各LEDの輝度をPico WのGPIOに伝えるコードです。
まず最初に、URLにparamsが存在することを確認しなければならない。これは もし 声明 request_str.find('red') > -1.を使っただけだ。 赤 というのも、このフォームを使うと、100%のparamsに文字列'red'が含まれてしまうからです。
Pico WのIPアドレス(例:http://192.168.1.142/)に初めてアクセスする場合、paramsを持っていないので、次のように実行するとプログラムがクラッシュします。 find_intensity.
paramsが存在する場合は、送信された値に従って各LEDの強度を求めます。それでは 赤の強度。
red_intensity = int(find_intensity('red=', request_str) /100 * 65534)
...
red_led.duty_u16(red_intensity)
find_intensity はゼロから100までの整数を返す。これを100で割ってパーセンテージを求めます。このパーセンテージは duty_u16 メソッドが取ることができる。
しかし、そのためには イント 関数でラップすることができます。 duty_u16 が必要だ。 イント.例えば、41%の明るさが欲しかったとします - 65534の41%は26,868.94です。プログラムがクラッシュするので、このフロートを渡すことはできません。
4.ピコWのブザー動作
ブザーは、基本的な通知のためのかなり重要な部品である。LEDが何かの状態を教えてくれるのと同じように、ブザーは聴覚的な通知を与えてくれる。
独自のコードを実装するよりも、私は ジュゼッペ・カシッバの実装.ピコWで彼のコードを実行すると、ブザーでビープ音が鳴る。
しかし、このコードはPico用なので、ワイヤレス・インタラクティビティ機能はない。
では、フォークを出そう!
まず 索引.html ボタンを実装する。ON"、"OFF"、"SCALE"、"MUSIC "のボタンを用意しよう。
最初の2つのボタンは説明不要。3番目のボタンはCスケールを、最後のボタンは音楽を再生する。
<!DOCTYPE html>
<html>
<head>
<title>Pico W</title>
</head>
<body>
<h1>Pico W Buzzer</h1>
<p>Control the buzzer</p>
<a href=\"?buzzer=on\"><button>ON</button></a>
<a href=\"?buzzer=off\"><button>OFF</button></a>
<a href=\"?buzzer=scale\"><button>SCALE</button></a>
<a href=\"?buzzer=music\"><button>MUSIC</button></a>
</body>
</html>
先ほどと同じように、いくつかの <button> タグ <a> タグで囲まれています。ボタンをクリックすると、URLには次のようなパラメータが追加されます。 /ブザー=オン.ピコWはこれを読み取り、ブザーをオンにする。
さて、ジュゼッペのピコ用コードを見てみよう:
from machine import Pin, PWM
from time import sleep
buzzerPIN=16
BuzzerObj=PWM(Pin(buzzerPIN))
def buzzer(buzzerPinObject,frequency,sound_duration,silence_duration):
# Set duty cycle to a positive value to emit sound from buzzer
buzzerPinObject.duty_u16(int(65536*0.2))
# Set frequency
buzzerPinObject.freq(frequency)
# wait for sound duration
sleep(sound_duration)
# Set duty cycle to zero to stop sound
buzzerPinObject.duty_u16(int(65536*0))
# Wait for sound interrumption, if needed
sleep(silence_duration)
# Play following notes by changing frequency:
#C (DO)
buzzer(BuzzerObj,523,0.5,0.1)
#D (RE)
buzzer(BuzzerObj,587,0.5,0.1)
#E (MI)
buzzer(BuzzerObj,659,0.5,0.1)
#F (FA)
buzzer(BuzzerObj,698,0.5,0.1)
#G (SOL)
buzzer(BuzzerObj,784,0.5,0.1)
#A (LA)
buzzer(BuzzerObj,880,0.5,0.1)
#B (SI)
buzzer(BuzzerObj,987,0.5,0.1)
#Deactivates the buzzer
BuzzerObj.deinit()
彼のコードは、関数 ブザー()これは4つのパラメーターを取る:ブザーオブジェクト、周波数(ヘルツ)、発音時間、次の音を再生するまでの一時停止時間。
を有効にするようにコードを修正しよう。 オン、オフ、スケール そして 音楽.
以下は、ジュゼッペのコードを我々の main.py:
from wifi import init_wifi
import socket
import machine
import time
init_wifi()
# Buzzer
buzzerPIN = 16
BuzzerObj = machine.PWM(machine.Pin(buzzerPIN))
def buzzer(buzzerPinObject, frequency, sound_duration, silence_duration):
# Set duty cycle to a positive value to emit sound from buzzer
buzzerPinObject.duty_u16(int(65536*0.2))
# Set frequency
buzzerPinObject.freq(frequency)
# wait for sound duration
time.sleep(sound_duration)
# Set duty cycle to zero to stop sound
buzzerPinObject.duty_u16(int(65536*0))
# Wait for sound interrumption, if needed
time.sleep(silence_duration)
# Function to load in html page
def get_html(html_name):
# open html_name (index.html), 'r' = read-only as variable 'file'
with open(html_name, 'r') as file:
html = file.read()
return html
# HTTP server with socket
addr = socket.getaddrinfo('0.0.0.0', 80)[0][-1]
s = socket.socket()
s.bind(addr)
s.listen(1)
print('Listening on', addr)
# Listen for connections
while True:
try:
cl, addr = s.accept()
print('Client connected from', addr)
request = cl.recv(1024)
request = str(request)
buzzer_on = request.find('?buzzer=on')
buzzer_off = request.find('?buzzer=off')
buzzer_scale = request.find('?buzzer=scale')
buzzer_music = request.find('?buzzer=music')
if buzzer_on > -1:
BuzzerObj.duty_u16(int(65536*0.2))
BuzzerObj.freq(440)
if buzzer_off > -1:
BuzzerObj.duty_u16(0)
if buzzer_scale > -1:
#C (DO)
buzzer(BuzzerObj, 523, 0.5, 0.1)
#D (RE)
buzzer(BuzzerObj, 587, 0.5, 0.1)
#E (MI)
buzzer(BuzzerObj, 659, 0.5, 0.1)
#F (FA)
buzzer(BuzzerObj, 698, 0.5, 0.1)
#G (SOL)
buzzer(BuzzerObj, 784, 0.5, 0.1)
#A (LA)
buzzer(BuzzerObj, 880, 0.5, 0.1)
#B (SI)
buzzer(BuzzerObj, 987, 0.5, 0.1)
BuzzerObj.deinit()
if buzzer_music > -1:
pass
response = get_html('index.html')
cl.send('HTTP/1.0 200 OK\r\nContent-type: text/html\r\n\r\n')
cl.send(response)
cl.close()
except OSError as e:
cl.close()
print('Connection closed')
上記の実装では 音楽.
コードは上記の赤色LEDのチュートリアルと非常に似ており、Pico WのIPアドレスの後のパラメータをPico Wがキャプチャします。パラメータ ブザー=ON、 440Hzの音を再生します。もし ブザー=スケールすると、ジュゼッペのコードから引用した音階が演奏される。
音楽の実装は?音楽の実装はもう少し複雑なので、次のような新しいファイルを作りましょう。 定数.py に数行追加する。 main.py.
このコードは ローワン・パッカードのArduinoコード。
定数.py
A3F = 208 # 208 Hz
B3F = 233 # 233 Hz
B3 = 247 # 247 Hz
C4 = 261 # 261 Hz MIDDLE C
C4S = 277 # 277 Hz
E4F = 311 # 311 Hz
F4 = 349 # 349 Hz
A4F = 415 # 415 Hz
B4F = 466 # 466 Hz
B4 = 493 # 493 Hz
C5 = 523 # 523 Hz
C5S = 554 # 554 Hz
E5F = 622 # 622 Hz
F5 = 698 # 698 Hz
F5S = 740 # 740 Hz
A5F = 831 # 831 Hz
main.py 太字
from wifi import init_wifi
import socket
import machine
import time
from constants import *
init_wifi()
# Buzzer
buzzerPIN = 16
BuzzerObj = machine.PWM(machine.Pin(buzzerPIN))
def buzzer(buzzerPinObject, frequency, sound_duration, silence_duration):
# Set duty cycle to a positive value to emit sound from buzzer
buzzerPinObject.duty_u16(int(65536*0.2))
# Set frequency
buzzerPinObject.freq(frequency)
# wait for sound duration
time.sleep(sound_duration)
# Set duty cycle to zero to stop sound
buzzerPinObject.duty_u16(int(65536*0))
# Wait for sound interrumption, if needed
time.sleep(silence_duration)
# Function to load in html page
def get_html(html_name):
# open html_name (index.html), 'r' = read-only as variable 'file'
with open(html_name, 'r') as file:
html = file.read()
return html
# HTTP server with socket
addr = socket.getaddrinfo('0.0.0.0', 80)[0][-1]
s = socket.socket()
s.bind(addr)
s.listen(1)
print('Listening on', addr)
# Listen for connections
while True:
try:
cl, addr = s.accept()
print('Client connected from', addr)
request = cl.recv(1024)
request = str(request)
buzzer_on = request.find('?buzzer=on')
buzzer_off = request.find('?buzzer=off')
buzzer_scale = request.find('?buzzer=scale')
buzzer_music = request.find('?buzzer=music')
if buzzer_on > -1:
BuzzerObj.duty_u16(int(65536*0.2))
BuzzerObj.freq(440)
if buzzer_off > -1:
BuzzerObj.duty_u16(0)
if buzzer_scale > -1:
#C (DO)
buzzer(BuzzerObj, 523, 0.5, 0.1)
#D (RE)
buzzer(BuzzerObj, 587, 0.5, 0.1)
#E (MI)
buzzer(BuzzerObj, 659, 0.5, 0.1)
#F (FA)
buzzer(BuzzerObj, 698, 0.5, 0.1)
#G (SOL)
buzzer(BuzzerObj, 784, 0.5, 0.1)
#A (LA)
buzzer(BuzzerObj, 880, 0.5, 0.1)
#B (SI)
buzzer(BuzzerObj, 987, 0.5, 0.1)
BuzzerObj.deinit()
if buzzer_music > -1:
pause = 0.05
# pauses between notes
t = 0.125
# time that music note plays
music_notes = [B4F, B4F, A4F, A4F,
F5, F5, E5F, B4F, B4F, A4F, A4F, E5F, E5F, C5S, C5, B4F,
C5S, C5S, C5S, C5S,
C5S, E5F, C5, B4F, A4F, A4F, A4F, E5F, C5S,
B4F, B4F, A4F, A4F,
F5, F5, E5F, B4F, B4F, A4F, A4F, A5F, C5, C5S, C5, B4F,
C5S, C5S, C5S, C5S,
C5S, E5F, C5, B4F, A4F, A4F, A4F, E5F, C5S, C5S]
rhythm = [1, 1, 1, 1,
3, 3, 6, 1, 1, 1, 1, 3, 3, 3, 1, 2,
1, 1, 1, 1,
3, 3, 3, 1, 2, 2, 2, 4, 8,
1, 1, 1, 1,
3, 3, 6, 1, 1, 1, 1, 3, 3, 3, 1, 2,
1, 1, 1, 1,
3, 3, 3, 1, 2, 2, 2, 4, 8, 4]
for i in range(len(music_notes)):
buzzer(BuzzerObj, music_notes[i], rhythm[i]*t, pause)
response = get_html('index.html')
cl.send('HTTP/1.0 200 OK\r\nContent-type: text/html\r\n\r\n')
cl.send(response)
cl.close()
except OSError as e:
cl.close()
print('Connection closed')
ご覧のように、2つの配列がある、 楽譜 そして リズム.次に、for ループを実行して、これらの値を ブザー() 関数を使用している。また、コードの先頭で、すべての変数を 定数.py.
のです。 ブザー() 関数は、2つの新しい変数 t そして ポーズ.この2つの変数は、音楽のテンポを調整するのに役立ちます。 t 各音符の演奏時間を定義し ポーズ は、音符と音符の間の沈黙の長さを定義する。
5.Pico WとHC-SR04超音波センサー
これまでのチュートリアルでは、Pico Wを使ってLEDやブザーにコマンドを送ってきた。
しかし、ピコWを使って情報を受け取る場合はどうだろう?
今回は、超音波距離センサーHC-SR04について。
超音波センサーを接続する際は、それが5Vか3.3Vの部品であるかを確認してください。私は5Vバージョンを3.3Vピンに差し込んだが、プログラムからの応答は得られなかった。電源を5Vピンに移すと、すぐに反応があった。
新しいバージョンのHC-SR04は、3.3Vと5Vの両方に対応しているようです。おそらく、最初に3.3Vピンを試して、結果が出るかどうかを確認するのがベストだろう。もしダメなら、5Vを試してみよう。
ここに回路図とThonnyで実行できるプログラムがあります。応答があれば、電圧も含め、すべてのプラグが正しく差し込まれていることを意味します。
配線
HC-SR04センサーのラベル付きピンからの配線は以下の通りです:
- VCC~3.3Vまたは5Vピン (疑わしい場合は、まず3.3Vを試す)
- TRIGからGPIO 16
- ECHO から GPIO 15
- GND~GND
HC-SR04用テストプログラム
配線が正しいかどうかをテストするために、このコードを試してみてください。
from machine import Pin
import time
trigger = Pin(16, Pin.OUT)
echo = Pin(15, Pin.IN)
def ultrasonic():
trigger.low()
time.sleep_us(1)
trigger.high()
time.sleep_us(10)
trigger.low()
while echo.value() == 0:
signaloff = time.ticks_us()
while echo.value() == 1:
signalon = time.ticks_us()
timepassed = signalon - signaloff
distance = (timepassed * 0.0340) / 2
print("Distance = ",distance,"cm")
while True:
ultrasonic()
time.sleep(1)
出力はこうなるはずだ:
Distance = 9.707001 cm
Distance = 9.707001 cm
Distance = 8.619 cm
Distance = 8.415001 cm
Distance = 8.551001 cm
Distance = 8.551001 cm
Distance = 8.619 cm
プログラムが実行され、何も出力されずに終了する場合は、おそらく配線が間違っています。センサーを5Vではなく3.3Vピンに接続すると、プログラムは何の反応もなく終了した。
ブラウザに送信されるデータの取得
ウェブページを提供するために使用したファイルを作成し、距離の値を見ることができるように変更してみよう。
これが最終的なコードだ:
main.py
from wifi import init_wifi
import socket
from machine import Pin
import time
init_wifi()
# ultrasonic sensor pins and functions
trigger = Pin(16, Pin.OUT)
echo = Pin(15, Pin.IN)
def ultrasonic():
trigger.low()
time.sleep_us(1)
trigger.high()
time.sleep_us(10)
trigger.low()
while echo.value() == 0:
signaloff = time.ticks_us()
while echo.value() == 1:
signalon = time.ticks_us()
timepassed = signalon - signaloff
distance = (timepassed * 0.0340) / 2
return distance
# Function to load in html page
def get_html(html_name, distance):
# open html_name (index.html), 'r' = read-only as variable 'file'
with open(html_name, 'r') as file:
html = file.read()
content = html.replace(
"<h2 id=\"ultrasonic\"></h2>", f"<h2 id=\"ultrasonic\">{distance}cm</h2>")
return content
# HTTP server with socket
addr = socket.getaddrinfo('0.0.0.0', 80)[0][-1]
s = socket.socket()
s.bind(addr)
s.listen(1)
print('Listening on', addr)
# Listen for connections
while True:
try:
cl, addr = s.accept()
print('Client connected from', addr)
request = cl.recv(1024)
print(ultrasonic())
response = get_html('index.html', ultrasonic())
cl.send('HTTP/1.0 200 OK\r\nContent-type: text/html\r\n\r\n')
cl.send(response)
cl.close()
except OSError as e:
cl.close()
print('Connection closed')
索引.html
<!DOCTYPE html>
<html>
<head>
<title>Pico W</title>
</head>
<body>
<h1>Pico W Ultrasonic Distance</h1>
<h2 id="ultrasonic"></h2>
<script>
setInterval(() => location.reload(), 500)
</script>
</html>
何が起こっているのかを理解するために、コードの断片を見てみよう。
超音波距離取得コード
def ultrasonic():
trigger.low()
time.sleep_us(1)
trigger.high()
time.sleep_us(10)
trigger.low()
while echo.value() == 0:
signaloff = time.ticks_us()
while echo.value() == 1:
signalon = time.ticks_us()
timepassed = signalon - signaloff
distance = (timepassed * 0.0340) / 2
return distance
上記のコードブロックは、超音波の発信をトリガーする。この タイムスリープ 超音波センサーが機能するためには、低域と高域の差が必要である。
超音波が発射されてから、音波が戻ってくるまでの時間を測定するには、次のようにする。 時間.ticks_us 発光時間とエコーが検出されるまでの時間を測定する。
時間.ticks_us は任意の数である。 シグナルン から シグナルオフ 時間経過を取得する。
距離を求めるには、次の式を使う。 距離 = (経過時間 * 音速)) / 2. 音速は340m/sなので、0.0340となる。
なぜ2で割らなければならないかというと、音波は物体まで行って戻ってくるからである。
距離の値でウェブページを提供するコード
def get_html(html_name, distance):
# open html_name (index.html), 'r' = read-only as variable 'file'
with open(html_name, 'r') as file:
html = file.read()
content = html.replace(
"<h2 id=\"ultrasonic\"></h2>", f"<h2 id=\"ultrasonic\">{distance}cm</h2>")
return content
...
response = get_html('index.html', ultrasonic())
この関数は、以前のチュートリアルから少し変更され、追加のパラメータが追加されています。 距離を実行する。 超音波()。
この関数は 索引.html ファイルを使用する。 置き換える メソッドを使用して <h2> を挿入する。 距離 変数である。
index.htmlは500ミリ秒ごとにサーバーにpingを打ち、新しい値を取得する。
メインのウェブページは500msごとにウェブページをリロードする関数を受け取る。リロードのたびにPico Wにpingを送り、新しい超音波距離の値を取得する。
<script>
setInterval(() => location.reload(), 500)
</script>
6.超音波データだが、AJAXを使ってペイロードを減らそう
前回のチュートリアルでは、Raspberry Pi Pico Wに全く新しい 索引.html ファイルを作成する。
これはうまくいくが、信じられないほど効率が悪い。 索引.html が再送されている。
前のチュートリアルと同じ結果が欲しいが、前の方法のような重いペイロードはない。
そこで、クライアント(あなたの携帯電話やPC)が超音波データだけで応答するエンドポイントにpingを打つようにする必要がある。
新しい方法論はこうだ:もし人々がルートURL、例えば192.168.1.119にアクセスすると、そのURLには 索引.html.
索引.html をpingするJavaScriptがあります。 /データ ピコWが超音波距離データを取得し、それに応答する。
それからだ、 索引.html はこのデータを受け取り、ウェブページを更新する。
クライアントからのリクエストをスプライシングする
を思い出してほしい。 main.pyというセリフが必ずある。 requests = cl.recv(1024).リクエスト・オブジェクトは次のようになる:
b'GET /data HTTP/1.1
Host: 192.168.1.119
Connection: keep-alive
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Referer: http://192.168.1.119/data
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.9,es;q=0.8,zh-TW;q=0.7,zh-CN;q=0.6,zh;q=0.5
まず最初に、このテキストの壁をフィルタリングする必要がある。
を使用している。 find() メソッドを使用して リクエスト 変数に"/data "がある。もしあれば、超音波距離データで応答する。もし"/data "がなければ、次のように応答する。 索引.html.
前
request = cl.recv(1024)
print(ultrasonic())
response = get_html('index.html', ultrasonic())
その後
request = cl.recv(1024)
request = str(request)
print (request.find('/data'))
if (request.find('/data') > -1):
#if string is found, respond with data.
response = str(ultrasonic())
else:
response = get_html('index.html', ultrasonic())
ブラウザで/dataにアクセスすると、以下のように距離の値が表示される。
以前はバックエンドがほとんどすべてを処理していた。超音波の距離は、index.htmlとして提供される前に修正された。
今すぐだ、 索引.html はPico Wからセンサーデータをフェッチしているので、HTMLファイル内のJavaScriptに変更を加えなければならない。変更点は太字でハイライトされています。
<!DOCTYPE html>
<html>
<head>
<title>Pico W</title>
</head>
<body>
<h1>Pico W Ultrasonic Distance</h1>
<h2 id="ultrasonic"></h2>
<script>
//instead of hardcoding, use address which browser accessed Pico W.
const PicoAddress = window.location.href
const getData = async () => {
//there is a slash at the end of PicoAddress, so don't use "/data". use "data"
const data = await fetch(`${PicoAddress}data`);
//response is just a string, so use data.text() to decode the Response's body
const distance = await data.text();
//target ultrasonic id and change its inner HTML
ultrasonic.innerHTML = `${distance} cm`;
//run getData() again.
setInterval(getData,100)
//you can run getData() but it seems more optimized if you give it some time to breathe
};
getData();
</script>
</html>
このコードの中心は フェッチAPI そして最新の 非同期/待機 構文はこちら。
機能 getData() Pico Wの/dataエンドポイントにpingを打つと、Pico Wが応答する。という完全な応答を得る前にプログラムがスキップしないようにする。 待つ.
FetchはResponseオブジェクトになり、Response.text()メソッドを使用してレスポンスの本文を取得する必要があります。したがって const distance = await data.text();
超音波のデータが得られたら、次のように変更する。 <h2 id="”ultrasonic”"> 要素の内側のHTMLは空で始まり、距離データが入ります。要素を アイドル を使わずに直接 getElementById() または クエリセレクタ() のメソッドがある。
すべてのコードが終わったら、もう一度getData()を実行したい。なぜ セットインターバル 100ミリ秒間隔を設定するには?
私が発見したのは、間隔を空けずにgetData()を呼び出すと、出力と出力の間にもっと間が空くということです。高速な更新が連続して行われ、その後一時停止する。100msの余裕を持たせることで、Pico Wの動作は少し改善され、更新はほぼリアルタイムで行われるようになった。
ボンネットの下で何が起きているのかを理解したい場合は、以下の記事を参照してほしい。 Fetch API ドキュメント とのことです。 非同期/待機 ドキュメンテーション
7.ピモロニ ふぅ、よりクリーンなコードに
最後のセクションでは、超音波センサーのデータを更新するAJAX方式を取り上げた。
しかし、もっといい方法はないだろうか?
Pimoroni's Phewは、様々なネットワーキングを容易にするライブラリだ。
目標は同じだ:
- 超音波データの取得と表示 索引.html
- ペイロードは可能な限り低く抑える。
これがその方法だ。 main.py のように見える。
from wifi import init_wifi
from phew import server
from phew.template import render_template
from machine import Pin
import time
init_wifi()
# ultrasonic sensor pins and functions
trigger = Pin(16, Pin.OUT)
echo = Pin(15, Pin.IN)
# Function to load in html page
@server.route("/data", methods=["GET"])
def ultrasonic(request):
trigger.low()
time.sleep_us(1)
trigger.high()
time.sleep_us(10)
trigger.low()
while echo.value() == 0:
signaloff = time.ticks_us()
while echo.value() == 1:
signalon = time.ticks_us()
timepassed = signalon - signaloff
distance = (timepassed * 0.0340) / 2
return str(distance), 200
@server.catchall()
def catchall(request):
return render_template("index.html")
server.run()
ご覧のように、エンドポイントを設定し、特定のデータを返す関数とリンクさせることができるため、コードはかなり読みやすくなっている。
ソケットを実行するためにコードをいじくり回す代わりに、Phewのライブラリから関数を呼び出すだけだ。
Phewについて気に入っている点はいくつかある:
- を使う必要はない。 request.find() エンドポイントを作成する
- これ以上 ゲット_html() 関数を使用して 索引.html ファイルでは、Phewの render_template()
- main.py は、最小限の追加労力で、かなり読みやすくなっている!
- Phewはまた、あなたのコードをより簡単にデバッグできるようにするロギング機能を追加している。
唯一の欠点は、Phewがまだ "非常に新しいプロジェクトであり、せいぜいアルファ段階と考えるべき "ということだ。そのため、時には予期せぬ障害に遭遇するかもしれない。
これまでのチュートリアルでは、Pico WとPC/携帯電話を連動させる方法について説明しました。
ここから一歩踏み出して、Pico Wをクラウド・サービスとやりとりさせてみよう。
そのために、IFTTT経由でGoogle Sheetsにデータを送信するDHT22センサーを使った温湿度ロガーを作ってみよう。
8.DHT22温湿度センサーをPico Wにセットアップする
これらの手順はすべてDHT11とDHT22で機能します。両者の主な違いは、測定値の精度です。DHT11は青色ですが、DHT22は白色です。
DHT11を使用している場合、コード内のDHT22への参照はDHT11に変更する必要があることに注意してください。例えば
import dht
#dht22 = dht.DHT22(Pin(16))
#should be
dht11 = dht.DHT11(Pin(16))
下の図を見ると、DHT22の上から下に向かって、最初のピンに3.3Vを接続することになる。
番目のピンはデータ・ピンです。電源が必要だ。そこで、パワーレールから10KΩの抵抗を接続し、別のジャンパー線をRaspberry Pi PicoのGPIO 16に接続する。
GNDはGNDへ。
センサーをテストするには、以下を実行する:
from machine import Pin
import dht
# ultrasonic sensor pins and functions
dht22 = dht.DHT22(Pin(16))
print(dht22.measure())
print(dht22.temperature())
print(dht22.humidity())
もし OSError:[Errno 110] ETIMEDOUT は、スクリプトの実行が早すぎることを意味します。DHT22は、別の値を返す前に2秒の休憩が必要です。DHT11では1秒必要です。
IFTTTとGoogle Sheetsを接続する
Pico WからGoogle Sheetsにデータを取得する最も簡単な方法は、IFTTTを使うことだ。
最初に IFTTTアカウントにサインアップする.
次に、「作成」ボタンをクリックしてアプレットを作成します。
この画面が表示されます:
If This」をクリックし、Webhooksを検索する。Receive a web request "をクリックする。JSONは選ばないでください。イベント名を「dht22」とする。IFTTTがどのアプレットをトリガーするかを知る方法なので、イベント名は重要である。
ここで行っているのは、DHT22のセンサーデータでpingを送信できるエンドポイントを作成することです。
次に、"Then That "をクリックする。Google Sheets "を選ぶ。そして「スプレッドシートに行を追加」を選ぶ。Google Sheetsのアカウントをリンクする必要があります。
スプレッドシート名」と「ドライブのフォルダパス」を好きなものに変更する。ここで重要なのは、「書式付き行」だけです。
{{OccurredAt}} ||| {{Value1}} ||| {{Value2}}
ここで、Pico Wがセンサーデータを送信できるエンドポイントを取得する必要がある。
に向かう。 https://ifttt.com/maker_webhooks をクリックし、"Documentation "をクリックする。
ドキュメントには、キー、データを送信するエンドポイント、JSONボディの構造について書かれている。
イベント名として "dht22 "を使用しているので、エンドポイントは以下のようになる:
ttps://maker.ifttt.com/trigger/dht22/with/key/[your_key_here]
また、JSON本体をこのように構成したい:
{'value1': *** temperature data *** , value2': *** humidity data *** }
Pico WでDHT22のデータを取得し、IFTTTに送信するためのコーディング
その方法をご紹介します。
from machine import Pin
from wifi import init_wifi
import urequests
import ujson
import dht
import time
init_wifi()
dht22 = dht.DHT22(Pin(16))
def send_data():
#tell dht22 to take a reading
dht22.measure()
#find temp & humidity data and then jsonify data.
dht_data = {'value1': str(dht22.temperature()),
'value2': str(dht22.humidity())}
post_data = ujson.dumps(dht_data)
request_url = 'https://maker.ifttt.com/trigger/dht22/with/key/[your_key_here]'
res = urequests.post(request_url, headers={
'content-type': 'application/json'}, data=post_data)
#log response from IFTTT.
print(res.text)
#sleep for a minute before running send_data again
time.sleep(1*60)
send_data()
send_data()
このコードをコピーする場合は、次のように置き換えてください。 [your_key_here]。 にある。 リクエストURL 変数である。
以下のように、1分ごとに新しい測定値がGoogle Sheetに記録されるはずだ。
記録される温度は摂氏であることに注意。華氏で記録したい場合は、以下の計算式を参照してください:
fahrenheit = dht22.temperature() * 1.8000 + 32.00
データのロギング頻度を上げたい(または下げたい)場合は、以下の値を変更してください。 タイムスリープ().
エラーが発生したらIFTTTを使って通知する
もちろん、このコードはまだかなり脆弱だ。
何かがうまくいかなかったとしよう。例えば、温度を記録するために床に置いたまま、猫が3.3Vのジャンパー・ワイヤーを引っ張ってしまったとします。
プログラムは終了するが、データが記録されていないことに気づくまで、何の通知もない。
どう解決するのですか?
そうなったら、IFTTTに通知を送ってもらおう!
お使いの携帯電話にIFTTTアプリが必要です。ダウンロードしてください。
それから、新しいアプレットを作る。
については "もしも" パート, 選択 Webhooks -> ウェブリクエストを受け取る.イベント名 "失態".
についてそれならこれだ 部分を選択する。お知らせ" と "IFTTTアプリから通知を送る".
メッセージはシンプルにした
Error: {{Value1}}
では、トライ・エラー・ブロックを作ってみよう。
from machine import Pin
from wifi import init_wifi
import urequests
import ujson
import dht
import time
init_wifi()
dht22 = dht.DHT22(Pin(16))
def send_data():
# tell dht22 to take a reading
dht22.measure()
# find temp & humidity data and then jsonify data.
dht_data = {'value1': str(dht22.temperature()),
'value2': str(dht22.humidity())}
post_data = ujson.dumps(dht_data)
request_url = 'https://maker.ifttt.com/trigger/dht22/with/key/[your-key-here]'
res = urequests.post(request_url, headers={
'content-type': 'application/json'}, data=post_data)
# log response from IFTTT.
print(res.text)
# sleep for a minute before running send_data again
time.sleep(1*60)
send_data()
try:
send_data()
except Exception as e:
print(e)
request_url = 'https://maker.ifttt.com/trigger/error/with/key/[your-key-here]'
post_data = ujson.dumps({"value1": str(e)})
urequests.post(request_url, headers={
'content-type': 'application/json'}, data=post_data)
試してみてください。DHT22から3.3Vワイヤーを抜くと、そのような通知が表示されます:
9.Raspberry Pi Pico WでSpotifyのリモコンを作る
前回のプロジェクトをベースに、IFTTTを使ってSpotifyをコントロールする。
再生、一時停止、トラックスキップボタンを持つデバイスを作成する。
IFTTTを使ってSpotifyをコントロールする最大のメリットは、その簡単さだ。
欠点は、有料のSpotifyアカウントが必要なことと、レスポンスが遅いことだ。つまり、スキップボタンを押しても、結果が表示されるまでしばらく待たなければならない。
Spotify専用リモコンを持つことの良さは、携帯電話を持ち歩いたり、Spotifyアプリを開いたりすることなく音楽を変更できることだ。
最新のクルマに乗ったことがある人なら、ステアリングホイールで操作できることがどんなにいいことかわかるだろう。
リモートSpotifyコントローラーの配線
必要なのは...
- 7xジャンパーワイヤー
- 3倍ボタン
- Raspberry Pi Pico W
- スポティファイ有料アカウント
画像では多くのワイヤーが交差しているので、ここで文字による説明をする。
押しボタンはスイッチのようなものだ。3V3ピンをそれぞれに接続する必要があり、ブレッドボードのプラス側の列を使うことになる。したがって
3V3→ブレッドボード正列→押しボタン(ブレッドボードの溝の片側)→GPIO(反対側)
私のコードでは、GPIO 16を再生ボタンに、GPIO 2を一時停止ボタンに、GPIO 15をトラックスキップボタンに使用する。
SpotifyをコントロールするIFTTTの設定
再生、一時停止、スキップ機能用にそれぞれ1つずつ、計3つのアプレットを作らなければならない。
もしあなたがIFTTTのプレミアム版を持っているなら、JavaScriptフィルターを使ってすべてを1つのアプリにまとめることができるだろう。しかし、そうではないので、それぞれアプレットが必要だ。
ログインしたら、メインメニューの右上にある「作成」をクリックします。
If This "バーをクリックし、Webhooksを検索する。
次に、"Receive a web request "をクリックする("with a JSON payload "と表示されている他のオプションは選択しない)。
イベント名には SPOTIFY_SKIP.
のために、このステップをさらに2回繰り返す必要がある。 spotify_pause そして スポティファイ・プレイ このアプレットの作成が終わったら
それが終わったら、"それから"バーをクリックする。を検索する。スポティファイ".
Spotifyに接続するためには、IFTTTを一度認証する必要がある。
もし、あなたが SPOTIFY_SKIP アクションを実行する場合は、"Skip track "をクリックします。しかし、アプレットで他のアクションを行う場合、上の画像はどちらを使うべきかを示しています。
つのアプレットを作成したら、次はコードを書く番だ!
Pico W用Spotifyリモートのコーディング
まず最初に、ヒットさせるべきエンドポイントを知る必要がある。
このページへ をクリックしてください。 ドキュメンテーション.
そこにあなたのキーが表示されます。上記のステップをすべて踏んだのであれば、あなたのエンドポイントと私のエンドポイントの違いはあなたのキーです。したがって
プレー・エンドポイントhttps://maker.ifttt.com/trigger/spotify_play/with/key/[your_key_here]。
ポーズhttps://maker.ifttt.com/trigger/spotify_pause/with/key/[your_key_here]。
スキップhttps://maker.ifttt.com/trigger/spotify_skip/with/key/[your_key_here]。
コード
from machine import Pin
from wifi import init_wifi
import urequests
import time
init_wifi()
play_btn = Pin(16, Pin.IN, Pin.PULL_DOWN)
pause_btn = Pin(2, Pin.IN, Pin.PULL_DOWN)
skip_btn = Pin(15, Pin.IN, Pin.PULL_DOWN)
def play():
request_url = 'https://maker.ifttt.com/trigger/spotify_play/with/key/[your_key_here]'
res = urequests.post(request_url)
# print response from IFTTT.
print(res.text)
def pause():
request_url = 'https://maker.ifttt.com/trigger/spotify_pause/with/key/[your_key_here]'
res = urequests.post(request_url)
# print response from IFTTT.
print(res.text)
def skip():
request_url = 'https://maker.ifttt.com/trigger/spotify_skip/with/key/[your_key_here]'
res = urequests.post(request_url)
# print response from IFTTT.
print(res.text)
try:
while True:
if play_btn():
print('play btn')
play()
time.sleep(0.25)
if pause_btn():
print('pause btn')
pause()
time.sleep(0.25)
if skip_btn():
skip()
print('skip')
time.sleep(0.25)
except Exception as e:
print(e)
request_url = 'https://maker.ifttt.com/trigger/error/with/key/[your_key_here]'
post_data = ujson.dumps({"value1": str(e)})
urequests.post(request_url, headers={
'content-type': 'application/json'}, data=post_data)
コードを見てみよう。
を交換する必要があることに注意してください。 [your_key_here]。 を通して取得した、あなたの本当のキーで ドキュメンテーション リンク
まず、押しボタン用の変数を宣言する。
play_btn = Pin(16, Pin.IN, Pin.PULL_DOWN)
pause_btn = Pin(2, Pin.IN, Pin.PULL_DOWN)
skip_btn = Pin(15, Pin.IN, Pin.PULL_DOWN)
現在、ボタンを押さなければ、変数の値は 0. これを押すと 1.をトリガーするために使用します。 プレイ() , ポーズ そして スキップ の機能がある。
次に、再生、一時停止、スキップのエンドポイント用の関数を作成する。一般的なテンプレートはこうだ:
def play():
request_url = 'https://maker.ifttt.com/trigger/spotify_play/with/key/[your_key_here]'
res = urequests.post(request_url)
# print response from IFTTT.
print(res.text)
とてもシンプルだ。この関数を実行すると、IFTTTにPOSTリクエストが送信される。GETリクエストを送っても動作しません。
次に、try/exceptブロックがある。
try:
while True:
if play_btn():
print('play btn')
play()
time.sleep(0.25)
if pause_btn():
print('pause btn')
pause()
time.sleep(0.25)
if skip_btn():
skip()
print('skip')
time.sleep(0.25)
except Exception as e:
print(e)
request_url = 'https://maker.ifttt.com/trigger/error/with/key/[your_key_here]'
post_data = ujson.dumps({"value1": str(e)})
urequests.post(request_url, headers={
'content-type': 'application/json'}, data=post_data)
ボタンが押されると、コードは関連する機能を実行する。例えば、スキップボタンを押すと、次の関数が実行されます。 スキップ.
A time.sleep(0.25) は250msの間機能を一時停止します。これがないと、短時間のプレスでもオーバーロードしてPico Wがクラッシュする可能性がある。
のです。 ただし ブロックはオプションだが、私はすでにIFTTTで「エラー」アプレットを持っていたので、これを実行した。前のチュートリアルに従ったことがあれば、使ったことがあるかもしれない。
基本的にはエラーメッセージを送信する、 eエラーメッセージを電話アプリの通知として受け取れるようにする。
なぜ動かないのか?
Spotifyをコントロールする手段としてIFTTTを使うのは簡単だが、デメリットもある。
まず通常の方法で音楽を始めなければならない
ピコWの再生ボタンを押して、音楽が再生されると思っていたら...何も起こらない。
解決策は、パソコンやスマホで普通に音楽を始めることです。アプリで再生ボタンを押してください。
これは、どのデバイスがアクティブデバイスであるかを宣言するものだと思います。これでPico W Spotifyリモコンが使えるようになります。
反応が遅い
ボタンを押してから反応するまで数秒かかる。残念ながら、これが現状なのだ。
IFTTTのアップグレードにお金を払えば、より速いレスポンスを得ることができる。少なくとも、IFTTTはそれを約束する。
Spotifyに直接接続する方法はありますか?
はい!SpotifyにはAPIがあり、接続することができます。
コントロールの幅が格段に広がる。ロータリーエンコーダーを追加して音量をコントロールすることもできる。何が再生されているかを表示するLCDスクリーンを追加することもできる。 スポティファイのコンソールはこちら。
驚くべきことだが、特にピコWではプログラムするのがより難しい。
IFTTTは力仕事をすべてやってくれるので、すべてが簡単だ。もしあなたが力仕事をしたいのであれば、認証フローをチェックしよう。
もちろん、私たちはRaspberry Pi愛好家だ。誰かがやるでしょう。それはあなたですか?それとも私?以下にコメントしてください。
PiCockpitでPico Wをワイヤレスでコントロール!
PiCockpitを使えば、Pico Wをワイヤレスでコントロールし、データを取得することができます。
PiCockpitは、GPIOアプレットを介して、GUIでPWMの値取得、制御、利用が可能です。
また、PiStatsアプレットを通して、Pico Wの統計情報を見ることができます。
PiCockpitをPico Wに組み込むのは超簡単です。
PiCockpitとPico Wでさらに少ないコードを書こう
PiCockpitを使えば、コードを書かずに簡単にGPIOピンを制御することができます。
を見ると チュートリアル2LEDを点灯させるだけで、どれだけのコードが必要なのか、おわかりいただけますでしょうか。
新しいPico Wの統合により、PiCockpitは何もプログラムする必要がなくなり、とても簡単になりました。WiFiの設定さえも、セットアップウィザードで完了します。
10.PiCockpitとPico Wで簡単LED制御
チュートリアルNo.2で紹介した方法でLEDの設定が完了したら、あとはPiCockpitで設定するだけです。
コーディングする場合は、どのピンのLEDを点灯させるか、次のように宣言します。 led = machine.Pin(2, machine.Pin.OUT)
PiCockpitで、GPIOアプレットに移動し、"GPIO Output (On/Off) "にスクロールします。
LEDがGPIO 2にあるので、ドロップダウンメニューからBCM02を選択します。
そして、「Control」欄で、スイッチを切り替えてLEDを点灯させます。
また、下記のソフトウェアPWMの項を使えば、簡単にLEDの明るさを制御することができます。
なお、同じGPIOに2つの出力を持たせることはできないので、前の設定を削除する必要があります。
Control」スライダーを切り替えると、LEDの明るさが変化するのがわかります。
11.PiCockpitで制御するPico W、5Vファン、トランジスター
同じGPIO Outputトグルを使って、もう少し包括的なことをやってみましょう。
実際の使用例を説明するために、PiCockpitを使用して5Vファンを駆動してみます。
これは、私のRaspberry Pi 4から取り出した低電力の5Vファンなので、Raspberry Pi Pico Wの出力能力の範囲内と言えるでしょう。
とはいえ、5Vファンなので、GPIOピンを使うわけにはいきません。LEDのような電力をあまり必要としない部品では、GPIOに部品への電力供給とON/OFFの「スイッチ」の二重の役割を持たせることができます。
しかし、5Vのファンでは高すぎる電圧が必要です。そこで、次善の策として、真ん中にトランジスタを入れることにしました。
これでファンに5Vを供給しつつ、ON/OFFを確実に行えるようになりました。
今回もPiCockpitのおかげで、プログラミングはゼロでした。ハードウェアだけやって、以下のように配線しています。
ファンは5V/0.12Aで、プラス端(赤線)を5Vに接続し、マイナス線はトランジスタのエミッタレグに接続します。
トランジスタはPN2222(NPN)トランジスタで、Highの信号を受けるとスイッチがONになる。
半円の部分を手前にして左から、エミッター、ベース、コレクターと呼ばれる脚部です。
Baseの足は1K抵抗に接続され、GPIO15に接続されます。
コレクタの足はグランドに接続されています。
PiCockpitがトランジスタで動作するように設定する
今回も超簡単。
GPIO Outputセクションのドロップダウンメニューから、BCM15を追加します。
入ったら、下向きの矢印をクリックし、State Namesを「fan off」と「fan on」に変更することができます。
コントロールスイッチを切り替えると、ファンが回転するのが見えるはずです。
また、PiStatsを使えば、基板の温度低下を確認することができます。
ピコWでMQTTとNode-REDを使用したディスプレイ・フォト・レジスター。
このチュートリアルの主な目的は、MQTTを紹介することです。
これまでのチュートリアルでは、Pico Wを使ってデータを配信する方法を紹介しました。
HiveMQクラウドは、この目標を達成するために利用できる無料のサービスです。他人のコンピュータを使うことで、Pico Wの負荷を軽減することもできる。
さらに付け加えると、MQTTには、これまで使われてきた方法と比較して大きな利点がある。ひとつは、小さなデータを送信するのに非常に効率的だということだ。MQTTプロトコルのヘッダーのサイズは2バイトだ。HTTPは約4000倍大きい。
ローカル処理負荷とネットワーク負荷の低減は、Pico Wのバッテリー寿命の延長を意味し、バッテリー駆動やソーラー駆動のプロジェクトに最適です。
フォトレジスターとピコWの接続
フォトレジスタ(光電池)の接続は超簡単だ。
ブレッドボードの中央の溝を横切ってフォトレジスターを置く。
次に、3V3ピンをフォト・レジスタの片側に接続する。
フォトレジスタの反対側にADCピンを接続したいので、GPIO 26に接続する。
最後に、アースからフォトセルまで10KΩの抵抗を接続する。
HiveMQクラウドとPico Wのコーディング
まずはこれだ、 HiveMQ Cloudへのサインアップはこちらから。
セットアップを行い、クラスタを作成する。AWSかAzureを選択するよう求められる。我々の目的では、違いはない。
次に、"Manage Cluster "をクリックする。
クラスタのURLをメモし、Access Managementをクリックして新しいユーザーを作成します。手順に従って新しいユーザーを作成します。
これで、Pico Wにデータを送信するようプログラムすることができる。
フォトセルデータとMQTTClientを受信するためのPico Wのコーディング
from machine import Pin, ADC
from wifi import init_wifi
import time
from umqtt.simple import MQTTClient
init_wifi()
photoresistor = ADC(Pin(26))
def readLight():
light = photoresistor.read_u16()
return light
# Connect MQTT
def connectMQTT():
client = MQTTClient(client_id=b"[your_client_id]",
server=b"[your-host-name]",
port=0,
user=b"[your-user]",
password=b"[your-pw]",
keepalive=7200,
ssl=True,
ssl_params={
'server_hostname': '[your-host-name]'}
)
client.connect()
return client
client = connectMQTT()
def publish(topic, value):
print(topic)
print(value)
client.publish(topic, value)
print("data published")
while True:
brightness = str(readLight()) #to publish, must send string
print(brightness)
publish('picow/brightness', brightness)
time.sleep(0.1)
まず、輸入品を整理しよう。
from machine import Pin, ADC
from wifi import init_wifi
import time
from umqtt.simple import MQTTClient
のです。 wifi
インポートは以前のチュートリアルから。
umqtt.simpleライブラリが必要です。 ダウンロードはこちらから.
ダウンロードが完了したら、それを自分のボードにアップロードすることができる(ガイドはこちら).
ピコWにこれらのファイルがあるはずだ。
次に、フォトレジスターから読み取り値を得る関数を作成する:
photoresistor = ADC(Pin(26))
def readLight():
light = photoresistor.read_u16()
return light
これは65535までの値を返す。明るければ明るいほど、値は高くなる。
HiveMQへの接続
HiveMQに接続するには、MQTTClientクラスにいくつかのパラメータを送信する必要があります。
# Connect MQTT
def connectMQTT():
client = MQTTClient(client_id=b"[your_client_id]",
server=b"[your-host-name]",
port=0,
user=b"[your-user]",
password=b"[your-pw]",
keepalive=7200,
ssl=True,
ssl_params={
'server_hostname': '[your-host-name]'}
)
client.connect()
return client
client = connectMQTT()
your-host-name]をダッシュボードにあるアドレスに置き換えてください。これを2回行う必要があります。 server
もうひとつは server_hostname
.また、[your_client_id]は、"your_picow "のように、あなたのデバイスの名前に置き換えてください。
そして、次のように置き換える。 [your-user]
そして [your-pw]
を、アクセス管理ページで作成したユーザーと置き換えてください(以下のアクセス管理ページのスクリーンショット)。
参考までに、この関数はHiveMQにデータを送信します:
def publish(topic, value):
print(topic)
print(value)
client.publish(topic, value)
print("data published")
それを while
ループだ:
while True:
brightness = str(readLight()) #to publish, must send string
print(brightness)
publish('picow/brightness', brightness)
time.sleep(0.1)
パブリッシュする際には、文字列を送信する必要があります。 brightness = str(readLight())
がいる。
整数や浮動小数点を送ると、プログラムは死んでしまう。
公開機能で、トピックに名前をつける。と言う、 picow/brightness
次に、送信したい値を追加する。この場合、文字列化されたライトの数値を送信したい、 brightness
.
Web Clientタブにログインすると、データが公開されていることが確認できるはずです。
ノードレッド
それはネット上の数字に過ぎず、ちんぷんかんぷんに見えるかもしれません。HiveMQクラウド上のデータにアクセスし、それをグラフィカルに表示したいとしたらどうでしょう?
自分で開発するよりも、Node-REDを使えばいい。
Node-REDは、HiveMQからデータを取得し、それをグラフィカルな表現を使って表示することをとても簡単にします。
Node-REDを使ってゲージを作るんだ。
まず、以下のものが必要です。 ノードジス.HiveMQのドキュメントを確認する をクリックして、どのバージョンが推奨されているかを確認してください。
Nodeをインストールしたら、コマンドプロンプト/ターミナルを開き、以下のコマンドを実行する必要がある(Windowsの場合はsudoを除く):
sudo npm install -g --unsafe-perm node-red
これはnode package manager (npm)を使ってNode-REDをグローバルにインストールします。
次に、Node-REDを次のように入力して実行します。 node-red
をターミナル/コマンドプロンプトに入力する。
ブラウザを開き、次のサイトにアクセスする。 http://127.0.0.1:1880 またはターミナルに記載されているアドレス。
フローを作ってみよう。mqtt in」をキャンバスにドラッグする。左サイドバーの「ネットワーク」タブの下にあります。
タブを設定する必要があるので、長方形をダブルクリックして以下のようにする:
トピック "フィールドには、以下を必ず追加する。 ピコーの明るさピコWから発表されたものだからね。
サーバー」で、鉛筆のアイコンをクリックして新しいサーバーを追加すると、次のメニューが表示されます。
新しいサーバーアドレスを入力し、ポートを8883に変更する。Use TLS "にチェックを入れるが、わざわざ新しいtls-configを追加する必要はない。
次に、セキュリティ・タブに行き、ログイン認証情報を追加する。
これらの詳細はすべて、MQTTClientを初期化する際にコードで確認できる。
ゲージの追加
ゲージを追加するには ノードレッドダッシュボード.
左サイドバーに、これらが表示されていない場合:
次にメニュー(右上のボタン)→パレットを管理します。次にインストールタブに行き、node-red-dashboardを検索します。インストール」をクリックします。
の右側に「ゲージ」をドラッグ&ドロップする。 でmqtt から線をドラッグしてつなげます。 でmqtt をゲージにセットする。
ゲージの長方形をダブルクリックし、ラベルを "brightness "に、"range "の最大値を65535に変更する。
素晴らしい。では、"Deploy "を押してみよう。
設定が正しければ、長方形の下に緑色の円と「connected」が表示されます。そうでない場合は、端末にエラー原因の詳細が表示されます。
Pico WがHiveMQクラウドにデータを配信しているので、ダッシュボードをチェックしましょう。訪問 http://127.0.0.1:1880/ui そうすれば、ゲージが頻繁に更新されているのがわかるはずだ。
あなたの提案を歓迎する。
下のコメント欄にコメントをどうぞ!
こんにちは、
私たちと知識を共有してくれてありがとう。
WiFiエクササイズはネットワーク内専用ですか?別のWiFiネットワークにいる場合、Pico Wにアクセスできませんでした。もしそうなら、ネットワーク外からのアクセスの例はありますか?
ありがとう。
はい、ネットワーク、ルーター、ファイアウォールの性質上、これらの演習は同じWiFiネットワーク内でのみ機能します。
PiCockpit自体がネットワークをまたぐソリューションであり、インターネット上のどこからでもPico Wにアクセスできます。
私たちは、より多くの機能をこのプラットフォームにもたらすために努力しています。
そのようなものを自分で再現しようと思ったら、ネットワークへのトンネリングソリューションか、リレーサーバーか、そのようなものが必要になる。
このテーマについて深く掘り下げたい方には、コンサルティング・サービスを提供しています。
素晴らしいチュートリアルをありがとう。
残念ながらうまくいかない。
1.ピコに "Hello World "と書かれたウェブページを表示する」の最後の部分で行き詰まっています。
私のウェブブラウザFirefoxとChromeは、「エラー接続が中断されました」としか教えてくれません。
トニーで私は見た
接続済み
ip = 192.168.188.198
リスニングオン ('0.0.0.0', 80)
クライアントが接続元 ('192.168.188.100', 54025)
接続クローズ
接続が切れることが何度かあった。
ピコWを動作させるには何を修正すればいいのですか?
よろしくお願いします。
ピート
main.pyを実行するとエラーメッセージが表示されます。
ファイル "", 行 1, in
ImportError: 'wifi'という名前のモジュールがありません。
よろしくお願いします。
wifi.pyを作成して追加する必要があります。wifi.pyがないとコードは動きません。
Raspberry Pi Pico W beginners' components tutorial」は、Raspberry Pi Pico Wプラットフォームを初めて使う人のための素晴らしいガイドです。このチュートリアルはよく構成されており、初心者にとって理想的な内容となっています。このチュートリアルは、必要不可欠なコンポーネントをカバーし、明確な手順を提供しているため、この技術を探求しようとするすべての人にとって素晴らしい出発点となっています。詳細な説明と画像が含まれているため、読者はすぐにコンセプトを理解することができ、学習効果が高まる。全体として、このチュートリアルは、Raspberry Pi Pico Wとそのコンポーネントを始めようとする人にとって貴重なリソースです。