「音声合成IC-ATP3011F1+PICO+micropython」はこれ↓
でしたが、今回はPICOからXIAO(RP2040)へ、かつcircuitpythonに変更しました。
理由:単なる都合
micropythonとcircuitpythonは親戚みたいなものだから、
コード変換があってもチョイチョイで済むはず・・・との考えは、
おおいなる間違い
でした。
■ハードウェア
転用可能なようにSDAとSCLはピンワイヤーで接続。
とにかくハーフ基板1枚で済んでしまいました。
専用基板にしたらこれの1/4ぐらいになりそうです。(やらんけど)
XIAOすなわち「小」(発音もxiao)の本領。
・・・
ここまでは楽しい工作でした。
■ソフトウェア
とにかく妙なエラーが次々続々、なんのこっちゃ!!!でした。
以下、わかったこと。(実際はぐちゃぐちゃの順序での謎の紐解き)
1:既定のGPIOはGP番号で指定できない。
GP〜ではnot definedになる番号がある。フルカラーLEDなど既定ピンが該当。
GP番号に対応した固定変数名がある。
・赤LED:PICOならばGP17だが、XIAOではRED_LED
・緑LED:PICOならばGP16だが、XIAOではGREEN_LED
・青LED:PICOならばGP125だが、XIAOではBLUE_LED
本件の本題ではないLチカでどん詰まりで、さっぱりでしたが、
ネット上を彷徨って解決方法を発見。(出典メモ忘れました、すみません!)
2:i2cオブジェクトの定義にはboardを使い、busioライブラリを使わない。
かつ、I2CにGP番号を振り当てなし(引数なし)でよい。
NG; i2c=busio.I2C(GP7,GP6)
OK: i2c=board.I2C()
3:CircuitpythonのI2Cにはreadfromが無い!単純なコード変換ができない。
出典:I2Cクラスを追加(RPiベアメタルMicroPython)
https://blog.boochow.com/article/459629304.html
↑だそうです。
Micropythonにてi2Cのreadfromを使ってI2Cデバイスのステータスを読みで動作待機などをしている場合、Circuitpythonのi2cには対応する属性がなく、単純にはコード変換できないことがわかりました。とにかく動かすには、タイマーなどで待機時間を調整する方法が代替として簡単だが、不便です。が、しようがない。
ということで、とにかくXIAOとCircuitpythonの組み合わせはクセありすぎ〜!
とわかりまして、メインコードとライブラリを修正、
スピーカからゆっくりの声が聞こえました!
以下、コードと変更点、注意点のコメント(赤文字部分)。
■メインコード
ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー
#testatp3011CP.py #CPU XIAO-RP2040#circuitpython 9.2.7
#library #general
from board import * # boardモジュールからすべてのピンの定義を準備
from digitalio import DigitalInOut, Direction # 入出力ピン制御用モジュールを準備
import time # タイマーモジュールを準備
#from machine import Pin,I2C #←machineモデュールではなく↓board。
from board import *
#import busio # I2C通信用モジュールを準備・・・使わないのでコメントアウト
#please set atp3011f4CP in lib-folder 事前にlibフォルダに入れてください。
#library for atp3011
import mame_atp3011f4CP #前回記事引用の「だいちゃまめ」さんのライブラリを改造
#set full-color LED assigned R:GP17 B:GP16 B:LED(GP25)
red = DigitalInOut(LED_RED) # on board Red-LED 専用の変数がある。GP番号ではundefindになる。
red.direction = Direction.OUTPUT # set dio-mode as output for LED
# full-color LED all on and off ・・・これはフルカラーLEDの赤の点灯テストだけの意図
red.value = False # Red LED on
time.sleep(1.0)
red.value = True # Red LED off
#set atp3011 on i2c
atp3011=mame_atp3011f4CP.ATP3011F4() #ライブラリ側で複数箇所変更
red.value = False # Red on 動作確認用に赤LEDを点灯
atp3011.talk_date(2025,4,14) #2025年4月14日と発音させる
time.sleep(10) # ライブラリ内でデバイス動作ステータス監視を削除したため、適当に待機。
red.value = True # Red off
atp3011.talk_time(16,12) #16時12分と発音させる
time.sleep(10) # ライブラリ内でデバイス動作ステータス監視を削除したため、適当に待機。
atp3011.talk_temp(25.5,58) #気温25.5度、湿度58%と発音させる
time.sleep(10) # ライブラリ内でデバイス動作ステータス監視を削除したため、適当に待機。
atp3011.send_cmd("kyouwa sukosisamuidesune.") #今日は少し寒いですね、と発音させる
print("process end")
ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー
■ライブラリ・・・micropuython用と区別するためにファイル名にCPを付加
ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー
#mame_atp3011f4CP.py #CPU XIAO-RP2040 #circuitpython 9.2.7
#library for i2c on circuitpython
import board
import time
class ATP3011F4(object):
# I2C
ADDRESS = const(0x2e)
def __init__(self):
# xiao with circuitpython
# XIAOのピンにはi2c1が接続され、port for SCL on D5=GP7、SDA on D4=GP6だが、
#引数を入れずにどーーんと単純に定義するだけ
self.i2c = board.I2C()
#以下の2行がないとi2cが正しく動作しない。理由:i2cのロック制御のため
while not self.i2c.try_lock():
pass
#どこかに「i2c.unlock()」が必要なはずですが・・・わかりません。が、とにかく動く。
# バージョン
def version(self):
ret=self.i2c.writeto(self.ADDRESS,"#V\r")
# デバイスへのコマンド送信
def send_cmd(self, command):
self.cmd = command + '\r'
self.i2c.writeto(self.ADDRESS,self.cmd)
# 発声中は、待機
#while self.i2c.readfrom(self.ADDRESS,1) == b'*':
#↑circuitpythonにはi2c.readfromが無く、代替もない→コメントアウトするのみ!
time.sleep(1.0)
# 以下のコマンド定義は変更なし。
# 年月日
def talk_date(self,year,month,day):
self.send_cmd("'hidukewa <NUMK VAL=" + str(year) + \
" COUNTER=nenn> <NUMK VAL=" + str(month) + \
" COUNTER=gatu> <NUMK VAL=" + str(day) + \
" COUNTER=nichi>de_su.")
# 時分
def talk_time(self,hour,minute):
self.send_cmd("ji'kokuwa <NUMK VAL=" + str(hour) + \
" COUNTER=ji> <NUMK VAL=" + str(minute) +\
" COUNTER=funn>de_su.")
# 気温、湿度
def talk_temp(self,temp,hum):
self.send_cmd("'kionwa <NUMK VAL=" +str(temp) + \
" COUNTER=do>. shi'tudowa <NUMK VAL=" + \
str(hum) + " COUNTER=pa-sento>de_su.")
# 電話番号
def talk_telno(self,telno):
self.send_cmd("denwaba'ngo-wa <NUM VAL="+ telno +">de_su.")
# 金額
def talk_amount(self,amount):
self.send_cmd("kingaku-wa <NUMK VAL="+str(amount)+" COUNTER=enn>de_su.")
# コード
def talk_code(self,code):
self.send_cmd("ko-doba'ngo-wa <ALPHA VAL="+ code +">de_su.")
ということでなんとか克服!
思わぬ時間消耗でしたが、知識不足多々残っているものの、
(micropython、cirucuitpython)*(PICO、XIAO-RP2040)
の組合せでの注意点がなんとなく理解できました。
以上