#はじめに
ESP-WROOM-32ってWiFiにつながるんだから、もっと役に立ちそう。
単体で情報取得してLEDでも点灯させようかな。
でも、天気予報に応じて色が変わる傘立てとかあったような。
じゃあ、QiitaAPIを使ってみよう!
そして、「いいね」を取得してみよう!
#やりたいこと
「いいね」メーターによる投稿状況の可視化で、目標達成へのモチベーションを上げる。
#やり方
1.ESP-WROOM-32をWiFiにつなぐ
2.Qiita APIを使って情報を取得
3.いいね状況に応じてメーターに反映する
##完成イメージ
##詳細ルール
1.「いいね」状況をQiita APIを使用して15分ごとに確認する
2.メーターは__100__「いいね」をMAX(これは自分の目標に合わせる)
3.新着LEDで新着「いいね」があった場合に点灯する
4.新着LEDはESP-WROOM-32のタッチセンサへのタッチで消灯する
#用意するもの
- ESP-WROOM-32(ESP32-DevKitC)
- バーグラフLED : いいね目標値への達成度表示用
- LED : 新着いいね用
- 抵抗 : LED抵抗用
タッチセンサはESP-WROOM-32に内蔵されている
#作る
##接続する
回路はあまり得意ではないので、チップの寿命を縮めているかもしれない。
完成!
##プログラムを作る
WebアクセスやJSONなどはC言語で使いにくいため、MicroPythonを使用した。これはいい。
Qiita APIは「いいね」を直接取得することはできない。そのため投稿からその数を取得する。
投稿を取得すると、ESP-WROOM-32ではメモリが不足したため工夫が必要だった。
###ソースコード
ソースコード全体はgithubにおいた。
####WiFiに接続する
SSIDとパスワードを指定してWiFiに接続する。
def connect_wifi(ssid, passkey, timeout=10):
wifi = network.WLAN(network.STA_IF)
if wifi.isconnected():
print('already Connected. skip')
return wifi
else:
wifi.active(True)
wifi.connect(ssid, passkey)
while not wifi.isconnected() and timeout > 0:
print('.')
utime.sleep(1)
timeout -= 1
if wifi.isconnected():
print('Connected')
return wifi
else:
print('Connection failed!')
return null
####WebAPIを使う
urequestsを使用し、HTTP GETを行なっている。
投稿を一度に取得すると、ESP-WROOM-32上のMicroPythonではメモリが足りなくなった。
そのため、get_item_count
で投稿数を取得し、get_likes_count
で1投稿ずつ「いいね」の数を取得している。
1投稿ずつでもメモリが足りなくなるため、del
、gc.collect()
で使用しなくなった変数を解放している。
def get_items_count():
token = 'set_your_token'
headers = {
'content-type' : 'application/json',
'charset' : 'utf-8',
'Authorization' : 'Bearer ' + token
}
url = 'https://qiita.com/api/v2/authenticated_user'
response = urequests.get(url, headers=headers)
json = response.json()
count = int(json["items_count"])
del token
del headers
del url
del response
del json
gc.collect()
return count
def get_likes_count(num):
token = 'set_your_token'
headers = {
'content-type' : 'application/json',
'charset' : 'utf-8',
'Authorization' : 'Bearer ' + token
}
u1 = 'https://qiita.com/api/v2/authenticated_user/items?page='
u2 = str(num)
u3 = '&per_page=1'
url = u1 + u2 + u3
del token
del u1
del u2
del u3
gc.collect()
response = urequests.get(url, headers=headers)
pattern = r'"likes_count":[0-9]+'
matchOB = ure.search(pattern, response.text)
if not matchOB:
sys.exit(0)
likes_str = matchOB.group(0)
likes_str = likes_str.split(':')
count = int(likes_str[1])
del headers
del pattern
del url
del response
del matchOB
del likes_str
gc.collect()
return count
####JSONをParseする
ujsonを使用したかったがメモリが足りず。。。
文字列を解析し、いいね数を取得する方針とした。
response = urequests.get(url, headers=headers)
pattern = r'"likes_count":[0-9]+'
matchOB = ure.search(pattern, response.text)
if not matchOB:
sys.exit(0)
likes_str = matchOB.group(0)
likes_str = likes_str.split(':')
count = int(likes_str[1])
####バーグラフLEDを制御する
達成度に応じて、つけるLEDを増やしていく。
def set_led_level(level):
pin12 = machine.Pin(12)
pin14 = machine.Pin(14)
pin27 = machine.Pin(27)
pin26 = machine.Pin(26)
pin25 = machine.Pin(25)
pin33 = machine.Pin(33)
pin32 = machine.Pin(32)
pin5 = machine.Pin(5)
pin18 = machine.Pin(18)
pin19 = machine.Pin(19)
if level >= 10:
pin12.value(1)
if level >= 20:
pin14.value(1)
if level >= 30:
pin27.value(1)
if level >= 40:
pin26.value(1)
if level >= 50:
pin25.value(1)
if level >= 60:
pin33.value(1)
if level >= 70:
pin32.value(1)
if level >= 80:
pin5.value(1)
if level >= 90:
pin18.value(1)
if level >= 100:
pin19.value(1)
####新着LEDを点灯/消灯する
GPIO21に新着LEDを接続しており、その制御をする。
def set_arrivals_led_on():
pin = machine.Pin(21)
pin.value(1)
def set_arrivals_led_off():
pin = machine.Pin(21)
pin.value(0)
####「いいね」状況をLEDに反映する
目標値を100として今の達成度合いをバーグラフLEDに反映させる。
また、前回取得時から「いいね」が増加している場合は新着LEDを点灯させる。
def update_likes_led():
global prev_likes_count
items_count = get_items_count()
likes_count = 0
for num in range(1, items_count+1):
likes_count += get_likes_count(num)
print(likes_count)
target = 100
rate = (likes_count/target)*100
set_led_level(int(rate))
if (likes_count > prev_likes_count) and (prev_likes_count > 0) :
set_arrivals_led_on()
prev_likes_count = likes_count
####タッチセンサ入力を取得する
タッチセンサを使用する方法は以下である。
タッチで数値が下がるため閾値(適当)を設けてタッチ判定を行なっている。
割り込み処理のやり方が分からなかったため、ポーリングにしている。
tp = machine.TouchPad(machine.Pin(13))
while True:
utime.sleep(0.1)
value = tp.read()
if value < 400:
print('touched')
set_arrivals_led_off()
####15分毎に状況を確認する
タイマー割り込みを使用している。
900000msec(15分)ごとにcallback関数が呼ばれるように設定する。
callback関数はupdate_likes_ledが呼ばれる。
t0 = machine.Timer(0)
t0.init(period=900000, mode=machine.Timer.PERIODIC, callback=intr_handler_timer0)
#テスト
##いいね達成度メーター
いいね状況が分かる!
現在、58いいねだから、取得と表示が成功しているようだ。
##新着LED
新着LEDの点灯/消灯は新しく「いいね」がつかないので確認できなかった。
この投稿で確認できたらなぁ。
#最後に
サイト見れば済む話だけどね。
#参考サイト
techtutorialsx
micropython on ESP32 でぽちっとな
いっぺーちゃんの いろいろやってみよ~