ShunjiHashimoto / tang

収穫サポートロボットTANG
2 stars 1 forks source link

プログラム開始時に操作者にロボットが動き出すことを音で伝える #223

Closed ShunjiHashimoto closed 1 year ago

ShunjiHashimoto commented 1 year ago

https://docs.m5stack.com/en/core/atom_lite
まずdriverをインストールする 次にUIFlowを試してみる https://docs.m5stack.com/en/quick_start/atom/uiflow

ShunjiHashimoto commented 1 year ago

UI FlowのBeta版ではないほうがブザーモジュールが選択できない。ブラウザならBeta版を選択できるが、一方でAtom Liteと接続することができない。ボーレート?? これでもダメならUIFlowは一旦やめて、ArduionIDEを使うか

ShunjiHashimoto commented 1 year ago

https://laboratory.kazuuu.net/how-to-download-and-install-arduino-ide/ Arduinoならこの通りにやればできる

ShunjiHashimoto commented 1 year ago

https://www.ftdichip.com/Drivers/D2XX/Linux/ReadMe.txt MicroPythonならまずUSBドライバをUbuntuに上記の手順通りに入れる

Ends your super-user session.

Notes on Kernel Built-in Support of FTDI devices.

ここまでのコマンドを打った つぎに、USBの認識をVMで行う http://www.oversea-pub.com/free/environment/2073.html M5Burnerのインストール https://docs.m5stack.com/en/quick_start/atom/mpy 次にVscodeでM5stackの拡張モジュールをインストールする https://docs.m5stack.com/en/quick_start/atom/mpy

VSCode IDE Development.

最後に、写真のようにM5STACK Deviceを選択後、再生ボタンを押すとプログラムが実行される Screenshot from 2022-12-17 04-41-27

ShunjiHashimoto commented 1 year ago

上記コメントのスクショの中のboot.pyに音を鳴らす以下のコードを書き込めば、次回起動時に毎回実行される

from machine import Pin, PWM
import time
import machine

frequency = 440
duty = 0.1
pwm = PWM(Pin(26), frequency, duty) # create and configure in one go
time.sleep(1.0)
pwm.duty(0)
ShunjiHashimoto commented 1 year ago

次にUART通信で音を鳴らす。これができればプログラム実行時に音を鳴らしたり、モード切替時に音がなったりできる。

ShunjiHashimoto commented 1 year ago

https://docs.micropython.org/en/latest/esp8266/quickref.html#uart-serial-bus 参考資料

ShunjiHashimoto commented 1 year ago

上記の資料、こちらの資料両方でTeraterm使って文字が遅れていること確認できた。ただピンのさすところを間違えていただけでした。 https://docs.m5stack.com/en/mpy/advanced/uart

ShunjiHashimoto commented 1 year ago

次にRaspberry piのUARTピンから音を鳴らす!!明日の朝やる!

ShunjiHashimoto commented 1 year ago

https://www.ingenious.jp/articles/howto/raspberry-pi-howto/gpio-uart/ Rasberr piはUARTピンが6こあるらしい。またatom liteとレベル変換が必要かもしれない

ShunjiHashimoto commented 1 year ago

Raspberry piのUART https://tshell.hatenablog.com/entry/2021/03/04/205346

ShunjiHashimoto commented 1 year ago

RaspberryPi -> USB -> USBtoUART -> atom lite's UART reference: https://qiita.com/ytetsuo/items/502ddcb0430a41dcaed4

import serial
import time

#Open SerialDevice
SerDevice = serial.Serial('/dev/ttyUSB0', '9600', timeout=0.1)

#******************************
#Recieve Response
while True:
    #Read data one Line (top->'\r\n')
    L_RecieveData=SerDevice.readline()
    RecieveData = L_RecieveData.decode()

    #Get Data Length
    DataLength = len(L_RecieveData)

    #If DataLength = 2, then Response END!!
    #1行の文字列が2文字があることが受信データの終わりという条件にした
    if DataLength==2:
        break
    else:
        print(RecieveData)

#******************************
#Close Serial Device
SerDevice.close()
ShunjiHashimoto commented 1 year ago

UART通信はできるので、あとはプログラム実行時に上記の方法でUARTを使って文字列をatom liteに送信し、atom liteはそれに従って音を変更できればおけ

ShunjiHashimoto commented 1 year ago

RaspberryPiでatom_lite.pyを実行する
また、AtomLiteから送られてくる信号を表示するために別ターミナルで以下を実行する もし不具合あればsudo chmod 777 /dev/ttyUSB0を実行する

screeen /dev/ttyUSB0

atom_lite.py

import serial
import time

usb_device = serial.Serial('/dev/ttyUSB0', '9600', timeout=1.0)

def main():
    command = "HumanFollow"
    while(True):
        try:
            print("Write signal")
            usb_device.write(command.encode())
            time.sleep(1.0)
        except:
            print("close usb_device", flush=True)
            usb_device.close()
            return

if __name__ == "__main__":
    main()

AtomLiteのboot.pyを実行する boot.py

from machine import Pin, PWM, UART
import time

frequency = 440
duty = 0.1
pwm = PWM(Pin(26), frequency, duty) # create and configure in one go
time.sleep(1.0)
pwm.duty(0)

# Create a serial port instance
uart1 = machine.UART(1, tx=22, rx=19)

# # Initialize the serial port
uart1.init(9600, bits=8, parity=None, stop=1)

# # Is there any content in the cache?
uart1.any()

# # Read the content in the buffer area
uart1.read()

# # # Write content to the serial port
uart1.write('Start to read')

# Read/write case
while True:
    if uart1.any():
        data = uart1.read()
        uart1.write(data)

RaspberryPiのターミナル上に文字列が表示される

HumanFollowHumanFollowHumanFollowHumanFollowHumanFollowHumanFollow
ShunjiHashimoto commented 1 year ago

文字列をdecodeしてif文に書き換えた

from machine import Pin, PWM
import time
import machine
from machine import UART

frequency = 440
duty = 0.1
pwm = PWM(Pin(26), frequency, duty) # create and configure in one go
time.sleep(1.0)
pwm.duty(0)

# Create a serial port instance
uart1 = machine.UART(1, tx=22, rx=19)

# # Initialize the serial port
uart1.init(9600, bits=8, parity=None, stop=1)

# # Is there any content in the cache?
uart1.any()

# # Read the content in the buffer area
uart1.read()

# # # Write content to the serial port
uart1.write('Hello')

# Read/write case
while True:
    if uart1.any():
        data = uart1.read()
        m = data.decode('utf-8')
        if(m == "HumanFollow"):
            pwm = PWM(Pin(26), frequency, duty) # create and configure in one go
            time.sleep(1.0)
            pwm.duty(0)
        else:
            uart1.write(m)

参考:https://note.com/upyc101/n/n36348b4b006b

ShunjiHashimoto commented 1 year ago

https://github.com/ShunjiHashimoto/tang/commit/3a16fbb0c9a53502d61ab8a69ef249e02ac22c1d push済み

ShunjiHashimoto commented 1 year ago

ロボットの起動音はルンバのものを参考にする

do = 1046
re = 587
so = 1567
duty = 1.0
pwm = PWM(Pin(26), so, duty) # create and configure in one go
time.sleep(0.4)
pwm.duty(0)
pwm = PWM(Pin(26), do, duty) # create and configure in one go
time.sleep(0.4)
pwm.duty(0)
pwm = PWM(Pin(26), re, duty) # create and configure in one go
time.sleep(0.4)
pwm.duty(0)
pwm = PWM(Pin(26), so, duty) # create and configure in one go
time.sleep(1.0)
pwm.duty(0)
time.sleep(0.1)
pwm = PWM(Pin(26), so, duty) # create and configure in one go
time.sleep(1.0)
pwm.duty(0)
time.sleep(0.1)
pwm = PWM(Pin(26), so, duty) # create and configure in one go
time.sleep(1.0)
pwm.duty(0)
time.sleep(0.1)

音階参考:http://www15.plala.or.jp/gundog/homepage/densi/onkai/onkai.html https://rt-net.jp/mobility/archives/8971 ルンバの音:https://www.youtube.com/watch?v=qoMXAOxiUeU

ShunjiHashimoto commented 1 year ago

ロボットの起動音、モード切替はこれにする

from machine import Pin, PWM
import time
import machine
from machine import UART

do = 1046
re = 587
so = 1567
do_high = 2000
do_low = 261

duty = 1.0
# ロボットの起動音
pwm = PWM(Pin(26), so, duty) # create and configure in one go
time.sleep(0.4)
pwm.duty(0)
pwm = PWM(Pin(26), do, duty) # create and configure in one go
time.sleep(0.4)
pwm.duty(0)
pwm = PWM(Pin(26), re, duty) # create and configure in one go
time.sleep(0.4)
pwm.duty(0)
pwm = PWM(Pin(26), so, duty) # create and configure in one go
time.sleep(1.0)
pwm.duty(0)
time.sleep(0.1)
pwm = PWM(Pin(26), so, duty) # create and configure in one go
time.sleep(1.0)
pwm.duty(0)
time.sleep(0.1)
pwm = PWM(Pin(26), so, duty) # create and configure in one go
time.sleep(1.0)
pwm.duty(0)
time.sleep(0.1)

# 人への追従モード
time.sleep(1.0)
pwm = PWM(Pin(26), do, duty) # create and configure in one go
time.sleep(0.2)
pwm.duty(0)
pwm = PWM(Pin(26), do_high, duty) # create and configure in one go
time.sleep(0.1)
pwm.duty(0)

# 手動モード
time.sleep(1.0)
pwm = PWM(Pin(26), do_high, duty) # create and configure in one go
time.sleep(0.2)
pwm.duty(0)
pwm = PWM(Pin(26), do, duty) # create and configure in one go
time.sleep(0.1)
pwm.duty(0)
ShunjiHashimoto commented 1 year ago

boot.py

from machine import Pin, PWM, UART
import time
import robot_music

sound  = robot_music.RobotMusic(26, 0.1)
sound.bringup_music()

# Create a serial port instance
uart1 = machine.UART(1, tx=22, rx=19)

# Initialize the serial port
uart1.init(9600, bits=8, parity=None, stop=1)

# Is there any content in the cache?
uart1.any()

# Read the content in the buffer area
uart1.read()

# Write content to the serial port
uart1.write('Hello')

# Read/write case
while True:
    if uart1.any():
        data = uart1.read()
        decoded_data = data.decode('utf-8')
        if(decoded_data == "HumanFollow"):
            sound.follow_mode_music()
        elif(decoded_data == "Manual"):
            sound.manual_mode_music()
        else:
            uart1.write(decoded_data)
    pwm = PWM(Pin(26), 440, 0.5)
    time.sleep(0.2)
    pwm.duty(0)
    time.sleep(0.5)

config.py

class MusicScale():
    do = 1046
    re = 587
    so = 1567
    do_high = 2000
    do_low = 261

robot_music.py

import time
from machine import Pin, PWM

import config

music_scale = config.MusicScale()

class RobotMusic:
    def __init__(self, pin, duty):
        self.pin  = pin
        self.duty = duty

    def bringup_music(self):
        pwm = PWM(Pin(self.pin), music_scale.so, self.duty) 
        time.sleep(0.4)
        pwm.duty(0)
        pwm = PWM(Pin(self.pin), music_scale.do, self.duty) 
        time.sleep(0.4)
        pwm.duty(0)
        pwm = PWM(Pin(self.pin), music_scale.re, self.duty) 
        time.sleep(0.4)
        pwm.duty(0)
        pwm = PWM(Pin(self.pin), music_scale.so, self.duty) 
        time.sleep(1.0)
        pwm.duty(0)
        time.sleep(0.1)
        pwm = PWM(Pin(self.pin), music_scale.so, self.duty) 
        time.sleep(1.0)
        pwm.duty(0)
        time.sleep(0.1)
        pwm = PWM(Pin(self.pin), music_scale.so, self.duty) 
        time.sleep(1.0)
        pwm.duty(0)
        time.sleep(0.1)

    def follow_mode_music(self):
        pwm = PWM(Pin(self.pin), music_scale.do, self.duty)
        time.sleep(0.2)
        pwm.duty(0)
        pwm = PWM(Pin(self.pin), music_scale.do_high, self.duty)
        time.sleep(0.1)
        pwm.duty(0)

    def manual_mode_music(self):
        pwm = PWM(Pin(self.pin), music_scale.do_high, self.duty) 
        time.sleep(0.2)
        pwm.duty(0)
        pwm = PWM(Pin(self.pin), music_scale.do, self.duty)
        time.sleep(0.1)
        pwm.duty(0)
ShunjiHashimoto commented 1 year ago

無事TANG側のラズパイでも動作確認完了した。

ShunjiHashimoto commented 1 year ago

https://zenn.dev/articles/087b04ca268c52/edit

ShunjiHashimoto commented 1 year ago

実際のロボットを起動する手順で動作音を鳴らす実験を今日やる

ShunjiHashimoto commented 1 year ago

動作音を鳴らすことはできたが、少しコードを編集しようとしてVSCodeで以前書いたブログ通りにしたらうまく開けなかった。また今度原因調査する

ShunjiHashimoto commented 1 year ago

M5BurnerでModeをApp mode -> USB modeに変更すれば上記のバグは直った

ShunjiHashimoto commented 1 year ago

boot.py

from machine import Pin, PWM, UART
import time
import robot_music

sound  = robot_music.RobotMusic(26, 0.1)
sound.bringup_music()

try:
    uart1 = machine.UART(2, 9600, tx=22, rx=19)
except:
    pwm = PWM(Pin(26), 440, 0.5)
    time.sleep(0.2)
    pwm.duty(0)
    time.sleep(0.5)

uart1.write('Hello')

なぜかこのコードがreboot後にうまく動作しない シリアルポートを作ろうとして作れていない

ShunjiHashimoto commented 1 year ago
from machine import Pin, PWM, UART
import time
import robot_music

sound  = robot_music.RobotMusic(26, 0.1)
sound.bringup_music()

try:
    uart1 = UART(1, tx=22, rx=19)
    uart1.init(115200, bits=8, parity=None, stop=1)
    uart1.any()
    uart1.read()
    uart1.write('Hello')

except:
    pwm = PWM(Pin(26), 440, 0.5)
    time.sleep(0.2)
    pwm.duty(0)
    time.sleep(0.5)

while True:
    if uart1.any():
        data = uart1.read()
        decoded_data = data.decode('utf-8')
        if(decoded_data == "HumanFollow"):
            sound.follow_mode_music()
        elif(decoded_data == "Manual"):
            sound.manual_mode_music()
        else:
            uart1.write(decoded_data)
        pwm = PWM(Pin(26), 440, 0.5)
        time.sleep(2.0)
        pwm.duty(0)
        time.sleep(0.2)
    else:
        pwm = PWM(Pin(26), 440, 0.5)
        time.sleep(0.2)
        pwm.duty(0)
        time.sleep(2.0)

エラー解決した。 ボーレートの設定がいけていなかったのかも M5Burnerでは125000で設定していので、こちらもそのように設定した。ただ、この設定をやっても昨日の夜はうまく行かなかった気がする。。もう少し様子を見る

ShunjiHashimoto commented 1 year ago

実装完了した👏 人追従プログラムが動いているときはブザーを一定周期で鳴らし、操作者に正常に動作していることを知らせる   また、モードが切り替わるときも音で知らせるようにした。 音の大きさは外で実験して要調整

from machine import Pin, PWM, UART
import time
import robot_music

sound  = robot_music.RobotMusic(26, 0.5)
sound.bringup_music()

try:
    uart1 = UART(1, tx=22, rx=19)
    uart1.init(115200, bits=8, parity=None, stop=1)
    uart1.any()
    uart1.read()
    uart1.write('Hello')

except:
    pwm = PWM(Pin(26), 440, 0.5)
    time.sleep(0.2)
    pwm.duty(0)
    time.sleep(0.5)

heart_on = 0
while True:
    if uart1.any():
        data = uart1.read()
        decoded_data = data.decode('utf-8')
        if(decoded_data == 'hearton'):
            heart_on = 1
        elif(decoded_data == 'heartoff'):
            heart_on = 0
        elif(decoded_data == 'human'):
            sound.follow_mode_music()
        elif(decoded_data == 'manual'):
            sound.manual_mode_music()
        else:
            uart1.write(decoded_data)
            sound.heart_off_music()
        time.sleep(0.5)
    else:
        if(heart_on == 1):
            sound.heart_beat_music()
        else:
            sound.heart_off_music()
ShunjiHashimoto commented 1 year ago

https://github.com/ShunjiHashimoto/tang/pull/229 PRを出して、Mergeした