スピーカ端子にはプラスとマイナスの表示がされています。この端子はボイスコイルに繋がっています。プラス端子にプラスの電圧が加わった時にコーン紙が前に出るのか後ろに引っ込むのか決まっています。
今回はこの極性をチェックするツールの製作です。
先ず、スピーカに電圧を加えるパルサーとでも言えばいいのでしょうか、これを作ります。これは簡単な仕組みでコンデンサにチャージした電荷をプッシュスイッチで放電します。其の後、マイクでスピーカの音を拾う為のアンプを作ります。
とり合えず、スピーカのプラス端子にプラス電圧が印加された時に、マイクからどんな波形が出るのかをチェックし、次に逆の電圧を加えたときの波形を観測します。
マイクアンプはOPアンプの反転回路を使いました。プラスを加えるとOPアンプの出力はプラスに振れます。マイナスの時はマイナス側に振れます。傾向が分かったのでダイオードを使いプラス、マイナスを弁別する回路を作り、其の後。コンパレータで5Vのパルス変換、其の後、556を使い適当な時定数を持たせて緑、赤のLEDを点灯させます。
極性が正しい場合は緑のLED点灯。
極性が逆の場合は赤のLED点灯。
左手でパルサのプッシュスイッチを押しながら、右手で携帯のカメラのシャッターを押すのでブレてます。携帯のカメラはシャッターを押しても反応が遅くLEDが消えてしまいます。
スピーカもフルレンジ、ツーイータ、大きさ等色々あり、極性チェッカーの動作もいまひとつ、赤、緑が両方点灯したり、プラスを加えているのに赤が点灯したりです。
回路変更を何度か行い、どうにか、安定したチェック結果が得られるようになりました。
AVRは使っていません。 コンパレータ、LED点灯に使えばもっと色々できるかもです。
USARTのコンパイル条件をどのように反映させるのか、あれやこれややってみました。最終的に次のようにしました。これでいいのかどうかは分りませんが。
#if defined(__AVR_ATmega48__)||defined(__AVR_ATmega88__)||defined(__AVR_ATmega168__)\
||defined(__AVR_ATmega328P__)||defined(__AVRATmega328__)
//#define RX0_INTERRUPT USART_RX_vect
//#define TX0_INTERRUPT USART_TX_vect
#define UDR0_REG UDR0
#define UBRR0L_REG UBRR0L
#define UBRR0H_REG UBRR0H
#define UCSR0A_REG UCSR0A
#define UCSR0B_REG UCSR0B
#define UCSR0C_REG UCSR0C = (1<<UCSZ00_BIT | 1<<UCSZ01_BIT) <追加
略
#if defined(__AVR_ATmega8__)||defined(__AVR_ATmega8P__)||defined(__AVR_ATmega16__)\
||defined(__AVR_ATmega32P_)
//#define RX0_INTERRUPT USART_RXC_vect
//#define TX0_INTERRUPT USART_TXC_vect
#define UDR0_REG UDR
#define UBRR0L_REG UBRRL
#define UBRR0H_REG UBRRH
#define UCSR0A_REG UCSRA
#define UCSR0B_REG UCSRB
#define UCSR0C_REG UCSRC = (1<<URSEL | 1<<UCSZ00_BIT | 1<<UCSZ01_BIT) <追加
略
void USART_Init( unsigned int ubrr)
{
// Set baud rate
UBRR0H_REG = ubrr>>8;
UBRR0L_REG = ubrr;
// Enable receiver and transmitter
UCSR0A_REG = (0<<U2X0_BIT);
UCSR0B_REG = (1<<RXEN0_BIT)|(1<<TXEN0_BIT);
下記はコメントアウト
// Set frame format: 8 bit, no parity, 1 stop bit,
// UCSR0C_REG = (1<<UCSZ00_BIT | 1<<UCSZ01_BIT);
// UCSR0C_REG = (1<<URSEL | 1<<UCSZ00_BIT | 1<<UCSZ01_BIT);
略
この様に変更してMakefielのCPUをmega8、mega328を切り替えて、それぞれでコンパイルしましたがエラー無しでパスしました。
ATmega8にhexを書き込んで動作をみました。LCDの表示は正常、遅い感じはありません。RS232Cは夜に試して見ます。ATmega328についても。
2014/5/22(木)
ATmega8L: LCD,RS232共に正常に表示。
ATmega328: LCD ,RS232C共に正常に動作している。
プログラムの記述法は?だが、兎に角コンパイルが出来、書き込んだhexも期待通りに動いています。取りあえず良い事としましょう。
因みに、ATmega8でもVcc=3.3Vで動作しました。
BMP085を使った気圧計、ATmega328では正常に動作、しかし、ATmega8ではCPUの動作が遅く何となくおかしな挙動です。
色々調べて分りました。
プログラム抜粋:
#if defined(__AVR_ATmega48__)||defined(__AVR_ATmega88__)||defined(__AVR_ATmega168__)\
||defined(__AVR_ATmega328P__)||defined(__AVRATmega328__)
//#define RX0_INTERRUPT USART_RX_vect
//#define TX0_INTERRUPT USART_TX_vect
#define UDR0_REG UDR0
#define UBRR0L_REG UBRR0L
#define UBRR0H_REG UBRR0H
#define UCSR0A_REG UCSR0A
#define UCSR0B_REG UCSR0B
#define UCSR0C_REG UCSR0C
#define TXCIE0_BIT TXCIE0
#define RXCIE0_BIT RXCIE0
#define TXEN0_BIT TXEN0
#define RXEN0_BIT RXEN0
#define U2X0_BIT U2X0
#define UCSZ00_BIT UCSZ00
#define UCSZ01_BIT UCSZ01
#define UDRE0_BIT UDRE0
#endif
#if defined(__AVR_ATmega8__)||defined(__AVR_ATmega8P__)||defined(__AVR_ATmega16__)\
||defined(__AVR_ATmega32P_)
//#define RX0_INTERRUPT USART_RXC_vect
//#define TX0_INTERRUPT USART_TXC_vect
#define UDR0_REG UDR
#define UBRR0L_REG UBRRL
#define UBRR0H_REG UBRRH
#define UCSR0A_REG UCSRA
#define UCSR0B_REG UCSRB
#define UCSR0C_REG UCSRC
#define TXCIE0_BIT TXCIE
#define RXCIE0_BIT RXCIE
#define U2X0_BIT U2X
#define UCSZ00_BIT UCSZ0
#define UCSZ01_BIT UCSZ1
#define UDRE0_BIT UDRE
#define TXEN0_BIT TXEN
#define RXEN0_BIT RXEN
#endif
MakefileのCPUを指定してコンパイル、上記の定義が参照されます。ここまではOKです。問題はここです。
void USART_Init( unsigned int ubrr)
{
// Set baud rate
UBRR0H_REG = ubrr>>8;
UBRR0L_REG = ubrr;
// Enable receiver and transmitter
UCSR0A_REG = (0<<U2X0_BIT);
UCSR0B_REG = (1<<RXEN0_BIT)|(1<<TXEN0_BIT);
// Set frame format: 8 bit, no parity, 1 stop bit,
UCSR0C_REG = (1<<URSEL | 1<<UCSZ00_BIT)|(1<<UCSZ01_BIT);
stdout = &mystdout; //Required for printf init
}
ATmega8のUCSRCに上の赤字の1<<URSELを設定しないと駄目なのです。ATmega328にはこの設定はありません。
UCSR0C_REG = ( 1<<UCSZ00_BIT)|(1<<UCSZ01_BIT);
最初は上の記述だけでやっていました。これだとATmega328ではOKですがmega8ではNGです。
UBRRHの値がおかしくなるようです。
UCSR0C_REG = (1<<URSEL | 1<<UCSZ00_BIT)|(1<<UCSZ01_BIT);この部分を条件により
UCSR0C_REG = (1<<URSEL | 1<<UCSZ00_BIT)|(1<<UCSZ01_BIT);にするかあるいは
UCSR0C_REG = ( 1<<UCSZ00_BIT)|(1<<UCSZ01_BIT);とするかコンパイル条件を反映させる必要があります。
CPUのVccは関係なかった様ですが、Vcc=3.3VでATmega8を使うのであればLタイプを使うべきでしょう。
今日はケースを作りました。止めればいいもの、有り合わせの塗料を塗りたくりました。奥に見えるのがLPS331APを使った気圧計です。周りを囲ってしまった性かどうかは定かではありませんが温度がBMP085に比べて3度も高くなっています。どうも、自己発熱か他のICの熱が影響しているようです。
裏側です、面倒なので蓋は作りませんでした。かえってこの方がいいのかも知れません。
全体像です。
塗料はなかなか気に入った色合いのものがなく(あることはあるのですが、もっと大きな容器で値段も高い)安物塗料で間に合わせました。
2014/5/20(火)
ATmega8Lを入手して検証してみましたが、結果は変わらず、残念、、、、うーん、プログラムのどこかに問題ありと云うことの様です。UART部分を取りあえずコメントアウトしてやってみましょう。