2011年4月17日日曜日

アンプ

前回からの話は割愛し、アンプを実装してみました。

写真をミスって消してしまって撮り直すのが面倒なので今回はなしということに(ぇ


回路図はこんな感じになりました。



なんとなく解りづらくなってしまいましたが、
AC-INにはイヤフォン端子からのプラスが刺さります。
グランド(マイナス)端子はもちろんグランド(電位のマイナス)に。

イヤフォンからは2本の線が出ているのが多いと思いますが(耳につける部分が2つあるのはそう)、
マイナス端子はどちらでもなく、周りについてる銀色の「網」みたいなのです。
2本の線は両方プラス端子なので、その2つをアンプにつなげてもたぶん変な音がします。


あんまり当初との差異はないですね。
右上の5kΩが1kΩに変化しているくらいでしょうか。

図面では修正していますが右側の0.1uFのコンデンサは最初は100uFの予定でしたけど、
100uFを入れてしまうとどうやらクリップしてしまうようなので結構小さくしました。

クリップというのは波形が大きすぎて(バイアス電流があっていなくて)、
上下がトランジスタの出力できる範囲から外れてしまっている現象です。


それとスピーカに直列になっているコンデンサも最初は10uFの予定でしたが、
10uFを持っていないので100uFにしました。
こっちは0.1uF(小さくする)だと若干不具合が起こったので大きい方に差し替えました。

どちらも正直、10uFがあればちょうどよかったんですけど、
持っていないのでしょうがない、って感じですかね。

まあ製品でもないしただの実験なので関係ない関係ない。動けばいいんです(笑


実験する場合にそこそこ重要だと思うのが、自分が持っている部品に合わせるということ。
ほんとは33kΩだったりのE系列とやらが適しているようなのですが、
自分は100、1k、10k、100kしか持っていないので、それで簡単に作れる数値に合わせました。

50kは100kを2つ並列、あとは単体で作れますね。
コンデンサは直列で抵抗の並列と同じ計算(和分の積)になるんですけど、
まあそこまで厳密な静電容量はいらないのでそのままで。


そしてこれが実装した波形のシミュレーションです。




下が入力、上が出力です。
クリップもなくいい感じです。
実際に聞いてみても結構クリアな音だと思いました。

ただトランジスタが2石なのと、1次側の出力をそのまま2次側の入力に持っていってるので
もう少し上手いこと増幅することは可能だと思います。
(2回もバイアスの計算をするのが面倒だったからとかではない)


今回は電池以外は手持ちだったので、電池の価格=製作費になりました。
この電池もまだまだ使えるのでパーツがひとつ増えたって感じですね。


アンプとは無関係ですけど実はいまさらマルチバイブレータが学校で出てきたので、
これで何かできないかなーとか考えてます。
せっかくだしパルス速度上げて音でも出してみようかな?


全くアナログ回路を知らないままデジタルを触り始めたので
まだまだやることがたくさんありそうです。

もともと若干ソフト寄りだからなぁー。
メカトロニクス技術者に向けてアナログ、デジタル、メカニクスは習得しておきたい。

なんというか抱負でした。以上。

2011年4月5日火曜日

LTspice(フリーソフト)とアンプ

私の部屋(というか家)にはオーディオというものが一切なくてですね、
もちろんスピーカーの類もないわけです。

音楽聴くときはだいたいノートPCのスピーカーとかイヤフォンとか。

そんなときにふと、PCのイヤフォンジャックから手持ちの0.5Wスピーカにつなげるのではないか、
とかいうわけのわからない発想が出てきましてイヤフォンのケーブルを切ってテスタで電圧とかを測ってみたんですけど
まったくもって針が振れないという結果に終わりました。
いや、10mAのレンジでやや振れるかなー程度には観測できました。

もちろんスピーカにつなげても音など鳴るはずもなく、ならトランジスタで増幅を~(アンプ自作)と思ったものの
現在、ブレッドボードは使用中…。
そして一回ずつ回路を組み替えて測定するのは骨が折れる。
入力波形も微弱なためミスが発見し難い。

そんなときにアンプ関連のサイトでLTspiceとかいうソフトが紹介されていたわけです。
一番上の箱の「ダウンロード!LTspiceIV」を押して、
「No thanks...」とかいう下の方を押せばDL完了です。


LTspiceは回路シミュレータ(シュミレータ、ではない)で、
回路をコンピュータ上で実験してくれるソフトです。

物理系ならphunとかBlenderとかのフリーソフトがあるんですけど、
電気はなかなか見つかりませんで^^;
(といっても探す気もなかった)

あと機械系ならAutodeskかどっかが出してたなぁ。これはもちろん有料(数百万のレンジだったと思う)。
ちなみにそこに使う3DcadもAutodeskが出してるけど有料。


それでまあ電気CADもAutodeskが出していたような気がするので大体有料か、
そうでなければ機能制限もしくはロークォリティな感じかと思っていましたが、まさかのミドルレンジ。

いや、実際そうなのかは知らないけど(笑
部品点数の制限がありません。

そんな感じで波形やら電圧やら電流やら消費電力やらを解析(シミュレーション)できるソフトを手に入れたってわけです。

余談だけど(我が)龍谷大学ではPspiceというソフトらしいです。これもフリー(まさかのフリー)


見ているうちにどっかのサイト(http://gomisai.blog75.fc2.com/blog-entry-448.html)が
PspiceとLTspiceの比較をしていたので見た結果、LTspiceに。

(前置きここまで)


試しにここ(http://www005.upp.so-net.ne.jp/guitarder/other/o-07-tr-01.html)の
一石トランジスタ回路をシミュレートしてみた結果、素晴らしい感じに。




中心付近の波形が入力(スピーカー端子から)で、一番振幅の大きいのが出力電圧、
あいだにある青いのが出力電流(負荷は適当)です。


なぜかへんに嵌ってしまってインダクタとコンデンサで適当な波形を作ったりして遊んでいます。
部品数の制限がないのでバーサライタのシミュレーションもできます。
もちろん、マイコン(AVRとか)は出来ませんけど。
解放時の出力電流や、消費電力などがシミュレートできるのでお薦め。


そんな感じで支離滅裂ながらお遊び日記。

使用方法はさっきのねがてぃぶろぐさんにあります。以上。

LEDバーサライタmarkII・スケッチ


前回の最後の方で行ってたスケッチです。
見ての通り一部の文字しか対応していません(笑

これでおおよそ1500byteくらいです。
Attiny2313のフラッシュメモリが2000byteなので頑張れば移植できそうです。
ただポート番号が変わるのと、PCINTがBピンの並びにしかないので
使うならばINT割り込みになるんじゃないでしょうか。
(INT0はPD2、INT1はPD3)

LEDが9列なので少し見難い感はありますけど当初よりはスマートになったんじゃないかな?
以下。


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


const prog_uint8_t a_line[2][6] = {{0b00000000,0b00000001,0b00000001,0b00000001,0b00000001,0b00000000},
{0b11111111,0b00001000,0b00001000,0b00001000,0b00001000,0b11111111}};
const prog_uint8_t b_line[2][6] = {{0b00000001,0b00000001,0b00000001,0b00000001,0b00000001,0b00000000},
{0b11111111,0b00010001,0b00010001,0b00010001,0b00010001,0b11101110}};
const prog_uint8_t d_line[2][6] = {{0b00000001,0b00000001,0b00000001,0b00000001,0b00000000,0b00000000},
{0b11111111,0b00000001,0b00000001,0b00000001,0b10000010,0b01111100}};
const prog_uint8_t e_line[2][6] = {{0b00000001,0b00000001,0b00000001,0b00000001,0b00000001,0b00000001},
{0b11111111,0b00010001,0b00010001,0b00010001,0b00010001,0b00000001}};
const prog_uint8_t h_line[2][6] = {{0b00000001,0b00000000,0b00000000,0b00000000,0b00000000,0b00000001},
{0b11111111,0b00010000,0b00010000,0b00010000,0b00010000,0b11111111}};
const prog_uint8_t i_line[2][6] = {{0b00000001,0b00000001,0b00000001,0b00000001,0b00000001,0b00000001},
{0b00000001,0b00000001,0b11111111,0b00000001,0b00000001,0b00000001}};
const prog_uint8_t l_line[2][6] = {{0b00000001,0b00000000,0b00000000,0b00000000,0b00000000,0b00000000},
{0b11111111,0b00000001,0b00000001,0b00000001,0b00000001,0b00000001}};
const prog_uint8_t m_line[2][6] = {{0b00000001,0b00000000,0b00000000,0b00000000,0b00000000,0b00000001},
{0b11111111,0b11000000,0b01110000,0b01110000,0b11000000,0b11111111}};
const prog_uint8_t o_line[2][6] = {{0b00000000,0b00000001,0b00000001,0b00000001,0b00000001,0b00000000},
{0b11111110,0b00000001,0b00000001,0b00000001,0b00000001,0b11111110}};
const prog_uint8_t p_line[2][6] = {{0b00000001,0b00000001,0b00000001,0b00000001,0b00000001,0b00000000},
{0b11111111,0b00010000,0b00010000,0b00010000,0b00010000,0b11100000}};
const prog_uint8_t r_line[2][6] = {{0b00000001,0b00000001,0b00000001,0b00000001,0b00000001,0b00000000},
{0b11111111,0b00010000,0b00010000,0b00011000,0b00010100,0b11100011}};
const prog_uint8_t t_line[2][6] = {{0b00000001,0b00000001,0b00000001,0b00000001,0b00000001,0b00000001},
{0b00000000,0b00000000,0b11111111,0b00000000,0b00000000,0b00000000}};
const prog_uint8_t u_line[2][6] = {{0b00000001,0b00000000,0b00000000,0b00000000,0b00000000,0b00000001},
{0b11111110,0b00000001,0b00000001,0b00000001,0b00000001,0b11111110}};
const prog_uint8_t v_line[2][6] = {{0b00000001,0b00000000,0b00000000,0b00000000,0b00000000,0b00000001},
{0b11111000,0b00000110,0b00000001,0b00000001,0b00000110,0b11111000}};
const prog_uint8_t w_line[2][6] = {{0b00000001,0b00000000,0b00000000,0b00000000,0b00000000,0b00000001},
{0b11111100,0b00000111,0b00111100,0b00111100,0b00000111,0b11111100}};
const prog_uint8_t y_line[2][6] = {{0b00000001,0b00000000,0b00000000,0b00000000,0b00000000,0b00000001},
{0b11000000,0b00100000,0b00011111,0b00010000,0b00100000,0b11000000}};

void space(){
PORTB = 0b00000000;
PORTD = 0b00000000;
_delay_ms(30);
}

int main(void){
cli();
DDRB = 0b11111111;
DDRD = 0b11111111;
DDRC = 0b00000000;
PORTC = 0b11111111;
PCICR = (1<<PCIE1);
PCMSK1 = (1<<PCINT8);
int i;
sei();
while(1){
for(i = 0;i < 6;i++){
PORTB = pgm_read_byte(&h_line[0][i]);
PORTD = pgm_read_byte(&h_line[1][i]);
_delay_ms(3);
}
PORTB = 0b00000000;
PORTD = 0b00000000;
_delay_ms(3);


for(i = 0;i < 6;i++){
PORTB = pgm_read_byte(&a_line[0][i]);
PORTD = pgm_read_byte(&a_line[1][i]);
_delay_ms(3);
}
PORTB = 0b00000000;
PORTD = 0b00000000;
_delay_ms(3);


for(i = 0;i < 6;i++){
PORTB = pgm_read_byte(&p_line[0][i]);
PORTD = pgm_read_byte(&p_line[1][i]);
_delay_ms(3);
}
PORTB = 0b00000000;
PORTD = 0b00000000;
_delay_ms(3);


for(i = 0;i < 6;i++){
PORTB = pgm_read_byte(&p_line[0][i]);
PORTD = pgm_read_byte(&p_line[1][i]);
_delay_ms(3);
}
PORTB = 0b00000000;
PORTD = 0b00000000;
_delay_ms(3);


for(i = 0;i < 6;i++){
PORTB = pgm_read_byte(&y_line[0][i]);
PORTD = pgm_read_byte(&y_line[1][i]);
_delay_ms(3);
}
PORTB = 0b00000000;
PORTD = 0b00000000;
_delay_ms(3);


space();


for(i = 0;i < 6;i++){
PORTB = pgm_read_byte(&b_line[0][i]);
PORTD = pgm_read_byte(&b_line[1][i]);
_delay_ms(3);
}
PORTB = 0b00000000;
PORTD = 0b00000000;
_delay_ms(3);


for(i = 0;i < 6;i++){
PORTB = pgm_read_byte(&i_line[0][i]);
PORTD = pgm_read_byte(&i_line[1][i]);
_delay_ms(3);
}
PORTB = 0b00000000;
PORTD = 0b00000000;
_delay_ms(3);


for(i = 0;i < 6;i++){
PORTB = pgm_read_byte(&r_line[0][i]);
PORTD = pgm_read_byte(&r_line[1][i]);
_delay_ms(3);
}
PORTB = 0b00000000;
PORTD = 0b00000000;
_delay_ms(3);


for(i = 0;i < 6;i++){
PORTB = pgm_read_byte(&t_line[0][i]);
PORTD = pgm_read_byte(&t_line[1][i]);
_delay_ms(3);
}
PORTB = 0b00000000;
PORTD = 0b00000000;
_delay_ms(3);


for(i = 0;i < 6;i++){
PORTB = pgm_read_byte(&h_line[0][i]);
PORTD = pgm_read_byte(&h_line[1][i]);
_delay_ms(3);
}
PORTB = 0b00000000;
PORTD = 0b00000000;
_delay_ms(3);


for(i = 0;i < 6;i++){
PORTB = pgm_read_byte(&d_line[0][i]);
PORTD = pgm_read_byte(&d_line[1][i]);
_delay_ms(3);
}
PORTB = 0b00000000;
PORTD = 0b00000000;
_delay_ms(3);


for(i = 0;i < 6;i++){
PORTB = pgm_read_byte(&a_line[0][i]);
PORTD = pgm_read_byte(&a_line[1][i]);
_delay_ms(3);
}
PORTB = 0b00000000;
PORTD = 0b00000000;
_delay_ms(3);


for(i = 0;i < 6;i++){
PORTB = pgm_read_byte(&y_line[0][i]);
PORTD = pgm_read_byte(&y_line[1][i]);
_delay_ms(3);
}
PORTB = 0b00000000;
PORTD = 0b00000000;
_delay_ms(3);


for(i = 0;i < 2;i++){
space();
}
}
}

ISR(PCINT1_vect){
if(bit_is_clear(PINC,PC0)){
_delay_ms(80);

int i;

for(i = 5;i >= 0;i--){
PORTB = pgm_read_byte(&d_line[0][i]);
PORTD = pgm_read_byte(&d_line[1][i]);
_delay_ms(3);
}
PORTB = 0b00000000;
PORTD = 0b00000000;
_delay_ms(3);


for(i = 5;i >= 0;i--){
PORTB = pgm_read_byte(&l_line[0][i]);
PORTD = pgm_read_byte(&l_line[1][i]);
_delay_ms(3);
}
PORTB = 0b00000000;
PORTD = 0b00000000;
_delay_ms(3);


for(i = 5;i >= 0;i--){
PORTB = pgm_read_byte(&r_line[0][i]);
PORTD = pgm_read_byte(&r_line[1][i]);
_delay_ms(3);
}
PORTB = 0b00000000;
PORTD = 0b00000000;
_delay_ms(3);


for(i = 5;i >= 0;i--){
PORTB = pgm_read_byte(&o_line[0][i]);
PORTD = pgm_read_byte(&o_line[1][i]);
_delay_ms(3);
}
PORTB = 0b00000000;
PORTD = 0b00000000;
_delay_ms(3);


for(i = 5;i >= 0;i--){
PORTB = pgm_read_byte(&w_line[0][i]);
PORTD = pgm_read_byte(&w_line[1][i]);
_delay_ms(3);
}
PORTB = 0b00000000;
PORTD = 0b00000000;
_delay_ms(3);


space();


for(i = 5;i >= 0;i--){
PORTB = pgm_read_byte(&o_line[0][i]);
PORTD = pgm_read_byte(&o_line[1][i]);
_delay_ms(3);
}
PORTB = 0b00000000;
PORTD = 0b00000000;
_delay_ms(3);


for(i = 5;i >= 0;i--){
PORTB = pgm_read_byte(&l_line[0][i]);
PORTD = pgm_read_byte(&l_line[1][i]);
_delay_ms(3);
}
PORTB = 0b00000000;
PORTD = 0b00000000;
_delay_ms(3);


for(i = 5;i >= 0;i--){
PORTB = pgm_read_byte(&l_line[0][i]);
PORTD = pgm_read_byte(&l_line[1][i]);
_delay_ms(3);
}
PORTB = 0b00000000;
PORTD = 0b00000000;
_delay_ms(3);


for(i = 5;i >= 0;i--){
PORTB = pgm_read_byte(&e_line[0][i]);
PORTD = pgm_read_byte(&e_line[1][i]);
_delay_ms(3);
}
PORTB = 0b00000000;
PORTD = 0b00000000;
_delay_ms(3);


for(i = 5;i >= 0;i--){
PORTB = pgm_read_byte(&h_line[0][i]);
PORTD = pgm_read_byte(&h_line[1][i]);
_delay_ms(3);
}
PORTB = 0b00000000;
PORTD = 0b00000000;
_delay_ms(3);
space();
}else{
}
}

2011年4月1日金曜日

LEDバーサライタmarkII

そこそこ完成に近いと思います。

ブレッドボードの大きさの問題でLEDは初期と同じく9個ですけど
反対向きに振ったときの文字の表示もできるようになりました。

前回は割り込みを外部割り込みINT0~1を使う予定でしたが
あまりにも文字部分を書き換える手間が発生してしまうので、
最終的にはPCINTを使うことに。

INTもPCINTもたぶん大して変わりはない(INTはまったく使用せずなので)と思います。
INTがレジスタで割り込みの発生条件を決めるのに対して、
PCINTはプログラム内で発生条件を決める、という解釈でいいんでしょうか?

まあPCINTがなんでもかんでも拾うからそれをifとかで選別しろってことですね。たぶん(ぇ


というわけで回路図。


前より少しだけ横長になりました(笑

いつものことですけどGNDとかVCCとか書かないのはだれが見てもわかるように。
今はちょっと読めるようになったけど昔は「GNDってなんだ?」状態でしたので。



その他、プログラムの方は
「配列を作るとなぜかEEPROMに書き込まれる仕様」
となっていたので(AVR特有らしい)、それをフラッシュメモリ(プログラムと一緒のところ)に
入れるのに四苦八苦。

別にEEPROMでもよかったんですけどこれには深いわけが…。
ということもなく(実際にはあったんですけど)。

単純に電源の質が悪かっただけなのに行き着いた結果がこれです(笑
ダイジェストで説明。

LEDの点滅速度が一定じゃない(9個バラバラなので振っても文字にならない)
↓
もしかして割り込みが悪いんじゃないか
↓
違ったので、もしかしたら配列がEEPROMに入っているのが悪いんじゃ(略
↓
ここでEEPROMからフラッシュに移動させる(しかし改善されず)
↓
どうやらライタが接続されている間はちゃんと動作するのに、
ライタを外すとダメなようだ
↓
ライタの中で何か接続がされていてそこを繋げばいいんじゃ
↓
ISPケーブルを一本ずつ抜いていってどれを抜くとアウトかを調べる
↓
VCCまたはGNDでした。ということはつまり。


電源(電池)の接触が悪く、単にノイズ(というよりはもっと大きな電圧変化)の所為でした。
もともとブレッドボードは場所により接触悪いので、挿す場所を変え、
電源用の電解コンデンサをぶち込む事で解決でした。



なんという徒労…orz

上の「配列を作ると~」は全く関係なかったわけですね。
ライタを接続していれば大丈夫だった理由は、
たぶんライタ内にコンデンサでも入ってるってことなんでしょうね。
(半透明なのに見えない…( ̄⊿ ̄)ぐぬぬ…


まあ結果的に書き換え回数が10,000回のEEPROMを使わずに済んだのは良かったのかも。
今後はこれで嵌ることがないようにしないと…。数時間これと格闘してたからなぁ(遠い目

回路図のRESET10kΩもたぶんいらないです。

これを完成させるにはまずICソケットを買わないとなぁ。
物流動いてるんだろーか。
プログラムスケッチは別で貼ろう。