« 2025年8月 | トップページ | 2025年10月 »

2025年9月

2025年9月30日 (火)

ATtiny1614に時計用水晶発振子をつなぐ

同じ14ピンでもATtiny1604(やtiny804、tiny404
などのtinyAVR0系統)は時計用水晶発振回路を持っ
ていません。
32kHzの発振回路は内蔵してるのですが、時計と
して使うには精度が不十分です。
マイコン自身では発振できないので、精度の良い
クロックが欲しい時は別置きの発振器から外部
クロックを突っ込むしかありません。

対して、tinyAVR1シリーズになると、時計用の
水晶を発振できる発振回路を搭載しています。
精度の良いクロックがあれば、時計や周波数カウンタが
作れます。

ATtiny1614を使って、その動作を確かめてみました。
・32.768KHz水晶発振回路の始動方法。
  データシートにはややこしいことが
  書いてあるけど、リセット起動なら
  簡単に始動。
・発振周波数の確認方法。
  発振させた32.768kHzは直接取り出せない。
  イベントシステムを使ってRTCのオーバー
  フロー信号をイベント出力0(ポートPA2)に
  出して周波数を確認。(1/2の16.384kHz)
・発振安定タイミング確認のためポート出力。
・PITの動作確認のため1024Hzをソフトで出力。

こんな回路です。
Tt14_20251002175801
PA2を周波数カウンタ読むと16.38418kHzだったんで、
「+11PPMほど」の周波数でした。

制御スケッチ。 Arduino IDE環境です。

//  ATtiny1614 (14pin)
// 32.768kHz水晶の発振を確認
/***** RTC,PIT busy待ち *****/
// 両方とも0になるのを待つ
void rtcbusy(void) {
while((RTC.STATUS & 0x0F) || // RTC busy ?
(RTC.PITSTATUS & 1)); // PIT busy ?
}
/***** SETUP *****/
void setup() {
cli(); // 割込禁止
PORTA.DIR = 0b11111110;
// |||||||+---- PA0 10pin UPDI
// ||||||+----- PA1 11pin loopでHに
// |||||+------ PA2 12pin EVOUT0(16384Hz)
// ||||+------- PA3 13pin PITパルス(1024Hz)
// |||+-------- PA4 2pin 発振安定でH
// ||+--------- PA5 3pin
// |+---------- PA6 4pin
// +----------- PA7 5pin
PORTB.DIR = 0b00000011;
// |||+---- PB0 9pin out
// ||+----- PB1 8pin out
// |+------ PB2 7pin TOSC2 32.768kHz
// +------- PB3 6pin TOSC1 XTAL
// 32.768kHz XTAL
// _PROTECTED_WRITE(CLKCTRL.XOSC32KCTRLA, 0x00); // XTALオフ
// while(CLKCTRL.MCLKSTATUS & (1 << 6)); // XOSC32KSの0を待つ
// リセット起動なら↑の手順は不要 いきなりオン↓でOK
_PROTECTED_WRITE(CLKCTRL.XOSC32KCTRLA, 0b00000001); // 発振イネーブル
// || ||+-- ENABLE
// || |+--- RUNSTBY
// || +---- SEL
// ++------ CSUT 1kサイクル
// CSUT 01で16kサイクル、10で32k、11で64kサイクルの起動時間待ち
// RTC,PIT
rtcbusy(); // RTC,PIT ビジー待ち
RTC.CLKSEL = 0b00000010;
// ++---- XOSC32K 32.768kHzHz
RTC.CTRLA = 0b00000001;
// ||||| +---- RTCEN RTC周辺機能許可
// |++++------- CLK_RTC 1/1 →32.768kHz
// +----------- RUNSTBY
RTC.PER = 2 - 1; // 1/2 →16.384kHz
RTC.PITCTRLA = 0b00011001;
// |||| +-- PITEN PIT有効
// ++++----- PERIOD 32768Hz/16 →2048Hz
// RTCのオーバーフローをPA2(EVOUT0)に出力 16.384kHz
PORTMUX.CTRLA = 0b00000001; // PA2ポートをEVOUT0に
EVSYS.ASYNCCH1 = 0x08; // ch1入力:RTC_OVF
EVSYS.ASYNCUSER8 = 0x04; // ch1出力:EVOUT0(PA2:12pin) 出力
sei(); // 割込有効
}
/***** LOOP *****/
void loop() {
PORTA.OUTSET = (1 << 1); // PA1(11pin)をHにしてloopに来たことを通知
// RTC安定待ち
while(!(CLKCTRL.MCLKSTATUS & (1 << 6))); // XOSC32KSの1を待つ【1】
PORTA.OUTSET = (1 << 4); // PA4(2pin)をHに
while(1){
if(RTC.PITINTFLAGS & 1){ // PIT 2048Hz
RTC.PITINTFLAGS = 1;
PORTA.OUTTGL = (1 << 3); // PA3:13pinトグル (1024Hz)
}
}
}

とりあえず32.768kHzの発振ができるようになりました。
このクロックを使って何をするかは・・・これから考えます。

※発振タイミングのオシロ波形

電源オンから発振開始まで
Ca000_20251001084001
  (安定待ち=16kサイクルで)

発振安定から波形出力まで
Ca002_20251001084101

実験用手組み基板
Cc21_20251001084101

※ATtiny1614のタイマ・カウンタ、ちょっと不便なところが
 あります。
 周波数カウンタを作ろうとすると・・・
・16bitのタイマBで周波数計測機能があるんだけど、オーバーフローの
 検出ができないんで、カウント数を上げられない。
・タイマBのクロック入力はタイマAからイベントリンク機能で引っ張って
 来なくちゃならない。
・カウントクロックが無いと、キャプチャパルスを認識してく
 れない。
・タイマDは周波数カウントに使える機能があるんだけど、
 12bit(4095カウント)。

※注
リストの【1】の部分、XOSC32KS(発振安定)のチェックは、
32kHzクロックをどこかのモジュールが使い初めてからしか
チェックできない。使い始める前は「0」になっている。

※注意
2025年10月6日:ATtiny1614につないだ32kHz水晶発振子、隣のピンの影響を受けるみたい

| | コメント (0)

2025年9月29日 (月)

RTC機能付ATtiny RTCとPITの初期化注意点

RTC(リアルタイムクロック)の使用方法、
こんな注意点が記されています。

 注: RTC周辺機能はデバイス始動の間で内部的に
 使われます。
 常に及び初期構成設定で、状態(RTC.STATUS)
 と周期割り込み計時器状態(RTC.PITSTATUS)
 のレジスタで同期中多忙ビットを調べてください。


RTCとPITは「ビジーをチェックしてから触るんだ」っと。
関連するのはこのレジスタ。
Pi10
Pi11_20250929102001
RTCが4つ。PITが1つ。
Hならビジーで、Lになるのを待つ。

電源オン時、どのくらいの待ちが生じるのか調べて
みました。
こんなスケッチ。 (チップは14ピンのATtiny404)

//  ATtiny404 (14pin)
// I/O MACRO
#define PA5_H PORTA.OUTSET = (1 << 5); // PA5 3pin H/L
#define PA5_L PORTA.OUTCLR = (1 << 5);
#define PA6_H PORTA.OUTSET = (1 << 6); // PA6 4pin H/L
#define PA6_L PORTA.OUTCLR = (1 << 6);
/***** SETUP *****/
void setup() {
VPORTA.DIR = 0b11111110;
// |||||||+---- PA0 10pin UPDI
// +++++++----- PA7~PA1 out
VPORTB.DIR = 0b00001111;
// ++++---- PB3~PB0 out
PA5_H; // 3pin H
}

/***** LOOP *****/
void loop() {
if((RTC.STATUS & 0x0F) || // RTC busy ?
(RTC.PITSTATUS & 1)){ // PIT busy ?
PA6_H; // 4pin H/L
}
else{
PA6_L;
}
}

I/Oポートの初期化完了でPA5をH。
RTCとPITがビジーならPA6をH。
レディーならPA6をLに。
こんな波形が得られました。
Im000

電源のオン・オフを繰り返してビジー時間の変動を見ています。
Im001
Im002

ビジーをチェックせずにRTCを初期化しようとすると
失敗してちゃんと動きません。
初期化成功後のアクセスでビジー/レディー状態がどう
なるのかはもうちょいスケッチを触らなくちゃなりません。

| | コメント (0)

2025年9月26日 (金)

ATtinyのデータシートに「1/1023」が出現

ArduinoのA/D変換値(10bitなら0~1023)から
入力電圧を求めるときは「1/1024」でっせを
何度も言ってきました。
   トラ技にも書いたし。
ところが・・・
8ピンのAVRマイコン「ATtiny402」のデータシート
を見ていたら「1/1023」になっていたのです。

まずこれがArduino UNO R3のマイコンATmega328Pの
データシートでの記述。
正しく「1/1024」です。
T13_20250926090601

それがATtiny402(202~406まとめての)のデータシート
では「1/1023」と示されているのです。
T11_20250926090601

追跡しきってはいませんが、「アトメル」時代からあるチップは
正しく「1/1024」と。
「マイクロチップ」になってからできたチップが「1/1023」と
なっているような感じかと。

※追記 3・1/2桁電圧計IC(モトローラのMC14433)の資料から
大昔のデータシートを引っ張ってきました。
モトローラの3・1/2桁電圧計IC、BCDでの表示出力が±1999。
  ※関連
   ・1/2桁とは
   ・1/2桁とは 「セグメント説」
基準電圧が2.000Vだと±1.999Vがフルスケール。
0.2000Vだと±フルスケールは1999mVになります。
このあたりの関係、データシートではこのように
表現されています。

14433a
ごくあたりまえですが、このVref=2.000Vで
1.000Vが入力されたら
表示出力は1.000Vになります。
(1.000V ÷ 1.999) × Vref = 1.00050V
ではありません。
  出力桁外になる0.00050VがこのICで
  どういう挙動になるかは別問題。
(1.000V ÷ 2.000) × Vref = 1.000V
がまっとうな計算。
  Vrefがジャスト2.000Vじゃないとき、
  入力電圧に対して何Vが表示されるか
  の検証計算。

| | コメント (2)

2025年9月25日 (木)

東芝インパルスTNH-3LEとFDK HR-AAULT

東芝インパルスTNH-3LE(950mAh)とFDK HR-AAULT(1000mAh)
JIS C8708:2024充放電実験のその後です。

Bb12_20250925160101
Bb11_20250925160101

TNH-3LEは3200サイクルを終えてそろそろ寿命かという
ところです。
Cap001_20250925160101
0.5C放電での放電時間(1.0Vまでの)が、寿命判断の
72分(定格の60%)を切っています。<緑線>
でも、0.2C放電での3時間はまだ大丈夫なので、
もう1スパン(400サイクル)、頑張ってみます。

FDK HR-AAULTは5200サイクルを通過。
まだまだ大丈夫そう。
Cap002_20250925160201
両電池とも、400サイクルごとに電池を電池ホルダーから
外して内部抵抗を計っていました。
そして、計測後の電池再装着をミス。
  清掃したつもりがちゃんとしてなかった。
  HR-AAULTは端子形状が不通の電池より短い
  ので電池ホルダー電極の接触がちょっと。
その1スパン400サイクルの間、接触が不安定に
なりデータがおかしくなっています。
測定をやり直すのも時間がかかるしということで、
そのまま充放電を続けています。

  TNH-3LEは2024年10月スタート
  HR-AAULTは2022年9月スタート

| | コメント (1)

「AD549」のチップ写真

ちょいと仕事がらみで「AD549」(超低入力バイアス電流品)を
調べていたら、こんなページに遭遇。
  ・https://www.richis-lab.de/Opamp61.htm
きれいなチップの写真に感激。

超低入力バイアス電流のオペアンプ、推奨品は電源電圧範囲
が低いし・・・

オペアンプがいっぱい
  ・https://www.richis-lab.de/Opamp.htm


| | コメント (0)

2025年9月24日 (水)

伊能忠敬・万歩計 水没!

水没させてしまった「万歩計」の修理依頼。
  (水没原因は洗濯とのこと)
画面は出るけどスイッチ操作できないという症状。
新・平成の伊能忠敬」とロゴが入っています。
Hh10
2017年製。
山佐時計計器」製なので「万歩計」の呼称はOK。
  ※一般呼称は「歩数計」
Hh12_20250924101101
  圧電振動板への配線が切れてました
Hh12a
操作スイッチは3つ。
導電ゴムではなく、凹状スイッチ金属板で金メッキさ
れたパターンを押すという構造。
金属板の上から樹脂シールで押さえられていました。
この操作スイッチの基板パターンとに金属板に
水没による腐食が見られました。
Hh13_20250924101301
Hh14_20250924101301

他のパターンの銅箔や電池電極には「サビ」が若干
出ていましたが、接続が切れるほどではありません。
IPAできれいに洗浄して修理完了。
スイッチ操作でこんな画面が出てきます。

Hh16
頑張って歩けば日本地図ができあがるようです。
Hh15

操作説明書(pdf)

| | コメント (0)

2025年9月18日 (木)

スイッチサイエンスさん扱い「配線チェッカー」

2025年8月21日:「配線チェッカー」スイッチサイエンスさんで扱い開始
で、紹介しました
 ・SKU 10550:配線チェッカー
初回ロット、売り切れとのこと。

お代が税込2万2千円とちょっとお高いのですが・・・
現場での使用感などお聞きしたいところです。

※これ、電子回路屋の私は日常的には使いません。
 100V、200Vを使う制御回路の配線チェックでも
 私が扱うような回路では今までの導通チェッカー 
 で十分なのです。
 でも、直流抵抗値が小さな電源トランスや電流計が含
 まれる回路の配線チェックでは、この「配線チェッカー」が
 役に立つでしょう。

前の記事にも書きましたがCT接続の交流電流計、
それが、
  直流抵抗ざっと0.03Ω。
  インダクタンスがおよそ16μH。
このメータを介しての「つなぎを判断できれば」という
要望だったわけです。
直流では無理。
5kHzだと0.5Ωくらいのインピーダンスになり、なんと
か判別できるかというところまで追い込めました。

最初1kHzだった駆動周波数を5kHzまで上げてなんと
かなったという次第です。

導通チェック判断レベルを調整するボリューム、
これを外に出したのも、チェック用のリード線を
延長したときの補正のため。
(大きな盤だと数m以上延ばすこともあると)
  アナログテスターの抵抗レンジには
  ゼロ調ボリュームがついてるでしょ。
  この感覚です。


| | コメント (0)

2025年9月16日 (火)

リコーGX200でもAWB異常が出現

 ・2007年7月にやってきたリコーGX100
がアウトになってGX200の中古品を手に入れたのが
 ・2022年7月18日:リコーGX200の中古品を入手
その後、半年ほど前に
 ・2021年12月20日:リコー「GXR+S10」がやってきた 中古だけど
を安価で入手してました。

発売日を見ると、
  GX100  2007年4月
  GX200  2008年7月
  GXR   2009年12月

やはり、新しいGXRのほうがキビキビ使えると
GX200の出番はほとんどありませんでした。
 ・GX100で便利だったリングライトが同じように使える
ので、ややこしいものの撮影には便利。

GX100で困っていたのが、AWBの異常
 ・リコーのデジタルカメラ「Caplio GX100」の自動ホワイトバランス異常
現象再現にたいそう時間をつぶしました。
結果、撮影場所の蛍光灯が問題だというのが判明。
にっくき「白色蛍光灯」。

その後、仕事場もガレージも蛍光灯が入れ替わり
昼光色」になったのでGX100・AWBでの異常遭遇は
ほんとに無くなりました。

そして、GX100が引退して、GX200になったのですが、
主力がGXRになったので、GX200の出番はほとんど無しに。
ところが・・・
 ・ラジオペンチさんの「ダイソーのゆらゆらLEDキャンドルライト」#2
で、「三つ編み」の話に「ドリルで電線ねじり」で
参戦しようとしたら、
  ありゃま、GX200でAWBの異常発生!
となったのです。
並べると一目瞭然。
Cc01_20250916102001
照明はGX100で大丈夫だった昼光色蛍光灯。
撮影条件、ほとんど変わっていません。

 【上】
 ISO感度    100
 対象物の明るさ  4.60
 焦点距離     10.1mm
 レンズ絞り値   3.36
 露出時間     1/64秒

 【下】
 ISO感度    100
 対象物の明るさ  4.60
 焦点距離     10.1mm
 レンズ絞り値   3.40
 露出時間     1/64秒

絞りがほんの少し違うだけ。
カメラの向きもほぼ同じ。
昼光色蛍光灯で解決したGX100のAWB異常、
それがGX200になって再発のようです。
困ったぞ!

| | コメント (0)

2025年9月15日 (月)

ラジオペンチさんの「ダイソーのゆらゆらLEDキャンドルライト」#2

ラジオペンチさんの「ダイソーのゆらゆらLEDキャンドルライト」
3ch出力にした回路をでっち上げました。
Photo_20250915170901
図では出力コネクタが3つですが、2パラにして
(抵抗の左から分岐)合計6つのキャンドルを駆動
できるようにしました。
Cd21
  LEDの色を変えたのを追加
  VF=3Vほどの高輝度タイプは青と緑
  しか手持ちがなかった。
  元の橙色LED、発光角が広いのでしょう、
  手持ちの青と緑と違って「ろうそくの中」
  までエエ感じで光っています。
  青と緑の、中を照らすLEDを増設しようかしら。

LEDの直列抵抗、値を小さくして最大10mAほど
流れるようにしています。
  (ラジペンさんの回路だと560Ω)

Arduino UNO環境ですが、発振子無し
内蔵8MHzクロックで動かしています。
ATmega328Pに8MHz用ブートローダを書いて、
ヒューズを内蔵8MHzにしなくちゃなりません。

そして、Arduino IDEのボード選択を"UNO"ではなく
"Arduino Pro or Pro Mini"を選び、
プロセッサを
 "ATmega328p (3.3V,8MHz)"にします。

これで発振子無しの8MHzで動いてくれるはず。
  ・ダウンロード - candle01b.txt
    テキストファイル(UTF8N)にしてます
スケッチをアップできて、115.2kBPSで通信が
できてれば大丈夫じゃないかしら。
  PB5のLEDは0.2秒ちょい周期で点滅。

スケッチそのものは、8MHzも16MHzも変わりま
せんので、Arduino UNO R3環境でも手直しなしで
動作します。
  このあたり、たいへん便利なんですが、
  昔人間が思うところ・・・
   「どこでその違いを補正してるねん」
  が気になって、「16MHz→8MHzでも
  動くでぇ~」が「ほんまかいな」状態で
  落ち着きません。
  F_CPUが駆動周波数を示しています。
  それを「誰が(どのファイルが)、どこで(どのフォルダで)
  決めてるねん」をつかんでおきたいのですが、
  ワケワカメ。

元の基板のチップ部品3つを取り去り2つを間をジャンパ。
ダイオードもこの基板のコイル端子にハンダして3本の
電線を引き出しています。
Cd22

ゆらゆらキャンドル、「出窓」 へのデビューは女房次第でっす。
  『まだ「夏」のまんまやしなぁ~』
なんて言っとりましたんで。


そしてそして・・・
  ラジペンさんの「三つ編みケーブル」。
こちらでは手抜きで、ドリルを使って
電線をよじっています。
Cd24
チャックで電線を挟み込み、ギュイ~ン。
完成。
Cd25
  ※GX200で写したんだけどホワイトバランスに差がぁ。

| | コメント (4)

2025年9月14日 (日)

リコーのデジカメGXR+S10 寿命か!?

2021年12月、中古で買ったリコーの「GXR+S10」
先日来、調子が良くありません。
G10_20250914144301
うまく写るときもあるのですが、こんな具合に
横縞が発生することがあるのです。
G12_20250914144301

これは最大画素(横3648ドット)から中央の
640x480ドットを切り抜いたもの。
横線が走っているでしょう。
本体とレンズ部をつなぐ接点を清掃してもダメ。

これまでどおり、普通に撮れることもあるのですが
 ・ズームを望遠側に
 ・まわりが暗いとき
にこの横縞発生が起こりやすいようです。

画像サイズを横1280縦960にして撮ると、こんな具合。
G11_20250914144401

手ぶれ補正をオンにすると、ますますひどく。
G14_20250914144401

露出もおかしく(露光過多)なります。
ISO感度をさわってもダメ
撮影モード「PASM」を変えてもダメ。
ズームを広角にして撮るとちゃんと写る
割合が大きくなる感じです。

製作物の撮影に便利に使ってきたのですが、寿命が
きたのかと。

2022年7月:リコーGX200の中古品を入手
ということで、GX200もあるのでこれまでどおりに
小物の撮影はできるのですが、GXR+S10のほうが
キビキビ写せます。

古いカメラだし、どうしたものか・・・

※追記
この「GXR+S10」では2022年9月に
 ・リコーのデジカメ「GXR+S10」「シアンの横線」
こんなトラブルが発生しましたが、電源オフで解消。

もっと昔、GX100ではこんな「異常」も。
 ・リコーGX100 突然の二段表示
   これはなかなかの「お笑い」現象。
 ・リコーGX100 さっき撮った1枚の中に・・・


※さらに追記
本体とレンズユニットを何度か抜き差ししていたら、
レンズユニットを認識しなく(カードの画像データ
再生しかできなく)なって、写せない状態になって
しまいましたゾ。
G31
コネクタを清掃してもだめ。

| | コメント (0)

2025年9月11日 (木)

ラジオペンチさんの「ダイソーのゆらゆらLEDキャンドルライト」

ダイソーのゆらゆらLEDキャンドルライト(1/f ゆらぎに改造):ラジオペンチさん
「出窓」に面白そうと、ご近所のダイソーを3軒探したの
ですが、見つからず。
やむを得ず、ダイソーの通販に注文しました。
  送料がかかるけど・・・単3Looperもいっしょに
Cc11_20250911093901
  ※しかし・・・今朝見たら、商品ページが消えてました。
    ちゃんと届くのか不安がぁぁ

ラジオペンチさんのArduino UNOによる駆動系、
せっかくですんで使えるPWM出力6つを全部使って、
3つのキャンドルライトを駆動できるようにスケッチを
手直ししてみました。

・PWM出力チャンネル番号をテーブルに。
・明るさデータを3つの配列に。
・3chのループを回して独立して処理。
・「チラツキ防止のため、10回に分けて」
 「補間1ステップ時間(全体ではこの10倍)」
 は、loopの一番外側に「for(i = 1」を持ってきて
 コイル駆動は i = 1のときだけにして、LED処理
 は毎回で、というふうに。

// ラジオペンチさん:
// ダイソーのゆらゆらLEDキャンドルライト(1/f ゆらぎに改造)
// http://radiopench.blog96.fc2.com/blog-entry-1355.html
// 20250908_LedCandleCaosMethod.ino
// カオス方を使った 1/f ゆらぎを持つLEDキャンドル
// 2025/9/8 ラジオペンチ
// 9/11 3ch出力に改造:居酒屋ガレージ店主(JH3DBO)
byte COIL_PIN[] = { 6, 9, 11 }; // コイル駆動PWM出力 3ch
byte LED_PIN[] = { 5, 10, 3 }; // LED駆動
float xx[3] = { 0.7, 0.7, 0.7};
float last_xx[3];
float xxx[3];

void setup() {
Serial.begin(115200);
pinMode(13, OUTPUT); // LED
Serial.println("Start ");
}

void loop() {
PINB |= (1 << 5); // PB5 LED on/off
for (int i = 1; i <= 10; i++) { // チラツキ防止のため、10回に分けて、
for (byte j = 0; j < 3; j++){ // 3ch loop (0,1,2)
if (i == 1){ // 10loopの最初だけ実行
xx[j] = fluctuate(xx[j]); // カオス法で新しい明るさを決定
Serial.print(j);
Serial.print(", ");
Serial.print(xx[j]);
Serial.print(", ");
// コイルに通電して炎の板を揺らす
xxx[j] = last_xx[j] - xx[j]; // 明るさの差(減光量)が、
if (xxx[j] > 0.15) { // 一定値を超えていたら(値は要調整)
analogWrite(COIL_PIN[j], 255 * sqrt(xxx[j])); // コイルに通電
//(sqrtは値を1に近付けるため)
Serial.println(sqrt(xxx[j]));
} else { // 超えてなければ
analogWrite(COIL_PIN[j], 0); // コイル通電OFF
Serial.println(0);
}
}
// LEDの明るさを変える (i=1~10)
xxx[j] = last_xx[j] + (xx[j] - last_xx[j]) * i / 10.0; // 指定値まで直線補完で、
analogWrite(LED_PIN[j], 70 + xxx[j] * 180); // LEDの明るさを設定
last_xx[j] = xx[j];
}
delay(10); // 補間1ステップ時間(全体ではこの10倍)
}
}

float fluctuate(float x) { // 間欠カオス法で 1/f波形を生成
if (x < 0.5) { // 0.5以上なら
x = x + 2 * x * x; // 2x^2で徐々に増加
} else { // 0.5以下なら
x = x - 2 * (1.0 - x) * (1.0 - x); // 2(1-x)^2で徐々に減少
} //
if (x < 0.05 || x > 0.95) { // 結果が上下限を外れていたら、
x = random(100, 900) / 1000.0; // 乱数で0.1-0.9の範囲に戻す
}
return x;
}

こんな具合にスケッチはできたけど、キャンドルライトが
来ないことには試運転もできません。
  出力パルスをオシロで見てるだけ。

商品ページが消えてしまったキャンドルライト、
はたしてちゃんと届くのでしょうか。

※PWM出力の順番
 コイル駆動PWM出力 : 6, 9, 11
 LED駆動PWM出力 : 5, 10, 3 
これはATmega328Pにある3つのタイマーユニット
出力のペアに合わせてるので飛び飛びになってます。
  OC0A 6
  OC0B 5
  OC1A 9
  OC1B 10
  OC2A 11
  OC2B 3

※3ch版、完成形に
ラジオペンチさんの「ダイソーのゆらゆらLEDキャンドルライト」#2
  出窓へのデビューはいつになりますか・・・

| | コメント (1)

2025年9月 9日 (火)

ATtiny402サンプル:"Wire.h"を使わずI2Cで液晶表示 AQM1602だと

ATtiny402サンプル:I2Cで液晶表示 SCL周波数を設定できるようにしたら
で使った液晶AC0802は、コントラストを外付け
ボリュームで調整します。

AQM1602Y-NLW(FLW、FLB)やAQM1602XA-RNは
内部レジスタの操作でコントラストが変わります。

電源電圧3.3Vなら内部ブースター回路をオンに
して、液晶の駆動電圧を上げるので、5Vで使う
時とで微妙にコントラストが変わりますが
両方とも「35」あたりでOKのようです。

バックライト付のAQM1602Y-FLW-FBWを試したのが
このページ。 ※ずいぶん前だぁ
 ・秋月電子16文字x2行のI2Cインターフェース液晶AQM1602Y

今回はATtiny402でバックライト無しの
AQM1602Y-RN-GBWを試してみました。
  電源電圧は3.3Vでこんな回路。
Sch21
VRを回すとコントラストが変わります。
Cc01_20250909165301

※制御スケッチ
  ・ダウンロード - lcd_test2a.zip
    ※BCD変換ルーチンを別ファイルにしてあります。

これで、
  スケッチが1537バイト(37%)
  グローバル変数が37バイト(14%)
というメモリー使用量。

"Wire.h”をやめたおかげでRAMへの圧迫が
取り除かれています。

初期化のところで、文字数と行数、SCL周波数、
電源電圧を設定します。

  LCD.begin(16, 2, 100, LCD_V3R3);
   // I2C液晶 ★wire.hは使わない
   // 液晶初期化 16文字x2行,100kHz,3.3V
   // (5V:LCD_V5R0,3.3VならLCD_V3R3に)

3.3Vならブースター回路をオン。
5Vならオフに。

tiny402の動作周波数はArduino IDEの画面で設定
します。
3.3V動作なら10MHzが最大。
Ide02

電源電圧5Vでは必ず電圧ブースターをオフにという
のが注意点です。
  LCD.begin()での電圧設定をLCD_V5R0
  にしたらオフになります。

Arduinoでのアナログ入力といえば「analogRead() 」ですが、
tiny402には連続変換モード(自由走行という表現)というのが
あって、変換を始めたらいつでも最新値を読み出せるのです。
  入力チャンネルを切り替えるとなると
  タイミングがちょっとややこしいけど。
累積加算の機能と合わせて、割り込みで処理しなくて
良いのでなかなか便利。

もうひとつ。
内蔵クロック32.768kHzベースのRTCタイマに付随する
PIT(Periodic Interrupt Timer)が、メインクロック周波数が
変わっても一定時間を数えてくれるので、これも便利。
  通常はF_CPUで動作クロックが分かるのですが、
  例えばこのサンプルでは0.25秒(1/4秒)サイクル
  でPITフラグが立つようにしています。
  メイン周波数が変わっても、一定タイミングが
  得られます。
    delay()を使わなくてもエエんです。

| | コメント (0)

ATtiny402サンプル:I2Cで液晶表示 SCL周波数を設定できるようにしたら

ATtiny402マイコン サンプル:I2Cで液晶表示(Wire.hを使わないで)
これの続き。

I2C液晶、スペックを見ると電源5VならSCL周波数は
400kHzに対応しています。
そこで・・・液晶の文字数・行数をセットするときに
SCL周波数をセットできるようにしてみました。

//  I2C液晶
LCD.begin(8, 2, 400); // 液晶初期化 8文字x2行,SCL=400kHz

設定処理はこんな具合。
  WIFビットのタイムアウトチェックは無くしました。

/*****  TWI 初期化      *****/
// _scl_frq(kHz)からTWI周波数を設定
// MBAUD = F_CPU/2/fSCL - 5
void i2c_lcd_acm0802_tn::twiInit()
{
int16_t d;
// TWI0.MBAUD = 50; // TWI SCL周波数設定
// CPUクロックから計算してみる
d = F_CPU / 1000; // CPU クロック周波数(kHz)
d = (d / 2 / _scl_frq) - 5; // F_CPU/2/fSCL-5
if(d < 0) d = 1; // 1~255
if(d > 255) d = 255;
TWI0.MBAUD = d; // TWI SCL周波数設定
TWI0.MCTRLA = 0b00000001;
// || ||||+----- ENABLE 主装置許可
// || |||+------ SMEN 簡便動作しない
// || |++------- TIMEOUT 使わない
// || +--------- QCEN 迅速指令 しない
// |+----------- WIEN 書き込み割り込み なし
// +------------ RIEN 読み込み割り込み なし
TWI0.MSTATUS = 0b00000001;
// ||||||++----- BUSSTATE アイドル状態に
// |||||+------- BUSERR
// ||||+-------- ARBLOST
// |||+--------- RXACK
// ||+---------- CLKHOLD
// |+----------- WIF
// +------------ RIF
}
/***** TWI 書込み送出開始 *****/
void i2c_lcd_acm0802_tn::twiStartW(uint8_t adrs)
{
TWI0.MADDR = adrs << 1; // アドレス 書き込みで(0)
while(!(TWI0.MSTATUS & TWI_WIF_bm)); // WIF=1を待つ
}
/***** TWI データ書き込み *****/
void i2c_lcd_acm0802_tn::twiWrite(uint8_t data)
{
TWI0.MDATA = data; // データ書き込み
while(!(TWI0.MSTATUS & TWI_WIF_bm)); // WIF=1を待つ
}
/***** TWI 送出終了 *****/
void i2c_lcd_acm0802_tn::twiStop()
{
TWI0.MCTRLB = TWI_MCMD_STOP_gc; // Stop Condition
}

メイン側の記述でSCL周波数が設定できてエエかな
っと思ったのですが、「割り算」が入るので、単純に
「TWI0.MBAUD」に値を書くだけの元のに比べると
「90バイト」ほど肥大してしまいました。

ここらは目をつぶってSCL周波数を設定できるほうが
便利になるかと。
  100kHz→400kHzにしたら液晶表示のための
  処理速度が1データの書き込み単位で4倍に。

※スケッチ全体の様子
  ・ダウンロード - lcd_test1a.zip
    上で示したのとはちょっと変えてます

※表示画面
At41
回路図はこの記事の
 ・ATtiny402マイコン サンプル:I2Cで液晶表示

| | コメント (0)

2025年9月 8日 (月)

ATtiny402マイコン サンプル:I2Cで液晶表示(Wire.hを使わないで)

ATtiny402マイコン サンプル:I2Cで液晶表示 この続き。

ATtiny402での液晶表示、ちょっとでも「軽く」する
(メモリ使用量を減らす)ため、"Wire.h"を使わない
液晶表示ルーチンを仕立ててみました。

■LCD_TEST0 : "Wire.h"を使った場合

// "Wire.h"を使ってのACM0802液晶テスト
// ATtiny402 20MHz Arduino IDE環境
// PA0 6pin UPDI
// PA1 4pin - SDA I2C液晶
// PA2 5pin - SCL I2C液晶
// PA3 7pin out
// PA6 2pin out
// PA7 3pin out
// ボードマネージャー:
// http://drazzy.com/package_drazzy.com_index.json
#include "Wire.h" // I2C ACM0802液晶
#include "i2c_lcd_acm0802.h" // LCD制御ヘッダーファイル
i2c_lcd_acm0802 LCD(0x3C); // LCD I2Cアドレスを設定
/***** SETUP *****/
void setup() {
cli(); // 割込禁止
PORTA.DIR = 0b11001000; //ポート出力指定
// || |||+---- PA0 6pin UPDI
// || ||+----- PA1 4pin in SDA
// || |+------ PA2 5pin in SCL
// || +------- PA3 7pin out
// |+---------- PA6 2pin out
// +----------- PA7 3pin out
// PIT 1秒タイミング
RTC.CLKSEL = 0b00000001;
// ++---- INT1K 1024Hz
RTC.CTRLA = 0b00000001;
// ||||| +---- RTCEN RTC周辺機能許可
// |++++------- CLK_RTC DIV1 1/1
// +----------- RUNSTBY
RTC.PITCTRLA = 0b01001001;
// |||| +-- PITEN
// ++++----- PERIOD 1/1024 →1秒
// I2C液晶
Wire.begin(); // I2C開始
LCD.begin(8, 2); // 液晶初期化 8文字x2行
}
/***** LOOP ******/
void loop() {
byte c = '0';
LCD.setCursor(0, 0); // LCD上段
LCD.strdisp("Test LCD"); // タイトル
while(1){
if(RTC_PITINTFLAGS & 0x01){ // 1秒経過
RTC_PITINTFLAGS = 1; // PIフラグクリア
LCD.setCursor(7, 1); // LCD右下段
LCD.write(c); // 0~9
c++;
if(c > '9') c = '0';
}
}
}

結果。
  スケッチが1523バイト(37%)
  グローバル変数が100バイト(39%)

~~~~~~~~~~~~~~~~~~~~~~~~~~
■LCD_TEST1 : "Wire.h"を使わない場合

// "Wire.h"を使わないACM0802液晶テスト
#include "i2c_lcd_acm0802_tn.h" // LCD制御ヘッダーファイル
// ★wire.hは使わない
i2c_lcd_acm0802_tn LCD(0x3C); // LCD I2Cアドレスを設定
/***** SETUP *****/
void setup() {
cli(); // 割込禁止
PORTA.DIR = 0b11001000; //ポート出力指定
// || |||+---- PA0 6pin UPDI
// || ||+----- PA1 4pin in SDA
// || |+------ PA2 5pin in SCL
// || +------- PA3 7pin out
// |+---------- PA6 2pin out
// +----------- PA7 3pin out
// PIT 1秒タイミング
RTC.CLKSEL = 0b00000001;
// ++---- INT1K 1024Hz
RTC.CTRLA = 0b00000001;
// ||||| +---- RTCEN RTC周辺機能許可
// |++++------- CLK_RTC DIV1 1/1
// +----------- RUNSTBY
RTC.PITCTRLA = 0b01001001;
// |||| +-- PITEN
// ++++----- PERIOD 1/1024 →1秒
// I2C液晶
// Wire.begin(); // I2C開始 ★wire.hは使わない
LCD.begin(8, 2); // 液晶初期化 8文字x2行
}
/***** LOOP ******/
void loop() {
byte c = 'A';
LCD.setCursor(0, 0); // LCD上段
LCD.strdisp("Test LCD"); // タイトル
while(1){
if(RTC_PITINTFLAGS & 0x01){ // PIT 1秒経過
RTC_PITINTFLAGS = 1; // PIフラグクリア
LCD.setCursor(7, 1); // LCD右下段
LCD.write(c); // A~Z
c++;
if(c > 'Z') c = 'A';
}
}
}

結果。
  スケッチが773バイト(18%)
  グローバル変数が14バイト(5%)

8文字×2行の液晶、1行目にタイトルを表示して
右下に1文字の数字(TEST0)あるいは大文字英字
(TEST1)を1秒サイクルでインクリメント。

例題の違いはWire.hを使うか使わないか。
TEST0の下請けルーチン、i2c_lcd_acm0802は
これまでどおりにWire.hとtwi.hで制御。

TEST1のi2c_lcd_acm0802_tnはtiny402の
TWIレジスタを直接操作。
手抜きで、I2Cの制御にエラーが生じても(ACKが来ない
ゾ)そこでストップさせずにそのまま最後まで進んじゃ
います。

その結果、Wire.h仕様のTEST0だと、
  スケッチが1523バイト(37%)
  グローバル変数が100バイト(39%)

それがTEST1だと
  スケッチが773バイト(18%)
  グローバル変数が14バイト(5%)
と、大幅に使用メモリが少なくなりました。
RAMの使用量を減らせたのが大きいかと。

スケッチと下請けルーチンはダウンロードで。(zip圧縮)

 ・ダウンロード - lcd_test0.zip Wire.h使用

 ・ダウンロード - lcd_test1.zip TWIレジスタ直書きで


TEST1(i2c_lcd_acm0802_tn)で使ったTWIレジスタ
のアクセス方法。

/********************************/
/* TWIモジュールのアクセス */
/********************************/
// ATtiny402のTWIハードウェアを制御
// 割り込みを使わなない
// タイムアウトチェックカウンタを設けて異常でも抜けるように
// 正しくACKが帰ってこない場合も処理を続行
/***** TWI 初期化 *****/
// TWI周波数を設定 100kHz
void twiInit(void )
{
TWI0.MBAUD = 100; // 20MHz/2/fSCL
// 100kHz→100
// 400kHz→25
TWI0.MCTRLA = 0b00000001;
// || ||||+----- ENABLE 主装置許可
// || |||+------ SMEN 簡便動作しない
// || |++------- TIMEOUT 使わない
// || +--------- QCEN 迅速指令 しない
// |+----------- WIEN 書き込み割り込み なし
// +------------ RIEN 読み込み割り込み なし
TWI0.MSTATUS = 0b00000001;
// ||||||++----- BUSSTATE アイドル状態に
// |||||+------- BUSERR
// ||||+-------- ARBLOST
// |||+--------- RXACK
// ||+---------- CLKHOLD
// |+----------- WIF
// +------------ RIF
}
/***** TWI 書込み送出開始 *****/
void twiStartW(uint8_t adrs)
{
uint16_t tt; // time out check counter
TWI0.MADDR = adrs << 1; // アドレス 書き込みで(0)
tt = 2000; // 2000 loop
while(tt){ // time out?
if(TWI0.MSTATUS & TWI_WIF_bm) break; // WIF=1を待つ
tt--;
}
}
/***** TWI データ書き込み *****/
void twiWrite(uint8_t data)
{
uint16_t tt; // time out check counter
TWI0.MDATA = data; // データ書き込み
tt = 2000; // 2000 loop
while(tt){ // time out?
if(TWI0.MSTATUS & TWI_WIF_bm) break; // WIF=1を待つ
tt--;
}
}
/***** TWI 送出終了 *****/
void twiStop(void)
{
TWI0.MCTRLB = TWI_MCMD_STOP_gc; // Stop Condition
}

 

| | コメント (1)

2025年9月 5日 (金)

ATtiny402マイコン サンプル:I2Cで液晶表示

ATtiny402マイコン サンプル:割り込みでシリアル出力
ATtiny402マイコン サンプル:RCサーボモータテスター
に続いて、あらたなATtiny402マイコンのサンプルです。
これらに、I2C液晶を追加してみました。

Sch01

※参:Arduino IDEの環境
Ide01

・シリアル出力を割り込みで。
  出力完了を待たなくても、次の仕事が
  できる。

・A/D変換データ取得を割り込みで。
  変換完了を待たなくても最近値を
  いつでも読める。

・1ms割り込みでタイマー。
  この中でA/D変換開始を指令。


液晶表示の様子
Tn11

ざっと、タイミングを見てもらいましょう。
上から
  PWM出力 50Hz(20ms)でサーボ用パルスを出力
  シリアル出力データ(9600BPS)
  I2C SCL 液晶表示
  I2C SDA  〃

01m

4文字+6文字の液晶表示を行った後、シリアルデータを出力。
2msの時間待ちをしてから2文字を表示。
シリアル出力が割り込みで処理されるので、
2ms待ちと2文字表示が、シリアル出力完了を待たなくても
処理が進んでいます。

さて、なんとかしたいのが液晶表示のためのI2Cアクセス。
「Wire」「twi」ライブラリを使うので複雑になっています。
液晶表示だけなら書くだけ。
余計な処理はいらないので、もっと短くシンプルに
できるはず。

※参考
I2C液晶のアクセス、割り込み処理で遅れる原因らしきもの
I2C液晶のアクセス、割り込みで処理しないようにすると

Arduino UNO R3のI2C制御とATtiny402の制御が
異なるので、ATmega328用のプログラムは動きません。
もうちょい勉強です。

~~~~~~~~~~~~~~~~
  超低速2相パルス発生回路・ケース入れ で、
  I2C液晶表示をwireライブラリを使わない
  ようにしたら(wireの中からtwiを呼んでいる)、
  プログラムのサイズが1.8kバイトほど減少。
  RAMエリアも200バイトほど減りました。
~~~~~~~~~~~~~~~~
てな具合なので、なんとかしたいです。

※バックアップ代わりに今回のスケッチ
  液晶表示処理は別ファイルになってます
   ・ダウンロード - lcd_pwm_txint0.zip


※注意:I2Cのプルアップ抵抗
 ・秋月の液晶表示器 ACM0802C-NLW-BBW-IIC、I2Cのプルアップ抵抗
モジュールに2.2kΩのプルアップ抵抗が内蔵されています。

※続き
 ・ATtiny402マイコン サンプル:I2Cで液晶表示(Wire.hを使わないで)
   プログラムエリアとRAMエリアを縮小できます。

 ・ATtiny402サンプル:I2Cで液晶表示 SCL周波数を設定できるようにしたら


| | コメント (0)

2025年9月 2日 (火)

『暗号攻防史』

kitamuramasaさんからのおすすめ『暗号攻防史』
が図書館からやってきました。
An31

なんといっても「エニグマ」の話が面白い。

で、この本での知見・・・
 ・海軍用エニグマ(Uボートとの通信用)が1942年2月、
  暗号生成用ロータが1つ追加されて3ロータから
  4ロータになった。
 ・このせいで解読ができなくなってしまった。

エニグマ解説本に出てくるエピソードです。
どんな細工をして3→4にしたのかがこの本に
記されていました。
 ・端っこにある反転ドラムの厚みを薄く。
 ・隣のロータとの間に隙間ができる。
 ・そこに4つ目のロータを挿入。
 ・どうやら、追加した4つ目のは自動回転しない。
    初期設定するために回転はできる。
    可変プラグボード的役割。
  で、ロータの駆動メカ構造は3ロータのと
  変わらない
 ・こうすると、全部が4ロータ機に入れ替わるまで
  先に4ロータになった機械は4ロータ目を
  全ピンストレート接続のロータにしておけば、
  3ロータと同じ扱い。
  そして、4ロータ機が行き渡ったある日突然、
  4ロータ目を複雑配線されたのに入れ替えて、
  ロータの初期位置設定を4つにすれば・・・
  解読側は大混乱。

エニグマの最大の欠点が、暗号生成と翻訳を
お手軽に同じ機械でできるようにと入れた機構:
反転ドラムのせいで、
  打った文字と同じ字は出力に出てこない
どうやらこれ。
この本でも「反転ドラムの呪い」という項があります。


エニグマ解読に関する歴史、このページが面白い
※参考ページ
不思議net:彡(゚)(゚)「エニグマ解読……?」


| | コメント (0)

« 2025年8月 | トップページ | 2025年10月 »