
今回は128×64のOLEDディスプレイとDscordBotを使ってIoTディスプレイを作成していきます。
今回使用するもの
- RaspberryPi
- OLEDディスプレイ(128×64)
- ジャンプワイヤ
- DiscordBot TOKEN
実現したい動き
DiscordBotにコマンドを送信 モーダルウィンドウでディスプレイに表示したい内容を書く ディスプレイに表示される リセットコマンドを送信 ディスプレイの内容がリセットされる
サンプルコード
ディスプレイの内容をリセットするときはコマンドを送信してボタンを押すようにします。
import discord
from discord.ext import commands
import datetime
from busio import I2C
from adafruit_ssd1306 import SSD1306_I2C
import board
import time
from PIL import Image, ImageDraw, ImageFont
intents = discord.Intents.default()
intents.message_content = True
display = SSD1306_I2C(128, 64, I2C(board.SCL, board.SDA), addr=0x3c)#addr=0x3c
image = Image.new("1", (display.width, display.height))
draw = ImageDraw.Draw(image)
#日本語対応のフォント
font_jp = ImageFont.truetype("/usr/share/fonts/truetype/ipafont-nonfree-uigothic/ipagui.ttf", 17)
bot = commands.Bot(
    command_prefix=commands.when_mentioned_or("!"), debug_guilds=[サーバーID], intents=intents
)
@bot.event
async def on_ready():
    print('[INFO] <' + str(datetime.datetime.now().replace(microsecond=0)) + '> Bot is active')
#モーダルを表示
class sendNote(discord.ui.Modal):
    def __init__(self, *args, **kwargs) -> None:
        super().__init__(
            discord.ui.InputText(
                label="Line 1",
                placeholder="Write a note here",
                style=discord.InputTextStyle.short,
            ),
            discord.ui.InputText(
                label="Line 2",
                placeholder="Write a note here",
                style=discord.InputTextStyle.short,
            ),
            discord.ui.InputText(
                label="Line 3",
                placeholder="Write a note here",
                style=discord.InputTextStyle.short,
            ),
            *args,
            **kwargs,
        )
    #モーダルの内容を取得
    async def callback(self, interaction: discord.Interaction):
        embed = discord.Embed(
            title="Your Request",
            fields=[
                discord.EmbedField(
                    name="Line 1", value=self.children[0].value, inline=False
                ),
                discord.EmbedField(
                    name="Line 2", value=self.children[1].value, inline=False
                ),
                discord.EmbedField(
                    name="Line 3", value=self.children[2].value, inline=False
                ),
            ],
            color=discord.Color.from_rgb(153,170,181)
        )
        await interaction.response.defer()
        
        line_1 = self.children[0].value
        line_2 = self.children[1].value
        line_3 = self.children[2].value
        #print(line_1,line_2,line_3)
                
        display.fill(0)
        display.show()
        
        draw.rectangle((0,0,display.width,display.height), outline=0, fill=0)
        draw.text((0, 0), line_1, font=font_jp, fill=1)        
        draw.text((0, 20), line_2, font=font_jp, fill=1)
        draw.text((0, 40), line_3, font=font_jp, fill=1)
        
        display.image(image)
        display.show()
        
        await interaction.followup.send(embeds=[embed])
#ディスプレイをリセットする
class resetView(discord.ui.View):
    @discord.ui.button(label='reset', style=discord.ButtonStyle.green)
    async def first_button(self, button: discord.ui.Button, interaction: discord.Interaction):
        button.disabled = True
        display.fill(0)
        draw.rectangle((0,0,display.width,display.height), outline=0, fill=0)
        draw.text((39, 28), 'Empty', font=font_jp, fill=1)
        display.image(image)
        display.show()
        await interaction.response.edit_message(content="RESET", view=self)
@bot.slash_command(name="resetnote")
async def view_test(ctx: discord.ApplicationContext):
    """reset"""
    view = resetView()
    await ctx.interaction.response.send_message(content="Reset Button", view=view)
@bot.slash_command(name="sendnote")
async def modal_slash(ctx: discord.ApplicationContext):
    """OLED"""
    modal = sendNote(title="NOTE")
    await ctx.send_modal(modal)
bot.run("DiscordBot TOKEN")
実行結果
ディスプレイに表示
モーダル送信後

OLEDディスプレイの様子

ディスプレイをリセット
ボタンを表示させる(押した後)
1回押すと再び押せないようになります。

OLEDディスプレイの様子

まとめ
ディスプレイの内容が更新されると圧電ブザーなどを用いて音が鳴るようにすると良いかもしれません。
また、リセットボタンはコマンドだけでなくタクトスイッチで物理ボタン化した方がよさそうです。
長い文章を送ると画面から見切れてしまうのでスクロールさせる方法を考える必要があります。

 
 
 
 
 
 
 
0 件のコメント:
コメントを投稿