ラベル 測定器 の投稿を表示しています。 すべての投稿を表示
ラベル 測定器 の投稿を表示しています。 すべての投稿を表示

2009年4月1日水曜日

TinyでDRO!(ソフトウェア2)

データの頭出しは、データ送出の時間間隔が約0.3秒開いているという仕様に頼ります。0.3秒と仕様にしてはやや甘いので、実際のプログラムでは「0.25秒以上開いたら」という条件に置き換えます。

このタイミングはTimer1を使って計ります。システムクロックを256分周した周波数でカウントアップします。カウントアップの最大値が0.25秒で訪れるように比較一致レジスタOCR1Aを設定し、最大値に達したら自動ゼロクリアするようにCTC動作にします。

下図のタイミングチャートでは、データビットの送出タイミングに合わせてTimer1のカウント値がどのように変化するかを示しています。「絶対座標のデータ」または「相対座標のデータ」の下の部分を見て分かる通り、データビットを取り込むタイミング(INT1のハンドラ内)でTimer1をクリアしています(図の「エッジ割り込みでクリア」と書いてある部分)。0.25秒未満の短い間隔では決して最大値には達しません。

ところが、データを送出し終わってしばらくデータが来ないとTimer1を強制クリアする機会がなく、そのまま増加し続け、0.25秒経過の後ついには最大値=比較一致レジスタの値に達します(図の「比較一致」)。つまり、この時点でデータの区切りが訪れたと認識するのです。プログラムでは比較一致割り込みを起こさせるようにしてあり、そのハンドラの中でバッファポインタを先頭に持ってくる、つまりデータの頭出しをすることになります。以下は再び"interrupt.c"の該当部分です。(行間が空いているのはCPUタイプによるIF-DEFを消して見やすくしたためです。)

// スケールのデータ送信間隔を測る



ISR(TIMER1_COMPA_vect)

{
Rbufp = Rbuf; /* バッファポインタを先頭へ */
}

2009年3月27日金曜日

TinyでDRO!(ソフトウェア1)

ソフトウェアの説明です。例によってSourceForgeで公開します。


ヒューズの設定はZIPファイルの中のFuseMapping.jpgにAVRStudioの(中のAVRProgの)設定画面のスクリーンショットを入れてありますので参考にしてください。また、ソースコード中にもコメントで書き込んであります。要は内蔵RC発振器をONにして、1/8分周をOFFにするということです。

今回のプログラムの要点は、スケールから送られてくるデータをクロックに同期して取り込むこと、そして直列で送られてくるデータを切り出し---つまり頭出し---することです。

まずマクロな視点から。データブロックは約0.3秒の間隔でスケールから出力されています。


クロック(CLK)は出っぱなしではなく、データ(DATA)が送られるときのみ出ているのが分かります。クロックが出ていないときは論理"0"(-1.5V電位)にスタックしています。データブロックの部分をクローズアップしてみます。


クロックはデータ出力開始直前に"1"(GND電位)となり、しばらくしてからクロッキングを始めます。クロック周期は約12usですので、周波数にすると約83kHzです。

データは2種類送られてきます。先に絶対座標のデータ、後に相対座標のデータです。絶対座標はそのスケール固有の位置情報で、原点が絶対にずれることはありません。相対座標はスケールのゼロクリアボタンを押すごとに原点を設定するもので、通常はこちらが使われることになります。

これらのデータは24ビット長で、クロックパルスに同期して順次最下位ビットから送り出されます。図でA0~A23が絶対座標、R0~R23が相対座標です。R24(ダミー)と書いてあるビットがありますが、これは本来は取り込まないビットで、後ほど説明します。

図で分かる通りクロックの立下りエッジでデータを取り込むとよさそうな感じです。実際のプログラムでは、AVRに入ってくるときにレベルシフタにより論理反転していますので、クロックの立ち上がりエッジで捉えることにしています。ここでファイル"interrupt.c"の該当部分。(コメント部分で改行されてしまい読みにくいのでコメントをちょっといじってあります。)

// スケールからのデータ取り込み。検出エッジは立上がりエッジ。
ISR(INT1_vect)
{
*Rbufp++ = SCALE_PIN; /* 読んでバッファにためる */
if (Rbufp >= Rbuf + sizeof(Rbuf)) {/*バッファ端*/
Rbufp = Rbuf + sizeof(Rbuf) - 1;
Updated = 1; /* main()に更新を通知 */
}
TCNT1 = 0; /* 送信間隔タイマーをクリア */
}
INT1は立ち上がりエッジを検出するように設定されています。重要なことは割り込みセンスから割り込みプログラムが起動されるまでの時間がかなりかかることです。あまり時間がかかるとデータを読みそこなってしまいます。割り込み処理のシーケンスは、
  1. INT1エッジ認識
  2. 割り込みハンドラに分岐
  3. 使用するレジスタ群を退避
  4. ユーザの定義した割り込み処理プログラムを実行
上記の1.から2.までで約4クロックかそれ以上かかり、これはAVRハードウェアによるオーバーヘッドですので回避不能です。3.はコンパイラの出力するコードによるオーバーヘッドが含まれ、アセンブラで書かない限りは制御はやっかいです。コンパイラのアセンブラ出力を見るとここに16クロックかかっていることが分かります。そこでこの割り込み処理では、スケールのDATAがつながっている入力ポート(上記リストの"SCALE_PIN"=PIND)を何はともあれ読み込んで、バッファにためることだけを行っています(52行目)。その際にそのビットを抽出するなど余計なことはやっていません。ちょっとでも複雑なことをしようとすると、コンパイラはためらうことなくたくさんのレジスタを使おうとして、それらを退避するコードを割り込み処理の冒頭に突っ込んでくるからです。

今回データ読み込みはすべてクロックの立ち上がりエッジ(タイミング図上では立下り)で検出しているので、前出のタイミング図では、データ送出終わった後にクロックが"0"スタックする時点でもうひとつ検出エッジが来てしまいます。これが「R24(ダミー)」と書いてあるゆえんです。プログラムではこの部分も愚直に読み込んでしまうことで、割り込みプログラム中の無用な条件判定を回避しています。読み込んだとしても値を集計するときに使わなければいいのです。

2009年3月25日水曜日

TinyでDRO!(ハードウェア2)

このプロジェクトで何が一番難しかったかって、デジタルスケールにどうやってケーブルを接続するか考え出すことでした。プラグインできる汎用のコネクタなどありませんし、かといってケーブルをじかに出すのは気が引けるし。逡巡したあげく結局どこかのサイトで見た、コネクタヘッダをはんだ付けする方法を取りました。出来上がりはこんな風になります。



スケールを完全に分解する改造です。メーカー保証はあきらめましょう。分解して基板をむき出しにしたら基板用コネクタヘッダをはんだ付けします。基板エッジにでている接点パターンは、きちんと計測すると1.65mmピッチくらいだということが分かるのですが、ここでは2.0mmピッチのこれを使いました。4ピンなのでぎりぎりこれでも大丈夫です。ただ、このコネクターは非常に熱に弱くて少しでも余分に長くこてを当てようものならコネクタハウジングが融けてピンが泳ぎだすのが難点です。少々高くても他のメーカーのものを使うのが賢明でしょう。なお、分解しないで無理やりはんだ付けする方法もありますが、スケールのケースが溶けるのでお勧めはできません。後述のコネクタカバーが閉まらなくなってしまいます。



組み立てる前にスケールのプラスチックカバーの加工をします。下の写真の緑の四角で囲んである部分を削り落します。こうしないとコネクタヘッダの下半分が干渉してしまうからです。



組み立てた後はこうなります。


このままだとコネクタカバーが閉まりませんのでこいつも加工します。左下から11.0mm×2.5mmだけ削り込んでやると…

下側の「ツメ」がぎりぎり0.5mmほど残ります。このおかげでパチンと小気味よくカバーが閉まります。このポストの最初の写真がカバーを閉めたところです。

2009年3月19日木曜日

TinyでDRO!(ハードウェア1)

このシステム全体は+5V電源で動作するようになっています。5V出力のACアダプターで直接給電です。それを前提に回路の説明です。

図の左端にはスケールからのクロックおよびデータの信号入力があります。スケールの電源は電位の高いほうがフレーム=GND電位で、低いほうが-1.5Vと通常とは逆の電位になっているので、C3およびC4による容量結合で4049(hex inverter, IC1)でレベルシフト、増幅しています。4049から出力された両信号は元の信号の反転になっています。これらはTiny2313のポート入力につながります。

左上のNチャンネルMOSFET uPA2753GR(Q7)はゼロクリアをスケールに対して送るためにあります。ポート出力でスケールのGNDとクロック線を(抵抗を介して)ショートさせます(スケール本体のZEROボタンを押したのとまったく等価と思われる)。

図の上半分はLEDドライブ回路です。Tiny2313の少ないポートでこれだけのLEDセグメントを駆動するためダイナミック点灯をさせることにします。数字が6桁すなわちデューティ1/6なので、見掛け上の明るさを稼ぐために1セグメントあたり20mAずつ流します。1コモン端子あたりの最大電流は、7セグメント+1DPで8素子ですから×8で、160mAです。ドライブ用トランジスタをポピュラーな2SA1015ではなく2SA950にしたのはこのためです。実は160mAというのはTiny2313の「全ポートのIOLの合計が60mAを超えるべきではない」という注意書きから外れています(前モデルの90S2313にすればこの条件が100mAと若干軽減されます)。本来ならばドライバトランジスタを挿入するべきでしょう。…が、とりあえず動いているのでまあいいかと。

LEDコモンのドライバトランジスタの選択に74HC138(3-to-8 decoder, IC3)を使用しています。Tiny2313のピン数が足りないための苦肉の策。リセット直後のポート出力が確定していない時期に、特にフラッシュ書き込みを行っている最中に変な表示が出ないように、リセットが利いている間は出力を禁止するようHC138のG1にリセット線を接続しています。

図の右下にダイオードを介してスイッチがつながっているのが見えます。LEDの(ダイナミック点灯のための)スキャンをキーのスキャンにも利用しているのです。これもやはりポートが足りないのが理由です。LEDはダイナミック点灯により約360Hz周期で切り替えますので約60Hzで1周します。キーのスキャンにはちょうど良いくらいの周期です。この方法ならばあと4つもスイッチを増やすことも可能です。なおダイオードと反対側のスイッチの端子は1つの入力ポートに集められます。この入力ポートはプルアップされてなければいけません。ダイオードの役割は2つのスイッチが同時にONになったときHC138の出力同士がショートしてしまうのを防ぐためにあります。逆流防止ダイオードとかいいますね。

Tiny2313にはセラロックが接続されているように書いてありますが、内蔵のRC発振回路で十分だということが分かりましたので、実際は接続しません。ただ、90S2313を使用する場合は必要です。RC発振回路が内蔵されていないからです。

回路の簡単な説明でした。次は基板を設計してOLIMEXに発注するのですが、先人が苦労されてきたとおりやはり最初は一筋縄ではいかずちょっと苦労しました。その話はまたいずれ。

基板が届くまでにずいぶんと時間がありますから、その間にソフトのコーディングとブレッドボードによるプロトタイピングです。これはそのときの様子です。ここまでちゃんと動くのに結構悩みました…。

2009年3月18日水曜日

TinyでDRO!(概要)

以前このブログでデジタルスケールをフライスに装着した話を載せました。その中で、「そのうちLEDの表示器作ろっと」と書いたとおり作ってしまいました。

まずは先例の調査から。ググるためにはまずキーワードが必要です。「デジタルスケール」ちゅう言葉は実は「デジタル式の秤」--つまりキッチンスケール--の意味のほうが(英語でも)一般的らしい。いろいろ探し回ったところ、こういうのは「DRO (Digital Read-Out) 」と言うのだということが分かりました。NCフライスなどを使ったことのある人にとっては当たり前のことかもしれませんが、知らなかったなぁ…。あと、まったく同じメカニズムを持つ「デジタルノギス」「Digital Caliper」なども検索キーワードとしては役に立ちました。

果たして信号の解説をしているサイト(ここここ)や製作例を掲げるいくつかのサイト(ここここ)が見つかりました。信号の解説をしているサイトによれば、また、自身で測定してみたところこのデジタルスケールの信号は以下の特徴があることが分かります。
  • クロック線と1本のデータ線を持つ同期式シリアルである。
  • 電源はGNDと-1.5V。GNDはフレームに落ちている。
  • データは24ビットの2の補数で、最下位ビット(LSB)から送られてくる。
  • 1回のデータ送信で2つのデータ--先に絶対座標、後に相対座標--がつながって送られる。
  • データの送信間隔は約0.3秒。
  • クロックの周波数は約80kHz。データ送信していない間は-1.5Vに固定されている。
  • データの取り込みはクロックの立下りエッジで行うのが妥当。
  • 外からクロック線をGNDレベルに落とすことでゼロクリア信号入力となる。つまりZEROボタンを押したのと同じ。
  • 外からデータ線をGNDレベルに落とすことでモード切換え入力となる。これ相当のボタンは本体にはない。
  • スケール本体の電源がOFFでも信号だけは出力され続ける(液晶画面は消えている)。
負電圧になっているのが嫌だなあと思いつつ、ここは挑戦です。以下の目標を掲げて突進です。
  • とにかく安い部品を使って仕上げる。そのためATTiny2313を使う。できれば部品箱に眠っているAT90S2313でも動くようにする。
  • 軸ごとの独立とする。つまり、X・Y・Z軸それぞれに1基板を使う。
  • ボタンはゼロクリアとミリ/インチ切り替えのみ。
  • 枚数の少ない試作基板では一番安価と思われるブルガリアのOLIMEXに基板を発注する。
  • 最近になって秋月で販売し始めたプラスチックケース(195×110×76mm)に収める。これは500円で非常に安価だ。
  • スケール本体から出すケーブルにはUSBケーブルのデバイス側をちょん切って使う。切ったところに2mmピッチ×4ピンのコネクタをつける。
  • スケール本体から出るケーブルとDROの接続はUSB(A-Type=ホスト側)を使う。安く上げるため。A-Typeメスのパネル取り付け用ケーブルが2本入りで280円(@千石)。
  • 基板以外は1軸あたり1,000円程度に抑える。
写真は完成して動作させているところです。上からX軸、Y軸、Z軸なのですが、Z軸にはスケールそのものがついていない(まだ買ってない…)ので消えたままになっています。次回はハードウェアの説明をします。

2009年2月2日月曜日

フライスにデジタルスケールがついた

プロクソンの小型フライスを使っています。プラケースにスライドスイッチ用の角穴を開ける時などに重宝しているのですが、X-Yテーブルの送りハンドルのバックラッシュ(遊び)に手を焼いていました。バックラッシュがあるのは当然のことだとは思うのですが、それを考慮に入れてもハンドルに刻んである目盛がなんか信用できない。ハンドルの目盛を頼りに四角くぐるっと一周しても元の位置に戻らないんです。
いらいらは募り、ついにデジタルスケールを装着することにしました。かなり高額なものなんだろうと思っていたら、探したら結構安いのがあったんです。

昨今はこの手のフライスを改造してコンピュータNC化するキットなども比較的安価(といっても20万円くらいはする)に買え、それを使えばNCデータを作成するだけで加工は機械任せにできます。しかし…そこまで一足飛びにやるべきか?とりあえず練習の意味を込めて手動でもきちんと図面通りに加工できるレベルに到達することが大切と考えました。

右の写真はX軸側、左下のはY軸側です。3×30mmのアルミ材に固定し、そのアルミ材をテーブルに固定しています。スライダー部の裏側には同じアルミ材やLアングル(今回は手元にあったアルミ製のブックエンドを切って利用)をねじ止めしています。困ったのはテーブルの壁面が垂直じゃないこと!微妙に下方向にすぼまってる。あと、ねじの頭が引っかからないように皿ネジにしたり、ハンドルのコラムが邪魔でタップ(ネジ切りの道具)のハンドルが回せないところにある穴はタップタイトねじを使ってねじ切りしたり…。まあいろいろと、現物合わせで苦労しましたが、なんとか形になりました。

このX-Yテーブルは左右に約140mm(=±70mm)、前後に110mm移動しますので、デジタルスケールはどちらも150mmまで計測可能なタイプにしました。ゼロ点合わせ、インチ/ミリ切り替えの機能がついて1本税込3,780円と安価でした。ちゃんとしたモノでしたよ。バックル付きの木箱に入って、合格検査証も入ってたし。でも…たぶん某国製なんでしょうね、取説の説明と現物が合わない…ボタンの数が違うし…。

あと、通常デジタルスケールにはリードアウト端子が出ていて外部表示装置をつなぐことができるようになっているのですが、今回購入したものは端子がありませんでした(涙)。取説上はあることになっているのに。諦めきれずに分解して中をのぞくと…ありました!それらしきものが。オシロで観測してみるときちんと信号が出ています。ラッキー!ケースの外には出てないけど、基板上にはあったのです。むふふ。そのうちLEDの表示器作ろっと。ケースに穴あけて。おっと、右の写真、ピンボケですな…。

ちなみにデジタルスケールの購入先はスリースカンパニーでした。きちんと使えるし、質感も悪くないし、値段考えると十分満足。他の特価商品としてデジタルノギス1,400円(!)などがありました。うぉっ、安すぎる…。

2008年9月26日金曜日

Tiny26Lで電圧計(4)

Sourceforgeにソースコードと回路図PDFを置いてみました。初めてなので、こんな方法でいいのかどうか不安ですが…。

Tiny26Lで電圧計(3)


電圧計のソースコードです。Cで書いてあります。下の「+expand source」というリンクをクリックすると表示されます。私はWinAVRを導入して、開発環境AVR Studioからビルドしています。

Tiny26Lへのプログラムの書き込みはAVRISPmkIIを使っています。ヒューズ設定をデフォルトのまま「内蔵RC発振=1MHz」として使えばOKです。特にいじる必要はありません。ただし、一度設定をいじったヒューズをデフォルトの状態に戻そうとした場合には注意が必要です。AVR Studio 4.13というバージョンではTiny26Lの構成ファイルにバグがあり、ヒューズの設定をプルダウンメニューから正しく選ぶことができないのです。その場合にはデータシートとにらめっこして、直接ヒューズの下位バイトに数値を入力してください。今回の場合はLow Byte=0xE1です。上のイメージはその時のウィンドウのスナップショットです。

電圧計 main.c

#define F_CPU 1000000L /* システムクロック=1 MHz(内蔵RC発振) */
#define COM_MAX 3 /* LEDのcommon端子の数 */
#define CALIB_REAL_MV 5080L /* リアル校正電圧[mV] */
#define CALIB_ADC_MV 2570L /* ADC校正電圧[mV](リアル校正電圧の約半分で入ってくる) */
#define LED_REFRESH_MS 15 /* LEDのリフレッシュレート[ms] */
#define LUMINOUS_PERSENT 30 /* LED輝度[%] */
#define ADC_REFRESH_MS 200 /* ADCの更新周期[ms] */
#define ADC_REFRESH (ADC_REFRESH_MS / LED_REFRESH_MS) /* ADCの更新周期[LEDリフレッシュ回数] */

#define COM_SWITCH_MS (LED_REFRESH_MS / COM_MAX) /* COM端子1本当たりの時間[ms] */
#define LED_ON_MS (COM_SWITCH_MS * LUMINOUS_PERSENT / 100) /* LEDがONしている時間[ms] */
#define LED_OFF_MS (COM_SWITCH_MS - LED_ON_MS) /* LEDがOFFしている時間[ms] */

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

//
// Globals
//
uint16_t CurVolt;
uint8_t SegRAM[3];
uint8_t CurCom = 0; /* Current COM Number 0, 1, 2, 0, 1, 2, ... */
uint8_t SegFont[10] PROGMEM = {
//_abcdefg
0b10000001, /* 0 */
0b11001111, /* 1 */
0b10010010, /* 2 */
0b10000110, /* 3 */
0b11001100, /* 4 */
0b10100100, /* 5 */
0b10100000, /* 6 */
0b10001101, /* 7 */
0b10000000, /* 8 */
0b10000100, /* 9 */
};

//
// Prototypes
//
void wdt_off(void);
void init_io(void);
void adc_cont_start(void);
void put_digit(void);
void print_volt(void);

//
// MAIN LOOP
//
int main(void)
{
wdt_off(); /* ウォッチドッグタイマーをOFF */
init_io(); /* I/Oの初期化 */
adc_cont_start(); /* ADCを連続変換モードでスタート */

uint8_t adcref = 0; /* ADCのリフレッシュカウンタ */

while(1) {
if (adcref == 0 && (ADCSR & _BV(ADIF))) {
ADCSR |= _BV(ADIF); /* ADCの読み込み */
CurVolt = ADCW; /* 現在電圧の更新 */
}
print_volt(); /* 電圧の表示 */

if (++CurCom >= COM_MAX) { /* 各カウンタの回転 */
CurCom = 0;
if (++adcref >= ADC_REFRESH)
adcref = 0;
}

_delay_ms(LED_ON_MS); /* 輝度調整:ONの時間 */
PORTB |= 0b00111000; /* 全消灯 */
_delay_ms(LED_OFF_MS); /* 輝度調整:OFFの時間 */
}

return 0;
}

//
// Functions
//
void wdt_off(void)
{
cli();
wdt_reset();
MCUSR &= ~(1 << WDRF);
WDTCR |= (1 << WDCE) | (1 << WDE);
WDTCR = 0x00;
//sei();
}

void init_io(void)
{
PORTA = 0xff;
DDRA = 0xff;

PORTB = 0b10111111;
DDRB = 0b00111000;

ADMUX = 0x29; /* REFS[1:0]/ADLAR/MUX[4:0] = 00101001 */
/* AVCCピン基準電圧、左揃え、シングルエンドCH9 */
ADCSR = 0x87; /* ADEN/ADSC/ADATE/ADIF/ADIE/ADPS[2:0] = 10000111 */
/* 完了割り込み禁止、クロック128分周 */
}

void adc_cont_start(void)
{
ADCSR |= _BV(ADSC) + _BV(ADFR);
}

void put_digit(void)
{
uint8_t pb, pa;

pb = PORTB | 0b00111000;
pb &= ~(0b00001000 << CurCom);
pa = SegRAM[CurCom];

PORTB = pb; /* COM端子のスイッチ */
PORTA = pa; /* フォントパターンの出力 */
}

void print_volt(void)
{
uint32_t r;
uint16_t p;

if (CurCom == 0) {
r = CurVolt;
//r = r * VCC_MV / 1000;
r = r * (CALIB_REAL_MV * CALIB_REAL_MV / CALIB_ADC_MV) / 1000L;
p = r >> 16;
if (p > 9)
p = 9;
SegRAM[0] = pgm_read_byte(&SegFont[p]) & 0b01111111; /* 最上位桁+小数点 */

r -= p * 65536L;
r *= 10;
p = r >> 16;
SegRAM[1] = pgm_read_byte(&SegFont[p]); /* 中位桁 */

r -= p * 65536L;
r *= 10;
p = r >> 16;
SegRAM[2] = pgm_read_byte(&SegFont[p]); /* 最下位桁 */

// r -= p * 65536L;
// r *= 10;
}

put_digit(); /* SegRAM[]の内容(フォントパターン)で表示 */
}

Tiny26Lで電圧計(2)



電圧計の回路図です。図中左下のオレンジ枠の部分はブレッドボード用の可変電圧電源であって、電圧計とは直接の関係はありません。ただ、この電源の出力の電圧を表示するという意図で載せてあります。

電圧測定入力はちょうど半分の電圧になるようにR10とR14で分圧してあり、これをTiny26L内蔵のAD変換器に入力しています。こうすることでTiny26Lの電源電圧を超える電圧も読むことができるようになります(フルスイングしても電源電圧どまりになってしまうので)。ただ、この入力抵抗でそこそこ電力消費をしますので、もう少し大きな抵抗値のほうがよかったかもしれません。47kΩずつくらいがちょうどいいかも。

LEDは3コモン×(7セグメント+DP)のダイナミックドライブを構成しています。部品点数が増えるので本当はLEDのコモンも直接AVRでドライブしたかったんですが、十分な輝度を出すためにはチップの定格を超えてしまうので涙をのんでPNPトランジスタでドライブしています。

さあ、次はソースコードの紹介です。

Tiny26Lで電圧計(1)


第一弾は、簡易電圧計を。

実験用のブレッドボードにお手製の可変電圧電源を組み込んで使っているのですが、出力電圧を調整するのにいちいちテスターで測っていました。これが面倒くさくなり、専用の電圧計を作ってしまいました。


ATTiny26Lを使って0.00V~9.99Vで0.01V刻みでLED表示します。実際には可変電圧源の可変範囲1.24V~5.09Vでしか試していません。

電圧計そのものへの電源は、写真では切れていますがお隣の可変電圧電源の一次側(DC7.5~12V)から引いてきています。これを三端子レギュレータで5Vに落として使っています。 LEDのコモン側のドライバーは手元にあったチップトランジスター2SA1202を使っていますが、裏面に実装してあるので写真には写っていません。

回路図とソースコードは次回以降にて。