google-site-verification: google3bd66dd162ef54c7.html
fc2ブログ

Arduino よもやま話-19(ピンチェンジ割り込みの回路とスケッチ)

◆まえがき
ESP32を使ったミニオシロ作りを少しずつやっているのですが、その作業の中でタクトスイッチを使った割り込みで、チャッタリングの影響が(ほとんど)出ない回路とソフトを作ることが出来ました。ということで、自分へのメモを兼ねて紹介します。なお、ボードは Arduino UNO と ESP32 を対象としています。

・UNOでタクトスイッチを読み込み
Arduino UNO で動作確認
よくある使い方ですが、ちゃんとやろうとすると奥が深いです。

◆チャッタリング現象
スイッチの検出で問題になるのが接点のチャッタリングです
チャッタリング波形
上の写真はタクトスイッチを操作した時に発生するチャッタリングの波形です。こんなにばたばたしていたのでは、プログラムに何度も割り込みが入ってしまって、おかしなことが起きます。

◆回路
スイッチの状態を検出する場合、抵抗でプルアップしてGNDに落とすやり方が定石です。しかし、今回はスイッチがONになった瞬間の検出だけ出来れば良いので、コンデンサでGNDに落とす方法でやってみました。回路図としては以下のようになります。

・Arduino UNO の回路図
UNOの場合
C1で入力ピンを瞬間的にGNDに落とす回路になっています。C1と並列に入っている抵抗(R1)はコンデンサの電荷を放電させるためのものです。これが無いと1回ボタンを押すとC1が充電されてしまって、2回目以降の検出が出来なくなります。
右側の図はCPUの内部まで表現した回路で、内部のプルアップ抵抗(Rp 20-50kΩ)で入力ピンは+5Vに引っ張り上げられています。なお、UNOではピン割り込みに使えるピンはD2とD3だけなので、この例ではD2を入力ピンに使っています。

・ESP32の場合
ESP32の場合
ESP32はピン割り込みに使えるピンは多いのですが、この図ではD26を使っています。なお、データーシートによるとESP32のプルアップ抵抗(Rp)は45kΩ(TYP) となっています。

◆チャッタリング対策の原理
ポイントとなるのはC1とR1の値で、今回はC1=0.1μF、R1=470kΩにしたのですが、その理由は以下の通りです。

・C1の値の決定
C1の値を変えて試してみると、330pFまで減らしてもピンチェンジ割り込みが正常に掛かりました。だったら少し余裕を見て1000pFにしようかと思ったのですが、それでは放電抵抗のR1の値が大きくなりすぎてしまいます。そんなことで0.1μFにしました。詳しくは次の項で説明しますが、R1の値は470kΩにしたので、放電の時定数(T2)は47msになります。

・動作波形
話はもう少し複雑なので波形で説明します。下の図の上側がポートの入力波形、下側はコンデンサ(C1)の電圧波形です。

波形(修正版)

①は待機状態でスイッチはOFFです。

②スイッチON
スイッチがONになると、ポートの電圧は瞬間的にGNレベルになります。この時、ソフトにピンチェンジ割り込み(FALLING)が発生します。

②スイッチONの後
RpとC1の時定数(T1 4.5ms)で決まるカーブで電圧が上昇して行きます。電圧の上昇つまりRAISINGなので、ピンチェンジ割り込みのFALLINGには引っかからないはずなのですが、実際には電圧上昇速度が遅いためにノイズの影響を受けてピンチェンジ割り込みが入ってしまう、つまり誤検出することがありました。

ATmega328Pのポートの入力はシュミットトリガなのでノイズには強いはずなのですが、これくらいゆっくりした電圧の変化に対してはあまり効果は無いようです。電圧上昇速度をうんと速くすれば誤検出しなくなるはずですが、後で説明するチャッタリング対策のためにはC1を小さくすることは出来ません。

③チャッタでスイッチOFF
ここからがスイッチを離す場合の挙動です。
スイッチを離す時にチャッタが発生し、瞬間的にスイッチがOFFになったとしても、ポートの入力電圧に変化はありません(厳密にはRpとR1で分圧されなくなるので僅かに電圧は上昇)。しかし、コンデンサ(C1)の電圧は時定数T2で放電して行きます。このまま接点OFFが続けば何も起こらずに済むのですが、、

④再度ON
チャッタリングなので再度接点がONになってしまうことがあります。こうなると、ポートの入力電圧は一旦その時点のコンデンサの電圧(Vx)まで下がった後で再度時定数T1で上昇することになります。
この時、もしVxが入力のロジックのLowレベル電圧より下がっていれば、ピンチェンジ割り込みが発生してしまって誤動作になります。

・対策
②で電圧が上昇する時の誤動作は、正規の割り込みの直後に発生するので、これはソフトで対策することにしました。説明は省略しましたが、②のスイッチONの時にもチャッタリングが発生しますがこれも同じソフトで対策(無視)可能です。

④のタイミングで発生する誤動作は、T2の時定数を大きくすることで回路的に対策することにしました。具体的には、T2の時間を長くすることで、チャッタの発生時間程度ではVxの電圧があまり下がらないようにしました。ちなみに、チャッタの時間が5ms程度なのに対して、T2は47msとしています。

◆プログラム
チャッタ対策効果の確認プログラムを以下に示します。
// ピンチェンジ割り込みのチャッタ対策効果確認(ESP32, Arduino UNO)
// SwPinに接続したボタンスイッチの操作でLEDとシリアルに出力
// 2020/09/27 ラジオペンチ

//#define SwPin 26 // swPin (ESP32)
//#define LedPin 2 // ESP32 DevKit 搭載LED
#define SwPin 2 // swPin (Arduino UNO int0)
#define LedPin 13 // Arduino UNO 搭載LED

volatile boolean swPushed = false; // swPushed flag
volatile boolean irq = false; // 割込み有りフラグ
volatile unsigned long tXXX = 0; // ボタン操作時刻

void setup() {
Serial.begin(115200);
pinMode(LedPin, OUTPUT);
pinMode(SwPin, INPUT_PULLUP); // 操作ボタン(Hold)
// attachInterrupt(SwPin, irq_Sw, FALLING); // ピンチェンジ割り込み(ESP32)
attachInterrupt(0, irq_Sw, FALLING); // ピンチェンジ割り込み(Arduino UNO)
}

void loop() {
while (irq == false) { // ボタン操作待ち(ボタン押し待ち)
}
irq = false; // 割込みフラグクリア
Serial.println(tXXX); // 時刻(millisの値)を出力
digitalWrite(LedPin, swPushed); // 動作確認LEDを点灯
}

void irq_Sw() {
static unsigned long tLast = 0; // 最後のボタン操作時刻(millsの値)
unsigned long tNow;
tNow = millis(); // 現在時刻を記録
if (digitalRead(SwPin) == LOW) { // 本当にLOWになっていて、←念のため
if ((tNow - tLast) > 50) { // 前回の操作から50ms以上たっていたら、
irq = true; // 割込み(ボタン押し)フラグON
swPushed = ! swPushed; // 状態フラグをトグル
tLast = tNow; // 次回の判定用に時刻を保存
tXXX = tLast; // 動作確認用に時刻をコピー
}
}
}
このプログラムはArduino UNO で動く状態になっていますが、コメントアウトを変更すればESP32でも動きます。(5, 6, 18行のコメントアウトを解除し、7, 8, 19行をコメントアウト)

プログラムの動作としては、スイッチを押すたびにボード上のLEDがトグルで点滅させ、同時にスイッチが押された時刻(millsの値)をシリアルに表示します。

割込み処理ルーチンの irq_Sw() の中でチャッタ対策を行っています。
34行目はノイズで割り込みが入った場合の処置で、FALLING割り込みなので本当にLOWレベルになっているか確認しています。(この行は無いよりマシ程度の効果かも知れません)
35行目で最後に有効と見なした割り込みからの経過時間をチェックしていて、50ms以内の割込みだったらチャッタリングと見なして無視するようにしています。
割込みの都度 irq を true にしてメインルーチン側で表示などの処理を行っています。これ以外にも動作確認用にいろいろな変数を使っていますが、これらは動作確認用なので削除可能です。

テストの様子(ESP32)
ESP32で動作確認
横に実験に使ったセラコンが転がっています。記事では簡単に出来たように書いていますが、実際にはいろいろな値を試しています。なお、このブレッドボードは標準品を加工して作った「ガニ股ブレッドボード」です。

◆まとめ
対策のための追加部品は抵抗とコンデンサが各1個必要になりました。実はプログラムはもっと複雑になっても構わないから外付け部品を出来るだけ少なくしたかったのですが、これくらいが限界でしょう。

冒頭に書きましたが、この記事はボタンが押されたことの検出を目的としています。つまり、ボタンが押され続けている、あるいは、ボタンが離された場合の検出は別の話になります。ただ、マイコンの操作はスイッチをちょんちょんと押して設定していくような使い方が多いので、この記事の対策だけで使える場合が多いと思います。

あと、タイマー割り込みでスイッチの状態を周期的にチェックする方法を使えばこの記事に書いたようなことは考えないでも良くなります。でも、今取り組んでいるオシロスコープでタイマー割り込みを使うと、波形キャプチャーの周期が乱れる恐れがあります。これは測定器としては致命的な問題になりかねません。

ということで、ピンチェンジ割り込みで処理したいと考えています。そのあたりの話は以前の記事の中にちょっと出て来ます。なお、Arduino の環境で動かしている限り、millis()などの関数のためにタイマー割り込みが使われるのは仕方ないものとあきらめています。もしこれが問題になる場合はシステム割り込みを止めて対策することが必要になると思います。

Arduino よもやま話-18(未使用ピンをまとめて設定する関数を作った)

◆未使用ピン
Arduinoでは未使用ピンは何もしないで放置しておくのが普通ですが、そうやると少し問題があることが判りました。特に気になるのが電源の消費電流の増加で、何も対策しないと約3mAも消費電流が増えてしまいます。そのあたりの話はよもやま話に書いてきましたが、重要と思われる記事へのリンクを以下に貼っていきます。
Arduino よもやま話-15 (未使用ピンの電圧変化の観察)
Arduino よもやま話-16 (未使用ピンの電圧と電源の消費電流の関係)

◆プログラムからの対策
この問題の対策は、未使用ピンを入力プルアップや出力LOWの状態に設定して電圧を確定してしまえば良く、居酒屋ガレージ日記さんのArduino やっぱり気になる放置ポートという記事で詳しく解説されています。
ここまでやれば完璧ですが、これまで pinMode( )なんちゃらとやって 1ピンずつ設定してきたので、いきなりこの書き方、つまりポート制御レジスタを直接いじる方式に変えるのは大変です。

◆未定義ピンを設定するプログラム
未定義のピンだけ空き端子処理することが出来れば良いので、そこに特化した関数を作ってみました。
// Arduino の空き端子処理関数 20200530uuPinSetup.ino
// uuPinOutputLow, uuPinOutputHigh, uupinInputPullup, uuPinInput
// 2020/05/30:割り込み対策追加 (居酒屋ガレージ日記さんご指摘)*1
// ラジオペンチ

void setup() {
// Serial.begin(115200);
// pinMode(13, OUTPUT);
uuPinOutputLow(0b01111111111100, 0b111111); // 未使用ピンをLOW出力に設定
// uuPinOutputHigh(0b01111111111100, 0b111111); // 未使用ピンをHIGH出力に設定
// uuPinInputPullup(0b01111111111100, 0b111111); // 未使用ピンを入力プルアップに設定
// uuPinInput(0b01111111111100, 0b111111); // 未使用ピンを入力に設定(デフォルトに戻す)
}

void loop() {
}

void uuPinOutputLow(unsigned int d, unsigned int a) { // 指定ピンを出力/LOWに設定(un used Pin set to Output Low)
// ビットパターンで該当ピンを指定(1で有効)。d:D13-D0, a:A5-A0
// PORTx=0, DDRx=1
unsigned int x;
uint8_t oldSREG = SREG; // ステータスレジスタ保存(割込状態保存)*1
cli(); // 割込み禁止*1
x = d & 0x00FF ; PORTD &= ~x; DDRD |= x; // D0-7
x = (d >> 8) & 0x3F; PORTB &= ~x; DDRB |= x; // D8-13
x = a & 0x003F ; PORTC &= ~x; DDRC |= x; // A0-5
SREG = oldSREG; // ステータスレジスタ復元(割込状態復元)*1
}

void uuPinOutputHigh(unsigned int d, unsigned int a) { // 未使用ピンを出力/HIGHに設定(un used Pin set to Output High)
// ビットパターンで該当ピンを指定(1で有効)。d:D13-D0, a:A5-A0
// PORTx=1, DDRx=1
unsigned int x;
uint8_t oldSREG = SREG; // ステータスレジスタ保存(割込状態保存)*1
cli(); // 割込み禁止*1
x = d & 0x00FF ; PORTD |= x; DDRD |= x; // D0-7
x = (d >> 8) & 0x3F; PORTB |= x; DDRB |= x; // D8-13
x = a & 0x003F ; PORTC |= x; DDRC |= x; // A0-5
SREG = oldSREG; // ステータスレジスタ復元(割込状態復元)*1
}

void uuPinInputPullup(unsigned int d, unsigned int a) { // 未使用ピンを入力/PULLUPに設定(un used Pin set to Input Pullup)
// ビットパターンで該当ピンを指定(1で有効)。d:D13-D0, a:A5-A0
// PORTx=1, DDRx=0
unsigned int x;
uint8_t oldSREG = SREG; // ステータスレジスタ保存(割込状態保存)*1
cli(); // 割込み禁止*1
x = d & 0x00FF ; PORTD |= x; DDRD &= ~x; // D0-7
x = (d >> 8) & 0x3F; PORTB |= x; DDRB &= ~x; // D8-13
x = a & 0x003F ; PORTC |= x; DDRC &= ~x; // A0-5
SREG = oldSREG; // ステータスレジスタ復元(割込状態復元)*1
}
void uuPinInput(unsigned int d, unsigned int a) { // 未使用ピンを入力(Hi-Z)に設定(un used Pin set to Input)
// ビットパターンで該当ピンを指定(1で有効)。d:D13-D0, a:A5-A0
// PORTx=0, DDRx=0
unsigned int x;
uint8_t oldSREG = SREG; // ステータスレジスタ保存(割込状態保存)*1
cli(); // 割込み禁止*1
x = d & 0x00FF ; PORTD &= ~x; DDRD &= ~x; // D0-7
x = (d >> 8) & 0x3F; PORTB &= ~x; DDRB &= ~x; // D8-13
x = a & 0x003F ; PORTC &= ~x; DDRC &= ~x; // A0-5
SREG = oldSREG; // ステータスレジスタ復元(割込状態復元)*1
}

居酒屋ガレージ日記さんから、「IOピンのレジスタ操作中は割り込みを禁止した方が良い」とのアドバイスを頂いたので修正しました。
なお旧版はこちら → 0528版(割り込み対策無し版)

つまり、空きピンの処理用に下記の関数を作った訳です。
・出力でLOW     uuPinOutputLow(d, a);
・出力でHIGH     uuPinOutputHigh(d, a);
・入力でプルアップ  uupinInputPullup(d, a);
・入力         uuPinInput(d, a);

空き端子を行いたいピンを引数のビットで指定する方式で、引数の d が D0~D13、引数の a が A0~A5に対応しています。 1 が指定されていればそのポートの空き端子処理を行い、0 だったら、元の設定のままで何もしないという動作を行います。

pinModeの設定が終わったあたりで未使用ピンに対してこの関数を使って空き端子処理を行えばよいと思います。あるいは最初にこの関数で全ピンの空き端子処理を行い、後でpinModeで変更するという手順でもいけると思います。どちらの場合でもグリッジが出る可能性があります。

どの空き端子処理を選択するかは好みに合わせて使えば良いと思いますが、私は居酒屋ガレージ日記さんの作法にならって、LOWを出力、つまり uuPinOutputLow を使っていこうかと思います。なお、入力 (uuPinInput) は無くても良いのですが、コードの対称性が悪くなるので作っておきました。設定を途中でにデフォルトに戻したい場合などで、あると便利かも知れません。

なお、必要なコードだけソースに書けば良く、使っていないコードは削除しても大丈夫です。(書いてあっても使っていなければコンパイラの段階で無かったことになるので悪影響はありません。)

◆効果
上記のプログラムを動かしたときのCPUの消費電流は約11mAでした。一方で、未使用ピンの処理無し、つまり uuPinOutputLow() をコメントアウトした状態の消費電流は 14mA、つまり消費電流を 3mA減らす効果が確認出来ました。
他の関数を使っても消費電流の低減効果は同じでした(デフォルト状態と同じuuPinInput() は除く)

◆電流波形
以上の確認はDMMによる測定と共に、オシロで電流波形も見たものです。オシロの波形で面白い結果が出ているので以下に示します。なお、この波形はCPUの電源ピンに入れた1Ωのシャント抵抗の電圧波形、つまり1mVは1mAに相当しています。

空き端子処理無しの状態
CPU電源電流波形の測定
約14mA流れています。

空き端子処理(OutputLow)ありの場合
出力LOWに設定
消費電流が10.5mAまで下がっています。

再び空き端子処理無しの状態
ACラインノイズの影響
I/Oコネクタに指を近付けると電源電流がACライン波形で変調されました。
空きピンがACラインの影響を受けて電位が変化し、そのために消費電流が変化しているのだと思います。空き端子処理をしていない場合の消費電流の値がフラフラするのが気になっていたのですが、どうもこういう現象が起きていて値が安定しなかったようです。

◆プログラム書き込み電流と同時観察
せっかくなのでCPUのフラッシュメモリーに書き込む様子と合わせて電流波形を観察してみました。

・空き端子処理無しの場合
プログラム書き込み、デフォルト
25mAくらいのスパイク電流がフラッシュに書き込みを行っているタイミングだと思います。その電流が6mAくらいまで減った後で、ユーザープログラムに制御が移り、消費電流14mAの状態で動き始めるのだと思います。小さな周期的な波は、AC電源からの誘導があるためだと思います。

・空き端子処理あり(OUTPUT LOW)
プログラム書き込み、OUTPUT LOW
こちらはユーザープログラムが動き出した後は消費電流が約11mAに減っています。これは前記した話と同じですが、さらにユーザープログラムが起動した後の波形は平坦になっています。これは空き端子処理を行ったためにノイズの影響を受け難くなった効果が表れているのだと思います。

◆まとめ
好みの問題はあるでしょうが、空き端子処理が必要な場合は、今回の記事の関数を使っていきたいと思います。何か問題があったらその時に修正したいと思います。

マイコンはデジタル処理の典型的なデバイスですが、そこにAC電源からの誘導、つまりハムが乗るとは油断が出来ないです。

Arduino NANO にはA6,A7ピンがありますが、この2つのピンにはデジタル入出力機能が無いので初期化は不要なはずです。

Arduino よもやま話-17 (アナログポートの未使用ピンの処置)

◆DIDR0 レジスタ
このところ Arduino の未使用ピンの処置方法についていろいろ調べています。ほぼ結論が出たと思っていたら、居酒屋ガレージ店主(JH3DBO)さんからコメントを頂き、アナログポートについては DIDR0 レジスタの設定でうまく処置出来るという情報を頂きました。そんな機能があるとは知らなかったので、さっそく試してみました。

◆測定の回路図
アナログ入力ピンに電圧印加
アナログポート (A0-5) を全部パラに接続し、テスト用の電圧を加えてその時のCPUの電源ピンの電流を測定しました。(CPUの電源はこの回路図には出てきません)
残りの信号ピンは、これまでの調査では何も接続せずオープンにしていたのですが、それでは電源電流が無駄に増えてしまって、良くないことが判りました。そこで、今回の調査ではプログラムで出力にアサインして LOW を出力しておきました。つまり、真面目に空き端子処理をやっておきました。

◆テスト用のプログラム
// 20200505 アナログ入力ピンのデジタル回路切り離し機能の効果測定プログラム
// DIDR0 レジスタを設定した場合の効果比較プログラム
void setup() {
// Serial.begin(115200);
pinSetup(); // D2-7, D8-13 を空きピン処理(全部LOW出力)A0-5は入力(何もしていない)
DIDR0 = 0b00111111; // digitalRead部切り離し(通常状態にするときはコメントアウト)
}

void loop() {
// Serial.println(PINC,BIN); // A0-5の状態確認
// delay(200);
}

void pinSetup() { // 空き端子処理
// 居酒屋ガレージ日記さんの書き方を真似した
// PORTBは全ピンLOW出力
PORTB = 0b00000000; // data/pull up
DDRB = 0b00111111; // I/O (0:in 1:out)
// |||||+---- PB0 IO8 out
// ||||+----- PB1 IO9 out
// |||+------ PB2 IO10 out
// ||+------- PB3 IO11 out
// |+-------- PB4 IO12 out
// +--------- PB5 IO13 out
// PORTDはTX,RD以外は全部LOW出力
// PORTCはデフォルトのまま(全部input)
PORTD = PORTD &= 0b00000011; // data/pull up (下位2ビット以外はLOW)
DDRD = 0b11111110; // I/O (0:in 1:out)
// |||||||+---- PD0 IO0 in RXD
// ||||||+----- PD1 IO1 out TXD
// |||||+------ PD2 IO2 out
// ||||+------- PD3 IO3 out
// |||+-------- PD4 IO4 out
// ||+--------- PD5 IO5 out
// |+---------- PD6 IO6 out
// +----------- PD7 IO7 out
}

◆測定結果
DIDR0レジスタの効果(入力電圧vs電源電流)
横軸がアナログポート(A0-5) に加えた電圧で、縦軸が CPU の電源ピンの電流です。

青色のプロットが DIDR0 レジスタに何も設定しない状態、つまり前の記事と同じ状態を再測定したものです。この場合 1/2Vcc を中心に消費電流が増えます。なお、今回の測定では残りのピンは全部LOW出力に設定して空きピン処理を行っているので、電流の値は前の記事より 1.5mAくらい少なくなっています。

オレンジ色のプロットが DIDR0 レジスタを設定 (0b00111111) した場合で、こちらは、入力ピンの電圧が変わっても電源電流には全く影響が出ていません。DIDR0 レジスタの目的は、アナログ入力ピンに、デジタル入力のシュミットトリガ回路の影響が出て、電圧/電流特性に非線形な影響が出ることを防ぐことで、そのためにアナログスイッチを使ってデジタル回路への接続を絶つと共に、デジタル入力を LOW レベルにクランプしています。

このような操作を行ったことによる別の効果として、電源電流が無駄に増加するという現象が解消出来る、ということになろうかと思います。ただ細かい話をすると、入力電圧がゼロの場合の電源電流を比較すると、DIDR0レジスタを使うより、LOW にクランプしておいた方が、電源の消費電流は約1mA 少なくなっています。

そんなことで、省電流化を狙う場合は出力 LOW で空き端子処理を行った方が良いのかも知れません。ただアナログ電圧の測定を行うピンではそんなことは出来ないので、やはり DIDR0 レジスタを設定するしか対策方法は無いでしょう。なお、Arduino で analogRead(An) とやる場合はおそらくそういう状態を作っているのだと思います。

◆データーシート
今回 DIDR0 レジスタの効果についてコメントで教えて頂きましたが、こういうことはデーターシートに書いてあるはずなので原文を確認してみました。("DIDR0" でPDFを文字列検索すると関係した部分を手早く発見出来ます)
datasheet of ATmega328P

すると、
ATmega328Pのデーターシート、9.10.6項

ATmega328Pのデーターシート、23.9.5項
確かにいろいろ書いてありました。

ここの説明は、アナログ入力ピンにパラに入っているデジタル入力回路の影響についての言及であって、デジタル入力ピンについては何も触れられていません。デジタル入力ピンの場合は切り離したりする機能は無いので、ここに書いてある影響がそのまま出るということだと思います。

◆まとめ
Arduino の空きピン処理も詳しく見るといろいろ難しいものです。ブレッドボードで一時的に組んで動作を試すような場合、空きピン処理などは気にしないで楽しんでしまえば良いと思います。この場合、CPUの消費電流が数mA増えているかも知れません。

一方で電池で長期間動かすような場合は、消費電力は重要なのできちっと空き端子処理を行った方が良いでしょう。あと、仕事で使うような場合は誘導ノイズなどで誤動作しては困るので、きっちりと空き端子処理を行っておく必要があります。

ところで、今回の記事では pinSetup() という関数を作って、ここでまとめて空き端子処理を行いました。しかし、この関数の中身を書くのがちょっと面倒です。例えば空き端子処理をしておきたい端子名を引数に列挙して呼び出せば、空き端子処理 (例えば出力で LOW) をやってくれるライブラリ、あるいは関数を作れば便利かも知れません。まあ逆に判りづらくなって変な問題のタネを蒔くだけになりかねないのですが。
カレンダー
05 | 2023/06 | 07
- - - - 1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30 -
プロフィール

ラジオペンチ

Author:ラジオペンチ
電子工作を中心としたブログです。たまに近所(東京都稲城市)の話題など。60過ぎて視力や器用さの衰えを感じつつ日々挑戦!
コメントを入れる時にメールアドレスの記入は不要です。なお、非公開コメントは受け付けていません。
記事の内容のご利用は読者の自己責任でお願いします。

記事が気に入ったらクリックを!
最新記事
カテゴリ
最新コメント
リンク
FC2カウンター
検索フォーム
月別アーカイブ
RSSリンクの表示
QRコード
QRコード