フォト
2018年9月
            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            
無料ブログはココログ

« 2018年4月 | トップページ | 2018年6月 »

2018年5月の8件の記事

2018年5月30日 (水)

NeoPixel(WS2812B)の制御 その3

前回行った、ArduinoによるNeoPixel(WS2812B)の制御の続きです。
今回は8x8ドットマトリックスタイプのNeoPixelを使って簡単なメッセージ表示を行いました。

Dscn8015

  接続
    Arduino:D11   -  NeoPixel:DIN
    Arduino:5V     -  NeoPixel:5V
    Arduino:GND  -  NeoPixel:GND

マトリックスタイプのNeoPixel、Aliexpressだと安価に入手できます。

01

amazonだと倍の金額。さすがにこの金額だと買う気がしないなぁ。02

動いている様子


以前作成した美咲フォントをつかったライブラリを利用して簡単な日本語メッセージを
表示しています。Neopixelの制御は前回作成した関数を利用しています。

   ライブラリ
    ・Arduino用 美咲フォントライブラリ 教育漢字・内部フラッシュメモリ乗せ版
     https://github.com/Tamakichi/Arduino-misakiUTF16
 

スケッチ

//
// Neopixel 8x8ドットマトリックス 制御 SPIバージョン by たま吉さん  2018/05/30
//

#include <SPI.h>
#include <misakiUTF16.h>

//***************
// 定数
//***************

#define PIXCELNUM   64           // Neopixel ピクセル数(LED数)
#define PIN         11           // Neopixel 制御用ピン番号
#define NEOSPI_0    0b11100000   // 1ビット 値0
#define NEOSPI_1    0b11111000   // 1ビット 値1
#define NEOSPI_RST  0b00000000   // REST

//***************
// グローバル変数
//***************
uint8_t buf[PIXCELNUM*3];     // Nexpixel用ピクセル色データ(ピクセル数 x 24ビット)

//***************
// 関数
//***************
// Neopixel初期化
void NeoInit() {
  memset(buf, 0, PIXCELNUM*3); // バッファの初期化

  // SPIの初期化
  SPI.setBitOrder(MSBFIRST);            // 最上位ビットから送信
  SPI.setClockDivider(SPI_CLOCK_DIV2);  // クロック 8MHz
  SPI.setDataMode(SPI_MODE1);           // アイドル時 LOW、立上りエッジ時送信
  SPI.begin();                          // 開始
}

// Neopixelへのデータ送信
void NeoUpdate() {
  // RESET送信
  SPDR = NEOSPI_RST;              // SPIデータ送信
  while(!(SPSR & (1 << SPIF))) ;  // 送信完了待ち
  delayMicroseconds(50);

  // ピクセル数x24ビット送信
  for (uint8_t i = 0; i < PIXCELNUM*3; i++) {
    for (uint8_t j = 0; j < 8; j++) {
      SPDR = buf[i] & (0x80>>j) ? NEOSPI_1:NEOSPI_0; // SPIデータ送信
      while(!(SPSR & (1 << SPIF))) ;                 // 送信完了待ち
    }
  }
}

// Neopixelの表示クリア
void NeoCLS(uint8_t flgUpdate=false) {
    memset(buf, 0, PIXCELNUM*3); // バッファの初期化
  if (flgUpdate)
    NeoUpdate();
}

// 指定したピクセルの色を設定
void NeoSetRGB(uint8_t no, uint8_t R, uint8_t G, uint8_t B, uint8_t flgUpdate=false) {
  if (no < PIXCELNUM) {
    buf[no*3+0] = G;
    buf[no*3+1] = R;
    buf[no*3+2] = B;    
  }
  if (flgUpdate)
    NeoUpdate();
}

// ピクセルのシフト
void ShiftPixel(uint8_t flgUpdate=false) {
  uint8_t tmpbuf[3];
  memmove(tmpbuf,buf,3);
  memmove(buf, buf+3, (PIXCELNUM-1)*3);
  memmove(buf+(PIXCELNUM-1)*3,tmpbuf,3);
  if (flgUpdate)
    NeoUpdate();
}

// 8x8ドットマトリックス 指定座標ピクセル番号変換
inline uint8_t XYtoNo(uint8_t x, uint8_t y) {
  return y&1 ? 8*y + x : 8*y + 7 -x;
}

// ドットマトリックス 左スクロール
void NeoScroll(uint8_t flgUpdate=false) {
  for (uint8_t i=0; i < 8; i++) {
    if ( i&1 ) {
      memmove(&buf[i*8*3], &buf[(i*8+1)*3],7*3);
      memset(&buf[(i*8+7)*3], 0, 3);
    } else {
      memmove(&buf[(i*8+1)*3], &buf[i*8*3],7*3);
      memset(&buf[i*8*3], 0, 3);
    }
  }
  if (flgUpdate)
    NeoUpdate();
}

// 1文字左スクロール挿入
void NeoScrollInChar(uint8_t *fnt, uint8_t R, uint8_t G, uint8_t B, uint16_t tm) {
  for (uint8_t i = 0; i < 8; i++) {
    // 左1ドットスクロール
    NeoScroll(false);

    // フォントパターン1列分のセット
    for (uint8_t j = 0; j < 8; j++) {
      if (fnt[j] & (0x80 >> i)) {
         NeoSetRGB(XYtoNo(7,j), R,G,B, false);
      } else {
         NeoSetRGB(XYtoNo(7,j), 0,0,0, false);        
      }
    }
    NeoUpdate();
    delay(tm);
  }
}

// メッセージの表示
void NeoMsg(char* msg, uint8_t R, uint8_t G, uint8_t B, uint16_t tm) {
  uint8_t  fnt[8];
  int8_t   len;
  
  // テスト用文字列
  //char msg_str[] = "あいうえお、今日は5月30日です。かんたんなかんじの表示ができます。";

  char *str = msg;
  NeoCLS();
  while(*str) {
    if (! (str = getFontData(fnt, str)) )  {
         Serial.println("Error"); 
         break;
    }
    NeoScrollInChar(fnt, R, G, B, tm);         
  }
}

void setup() {
  NeoInit();  // Neopixcelの初期化
  NeoCLS();   // Neopixcelの表示クリア
}

void loop() {
   NeoMsg("あいうえお、",0, 16, 0, 100);
   NeoMsg("今日は5月30日です。",0, 8, 8, 100);
   NeoMsg("かんたんなかんじの表示ができます。",16, 4, 4, 100);      
   delay(1000); 
}

意外とお手軽に実装出来ました。表示についてもチラつきや遅延もなく、スクロール表示
出来ています。

8x8だと流石に日本語表示は辛いですね。
16x16ドットくらいだともうちょっと面白い表示が出来るかもしれません。
機会があればチャレンジしてみます。

関連記事
 NeoPixel(WS2812B)の制御 その3(2018.05.30)  ・・・ 8x8マトリックスの制御(この記事です)
 NeoPixel(WS2812B)の制御 その2(2018.05.22)   ・・・ SPIを使った制御
 NeoPixel(WS2812B)の制御(2018.05.20)            ・・・ GPIOを使った制御

2018年5月23日 (水)

梅澤無線電機さんの「電子倶楽部60」を購入してみました

電子工作関連のブログを色々と読みあさっていたところ、
梅澤無線電機さんの「電子倶楽部60」を発見、レトロな雰囲気につられてポッチってしまいました。

個人的な趣味として電子工作をやってますが、アナログ回路はあまり得意でなないので、
勉強しようと、教材を探していたんですよね。

梅澤電機株式会社 - 電子倶楽部60

01

関連情報
電子倶楽部60

価格は税込みで1,058円ですが、送料に868円かかりました。

注文して2、3日で商品が到着しました。さっそく開封してみます。

到着した商品

外箱は手抜きのない立派な箱です。
これなら、子供さんへのプレゼントとしても使えそうです。

Dscn7930

箱の裏

Dscn7932


開封

箱の中はこんな感じで入ってます。

Dscn7933

本体

値段の値段の割には、しっかりした作りです。
上面ボードの材質は、ボール紙ですが厚さが1ミリあり樹脂化粧していて丈夫そうです。
付属品として、ケーブル類とクリスタルイヤホン等が付いています。

Dscn7935

バーアンテナ、ポリバルコン、トランジスター、ダイオードがあるので鉱石ラジオや
1・2石トランジスターラジオなんかも作れそう。

搭載しているパーツ類、個別に買った場合1058円じゃすまないとおもいますね。

テキスト類

36ページの冊子がついています。意外としっかした内容のテキストです。

Dscn7943

60種類の実験回路が掲載されています。
色々と面白そうな実験が出来そうです。

Dscn7945

Dscn7944

Dscn7937

裏はこんな感じです。電池ボックスがあります。
うらは若干チープ間がありますが、良しとしましょう^^

Dscn7940

子供のころ、学研の電子ブロックを持っていたのですが、
あれって電子部品を直感的に結線出来ず、ブロックの配置に悩んでしまいました。
このワイヤー直結の方が楽ちんです。ブレッドボードとの併用もできますね。

ArduinoやIchigojam等のマイコンと組み合わせての利用にも良さそうです。
Lチカや音出し、リレーを使った実験等はこのボードを使って出来そうです。

2018年5月22日 (火)

NeoPixel(WS2812B)の制御 その2

前回行った、ArduinoによるNeoPixel(WS2812B)の制御の続きです。
前回の処理の一部をSPIを利用する方式に書き換えました。

SPIを使っているため、出力ピンはMOSIピン(D11)固定となりますが、
前回よりも安定したクロックでの出力となりました。

  04

前回の信号生成の条件を考慮し、

02

03

SPIのクロックを8MHzとした場合、1クロック幅は0.125μ秒となります。
このクロック幅を元に利用して、

   T0H、T1L : 0.375μ秒 (3クロック分)
   T0L、T1H : 0.625μ秒 (5クロック分)

として利用します。値としては、「Data transfer time」の表の有効範囲から
少々ずれていますが、問題無いようです。

ちょうど0、1の送信とも8クロック分になりSPIの送信単位の8ビットにマッチします。

01
NeoPixelに1ビット送信するのに、SPIを利用して1バイト送れば良いことになります。
    0 : 0b11100000
    1 : 0b11111000



修正したスケッチ(2018/05/30 修正)

前回のスケッチでNeoPixelの初期化とデータ送信を行っている
NeoInit() 、NeoUpdate()をSPIを利用する方式に修正しました。

//
// Neopixelの制御 SPIバージョン by たま吉さん  2018/05/22
//

#include <SPI.h>

//***************
// 定数
//***************

#define PIXCELNUM   16           // Neopixel ピクセル数(LED数)
#define PIN         11           // Neopixel 制御用ピン番号
#define NEOSPI_0    0b11100000   // 1ビット 値0
#define NEOSPI_1    0b11111000   // 1ビット 値1
#define NEOSPI_RST  0b00000000   // REST

//***************
// グローバル変数
//***************
uint8_t buf[PIXCELNUM*3];     // Nexpixel用ピクセル色データ(ピクセル数 x 24ビット)

//***************
// 関数
//***************
// Neopixel初期化
void NeoInit() {
  memset(buf, 0, PIXCELNUM*3); // バッファの初期化

  // SPIの初期化
  SPI.setBitOrder(MSBFIRST);            // 最上位ビットから送信
  SPI.setClockDivider(SPI_CLOCK_DIV2);  // クロック 8MHz
  SPI.setDataMode(SPI_MODE1);           // アイドル時 LOW、立上りエッジ時送信
  SPI.begin();                          // 開始
}

// Neopixelへのデータ送信
void NeoUpdate() {
  // RESET送信
  SPDR = NEOSPI_RST;              // SPIデータ送信
  while(!(SPSR & (1 << SPIF))) ;  // 送信完了待ち
  delayMicroseconds(50);

  // ピクセル数x24ビット送信
  for (uint8_t i = 0; i < PIXCELNUM*3; i++) {
    for (uint8_t j = 0; j < 8; j++) {
      SPDR = buf[i] & (0x80>>j) ? NEOSPI_1:NEOSPI_0; // SPIデータ送信
      while(!(SPSR & (1 << SPIF))) ;                 // 送信完了待ち
    }
  }
}

// Neopixelの表示クリア
void NeoCLS() {
    memset(buf, 0, PIXCELNUM*3); // バッファの初期化
    NeoUpdate();                 // 表示更新
}

// 指定したピクセルの色を設定
void NeoSetRGB(uint8_t no, uint8_t R, uint8_t G, uint8_t B, uint8_t flgUpdate=false) {
  if (no < PIXCELNUM) {
    buf[no*3+0] = G;
    buf[no*3+1] = R;
    buf[no*3+2] = B;    
  }
  if (flgUpdate)
    NeoUpdate();
}

// ピクセルのシフト
void ShiftPixel() {
  uint8_t tmpbuf[3];
  memmove(tmpbuf,buf,3);
  memmove(buf, buf+3, (PIXCELNUM-1)*3);
  memmove(buf+(PIXCELNUM-1)*3,tmpbuf,3);
  NeoUpdate();
}

void setup() {
  
  NeoInit();  // Neopixcelの初期化
  NeoCLS();   // Neopixcelの表示クリア
  
  NeoSetRGB(0, 128,0,0,true); // No.0のピクセルを赤
  NeoSetRGB(1, 0,128,0,true); // No.1のピクセルを緑
  NeoSetRGB(2, 0,0,128,true); // No.2のピクセルを青
}

void loop() {
 delay(80);
 ShiftPixel(); // ピクセルをシフトして更新表示
}

SPIによるデータ送信は、関数呼び出しだと処理が間に合わないと判断し、
データレジスタSPDRに送信データをセットし、ステータスレジスタSPSRを参照して
送信完了待ちを行っています。

次回は8x8ドットマトリックスタイプのNeopixelを使ってもう少し複雑なことをやろうかと思います。

関連記事
 NeoPixel(WS2812B)の制御 その3(2018.05.30)  ・・・ 8x8マトリックスの制御
 NeoPixel(WS2812B)の制御 その2(2018.05.22)   ・・・ SPIを使った制御(この記事です)
 NeoPixel(WS2812B)の制御(2018.05.20)            ・・・ GPIOを使った制御

参考にしたサイト
Todotaniのはやり物Log - SPIの基本動作とArduinoでの使い方
しなぷすのハード製作記 - 「SPI」の解説
garretlab - Arduinoで遊ぶページ - SPI関連レジスタ
Stupiddog - ArduinoでSPI通信を行う方法
株式会社インデペンデンスシステムズ横浜 - Arduino UnoでSPI通信(その1)Arduino Uno2台で通信
QEEWiki - SPI (Serial Peripheral Interface)

2018年5月20日 (日)

NeoPixel(WS2812B)の制御

Arduino UnoでNeoPixel(WS2812B)の制御をライブラリ無しで行ってみました。
まずは手持ちのリング形状16個LEDのタイプを制御してみました。

Dscn7924

動いている様子



スケッチ
2018/05/30 修正)

//
// Neopixelの制御 by たま吉さん  2018/05/20
//

//***************
// 定数
//***************

#define PIXCELNUM   16        // Neopixel ピクセル数(LED数)
#define PIN         2         // Neopixel 制御用ピン番号

//***************
// グローバル変数
//***************
uint8_t buf[PIXCELNUM*3];     // Nexpixel用ピクセル色データ(ピクセル数 x 24ビット)
volatile uint8_t * NeoOutReg; // Neopixcel出力レジスタ
uint8_t  NeoBitOut;           // Neopixcelセットビット
uint8_t  NeoBitMask;          // Neopixcelクリア用マスク

//***************
// 関数
//***************

// Neopixel初期化
void NeoInit() {
  memset(buf, 0, PIXCELNUM*3); // バッファの初期化

  // 出力ピンの初期化
  pinMode(PIN, OUTPUT);
  digitalWrite(PIN, LOW);
  NeoOutReg  = portOutputRegister(digitalPinToPort(PIN));  // Neopixcel出力レジスタ
  NeoBitOut  = digitalPinToBitMask(PIN);  // Neopixcelセットビット
  NeoBitMask = ~NeoBitOut;                // Neopixcelクリア用マスク
 }

// Neopixelへ1を出力
inline void NeoOut_1() {
  *NeoOutReg |= NeoBitOut;   // HIGHの出力
  asm volatile(
     "nop"    "\n\t"
     "nop"    "\n\t"     
     "nop"    "\n\t"
     "nop"    "\n\t"     
  );
  *NeoOutReg &= NeoBitMask;  // LOWの出力
}

// Neopixelへ0を出力
inline void NeoOut_0() {
  *NeoOutReg |= NeoBitOut;   // HIGHの出力
  *NeoOutReg &= NeoBitMask;  // LOWの出力
  asm volatile(
     "nop"    "\n\t"
     "nop"    "\n\t"     
     "nop"    "\n\t"
     "nop"    "\n\t"     
     "nop"    "\n\t"
     "nop"    "\n\t"     
     "nop"    "\n\t"     
     "nop"    "\n\t"
  );  
}

// Neopixelへのデータ送信
void NeoUpdate() {
  uint8_t testbit = 0b10000000;
  *NeoOutReg &= NeoBitMask;  // LOWの出力
  delayMicroseconds(50);
  cli(); 
  for (uint8_t i = 0; i < PIXCELNUM*3; i++) {
    if (buf[i] & 128) NeoOut_1(); else  NeoOut_0();
    if (buf[i] &  64) NeoOut_1(); else  NeoOut_0();
    if (buf[i] &  32) NeoOut_1(); else  NeoOut_0();
    if (buf[i] &  16) NeoOut_1(); else  NeoOut_0();
    if (buf[i] &   8) NeoOut_1(); else  NeoOut_0();
    if (buf[i] &   4) NeoOut_1(); else  NeoOut_0();
    if (buf[i] &   2) NeoOut_1(); else  NeoOut_0();
    if (buf[i] &   1) NeoOut_1(); else  NeoOut_0();
  }
 sei();
}

// Neopixelの表示クリア
void NeoCLS() {
    memset(buf, 0, PIXCELNUM*3); // バッファの初期化
    NeoUpdate();                 // 表示更新
}

// 指定したピクセルの色を設定
void NeoSetRGB(uint8_t no, uint8_t R, uint8_t G, uint8_t B, uint8_t flgUpdate=false) {
  if (no < PIXCELNUM) {
    buf[no*3+0] = G;
    buf[no*3+1] = R;
    buf[no*3+2] = B;    
  }
  if (flgUpdate)
    NeoUpdate();
}

// ピクセルのシフト
void ShiftPixel() {
  uint8_t tmpbuf[3];
  memmove(tmpbuf,buf,3);
  memmove(buf, buf+3, (PIXCELNUM-1)*3);
  memmove(buf+(PIXCELNUM-1)*3,tmpbuf,3);
  NeoUpdate();
}

void setup() {
  NeoInit();  // Neopixcelの初期化
  NeoCLS();   // Neopixcelの表示クリア
  
  NeoSetRGB(0, 128,0,0,true); // No.0のピクセルを赤
  NeoSetRGB(1, 0,128,0,true); // No.1のピクセルを緑
  NeoSetRGB(2, 0,0,128,true); // No.2のピクセルを青
}

void loop() {
 delay(80);
 ShiftPixel(); // ピクセルをシフトして更新表示
}

制御を行うためのプロトコル自体は非常に簡単です。
1ポートからLOW or HIGHを指定したタイミングで出力するだけです。

リセット(RET)コード送信後、1つのLED(ピクセル)毎に24ビット分の0 or 1の送信、
複数のLEDの場合、24ビットxLED数分のデータを送信します。

02

リセット(RET)コードは、Treset(50μ秒)間 LOWを出力、
1ビット 0 を送信(0 code)は、T0H間HIGHを出力後、T0L間LOWを出力、
1ビット 1 を送信(1 code)は、T1H間HIGHを出力後、T1L間LOWを出力、
します。

だだし、このタイミングがシビアです。

03

作成したスケッチでは、
   T0H、T1L : 0.375μ秒 (6クロック分)
   T0L、T1H : 0.625μ秒 (10クロック分)

をとしました。
値としては、「Data transfer time」の表の有効範囲から少々ずれていますが、
問題無いようです。

Arduino Unoはシステムクロックが16MHzで動作しています。
1クロックは 1/16000000 = 0.0625μ秒 となります。

わずか、6~10クロックというシビアなタイミングで信号を出力する必要があります。
今回は6~10クロックの待ち時間の調整はインラインアセンブラ命令でNOPを入れて
調整しました。

  *NeoOutReg |= NeoBitOut;   // HIGHの出力
が6クロック
  *NeoOutReg &= NeoBitMask;  // LOWの出力
が3クロック
要していることを考慮しています。

時間待ち中は割り込みを禁止しています。
割り込みが入ると動作に外乱が入り、データが化けます。
また、デジタル出力をdigitalWire()で行うと処理が間に合いません。
そこで、出力レジスタに直接、値を書き込んでいます。

まあ、これだとシリアル通信等、他に何も出来ません。
そこで、次の対策としてSPIを使って何とかしようと思います。

関連記事
 NeoPixel(WS2812B)の制御 その3(2018.05.30)  ・・・ 8x8マトリックスの制御
 NeoPixel(WS2812B)の制御 その2(2018.05.22)   ・・・ SPIを使った制御
 NeoPixel(WS2812B)の制御(2018.05.20)            ・・・ GPIOを使った制御(この記事です)

参考にしたサイト
uratan - WS2812B の駆動タイミングの限界調査
PICマイコンの小部屋 - 秋月でWS2812B買ってしまったので動かないかも知れないけれど作ってみた

2018年5月16日 (水)

ゲームボーイ(旧タイプ)のパーツ その2

前回からの続きです。
その後、ケースの他に液晶モジュールとそのカバーを追加注文し、部品が到着しました。
とりあえず、IchigoJamで稼働させてみる予定です。

到着したパーツ

Dscn7908

Dscn7910

追加注文したパーツ

・LCDモジュール
3.5インチ 4:3の画面だと選択枝がこれしかありませんでした。
Podofo 3.5" TFT LCD Display RGB LCD Display Module Kit

01

・LCD用のカバー
  プラスチックではなくガラス製です。
Glass For GameBoy Zero DMG-01 For Raspberry Pi Modify Glass Lens Protector

02


まずは、LCDディスプレイの動作チェック

LCD部とドライバーボードのセットです。NTSCビデオ入力で表示出来ます。
IchigoJamに接続して表示確認をしたところ、仕様では12V駆動ですが5Vで動作しました。
意外と視野角の広く、斜めからも良く見える液晶です。

Dscn7907

液晶パネルはLQ035NC111という、比較的入手しやすいパーツです。

さっそく、今回の試みで一番重要なLCDの組み込みをやってみました。
傷防止のマスキングテープを付けて、段差のある部分をカットします。
パネルカバーが載せられるように、若干フチを残します。

Dscn7912

マスキングテープで仮止めして、一旦組み立ててみます。

Dscn7914

基板も装着

Dscn7917

ふたを閉めて、表示の確認をします。
LCDモジュールからケーブルを引き出して電源供給とビデオ信号入力を行っています。

Dscn7921

とりあえず、見栄えも良くいい感じに仕上がりました。
LCDカバーは購入して正解でした。

次に裏の電池ボックスからの電源供給をどうするか考えてみます。
Ichigojamを中にどう入れるかも検討します。

Dscn7922

他にもコネクタ類(キーボード、シリアル通信、外部電源)も何とかしたいですね。


2018年5月15日 (火)

micro:bitで8x8ドットNeopixelを使ったメッセージ表示

豊四季Tiny BASIC for micro:bit で 8x8ドットNeopixelによるメッセージ表示を実装しみました。

01

8x8ドットNeopixelは以前Aliexpressにて購入したものを使いました。

02

64個のNeopixelを駆動させるので、電源は電池から供給しています。

動いている様子



プログラムソース

10 'Neopixelで文字のスクロール表示
20 NPBEGIN 12,64
30 GOSUB "@CLSM"
40 S="こんにちは さいたま":N=RGB8(0,1,1) B=0:W=70:GOSUB "@MSG"
50 WAIT 500:NPCLS
60 S="これはNeoPixelによるメッセージ出力サンプルです"
70 N=RGB8(2,1,0):B=0:W=70:GOSUB "@MSG"
80 WAIT 500:GOTO 30
90 "@SCRL":'左スクロール
100 FOR Y0=0 TO 7
110 IF Y0&1 GOTO 170
120 FOR X0=6 TO 0 STEP -1
130 POKE MEM+Y0*8+X0+1,PEEK(MEM+Y0*8+X0)
140 NEXT X0
150 POKE MEM+Y0*8,0
160 GOTO 210
170 FOR X0=1 TO 7
180 POKE MEM+Y0*8+X0-1,PEEK(MEM+Y0*8+X0)
190 NEXT X0
200 POKE MEM+Y0*8+7,0
210 NEXT Y0
220 RETURN
230 "@INSC":'1文字分挿入スクロール
240 A=WADR(C)
250 FOR X1=0 TO 7
260 GOSUB "@SCRL"
270 FOR Y1=0 TO 7
280 IF PEEK(A+Y1)&($80>>X1) N0=N ELSE N0=B
290 IF Y1&1 POKE MEM+Y1*8+7,N0 ELSE POKE MEM+Y1*8,N0
300 NEXT Y1
310 NPPUT 0,MEM,64,1,1
320 WAIT W
330 NEXT X1
340 RETURN
350 "@MSG":'メッセージのスクロール表示
360 FOR I2=1 TO WLEN(S)
370 C=WASC(S,I2)
380 GOSUB "@INSC"
390 NEXT I2
400 RETURN
410 "@CLSM":'表示のクリア
420 FOR I3=0 TO 63:POKE MEM+I3,0:NEXT I3
430 NPPUT 0,MEM,64,1,1
440 RETURN

表示するメッセージは日本語に対応しています。
フォントは美咲フォントを利用しています。

8x8のピクセルは次のような順番で並んでいるため、、文字の表示やスクロール処理が
ちょっと面倒です。奇数行・偶数行でピクセル点灯の処理が異なります。

03

プログラムでは20行から80行で指定したメッセージを表示しています。
20行のNPBEGIN 12,64 は制御するピンとして12ピン、ピクセル数として64を指定、
30行のGOSUB "@CLSM" は表示用バッファの消去
40行、60行は次の変数にメッセージ等を設定し、GOSUB "@MSG"にてメッセージを
表示しています。

  変数
    S: メッセージ文字列
    N: 表示する文字色(RGB8関数で各R・G・Bの値を指定)
    B: 表示する文字の背景色(ここでは0:黒を指定)
    W: スクロール速度

50行、80行は消去及び時間待ちを行っています。
サブルーチンについては、説明を省略します。

2018年5月14日 (月)

豊四季Tiny BASIC for micro:bit をV0.08に更新しました

豊四季Tiny BASIC for micro:bit をV0.08に更新しました。
公開サイト
  https://github.com/Tamakichi/ttbasic_microbit

V0.07からの変更点
・シリアル通信をI/Oピン経由で行うUARTコマンドの追加
・キャラクタで直線・矩形・塗りつぶし四角を描画するCLINEコマンドの追加
・プログラム保存領域の増量(8本 ⇒ 16本)
・リファレンスマニュアルの見直し(問題点修正・追記)

今回の修正で、任意のピンにシリアル通信用のTxD、RxDを割り当ててシリアル通信を
行うことが出来るようになりました。

次の写真はUART 12,13,"921600"を実行して12ピンにRxD、13ピンにTxDを割り付けています。01

USB-シリアル変換モジュールが対応していれば、921600bpsの高速通信が利用出来ます。
ついでに今回追加したCLINEコマンドを使って矩形描画を行っています。

02


2018年5月 8日 (火)

ゲームボーイ(旧タイプ)のパーツ

ゲームボーイ(旧タイプ)のパーツがAliexpressやeBeyで出回っています。

02

01

古いゲームの傷ついたハウジング(外側ケース)やボタンを交換したりってニーズが
海外ではあるようです。

Pi Zeroとの記載があり、中にラズパイ Zeroを入れて利用する用途もあるようです。
私も「Arduinoや何かに使えるのでは?」と思い、幾つかパーツを注文しました。

私は、ゲームボーイ自体で遊んだことがなく、本物の使い勝手が分かりません。
そこで、中古を探して入手しました。
初代ゲームボーイ(DMG-01) 、amazonで3,290円でした。

Dscn7866

Dscn7867

状態はかなり良いです。
ゲームボーイは初めて手にしましたが、かなり頑丈な作りです。

ゲームは近くのHardOffで入手しました。

Dscn7874

テトリス 200円、それ以外は40円でした。

Dscn7871

テトリス、久々にやりました。液晶の表示も良好です。
問題無くプレイできました。
う~ん。面白い、操作性も抜群です。ハマってしまいました。

残念ながら、ハイスコアの保存で出来ないようです。
ゲームカーリッジ内のバッテリーバックアップが動作していないようです。

Dscn7873

カートリッジは特殊なねじで開けることが出来ません。
このタイプのドライバーをamazonで見つけ注文しました。

ゲームボーイ本体は調査のため解体して、基板の寸法等を調べる予定です。

2018/05/10 追記

工具が到着したので、早速ゲームカートリッジを分解してみました。

Dscn7876

以前ダイソーで購入したドライバーに嵌めて利用できました。

Dscn7877

テトリスを分解しみると、バックアップ電池はありませんでした。
ググってみると、どうやらテトリスはハイスコアを保持する機能は無いようです。
残念。

Dscn7878

とりあえず、遊戯王も分解してみました。
こちらには、バックアップ電池がありました。
ICが4つも搭載。グラフィック等を多用するためか、容量の大きいROMが搭載されているようです。

Dscn7880

« 2018年4月 | トップページ | 2018年6月 »