フォト
2019年1月
    1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30 31    
無料ブログはココログ

arduino

2019年1月16日 (水)

VS1053 MP3 プレーヤー・シールドの調査 (2) 録音機能(2)

前回からの続きです。

目的の、MSXのカセットテープインタフェースでのプログラム保存、
結論としては、録音品質が良くなく、上手くいきませんでした。

01


このボードでは次の問題が発生しました。
1) ライン入力モードはモノラル録音ができない
2) ライン入力モード経由の録音では、録音の音が小さい


前回利用したサンプルスケッチ record_oog では、
下記の部分を true から false に変更することでボード上のコンデンサーマイクからの
録音からライン入力からの録音に切り替えることが出来ます。

musicPlayer.startRecordOgg(false); // use microphone (for linein, pass in 'false') 

ところが、ライン入力では、何故かモノラルでの録音が出来ませんでした。
モノラルをステレオに変換(LをR・Lの両方に接続)も試したのですが、
録音出来ません。

仕方がなく、ステレオ録音で試したのですが、今度は書き込み速度が追いつきません。
ステレオ録音ではデータ量が2倍なので、当然でしょう。

サンプリングレート 16kHz ステレオ録音に変更することで、
一応、録音は出来たのですが、録音品質以前に音が小さくでダメでした。
このボード、再生のためのアンプは載っているのですが、
録音入力のアンプは載っていないようです。

録音レベルの調整をレジスタ操作で行えるので試してみたのですが、
ノイズが乗って、音質が劣化してダメでした。

02

デジタル的に音量を上げているっぽいです。

ちなみに、レジスタの設定は ライブラリの Adafruit_VS1053.cpp ファイルの
startRecordOgg(boolean mic) 関数内の記述を変更すれば可能です。

まとめ

ということで、残念ながらこのボードでのデーターレコーダの実装はダメっぽいです。
ただし、再生機能はかなり優れているので、別途色々と遊んでみようと思います。

今回の実験で参考にしたサイト
放課後の電子工作 - VS1053b 日本語データシート私家版
日本語訳、VS1053Bの理解に大変参考になりました。有益な情報の公開に感謝します。



2019年1月11日 (金)

VS1053 MP3 プレーヤー・シールドの調査 (2) 録音機能

今回はVS1053 MP3 プレーヤー・シールド の録音機能の調査です。

先日利用したライブラリを調べると、録音機能に関するAPIが存在しません。
Wikiにも解説がありません。

このボード、ピン構成やElecrowWiki リンク先を見ると、
SparkFun MP3 Player Shield がベースとなっているようです。

ベースのボードには録音機能(コンデンサーマイク、マイク端子)が無いんですよね。
それで、録音機能については何も解説が無いようです。

  商品  SparkFun MP3 Player Shield  (チュートリアル MP3 Player Shield Hookup Guide V15
  01
  (チュートリアルのMP3 Player Shield Hookup Guide V15 はこれはこれで参考になります)
 

う~ん、困った..
色々と調べると、
VS1053の公式フォーラム(VSDSP Forum)を見るとAdafruitのボード用の
ライブラリ(Adafruit_VS1053_Library)を使うと録画が出来ると判明しました。

  参考: AdafruitのVS1053ボード
  VS1053 Codec + MicroSD Breakout - MP3/WAV/MIDI/OGG Play + Record - v4

 
02
 
チュートリアル Adafruit VS1053 MP3/AAC/Ogg/MIDI/WAV Codec Breakout Tutorial


録音機能の実装


前置きが長くなりましたが、本題の録音機能について試してみました。
Ogg Vorbisという形式にてSDカード上にファイルとして録音します。

まずは、ボード上のコンデンサーマイクを使った録音のお試しです。

Adafruitのチュートリアルを参考にして、Adafruit_VS1053_Library をダウンロードし、
サンプルスケッチのrecode_ogg を動かしてみました。

  05

そのままでは動かないので次の修正を行いました。
  1)利用するピンの変更(=>スケッチの変更)
  2)SDライブラリの利用からSdFatライブラリの利用に変更(=>スケッチ、ライブラリの変更)
  3)VS1053 ogg encoder プラグインの変更(=>スケッチの変更)

VS1053用プラグインのダウンロード

Adafruit_VS1053_Library
のサンプルスケッチ recode_ogg のフォルダに
モノラル 44.1KHz, 高品質録音のプラグイン v44k1q05.img が用意されているのですが、
Arduinoの処理が間に合わず、音飛び発生や、ファイルが壊れて再生出来ずでした。

そこで、別のプラグインを利用しました。
公式サイト(VLSI社) には、別のプラグインが公開されてます。
用途に応じて選択して利用することが出来ます。下記のリンクからダウンロードできます。

  ・VS1053 Ogg Vorbis Encoder Application
    http://www.vlsi.fi/fileadmin/software/VS10XX/vs1053-vorbis-encoder-170c.zip

解凍したフォルダprofilesの中の vencXXkYqZZ.img がプラグインです。
下記の組み合わせで複数用意されています。
  XX: サンプリング周波数 08: 8kHz、16:16kHz、44:44kHz、
  Y:   1:モノラル、2:ステレオ
  ZZ: 品質00~05 or 10 数字が大きいほど高品質

試した感じでは、44kHzでは、ステレオ録音は処理が追いつきません。
  44kHzでは モノラル venc44k1q04.img
  16kHzでは モノラル venc16k1q10.img 、ステレオ venc16k2q5.img
がちょうど良い感じでした。

ここでは、venc44k1q04.img  を v44k1q04.img にファイル名を変更して
SDカードのルートフォルダにコピーします。

ライブラリの修正


Sdfat対応のために、ヘッダーファイル Adafruit_VS1053.hに PREFER_SDFAT_LIBRARY の定義を追加します。

#define ADAFRUIT_VS1053_Hの次の行に追加しました。
  #ifndef ADAFRUIT_VS1053_H
  #define ADAFRUIT_VS1053_H
  #define PREFER_SDFAT_LIBRARY


スケッチの
修正

ピン割り付けを変更しています。録音開始のボタンはD3を使いました。
/*************************************************** 
  This is an example for the Adafruit VS1053 Codec Breakout

  Designed specifically to work with the Adafruit VS1053 Codec Breakout 
  ----> https://www.adafruit.com/products/1381

  Adafruit invests time and resources providing this open source code, 
  please support Adafruit and open-source hardware by purchasing 
  products from Adafruit!

  Written by Limor Fried/Ladyada for Adafruit Industries.  
  BSD license, all text above must be included in any redistribution
 ****************************************************/

// This is a very beta demo of Ogg Vorbis recording. It works...
// Connect a button to digital 7 on the Arduino and use that to
// start and stop recording.

// A mic or line-in connection is required. See page 13 of the 
// datasheet for wiring

// Don't forget to copy the v44k1q05.img patch to your micro SD 
// card before running this example!


// include SPI, MP3 and SD libraries
#include <SPI.h>
#include <Adafruit_VS1053.h>
// SDライブラリからSdFatライブラリの利用に変更 by たま吉さん
//#include <SD.h>
#include "SdFat.h"
SdFat SD;

// ピン割り付けの変更 by たま吉さん
// define the pins used
//#define RESET 9      // VS1053 reset pin (output)
//#define CS 10        // VS1053 chip select pin (output)
//#define DCS 8        // VS1053 Data/command select pin (output)
//#define CARDCS A0     // Card chip select pin
//#define DREQ A1       // VS1053 Data request, ideally an Interrupt pin

#define RESET 8      // VS1053 reset pin (output)
#define CS 6         // VS1053 chip select pin (output)
#define DCS 7        // VS1053 Data/command select pin (output)
#define CARDCS 9     // Card chip select pin
#define DREQ 2       // VS1053 Data request, ideally an Interrupt pin

//#define REC_BUTTON 7
#define REC_BUTTON 3

Adafruit_VS1053_FilePlayer musicPlayer = Adafruit_VS1053_FilePlayer(RESET, CS, DCS, DREQ, CARDCS);

File recording;  // the file we will save our recording to
#define RECBUFFSIZE 128  // 64 or 128 bytes.
uint8_t recording_buffer[RECBUFFSIZE];

void setup() {
  Serial.begin(115200);
  Serial.println("Adafruit VS1053 Ogg Recording Test");

  // initialise the music player
  if (!musicPlayer.begin()) {
    Serial.println("VS1053 not found");
    while (1);  // don't do anything more
  }

  musicPlayer.sineTest(0x44, 500);    // Make a tone to indicate VS1053 is working
 
  if (!SD.begin(CARDCS)) {
    Serial.println("SD failed, or not present");
    while (1);  // don't do anything more
  }
  Serial.println("SD OK!");
  
  // Set volume for left, right channels. lower numbers == louder volume!
  musicPlayer.setVolume(10,10);
  
  // when the button is pressed, record!
  pinMode(REC_BUTTON, INPUT);
  digitalWrite(REC_BUTTON, HIGH);
  
  // load plugin from SD card! We'll use mono 44.1KHz, high quality
  // プラグインの変更 by たま吉さん (mono 44.1KHz, middle quality)
  //  if (! musicPlayer.prepareRecordOgg("v44k1q05.img")) {
  if (! musicPlayer.prepareRecordOgg("v44k1q04.img")) {
     Serial.println("Couldn't load plugin!");
     while (1);    
  }
}

uint8_t isRecording = false;

void loop() {  
  if (!isRecording && !digitalRead(REC_BUTTON)) {
    Serial.println("Begin recording");
    isRecording = true;
    
    // Check if the file exists already
    char filename[15];
    strcpy(filename, "RECORD00.OGG");
    for (uint8_t i = 0; i < 100; i++) {
      filename[6] = '0' + i/10;
      filename[7] = '0' + i%10;
      // create if does not exist, do not open existing, write, sync after write
      if (! SD.exists(filename)) {
        break;
      }
    }
    Serial.print("Recording to "); Serial.println(filename);
    recording = SD.open(filename, FILE_WRITE);
    if (! recording) {
       Serial.println("Couldn't open file to record!");
       while (1);
    }
    musicPlayer.startRecordOgg(true); // use microphone (for linein, pass in 'false')
  }
  if (isRecording)
    saveRecordedData(isRecording);
  if (isRecording && !digitalRead(REC_BUTTON)) {
    Serial.println("End recording");
    musicPlayer.stopRecordOgg();
    isRecording = false;
    // flush all the data!
    saveRecordedData(isRecording);
    // close it up
    recording.close();
    delay(1000);
  }
}

uint16_t saveRecordedData(boolean isrecord) {
  uint16_t written = 0;
  
    // read how many words are waiting for us
  uint16_t wordswaiting = musicPlayer.recordedWordsWaiting();
  
  // try to process 256 words (512 bytes) at a time, for best speed
  while (wordswaiting > 256) {
    //Serial.print("Waiting: "); Serial.println(wordswaiting);
    // for example 128 bytes x 4 loops = 512 bytes
    for (int x=0; x < 512/RECBUFFSIZE; x++) {
      // fill the buffer!
      for (uint16_t addr=0; addr < RECBUFFSIZE; addr+=2) {
        uint16_t t = musicPlayer.recordedReadWord();
        //Serial.println(t, HEX);
        recording_buffer[addr] = t >> 8; 
        recording_buffer[addr+1] = t;
      }
      if (! recording.write(recording_buffer, RECBUFFSIZE)) {
            Serial.print("Couldn't write "); Serial.println(RECBUFFSIZE); 
            while (1);
      }
    }
    // flush 512 bytes at a time
    recording.flush();
    written += 256;
    wordswaiting -= 256;
  }
  
  wordswaiting = musicPlayer.recordedWordsWaiting();
  if (!isrecord) {
    Serial.print(wordswaiting); Serial.println(" remaining");
    // wrapping up the recording!
    uint16_t addr = 0;
    for (int x=0; x < wordswaiting-1; x++) {
      // fill the buffer!
      uint16_t t = musicPlayer.recordedReadWord();
      recording_buffer[addr] = t >> 8; 
      recording_buffer[addr+1] = t;
      if (addr > RECBUFFSIZE) {
          if (! recording.write(recording_buffer, RECBUFFSIZE)) {
                Serial.println("Couldn't write!");
                while (1);
          }
          recording.flush();
          addr = 0;
      }
    }
    if (addr != 0) {
      if (!recording.write(recording_buffer, addr)) {
        Serial.println("Couldn't write!"); while (1);
      }
      written += addr;
    }
    musicPlayer.sciRead(VS1053_SCI_AICTRL3);
    if (! (musicPlayer.sciRead(VS1053_SCI_AICTRL3) & _BV(2))) {
       recording.write(musicPlayer.recordedReadWord() & 0xFF);
       written++;
    }
    recording.flush();
  }

  return written;
}

ボタンを押すと録音開始、再度押して録音終了です。
(ボタン操作がちょっとシビアで、瞬間的に押さないと開始・終了を繰り返します)

動作状況は、シリアルコンソールで確認できます。

04

試してみた感じでは、一応は録音できました。
oggファイルの再生は、ブラウザのChromeにドラッグ&ドロップして再生しました。

ただし、現時点では
  ・音が小さい
  ・音質が今一
でした。

もうちょっとどうにかならないか、調べてみます。


2019年1月10日 (木)

VS1053 MP3 プレーヤー・シールドでMIDIファイルの再生

VS1053 MP3 プレーヤー・シールド」、MIDIファイルの再生が出来るようなので、
どんな感じの音が出るのか、動作確認してみました。

01

先日使ったサンプルスケッチ fileplayer.inoMIDIファイルを再生してみました。


演奏の様子


アンプ付きのスピーカーに接続して音を出しています。
以前どこかで入手したQueenの「Bohemian Rhapsody」のMIDIファイルを再生してみました。



かなりいい感じに演奏出来ています。
(若干ホワイトノイズが乗っていますが、撮影に使ったデジカメのせいです)

このボードでは、MIDIファイルはFormat 0にしか対応していないため、
SMFConverter for Windows」を使ってFormat 0に変換しました。

色々と遊べそうです。
ストリーミングも出来るみたいで、ESP8226を使ったインターネットラジオの実装例があるようです。

このボードに載っているDSPプロセッサのVS1053
結構使われているようで、秋月電子でも単体売りされています。
秋月電子 MP3デコーダ VS1053b
02

MSX用のデータレコーダの実装とは別途、用途を探りたいと思います。

2019年1月 8日 (火)

VS1053 MP3 プレーヤー・シールドの調査

MSXのデータレコーダ用に使えるのではないかと思い、注文したボードが到着しました。

商品購入サイト
  VS1053B Stereo Audio MP3 Player Shield

  06

到着した製品

  01

Aliexpressのため、当然マニュアル等の付属品はなく、本体のみでした。
商品ページにもマニュアル類の記載がありません。

基板上の刻印 「VS1053 MP3 Sheald」でググってみると、
ElecrowGETECHの製品に類似のものがあります。どうもこの製品っぽいです。

それぞれのページにWiki、ライブラリ、サンプルプログラムのリンクがあり、
製品概要が分かりました。

このボードに関する情報

  製品 Elecrow VS1053 MP3 Shield (Wikiページはこちら

   04

  製品 GETECH Arduino MP3 shield board with TF card (Wikiページはこちら

   03


動作確認

まずは、とりあえずボードの製品チェック、サンプルプログラムで動作確認してみます。

上記それぞれのWikiには、ボードで利用可能な、ライブラリ及びサンプルプログラム
のリンクが掲載されています。

だだし、ダウンロードして確認すると、
両方ともライブラリ Arduino_Library-vs1053_for_SdFat の古いバージョンのようです。
Arduino 1.8.7環境では、コンパイルエラーとなりました。
そこで最新版の Arduino_Library-vs1053_for_SdFatを使って動作確認を行いました。

Arduino Unoにシールドを載せ、スピーカー端子にアンプ無しスピーカーを接続します。

07

ライブラリのサンプルスケッチ fileplayer.ino を利用しました。

05

問題なくコンパイル出来ました。
実行すると、メニューが表示されます。

06

SDカードには、あらかじめ2つのMP3ファイル:hello.mp3hello.wav
入れています。
この2つのファイルは「MP3プレーヤーでMSXにプログラムをロードさせる」で
利用したHello,Worldを表示するプログラムデータです。
hello.mp3hello.wavMP3形式に変換したものです。

再生したいファイルリストの番号を入力して送信すると、
スピーカーから「ピー、ガー・ガー」と音が出力出来ました。
問題なく動作しているようです。

このスケッチプログラムでは、mp3形式wav形式の両方を再生出来ました。


MSXでカセットテープ代わりに使えるかのか確認


本来の目的の、MSXのカセットテープインタフェースにてプログラムをロードさせてみました。

デフォルトでは、失敗しましたがメニューの+コマンドでボリュームを最大の -2dBにすると
MSXでロードすることが出来ました。mp3形式wav形式ともOKでした。

機種によては、レベル不足となるかもしれません。間にアンプを入れた方が良さそうです。

08

ロードしたプログラムも実行することが出来ました。

10

とりあえず、ロードは出来たので次はMSXから音声データとしてSDカードに
保存出来るかを確認したいと思います。



2018年12月25日 (火)

CASduinoを試してみました

Arduinoカセットテープ ドライブをエミュレートする、CASduinoとういのを見つけ、
面白そうなので、試してみました。

昔(30年前)の8ビットパソコンのプログラム保存方法といえば、
カセットテープが標準的な方法でした。「ピー、ガー・ガ―」と音で記録保存します。
CASduinoは、「ピー、ガー・ガ―」音を生成してMSXにプログラムとしてロードさせるものです。

01

参考にしたサイト
・MSX – Arduino as Tape Drive (CASDuino)
  https://modelrail.otenko.com/arduino/msx-arduino-as-tape-drive-casduino


動作の様子

カセットテープをプログラム保存メディアとして使ったことが無い世代の方には
意味不明な動画かもしれません。

MSXは、ヤフオクで1,000円で落札したSANYO MPC-2 WAVY2 を利用しました。

上の動画では、
ブラウザ上で動くMSXエミュレータWMSX(https://webmsx.org)で作成した
カセットテープイメージ形式(CAS形式)のプログラムを実機のMSXに読み込ませています。

CAS形式のファイル(拡張子.CAS)は、カセットテープの音声データを、
バイナリーデータ化したのもで、MSXの世界では標準的に使われているようです。
そのファイルの作成にあたり、MSXエミュレータWMSX を利用しました。

04

1行プログラム("hello,world"を表示)を、
CSAVEコマンドでカセットテープ(当然エミュレータ)に保存します。

05

エミュレータのメニューでブランクのテープの作成し、CSAVEコマンドで
保存したプログラムを更にCAS形式のファイルとしてSDカードに保存します。
ここでは、"hello.cas"という名前で保存しました。

このファイルをCASDuinoで実機のMSXに読み込ませることが出来ます。


CASDuinoの製作について

CASDuinoの実装は、手持ちのSDカードロガーシールドをベースとして、
先日購入したキャラクタ液晶をI2Cで接続しています。

CASDuinoの最新版V1.1.7のソースを見ると、
表示デバイスはOLED(SSD1306)ディスプレイ、 P8544モノクログラフィックディスプレイにも
対応しているようです。

データ通信速度は、最大速度で 3675ボーレートまで対応しているようです。
MSXの仕様では1200、2400ボーレートが利用出来るのですが、MSXBIOSレベルでは
3600ボーレートにも対応しているようです。
更にちょことだけ、オーバースペックの3675ボーレートも機種によっては利用出来るようです。

04_2

とりあえず、3600ボーレートで利用しました。
ボーレートの設定は、内部EEPROMに保存することが出来ます。
以降の利用では、再設定不要です。

データ出力(音声)は、矩形波を生成して出力してます。
圧電スピーカーを付けるとモニター出来ます。

ピンからの出力だけではラベル不足になるようで、参考にしたサイトでは
アンプモジュールを利用して増幅しています。
私も同じものを利用しましたが、オペアンプやトランジスタを使った増幅でも
行けると思います。

03

比較的実装は楽でしたが、MSXに接続するための8ピンDINコネクタが類の入手が
意外と困難でした。

結局、Aliexpressにてパーツを見つけました。

07

06_2

DIN 8ピンオス - オス ケーブルを自作しました。


最後に

さてこの、CASduino、残念ながらデータのセーブに対応していません。
データのロード専用となります。

用途としては、ゲームローダ専用機のようです。
インターネット上に公開されているCAS形式のゲームイメージをSDカードにいれて
ロード出来ます。
MSXでプログラムをロードする手段としては、安価でお手軽な手段なのは確かです。

ただし、3600ボーレートとだと、
450バイト/秒なので32Kバイトのゲームをロードするのに73秒、
ヘッダー部やらいろいろと入れると2分はかかると思います。

プログラムの保存も含め、何にか別の手段を模索中です。

追記

実験的に実装したCASduino、このままでは使いにくいので、
ユニバーサル基板に実装し直しました。

Dscn9222

裏側にArduino Pro miniを使っています。
ディスプレイはOLEDに変更しました。
裏には、同じ基板をかぶせて保護するようにしています。

Dscn9212

3.3V電源のみ対応の小型のマイクロSDカードスロットを使いたいため、
5V 16MHz版 Arduino pro miniを3.3Vで動かしています。

マイクロUSBコネクタから5Vを三端子レギュレータで3.3Vに落として
全体の電源として利用しています。

Dscn9226

とりあえず、いい感じに利用出来るようになりました。

Dscn9221

ちょっとしたプログラムの持ち運びに利用出来るでしょう。

2018年12月22日 (土)

Aliexpressの安価なキャラクタ液晶モジュールの動作確認

Aliexpressで安価なキャラクタ液晶モジュールを見つけ、購入しました。

1602 16x2 HD44780 for Arduino Character LCD /w IIC/I2C Serial Interface Adapter Module DIY KIT

01

16文字 x 2行 のパラレル接続の液晶モジュールと I2C変換モジュールがセットで$2.17です。

到着した製品

梱包も中身も特に問題なし。

Dscn9168

Dscn9169

基板の刻印や、乗っているICを調べてみると、それぞれのモジュールは、
・フィリップス社製PCF8574(8-bit I/O expander for I2C-bus)搭載モジュール
・1602A(16x2 コントローラHD44780)
のようです。

aitendoで販売されている、下記の製品とまったく同じもののようです。
液晶I/Fモジュール(I2C) [IFB-I2C-8574]   
STNキャラクタ液晶(16x2) [1602A-V2] の青色(1602A-V2-B)バージョン

説明書が無いのですが、裏側にはんだ付けするだけで良いようです。

Dscn9171

左側の4つの端子(I2C、GND、5V)だけで制御出来ます。
可変抵抗でLEDバックライトの調整が出来るようです。

早速、はんだ付けしてArduinoに接続して動作確認してみました。

Dscn9189

手持ちのデジカメでは、今一ちゃんと撮れていませんが、
見た目は写真よりも文字がくっきり表示出来き、視野角も広いです。

Dscn9185

動作確認には、下記のライブラリを利用しました。

利用ライブラリ
・LiquidCrystal_I2C
  https://github.com/johnrickman/LiquidCrystal_I2C

動作確認スケッチ

ライブラリに添付のサンプルプログラムのHelloWorldを少々修正しただけです。
(4行表示するメッセージを2行表示に修正)

#include <LiquidCrystal_I2C.h>

LiquidCrystal_I2C lcd(0x27,16,2);  // set the LCD address to 0x27 for a 16 chars and 2 line display

void setup() {
  lcd.init();                        // initialize the lcd 
  // Print a message to the LCD.
  lcd.backlight();
  lcd.setCursor(0,0);
  lcd.print(" Hello, world!");
  lcd.setCursor(0,1);
  lcd.print(" LCD 1602A(I2C)");
}  


void loop() {

}

安くてお手軽に使えて良い製品です。
このモジュールは、MSX用のテープ・ドライバ CASDuinoを製作に使う予定です。

2018年12月13日 (木)

豊四季Tiny BASIC for Arduino STM32 をV0.87に更新しました

豊四季Tiny BASIC for Arduino STM32 をV0.87に更新しました。

公開サイト
・豊四季タイニーBASIC for Arduino STM32V0.87β
  https://github.com/Tamakichi/ttbasic_arduino_stm32

  テストが不十分でβ版です^^;

マニュアルの作成がまだまだ進まないのですが、とりあえすコマンドリファレンスを
V0.87対応に更新しました。

・「豊四季タイニーBASIC for Arduino STM32」 コマンドリファレンス(更新中)

V0.87の主な追加機能


・漢字フォント利用の対応(SDカード上のシフトJISコードフォントファイルを利用)
   - KANJI コマンドによる全角文字列の描画が出来る
   - SETKANJI コマンドで全角文字描画時のフォントサイス等の設定が出来る
   - KFONT コマンドによる、漢字フォントデータの取得が出来る

・内部フラッシュメモリのプログラム保存領域の直接書き換え対応
   - 仮想化ドレスPRG2 の追加
   - BANK コマンドの追加
   - FWRITE コマンドの追加、
   - BLOAD コマンドの機能強化でバイナリファイルに直接書き込みに対応

   この機能は少々危険ですが、プログラム保存領域4096バイト x 6本の領域を
   有効利用するために、データを配置して利用出来たら.. と思い追加しました。
   
   SDカード上のバイナリーファイルをBLOADコマンドでフラッシュメモリに
   読み込んだり出来ちゃいます。
   ファイルからちょっとした画像や文書データを読み込んで配置出来ます。

・バイナリファイル操作の機能強化
   - BLOADBSAVE コマンドで、ファイル内読み書き位置を指定可能にしました

   ちょっとしたレコードファイルの構造を実現できると思います。

・文字列比較関数の追加
   - STRCMP 関数を追加しました

・グラフィック描画関連のコマンド追加
   - GCOLOR GCLS コマンドの追加

・その他
   いくつかの不具合対応を行いました


ここで、あらためて補足ですが、
豊四季Tiny BASICのオリジナル版開発は私ではなく、鈴木氏です。
私は、オリジナル版をSTM32対応し、機能拡張しているのみです。
オリジナル版  https://github.com/vintagechips/ttbasic_arduino


今後の予定としては、機能追加はこのあたり迄として、
ドキュメントの充実、BASICプログラムの作成、基板作成を行っていこうと思っています。

2018年12月 7日 (金)

豊四季Tiny BASIC for Arduino STM32で日本語フォント利用対応中(4)

豊四季Tiny BASIC for Arduino STM32の日本語フォント対応版、
ちびちびとドキュメント類を作成しています。
ドキュメント作成は、モチベ―ジョンが下がり、なかなか作業が進みません。

今回は、リファレンスマニュアルよりも先に「早見表」(クイックリファレンス)を
先に作成しました。PDF化して添付を予定しています。

Dscn9093

パウチして、傍らにおいて参照する感じでの利用を想定しています。

Dscn9091

コマンド、編集キー、ボードピン配置、ピン用途一覧、結線図の
7ページにまとめています。

01

コマンド一覧を1枚に収めるのにちょっと苦労しました。

02

ピン割り付けと、起動時のコンソール選択の設定関連のシート

03

英語版も作成したいところですが、とりえずは後回しです。

追記

このドキュメントをブランチの方に追加しました。
ttbasic_arduino_stm32/TinyBASIC早見表.pdf

2018/12/08 修正

マスターブランチにマージしました。
早見表は下記のリンクからの参照となります。
ttbasic_arduino_stm32/TinyBASIC早見表.pdf

キーワード一覧(簡易コマンドリファレンス) キーワード.html追加しました。

04


2018年11月30日 (金)

豊四季Tiny BASIC for Arduino STM32で日本語フォント利用対応中(3)

豊四季Tiny BASIC for Arduino STM32の日本語フォント乗せ対応、
追加したい機能の実装はほぼ完了し、マニュアル作成と動作確認中です。
文字列比較関数等も追加しました。

動作の様子


NTSC版で全角フォントを表示するデモです。
全角フォントは8、10、12、14、16、20、24ドットの7種類が利用出来ます。
また、倍角、四倍角等の拡大表示も可能です。

デモのプログラムソース

10 CONSOLE 0
20 GCLS
30 SETKANJI 20,1,0,0
40 KANJI 10,0,"こんにちは、埼玉!"
50 SETKANJI 10,1,2,1
60 KANJI 10,30,"7種類の漢字フォントを使って、"
70 KANJI 10,42,"全角表示が出来るようになりました。"
80 SETKANJI 24,2,2,2
90 KANJI 0,60,"豊四季"
100 SETKANJI 20,2,0,0
110 KANJI 0,106,"Tiny BASIC"
120 SETKANJI 16,1,0,0
130 KANJI 0,150,"for Arduino STM32"
140 SETKANJI 24,2,0,0
150 KANJI 90,170,"V0.87"
160 WAIT 2000
170 FOR I=1 TO GW
180 GSCROLL 0,0,GW-1,GH-1,LEFT
190 WAIT 10
200 NEXT I
210 WAIT 2000
220 GOTO 20

マニュアル作成とテストにちょっと手こずっています。

現時点のバージョンは、GitHubのブランチからダウンロード可能です。
(このブランチは随時更新しています)
https://github.com/Tamakichi/ttbasic_arduino_stm32/tree/add_SDSfonts

   2018/12/08 修正 マスターブランチにマージしました(上記ブランチは削除します)。
                     => https://github.com/Tamakichi/ttbasic_arduino_stm32

ただし、ファームウェア・マニュアル等は旧版のままです。
ソースからコンパイルする必要があります。

フォント利用には、解凍したfontbinの下にあるSFONT.BINをSDカードに入れる必要があります。

描画速度をもう少し何とかしたいです。
漢字フォントをSPI接続のフラッシュメモリに配置すれば高速化出来るのですが、
フラッシュメモリの入手と書き込みがちょっと面倒なので悩みどころです。

また、BASICプログラムのソースが英字大文字だと可読性が悪いので、
GOTO => GoTo
WAIT => Wait
SETKANJI => SetKanji
IF => If
FOR I=0 TO 10 STEP  2:NEXT I => For I=0 To 10 Step 2: Next I
のように大文字小文字を混ぜる感じにしようかと検討中です。

2018年11月20日 (火)

RobotDyn STM32 Miniボード(Blue Pill互換)でJPEG画像表示

RobotDyn STM32 Miniボード(Blue Pill互換)でJPEG画像の表示をやってみました。
(BluePillより面積が狭いので、ブレッドボードで多線が出来ます)

グラフィック液晶モジュール は、
ILI9341搭載(SPI接続)+ SDカードスロット付きのものを利用しました。

Dscn9014

グラフィック液晶モジュールのスロットに刺したSDカードに
320x240ドット JPEG形式のフルカラー画像を配置し、それを表示しています。
開発環境はArduino STM32を利用しています。

JPEG表示は、Arduino UNOではSRAMの容量的に無理(バッファに2kバイト必要)ですが、

Blue Pillでは比較的簡単に表示出来ました。

動いている様子

これくらいの、速度で表示出来ればOKでしょう。

構成

03
※クリックすると拡大表示します

結線表
04
利用したテスト画像(test1.jpg)

Test1


スケッチは下記のサイトのESP8266用のJPEG画像表示スケッチを
参考にしました。

参考にしたサイト
・楽しくやろう。 ESP8266でJPEG画像をTFT LCDに表示する
   https://blog.boochow.com/article/427690966.html


利用ライブラリ

・JPEGデコーダーライブラリ
   MakotoKurauchi/JPEGDecoder
 https://github.com/MakotoKurauchi/JPEGDecoder
 
   ※fdfat対応にJPEGDecoder.cppの一部を修正しています。

   修正
    ・
#include <SD.h> を #include <SdFat.h> に変更
   
・ その下に
       extern SdFat SD;
      を追加

スケッチ
(こちらからも参照出来ます Tamakichi/stm32_jpeg_tft.ino)

//
// Arduino STM32 TFT(ILI9341) SPI接続 jpeg画像表示サンプル
//
// 参考にしたサイト
//  元にしたスケッチ
//  ・楽しくやろう。 ESP8266でJPEG画像をTFT LCDに表示する
//    https://blog.boochow.com/article/427690966.html
//  ライブラリ
//  ・MakotoKurauchi/JPEGDecoder
//    https://github.com/MakotoKurauchi/JPEGDecoder
//  Jpegに関する情報
//  ・JPEG/MCU
//    https://monobook.org/wiki/JPEG/MCU
//

#include <SPI.h>
#include <Adafruit_GFX_AS.h>
#include <Adafruit_ILI9341_STM.h>
#include <SdFat.h>
#include <JPEGDecoder.h>

// SDカード(SPI2利用)
#if ENABLE_EXTENDED_TRANSFER_CLASS == 1
  SdFatEX  SD(2);
#else
  SdFat  SD(2);  
#endif

#define SPI_SPEED SD_SCK_MHZ(36) // バスクロック
#define SD_CS PB0                // SDカード選択

// TFT制御用ピン (SPI1利用)
#define TFT_CS  PA0
#define TFT_RST PA1
#define TFT_DC  PA2

// TFT制御用オブジェクト
Adafruit_ILI9341_STM tft = Adafruit_ILI9341_STM(TFT_CS, TFT_DC, TFT_RST);

void setup() {
  Serial.begin(115200);
  delay(200);
  
  if (!SD.begin(SD_CS,SPI_SPEED)) {
    Serial.println("failed!");
  }
 
  tft.begin();
  tft.setRotation(3);
  tft.fillScreen(ILI9341_BLUE);
  Serial.println("OK!");

  jpegDraw("/test1.jpg"); // 320x240ドットフルカラー画像の表示
}

void jpegDraw(char* filename) {
 char str[100];
 uint8_t *pImg;
 int x,y,bx,by;
 
 // Decoding start
 JpegDec.decode(filename,0);
 uint16_t buf[JpegDec.MCUWidth*JpegDec.MCUHeight];
 uint16_t pos = 0;

 // Image Information
 Serial.print("Width     :");
 Serial.println(JpegDec.width);
 Serial.print("Height    :");
 Serial.println(JpegDec.height);
 Serial.print("Components:");
 Serial.println(JpegDec.comps);
 Serial.print("MCU / row :");
 Serial.println(JpegDec.MCUSPerRow);
 Serial.print("MCU / col :");
 Serial.println(JpegDec.MCUSPerCol);
 Serial.print("Scan type :");
 Serial.println(JpegDec.scanType);
 Serial.print("MCU width :");
 Serial.println(JpegDec.MCUWidth);
 Serial.print("MCU height:");
 Serial.println(JpegDec.MCUHeight);
 Serial.println("");
 
 sprintf(str,"#SIZE,%d,%d",JpegDec.width,JpegDec.height);
 Serial.println(str);

  // Raw Image Data
  while( JpegDec.read() ){    // MCU毎の描画処理
    pImg = JpegDec.pImage ;   // MCUブロックの先頭アドレス
    pos = 0;                   // バッファ位置初期化
    
    // MCUブロック描画ウィンドウの設定
    tft.setAddrWindow(JpegDec.MCUx * JpegDec.MCUWidth,
                      JpegDec.MCUy * JpegDec.MCUHeight,
                      JpegDec.MCUx * JpegDec.MCUWidth+JpegDec.MCUWidth-1,
                      JpegDec.MCUy * JpegDec.MCUHeight+JpegDec.MCUHeight-1);
 
    // ウィンドウ領域へのデータ転送
    for( by = 0; by < JpegDec.MCUHeight; by++)
      for( bx = 0; bx < JpegDec.MCUWidth; bx++, pImg += JpegDec.comps, pos++)
        buf[pos] = (JpegDec.comps == 1) ? 
         tft.color565(pImg[0], pImg[0], pImg[0]) : tft.color565(pImg[0], pImg[1], pImg[2]);
    tft.pushColors(buf, JpegDec.MCUWidth*JpegDec.MCUHeight, 0); 
  }
}
   
void loop() {
}

スケッチは高速化優先で、MCU内の端数画像には考慮していません。

SDカード利用のためのライブラリは、SdFatを利用しています。
SDカードアクセルのパフォーマンス改善のために、SdFatConfig.hの設定を修正しています。

変更
#define ENABLE_EXTENDED_TRANSFER_CLASS 1

より以前の記事一覧