main.py
from machine import Pin, PWM, reset
import socket
import network
import ujson
from utime import sleep, sleep_ms
red = PWM(Pin(13))
green = PWM(Pin(14))
blue = PWM(Pin(15))
red.freq(1000)
green.freq(1000)
blue.freq(1000)
r = 0
g = 0
b = 0
def interval_mapping(x, in_min, in_max, out_min, out_max):
return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min
def color_to_duty(rgb_value):
rgb_value = int(interval_mapping(rgb_value,0,255,0,65535))
return rgb_value
def color_set(red_value,green_value,blue_value):
red.duty_u16(color_to_duty(red_value))
green.duty_u16(color_to_duty(green_value))
blue.duty_u16(color_to_duty(blue_value))
def callback(Timer):
color_set(r,g,b)
class WiFiConnectError(Exception):
pass
def connect():
"""
Wi-Fiに接続する。
Returns:
ip (str): IPアドレス
Raises:
WiFiConnectError: Wi-Fiに接続できなかった場合
"""
# Wi-Fiの接続情報を取得する
config = {}
with open('config.json', 'r') as f:
config = ujson.load(f)
# Wi-Fiに接続する
wlan = network.WLAN(network.STA_IF)
wlan.active(True)
wlan.connect(config['ssid'], config['password'])
timeout = 10
while timeout > 0:
timeout -= 1
print('Waiting for connection...')
if wlan.isconnected():
ip = wlan.ifconfig()[0]
print(f'Connected: {ip}')
return ip
sleep(1)
raise WiFiConnectError('Wi-Fiに接続できませんでした。')
def open_socket(ip):
"""
ソケットを開く。このソケットオブジェクトを介してクライアントとの通信を行う。
Parameters:
ip: WLAN上で自分自身を表すIPアドレス
Returns:
connection(socket.socket): ソケット接続
"""
address = (ip, 80) # 80ポートでソケット通信を行う
connection = socket.socket()
connection.bind(address)
connection.listen(1) # 同時接続の最大数1
return connection
def serve(connection):
"""
WEBサーバーを起動する。
Parameters:
connection(socket.socket): ソケット接続
"""
global r
global g
global b
print('Starting Web Server...')
while True:
# 接続があるまで待機し、クライアントのソケットオブジェクトを取得する
client = connection.accept()[0]
# クライアントからのデータを受信する(最大1024バイト)
request = client.recv(1024)
# 受信したバイナリデータを文字列にする
request = str(request)
try:
# リソースのパスを取得する
# request.split()[0]: HTTPメソッド
# request.split()[1]: リソースのパス
request = request.split()[1]
print(request)
except IndexError:
pass
# スライドバーの値を取得する
if '/led?' in request:
params = request.split('?')[1].split('&')
r = int(params[0].split('=')[1])
g = int(params[1].split('=')[1])
b = int(params[2].split('=')[1])
response = ujson.dumps({'message': 'ok'})
client.send("HTTP/1.1 200 OK\r\nContent-Type: application/json\r\n\r\n" + response)
client.close()
continue
# HTTPレスポンスを生成する
response = 'HTTP/1.1 200 OK\r\n'
response += 'Content-Type: text/html\r\n\r\n'
response += """
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
<title>PWMでRGB LEDを制御する</title>
</head>
<body style="display: flex;justify-content: center;align-items: center;height: 100vh;margin: 0;">
<div style="text-align: center;">
<h1 style="font-family: Arial, sans-serif;"></h1>
<input type="color" id="colorPicker" onchange="getColorValue()">
</div>
<script>
function getColorValue() {
// input要素から選択された色を取得
var colorPicker = document.getElementById("colorPicker");
var selectedColor = colorPicker.value;
// 色をRGB値に変換
var hex = selectedColor.slice(1); // 先頭の#を削除
var bigint = parseInt(hex, 16);
var r = (bigint >> 16) & 255;
var g = (bigint >> 8) & 255;
var b = bigint & 255;
// APIを呼び出す
fetch(`/led?r=${r}&g=${g}&b=${b}`, {
method: 'GET',
headers: {
'Content-Type': 'application/json'
}
})
.then(response => {
if (!response.ok) {
throw new Error('API呼び出しエラー');
}
return response.json();
})
.then(data => {
console.log(data);
var rgbValue = document.querySelector('h1');
rgbValue.textContent = "RGB: (" + r + ", " + g + ", " + b + ")";
})
.catch(error => {
console.error('API呼び出しエラー:', error);
});
}
</script>
</body>
</html>
"""
# HTTPレスポンスを送信する
client.send(response)
# クライアントソケットを閉じる
client.close()
if __name__ == '__main__':
try:
# Wi-Fiに接続する
ip = connect()
# ソケットを開く
connection = open_socket(ip)
# 1秒ごとにcallback関数を呼び出す設定をする
timer = machine.Timer(-1)
timer.init(period=3000, mode=machine.Timer.PERIODIC, callback=callback)
# Web Serverを起動する
serve(connection)
except WiFiConnectError as e:
print(f'Error: {e}')
except Exception as e:
# 再起動する
reset()
config.json
{"ssid": "Your SSID", "password": "Your Password"}