« 2020年1月 | トップページ | 2020年3月 »

2020年2月

2020年2月28日 (金)

町会長旅行、中止に

この日・月に予定していた中川連合・町会長旅行(牡蠣を食べに行こう)、中止(延期)です。
コロナ騒動が落ち着いてから行こうということに。

 

| | コメント (2)

2020年2月27日 (木)

コーナンブランドのLED電球 寿命

ガレージのシャッター上に取り付けていたコーナン
LDA6N-H 6.0W 昼光色」LED電球、先日来
えらい暗なってきたな~」ということで、昨晩交換しました。

11_20200227132801

取り外したLED電球、ベースに「2013-2-6」と日付が書いてあった
ので、使用期間はざっと7年。
自動点滅器で夜になったら一晩中点灯という接続にしていたので、
点灯時間の推定は3年半、3万時間というところ。

「電源回路のコンデンサでもアウトになったかな~」っと解体。

13_20200227132801
12_20200227132801

すると・・・
電源部のコンデンサや部品は大丈夫そう。
液漏れや部品の焼け、ハンダ割れは見当たりません。

14_20200227132801
15_20200227132801

使ってあるLEDは全部で10個。
2パラしたものが5直になっています。
チップLEDそのものも中のLED素子が2つ直列に。
32V加えてやっと点灯。

16_20200227132801

すると・・・
10個のうち3つがアウト。
直列ですので、どこかが切れたら完全に消灯するはず。
LEDは光らないけれど、断線はしてませんでしたんでとりあえず
点いていたという状況です。

さらによく観察すると・・・
7時方向のLED、内部に2つあるLEDのうち1つしか生きていません。

正常なLEDはこんな光りかた。

17_20200227132801
7時方向のLED。↓ 光るのは1つだけ。
18_20200227132801

普通に見てみると・・・

19_20200227132801

光っていない方のLEDが破裂したみたいになっていました。

※関連
2016年01月03日:パナソニックLED電球 LDA7D-A1 寿命!
ダイソーの400円LED電球 (LDA8L-G-T/60W)長期間点灯実験終了
修理:LEDクリップライト、点滅!

電球形蛍光灯の故障原因、電源回路のコンデンサやらパーツの焼けが
目立ってましたが、LEDランプのトラブルは電源回路よりLEDそのもの
がアウトになってますなぁ。


| | コメント (4)

JIS C8708:2019充放電試験「-ΔV又はタイマー制御」の処理

JIS C8708:2019充放電試験 「又は」の解釈はの続き。

今回の制御ソフト、こんな設定パラメータを持っています。
  ※設定値はEEPROMに保存。

 データの 
 アドレス 初期値
  ↓    ↓
NULL   ,EP_CK // 0 - Ret Menu -
&cur_c010 , 190 // 1 0.1C 充電電流設定値 (0~1600mA) ※1
&cur_c050 , 950 // 2 0.5C 充電電流設定値 ※1
&cur_d020 , 380 // 3 0.2C 放電電流設定値 ※1
&cur_d050 , 950 // 4 0.5C 放電電流設定値 ※1
&cur_d49 ,  950 // 5 49cyc 放電電流設定値 ※1
&time_c010, 960 // 6 0.1C 充電時間 (分) 960分:16時間
&time_c050, 132 // 7 0.5C 充電時間 (分) 132分:2時間12分
&wait_c49 ,  20 // 8 1~49cyc 充電後待ち時間 (分) 20~30分
&wait_d49 ,  10 // 9 1~49cyc 放電後待ち時間 (分) 10~90分
&wait_c50 ,  60 // 10 50cyc 充電後待ち時間 (分) 60~240分
&wait_d50 ,  60 // 11 50cyc 放電後待ち時間 (分) 十分な
&v_stop48 , 100 // 12 1~48cyc  放電停止電圧 1.00V
&v_stop49 , 100 // 13 49cyc   放電停止電圧 1.00V
&v_stop50 , 100 // 14 0cyc,50cyc 放電停止電圧 1.00V
&dv_mv  ,  10 // 15 -ΔV (mV) 5,10mV
&dv_time ,  10 // 16 -ΔV 検出開始時間 (分)
&ad_ref100, 120 // 17 A/D基準値 1.00V ※2
&ad_ref180, 776 // 18 A/D基準値 1.80V ※2
&pwm_c010 , 242 // 19 充電電流PWM 0.1A基準値(0~4095) ※2
&pwm_c150 , 3632 // 20 充電電流PWM 1.5A基準値 ※2
&pwm_d010 , 240 // 21 放電電流PWM 0.1A基準値 ※2
&pwm_d150 , 3767 // 22 放電電流PWM 1.5A基準値 ※2
&txcyc_1m ,  0 // 23 1分ごとデータ送出有無 0/1
&tx_d50  ,  0 // 24 50cyc放電時電圧送出有無 0/1
&t_spdup , 100 // 25 タイマー加速データ 通常100
&chk_cyc ,  50 // 26 測定最大サイクル 通常50回目で放電記録
&end_cyc ,  8 // 27 最終測定サイクル 1~8 EEPROMの容量
NULL   ,EP_CK // 28 - Ret Menu -
// ※1 電池により設定  ※2 要調整の数値

データ番号0と28、「- Ret Menu -」となっているところには
マジックナンバーを入れて、初めての電源オン(EEPROMに
有効なデータが書かれていない)をチェックしています。

そして、「-ΔV又は132分」制御に関係するのは以下の3つ。
 データ番号7 time_c050
 データ番号15 dv_mv
 データ番号16 dv_time

time_c050は1cyc~49cycでの0.5C充電時間 (分)で、
132分のタイムアップ時間を設定。

dv_mvは-ΔVの検出電圧を「mV」値で設定。

dv_timeは-ΔV検出を有効にするまでの遅延時間(分)。

タイマーに関する制御条件の設定、こんな具合になります。

(1) 「dv_time < time_c050」 だと、dv_time経過後に
  -ΔV検出が有効になる。 (普通はこれで)
  ただし、-ΔVが見つからなかったらtime_c050で
  充電停止。

(2) 「dv_time >= time_c050」 だとtime_c050経過まで
  -ΔV検出が始まらないので、-ΔVは無視してtime_c050
  で充電停止。
  
(3) 「dv_time < time_c050」という設定で、time_c050を
  規定の132分より長くしておけば、その時間内で-ΔV
  を待って充電停止。
  もし-ΔVが見つからなくても最大はtime_c050まで。

だもんで、132分で充電を止めるのではなく、
「電池が元気な間は-ΔVを見つけたい」という制御にも
パラメータの設定で対応できます。

(1)と(2)で「-ΔV又は132分」の切り替え(どちらか一方)
ができます。
(3)にすると「132分で止めない-ΔV」という制御になります。

意図して設けた区分ではありません。
設定値によって「たまたま」こういう制御になるなぁということで。

 

| | コメント (1)

無塗装、無メッキの鉄製文鎮・・・そんなに錆びない

私が使っている2015年11月製の鉄製文鎮:ハンダ付け補助ツール
無塗装、無メッキ、手入れしていない・・・ 
でも、そんなに錆びてないでしょ。
11_20200227091401

せっかくですんで、クリップを外して油を塗っておきますわ。
ついでに、他の鉄製工具(ペンチ、ニッパ、ストリッパ、圧着器など)も
油をつけたウエスでゴシゴシと。

文鎮:ハンダ付け補助ツールまとめ

使い勝手や感想などは、↑の適当な記事にどうぞ。

| | コメント (0)

2020年2月26日 (水)

JIS C8708:2019充放電試験 「又は」の解釈は

昨日より新しい「ReVOLTES単3」を使っての充放電実験を始めています。

こんなチャートが出てきてます。
C11_20200226093801

そして、ログ用のシリアル出力データはこんな具合。
~~~~~~~~~~~~~~~~~~~
#Start
#D 0.2C 0cyc 0/8 0h00m 1.293V
#D 0.2C 0cyc 0/8 4h03m 1.000V
#D-Wait 0cyc 0/8 1h00m 1.167V
#Next
#C 0.5C 1cyc 1/8 2h12m 1.549V #1
#C-Wait 1cyc 1/8 0h20m 1.440V
#D 0.5C 1cyc 1/8 1h59m 1.000V @1
#D-Wait 1cyc 1/8 0h10m 1.177V
#C 0.5C 2cyc 1/8 2h12m 1.557V #2
#C-Wait 2cyc 1/8 0h20m 1.449V
#D 0.5C 2cyc 1/8 2h01m 1.000V @2
#D-Wait 2cyc 1/8 0h10m 1.176V
#C 0.5C 3cyc 1/8 2h12m 1.562V #3
#C-Wait 3cyc 1/8 0h20m 1.454V
#D 0.5C 3cyc 1/8 2h01m 1.000V
~~~~~~~~~~~~~~~~~~~

#1~#3@1、@2がチャートと対応しています。
「#C」が充電、「#D」が放電制御です。
その充電完了の時間を見ますと、
-ΔV検出で止まったのじゃなく132分経過で充電停止
しています。

充放電の時間比率は、
   放電 / 充電
1cyc 119分/132分 90.2%
2cyc 121分/132分 91.7%
3cyc 121分/132分 91.7%

と、およそ9割。 こうなると、
「0.5C充電(2時間)の1割増しの時間にしておく」という
132分の充電時間、合ってそうな気がします。

ニッ水電池のJIS規格 C8708:2019 で定められた充電制御方法の
又は」の解釈に悩みが出てきました。

・1~49サイクル:
  充電:0.5Cで-ΔV又はタイマー制御(a)で充電。
  静置:20~30分間静置。
  放電:0.5Cで1.0Vまで放電。
  静置:10~90分間静置。

(a)-ΔV=5~10mV又は132分間。
  132分ということは、0.5C容量の1割増しの時間。

この充電制御方法の「又は」の解釈。「OR」条件で、
 ・「-ΔV」あるいは「132分」どっちでもOKよ。
こう考えられます。

今回の制御プログラムではこんな処理を行ってます。
 ・充電開始とともにタイマースタート。
 ・-ΔV検出処理を遅らせるタイマー値を設定していて、
  充電開始直後の何分間は-ΔV処理をしない。
 ・「-ΔV検出」あるいは 「132分」経過で充電停止。
  -ΔVが見つからなくても充電は132分で停止。

(a)の「又は」解釈なんですが、
 (1)132分で充電する時は-ΔVは無視してもokよ。
 (2)-ΔVで充電制御する時は132分を越えて充電してもokよ。

(1)の解釈は「又は = OR条件」というふうに考えると正しいかと。
しかし、(2)はいかがでしょう。
「-ΔV」を選んだ時は「132分」を無視して良いのかどうか・・・。
今は132分をリミットにして充電しています。

今回のように新品電池での充電では、-ΔV検出より先に132分が経過
しちゃいました。
132分を越えても「-ΔV」を待つべきだったか・・・
  ※市販の充電器は電池容量が不明なので「-ΔV」でしか
   充電完了を知るすべがないわけでして。。。

方法としては、
 ・-ΔV充電か132分充電かどちらかを選ぶ。
    (又はの解釈→「どちらでも」ではなく「どちらかを」)

 ・132分充電を選んだのなら-ΔV制御はなし。
 ・-ΔV充電を選んだのなら132分での充電停止は無し。
  (安全のため、別の停止用タイマーを設けておく)
こんな制御方法も考えられます。
どんなもんなんでしょうね。

| | コメント (0)

2020年2月25日 (火)

新型コロナウィルスによるイベント中止の影響が

仕事場のほうで、イベント用機材
 ・大声コンテスト用・大声測定器「大声トライアル」
 ・「ボコスカ・ハンマー」
を貸し出しています。

新型コロナウィルスによる感染防止ということで、レンタル予約していただいて
いたイベントが中止になったとの連絡がやってきました。

地元生野区でも、講演会や音楽会、防災リーダーの訓練講習が中止になったりと
あれこれ影響が出ています。
地元中川では、4月の第一日曜に「桜まつり」を予定しています。
今のところ「決行」ということで準備を進めていますが、さてどうなりますか。

次の「日・月」は広島への町会長旅行。
はてさて。



| | コメント (0)

2020年2月22日 (土)

JIS C8708:2019充放電試験回路での「-ΔV」検出の様子

試運転中のJIS C8708:2019充放電試験回路
その「-ΔV」検出の様子をご覧ください。
※テストですんで新品の電池ではなく、
「ダイソーReVOLTES」JIS C8708:2019充放電試験 50サイクル目
で、ソフトのバグでデータ取得をミスった時に使ったダイソーの
ReVOLTES単3。
すでに200回の充放電試験を経ています。

新JISでの充電条件が(サイクル1~49)
  「0.5Cで-ΔV又は132分のタイマー制御」
  「-ΔVは5~10mV」
と記されています。

このテストでは-ΔV値をとりあえず「10mV」に設定。
1分サイクルでシリアル出力する経過時間と電圧値
を観察してみます。
  (7サイクル目の途中まで)

~~~~~~~~~~~~~~~~~~~~~
#C 0.5C 1cyc 1/5 1h39m 1.670V
#C 0.5C 1cyc 1/5 1h40m 1.670V
#C 0.5C 1cyc 1/5 1h41m 1.670V ★Peak #1
#C 0.5C 1cyc 1/5 1h42m 1.668V
#C 0.5C 1cyc 1/5 1h43m 1.668V
#C 0.5C 1cyc 1/5 1h44m 1.667V
#C 0.5C 1cyc 1/5 1h45m 1.666V
#C 0.5C 1cyc 1/5 1h46m 1.665V
#C 0.5C 1cyc 1/5 1h47m 1.663V
#C 0.5C 1cyc 1/5 1h48m 1.662V
#C 0.5C 1cyc 1/5 1h49m 1.661V
#C 0.5C 1cyc 1/5 1h49m 1.660V ★Stop
#C-Wait 1cyc 1/5 0h01m 1.520V

#D 0.5C 1cyc 1/5 1h07m 1.000V ←放電時間
~~~~~~~~~~~~~~~~~~~~~
#C 0.5C 2cyc 1/5 1h09m 1.689V
#C 0.5C 2cyc 1/5 1h10m 1.689V
#C 0.5C 2cyc 1/5 1h11m 1.689V ★Peak #2
#C 0.5C 2cyc 1/5 1h12m 1.688V
#C 0.5C 2cyc 1/5 1h13m 1.687V
#C 0.5C 2cyc 1/5 1h14m 1.685V
#C 0.5C 2cyc 1/5 1h15m 1.684V
#C 0.5C 2cyc 1/5 1h16m 1.682V
#C 0.5C 2cyc 1/5 1h17m 1.680V
#C 0.5C 2cyc 1/5 1h17m 1.679V ★Stop
#C-Wait 2cyc 1/5 0h01m 1.529V

#D 0.5C 2cyc 1/5 1h05m 1.000V ←放電時間
~~~~~~~~~~~~~~~~~~~~~
#C 0.5C 3cyc 1/5 1h06m 1.698V
#C 0.5C 3cyc 1/5 1h07m 1.698V
#C 0.5C 3cyc 1/5 1h08m 1.698V ★Peak #3
#C 0.5C 3cyc 1/5 1h09m 1.696V
#C 0.5C 3cyc 1/5 1h10m 1.695V
#C 0.5C 3cyc 1/5 1h11m 1.694V
#C 0.5C 3cyc 1/5 1h12m 1.691V
#C 0.5C 3cyc 1/5 1h13m 1.690V
#C 0.5C 3cyc 1/5 1h13m 1.688V ★Stop
#C-Wait 3cyc 1/5 0h01m 1.533V

#D 0.5C 3cyc 1/5 1h03m 1.000V ←放電時間
~~~~~~~~~~~~~~~~~~~~~
#C 0.5C 4cyc 1/5 1h03m 1.704V
#C 0.5C 4cyc 1/5 1h04m 1.705V
#C 0.5C 4cyc 1/5 1h05m 1.705V ★Peak #4
#C 0.5C 4cyc 1/5 1h06m 1.704V
#C 0.5C 4cyc 1/5 1h07m 1.702V
#C 0.5C 4cyc 1/5 1h08m 1.701V
#C 0.5C 4cyc 1/5 1h09m 1.700V
#C 0.5C 4cyc 1/5 1h10m 1.698V
#C 0.5C 4cyc 1/5 1h10m 1.695V ★Stop
#C-Wait 4cyc 1/5 0h01m 1.535V

#D 0.5C 4cyc 1/5 1h01m 1.000V ←放電時間
~~~~~~~~~~~~~~~~~~~~~
#C 0.5C 5cyc 1/5 1h02m 1.710V
#C 0.5C 5cyc 1/5 1h03m 1.710V
#C 0.5C 5cyc 1/5 1h04m 1.710V ★Peak #5
#C 0.5C 5cyc 1/5 1h05m 1.709V
#C 0.5C 5cyc 1/5 1h06m 1.707V
#C 0.5C 5cyc 1/5 1h07m 1.706V
#C 0.5C 5cyc 1/5 1h08m 1.704V
#C 0.5C 5cyc 1/5 1h09m 1.701V
#C 0.5C 5cyc 1/5 1h09m 1.700V ★Stop
#C-Wait 5cyc 1/5 0h01m 1.538V

#D 0.5C 5cyc 1/5 1h00m 1.000V ←放電時間
~~~~~~~~~~~~~~~~~~~~~
#C 0.5C 6cyc 1/5 0h59m 1.713V
#C 0.5C 6cyc 1/5 1h00m 1.715V
#C 0.5C 6cyc 1/5 1h01m 1.716V ★Peak #6
#C 0.5C 6cyc 1/5 1h02m 1.715V
#C 0.5C 6cyc 1/5 1h03m 1.715V
#C 0.5C 6cyc 1/5 1h04m 1.713V
#C 0.5C 6cyc 1/5 1h05m 1.711V
#C 0.5C 6cyc 1/5 1h06m 1.710V
#C 0.5C 6cyc 1/5 1h07m 1.707V
#C 0.5C 6cyc 1/5 1h07m 1.706V ★Stop
#C-Wait 6cyc 1/5 0h01m 1.540V

#D 0.5C 6cyc 1/5 0h59m 1.000V ←放電時間
~~~~~~~~~~~~~~~~~~~~~
#C 0.5C 7cyc 1/5 0h57m 1.716V
#C 0.5C 7cyc 1/5 0h58m 1.718V
#C 0.5C 7cyc 1/5 0h59m 1.720V
#C 0.5C 7cyc 1/5 1h00m 1.720V ★Peak #7
#C 0.5C 7cyc 1/5 1h01m 1.718V
#C 0.5C 7cyc 1/5 1h02m 1.717V
#C 0.5C 7cyc 1/5 1h03m 1.716V
#C 0.5C 7cyc 1/5 1h04m 1.715V
#C 0.5C 7cyc 1/5 1h05m 1.712V
#C 0.5C 7cyc 1/5 1h05m 1.710V ★Stop
#C-Wait 7cyc 1/5 0h01m 1.541V

~~~~~~~~~~~~~~~~~~~~~

0.5Cでの充電をはじめておよそ1時間してピーク電圧を
検出。
その数分後に10mVのドロップを検知して充電停止。
こんな充電制御が続いています。

2時間12分(132分)のタイマーで止まったのは、この7つ
のサイクルの中ではありませんでした。
   ※200サイクルの試験を経た古い電池だから

充電の次の工程、時間待ち後0.5Cで1.0Vまでの放電。
充電時間と放電時間を抜き出してみると・・・

  充電時間 放電時間 充放電時間比
1cyc 1h49m  1h07m   67/109 = 61.5%
2cyc 1h17m  1h05m   65/77 = 84.4%
3cyc 1h13m  1h03m   63/73 = 86.3%
4cyc 1h10m  1h01m   61/70 = 87.1%
5cyc 1h09m  1h00m   60/69 = 87.0%
6cyc 1h07m  0h59m   59/67 = 88.1%

1サイクル目は0.2Cで1.0Vまでゆっくりと放電したんで、
充電時間が長くなったようです。
その後は84%~88%の時間比で放電が行われています。

そしてチャートで記録している電池側面の温度変化を
見ると温度上昇は5℃ほど。
-ΔV制御無しで132分充電した場合に比べると、
優しい温度上昇になっています。

※以前の実験の温度変化 15℃ほど上昇。
  a1_20200210151501.jpg

もう少し様子を見てから(初めて動かすプログラムなんで)
新品電池をセットして試験をしてみます。


※追記
「-ΔV検出」による充電停止と、「132分充電」で電池の
側面温度がどうなるかしらべてみました。
#1~#7が「-ΔV充電」の時。 (↑の記録を採った時の)
およそ5℃くらいの温度上昇。
@1~@3が「132分充電」。
電圧波形を見ると、-ΔVが現れているのにまだ充電が行わ
れている様子がわかります。
それに連れて温度も上昇。 10℃くらい上がっています。
B32

  ※ナダ電子のプリンターシールドでの記録

「132分充電」後の放電結果を見てみると・・・
   (チャートの@1~@3のところ)
  放電時間  充放電時間比
@1 1h09m   69分/132分 = 52.3%
@2 1h07m   67分/132分 = 50.8%
@3 1h07m   67分/132分 = 50.8%

1.0Vまでの放電時間は-ΔV制御で充電したのと
(↑の#1~#6)ほとんど同じでした。

つまり、-ΔV発生以降の充電エネルギーは無駄に
なっていて、電池を暖めているだけということが
見えてきます。
このあたりもニッ水電池の寿命に関係してくるかと
推測できます。

市販の急速充電器での充電と自作放電器 での充放電繰り返し実験
では見えてこない部分が、今回の「-ΔV検出制御」で見えてきた
ような気がします。


・試運転中の基板
B41


| | コメント (0)

2020年2月21日 (金)

異形のハンダ付け補助ツール・・・試作で

2019年11月 7日文鎮:SUS304・16mm厚ハンダ付け補助ツール あと7コ
「2020年2月20日 19時19分」にコメントしましたように、
2018年6月20日文鎮:ハンダ付け補助ツ-ル …形状違いの素材
の穴あけ試作品を佐藤テック君が持ってきてくれました。

M5タップが2カ所開けているんで、クリップをいろんな方向に付けられます。
13_20200221193701

14_20200221193701

15_20200221193701

11_20200221193701

12_20200221193701

こんな穴(M5タップ)位置です。
21_20200222090901
22_20200222090901


「22mm厚」の素材バーを「シカル」で「V字」に切削。
その加工されたものの端材をクリップ幅に切断しています。

で、この材質ですが、佐藤テック君曰く、
  「S50CかS45C・・・たぶんハガネ だろう。
  「SS400などの普通の鉄ではない。」かっと。
※ちゃんと調べてくると。 →SS400でした。っと。

重さが「515グラム」。
だもんで、クリックポストでは一つしか送れません。
レターパック・ライト(370円)、レターパック・プラス(520円)
とも、制限重量が3kgですので、2つ以上の場合はこちらを。
  ※クリックポストとレターパック・ライトは、郵便受け
   へ放り込まれますんで、受け口が狭いと入りません。
   そんな場合はレターパック・プラスを使ってください。
   手渡しになります。

頒布価格ですが「1,200円」でよろしくっと。
これにクリックポスト代金「188円」が加わります。
M5のキャップボルトとワッシャ、クリップ口に付けるゴム板
を添付します。
素材を削ったまま、塗装もメッキも無しで。
クリップはご自身で入手してください。


集めた端材で何個作れるかは現時点不明ですが、ご希望の方は、
この記事にコメントして(メールアドレスを記入して)ください。


ハンダ付け補助ツール(文鎮)まとめ

※2020-02-25
今回の製作、残1つです。 (4月15日、完売しました)
11_20200225090601
佐藤テック君、昨晩ガレージにやってきて「ドリルの刃、折ったぁ」
っと、泣いていました。

| | コメント (22)

JIS C8708:2019充放電試験回路試運転

JIS C8708:2019充放電試験回路製作中、ざっと
制御ソフトが出来たので試運転中です。

今回はJIS C8708:2019の充電条件へ対応。
「0.5Cで132分 又は -ΔV(5mV~10mV)」
これに対応するため、電池電圧を読むA/D入力に
アンプを入れました。

Arduino(ATmega328P)のA/Dコンバータは10bit。
基準電圧を2.5Vにして0~2.5Vをそのまま入力
すると1ビットが約2.44mV。
5~10mVの-ΔVを拾うとすると、その変化量は
2~4ビットと微少。
もうちょい分解能が欲しいか、ということでこんな
アンプをA/Dの前段に入れました。 (U6 1,2,3のところ)

C1

考え方
・電池の寿命試験で電池電圧を測るのに0V付近は不要。
・0.9Vくらいから2.0Vの範囲を測れたらよいんじゃないか。
・A/Dの分解能を1ビットを1mVくらいにしたい。
・とりあえず、入力範囲を0.85V~2.1Vにして、測定スパン
 を1.25Vに。
・これを2倍に増幅。
・1ビットはきっちり1mVにはならないで約1.22mV。

こんな回路になっています。

また、A/D入力処理も、速度は不要なんで
・1mSごとのA/D変換で、256回の加算平均処理。
 256回分10ビットのA/D値を加算合計して、256回目に
 1/256して平均値を算出。256mSごとにA/Dデータが確定。
・この平均値を16回移動平均。
 リングバッファの古いのを捨てて新しいのを加える。
・さらに、バッファのデータをソートして、上下それぞれ
 4つのデータを捨て(maxに近い4つとminに近い4つ)、
 8つの中央値で平均計算。
・256mSごとにこのスムージング処理したデータが確定。
 16回なんで、A/D入力値が安定するまで約4秒。
・これで、一瞬の短絡や開放はデータに出てこない。

こんな処理で-ΔVを見つけるようにしました。

これでうまく処理できるか、試運転中です。

※OP-AMPについて
今回使ったMCP6072、電源電圧5V以下で使うならおすすめです。
特徴
・安価  100円くらい  ただしDIPは無い
・レール to レール入力/出力
・ゲインバンド幅 1.2MHz
・低オフセット電圧 0.15mV(max) ★
・入力バイアス電流 1pA (CMOSなんで)
・低消費電流 0.11mA
・動作電圧範囲 1.8V~6V

オフセット電圧の小さなCMOSアンプって、なかなか
ないんですよね。
ただ、DIP品が無いので試作にはピッチ変換基板が必須です。


※追記

・1msタイマー処理とその中で起動されるA/D変換。
・A/D割り込みで行う256回のA/D値平均処理。
  ↑
この2つの処理は割り込みで行うので、時間待ちは無し。
勝手にA/D平均データが上がってきます。

この中でスイッチ入力処理とブザー報知処理も実行。
液晶画面表示を行っていると、スイッチのチャタリング除去
処理やブザー報知の処理が遅れることがあるんで、タイマー
割り込みの中で勝手に処理するようにします。

・メインルーチン内でf_adokフラグをチェックして
 行う256msごとのA/D値スムージング処理。
 ソートを行うので、割り込み内からは出してます。

これを示しておきます。 (スペースは全角で)

/********************************/
/*   1ms タイマー割り込み  */
/********************************/
// 関数プロトタイプ宣言 (タイマー割込み内で処理)
void swscan(void);      // SW入力スキャン
void bzzexc(void);      // ブザー報知実行
/***** タイマーデータ  *****/
volatile byte tm_1ms;   // 1msダウンカウントタイマー
volatile byte tm_10ms;   // 10msダウンカウントタイマー
volatile byte f_1sec;   // 1秒経過フラグ
volatile byte f_1min;   // 1分経過フラグ
// 測定用タイマー(カウントアップ)
byte f_tmion;        // 計時指令
              // onで計測タイマーをカウントアップ
volatile word tmi_1min;  // 1分 カウントアップタイマー
              // 24時間で1440分 999分で16時間39分
volatile byte tmi_1sec;  // 1秒 カウントアップタイマー
              // 00~59
volatile byte tmi_10ms;  // 10ms カウントアップタイマー
// tmmreadで読む測定タイマー
word tmm_1min;       // 1分 max5999分=99時間59分
byte tmm_1sec;       // 1秒 0~59
/***** タイマー0コンペアマッチA割込み    *****/
// 割り込みでパルス出力(1kHz周期)
ISR(TIMER0_COMPA_vect)
{
static byte cnt10  = 0;
  PB0_H;           // (!!!) 14pin
  if(tm_1ms)   tm_1ms--;  // 1msダウンカウント
// 10msタイマー
  cnt10++;
  if(cnt10 >= 10){
    cnt10 = 0;
    if(tm_10ms)   tm_10ms--;   // 10mS ダウンカウント
    if(f_tmion){          // 計時する?
     tmi_10ms++;
     if(tmi_10ms >= t_spdup){   // 100カウントで1秒
      tmi_10ms = 0;
      f_1sec = 1;         // 1秒フラグをオン
      tmi_1sec++;         // +1秒
      if(tmi_1sec >= 60){     // 60秒
       tmi_1sec = 0;
       f_1min = 1;        // 1分フラグをオン
       tmi_1min++;        // +1分
       if(tmi_1min >= 6000){   // 6000分越え?
        tmi_1min = 5999;
        tmi_1sec = 59;     // 99時間59分59秒に
       }
      }
     }
    }
  }
// 1ms処理関数
  swscan();      // SW入力スキャン
  bzzexc();      // ブザー報知実行
// 内蔵A/D開始
  ADCSRA |= (1 << ADSC);   // A/D変換開始
  PB0_L;           // (!!!) 14pin
}

/******************************/
/*   内蔵A/D処理    */
/******************************/
/**** A/D データ    *****/
#define ADAVR_ADD   256   // A/D平均回数
volatile word ad_avr;     // A/D変換データ 0~1023
                // 平均処理された結果
volatile ulong ad_add;     // A/D平均処理用加算データ
volatile byte f_adok;     // A/D変換完了フラグ
                // 割り込みでセット
// 平均処理確定でad_avrを転送 電池電圧に変換
byte f_advolt;         // A/Dデータ転送変換完了フラグ
word ad_data;          // 電圧A/D値 (平均値)
word bat_ad;          // スムージング処理結果A/D値 (0~1023)
word bat_volt;         // 電池電圧 bat_adをmV値に変換
word bat_peak;         // 電池電圧ピーク値(mV)
word bat_deltav;        // ΔV値 ピーク-現在値 (mV)
byte f_peakon;         // ピーク検出開始フラグ
/***** A/D割り込み処理  *****/
//  1msタイマー割り込みでA/D変換開始
//  256回で平均値算出
ISR(ADC_vect)
{
word d;
static word cnt = 0;  // A/D変換平均回数
  PB4_H;           // (!!!) 18pin
  d = (word)ADCL;       //
  d |= (ADCH & 0x03) << 8;  // 符号なしで 0~3FF
// 測定値
  ad_add += (ulong)d;     // 平均用に加算
// 平均処理
  cnt++;           // 平均加算回数
  if(cnt >= ADAVR_ADD){    // 256回?
    cnt = 0;
    ad_avr = (word)(ad_add / ADAVR_ADD); // 平均
    ad_add = 0L;      // 次加算データクリア
    f_adok = 1;       // 変換完了
  }
  PB4_L;           // (!!!) 18pin
}
/***********************************/
/* A/Dデータスムージング処理   */
/***********************************/
// 処理バッファ
word ad_smzbff[16];     // A/Dデータ保存バッファ
word ad_sort[16];      // ソート用バッファ
/***** qsort用データ比較    *****/
// wordで比較
int wordcmp( const void *p, const void *q ) {
  if( *(word *)p > *(word *)q )   return 1;
  if( *(word *)p < *(word *)q )   return -1;
  return 0;
}
/***** スムージング処理  *****/
// 16コのA/Dデータを順にサンプル
// ソートして上下4コ(8コ)を捨て、中央の8コを平均
// 256ms X 16 = 4.096秒後に安定
word adsmz(word d)
{
static byte f1 = 0;   // はじめてフラグ
static byte wp;     // 書き込みポインタ
byte i;
long a;
word b;
  if(f1 == 0){        // 初めて
    f1 = 1;
    for(i = 0; i < DIMSIZ(ad_smzbff); i++){
      ad_smzbff[i] = d;    // バッファを初期データで埋める
    }
    wp = 0;           // データ書き込みポインタ
  }
  else{            // 2回目以降
    ad_smzbff[wp] = d;       // A/Dデータをストア
    wp++;              // 書き込みポインタを進める
    if(wp >= DIMSIZ(ad_smzbff))  wp = 0;  // 一周回って先頭に
  }
  memcpy(ad_sort, ad_smzbff, sizeof(ad_smzbff)); // バッファにコピー
  qsort(ad_sort, DIMSIZ(ad_sort), sizeof(word), wordcmp); // qsort実行
// 中央の8つで平均処理 上下4コは捨てる
  a = 0;             // 合計
  for(i = 0; i < 8; i++){     // 中央の8コを加算
    a += ad_sort[4 + i];    // 4コ目から8コを加算
  }
  b = word(a / 8);        // 1/8して平均値
  if((a % 8) >= 4)    b += 1; // 四捨五入
  return b;
}

全体のスケッチはまた今度に。

| | コメント (1)

2020年2月17日 (月)

定電流回路の電流検出抵抗

JIS C8708:2019充放電試験回路製作中、この中の定電流回路
(充電用と放電用の2つ)この電流検出抵抗をあれこれ模索。
今回使ったのは手持ちの関係で5W・0.3Ω。
その発熱が悩みどころ。

セメント抵抗に電力を食わせた時の温度上昇。
こんなグラフが出ていました。

B0
https://www.e-globaledge.com/products/ecomponents/tdo/

温度特性が「±400ppm/℃」。
ということは、10℃変化で0.4%。
触れないくらいの50℃も上がると2%の変動。

電流検出抵抗としてはちょいとなぁ~なんですが、
とりあえず手持ち部品の関係で「5W0.3Ω」というのを
用いました。

今回の回路、最大1.5Aで0.3Ωだと0.7Wほど。
5W定格の14%ほど。
十分に定格内なのですが、↑のグラフを見ると、
上昇温度が30℃ほどと読み取れます。
ということは抵抗値として1%ほどの変動を覚悟しな
くてはとなります。

仕事の装置ではこんな抵抗を使っていました。
   ※手持ちが無いので今回は使えなかった。
B1_20200217091601
「PWR4412」という金属でできたコの字のバー。
これで「±20ppm/℃」。
ただし、ラインナップされている最高の抵抗値が「0.1Ω」。

抵抗値を小さくすると、電力が減って発熱も少なくなりますが、
定電流回路の制御電圧を下げなければなりません。
今は制御電圧0.5Vで1.6A。
電流検出抵抗を0.1Ωにすると、0.16Vで1.6Aという制御に
なり、ちょっと電圧が低いかな~というところです。


※参考
ねがてぃぶろぐ セメント抵抗の温度特性 その1
ねがてぃぶろぐ セメント抵抗の温度特性 その2

※追記
手持ちの「コの字状抵抗」を引っ張り出してきました。
11_20200218090301
30mΩのと50mΩのが各2つ。
調べてると・・・
PWR4412」、廃番になってました!
えらいこっちゃ。
代替品を探さなくてはなりません。

ビシュイでSR3R、SR5Rというのが使えそう。
ちょいと温度係数が悪いか・・・。
SR3R(3Wタイプ)だと0.1Ωがある。
RiedonというメーカーでMSR5というのでも0.1Ωがある。

抵抗値を小さくすると、同じ電流なら電力がダウン。
1.5Aで0.3Ωだと0.675Wだったのが、0.1Ωにすると0.225Wに。
これで、発熱がずいぶんと減ります。
↑にあるグラフのように「負荷率に対する温度上昇曲線」あれば
発生誤差が推定できるんですけれどねぇ。

| | コメント (5)

2020年2月16日 (日)

JIS C8708:2019充放電試験回路製作中

ざっとハードが固まりました。
制御プログラムをごそごそしています。

A2_20200216162501

0.5Cで充放電させる必要があるので、設定できる最大を1.6Aに
しています。

A1_20200216162501
充電側のヒートシンクをもうちょい大きくしたいところ。




| | コメント (0)

2020年2月13日 (木)

マイコン型導通チェッカー、頒布しています。

2018年4月にマイコン型導通チェッカー、10年目に という記事を書いてます。
  ※現在も(有)アクト電子で頒布しています。
先日も、「新人の研修で使いたい」ということで、まとまった数の注文を
いただきました。 ※ありがとうございます。
ケース加工も丸穴だけだし、回路のハンダ付けや組み立ても難しくありません。
  ※面実装ICはこちらでハンダしてます。
組み立てておけば、電子回路工作で役立つ一生もののツールになること間違い
なしです。
回路図もソースファイルも(アセンブラですが)公開してますし、教材として
の価値もあるかと。
どうぞご検討ください。

※「導通チェックなんてテスターに付いてるやん」という意見もありますが、
 このチェッカーの手軽さは、実物で体験してもらわないと分かってもらえ
 ないかな。

そうそう。郵便局のクリックポスト が4月から198円に値上げです。
(現在は188円)

| | コメント (0)

2020年2月10日 (月)

ダイソーReVOLTES単3 JIS C8708:2019充放電試験 400サイクル目完了

ダイソーReVOLTES単3 JIS C8708:2019充放電試験 200サイクル目完了
の続き。 400サイクル目、完了です。

0400
400サイクル目で、放電持続時間が2時間ほどに。
寿命と判断して、今回の実験はこれで終了します。

実験回路 から取り外したReVOLTES、その内部抵抗を
計ってみると「481mΩ」。
0.5C、つまり650mA流すと「0.3V」のドロップが発生。
充電時も同じで、内部抵抗で充電電圧が上昇します。
そのため、充電時に1.8Vを越えてしまっています。
  ※そのあたりは電圧と温度変化のグラフで

A1_20200210151501
  ※350回目後に電圧レンジのゼロ点を下げた。
   フルスケールを1.8Vに。

今回は「充電0.5Cで132分 (-ΔV制御はしない)」という
充放電繰り返し条件でした。
これを-ΔV制御するとどうなるか・・・
無駄な温度上昇がマシになるんじゃないかと。
  ※制御プログラムを作り直さなくちゃなりません。

※関連
ダイソーReVOLTES単3 JIS C8708:2019充放電試験 続行中
ダイソーReVOLTES単3 JIS C8708:2019充放電試験 200サイクル目完了
パナソニックのニッケル水素電池、新JIS 8708:2019による充放電繰返し回数
「ダイソーReVOLTES」JIS C8708:2019充放電試験 50サイクル目
ダイソーReVOLTESでJIS C8708:2019サイクル試験開始
ニッ水電池のJIS規格 C8708:2019
電池イジメ、もうやめます





| | コメント (0)

ArduinoのanalogWrite 1/255なの?

ミスが広まる 1/1023 vs 1/1024 はA/Dコンバータのスケーリングの話。
Arduinoのタイマー OCRレジスタは「n」じゃなく「n - 1」の値を設定せよ
はタイマーコンペアレジスタ設定の話。

そして今度は「analogWrite」、ArduinoのPWM出力の話をちょっと。

Arduino-UNOだと3つのタイマーを使った6つのPWM出力が可能です。
仕様では分解能8bit。
  void analogWrite(uint8_t pin, int val)
という関数で使います。
ピン番号で使うタイマーが決まり、例えば5,6ピンならタイマー0が
用いられます。
タイマーのクロックが250kHzで8ビットですので、1.024ms周期で
1ビットが4usの分解能になります。

valの値がPWMのデューティー比で、設定できるのは0~255。
0で出力LOW固定になり、255で出力HIGH固定。
128でデューティー50%の方形波。

analogWriteを単にPWM出力ということではなく「D/Aコンバータ」
として使った時、その出力範囲をどう考えればよいでしょうか?
  (「1/1023 vs 1/1024」に近い話になります)

8ビットの0~255のデータを、可変範囲が0~5VのD/Aコンバータで
出力する時、最大値は「(255×5V)/256」で、フルスケールの5Vより
約20mV低いおよそ4.98Vがmax値となります。

ところがanalogWriteは「0V=LOWに張り付いてパルス無し
5V=HIGHに張り付いてパルス無し」まで出力できます。

本来ならフルスケール「(255×1.024ms)/256」で、
1020usのHIGHパルスに4usのLOWパルスが残るはず。
それがなぜか255でHIGHに張り付いちゃいます。
1/256ではなく1/255で処理されているのじゃないかと考え
られるのです。

analogWriteは「wiring_analog.c」内で処理されていますので、
ソースをちょいと覗いてみると・・・
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void analogWrite(uint8_t pin, int val)
{
  pinMode(pin, OUTPUT);   // 指定ピンを出力に
  if (val == 0){        // ★1
    digitalWrite(pin, LOW);  // 値が0ならLOWに張り付き
  }
  else if (val == 255){     // ★2
    digitalWrite(pin, HIGH); // 値が255ならHIGHに張り付き
  }
  else {      // ArduinoCPUによる区別
    switch(digitalPinToTimer(pin)) {  // その代表で
      case TIMER0A:         // タイマー0
        sbi(TCCR0A, COM0A1);    // OC0Aピン非反転PWM出力モード
        OCR0A = val;  // set pwm duty ★3 値が1~254の時
        break;
       :
    }
  }
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
★1と★2で0と255を分離処理して、★3で1~254の時だけ
PWMパルスが出るようにしています。

そこで、タイマー0のanalogWriteに対して、0~255の数値を順に
与えてみると・・・周期1.024msのパルスに対して、
  0ならずっとLOW
  1だと8usのHIGHパルス  ▼1
  2だと12usのHIGHパルス
   :
  253だと8usのLOWパルス
  254だと4usのLOWパルス
  255だとずっとHIGH
が観察されます。
タイマー0に関して、値0と1のところ▼1で、ほんとなら4usステップ
になって欲しいのが8usとなっていて、値1~255とは異なるピッチ
なっていることがわかります。

※この部分の注意点
 これ、タイマー0だからなんです。
   OCR0A = val
 とコンペアレジスタに設定値を与えているから。
   OCR0A = val - 1
 にすると、値1で4usのHIGHパルスが得られます。
 そして★2の処理を無くせば255で4usのLOWパルスとなり、
 「(255×1.024ms)/256」、「(255×5V)/256」の値が得られます。

なお、タイマー0が「8bit高速PWMモード」で初期化されている
ことに注意してください。
タイマー1とタイマー2は「8bit位相基準PWMモード」に設定されて
いて、動作が異なるのです。
このあたりの差が、数値に対するPWM波形出力に影響を与えます。

analogWriteにD/A変換機として純粋な精度を求める場合はちょいと
ご注意を。
ハードウェアマニュアルをよく読み、テストプログラムを書いて
動きを確かめてということで。

※追記
デューティー50%の方形波を得ようとして
  analogWrite(6,128);
しても、HIGH=512us、LOW=512usの波形にはなりません。
HIGHが516us、LOWが508usになり、デューティ50.4%くらいの
方形波が出てきます。
きっちり50%にしたいのなら、
  analogWrite(6,127);
です。 (タイマー0で)

※PWMでのD/A変換、こんな回路を使ってます。
B1_20200210161601
Arduinoの5Vは不安定なので、基準電圧ICで4.096Vとか
2.5Vなどを発生。
PWM波をアナログマルチプレクサ(74HC4053など)を使って
GND-VREF電圧を切り替える。
それをLPFで平滑。
OP-AMPでバッファして電圧出力に。
タイマー1を使うと分解能を10bitとか12bitに拡張できる。
analogWriteじゃなく自前のプログラムで制御。

※PWM出力の様子をオシロスコープで観察する
 ためのテストプログラム。 (注:スペースを全角で)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#include "wiring_private.h"
// I/O MACRO
#define PB0_H  (PORTB |= (1 << PB0))   // (!!!)PB0 H/L D8
#define PB0_L  (PORTB &= ~(1 << PB0))
#define PB4_H  (PORTB |= (1 << PB4))   // (!!!)PB4 H/L D12
#define PB4_L  (PORTB &= ~(1 << PB4))
#define PB5_H  (PORTB |= (1 << PB5))   // (!!!)PB5 H/L D13
#define PB5_L  (PORTB &= ~(1 << PB5))

/***** タイマー0 オーバーフロー回数読み出し *****/
extern volatile unsigned long timer0_overflow_count;
unsigned long readovf0(void)
{
unsigned long t;
  cli();         // 割込禁止
  t = timer0_overflow_count;
  sei();         // 割込許可
  return t;
}
/***** PWM出力    *****/
// val : PWM設定値 0~255
// OC0A,OC1A,OC2Aに出力
void pwm3ch(int val)
{
  analogWrite(6,val);    // タイマー0 OC0A
  analogWrite(9,val);    // タイマー1 OC1A
  analogWrite(11,val);   // タイマー2 OC2A
}
/*****  セットアップ    *****/
//  ATmega328Pのレジスタを直接制御
void setup()
{
  cli();         // 割込禁止
// I/Oイニシャル
  PORTB = 0b00000000;   // data/pull up
  DDRB = 0b00111111;   // port指定
  //     |||||+---- PB0 IO8  out    test pulse
  //     ||||+----- PB1 IO9  out OC1A
  //     |||+------ PB2 IO10  out OC1B
  //     ||+------- PB3 IO11  out OC2A
  //     |+-------- PB4 IO12  out    test pulse
  //     +--------- PB5 IO13  out (LED) test pulse
  PORTD = 0b00000000;   // data/pull up
  DDRD = 0b11111100;   // port指定
  //    |||||||+---- PD0 IO0  RXD
  //    ||||||+----- PD1 IO1  TXD
  //    |||||+------ PD2 IO2  out
  //    ||||+------- PD3 IO3  out OC2B
  //    |||+-------- PD4 IO4  out
  //    ||+--------- PD5 IO5  out OC0B
  //    |+---------- PD6 IO6  out OC0A
  //    +----------- PD7 IO7  out
  sei();         // 割込許可
}
/***** LOOP    *****/
void loop()
{
unsigned long ovf0;
unsigned long ovfck;
byte cnt  = 0;   // オーバーフローカウンタ
byte kubun = 0;   // PWM出力区分
static int val[]={ // PWM設定値
  0, 1, 2, 127, 128, 253, 254, 255, // 8つのPWM値
};                   // 0:LOW~255:HIGH
  ovf0 = readovf0();       // オーバーフロー回数
  while(1){
    ovfck = readovf0();
    if(ovf0 != ovfck){     // 変化あり
      ovf0 = ovfck;      // 1.024msタイマー0オーバーフロー
      PB0_H;         // 1.024msごとにパルス出力
      if(cnt == 0){
        PB4_H;             // 先頭カウントの時
        if(kubun == 0)   PB5_H;   // 区分0の時パルス
        else        PB5_L;
        pwm3ch(val[kubun]);  // 区分によりPWM出力  
      }
      else{
        PB4_L;
      }
      cnt++;
      if(cnt >= 6){      // 6回オーバーフロー
        cnt = 0;
        kubun++;      // PWM区分
        if(kubun > 7)  kubun = 0; // 0~7
      }  
      PB0_L;
    }
  }
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

・timer0_overflow_countがタイマー0割り込みでインクリメントされるので、
 これを見て1.024ms経過を検出。
・PB0は1.024msごとにパルス出力。
 PB4はPWM値設定ごとに、PB5は区分一周でパルス出力。
 オシロのトリガー源に。
・タイマー0のPWMはこのパルス周期に同期しているが、
 タイマー1、2のPWMは同期しない。
 タイマー0は1/256処理。タイマー1,2は1/255で処理されている
 ので、周期が異なるから。
・タイマー1,2でデューティー、ジャスト50%を得ようとしても、できない。
  127だと、H:1.016ms + L:10.24msに。
  128だと、H:1.024ms + L:1.016msになってしまう。
   (タイマー0は周期1.024msだけど、タイマー1,2は2.040ms周期)


| | コメント (2)

2020年2月 4日 (火)

Arduinoのタイマー OCRレジスタは「n」じゃなく「n - 1」の値を設定せよ

ミスが広まる 1/1023 vs 1/1024は、Arduino-UNO(ATmega328pマイコン)
のA/Dコンバータ・スケーリングのお話しでしたが、今回はタイマーのコンペアマッチ
レジスタのお話しです。

Arduinoのタイマーを直接操作する時(例えばMsTimer2などのタイマー
ライブラリーを使わずにタイマー割り込みを使いたい時など)、CTCモードで
アウトプットコンペアレジスタにタイマーの最大カウント値を設定します。
Arduinoから「タイマー0」を取り上げる(ユーザーが使う) では
「1m秒」割り込みを例にしました。
1msつまり1kHzの割り込み周期を得るには、
 ・CTCモードに。 (コンペアマッチでカウンタゼロクリアー)
 ・16MHzのクロックをプリスケーラーで1/64して250kHzに。
 ・それを1/250して1kHzに。
この1/250するのがアウトプットコンペアレジスタへの設定です。
↑の例では
   OCR0A = 250 - 1;    // 250カウントで1kHzを
の所。
1/250なんで「250 - 1」を設定しています。
これをミスして「-1していない」プログラム例や解説を見かけるのです。

なぜ「n - 1」なのかは、このタイミング図を見れば分かるかと。
A1_20200204115801
TOP値がOCR:コンペアレジスタへの設定値。
そして、CTCモードだとBOTTOM値はゼロになります。
TOP値を検出した次のサイクルがゼロとなるわけです。

例えば「1/4」したい時、TOP値つまりコンペアレジスタの値を
「4」にしてしまうと・・・
0 1 2 3 4  0 1 2 3 4  0・・・」と繰り返しが「5」になってしまいます。
TOP値としてOCRに設定するのは「カウント周期 - 1」でなければいけません。
「-1」しないと、「1/4」が欲しいのに「1/5」になってしまうという
スカタンが発生します。

これに気付かない原因の推測ですが、
・とりあえず、それらしい動きをしてるから。
・16ビットタイマーであるタイマー1に対して、大きな値をセットしてる。
 そのままの値と-1した場合とで、タイマー周期にほとんど違いが出ない
 から気がつかない。
・8ビットタイマーでも、ミスを測定する手段を持ってない、あるいは
  積極的に結果を計ろうとしていない。
   ※周波数カウンタやオシロスコープなどの測定器をつなぎ
    テストパルスを出せばすぐに気がつくはず。
・ハードウェアの非同期カウンタを思い浮かべている。
   ※1/10カウンタなら、7→8→9→[10=0]→1→2→
    と、10検出で直ちにリセットされて0になるので。

こんなところかと。

※見かけたミスの例
ArduinoのTimerを初心者が1からなんとなくわかるためのメモ - Qiita
  16MHzクロックを1/256し、「OCR1A = 62500;」として「1秒」としている。
Arduinoでtimerを使った割込み処理の方法 ? 自作のいろいろ
  「OCR2A=100; //100カウントごと(50μs)毎」と。。。
Timer1 - FreeStyleWiki
  ちょっと違う。
タイマー割り込みを使う - arduino始めました
  惜しいような。。。
Timer0 & 1
  アセンブラでもミス。

多くの正しい解説もありますが、ミスしたのが目立っちゃいます。

そして、もうひとつ気になるのが割り込み処理内で走らせるプログラム。
「呼んですぐに戻ってくる関数」が基本。
そして、それがメインの処理とぶつからないこと。
他の割り込み処理に影響(長い時間待たせる)を与えてもダメ。
割り込みの中で「Serial.println(xxx)」を使ってる例を見かけるのですが、
これはいかがなものかと・・・。


| | コメント (2)

« 2020年1月 | トップページ | 2020年3月 »