mametarou963
2021年02月21日作成 (2021年12月07日更新)
製作品 1350
こども向け-親族の絵を押すと音声が流れて、名前を楽しく覚えてもらうプロダクト
背景
コロナ禍になり、親族といえども、自粛の流れの中で会う頻度が減少していると思います。
しかし、お孫さんをもつおじいちゃん、おばあちゃんはできるだけ早くお孫さんに名前を覚えてもらいたいもの。
そこで、おじいちゃん、おばあちゃんがお孫さんに会うことなく存在や名前を覚えてもらうプロダクトを開発しようと考えました。
子どもが物を覚える手段の参考として、「音と絵で覚える子どもの本」のように絵と音を子どもの押す動作で紐づけるグッズを用いると、かなり早く子どもが覚えるということを聞きました。
そこで、親族の写真を子どもが押すと、親族の呼称が流れるプロダクトを開発しようと考えました。
部品
作成手順
画像の準備
画面上には6枚程度の親族画像を表示させたいと考えました。
M5Paperは540x960のため、250x250の正方形画像を6枚準備します。
- resourcesフォルダを作成します
- 250x250の1~6.pngをresourcesフォルダに配置する
- resoucesフォルダ下でimage2gray.pyを実行する→ImageResouce.h生成
folder<Program>
┣Program.ino
┗Program<resources>
┣1.png
┣2.png
┣3.png
┣4.png
┣5.png
┣6.png
┣image2gray.py
┗ageResource.h
*image2gray.pyは以下の場所にあります
https://github.com/m5stack/M5EPD/tree/main/tools/image2gray
microSDカードの準備
- 1~6.pngの呼称に対応した音声を作成する
- SDカードに「1から順に」データを書き込んでいきます
※Grove MP3モジュール v2.0は音声を書き込んだ順にindex番号を指定できます
接続
- Grove MP3モジュール v2.0にmicroSDカードを差し込む
- M5PaperのPort.AとGrove MP3モジュール v2.0をGroveで接続する
- M5Paperにプログラム書き込み
動作のようす
親族の顔をタッチすると、呼称が音声で流れます。
プログラム
M5Paperに以下のプログラムを書き込みます。
M5Paperのコード
#include <SoftwareSerial.h>
#include <MP3Player_KT403A.h>
#include <M5EPD.h>
#include "./resources/ImageResource.h"
// edp
#define PIC_SIZE 250
#define LEFT_INDEXX 10
#define RIGHT_INDEXX 280
#define UPPER_INDEXY 50
#define MIDDLE_INDEXY 320
#define LOWER_INDEXY 590
#define BUTTON_RESET_MSEC 1000
#define DELAY_MSEC 10
int preIndex = 0;
// mp3
#define swtxPin 25
#define swrxPin 32
// Note: You must define a SoftwareSerial class object that the name must be mp3,
// but you can change the pin number according to the actual situation.
SoftwareSerial mp3(swrxPin, swtxPin);
M5EPD_Canvas canvas(&M5.EPD);
void setup()
{
M5.begin();
M5.EPD.SetRotation(90);
M5.EPD.Clear(true);
// 写真の表示
canvas.createCanvas(540, 960);
canvas.setTextSize(3);
canvas.pushImage(LEFT_INDEXX, UPPER_INDEXY ,PIC_SIZE,PIC_SIZE,ImageResource_1_250x250);
canvas.pushImage(RIGHT_INDEXX, UPPER_INDEXY ,PIC_SIZE,PIC_SIZE,ImageResource_2_250x250);
canvas.pushImage(LEFT_INDEXX, MIDDLE_INDEXY ,PIC_SIZE,PIC_SIZE,ImageResource_3_250x250);
canvas.pushImage(RIGHT_INDEXX, MIDDLE_INDEXY ,PIC_SIZE,PIC_SIZE,ImageResource_4_250x250);
canvas.pushImage(LEFT_INDEXX, LOWER_INDEXY ,PIC_SIZE,PIC_SIZE,ImageResource_5_250x250);
canvas.pushImage(RIGHT_INDEXX, LOWER_INDEXY ,PIC_SIZE,PIC_SIZE,ImageResource_6_250x250);
canvas.pushCanvas(0,0,UPDATE_MODE_GC16);
// タッチパネルの準備
M5.TP.SetRotation(90);
// mp3初期設定
pinMode(swrxPin, INPUT);
pinMode(swtxPin, OUTPUT);
mp3.begin(9600);
delay(100);
SelectPlayerDevice(0x02); // Select SD card as the player device.
SetVolume(0x1E); // Set the volume, the range is 0x00 to 0x1E.
}
// 写真番号に応じた動作
void touchAction(int picNumber){
SpecifyMusicPlay(picNumber);
Serial.printf("x:%d\r\n", picNumber);
}
// 領域内をタッチしたかどうか判定
bool InsideSquare(int squareIndexX, int squareIndexY, int picSize, int touchX , int touchY)
{
if(touchX < squareIndexX) return false;
if((squareIndexX + picSize) < touchX) return false;
if(touchY < squareIndexY) return false;
if((squareIndexY + picSize) < touchY) return false;
return true;
}
// どの写真を押したかチェック
int CheckTouchPicture(int touchX , int touchY)
{
int index = 0;
if(InsideSquare(LEFT_INDEXX, UPPER_INDEXY ,PIC_SIZE, touchX, touchY)) index = 1;
else if(InsideSquare(RIGHT_INDEXX, UPPER_INDEXY ,PIC_SIZE, touchX, touchY)) index = 2;
else if(InsideSquare(LEFT_INDEXX, MIDDLE_INDEXY ,PIC_SIZE, touchX, touchY)) index = 3;
else if(InsideSquare(RIGHT_INDEXX, MIDDLE_INDEXY ,PIC_SIZE, touchX, touchY)) index = 4;
else if(InsideSquare(LEFT_INDEXX, LOWER_INDEXY ,PIC_SIZE, touchX, touchY)) index = 5;
else if(InsideSquare(RIGHT_INDEXX, LOWER_INDEXY ,PIC_SIZE, touchX, touchY)) index = 6;
return index;
}
// 0:タッチなし
// 1~6:写真をタッチ
int checkTouch(void){
int index = 0;
if(M5.TP.avaliable()){
if(!M5.TP.isFingerUp()){
M5.TP.update();
tp_finger_t FingerItem = M5.TP.readFinger(0);
index = CheckTouchPicture(FingerItem.x,FingerItem.y);
}
if(index != 0 && preIndex != index){
preIndex = index;
return index;
}else{
// 更新なし
return 0;
}
}
return 0;
}
int totalMsec;
void loop()
{
int picIndex = checkTouch();
if(picIndex != 0){
touchAction(picIndex);
totalMsec = 0;
}
// 押したことを初期化
if(preIndex != 0){
if(totalMsec < BUTTON_RESET_MSEC){
totalMsec = totalMsec + DELAY_MSEC;
}else{
preIndex = 0;
totalMsec = 0;
}
}else{
preIndex = 0;
totalMsec = 0;
}
delay(DELAY_MSEC);
}
投稿者の人気記事
-
mametarou963
さんが
2021/02/21
に
編集
をしました。
(メッセージ: 初版)
-
mametarou963
さんが
2021/02/21
に
編集
をしました。
-
mametarou963
さんが
2021/02/21
に
編集
をしました。
-
mametarou963
さんが
2021/02/24
に
編集
をしました。
-
mametarou963
さんが
2021/02/24
に
編集
をしました。
-
mametarou963
さんが
2021/12/07
に
編集
をしました。
ログインしてコメントを投稿する