BLANKFIELD

MP3プレイヤー製作日記1

卒業研究でMP3デコーダのEasyMP3(VS1011)を使ったので、せっかくなのでその経験を活かして趣味でMP3プレーヤーを作ろうと思いました。

実現したい目標を適当に列挙します。
・microSDカードから読み込み
・USBから充電、同時にmicroSDカードの読み書き
・カラー液晶にジャケット表示

要するに一般的なMP3プレイヤーみたいなものが作れたらいいなというわけで、とりあえずここまでで技術的な壁は無いように思えるので、部品が入手でき次第どんどこ作ります。

とりあえずArduino Pro MiniとカラーLCDのe-DISPを手にいれたので、とりあえずカラーLCDのテストをしました。

Arduino Pro Mini(5V)と専用のUSBシリアル変換は千石電商で、カラーLCDのe-DISPはD.D.Lで購入しました。

これらをArduinoのTXとe-DISPのRXを繋ぐだけです。あとはシリアルで文字や命令を送れば文字や図等を表示させることができます。

タクトスイッチを2つ使い、曲選択の真似事をしてみました。

ソースコード:

#include <WString.h>
void setup()
{
  Serial.begin(9600);
  Serial.print("\x1B@3Z"); // 文字コードをUTF-8 に設定
  pinMode(2, OUTPUT);
  digitalWrite(2, HIGH);
  pinMode(3, OUTPUT);
  digitalWrite(3, HIGH);
}
void setCursor(int x, int y) {
    Serial.print("\x1B[");
    Serial.print(y);
    Serial.print(";");
    Serial.print(x);
    Serial.print("H");
}
// 四角形の単色データを背景に表示する。
void drawRect(int buffer, int width, int height, int x, int y, word color) {
    Serial.print("\x1B@0;");
    Serial.print(buffer); Serial.print(";");
    Serial.print(width); Serial.print(";");
    Serial.print(height); Serial.print(";");
    Serial.print(x); Serial.print(";");
    Serial.print(y); Serial.print(";");
    Serial.print(color); Serial.print("z");
}
void clearBuffer(int buffer, int color)
{
  drawRect(0, 320, 240, 0, 0, color);
}
// (x0,y0)-(x1,y1)間にラインを表示する。
void drawLine(int buffer, int x0, int y0, int x1, int y1, word color) {
    Serial.print("\x1B@2;");
    Serial.print(buffer); Serial.print(";");
    Serial.print(x0); Serial.print(";");
    Serial.print(y0); Serial.print(";");
    Serial.print(x1); Serial.print(";");
    Serial.print(y1); Serial.print(";");
    Serial.print(color); Serial.print("z");
}
word n=0;
String str[] = {
  "1. 幕間劇「出会いと巻き添え」",
  "2. アキバ in ワンダーランド",
  "3. 幕間劇「三六五日五時間四八分四五秒」",
  "4. 片道きゃっちぼーる",
  "5. Nursery Time",
  "6. 幕間劇「理想の後宮」",
  "7. 三つ巴-motion~triangular fight",
  "8. 幕間劇「主題歌の甘いささやき」",
  "9. 最強○×計画",
  "10. 切情!佰火繚乱",
  "11. 幕間劇「炒めた車でもありませぬ」",
  "12. Pain Paint Car",
  "13. キュンキュンパニック",
  "14. 幕間劇「街道沿いの楽団達」",
  "15. We Love "AKIBA-POP"!! [NEW TAKE]",
  "16. 幕間劇「アトラクション・デリバリー」",
  "17. Amusement Pack",
  "18. 幕間劇「40ページの招待状」",
  "19. フィナーレ"
};
//0xFFFFFF->0x202020
uint16_t hex2RGB555(long color)
{
  //8bit(256)を5bit(32)にする
  uint8_t r,g,b;
  b = (color & 0xFF)/8;
  g = ((color>>8) & 0xFF)/8;
  r = ((color>>16) & 0xFF)/8;
  return b|(g<<5)|(r<<10);
}
void drawSelectRect(int line ,int fontSize)
{
  clearBuffer(0,32767);//バッファを消す
  drawRect(0, 319, fontSize, 0, line*fontSize, hex2RGB555(0x4b95e5));
}
void fontSettings(int color, boolean enableBold, boolean enableUnderline, boolean enableBlink)
{
  Serial.print("\x1B[");
  Serial.print(color);  Serial.print(";");
  if (enableBold)
    Serial.print("1;");
  else
    Serial.print("29;");
  if (enableUnderline)
    Serial.print("4;");
  else
    Serial.print("24;");
  if (enableBlink)
    Serial.print("5;");
  else
    Serial.print("25;");
  Serial.print("m");
}
void loop()
{  
  //Serial.print("\x1B@4Z");   //小
  Serial.print("\x1B@0Z");   //clear
  Serial.print("\x1B@21Z");   //自動改行しない
  Serial.print("\x1B[>5h");   //カーソル表示しない
  fontSettings(30,0,0,0);
  for(int i=0;i<sizeof(str)/sizeof(str[0]);i++)
    Serial.println(str[i]);
  int cursorY = 0;
  while(1)
  {
    if (!digitalRead(2))
    {
      /*Serial.print("\x1B");
      Serial.print("D");*/
      /*setCursor(39,++cursorY);*/
      drawSelectRect(++cursorY, 16);
      delay(200);
      continue;
    }
    if (!digitalRead(3))
    {
      /*Serial.print("\x1B");
      Serial.print("M");*/
      /*setCursor(39,--cursorY);*/
      drawSelectRect(--cursorY, 16);
      delay(200);
      continue;
    }
  }
}