CubeLED

>よく皆さんが作っていらっしゃるCubeLEDを制御してみました。
3*3*3=27個です。

制作は、例のごとく後輩です//

一枚のC型基盤にLEDも制御系も全部載ってます。

ピカピカさせました。

使用したLEDは
http://akizukidenshi.com/catalog/g/gI-01786/
です。
綺麗にみえたので。

回路図って前の電光掲示板の時みたいな感じかなぁと思いつつ、でも3次元だからAND回路とか組み合わせるのかなーって考えてたら、
意外と普通で残念です。

制御線は12本です。
段の選択が3本、場所の選択が9本です。
つまり、XYはダイナミック点灯していなくて、XYとZでダイナミック点灯しているわけです。

制御はATMega168Pを1MHzで動作させてます。

回路図も、LEDをつなぐだけ。

※この回路は、僕が床に落として踏んでしまったため、現在ひし餅のようになっております。

プログラムは

#include <avr/io.h>
#include <util/delay.h>

/*

PD4 PD3 PD2

PB5 PB4 PB3

PB2 PB1 PB0

*/

#define F_1 PORTC|=0b00000001;PORTC&=0b11111001//PC0
#define F_2 PORTC|=0b00000010;PORTC&=0b11111010//PC1
#define F_3 PORTC|=0b00000100;PORTC&=0b11111100//PC2
#define DARK PORTC&=0b11111000

#define LIGHTTIME 1

void output(uint16_t data);//9ビットのデータを入れる(上位7ビットは捨てる,左上(PD2)から)

uint16_t data[3];

void init_io();
void floor_select(uint8_t floor);
void delay_ms(uint16_t ms);
void delay_us(uint16_t us);
void draw();
void keep(uint16_t keeptime);//たぶん10000で1秒ぐらい

int main(){
init_io();

while(1){
data[0]=0b101010101;
data[1]=0b010101010;
data[2]=0b101010101;
keep(2500);

data[0]=0b010101010;
data[1]=0b101010101;
data[2]=0b010101010;
keep(2500);
}

}

void keep(uint16_t keeptime){
for(uint16_t k=0;k<=keeptime;k++){
draw();
}
}

void draw(){
output(data[0]);
F_1;
delay_us(LIGHTTIME);
DARK;

output(data[1]);
F_2;
delay_us(LIGHTTIME);
DARK;

output(data[2]);
F_3;
delay_us(LIGHTTIME);
DARK;
}

void output(uint16_t data){
PORTD=((data&0b111000000)>>4)&0b00011100;
PORTB=(data&0b000111111)&0b000111111;
}

void init_io(){
DDRC=0xff;//フロア選択用
DDRB=0xff;
DDRD=0xff;
}
void delay_ms(uint16_t ms){
while(ms–){
_delay_ms(1);
}
}

void delay_us(uint16_t us){
while(us–){
_delay_us(1);
}
}

こんな感じで動きました!

本当は動画もアップしたいのですがあまり綺麗でないのと、光り方のバリエーションをまだあんまり作ってないので動画に出来なかったんです……

それに写真見てもあまり綺麗じゃないですが、本物はめっちゃ綺麗です!

皆さんも作ってみてはどうでしょう?

Wiiモーションプラスの分解

>Wiiモーションプラスを分解してみました。

まだAVRでのi2c通信は試してません(一応組んでは見ましたが)
分解しようとしたらいきなり突き当たったのが
Y字ドライバー
……持ってねぇ
仕方が無いので……
メリメリ……
メリメリメリメリ……
ふぅ
にょき
とれた!
下が本体で上はモーションプラスの底に付いてる、別部品をさすためのコネクタです。
こっちが空。むなしい。
たぶん明日か明後日ぐらいにはしっかり動作確認してきます……

>FusionPCB

>前にプリント基板会社PCB CARTについて記事を書いたことがあります。

PCB CARTも安いですが、もっと安いとこもあります。
Fusion PCBです。

いつだったか(1年も前じゃない)値下げされて、5cm×5cmのプリント基板が10枚$9.90で作れます。
他のサイズもかなり安いです。
一回ぐらい失敗してもいいじゃんって思えるような値段ですよね。プロの方たちはよくここで試作してみて、別のところに本注文する、というパターンも有るようです。
※海外なので送料が結構高いです

また、結構細かいんですよ。

最小線幅が
OLIMEXは10mil
PCBCARTは8mil
FusionPCBは6mil
P板が5mil
です。

FusionPCBもなかなかやるでしょ?P板には負けますが、しかたないです。

そこで

こんな基板を頼もうと思うんですが、欲しい方いらっしゃいますか?サイズは50mm*50mmです
というか、エラーチェックをしてもらいたいなぁと思いまして……

こここうしたほうがいいよ。みたいなのがあればどしどしコメントください。

CTS信号の競合は……やっぱり直したほうがいいですかね?とか思いつつ直してません。XBeeの設定したい時はAVR外せばいいかなぁと思って。
基本Arduinoです。それにXBeeをUSB接続するための回路とか入ってます。

電源はL6920(昇圧DC-DCコンバータ)を載せているので、外部供給で乾電池1本もしくは2本で動きます。
LED一つ光らせるぐらいなら、JP1をジャンパーして、XBeeを外せばFT232RL内蔵のレギュレータで動かしてくれます(50mAまで)

※2011/10/18追記
実際に注文してみました→http://y-56tomo-mutter.blogspot.com/2011/10/blog-post.html

>加速度センサ

>ストリナで販売されている

この\945の加速度センサを使用してみました。

使用したマイコンは例のごとくATMega328Pで、
ここ(部活の先輩のブログ)でupされている(先輩作!)i2cのライブラリから加速度センサの部分をもらってきて、ちょっと書き換えればすんなり動いてくれました!

値域はだいたいそれぞれの軸で-70~+70ってとこです。(重力加速度のみの場合)
けっこうぶれますが。おそらく本当に加速度がかかっているんでしょう。

明日はずっと逃げているラスボス、Wiiモーションプラスに挑戦ですかね。

AVRからの8ビットタイマのPWMによるサーボモーター及びブラシレスモーターアンプの制御

論文みたいなタイトルつけてみましたw書いた事無いですが

AVRの8bitタイマ(Timer0,Timer2)の高速PWMモードでブラシレスアンプを制御することができました。
もちろんサーボモーターにも応用できるはずです。(信号部分は共通だが初期化部分は不要)

詳しい信号については他のページを参照していただきたいです。

なぜこのページが有用かといえば、AVRからサーボモータやブラシレスアンプを制御する資料はなぜか周期20msにこだわって数少ない16bitタイマー(Timer1)を使用するものばかりだからです。
Timer1を使うとAVR1つあたり1つしか使用できないサーボモータやブラシレスアンプを、これなら4つ同時に制御できます!

今回使用したのはヘリ用ののアンプ。
初期設定のまま使用しました。
ブレーキなし、一方向の回転のみ(これは変わりませんが)です。

まず悩んだのは初期化の仕方。
初期化なしでは全く回りませんでした。そこで
AVR Tiny13を用いて信号解析用にブレッドボードで回路を製作。

そして試行錯誤の結果出た結論が
「暫く1.5msのパルス→ブッブッブッブッブッ→暫く2.0msのパルス→プププッ→初期化完了!」
というフローチャートです。
もちろんサーボモータなら初期化いりませんが。

そして早速プログラムへ実装!
(開発環境はAVR Studio4,WinAVR使用)

※HTMLの関係から、<は<に、/は/に直してからご使用ください

/*

PWMによるブラシレス制御(アンプ使用)
rev 2 :2011/8/2

ATMega328P,16MHz

*/

#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>

#define PWM1 OCR0A
#define PWM2 OCR0B
#define PWM3 OCR2A
#define PWM4 OCR2B

#define PWM_FOR 31//2ms
#define PWM_NEUTRAL 23//1.5ms
#define PWM_STOP 15//1ms

uint16_t i;

void delay_ms(uint16_t ms){
while(ms–){
_delay_ms(1);
}
}
void delay_us(uint16_t us){
while(us–){
_delay_us(1);
}
}

void ioinit(){
DDRD|=0b01101000;//PWM
DDRB|=0b00001000;//PWM
}

void set_pwm(uint8_t pw1,uint8_t pw2,uint8_t pw3,uint8_t pw4){
PWM1=pw1;
PWM2=pw2;
PWM3=pw3;
PWM4=pw4;
}

void init_pwm(){
//タイマー0
TCCR0A = 0b10100011; //非反転 8ビット高速PWMモード
TCCR0B = 0×05; //1024分周

//タイマー2
TCCR2A = 0b10100011; //非反転 8ビット高速PWMモード
TCCR2B = 0×07;  //1024分周
}

int main(){
delay_ms(500);//起動待ち

ioinit();delay_ms(10);
init_pwm();delay_ms(10);

/*初期化*/
set_pwm(PWM_NEUTRAL,PWM_NEUTRAL,PWM_NEUTRAL,PWM_NEUTRAL);
delay_ms(5000);
set_pwm(PWM_STOP,PWM_STOP,PWM_STOP,PWM_STOP);
delay_ms(5000);

while(1){
set_pwm(PWM_FOR,PWM_FOR,PWM_FOR,PWM_FOR);
delay_ms(1000);

set_pwm(PWM_STOP,PWM_STOP,PWM_STOP,PWM_STOP);
delay_ms(1000);
}
}

以上です。
サーボモーターの場合は/*初期化*/の下の4行が不要ですね。
速度調節は16段階できるようになっています。(試したところあのアンプはパルス幅1.0ms~2.0msまで順々に速度が上がっていくようです)

やはり同時に多数の特殊モーターを制御できるのは嬉しいですね!

9/1追記:
初期化不要で、サーボモーターも動きました。

9/13追記:
プログラムのPWMの初期化部分がコメントはあってるのに値が間違っていたのを修正(TCCR2Bレジスタ)