ikkei blog

電子工作やパズルのブログです。主にLEDを使った電子工作をやっています。

ikkeiplexing shield 用 sketch

2010年06月22日 04時08分00秒 | Arduino
MTM05で出品した ikkeiplexing shield ですが、
サンプルスケッチがようやく出せる形にできました。



サンプルスケッチは以下ですが、 加速度センサが必要です。
 MsTimer2をダウンロードしてライブラリに加えておいて下さい。
 1msの割り込みを使って1ラインずつ表示します。
 加速度センサの読み取りと計算は16ライン毎に行っています。


/*
ikkeiplexing ( Charlieplexing by ikkei )
Use dual 8x8 dot matrix LED
Moving Dot
edited by ikkei 2010.06.22
*/

#include

#define A1 6
#define A2 10
#define A3 17
#define A4 2
#define A5 14
#define A6 3
#define A7 9
#define A8 5
#define K1 1
#define K2 4
#define K3 15
#define K4 7
#define K5 16
#define K6 8
#define K7 11
#define K8 12
#define AX 4
#define AY 5
#define AVE 16 // averaging times
#define XZEROG 518 // adjust offset value of zero G x-axis
#define YZEROG 545 // adjust offset value of zero G y-axis
#define RF1 3 // reflection rate RF1/RF2
#define RF2 4
#define MAG 1024 // magnify rate

const byte LINE[ 16 ][ 9 ] = {
{ K1, A1, A2, A3, A4, A5, A6, A7, A8 },
{ K2, A1, A2, A3, A4, A5, A6, A7, A8 },
{ K3, A1, A2, A3, A4, A5, A6, A7, A8 },
{ K4, A1, A2, A3, A4, A5, A6, A7, A8 },
{ K5, A1, A2, A3, A4, A5, A6, A7, A8 },
{ K6, A1, A2, A3, A4, A5, A6, A7, A8 },
{ K7, A1, A2, A3, A4, A5, A6, A7, A8 },
{ K8, A1, A2, A3, A4, A5, A6, A7, A8 },
{ A1, K1, K2, K3, K4, K5, K6, K7, K8 },
{ A2, K1, K2, K3, K4, K5, K6, K7, K8 },
{ A3, K1, K2, K3, K4, K5, K6, K7, K8 },
{ A4, K1, K2, K3, K4, K5, K6, K7, K8 },
{ A5, K1, K2, K3, K4, K5, K6, K7, K8 },
{ A6, K1, K2, K3, K4, K5, K6, K7, K8 },
{ A7, K1, K2, K3, K4, K5, K6, K7, K8 },
{ A8, K1, K2, K3, K4, K5, K6, K7, K8 }};

// 2-dimensional array of pixels:
int pixels[16][8];

int count;
int i;
int x = 1; // display next position
int y = 1;
int x0 = 1; // display last position
int y0 = 1;
int accxin[AVE]; // sensor signal averaging array
int accyin[AVE];
byte spt = 0; // averaging pointer
int accx; // acceleration
int accy;
int dx; // velocity
int dy;
int dotx; // moving distance ( calculation )
int doty;

void get_acc( void ){
// averaging acceleration sensor signal
accxin[ spt ] = analogRead( AX );
accyin[ spt ] = analogRead( AY );
spt++;
if ( spt >= AVE ){
spt = 0;
}
accx = 0;
accy = 0;
for ( i=0; i < AVE; i++){
accx += ( accxin[ i ] - XZEROG );
accy += ( accyin[ i ] - YZEROG );
}
accx /= AVE;
accy /= AVE;

// integrating acceleration makes velocity
dx += accx;
dy += accy;

// integrating velocity makes moving distance
dotx += dx;
doty += dy;

// reflection ( reverse velocity )
// 0 < x < 15
if ( dotx >= MAG*15){
dotx = MAG*15 - 1;
dx = -( dx * RF1 ) / RF2;
}else if ( dotx < MAG ){
dotx = MAG;
dx = -( dx * RF1 ) / RF2;
}
// 0 < y < 7
if ( doty >= MAG*7){
doty = MAG*7 - 1;
dy = -( dy * RF1 ) / RF2;
}else if ( doty < MAG ){
doty = MAG;
dy = -( dy * RF1 ) / RF2;
}

// x = accx + 8; // test acceleration value
// y = accy + 4;
// x = dx / 16 + 8; // test velocity value
// y = dy / 16 + 4;
x = dotx / MAG;
y = doty / MAG;

// display limitter
if ( x > 14) {
x = 14;
}else if ( x < 1 ){
x = 1;
}
if ( y > 6) {
y = 6;
}else if (y < 1){
y = 1;
}
}

// all output Hi-Z
void alloff( void ){
for ( i=0; i < 16; i++){
pinMode( LINE[ i ][ 0 ], INPUT );
}
}

// LED output control by Charlieplexing
void LED_digit( void ){
alloff();
pinMode( LINE[ count ][ 0 ], OUTPUT);
digitalWrite( LINE[ count ][ 0 ], LOW); // common cathode LOW output
for ( i=0; i < 8; i++){
if ( pixels[ count ][i] ){
pinMode( LINE[ count ][ 8-i ], OUTPUT);
digitalWrite( LINE[ count ][ 8-i ], HIGH); // turn on LED anode HIGH output
}
}
count++;
if ( count > 15 ){
count = 0;
get_acc(); // get acceleration and calculate next position
}

// turn off the last position
pixels[x0][y0] = 0;
pixels[x0+1][y0] = 0;
pixels[x0-1][y0] = 0;
pixels[x0][y0+1] = 0;
pixels[x0][y0-1] = 0;

// turn on the next position
pixels[x][y] = 1;
pixels[x+1][y] = 1;
pixels[x-1][y] = 1;
pixels[x][y+1] = 1;
pixels[x][y-1] = 1;

// store last position
x0 = x;
y0 = y;
}

void setup(){
alloff();
count = 0;
MsTimer2::set( 1, LED_digit); // 1ms interrupt setting
MsTimer2::start();
}

void loop(){
}