google-site-verification: google3bd66dd162ef54c7.html

Arduinoで液晶にマンデルブロ集合を描く

 aitendoの2015福袋(LCD)に入っていた3.2インチの320x240画素(QVGA)の液晶の動作確認のため、Arduinoで簡単なデモ画面を表示させました。これでこの液晶の使い方はほぼ理解できたような気がするので、ブレッドボードで作った回路はそのまま放置して何かの時に分解かなーと思っていました。

 でも、小さな画面ですがカラーグラフィックが表示出来る仕掛けなので、このまま壊してしまうのはちょっともったいないです。ということで、もう少しコンピューターらしい画像を表示させるプログラムを作ってみることにします。

 何を作るのか迷ったのですが、比較的簡単なプログラムで出来そうなマンデルブロ集合を作ってみました。

 やり方としては、Arduino UNO でスケッチを書き込み、CPUを引っこ抜いてこの写真の上の方ににちょっと見えているブレッドボードに移してから走らせて液晶に表示させます。
Arduinoでマンデルブロ集合

 マンデルブロ集合の計算では収束したかどうか確認する上限の回数(NMAX)を指定して計算を行います。つまりNMAX回繰り返しても値が発散しなかったらマンデルブロ集合の内側と判定します。ということで、NMAXの値で計算の結果が違ってきます。以下はNMAXを変えた場合に得られた画像です。

▼NMAX=500
Nmax=500
 500回くらい計算しておけば大丈夫そうです。ちなみにNMAX=100くらいまで下げても結果はほとんど変わりませんでした。まあこの解像度では少し画像の劣化があっても判らないでしょう。計算は単精度(32ビット)浮動小数点でやってます。

▼NMAX=50
Nmax=50
 さすがに細かい部分の描画が甘くなっていて、黒いお団子がくっついています。

▼NMAX=10
Nmax=10
 ここまで手抜きするとグダグダになりますが、フラクタルな雰囲気は残ってます。

 作画に使ったプログラムは下記です。NMAX=100の状態になっています。

/*
マンデルブロ集合図形をaitendo 3.2インチ液晶に表示
 ラジオペンチ 2015/01/15
 http://radiopench.blog96.fc2.com/
 */

#include <UTFT.h>                       // UTFTライブラリを使用

extern uint8_t SmallFont[];             // フォント定義
int NMAX=100;                           // 計算回数MAX指定(大きいほど精度上がるが計算時間がかかる) 

UTFT myGLCD(SSD1289_8,A0,A1,A2,A3);     // aitendoのM032C1289TP (QVGA)

void setup(){
  myGLCD.InitLCD();                    // 液晶初期化
  myGLCD.clrScr();                     // 画面クリア
  myGLCD.setColor(255, 255, 255);
  myGLCD.setFont(SmallFont);
  myGLCD.print("Mandelbort set written by Arduino", CENTER, 0);
  myGLCD.print("Jan.15.2014 radiopench", RIGHT, 228);
  myGLCD.print("NMAX=", LEFT, 228);
  myGLCD.printNumI(NMAX, 40, 228);     // 左下に計算条件を表示
}

void loop(){
  float x, y;
  int mResult, c, px, py;
  for(x = -1.1; x < 2.1; x += 0.01){
    for(y = 1.05; y > -1.05; y -= 0.01){
      mResult=mandelbrot(x, y);              // マンデルブロ判定
      c = mResult % 8;                       // 判定結果を0-7の数値に変換
      switch(c){                             // 値によって8色で表示
      case 0:                                // 0は集合の内側として黒(8,16,24・・も黒)
        myGLCD.setColor(0,0,0);              // 黒
        break;
      case 1:
        myGLCD.setColor(0,0,255);            // 青
        break;
      case 2:
        myGLCD.setColor(0,255,255);          // 水
        break;
      case 3:
        myGLCD.setColor(0,255,0);            // 緑
        break;
      case 4:
        myGLCD.setColor(255,255,0);          // 黄
        break;
      case 5:
        myGLCD.setColor(255,0,0);            // 赤
        break;
      case 6:
        myGLCD.setColor(255,0,255);          // 紫
        break;
      case 7:
        myGLCD.setColor(255,255,255);        // 白
        break;
      }
      px = (x * 100.0) + 110;            // 画面座標に変換
      py = (-y * 100.0) + 120;
      myGLCD.drawPixel(px, py);          // 画面にプロット
    } 
  }
  for(;;){                               // 無限ループで停止
  }
}

int mandelbrot(float a, float b){        // マンデルブロ判定
  float x = 0.0, y = 0.0, x1, y1;
  for(int n=1; n < NMAX; n++){
    x1 = x * x - y * y - a;
    y1= 2.0 * x * y - b;
    if( x1 * x1 + y1 * y1 > 4.0 ){
      return n;                         // 発散していたらその時の回数
    }
    x = x1;                             // 次回の計算用に値を更新
    y = y1;        
  }
  return 0;                             // 指定回数内で発散しなければ収束とみなす
}

▼場所を変えるとこんな画像が見えます
別の画像
 フラクタルなので、どこをどんなに拡大しても同じ感じの画像が出てきます。 

 インタラクティブに見え方を変更できればいいのですが、NMAX=50でも描画に1分45秒くらいかかるのでちょっと無理です。このCPUは8ビットでクロックは16MHz。8ビットの乗算機はありますがFPUなんてしゃれたものは付いていません。これ、たぶん1990年代初め頃のパソコンと同じくらいの実力でしょう。とはいってもこのCPUは今では250円で買えるので良い時代になったものです。

 ということで、いろいろ楽しませてもらいました。小さな画面ですが、ここにフルグラフィックスの画面が作れるのはワクワクします。機会があったらこの液晶をなにか実用的な物に使ってみたいと思います。
関連記事

コメントの投稿

管理者にだけ表示を許可する

とても素晴らしいです。

ラジオペンチさん始めまして。
マンデルブロ集合凄いです。感動しました。
僕は数学的なセンスが無いので、マンデルブロ集合自体には興味があるのですが、プログラミングする事は無理でした。
ソースまで公開されていらっしゃるので、早速計算領域と、表示変換部分を変更して、組み込んだ所、綺麗に表示されました。>当方HPのFACITの様な転送ツール(完成編)のハードウェアに組み込んで動かしました。
またお邪魔させていただきます。
では失礼します。

re:とても素晴らしいです。

藤原ささみさん、おはようございます。
この記事がお役に立ったようで嬉しいです。

そちらのHP拝見しました。マイコンをチップレベルで使っていて凄いもの作られているんですね。

AVRのネイティブなC言語(Arduinoでは無いという意味です)で動かすと速そうですね。
カレンダー
03 | 2017/04 | 05
- - - - - - 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 - - - - - -
プロフィール

ラジオペンチ

Author:ラジオペンチ
電子工作を中心としたブログです。たまに近所(東京都稲城市)の話題など。60過ぎて視力や器用さの衰えを感じつつ日々挑戦!
コメントを入れる時にメールアドレスの記入は不要です。なお、非公開コメントは受け付けていません。

記事が気に入ったらクリックを!
最新記事
カテゴリ
最新コメント
リンク
FC2カウンター
検索フォーム
月別アーカイブ
RSSリンクの表示
QRコード
QRコード