「音声合成IC-ATP3011F1+PICO+micropython」はこれ↓

でしたが、今回はPICOからXIAO(RP2040)へ、かつcircuitpythonに変更しました。
理由:単なる都合

 

micropythonとcircuitpythonは親戚みたいなものだから、

コード変換があってもチョイチョイで済むはず・・・との考えは、

 おおいなる間違い

でした。

 

■ハードウェア


前回作成の音声合成側の基板にXIAOを組み込み。

転用可能なように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)

の組合せでの注意点がなんとなく理解できました。

 

以上