« 2020年12月 | トップページ | 2021年2月 »

2021年1月

2021年1月30日 (土)

8bit乱数関数 random8()

2021年1月28日:Arduinoの乱数関数「random」に違和感
に関係して、
2021年1月22日:出窓に「跳ねるLED」 では
Adafruit_NeoPixel-master」のライブラリを用いましたが、
LEDテープの制御、もう一つの有名どころが
FastLED-master」です。

これを使ったサンプルやライブラリのソースを見ていると
こんな乱数関数を見つけました。

普通のrand()は16bitの正の値(0~32767)を返しますが、
桁数8bitでエエやん用に作られてます。
「C++」ですんで、引数で処理を区分。
こんな結果になります。

   random8()    == random from 0..255
   random8( n)   == random from 0..(N-1)
   random8( n, m) == random from N..(M-1)

ここでも最大値は「N-1」あるいは「M-1」に。

random8()だと「0~255」が出てくるのに、
random8(255)とすると得られるのが「0~254」と
いう値になってしまいます。

そして、この場合「(255 + 1)」とは記せません。
入力引数も8bitですんで256はアウト。
random8(n)で最大値255は永遠に出てきません。
random8(0, 255)
でも255は出せません。
random8() では255が出るのに・・・。


random8(n)とrandom8(n, m)のソース、こんな処理です。

uint8_t random8(uint8_t lim)
{
  uint8_t r = random8();
  r = (r*lim) >> 8;
  return r;
}

uint8_t random8(uint8_t min, uint8_t lim)
{
  uint8_t delta = lim - min;
  uint8_t r = random8(delta) + min;
  return r;
}


「剰余」を使わず、「(random8() * lim)」で符号無しの
16bit値を得て、それを1/256 (8回右シフトというか上位桁
だけ使う)して符号無し8bitの乱数を得ています。

「剰余を使った乱数」と「1/256での処理」、違いはいかが
でしょうか。
統計に強い人に確かめていただきたい。

 

| | コメント (1)

2021年1月29日 (金)

オフカメラシューコード改造

発端はこのトラブル。
2019年10月22日:やってしまった FL-600Rの根元が破損

カメラの頭に取り付けていたフラッシュ、私のカラダで押されて
その根元がポキリ。 ・・・修理費1万円。

カメラ頭のアクセサリーシューに取り付けるのではなく、
L形ブラケットを使ってカメラの横に設置かなぁ~っと
考えていました。

そうなると、今風なら電波で撮影指令。
あるいはスレーブモードで。

でも確実なのはフラッシュの延長コード。
オリンパスには「オフフラッシュケーブル FL-CB05」というのが
あったのですが、現在は廃番に。
そこで、Made in CHINAの
  PHOLSY
  Flash TTL off-canera cord
  for Olympus / Panasonic
というのを購入。

こんな箱でやってきました。
21_20210129113901
箱から出すと・・・
22_20210129113901
カールコードがトグロを巻いています。
縮んだ状態で0.6mほど。
引っ張ると・・・長~い(1.5mは行きます)

カメラの隣に併設するのでここまでの長さは不要です。
ということで、カールコードの短縮プロジェクトです。
まず代替のコードを見つけなければなりません。
電線は全部で5本。
まず条件がアダプタ部のケーブルブッシュに入ること。
付いているカールコードの外形が4.9mm。
交換するケーブル、スカスカのもイヤです。
ノギスを持ちながら「太いなぁ」「芯数が足らんなぁ」などと
何か良いのがないかと仕事場に置いてあるケーブルを物色。

で、「これ行けそう」と見つけたのが「USBケーブル」。
USBの信号と電源で4芯。それにシールドで5芯。
外形4.5mmでした。
  ※元のカールコード、ケーブルブッシュから抜くのが
   大変なほどギチギチでしたんで、ちょうど良い感じ。

この手のしっかりしたシールド線、外皮編線の材質がSUSで
ハンダ付けできません。
この編線に紛れて、ハンダ付けできるスズメッキ線が入ってま
すんでそれをGNDにします。

27_20210129113901
  ※この手の小物のハンダ付けで役立つのが
   文鎮:ハンダ付け補助ツール

アダプタ側の解体はこんな具合。
カメラのシュー側。
23_20210129113901
深い穴に刺さった鉄ネジは磁石をくっつけたドライバー
で引き出します。
ドライバーの磁化が弱くてもOK。

全体にしっかりと作られてます。
24_20210129113901
電線は全部で5本。
そのうちのGND線(カメラシュー外装に接触)がシールド。
29_20210129113901
まずビスを1本外したらネジロックしてあったので、
残り3本は抜かずに作業。

基板を樹脂外装に残したままハンダしたんで気を使います。
51_20210129134601
実体顕微鏡でハンダ付けの出来具合をチェック。
30_20210129113901
ロック部分があるので、平面に置けません。
テープに貼り付けて動かないように。

フラッシュ側は、こんなふうに接点をバネで導通させ
てあります。
25_20210129113901
26_20210129113901
配線完了↓  抜け止めに結束バンド+瞬着。
28_20210129113901

 

新しいケーブルの全長30cmちょいに仕上げました。

31_20210129115401
カメラに付けるとこんな感じです。
32_20210129115401

33_20210129115401


試運転前に導通チェック 。 (端子間の導通と不要な接触の確認)

重さを量ってみると、
・新しくなったアダプタ・コード    75g
・エツミのL字形ブラケット      145g
  (カメラ止めネジを大型のものに交換して)
・カールコードを切った残り     150g
  (これは重い!)

※参考
エツミ:ストロボ プロテクターL型

| | コメント (2)

2021年1月28日 (木)

Arduinoの乱数関数「random」に違和感

Arduino、あれこれ便利なんですが昔人間には
ちょいと違和感のある関数に遭遇しました。
  それが「random」。
乱数が32bitのlong値で得られます。
出てくるのは「0~0x7FFFFFFF」。

ある値までの乱数が欲しければ「剰余」を使って
計算します。
  b = random() % a;
これで「0 ~ (a-1)」の数値が得られます。
つまり数字の数が「a種類」。

Arduinoは「C++」なんで「random」はこんな書き方もOK。
  ※昔人間(Cだぜぃ)にはここらが難しい。

基本が
 (1) random(void)

そしてパラメータが1つ。
 (2) random(long howbig)

さらに2つも。
 (3) random(long howsmall, long howbig)
 
(1)は16bit値のrand()と同じなんで、自分で剰余を求めて
処理すればヨシ。

そして、(2)で出てくる結果が「0 ~ (howbig-1)」。
(1)で剰余を求めた時と同じ結果になるわけです。

しかし、出てくる最大値、「howbig - 1」を勘違いしない
かが気になるのです。
自分で剰余を求めれば「-1」の違いを勘違いすることは
まぁありません。
しかし、便利そうな関数です。
「-1」を気にせず「0 ~ howbig」が出てくるようにしてあ
るんじゃ?  ・・と、思いませんか?

  random(100);
としたら「0から100まで」の乱数が出てくるんじゃ・・・。

もう一つ勘違いしそうなのが(3)の書式。
これで出てくる値の範囲が「howsmall ~ (howbig - 1)」。
最大値が関数に記した値の「-1」になります。

  random(10, 100);
としたら、「10~100」の値が出るようにしてあるんじゃ
ないかと期待・・・。
ところが「10~99」が出てきます。

この最大数値が「-1」になること、(2)や(3)の書式では
要注意ということでちょいとメモ。

  ※これ、私は勘違いしちゃいます。
     random(10, 100+1); 
   と書いておくかな。

| | コメント (1)

2021年1月27日 (水)

カラーLEDテープ(WS2812B)の制御信号

カラーLEDテープの制御、こんな具合に1段目から2段目、
そして3段、4段へと信号が伝わってきます。

C13_20210127110201

C14_20210127110201

自分に対する制御信号は出力せず、次段へはその次の信号を伝える
ということで、数珠つなぎになったLEDが制御されます。

その様子をオシロでちょっと見ました。
買ったLEDテープ、表面はこんな具合に透明樹脂(プニプニしてる)で
保護されています。
C10

先の尖ったピンセットをグニっと差し込んで信号ラインに接触させました。
オシロのプローブにクリップでつないでいます。
C11_20210127110201
  ※ピンセット、指先が触っていますが
   インピーダンスが低いので観察信号に
   「ハム」は乗っていません。

こんな波形。
F000

2段目への信号、パルス幅が規制されているようで
入力したものよりちょっと短くなっています。

これが正規の「Hレベルのパルス幅」ということなのでしょう。
F002



| | コメント (0)

2021年1月22日 (金)

出窓に「跳ねるLED」

出窓:居酒屋ガレージ日記(旧ブログ)「跳ねるLED」 登場です。
 (昨夜、試運転。写真は今朝)
21_20210122140001

全体はこんな状態。 まだ正月モード。
22_20210122140001

・参考スケッチ
GitHub - KenKenMkIISR/Bouncing-LED: NeoPixel互換のLEDテープを利用したLEDが跳ねるアニメーション
これを使わせていただき、改造しました。

・落ちてくるLEDブロックの長さと重力加速度を乱数化。
   LEDの長さ:1~10で乱数 (元は6)
   重力加速度:4~30で乱数 (元は20)

・跳ね返りが大きい方が面白いかと、計数を大きく。
   GRAVITYや跳ね返り係数を変えると、停止判断をミス
   していつまでも止まらずにピョコピョコする場合
   があります。
   そこで乱数で決まったGRAVITY値の「√:sqrt()」か
   ら停止速度を算定。(早く止まっても面白くないので)

・GRAVITYと停止判定速度、跳ね返った時の速度をシリアル出力。

・外部信号で明暗と落下開始を制御。
   夜は暗くする。
   人が来た時に落下を始める。
   ふだんはLEDを消している。

・1mで144LEDの品を買ったが、出窓、チビな子供達だと
 地面の方から見上げるかっこうになるんで、先端の14LEDを
 カットして130LEDに。
 根元をちょい上に。
    こんな角度:保育園児のお散歩コース

・落ちる方向を逆に。 先端からスタートして根元に向かって
 落ちる。
   根元(下側)に回路を置いてケーブルをつなぐので。

・コの字形アルミチャンネルに貼り付け、突っ張り棒に固定。
 突っ張り棒は「電動上下駆動」で使っているもの。
 モータの駆動音(減速機の音)がうるさいからと、最近は
 停止状態。

こんな回路。

20_20210122140001

Arduino-UNOから抜いたATmega328Pで制御しています。

・スケッチ  ダウンロード - led_tape1.txt
  (ファイルタイプを「.ino」にして使ってください)

※2021-01-25変更
最終的にはこんな具合。(古いの消しちゃいます)
・落ちるブロックごとにGRAVITY値を乱数で設定。
 ブロックごとに速度が変わるということで。

・ブロックのLED数、乱数で決めるのを1~20と多めに。
 これが小さいと「流れ」が起きるまで時間が掛かっちゃう
 ので。


※突っ張り棒下端の様子。

41_20210123120401

結束バンドでLEDテープを貼り付けたアルミチャンネルを
突っ張り棒に固定。
赤・黒の2線が+5V電源供給。
赤・緑・白の3線が制御基板へ。

制御基板はこんな様子。
42_20210123120401

出窓の外からは見えないんで、箱には入れてません。

| | コメント (0)

2021年1月21日 (木)

カラーLEDテープを手に入れた

出窓 の新アトラクションに
GitHub - KenKenMkIISR/Bouncing-LED: NeoPixel互換のLEDテープを利用したLEDが跳ねるアニメーション
はいかがかと(モータ駆動系のはうるさいんで)、カラーLEDテープを
手に入れてみました。

11_20210121101001
うまいこと光るもんですなぁ。

「シリアルLEDスティック」光らせてみた! ? スイッチサイエンス マガジン
   ※7年くらい前に遡れるようです。

制御ICの制御方法がなるほどです。
WS2812B の制御タイミングを見ますと、短パルスと長パルスで
データの0と1を表現。
RGBそれぞれ8ビットのデータをドバ~っとの連続送出。
そのタイミング、データシートにはけっこうキビシイ値が記されていますが、実際は・・・
といいますのが、この記事
NeoPixel(WS2812B)の制御: 猫にコ・ン・バ・ン・ワ (WS2812B)の制御をライブラリ無しで行ってみました。
NeoPixel(WS2812B)の制御 その2 SPIで

Adafruit_NeoPixelライブラリーを使わず、自前で出力ポートを直叩き。
そして、SPIでもってハード的にパルス列を出そうという試み。

自前で制御すれば、Arduinoから離れられます。
28ピンのATmega328Pを使わないでもっと小さいマイコンで制御できるわけ
です。
  ※表示用バッファにRAMが必要ですが、1メートル60LEDの
   ものだと、1LEDに3バイトで240バイトのバッファ。
   ATtiny85だと512バイトでなんとかなりそう。

ということで、制御波形を見てみました。

まず、これがAdafruit_NeoPixelライブラリーでの制御波形。
L002

これもI/O直叩きですが、Hパルス、Lパルスのパルス幅が仕様通りに
出ている感じです。

これが「猫にコ・ン・バ・ン・ワ」さんのI/O直叩き。
L001

Lレベル部分がずいぶん長くなっていますが、これでもちゃんと制御
されています。

そしてSPIでの制御。
SCKパルスといっしょに見ています。
L000

これもずいぶんLレベル部分が長い。

WS2812Bの制御、Hレベル部分の長短が重要でLレベル部が少々延びても
問題ないのかな?

昔のデータシートと新しいデータシートで値が変わっています。

W1
パルス列のデューティーで判断してるんじゃ「TH」のパルス幅で
0/1を見ているのかな?
T0L、T1Lとももっと長くしてもOKなようです。

※ATmega328pのSPIについて
SPIを使っての転送タイミングを見ていて・・・
 「送信後の待ちってこんなにかかるの?」
っと、疑問に思ったんでちょっとテストプログラムを
書いてみました。

まず、関連するI/Oポート

    PORTB = 0b00010011;     // data/pull up
DDRB = 0b00101100; // port in/out指定
// |||||+---- PB0 IO8 in -
// ||||+----- PB1 IO9 in -
// |||+------ PB2 IO10 out /SS (L)
// ||+------- PB3 IO11 out MOSI →★LED接続
// |+-------- PB4 IO12 in MISO (pull up)
// +--------- PB5 IO13 out SCK

そしてSPI回りのイニシャル。

    SPCR  = 0b01010100;
// ||||||++---- SPR fosc/2
// |||||+------ CPHA sck位相 SCH↑で出力確定
// ||||+------- CPOL sck極性 mode1
// |||+-------- MSTR 主装置で
// ||+--------- DODR MSBから出力
// |+---------- SPE SPI許可
// +----------- SPIE 割り込みなしで
SPSR = 0b00000001;
// || +---- SPI2X fosc/2で
// |+---------- WCOL
// +----------- SPIF SPI完了割り込みはなし

LEDデータバッファの転送ルーチン

void ledshow(void)
{
word i;
byte j;
byte d;
cli(); // 割り込み禁止
for(i = 0; i < (LED_N * 3); i++){ // LEDの数*G,R,B
d = led_bff[i];
for(j = 0; j < 8; j++){ // 8bit loop
if(d & 0x80) SPDR = LED_1; // H
else SPDR = LED_0; // L
d <<= 1; // MSBから出力
PD7_H; // (!!!)
while(!(SPSR & (1 << SPIF))); // SPI送信完了待ち
PD7_L; // (!!!)
}
}
sei(); // 割込許可
}

送信完了待ちのタイミング、D7ポートをH/Lして待ち時間を
見られるようにしています

その結果。
L004

SPI完了の待ち時間だけでなく8回loopの処理時間も
大きいようです。 (しかし、どうしようもない)
クロックパルスが8MHzですんで。
これが限界かな。
  ※D7ポートへのテストパルス、これのH/Lだけで
   2クロック+2クロック、0.25usかかっています。

「猫にコ・ン・バ・ン・ワ」さんのSPIでの描画ルーチンは
こんな具合。

void NeoUpdate() {
// ピクセル数x24ビット送信
for (uint8_t i = 0; i < PIXCELNUM*3; i++) {
for (uint8_t j = 0; j < 8; j++) {
SPDR = buf[i] & (0x80>>j) ? NEOSPI_1:NEOSPI_0; // SPIデータ送信
while(!(SPSR & (1 << SPIF))) ; // 送信完了待ち
}
}
}

8回ループ内にバッファメモリの読み出しと0x80のシフト操作が
入っています。
毎回これが実行されるので遅くなっているのでしょう。

自由にタイミングを作れる出力ポート直叩きのほうが
よさそうです。

| | コメント (0)

2021年1月18日 (月)

アナデバの電力計用IC、arduinoで周波数(周期)を計る#2

2021年1月15日:アナデバの電力計用IC、arduinoで周波数(周期)を計る

で、周波数を求めるためにArduinoのICP1入力でパルスの周期を
計る方法を提示しました。

電力計の計算はまだこれからですが、測定した周波数を
シリアル出力するところまでをまとめてみました。

こんな具合に出力します。

●起動 (1kHz入力)
PWR-mon test. (input OCR1A)
1000.00Hz cnt:  16000 max-min:1
1000.00Hz cnt:  16000 max-min:1
1000.00Hz cnt:  16000 max-min:1

●ICP1(D0)入力とOC1A(D1)出力(122Hz)をつなぐ
  ※OC1B(D2)がオーバーフロータイミング
   比較するとovfとcapとの差がわかる
 122.07Hz cnt: 131072 max-min:0
 122.07Hz cnt: 131072 max-min:0
60     ← クロック差をキー入力
OCR1A = 60 ← オーバーフロータイミングとずらす
 122.07Hz cnt: 131072 max-min:60
 122.07Hz cnt: 131072 max-min:0
 122.07Hz cnt: 131072 max-min:0

●最低周波数付近
  0.50Hz cnt:32000654 max-min:0
  0.50Hz cnt:32000655 max-min:0
  0.33Hz cnt:48000983 max-min:0
  0.33Hz cnt:48000983 max-min:0
No pulse.  ← 4秒間パルス無しでメッセージ出力
  0.33Hz cnt:48000982 max-min:0
No pulse.
  0.25Hz cnt:64033614 max-min:0
  0.25Hz cnt:64001310 max-min:0
No pulse.

●周波数を上げる
 500.00Hz cnt:  32000 max-min:1
 500.00Hz cnt:  32000 max-min:1
 :
10000.00Hz cnt:  1600 max-min:1
10000.00Hz cnt:  1600 max-min:1
 :
20000.00Hz cnt:   800 max-min:1
20000.00Hz cnt:   800 max-min:1
 :
50000.00Hz cnt:   320 max-min:2
 :
52631.58Hz cnt:   304 max-min:2
 :
55555.55Hz cnt:   288 max-min:2
  ↑
このあたりが安定して測定可能な最高周波数
これ以上になると不安定。
シリアル出力割り込みが起動できなくなって、
データ出力ができなくなってしまう。

1秒周期でICP1で読み取ったパルス数を平均化して
周波数を算出しています。
「max-min」値は1秒間でのパルス周期の偏差。

OC1AとOC1Bにタイマー1の1/2の周波数を出しています。
OC1Aの値をキー入力(0~65535)で設定できるように
していますのでOC1Bとの位相差(OC1Bは0固定)パルス
が得られます。

OC1AをICP1に入力すれば、パルス数が65536の2倍で
「131072」、周波数122.07Hzという結果が得られます。
3つのポートに割り込み処理時間パルスを出しているので、
オシロでタイミングをチェックできます。
  ・D7 ICP1割り込み処理時間
  ・D11 ICP1内でのオーバーフロー処理
  ・D13 OVF1割り込み処理


とりあえずこんな制御プログラム。
ICP1入力にパルスを入れてみてください。

/****************************************/
/* 有効電力測定のためのパルス周期測定実験 */
/* "pwmmon1.ino" */
/****************************************/
// D8 PB0 16bitタイマーICP1 計測パルス入力
// D9 PB1 OC1A 122.07Hz方形波出力 0~65536入力でコンペア位置可変
// D10 PB2 OC1B 122.07Hz方形波出力 コンペア位置は0固定(ovfのタイミング)
// D11 PB3 ICP1内でのOVF1チェック
// D13 PB5 OVF1割り込みチェック
// D7 PD7 ICP1割り込みチェック
/***** I/O制御マクロ *****/
#define PB3_H (PORTB |= (1 << PB3)) // PB3 D11
#define PB3_L (PORTB &= ~(1 << PB3))
#define PB5_H (PORTB |= (1 << PB5)) // PB5 D13
#define PB5_L (PORTB &= ~(1 << PB5))
#define PD7_H (PORTD |= (1 << PD7)) // PD7 D7 H/L
#define PD7_L (PORTD &= ~(1 << PD7))
word chk_1ms = 1000; // 1秒チェックカウント
volatile word cnt_1ms; // 1ms カウント値
volatile byte f_timeup; // 1秒経過
// ICP1キャプチャー用データ
volatile long pls_cyc; // 1周期のパルスカウント値
// 16MHzクロックの総数
// ICP1で確定
volatile word cap_old; // 前回のキャプチャ値 ICR1を保存
// OVF1発生で0クリア
volatile word ovf_cnt; // オーバーフローカウント値
// OVF1処理回数
volatile long pls_add; // OVF発生した時のパルス加算結果
// OVF1割り込みで処理
// 計測指令と結果
volatile byte plsck_on; // 計測開始指令
volatile byte plsck_ok; // 計測完了
volatile word plsck_cnt; // 計測回数
volatile long plsck_add; // パルスカウント平均用加算値データ
volatile long plsck_max; // パルスカウントmax
volatile long plsck_min; // パルスカウントmin
// パルス値のmax,min,add,cnt途中データ
volatile word plsp_cnt; // 計測回数
volatile long plsp_add; // パルスカウント平均用加算値データ
volatile long plsp_max; // パルスカウントmax
volatile long plsp_min; // パルスカウントmin
// 出力チェック
byte f_nopls; // パルス無し出力フラグ
byte f_plsck2; // 2回目以降のパルス入力チェック

/****************************/
/* 割り込み */
/****************************/
#define OVF_CMAX 977 // オーバーフロー回数のmax(4sec)
// 4*(16MHz÷65536)
#define CAP_OVL 0x7FFF // cap,ovl重複チェッククロック数
// 割り込み処理時間の最大値を設定すればよいが
// 8000~FFFFならcapが早いと判断できる。
/***** タイマー1インプットキャプチャー割込 *****/
// ICP1の↓エッジでキャプチャー
ISR(TIMER1_CAPT_vect)
{
word d;
PD7_H; // (!!!) 13pin
d = ICR1; // キャプチャデータ 0~65535
if((d <= CAP_OVL) && // capとovfが重なったかも
(TIFR1 & (1 << TOV1))){ // オーバーフロー未処理あり
PB3_H; // (!!!) 17pin
if(ovf_cnt < OVF_CMAX){ // オーバーフローは最大4sec
ovf_cnt++; // 回数+1
pls_add += 65536L - (long)cap_old; // 前cap値からの差を加算
}
cap_old = 0; // キャプチャ値 次回用
TIFR1 |= (1 << TOV1); // オーバーフロー未処理を消す
PB3_L; // (!!!) 17pin
}
// パルスカウント
if(ovf_cnt == 0){ // オーバーフローがなかった
pls_cyc = (long)(d - cap_old); // 前回値との差がパルス数
cap_old = d; // キャプチャ値 次回用
}
else{ // オーバーフローがあった
pls_cyc = pls_add + (long)d; // パルス加算結果に現cap値を加算
cap_old = d; // キャプチャ値 次回用
ovf_cnt = 0; // オーバーフロー回数ゼロに
}
pls_add = 0; // 加算値を0に
// パルスカウントmin,max,addチェック
if(plsck_on){ // チェック開始指令
plsck_on = 0;
plsck_add = plsp_add; // 現在値を保存
plsck_max = plsp_max;
plsck_min = plsp_min;
plsck_cnt = plsp_cnt;
plsp_max = plsp_min = plsp_add = pls_cyc; // 新値
plsp_cnt = 1; // カウンタ1から
plsck_ok = 1; // 値確定
}
else{
plsp_add += pls_cyc; // add
plsp_cnt++; // 回数+1
if(pls_cyc > plsp_max) plsp_max = pls_cyc; // max
if(pls_cyc < plsp_min) plsp_min = pls_cyc; // min
}
PD7_L; // (!!!) 13pin
}
/***** タイマー1オーバーフロー割込 *****/
// pls_addにパルス数を残す
ISR(TIMER1_OVF_vect)
{
PB5_H; // (!!!) 19pin
if(ovf_cnt < OVF_CMAX){ // オーバーフローは最大4sec
ovf_cnt++; // オーバーフロー回数+1
pls_add += 65536L - (long)cap_old; // 前cap値からの差を加算
}
cap_old = 0; // キャプチャ値 次回用
PB5_L; // (!!!) 19pin
}
/***** タイマー2コンペアマッチA割込み *****/
// 1kHz周期
ISR(TIMER2_COMPA_vect)
{
cnt_1ms++;
if(cnt_1ms >= chk_1ms){ // 1秒経過
cnt_1ms = 0;
f_timeup = 1;
}
}

/**************************/
/* シリアル入出力 */
/**************************/
/***** シリアル1行入力 *****/
#define RXBF_SIZ 16 // 文字バッファ文字数
char rx_bff[RXBF_SIZ+1]; // 受信文字バッファ (+null)
byte f_rxok; // 受信データありフラグ
byte f_prompt; // プロンプト出力済みフラグ
/***** シリアル1行受信 *****/
// CRでターミネート f_rxokを1に
// BSで1文字戻す
void rxbff(void)
{
static byte cnt = 0; // 受信文字数
char c;
if(Serial.available()){ // 受信データあり
if(f_rxok == 0){ // 前データ受信処理した
c = Serial.read(); // 1文字読み出し
if(c == '\r'){ // CR?
rx_bff[cnt] = '\0'; // nullを最後に
Serial.println(); // 改行
f_rxok = 1; // 受信成功
cnt = 0; // 最初から
}
else if(c == '\x08'){ // BS?
if(cnt > 0){
cnt--; // 1文字戻す
Serial.print("\b \b"); // BS,space,BS
}
}
else{ // 文字
if((cnt < RXBF_SIZ) && // バッファサイズ内
(isprint(c))){ // 表示可能文字0x20~0x7E
Serial.write(c); // エコーバック
rx_bff[cnt] = c; // バッファに入れる
cnt++; // 1文字進める
}
}
}
}
}
/***** 書式付シリアル出力 *****/
void txprintf(const char *s, ...)
{
va_list vp;
char bff[80]; // バッファを確保
va_start(vp,s);
vsnprintf(bff, sizeof bff, s, vp);
Serial.print(bff);
va_end(vp);
}
/***** メッセージ出力 *****/
void txputsP(PGM_P s)
{
char c;
while(1){
c = pgm_read_byte(s);
if(c == '\x0') break;
Serial.write(c);
s++;
}
}

/*****************************/
/* セットアップ */
/*****************************/
/***** SETUP *****/
void setup()
{
cli(); // 割り込み禁止
// I/Oイニシャル
PORTB = 0b00000001; // data/pull up
DDRB = 0b00111110; // port in/out指定
// |||||+---- PB0 IO8 in ICP1キャプチャー パルス入力
// ||||+----- PB1 IO9 out OC1A 122Hz方形波出力
// |||+------ PB2 IO10 out OC1B 122Hz方形波出力
// ||+------- PB3 IO11 out ICP1内オーバーフロー処理タイミングチェック
// |+-------- PB4 IO12 out LCD E
// +--------- PB5 IO13 out OVF1割り込みタイミングチェック
PORTC = 0b00000000; // data/pull up
PORTC = 0b00000000; // data/pull up
DDRC = 0b00111111; // portin/out指定
// |||||+---- PC0 AD0 out LCD DB4
// ||||+----- PC1 AD1 out LCD DB5
// |||+------ PC2 AD2 out LCD DB6
// ||+------- PC3 AD3 out LCD DB7
// |+-------- PC4 AD4 out LCD RS
// +--------- PC5 AD5 out LCD R/W
PORTD = 0b00011111; // data/pull up
DDRD = 0b11100010; // portin/out指定
// |||||||+---- PD0 IO0 in RXD シリアルデータ入力
// ||||||+----- PD1 IO1 out TXD シリアルデータ出力
// |||||+------ PD2 IO2 in SW1
// ||||+------- PD3 IO3 in SW2
// |||+-------- PD4 IO4 in SW3
// ||+--------- PD5 IO5 out -
// |+---------- PD6 IO6 out -
// +----------- PD7 IO7 out ICP1割り込みタイミングチェック
// タイマー1,インプットキャプチャ
TCCR1A = 0b01010000;
// |||| ++--- WGM 標準動作
// ||++------- COM1B ポート トグル出力
// ++--------- COM1A ポート トグル出力
TCCR1B = 0b00000001;
// || ||+++--- CS 16MHz入力
// || ++------ WGM
// |+--------- ICES1 ICP1入力↓エッジ
// |---------- ICNC1 ノイズキャンセルなし
OCR1A = 0; // コンペアマッチでトグル出力(数値入力で変化)
OCR1B = 0; // コンペアマッチでトグル出力
TIMSK1 = 0b00100001; // 割り込み設定
// | ||+--- TOIE1 オーバーフロー割込on
// | |+---- OCIE1A
// | +----- OCIE1B
// +-------- ICIE1 キャプチャー割込on
// タイマー2,CTCモード 1msで割り込み
TCCR2A = 0b00000010;
// |||| ++--- WGM1,0 CTC
// ||++------- OC2B ポート
// ++--------- OC2A ポート
TCCR2B = 0b00000101;
// |+++--- CS 2,1,0 16MHz/128 125kHz
// +------ WGM2
OCR2A = 125 - 1; // 1kHz
TIMSK2 = 0b00000010; // 割り込み
// ||+--- TOIE2
// |+---- OCIE2A 割込on
// +----- OCIE2B
sei(); // 割込許可
// シリアル
Serial.begin(9600); // 9600BPSで
}

/******************************/
/* ループ */
/******************************/
/***** LOOP *****/
void loop()
{
word c_cnt;
long c_add, c_max, c_min;
long g1;
float f1;
char s1[16]; // float出力用
Serial.println(F("PWR-mon test. (input OCR1A)"));
while(1){
rxbff(); // 1行受信処理
if(f_rxok){ // CRでターミネート
f_rxok = 0;
g1 = atol(rx_bff); // 入力データをlongに
OCR1A = (word)g1; // OC1Aにセット 122Hz出力の位相
txprintf("OCR1A = %u\r\n", OCR1A);
}
if(f_timeup){ // 1秒経過
plsck_on = 1; // チェック開始
f_timeup = 0;
}
// ICP1パルス入力あり
if(plsck_ok){ // パルス入力あって計数完了した
plsck_ok = 0;
f_nopls = 0; // パルス無しフラグをクリア
if(f_plsck2){ // 2回目以降のパルス
cli(); // 割り込み禁止
c_cnt = plsck_cnt; // ICP1計測数カウンタ
c_add = plsck_add; // トータル数
c_max = plsck_max; // max
c_min = plsck_min; // min
sei(); // 割込許可
g1 = c_add / c_cnt; // 平均値
f1 = 16000000.0 / (float)g1; // 周波数に
dtostrf(f1, 8, 2, s1); // xxxx.xx
txprintf("%sHz cnt:%8ld max-min:%ld\r\n",
s1, g1, (c_max - c_min));
}
else{
f_plsck2= 1; // パルスあり,2発目以降に表示
}
}
// ICP1パルスが来ない
cli(); // 割り込み禁止
c_cnt = ovf_cnt; // オーバーフローカウンタmax4秒
sei(); // 割込許可
if(c_cnt >= OVF_CMAX){ // 4秒超えた
if(f_nopls == 0){ // パルス無し出力した?
f_nopls = 1;
Serial.println(F("No pulse."));
}
}
}
}

/*===== end of "pwrmon1.ino" =====*/

 

| | コメント (0)

2021年1月15日 (金)

アナデバの電力計用IC、arduinoで周波数(周期)を計る

2020年8月26日:アナデバの電力計用IC
2021年1月 8日:アナデバの電力計用IC、試運転

このIC、有効電力が出力パルスの周波数から計算できます。
まずは周波数(周期)を計らなければなりません。

2019年12月20日:Arduino UNOで周波数カウンタ
では、どちらかというと高い周波数の計測。
一定時間内に入ってきたパルスの数を数えますんで、
周波数カウンタの原理そのものです。

ところが、電力計では「低い周波数」を計る算段が必要に
なります。
ゲート時間を1秒にして計れる周波数の最小桁は1Hz。
電力値の変動を見るにはちょい不足です。

となると、周波数を計るのではなく、パルス間隔、
つまり「周期」を測定して、それを逆算して周波数を
得るという手法になります。

Arduinoでは16bitのタイマー1が使えます。
タイマーを標準動作にして、フリーランしているTCNT1を
ICP1入力のエッジでインプットキャプチャ。
パルス間隔が16bit単位で得られます。
16MHzクロックだと16bitで測れる最低が244Hz。(4.096ms)
それ以上の長いパルスはTCNT1のオーバーフローをチェック
します。

 ※デューティー比計測で往生しました。
  ・2020年8月24日:Arduino PWM波形のデューティー比測定 これで完成形か?

カウンタのオーバーフローをまたがないパルスの時は
このようにキャプチャ値C2とC1:前回値の差がその周期
になります。

C11_20210115100301

そして、その途中でオーバーフローが発生して、
TCNT1の値が0を通過した場合はこのように。

C12_20210115100301
オーバーフロー割り込みでP1のパルス数を一時保管
しておき、キャプチャ割り込みでP2の値を加算します。

さらに長い周期だと、このようにカウント値65536を
積み重ねます。

C13_20210115100301

1秒周期のパルスだと、TCNT1へ供給するクロック周波数
の数がカウント値になります。
   クロックが16MHzだと「16,000,000」と10進で8桁、
   16進にすると「0xF42400」。
これを逆算して周波数を得ます。

ところが、ここで問題。
インプットキャプチャもオーバーフローも割り込みで
処理するわけですが、この二つが重なった時を考えて
おかなくてはいけません。
  ※ATmega328Pではインプットキャプチャ割り込み
   が優先されます。

【2】の「オーバーフローをはさむとき」を見てください。
オーバーフローのポイント(F1)とインプットキャプチャの
ポイント(C2)が離れていれば問題ありません。
(C2)がどんどん(F1)に近づいてきて、同じタイミングに
なった時、インプットキャプチャの割り込み処理が優先
されてしまうのです。

(C2)で行う処理は、
  「オーバーフローの処理(F1)を済ませている」
として「P2」のパルス数を加算します。
ところが割り込みが同時だと(F1)が遅れてしまい、
カウントをミスります。

キャプチャの処理が早くなっても正常なカウント値が
得られるようにしなくちゃなりません。

そこで、キャプチャ割り込みの中で、
「まだ処理されてないオーバーフロー割り込みはあるか」を
「割り込み要求フラグ:TOV1」を見て判断します。
このTOV1がオンしてたら割り込みが保留中と判断するわけです。
  ※オーバーフロー割り込みが処理されると
   TOV1はクリアされます。

ところがまだ問題が。
【1】でのキャプチャタイミング(C2)がどんどん右へ来て
(F1)に近づくと・・・
キャプチャ割り込み処理が始まった直後にTOV1が
オンしてしまうかもしれません。
ここで「TOV1がある」と処理してしまうとミスします。
この誤判断を取り除かなくてはなりません。

これは、キャプチャ値を見ればわかります。
(C2)の値が「FFFF」だとオーバーフローはまだ
発生しません。
これがギリギリのタイミング。

つまりキャプチャされた(C2)の値を見れば、(F1)との
近さがわかるわけです。
「FFFF」のように大きな値なら【1】の状態で、
オーバーフロー前。
まだ競合は生じないのでTOV1のチェックは不要。

キャプチャ値が「ゼロに近い」値なら【2】の状態です。
未処理のオーバーフローがあるかどうかをチェックし
なければなりません。

さて、この(C2)の値をどのくらいにすれば良いか・・・
キャプチャー割り込みが始まってからのTOV1発生
タイミングを考えなければなりません。
ということは・・・
遅れの要因、キャプチャー処理の時間だけでなく、
他の割り込みの処理時間も関わってきます。
Arduinoの場合、タイマー0割り込みがバックグランドで
動いてますし、シリアル送受も割り込みが使われています。
これらと競合しても大丈夫な値にしておかなくてはなりません。

処理的にはこんな具合。
  (まだ最大カウント値規制など入れ込んでない)

/*****  タイマー1インプットキャプチャー割込  *****/
// ICP1の↓エッジでキャプチャー
ISR(TIMER1_CAPT_vect)
{
word d;
PD7_H; // (!!!) 13pin
d = ICR1; // キャプチャデータ 0~65535
if((d <= CAP_OVL) && // capとovfが重なったかも ★1
(TIFR1 & (1 << TOV1))){ // オーバーフロー未処理あり
PB3_H; // (!!!) 17pin
ovf_cnt++; // 回数+1
pls_add += 65536L - (long)cap_old; // 前cap値からの差を加算
cap_old = 0; // 次回用キャプチャ値をゼロに
TIFR1 |= (1 << TOV1); // オーバーフロー未処理を消す
PB3_L; // (!!!) 17pin
}
// パルスカウント
if(ovf_cnt == 0){ // オーバーフローがなかった
pls_cyc = (long)(d - cap_old); // 前回値との差がパルス数
cap_old = d; // キャプチャ値 次回用
}
else{ // オーバーフローがあった
pls_cyc = pls_add + (long)d; // パルス加算結果に現cap値を加算
cap_old = d; // キャプチャ値 次回用
ovf_cnt = 0; // オーバーフロー回数ゼロに
}
pls_add = 0; // 加算値を0に
PD7_L; // (!!!) 13pin
}
/***** タイマー1オーバーフロー割込 *****/
// pls_addにパルス数を残す
ISR(TIMER1_OVF_vect)
{
PB5_H; // (!!!) 19pin
ovf_cnt++; // オーバーフロー回数+1
pls_add += 65536L - (long)cap_old; // 前cap値からの差を加算
cap_old = 0; // 次回用キャプチャ値をゼロに
PB5_L; // (!!!) 19pin
}

ICP1パルスごとに、新たな周期データ(16MHzクロック数として)
「pls_cyc」が現れます。

★1の「CAP_OVL」の値をどうしたものかと。
16や32ではダメ。 (処理時間で言えば1uS~2uS)
他の割り込み処理が入るとミスします。
まぁ、大きくしておいても通常はオーバーフロー割り込み
が正しく動いてくれます。
想定される割り込み処理時間より大きな値をということ
でしょう。

そのあたりをオシロでみたのがこれ。
ch3がオーバーフロー割り込みのタイミングで、
ch2のインプットキャプチャ割り込みより前に処理され
ています。 これだと大丈夫。

C000

【2】のキャプチャータイミングがオーバーフローに近づくと、
オーバーフロー割り込みは処理しないで、キャプチャー割り込みの
中でオーバーフローの処理を行います。
C001
オーバーフロー割り込みは実行されません。

二つのタイミングが重なると、どっちがどうなるかは
運次第。  ※他の割り込みも入りますし。
C002

このように競合して、オーバーフローの処理が遅れた時を
キャプチャー割り込み内の処置でカバーしています。


安定した電力計算のためには、パルスカウント値の平均を算出するなど、
まだもうちょい手を入れなければなりません。

※参考
迷走の果て・Tiny Objects Arduinoでレシプロカル式周波数カウンタの実験
Arduino 周波数/周期カウンタ (1) - シンセ・アンプラグド
  続き:(OVF1とICP1割り込みの競合)
AVRマイコンによる 周波数カウンターの製作


※あれこれ読んで考えてみると・・・
ICP1処理時のTOV1フラグチェック、キャプチャレジスタの値がどれだけ
なら(ある値以下)capとovfが重複したかという判断、0~FFFFの中央値
でokのようです。

つまり、MSBが1(0x8000~0xFFFF)ならovfする前なのでTOV1の
チェックは不要。
cap処理のあと自動的にovf割り込み処理が行われるので放置でok。

MSBが0(0~0x7FFF)なら重複の可能性があるのでTOV1をチェック
してTOV1があればovf処理を行ってからTOV1を消しておく。
TOV1が無ければovfと重複してないのでcapの処理だけでok。

割り込み処理での遅れを考えて「いくらか以下なら?」という
判断はおおまかでok。ということで大丈夫です。

※割り込みで扱われる2バイト以上のデータはアトミック処理を!
割り込みで数を数えるプログラム、これをしてないのが目立ちます。

| | コメント (1)

2021年1月13日 (水)

アナデバの電力計用IC、16ピンの製品

2020年8月26日:アナデバの電力計用IC
2021年1月 8日:アナデバの電力計用IC、試運転
に絡んで・・・
アナデバの電力計用ICの紹介  の ICリスト
の中から16ピンのICをピックアップしますと、
ADE7757AADE7768ADE7769の3つが出てきます。

この中のADE7757AはAD71056Aと同じもの(らしい)。
  ※試運転で使ったのはAD71056
   Aあり、Aなしもよくわからない。
この残りの2つもほんとに似たようなスペックなんです。

ブロック図を見ても同じ。
11_20210113104001
12_20210113104001
13_20210113104001
14_20210113104001

何が違うねん? PDFを見比べても違いがよくわかりません。
  ※出力パルス周波数のところで違いがあるか・・・

★digikeyで調べるとADE7768とADE7769は生産中止っと。
 ADE7757とAD71056は両方出てきます。
 ただ・・・在庫数が少ない。

これらの石、ソフト的な設定が不要。
電源投入で、測定電力に比例した周波数のパルスが出てきます。
周波数(周期)を計れば有効電力の値がわかります。
周波数から電力値を計算するためのキャリブレーションは必要ですが、
ICへの設定は必要ありません。
高機能な石は、力率や電流電圧のRMS値などが読めますが、
ややこしい初期設定が必要です。

その点、この石はシンプル。
得られるのは有効電力だけ。
電気料金は有効電力に課金されますんで。


digikeyで、「ENERGY METERING」「SINGLE PHASE」
で検索して在庫数量でソートすると、こんなICが
出てきます。

ATM90E26   28pin
CS5463    24pin
MCP3906   24pin
STPM10BTR  20pin
ADE7753   20pin
ADE7755   24pin
CS5464    28pin
CS5467    28pin
 :

| | コメント (0)

2021年1月12日 (火)

かんたんケータイKYF38の「スピーカー付き卓上ホルダ」にイヤホンジャックを

女房の親父さん、現在、介護老人保健施設に入所しています。
 ※昨年夏、体調不良で東大阪市内の病院に入院。
  ところがその病院でコロナのクラスターが
  発生してしまい、退院、転院もできずで、見舞いにも
  行けずの状態に。
  年末、やっとこさ生野区内の施設に移動できたという
  次第。
やっと面会もできるようになったという時、コロナの感染拡大で
この施設でも面会禁止に。
 ※一時帰宅も×。

困ったことに、親父さん、耳が悪い。(補聴器必須)
携帯電話だと話ができない。
 ※親父さんの声はこっちに聞こえるが、こっちの
  言葉が親父さんに伝わらない。
 ※対面では会話できる。(こちら、ゆっくりと大きな声で)
  携帯電話や加入電話受話器から出る音が判別できないと。
  テレビの視聴でも音量が必要。
 ※携帯電話でのメール送受は不可。
  ちいさなボタンでの文字入力操作ができない。
看護の職員さんを通して伝えてもらうということになって
しまい、ややこしい話ができないという状態だったのです。
  ※一方的な伝言「あれとこれを持ってきて欲しい!」という
   ことは伝えられるんですが、こちらから「いつがエエ?」
   とか「あれはどうする?」っと質問しても、
   「なに言うてるかわからへんわ」状態で話が進みません。

面会できない状態・・・
  なんとかして親父さんと携帯電話で会話できないか・・・
この連休にあれこれと試してみました。

やったこと。
・携帯電話を新しく。
 これまでの3G携帯から4G携帯に。
 選んだのは京セラの「かんたんケータイKYF38」。
 義母もこれを使っている。
・AUショップのお兄さんとあれこれ相談して、
 ブルートゥースイヤホン、あるいはヘッドホンを使えば?
 という話に。
 音も大きいし、これで行けるのではと期待・・・
・ところが・・・90歳を越える親父さんにこまかい操作をしても
 らうのは不可能・・・。
 ペアリング設定のやり直し(何かの拍子におかしくなった時)とか、
 ヘッドホンの小さなスイッチを押してとか、充電のための小さな
 USBコネクタの抜き差しとかが難題・・・。
・手取り足取り教えられる状態じゃない(面会できない)ので
 「こりゃ、無理」と判断。

そこで・・・
新しい携帯は「スピーカー付き卓上ホルダ」で充電します。
これには大きな音が出るスピーカーが付いている。
このスピーカーの代わりにイヤホン(ワイヤー接続で)を
つないだらという目論見。

Sp11

卓上ホルダをバラすと、こんな構成。
S1  
USBのデジタル信号で音を出しています。
充電用電源でこの回路を動かしているんで、携帯電話は
充電状態になってます。
このスピーカー出力を切り替えてイヤホンをつなぎます。

S2
卓上ホルダの背面に(マイクロUSBのコネクタが挿さる)、
イヤホンジャックと切り替えスイッチの穴を開けて取り付け。
基板のスピーカーコネクタ、電線を途中で切って延長し、
スイッチとイヤホンジャックに配線。

この改造したセットを施設に持っていき、卓上ホルダにイヤホンを
つないで親父さんとの会話に成功。
ステレオイヤホンを渡したんで、片側を親父さん、もう片方を
職員さん(女性)が耳に付けて、あれこれお話しができました。
「よう聞こえるで~」っとうれしそう。


※ブルートゥースイヤホンと合わせて、携帯電話を「補聴器モード」に
 できれば便利そうなんですが・・・

 

| | コメント (1)

2021年1月 8日 (金)

アナデバの電力計用IC、試運転

2020年8月26日:アナデバの電力計用IC で紹介しました石を
手に入れましたんで、回路をでっち上げてみました。

使ったデバイスは「AD71056」。
AC100Vで最大50W程度を測れるように、定数を選んでみました。
こんな回路です。

Pwr_mtr1a

  ※AN-679で紹介されているのはADE7757ですが、
   データシートを読むと同じもののようです。
   digikeyの在庫を見ると、両ICとも数が少ないです。
   ということは主力品じゃない?

ノイズ対策、サージ対策部品は付けてません。

51_20210108160501

デバイスのGNDがAC100Vの片側につながります。
出力パルスの周波数で「電力が読める」という測定原理です。
測定系(周波数カウンタ)とはフォトカプラで絶縁という
のがミソ。(一つですむ)

電流検出抵抗と入力電圧分圧回路で、全体の感度(測定電力値に
対する出力周波数))が決まります。
何らかの方法でキャリブレーションが必要です。

負荷にする抵抗、とりあえず100Vの白熱電球を使いました。
直列にしたり並列にしたりして、電流を見ながら周波数を
メモします。

暖房のためエアコンを動かしているんで、100Vラインの電圧、
けっこう動きます。 (±0.5Vは変動)
波形も汚いし。
そのせいか、出力周波数がフラフラします。

RMS値として測定した電圧と電流から電力を計算し、出力周波数と
比較したのがこのグラフ。

Cap002_20210108160501
下限と上限の値を使って直線補間した値と、読み取り値との
差を右目盛に入れ込んでます。
ざっと1%くらいに収まっています。

測定した周波数(周期)がパラパラしないようにする必要がある
ようです。

 

| | コメント (0)

2021年1月 7日 (木)

STACKメーター、電池交換

2020年12月16日:車両汎用マルチメーターSTACK社ST8130(ST868)バックアップ用電池交換
の続編です。
↑の記事では、
  電線を引っ張り出し、別の場所に電池ホルダーを設けるという
  手も考えられますが、今回は単純に「タブ付のCR2032」を
  直ハンダすることにしました。
という方法で消耗した電池を入れ替えました。
その後、もう1台、電池交換の依頼がありました。
その時、「電池ホルダーを外に出してはどうだろか」と提案
したのです。

それが、
2020年12月25日:導電加工プラケース
2021年1月6日:ケースに絶縁取り付けできるCR2032用電池ホルダー
につながります。

結局、タカチの電池ホルダーを基板に載せてケース背面に
ネジ止めしました。
41_20210107093301
プラケースの表面、導通があるんで少し浮かせています。
これをもうちょいスマートにできればというのが、1月6日の
書き込みだったのです。

| | コメント (6)

2021年1月 6日 (水)

ケースに絶縁取り付けできるCR2032用電池ホルダー

ケースに絶縁取り付けできるCR2032リチウム電池用
電池ホルダーがないものかと探していました。

いつも使っているのはこんな基板取り付け用の電池ホルダー。
21_20210106111901

左のがタカチのタカチのBCR20H4
右が共立で売っているROC製のGS025-011G
どちらも基板への実装用です。

あれこれネットで探して見つけたのがこれ。
  ・Keystone社製1086

背面にon/offスイッチが付いていて、赤黒のリード線
が出ています。
これをパネルに取り付ける場合、どうなるのかが不明
でした。
ちょいと高価ですが現物を注文。
入ってきたのがこれ。

22_20210106111901
マルツのHPにある写真で見えていたポッチリ二つは
底面からの止めビスをねじ込む穴でした。
このホルダーをパネルに止めるとなると、簡易的には
両面テープ。
しかし、電池を交換する時には両面テープを剥がさなく
てはなりません。
ネジ側を上にしても同じ。
ネジを外すだけでは電池が取り出せない。

このホルダー自身を固定するための金具(何かの細工)を
作ってそれをパネルに付けておかなくては、せっかくの
絶縁型ホルダーが利用できません。

ということで、これを使うのはあきらめました。
  ・・・3Dプリンターで細工してもらうか・・・

※こんな方法は・・・
・丸形のホルダーGS025-011G底面の3つのポッチリ
 を切断。
・電極を保持している足が入る楕円穴2つをパネル
 に開ける。
・電池ホルダーをパネルに接着。(エポキシ2液ボンド)
・パネル裏から電極端子にアクセスしてリード線
 をハンダ付け。
  ※接着強度が心配か。
   ネジ止めできればイイんだけど・・・

※Keystone社製1086をもうちょい
SWがあるほうの固定ネジを外して、中を拝見。
23_20210106130101

固定ネジはM2の皿ビス。
右側4つのポッチリの内径を2.2mmくらいまで
広げて貫通させると、この穴で固定できそうです。
パネル側にM2のタップx4を設けて、SW側のビスで固定。
は電池交換の時は、開閉側のビスx2をゆるめるという
ことで対応。
こんな感じでしょうか。

しかしこのホルダーの電極、ちょい安っぽいです。
マイナス側の電極(SWがつながる)は先をつぶした
ポッチリ一つと、SW中央端子へのハンダ付けだけ
で位置決めされているだけ。
側面電極も頼りない感じがします。

| | コメント (4)

2021年1月 5日 (火)

年末夜警でダイソーのLEDライトが点灯せず

年末29日と30日の夜警、今回は縮小して実施しました。
例年だと、テントを建てて屯所を作ります。
夜回りも行うのですが、町会役員さんや班長さん、
有志の方々との忘年会という雰囲気。

今回は屯所のテントは無し。
役員さんと夜回りを一回だけということで簡略化しました。

その時、拍子木と懐中電灯、赤色点滅発光棒を使います。
メインのLED懐中電灯はパナソニック製のちゃんとしたもの
で、単1電池2本用。

子供達に持たせたらということで、予備にダイソーの
LEDライトをいくつか買ってあったのです。
2015年02月23日:LEDライト
  ※なにせ百円。
   子供らが乱雑に扱ってもOKということで。
そのうちの一つが点灯しないというトラブルに遭遇しました。

D11_20210105154501

ガレージで簡易的に見た感じ(テスターで)では
電池やスプリング電極、スイッチは大丈夫。
電池のプラス頭と発光部と接触するベロまで
電圧は来てました。
きっと点灯回路がおかしくなったんだろうと仕事場に
持ち込んで調べてみました。
  ※昇圧コイルが切れたのか、制御ICがアウトに
   なったのか、LEDそのものか?

D12_20210105154501

外部から電源を供給したら・・・ちゃんと光ります。
「あれれ?」です。

別のLEDライトと比べてみると、発光回路のマイナス側
金属リングと接触するベロ部の形が違ってました。
これが光らない方。
曲がっています。
D13_20210105154501

これ↓だと光ります。
D14

このマイナス側のベロ(スイッチで入り切り)が発光回路の
金属リング(電池のマイナス側)とうまく接触していなかった
のが原因でした。

電池を交換する時に曲げてしまったのでしょう。
年に1回しか使わないもんなんですが、メンテナンスは
重要です。

※関連
LEDの劣化まとめ

| | コメント (0)

2021年1月 1日 (金)

謹賀新年

本年もよろしくです。

出窓も正月モードに。
B11_20210101083601

(1)上下凧
 出窓上の人感センサーで起動。
 モータ駆動で凧が上下に。
 でも、駆動音がうるさいので(ピピのカゴが
 出窓のそばにあるので)、現在は停止中。

メモ:出窓用モータ駆動回路
出窓:正月モード

(2)横行ブランコ
 電磁駆動でブランコを振動。
 ブランコ底板に磁石が貼ってあって、
 それを下からコイルで駆動。

電磁ブランコ第三弾

(3)回転テーブル
 減速機付きの直流モータでゆっくり回します。

(4)出窓の結露防止用ヒーター制御回路
 窓内側真下に置いたヒーターを湿度センサーの
 値を見てon/off。

そろそろ出窓の結露が ・・・あれ? 湿度センサーがおかしい

(5)16セグLEDを使った時計。

16セグメントLEDを使った時計:回路図

 

| | コメント (0)

« 2020年12月 | トップページ | 2021年2月 »