
今回は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 件のコメント:
コメントを投稿