Lynx-EyEDの電音鍵盤 新館

制御とか数学とか駄文とか

LPC1114 DIPのArduinoボード "NeXtPino" 登場

Arduino本家がArduino DueでARMプロセッサに置き換わるなど、この界隈もまたにぎやかですが、依然としてDIPマイコンが使えるArduino UNOは人気が高いようですね。

32bit Arduinoクローン(ソフトのみ、ハードのみ互換含む)でも

  • chipKitシリーズ (PIC32MX/MIPS M4K)
  • Netduinoシリーズ (AT91SAM7/ARM7TDMI)
  • FEZ Dominoシリーズ(LPC2xxx/ARM7TDMI-S)
  • MAPLEシリーズ(STM32F/Cortex-M3)
  • Pellerduino (P8X32A/Parallax Propeller)

など、(あとなんかあったっけ?いろいろあると思います)

当ブログでも史上最速でCortex-M0に対応したArduino互換APIを提供しています。(STMicroのCortex-M0 Arduinoより早かったはず)

NeXtPino LPC1114 Arduino board

えとせとらのMatty氏より、DIP ARMが載るArduinoボードを提供いただきました。安心のUSB-UARTチップ搭載済み
f:id:Lynx-EyED:20121121000447j:plain
ピンアサインも深く考慮されており、使いやすくなっております。

使ってみた

コレにNetSynth.orgのGenie氏のご厚意により提供いただいたねむいさんTFT-LCDシールド(RC版)を載せてみました。*1
お約束のフラクタル描画
f:id:Lynx-EyED:20121121230006j:plain

eXodusinoライブラリのSPIの変更

NeXtPino登場にあわせ、eXodusinoライブラリのSPIクラスを改良しました
いままで、LPC1114FN28で

   SPI.begin();

とすると、今まではSCKピンはPIO0_6を使用するようになっていましたが、今回の修正でPIO0_10になりました。もし、PIO0_6をSCKピンとして使いたい場合は

   SPI.begin( SCK_P0_6 );

としていただく必要がございます。何卒ご了承ください。

f:id:Lynx-EyED:20121125102552j:plain

ボード入手方法

ITショップ「えとせとら」さんより
ITショップ「えとせとら」
あら、在庫わずか。早いもの勝ちですな。

ボクもマンデルブロ集合描きたい

eXodusinoライブラリが必要になります。
lynxeyed-atsu/eXodusino · GitHub
使い方1.(必須)
Arduino API互換環境eXodusinoをLPC1114 DIPで使うまとめ - Lynx-EyEDの電音鍵盤 新館
使い方2.(ブートローダなど。必須ではない)
Arduino API互換環境eX(ryまとめ その2 - Lynx-EyEDの電音鍵盤 新館

参考:マンデルブロについて参考にさせていただいたサイトです
マンデルブロ集合/C言語サンプル ソースプログラム/佐伯英子技術士事務所(情報工学)
ほぼそのままの実装を使わせていただいております。ありがとうございます。

user_application.cppに以下を記述し、コンパイル後NeXtPinoに書き込みます

#include <math.h>
#include <libmary.h>
#include "TFTLCD.h"

volatile int count = 0;
volatile float magnitude;
volatile float sub_x;
volatile float sub_y;

void setup() {
	Serial.begin(9600);
	SPI.setBitLength(8);
	SPI.setDataMode(SPI_MODE0);
	SPI.setClockDivider(SPI_CLOCK_DIV4);
	SPI.begin();
	//TFT-LCD init
	pinMode(LCD_DC,OUTPUT);
	pinMode(LCD_RES,OUTPUT);
	pinMode(LCD_CS,OUTPUT);

	initDisplay();

	//表示領域の初期化(全画面)
	resetArea();
	fillScreen(0,0);

	delay(1000);
	sub_x = -0.5;
	sub_y = 0.1;
	magnitude = 1;
	Serial.println("LCD Initialization finish...");
}

volatile int generateColor(int count, int base)
{
	int r,g,b;
	int d = (count % base) * 256 / base;
	int m = (int)(d / 42.667);

	switch(m) {
		case 0: r=0;          g=6*d;          b=255;         break;
		case 1: r=0;          g=255;          b=255-6*(d-43);break;
		case 2: r=6*(d-86);   g=255;          b=0;           break;
		case 3: r=255;        g=255-6*(d-129);b=0;           break;
		case 4: r=255;        g=0;            b=6*(d-171);   break;
		case 5: r=255-6*(d-214); g=0;         b=255;         break;
		default: r=0;         g=0;            b=0;           break;
	}

	return (((r >> 3) & 0x1f) << 11) | (((g >> 2) & 0x3f) << 5) | ((b >> 3) & 0x1f);
}


void loop() {

	int oldtime = 0,nowtime = 0;
	select_disp();
	resetArea();
	for(int y = 0;y < 130;y++)			// 虚部(縦方向)
	{
		for(int x = 0; x < 130; x++) {	// 実部(横方向)
			float cr = (x - 64) / 64. / magnitude + sub_x;
			float ci = (y - 64) / 64. / magnitude + sub_y;
			float zr = 0.0, zrN;
			float zi = 0.0, ziN;
			float E = 4.0;				// E:この値を超えたら発散とする
			int t,tmax = 512;			// tmax:最大計算回数

			// 収束検査
			for(t = 0; t < tmax; t++)
			{
				zrN = zr * zr - zi * zi + cr;
				if(zrN > E) break;
				ziN = 2.0 * zr * zi + ci;
				if(ziN > E) break;
				zr = zrN; zi = ziN;
			}

			int colour = generateColor(t, 64);
			int data1 = ((colour >> 8) & 0xff) | 0x100;
			int data2 = (colour & 0x0ff) | 0x100;
			sendData(data1);
			sendData(data2);
		}
	}

	unselect_disp();
	nowtime = millis();
	Serial.print("描画終了時間=");
	Serial.print(nowtime,DEC);
	Serial.println("mSec");
	Serial.print("描画時間=");
	Serial.print((nowtime - oldtime),DEC);
	Serial.println("mSec");
	magnitude = magnitude * 1.2;

	if(count++ > 10)
	{
		count = 0;
		magnitude = 1;
	}
	delay(1);
}

*1:なお、eXodusinoではこのTFT-LCDシールド専用ライブラリを標準で搭載しております