ミニ・エレキーの再改良
2013-09-28
そろそろ、ブログの題名を替えても良さそうですね・・・『過渡現象 ~エレキーでもQRPっておもろいのん?~』
さて、結局はパドルのプルアップ抵抗を10KΩ⇒47KΩに変更しました。これで「チャタ取り」としての時定数は、PICが「LOW」と認識する0.8V以下の区間が「-ln(1-(0.8/3))・47KΩ・0.0022μF」で求められる「32μs」程度になったと同時に、パドル押下における消費電流は約1/5と省エネになりました。
さらに「コメント主」たる(わぁ・・・乗っ取られたか
)我が知恵袋さんから「トランジスタスイッチのベース・グランド間抵抗は無意味じゃね
」というこの記事のコメントに合点し、これも取っ払いました。何となく、NPNのトランジスタスイッチには、ON⇒OFF時の安定動作に必須だと思い込んでいましたが、低VDDに高抵抗では確かに無意味ですね
諸元と回路図をリニューアルしました。
◆ 諸元
そんなに変わっていませんが、一応掲載。黄色の文字部分が、ここ一連の改良ポイントになります。
パドルの長・短点挟みっぱなしで連続送信している状態が最も「電気を食う状態」ですが、これで0.32mA程度ですので、諸元上は「Max 0.4mA」にしてあります。
◆ 回路図
回路図は以下の通りです。上の説明の通り修正しました。

スイッチ類のプルアップは、ひとまず10KΩとしたままですが、まぁパドルに比べりゃ出番は圧倒的に少ないですからいいでしょう。
◆ 残る宿題など
今のプログラムは、タイマ1を符号生成用の基本タイマとして使っており、付随するポートルックインは必要に応じてタイマ0、オートCQはタイマ2を使っています。特にオートCQは数秒間の「待ち」が存在するため、この部分を「寝て待つ」という方法にするとさらに省エネになります。「寝て待っていないときの消費電流」は実測で120μA程度であるため、まぁ気が向いたら直そう程度に考えています。
※2013/09/28
ちょっと回路を手直ししましたので差し替えます。
・電源瞬断保護用ケミコンの容量が大きいためスイッチを切ってもなかなかOFFにならず、メモリ切替に時間が掛かるため、スイッチOFF時に100Ωで放電
・MODE切換用のトグルスイッチについて、一瞬不定となる時間を短くするため、RA4-グランド間に0.0022μFのコンデンサを接続して影響期間を短くした
さて、結局はパドルのプルアップ抵抗を10KΩ⇒47KΩに変更しました。これで「チャタ取り」としての時定数は、PICが「LOW」と認識する0.8V以下の区間が「-ln(1-(0.8/3))・47KΩ・0.0022μF」で求められる「32μs」程度になったと同時に、パドル押下における消費電流は約1/5と省エネになりました。
さらに「コメント主」たる(わぁ・・・乗っ取られたか



諸元と回路図をリニューアルしました。
◆ 諸元
そんなに変わっていませんが、一応掲載。黄色の文字部分が、ここ一連の改良ポイントになります。
項目 | 内容 | 備考 |
動作仕様 | スクイーズモードB | |
長短点 メモリ | 有り | |
メモリ禁止 | 短点の50% | 余計な長短点送出防止 |
ウエイト | 長点:短点 1:3固定 | |
メッセージ 送出機能 | 4メッセージ 同時使用2パターン | 電源投入時に選択 EEPRROM格納で 書換可 |
メッセージ 書換機能 | パドル操作による | |
送信速度 | 15-40WPM | スイッチ操作により送信中 でも可変可能 |
KEY出力 | オープンコレクタ | 20mAまでキーイング可能 |
電源 | 単4×2本 | |
消費電流 | 待機時:1μA未満 送信時:0.4mA Max | 送信時平均0.2mA程度 |
パドルの長・短点挟みっぱなしで連続送信している状態が最も「電気を食う状態」ですが、これで0.32mA程度ですので、諸元上は「Max 0.4mA」にしてあります。
◆ 回路図
回路図は以下の通りです。上の説明の通り修正しました。

スイッチ類のプルアップは、ひとまず10KΩとしたままですが、まぁパドルに比べりゃ出番は圧倒的に少ないですからいいでしょう。
◆ 残る宿題など
今のプログラムは、タイマ1を符号生成用の基本タイマとして使っており、付随するポートルックインは必要に応じてタイマ0、オートCQはタイマ2を使っています。特にオートCQは数秒間の「待ち」が存在するため、この部分を「寝て待つ」という方法にするとさらに省エネになります。「寝て待っていないときの消費電流」は実測で120μA程度であるため、まぁ気が向いたら直そう程度に考えています。
※2013/09/28
ちょっと回路を手直ししましたので差し替えます。
・電源瞬断保護用ケミコンの容量が大きいためスイッチを切ってもなかなかOFFにならず、メモリ切替に時間が掛かるため、スイッチOFF時に100Ωで放電
・MODE切換用のトグルスイッチについて、一瞬不定となる時間を短くするため、RA4-グランド間に0.0022μFのコンデンサを接続して影響期間を短くした
チャタ取りの時定数考察
2013-09-27
未だやってるのか・・・とお思いでしょうが、未だやってます
昨晩投稿のつもりが今日になってしまった「パドルのチャタ見参」・・・ってか直前の記事について、ちょっと自問自答して「おかしいぞ」ということに気付き、午後からの会社イベント中にこっそりノートの裏に落書きしていた奴を清書しました。

今回作ったミニ・エレキーのパドル入力回路はプルアップ抵抗+時定数用コンデンサの組み合わせで至ってシンプルですが、昨日の時定数計算について「LOW/HIGHの閾値を50%」と決めてしまったところがどうにも引っ掛かり、「確か、PICのIOポートのLOW閾値は『0.8V以下』だっとような・・・」と、出勤途上のスマホでデータシートをチェック。まんざら、記憶力は落ちていませんでした
チャタ発生時にHIGH⇒LOWの動きで上図のように「パドルの接点がバウンドした」という場面を仮定すると、接点がバウンドで離れている時間が短い場合なら、現状の時定数の範囲内だと「OK
」ですが、それより長い場合はいわゆる「グレーゾーン」・・・不定区間ができいてしまいます。このことから考えると、今の時定数ではやはりちょっと短か過ぎ・・・。現ミニ・エレキーの抵抗は10KΩ、コンデンサ容量は0.0022μFですから、「-ln(1-(0.8/3))・10KΩ・0.0022μF」⇒6.8μsで0.8V超えになってしまいます。
一方、直前記事のチャタ波形を見ると、波々の怪しげな部分・・・チャタっていそうな部分が50μs程続いていますから、CRの時定数は、少なくとも現状の10倍程度はあっても良さそう。これは、抵抗値を上げてさらなる省エネにする「良い口実」になりそうですね
昨日書いたように実はソフト的な逃げも打ってありますから、この対策自体はあんまり意味はないんですが、例えば抵抗値を10KΩ⇒47KΩに上げても良さそう・・・ということは、省エネ仕様を目指す部分では「イイ感じ」になりそうです。またしても、改造に取り掛かろうかな

昨晩投稿のつもりが今日になってしまった「パドルのチャタ見参」・・・ってか直前の記事について、ちょっと自問自答して「おかしいぞ」ということに気付き、午後からの会社イベント中にこっそりノートの裏に落書きしていた奴を清書しました。

今回作ったミニ・エレキーのパドル入力回路はプルアップ抵抗+時定数用コンデンサの組み合わせで至ってシンプルですが、昨日の時定数計算について「LOW/HIGHの閾値を50%」と決めてしまったところがどうにも引っ掛かり、「確か、PICのIOポートのLOW閾値は『0.8V以下』だっとような・・・」と、出勤途上のスマホでデータシートをチェック。まんざら、記憶力は落ちていませんでした

チャタ発生時にHIGH⇒LOWの動きで上図のように「パドルの接点がバウンドした」という場面を仮定すると、接点がバウンドで離れている時間が短い場合なら、現状の時定数の範囲内だと「OK

一方、直前記事のチャタ波形を見ると、波々の怪しげな部分・・・チャタっていそうな部分が50μs程続いていますから、CRの時定数は、少なくとも現状の10倍程度はあっても良さそう。これは、抵抗値を上げてさらなる省エネにする「良い口実」になりそうですね

昨日書いたように実はソフト的な逃げも打ってありますから、この対策自体はあんまり意味はないんですが、例えば抵抗値を10KΩ⇒47KΩに上げても良さそう・・・ということは、省エネ仕様を目指す部分では「イイ感じ」になりそうです。またしても、改造に取り掛かろうかな

パドルのチャタを見てみよう!
2013-09-27
エレキー製作の課題に、パドルのチャタをどう防ぐか・・・というのがあります。今回のミニ・エレキーでは、長・短点押下の初っ端は「割り込み」(=1ショット)で検出し、その後「メモリ禁止区間」を短点の半分の時間分設けており、この間に押されたパドルは読み捨てますから、結果的にこの禁止区間が「チャタ取り」を行っていることになります。
一方、長・短点メモリー区間はルックインになっているため、送出中でない側の押下を周期的に(4ms毎に)拾いに行きますが、一度でも検出されたら押下として認めるようにしています。即ち、こちらには「チャタ取り」が利いていませんが、特段の不都合は生じません。なぜなら、この区間は送出中でない方のパドル操作を狙い打ちで待っていることと、周期でルックインしているため滅多に「拾い漏れ」しないためです。万一、多少チャタって読み飛ばしても「次があるさ・・・」といった案配です。
ハード的には、スイッチ部に重畳しておく消費電流をケチるあまり大きな抵抗でプルアップするとノイズを拾い易くなる・・・という部分に注意が必要で、現時点では 「10KΩと0.0022μF」の組み合わせでひとまず落ち着かせてしまいました。誤作動しない程度の抵抗値(10KΩ)にしているつもりですが、この辺りも「エイヤ」であり理屈になっていません。
本当は、全体の省エネ化のためにもう少し大きな抵抗値、或いは「弱プルアップ」にしたいなぁ・・・と思っていますが、そもそもパドルはどの程度チャタるのかを知らないと、全てが机上の空論になってしまいますね。
そこで実験。我が主戦パドルに47KΩの抵抗と超ヘタレたゴミ箱行き9V電池(ディップメータに入れっぱなしでほぼ放電しきった奴:0.2Vくらい出ています)を繋ぎ、これをOFF/ONさせたときの様子をオシロで見てみました。ストレージオシロならこの様子が簡単に記録できるんですが、まぁ「お遊び」ですから、我がアナログオシロの画面をデジカメのビデオモードで撮影し、波形の動きがあった部分のコマをパソコンのプリントスクリーンでコピペしました。
パドルを普通に押してもそんなにチャタは見られない感じですが、乱打すると時折上手く波形が出てきます。偽ストレージオシロ操作は、デジカメでビデオ撮影しながらパドル連打という荒技
そして、上の写真が上手く取れた瞬間の画像です。立ち上がり部分は、こんな感じかな・・・というところを破線で補っています。
左側は時間を補足していますが、パドルがOFFからONになっていく過程で過渡的に上昇していく時間は大凡19μSくらいで、その後怪しげな波々が続いて72μs後に収束しています。その後ろの四角で囲った奴もほぼ同様でしょう(波々が少し短いかな・・・程度)。これが本当なら、「50μs程度のざわめき」にビクともしない値で時定数を作ってやればいいことになります。普通のスイッチより、案外短いチャタなんだなぁ・・・。
ミニ・エレキーのCR時定数「10KΩと0.0022μF」の組み合わせについて、「T=-ln(0.5)CR」(丁度50%を閾値とする)で計算すると約118μsとなりますから、かなりイイ線いっているようです
ただ、この実験の接続配線が超テキトー・・・19μsも掛かって上がってくるということは、ヘタレ電池につないだ47KΩに対して数百pFの「浮遊容量」がある計算になります。幾ら何でもちと大きいかな
プローブ自体の浮遊容量が18pFですが、ワニ口リード線の空中配線ってこんなものかなぁ
その上、立ち下がりは真っ直ぐだし・・・。
何れにしても、パドルは「かなり大人しいスイッチ」であることは解りましたし、そんなに大袈裟に「チャタってないかなぁ
」と不安になるようなものでもないということも解りましたので、ひとまずヨシ
として寝ましょうかね・・・。
※2013/09/27
CR回路の応答が指数関数であること、PICのHigh/Lowの閾知が0.8Vくらいなことを考慮すると、時定数としてはやはり小さ過ぎるようですね・・・。この辺り、再計算が必要そうです。
一方、長・短点メモリー区間はルックインになっているため、送出中でない側の押下を周期的に(4ms毎に)拾いに行きますが、一度でも検出されたら押下として認めるようにしています。即ち、こちらには「チャタ取り」が利いていませんが、特段の不都合は生じません。なぜなら、この区間は送出中でない方のパドル操作を狙い打ちで待っていることと、周期でルックインしているため滅多に「拾い漏れ」しないためです。万一、多少チャタって読み飛ばしても「次があるさ・・・」といった案配です。
ハード的には、スイッチ部に重畳しておく消費電流をケチるあまり大きな抵抗でプルアップするとノイズを拾い易くなる・・・という部分に注意が必要で、現時点では 「10KΩと0.0022μF」の組み合わせでひとまず落ち着かせてしまいました。誤作動しない程度の抵抗値(10KΩ)にしているつもりですが、この辺りも「エイヤ」であり理屈になっていません。
本当は、全体の省エネ化のためにもう少し大きな抵抗値、或いは「弱プルアップ」にしたいなぁ・・・と思っていますが、そもそもパドルはどの程度チャタるのかを知らないと、全てが机上の空論になってしまいますね。
そこで実験。我が主戦パドルに47KΩの抵抗と超ヘタレたゴミ箱行き9V電池(ディップメータに入れっぱなしでほぼ放電しきった奴:0.2Vくらい出ています)を繋ぎ、これをOFF/ONさせたときの様子をオシロで見てみました。ストレージオシロならこの様子が簡単に記録できるんですが、まぁ「お遊び」ですから、我がアナログオシロの画面をデジカメのビデオモードで撮影し、波形の動きがあった部分のコマをパソコンのプリントスクリーンでコピペしました。

パドルを普通に押してもそんなにチャタは見られない感じですが、乱打すると時折上手く波形が出てきます。偽ストレージオシロ操作は、デジカメでビデオ撮影しながらパドル連打という荒技

左側は時間を補足していますが、パドルがOFFからONになっていく過程で過渡的に上昇していく時間は大凡19μSくらいで、その後怪しげな波々が続いて72μs後に収束しています。その後ろの四角で囲った奴もほぼ同様でしょう(波々が少し短いかな・・・程度)。これが本当なら、「50μs程度のざわめき」にビクともしない値で時定数を作ってやればいいことになります。普通のスイッチより、案外短いチャタなんだなぁ・・・。
ミニ・エレキーのCR時定数「10KΩと0.0022μF」の組み合わせについて、「T=-ln(0.5)CR」(丁度50%を閾値とする)で計算すると約118μsとなりますから、かなりイイ線いっているようです

ただ、この実験の接続配線が超テキトー・・・19μsも掛かって上がってくるということは、ヘタレ電池につないだ47KΩに対して数百pFの「浮遊容量」がある計算になります。幾ら何でもちと大きいかな


何れにしても、パドルは「かなり大人しいスイッチ」であることは解りましたし、そんなに大袈裟に「チャタってないかなぁ


※2013/09/27
CR回路の応答が指数関数であること、PICのHigh/Lowの閾知が0.8Vくらいなことを考慮すると、時定数としてはやはり小さ過ぎるようですね・・・。この辺り、再計算が必要そうです。
LFタイプの検証と回路直しのオマケ
2013-09-25
PIC12F1822はXLPに非ず・・・という記事を書きっぱなしではちょっと無責任かな
っと思ったというより、本当にそうなのかを確認すべく、帰宅途中に秋葉にササッと寄ってお目当ての品を買ってきました。

こんな写真じゃ判らないなぁと思いつつも掲載・・・正真正銘のPIC12LF1822です。136円也。沢山買っても仕方がないんで、ひとまずミニ・エレキー用に1つ入手。
さて、これでプログラムして早々に実験を・・・と思ったんですが、コメントを頂いた「BOR」(Brown-out Reset)についてのフェールセーフ(電池の接触不良による瞬断対策)として、ケミコンを1つ入れておくことにしました。まぁ「精神衛生」以外の何者でもない気もしますが・・・。そして、回路図を何気なく見渡したら、な、な、なんと・・・トランジスタスイッチの部分の抵抗値が間違っていることに気づきました。
そもそも、hFEの大きなトランジスタを選び、最低でもベース電流の400倍程度のキーイングはいけるだろう・・・と踏んで値を決めたつもりが、ベース-グランド間の抵抗と間違えていました
ここで、落ち着いて思案。
単4×2の3Vの電池が消耗して仮に1.8Vまで落ちたと仮定し、この状態でもベース電圧0.6V以上を保証してやれば、最後の最後(
)までエレキーが動作できるとします。すると、ベース抵抗の分圧は1:1で良さそう(ベース電位は0.9Vとなり、0.6Vより若干余裕有り)ですから、コレクタのスイッチング電流を20mA前提でベース電流が足りるように(流し過ぎないように)選び、同じ値の抵抗でベースとグランドを接続してやればよいことになります。
今までベース抵抗は10KΩでしたから300μAも流れていたわけですが、こうなるとこのhFE倍(450倍)・・・何と135mAもコレクタ電流を流せる状態にオーバドライブしていたことになります。逆に20mAをMaxと考えれば44μA程度のベース電流で良いはずで、ベース抵抗は67KΩくらいまで上げられそうです。そこでひとまず「47KΩ」としました。これでベース電流としては67μA、ベース-グランド間が同じく47KΩですから、キーイングがONになったときの消費電流は134μAまで小さくできそうです。

・・・というわけで、回路図を書き換えました。電源スイッチ横の47μF(ケミコン)追加、RA5とベース間の抵抗値を10KΩ⇒47KΩというマイナーチェンジです。この通り「実機」を直して、いざP12LF1822の出番。プログラムのヘッダファイル指定を変更してリコンパイルし、PICkit3でプログラムしました。果たして

SLEEP中の様子です・・・って、全然証拠写真になっていませんが、これでちゃんと動いています
カタログスペックを読み取ると、SLEEP中は30nA程度の筈。秋月のこのデジタルテスタでは測定不能な領域ですね。その他、パドル操作中の消費電流がやはり断然減りました。これは大いに、ベース抵抗の見直しによる部分が大きく、長短点同時押下で最大電流が1mAを若干超えていたものが、800μA程度(900μAにはならない程度)にまで抑えることができました。これは、上記の「300μA⇒134μA」を裏付けています。これで、TS-590もキーイングできましたからまずは問題ないでしょう。
また、「L付き」「L無し」の差として、動作時の消費電流(オートCQのストップ待ちなど、SLEEP中でないプログラム空転時)もPIC12LF1822の方が大凡30μAほど小さく、「56円高いだけのことはあるぞ
」という結論です。メデタシメデタシ・・・
それにしても「ナノ・アンペア」って、なんナノ
・・・お後が宜しいようで


こんな写真じゃ判らないなぁと思いつつも掲載・・・正真正銘のPIC12LF1822です。136円也。沢山買っても仕方がないんで、ひとまずミニ・エレキー用に1つ入手。
さて、これでプログラムして早々に実験を・・・と思ったんですが、コメントを頂いた「BOR」(Brown-out Reset)についてのフェールセーフ(電池の接触不良による瞬断対策)として、ケミコンを1つ入れておくことにしました。まぁ「精神衛生」以外の何者でもない気もしますが・・・。そして、回路図を何気なく見渡したら、な、な、なんと・・・トランジスタスイッチの部分の抵抗値が間違っていることに気づきました。
そもそも、hFEの大きなトランジスタを選び、最低でもベース電流の400倍程度のキーイングはいけるだろう・・・と踏んで値を決めたつもりが、ベース-グランド間の抵抗と間違えていました

単4×2の3Vの電池が消耗して仮に1.8Vまで落ちたと仮定し、この状態でもベース電圧0.6V以上を保証してやれば、最後の最後(

今までベース抵抗は10KΩでしたから300μAも流れていたわけですが、こうなるとこのhFE倍(450倍)・・・何と135mAもコレクタ電流を流せる状態にオーバドライブしていたことになります。逆に20mAをMaxと考えれば44μA程度のベース電流で良いはずで、ベース抵抗は67KΩくらいまで上げられそうです。そこでひとまず「47KΩ」としました。これでベース電流としては67μA、ベース-グランド間が同じく47KΩですから、キーイングがONになったときの消費電流は134μAまで小さくできそうです。

・・・というわけで、回路図を書き換えました。電源スイッチ横の47μF(ケミコン)追加、RA5とベース間の抵抗値を10KΩ⇒47KΩというマイナーチェンジです。この通り「実機」を直して、いざP12LF1822の出番。プログラムのヘッダファイル指定を変更してリコンパイルし、PICkit3でプログラムしました。果たして


SLEEP中の様子です・・・って、全然証拠写真になっていませんが、これでちゃんと動いています

また、「L付き」「L無し」の差として、動作時の消費電流(オートCQのストップ待ちなど、SLEEP中でないプログラム空転時)もPIC12LF1822の方が大凡30μAほど小さく、「56円高いだけのことはあるぞ


それにしても「ナノ・アンペア」って、なんナノ


ミニ・エレキーを解剖する-モールス符号複合化編
2013-09-22
エレキーの機能としてポピュラーな「メッセージ自動送出」は、事前に作ったASCII文字列を、直前の記事にあるASCII ⇒モールス符号データ変換を使って実現できますが、そもそもメッセージが永久固定ならいざ知らず、コールサインの後に「移動地」を付けたくなったり、コンテストナンバーを変えたくなったりします。即ち、EEPROMなどの書換可能なメディアにメッセージを用意しておき、必要に応じて変更できるようにする必要があります。
今回作ったミニ・エレキーは、当初「コンテスト専用」として「固定メッセージ」で考えていました。必要に応じてPICをプログラムし直せばいいや・・・ってな具合だったわけですが、なんか片手落ちな気がして、結局EEPROMにメッセージを書き、後からパドル操作で書き換えられるようにしました。
◆ 手打ちの短・長点の順序と数を記録する
世にあるCW解読ソフトは、細かいタイムスロットで信号をサンプリングし、そのON/OFF情報を紡いで複合化しているものが多いと思いますが、ミニ・エレキーではこんな芸当をさせずとも「パドル操作で打たれた短点・長点を、順番に記録すればできる」ということに気づきました。そもそも、エレキーの基本機能に「スクイーズ動作に合わせて短・長点を送出する」という機能があるわけですから、手操作の開始と終了さえ判れば、その間の短・長点の順序と数を記録してしまえばいいわけです。
そこで、以下のような手順を守って入力するようにしました(関連記事はこちら)。
1) エレキーから「R」を送出
2) パドル操作で書き換えたい文字を入力
3) 文字入力が終了したらボタンを押下
◆ ビットデータを逆に作っていく
直前の記事で説明したように、今回はビットのOFF/ONを短点/長点とし、その頭に「スタートビット」を付け足したものを送出データとしていますから、記録した短・長点の情報について、0ビット目に設定しては左に1ビットシフトして展開し、最後にスタートビットを設定すればよく、これも非常に簡単のロジックと変数2つで実現できました。
例えば「Q」の場合は、以下のようになります。
Q : - - ・ -
(1)(2)(3)(4)
0) 事前に2つの変数「ptn」「sbit」を以下のように初期化
ptn : 00000000 sbit : 00000001
1) 長点
・ptnを左1ビットシフト
ptn : 00000000
・ptnのLSB(最下ビット)に長点を示す1をORでセット
ptn : 00000001
・sbitを左1ビットシフト
sbit : 00000010
2) 長点
・ptnを左1ビットシフト
ptn : 00000010
・ptnのLSB(最下ビット)に長点を示す1をORでセット
ptn : 00000011
・sbitを左1ビットシフト
sbit : 00000100
3) 短点
・ptnを左1ビットシフト
ptn : 00000110
・ptnのLSB(最下ビット)に短点を示す0をORでセット
ptn : 00000110
・sbitを左1ビットシフト
sbit : 00001000
4) 長点
・ptnを左1ビットシフト
ptn : 00001100
・ptnのLSB(最下ビット)に短点を示す1をORでセット
ptn : 00001101
・sbitを左1ビットシフト
sbit : 00010000
5) 終了
sbitをptnにORでセット
ptn : 00011101
1)から4)は同じ処理で作れますよ・・・念のため。
◆ パターンマッチングで逆引きしてASCIIコードへ
出来上がったパターンデータ「ptn」を、直前の記事にあるテーブルの先頭から順に比較します。一致するものがあったら、先頭から何番目で見つけたか・・・この数に0x20を加算すれば、ASCIIコード(値)が求められます。これを、EEPROMの所定位置に書き込めば、その位置のデータが書き換わります。
以上、参考になれば幸いです
今回作ったミニ・エレキーは、当初「コンテスト専用」として「固定メッセージ」で考えていました。必要に応じてPICをプログラムし直せばいいや・・・ってな具合だったわけですが、なんか片手落ちな気がして、結局EEPROMにメッセージを書き、後からパドル操作で書き換えられるようにしました。
◆ 手打ちの短・長点の順序と数を記録する
世にあるCW解読ソフトは、細かいタイムスロットで信号をサンプリングし、そのON/OFF情報を紡いで複合化しているものが多いと思いますが、ミニ・エレキーではこんな芸当をさせずとも「パドル操作で打たれた短点・長点を、順番に記録すればできる」ということに気づきました。そもそも、エレキーの基本機能に「スクイーズ動作に合わせて短・長点を送出する」という機能があるわけですから、手操作の開始と終了さえ判れば、その間の短・長点の順序と数を記録してしまえばいいわけです。
そこで、以下のような手順を守って入力するようにしました(関連記事はこちら)。
1) エレキーから「R」を送出
2) パドル操作で書き換えたい文字を入力
3) 文字入力が終了したらボタンを押下
◆ ビットデータを逆に作っていく
直前の記事で説明したように、今回はビットのOFF/ONを短点/長点とし、その頭に「スタートビット」を付け足したものを送出データとしていますから、記録した短・長点の情報について、0ビット目に設定しては左に1ビットシフトして展開し、最後にスタートビットを設定すればよく、これも非常に簡単のロジックと変数2つで実現できました。
例えば「Q」の場合は、以下のようになります。
Q : - - ・ -
(1)(2)(3)(4)
0) 事前に2つの変数「ptn」「sbit」を以下のように初期化
ptn : 00000000 sbit : 00000001
1) 長点
・ptnを左1ビットシフト
ptn : 00000000
・ptnのLSB(最下ビット)に長点を示す1をORでセット
ptn : 00000001
・sbitを左1ビットシフト
sbit : 00000010
2) 長点
・ptnを左1ビットシフト
ptn : 00000010
・ptnのLSB(最下ビット)に長点を示す1をORでセット
ptn : 00000011
・sbitを左1ビットシフト
sbit : 00000100
3) 短点
・ptnを左1ビットシフト
ptn : 00000110
・ptnのLSB(最下ビット)に短点を示す0をORでセット
ptn : 00000110
・sbitを左1ビットシフト
sbit : 00001000
4) 長点
・ptnを左1ビットシフト
ptn : 00001100
・ptnのLSB(最下ビット)に短点を示す1をORでセット
ptn : 00001101
・sbitを左1ビットシフト
sbit : 00010000
5) 終了
sbitをptnにORでセット
ptn : 00011101
1)から4)は同じ処理で作れますよ・・・念のため。
◆ パターンマッチングで逆引きしてASCIIコードへ
出来上がったパターンデータ「ptn」を、直前の記事にあるテーブルの先頭から順に比較します。一致するものがあったら、先頭から何番目で見つけたか・・・この数に0x20を加算すれば、ASCIIコード(値)が求められます。これを、EEPROMの所定位置に書き込めば、その位置のデータが書き換わります。
以上、参考になれば幸いです

ミニ・エレキーを解剖する-モールス符号データ編
2013-09-22
各種の小さなマイコンでエレキー製作されている方は沢山いらっしゃると思いますので、モールス符号のデータ化も千差万別でしょう。どなたかの役に立つかも知れませんので、今回のミニ・エレキーのモールス符号化に関わる部分をまとめておきます。
◆ まずはASCII文字として扱う
普段使っているパソコンもそうですが、半角のアルファベット表現に「ASCIIコード」を用いているものは非常に多く、今さら解説するほどでもないでしょう。このコード、元々はアメリカ生まれですから、アルファベットの大・小文字(と数字)の通信ができれば良かったために「7ビット」でコード化されたものです。7ビット・・・128通りの意思疎通が可能というわけですね。
このコードの0x00から0x1Fまでは、通信手段として「これから送信するぞ」「これで終わりだぞ」・・・といった意味のコードになっており、普通の人は専ら0x20から上のコードを使うわけですが、大体以下のようになっています。
0x20-0x2F : 特殊文字-1
0x30-0x39 : 数字の「0-9」
0x3A-0x40 : 特殊文字-2
0x41-0x5B : アルファベットの「A-Z」
(以下、略)
一方、アマチュア無線のモールス通信でも特殊な意味合いの通信用に「?」や「/」(スラッシュ)或いは表示上よく使う「 」(半角のスペース」は特殊文字の範囲にあります。例えば、「QRZ? JM1DPL K」という文字列を書いてみると判るように、特殊文字の「?」に加え、「?」の後ろと「L」の後ろには「 」(半角スペース)が入りますよね
実際のCW通信上は「7短点分空ける」という規則ですが、何れにせよこの「何もない部分」も「何もないんだぞ」というデータ化をする必要があるわけです。
こうなると、ASCIIコードをそのまま扱って「A」なら「・-」、「?」なら「・・--・・」、「 」(半角スペース)なら「(7短点分の時間)」といった変換を行えれば、何となくエレキーができそうだなぁ・・・となるでしょう。そこでとりあえず、大本の送信したい文字は「ASCIIコード」で表現する(扱う)ことにします。
◆ 短点と長点を符号化
マイコンの最小記憶単位はビットであり、1ビットは「0」か「1」の値になりますので、これを短点と長点に当て嵌めてしまうと、モールス符号が簡単に表現できます。1バイト=8ビットに右詰で表現してみます。
「A」 ⇒ 00000001
「B」 ⇒ 00001000
「C」 ⇒ 00001010
「D」 ⇒ 00000100
「E」 ⇒ 00000001
「F」 ⇒ 00000010
この辺で止めておきます
・・・が、よく見ると「A」と「E」が同じになってしまっていますね
これは上手くありません。そこで、そのコードがどこから始まるかを示す「スタートビット」を付けてみます。
同じ表現になってしまった「A」と「E」ですが、実は「A」の場合は右から2ビット分がデータ、「E」は右から1ビット分がデータですよね
ここに着目して、スタートビットを追加すると・・・。
「A」 ⇒ 00000101
「B」 ⇒ 00011000
「C」 ⇒ 00011010
「D」 ⇒ 00001100
「E」 ⇒ 00000011
「F」 ⇒ 00010010
ピンクの「1」がスタートビットです。こうすると、このビットの右側が「コード化された短点と長点」だということが判りますし、「A」と「E」もきちんと区別できます。
◆ スタートビットを探していざ送出
さぁ、この「スタートビットを探す論理」にも幾つかバリエーションがありますが、特にアセンブラで組む場合には「左シフトしてキャリーが立ったら見つけたことにする」という論理が簡単で高速な処理になります。即ち、以下のように処理を進めます。
1) キャリーが立つまで左シフト
2) キャリーが立ったらもう1ビットシフトし、またキャリーが立ったら「長点」、立たなかったら「短点」を送出
3) キャリー探しを含め8ビット分で終了
◆ コード化されたデータの配列を準備
上記の論理でコード化されたものを配列にします。そして、ASCIIコードの値をその配列を索引するインデックスに使えば、一発で「送出したい文字のコード化されたデータ」を持ってくることができます。ここで、0x20未満は不要ですから、下の表のようなデータを作りました。

右端の「0x??」が「送出したい文字のコード化されたデータ」です。黄色はスタートビットです。また、今回は制御データについては未使用として扱っています。将来、何か制御したいときに使うための「個人的な予約」です。
PICのC言語による実際のコーディングイメージは以下のようになっています。
実際にこのテーブルをインデックスする際は、先頭が0x20に当たるため、ASCIIコードから0x20を減算してインデックスすればOK・・・簡単ですね
◆ スペースと未使用領域
スペース(0x20)は、実際には短点も長点も出ませんから省いてもいいんですが、例えば送出中の文字をLCDに表示させたり、EEPROMにメッセージを格納するときなどには無いと困る文字でもあるため含んでいます。もしスペースが不要なら、もう少しテーブル自体を小さく(先頭を「/」にするなど)しても良いでしょう。
未使用領域には「#」「$」・・・が眠っているわけですが、中には「.」(ピリオド)など、ひょっとしたらCWで送信するかも知れないコードもありますから、その場合は該当する位置に「送出したい文字のコード化されたデータ」として定義すれば済みます。
◆ この方法の欠点
この方法は、送りたい文字の送出データを簡単に拾い出すことにはかなり長けていて、オマケに必要な短点・長点のデータを取り出す処理も簡単で比較的高速になると思いますが、各データに2ビットほど無駄があるのが欠点です。
アルファベットと数字、それに幾つかの特殊文字を合計すると大凡40文字あれば良く、これを管理するためには「6ビット」もあれば事足ります。この辺り、例えばエレキー専用のPICを用意するのではなく、「何かの序でにこのPICの空き部分に入れちゃおう」といった場合や、特にメモリが小さいPICの場合には「デカ過ぎ
」ということもあり得ます。
ただ、原理的には難易度が低いため、「そろそろ自作でエレキーを・・・」といった方なら、Mid Rangeの比較的容量のあるPICを採用すれば、少なくともASCII ⇒モールス符号データ変換は簡単に作れると思います
◆ まずはASCII文字として扱う
普段使っているパソコンもそうですが、半角のアルファベット表現に「ASCIIコード」を用いているものは非常に多く、今さら解説するほどでもないでしょう。このコード、元々はアメリカ生まれですから、アルファベットの大・小文字(と数字)の通信ができれば良かったために「7ビット」でコード化されたものです。7ビット・・・128通りの意思疎通が可能というわけですね。
このコードの0x00から0x1Fまでは、通信手段として「これから送信するぞ」「これで終わりだぞ」・・・といった意味のコードになっており、普通の人は専ら0x20から上のコードを使うわけですが、大体以下のようになっています。
0x20-0x2F : 特殊文字-1
0x30-0x39 : 数字の「0-9」
0x3A-0x40 : 特殊文字-2
0x41-0x5B : アルファベットの「A-Z」
(以下、略)
一方、アマチュア無線のモールス通信でも特殊な意味合いの通信用に「?」や「/」(スラッシュ)或いは表示上よく使う「 」(半角のスペース」は特殊文字の範囲にあります。例えば、「QRZ? JM1DPL K」という文字列を書いてみると判るように、特殊文字の「?」に加え、「?」の後ろと「L」の後ろには「 」(半角スペース)が入りますよね

こうなると、ASCIIコードをそのまま扱って「A」なら「・-」、「?」なら「・・--・・」、「 」(半角スペース)なら「(7短点分の時間)」といった変換を行えれば、何となくエレキーができそうだなぁ・・・となるでしょう。そこでとりあえず、大本の送信したい文字は「ASCIIコード」で表現する(扱う)ことにします。
◆ 短点と長点を符号化
マイコンの最小記憶単位はビットであり、1ビットは「0」か「1」の値になりますので、これを短点と長点に当て嵌めてしまうと、モールス符号が簡単に表現できます。1バイト=8ビットに右詰で表現してみます。
「A」 ⇒ 00000001
「B」 ⇒ 00001000
「C」 ⇒ 00001010
「D」 ⇒ 00000100
「E」 ⇒ 00000001
「F」 ⇒ 00000010
この辺で止めておきます


同じ表現になってしまった「A」と「E」ですが、実は「A」の場合は右から2ビット分がデータ、「E」は右から1ビット分がデータですよね

「A」 ⇒ 00000101
「B」 ⇒ 00011000
「C」 ⇒ 00011010
「D」 ⇒ 00001100
「E」 ⇒ 00000011
「F」 ⇒ 00010010
ピンクの「1」がスタートビットです。こうすると、このビットの右側が「コード化された短点と長点」だということが判りますし、「A」と「E」もきちんと区別できます。
◆ スタートビットを探していざ送出
さぁ、この「スタートビットを探す論理」にも幾つかバリエーションがありますが、特にアセンブラで組む場合には「左シフトしてキャリーが立ったら見つけたことにする」という論理が簡単で高速な処理になります。即ち、以下のように処理を進めます。
1) キャリーが立つまで左シフト
2) キャリーが立ったらもう1ビットシフトし、またキャリーが立ったら「長点」、立たなかったら「短点」を送出
3) キャリー探しを含め8ビット分で終了
◆ コード化されたデータの配列を準備
上記の論理でコード化されたものを配列にします。そして、ASCIIコードの値をその配列を索引するインデックスに使えば、一発で「送出したい文字のコード化されたデータ」を持ってくることができます。ここで、0x20未満は不要ですから、下の表のようなデータを作りました。

右端の「0x??」が「送出したい文字のコード化されたデータ」です。黄色はスタートビットです。また、今回は制御データについては未使用として扱っています。将来、何か制御したいときに使うための「個人的な予約」です。
PICのC言語による実際のコーディングイメージは以下のようになっています。
static const uchar kcnv_t[59] = { 0x01,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x55,0x32, 0x3F,0x2F,0x27,0x23,0x21,0x20,0x30,0x38, 0x3C,0x3E,0xFF,0xFF,0xFF,0xFF,0xFF,0x4C, 0xFF,0x05,0x18,0x1A,0x0C,0x02,0x12,0x0E, 0x10,0x04,0x17,0x0D,0x14,0x07,0x06,0x0F, 0x16,0x1D,0x0A,0x08,0x03,0x09,0x11,0x0B, 0x19,0x1B,0x1C }; |
実際にこのテーブルをインデックスする際は、先頭が0x20に当たるため、ASCIIコードから0x20を減算してインデックスすればOK・・・簡単ですね

◆ スペースと未使用領域
スペース(0x20)は、実際には短点も長点も出ませんから省いてもいいんですが、例えば送出中の文字をLCDに表示させたり、EEPROMにメッセージを格納するときなどには無いと困る文字でもあるため含んでいます。もしスペースが不要なら、もう少しテーブル自体を小さく(先頭を「/」にするなど)しても良いでしょう。
未使用領域には「#」「$」・・・が眠っているわけですが、中には「.」(ピリオド)など、ひょっとしたらCWで送信するかも知れないコードもありますから、その場合は該当する位置に「送出したい文字のコード化されたデータ」として定義すれば済みます。
◆ この方法の欠点
この方法は、送りたい文字の送出データを簡単に拾い出すことにはかなり長けていて、オマケに必要な短点・長点のデータを取り出す処理も簡単で比較的高速になると思いますが、各データに2ビットほど無駄があるのが欠点です。
アルファベットと数字、それに幾つかの特殊文字を合計すると大凡40文字あれば良く、これを管理するためには「6ビット」もあれば事足ります。この辺り、例えばエレキー専用のPICを用意するのではなく、「何かの序でにこのPICの空き部分に入れちゃおう」といった場合や、特にメモリが小さいPICの場合には「デカ過ぎ

ただ、原理的には難易度が低いため、「そろそろ自作でエレキーを・・・」といった方なら、Mid Rangeの比較的容量のあるPICを採用すれば、少なくともASCII ⇒モールス符号データ変換は簡単に作れると思います

ミニ・エレキーを解剖する-C言語処理編
2013-09-22
今回製作したエレキーは、Mid Rangeの8ピンPICにXC8(オールC言語)という組み合わせで窮屈なメモリに押し込んだことなど、ちょっと記録しておきたいところがありますので、得意の備忘記事にしてみます。
なお、実プログラムの即値定義として各種のdefine定義を行っていますが、以下「ON:1、OFF:0」というもののみ残す形にしてあります。
◆ BSSの初期化を自動で行わせない
初期設定が必要な変数には初期値を事前に入れておくわけですが、XC8のLinkerはスタートアップに絡む便利そうな関数を勝手に付けてきます。とりわけ、BSSの0クリアに関しては一気にクリアする処理を付けてきますので、「初期設定は確実に自分でやる
」という方には不要でしょう。これを外すと数十バイト分のプログラムエリア消費が無くなります・・・まぁ微々たるもんでも無駄は無駄
この処理の取っ払いは、「MPLAB X IDE」のプロジェクトのプロパティにチェックボックスを外すことで行えます。

◆ SLEEP機能を「前向きに使う」
C言語のmain関数は以下のようになっています。
メインループで「やることがないぞ
」となれば即就寝・・・という作りです。変数「sts」は状態遷移表により「どんな状態か」を記憶しています。この値が「0」の時には何も実行している処理がないという判断で寝てしまいます。SLEEPからの復帰は、エレキーが待機状態で期待する動き・・・即ち、パドル操作か本体タクタイルスイッチ押下を待っていることになります。これを実現するために、初期設定関数内では以下のように初期化を行っています。
今回は全入力ポートが外付け抵抗でプルアップしていますから、パドルやスイッチがONになると当該ビットが「1⇒0」に動くため、「アクティブ・ロー」(ネガティブ・エッジ)でコントロールするようにIOCレジスタを設定しています。さらに、OPTION_REGで弱プルアップを禁止しています。
割込処理ではIOCIFをチェックし、立っていればポート読み出しをしてメインラインの処理に渡す・・・というやり方です。
パドル入力はエレキー処理のキューへ渡し(i_key_change)、スイッチ操作はメインラインのキュー(i_put_event)に渡すという形です。
この割込処理が動作するとmain関数のSLEEPから起き上がりNOPからスタートします(このNOPはデバッグ用に入れたまんまになっています)。そしてwhile文を前に戻り、割込処理でキューイングした個々のイベントを「xxx_handler」が覗き込み、実際の処理を開始します。すると、次の動作を待つ状態になるため「sts」が0以外の値となり、メインラインが空転を開始して処理を進め、やがて「sts」が0に戻るとまた寝るという形です。
イベントが起こるまでSLEEPするという作りは、今後もPICで何か作る場合には大いに利用して「省エネ化」を図りたいと思います。
◆ 状態遷移表関連の処理
状態遷移表については、ミニ・エレキーのとりあえずの完成記事に載せてありますが、これをハンドリングする処理は非常に簡単です(以下、uchar : unsigned char)。
記事にある状態遷移表のものとは違いますが、要は「ある状態でやるべき処理があれば、その関数を書いたデータ」を作っておけばいいだけです。処理のないところは「何もしない関数」(上記ではkproc_null:単にリターンのみの関数)を記述して埋めておけばOK・・・なんですが、以下の欠点があります。
1) スカスカの遷移表では、データに無駄が多くなる(上記の場合「kproc_null」だらけに・・・)
2) 横の要素数を2のべき乗の数(2,4,8・・・)にしないと、掛け算処理が必要になる
3) XC8では大きさに制限がある(最大255⇒同様な属性の部分と合わさってしまうため、実際の最大数は作りによる)
案の定、最初のバージョン完成時は何とかなっていましたが、結局3) に引っかかってしまいマイナーチェンジしました。
なお、実プログラムの即値定義として各種のdefine定義を行っていますが、以下「ON:1、OFF:0」というもののみ残す形にしてあります。
◆ BSSの初期化を自動で行わせない
初期設定が必要な変数には初期値を事前に入れておくわけですが、XC8のLinkerはスタートアップに絡む便利そうな関数を勝手に付けてきます。とりわけ、BSSの0クリアに関しては一気にクリアする処理を付けてきますので、「初期設定は確実に自分でやる


この処理の取っ払いは、「MPLAB X IDE」のプロジェクトのプロパティにチェックボックスを外すことで行えます。

◆ SLEEP機能を「前向きに使う」
C言語のmain関数は以下のようになっています。
void main(void) { initializer(); // 初期設定 while (1) { key_handler(); // キー処理 event_handler(); // イベント処理 if (sts == 0) { // 処理無し・・・ SLEEP(); // イベント待ち NOP(); } } } |
メインループで「やることがないぞ

OPTION_REG = 0b11001000; // No WPU, Prescaler 1/2 : IOCAN = 0b00001111; // Negエッジ IOCIE = ON; // IOC使用 |
今回は全入力ポートが外付け抵抗でプルアップしていますから、パドルやスイッチがONになると当該ビットが「1⇒0」に動くため、「アクティブ・ロー」(ネガティブ・エッジ)でコントロールするようにIOCレジスタを設定しています。さらに、OPTION_REGで弱プルアップを禁止しています。
割込処理ではIOCIFをチェックし、立っていればポート読み出しをしてメインラインの処理に渡す・・・というやり方です。
if (IOCIF == ON) { if ((IOCAF&0b00000011) != 0) { i_key_change(); // キー入力確認 IOCAF &= 0b11111100; } if ((IOCAF & 0b00001100) != 0) { i_put_event(); // SW押下 IOCAF &= 0b11110011; } IOCIF = OFF; } |
パドル入力はエレキー処理のキューへ渡し(i_key_change)、スイッチ操作はメインラインのキュー(i_put_event)に渡すという形です。
この割込処理が動作するとmain関数のSLEEPから起き上がりNOPからスタートします(このNOPはデバッグ用に入れたまんまになっています)。そしてwhile文を前に戻り、割込処理でキューイングした個々のイベントを「xxx_handler」が覗き込み、実際の処理を開始します。すると、次の動作を待つ状態になるため「sts」が0以外の値となり、メインラインが空転を開始して処理を進め、やがて「sts」が0に戻るとまた寝るという形です。
イベントが起こるまでSLEEPするという作りは、今後もPICで何か作る場合には大いに利用して「省エネ化」を図りたいと思います。
◆ 状態遷移表関連の処理
状態遷移表については、ミニ・エレキーのとりあえずの完成記事に載せてありますが、これをハンドリングする処理は非常に簡単です(以下、uchar : unsigned char)。
static void kproc_null(); static void kproc_0000(); static void kproc_0001(); static void kproc_0002(); static void kproc_0103(); : static void kproc_0503(); static void (*mtx_p[6][4])() = { {kproc_0000,kproc_0001,kproc_0002,kproc_null}, // 00 {kproc_null,kproc_null,kproc_null,kproc_0103}, : {kproc_null,kproc_null,kproc_null,kproc_0503} // 05 }; uchar ksts; : static void handler(uchar evno) { (mtx_p[ksts][evno])(); } |
記事にある状態遷移表のものとは違いますが、要は「ある状態でやるべき処理があれば、その関数を書いたデータ」を作っておけばいいだけです。処理のないところは「何もしない関数」(上記ではkproc_null:単にリターンのみの関数)を記述して埋めておけばOK・・・なんですが、以下の欠点があります。
1) スカスカの遷移表では、データに無駄が多くなる(上記の場合「kproc_null」だらけに・・・)
2) 横の要素数を2のべき乗の数(2,4,8・・・)にしないと、掛け算処理が必要になる
3) XC8では大きさに制限がある(最大255⇒同様な属性の部分と合わさってしまうため、実際の最大数は作りによる)
案の定、最初のバージョン完成時は何とかなっていましたが、結局3) に引っかかってしまいマイナーチェンジしました。
static void kproc_null(); static void kproc_0000(); static void kproc_0001(); static void kproc_0002(); static void kproc_0103(); : static void kproc_0503(); static void kproc_00(uchar); static void kproc_01(uchar); static void kproc_02(uchar); static void kproc_03(uchar); static void kproc_04(uchar); static void kproc_05(uchar); static void (*mtx_p[6])(uchar) = { kproc_00,kproc_01,kproc_02, kproc_03,kproc_04,kproc_05 } uchar ksts; : static void handler(uchar evno) { (mtx_p[ksts])(evno); } static void kproc_00(uchar evno) { switch (evno) { case 0 |
ミニ・エレキーのバージョンアップ完了!
2013-09-22
漸く一通りの動作確認を終え、ミニ・エレキーのバージョンアップ(書換可能なメッセージ・キーヤー機能、オートCQ機能の具備)を済ませました。
当初は固定メッセージだったため、スイッチ操作で簡単に拾える「6Ch」としていましたが、最終的にEEPROMへメッセージを格納してその書換ができるようになったため「4Ch」とし、立ち上げ時に2パターンの選択ができるようにしました。コンテスト狙いのため、とりあえず以下のようにChをアサインして個々に「意味」を持たせました。
Ch1:143バイト CQ送出 「CQ TEST DE・・・」
Ch2:31バイト コンテストNo.送出 「TU 5NN12P BK」
Ch3:31バイト コールサイン送出 「JM1DPL」
Ch4:31バイト 相手応答後コンテストNo.送出 「5NN12P」
勿論、単純にJCC/Gサービス等の長いCQ送出マシンとして「Ch1のみ」で賄えますし、要は工夫次第。
一方の「CQマシン化」はCh1のメッセージを繰り返し送出するもので、とりあえず1-9秒間隔で送出できるようにしました。この間隔時間は「Ch0」に1文字で入れるようにし、書換操作が同じようにできる形にまとめました。
まぁ、ここまで作り込んでおけばかなり活躍して貰えそうです。修理から戻ってきたIC-821での送信確認@ダミーも完了し、キーイングも問題なしです
実は、ブレッドボードでお茶を濁していた発振器もケースに入れてみました。メッセージ書換にはリグのサイドトーンでも十分ですが、ちょっとデバッグには手間だったため金曜の晩に急造し、昨日の午前中と夜の「エレキーの仕上げ工程」で参入・・・もっと早く作っておいた方がよかったかな

秋月の100円ケースに入れましたが、取り回しは確実にスッキリ。相変わらず小型スピーカ接続にしてあります。入力を少し工夫すると、格好の「導通テスタ」になりそうですから、様子を見てさらに改造するかも
これで、ひとまずこのエレキーのプログラム作成は終了としますが、次回はもう少し本格的なものをこしらえようかと思っています。LCDを付けないとEEPROM書換が難儀・・・と思っていましたが、今回の方法でもいけそうなんで、音モニタできる機能とメッセージを多くする工夫をしつつ、押しボタンを増やして操作性を上げたもの・・・この辺りで十分かと思えてきました。
なお、このちっこいPICに組み込んだプログラムについては、要点をポツポツと披露しようと思っていますので、興味のある方は「Don't miss it
」
当初は固定メッセージだったため、スイッチ操作で簡単に拾える「6Ch」としていましたが、最終的にEEPROMへメッセージを格納してその書換ができるようになったため「4Ch」とし、立ち上げ時に2パターンの選択ができるようにしました。コンテスト狙いのため、とりあえず以下のようにChをアサインして個々に「意味」を持たせました。
Ch1:143バイト CQ送出 「CQ TEST DE・・・」
Ch2:31バイト コンテストNo.送出 「TU 5NN12P BK」
Ch3:31バイト コールサイン送出 「JM1DPL」
Ch4:31バイト 相手応答後コンテストNo.送出 「5NN12P」
勿論、単純にJCC/Gサービス等の長いCQ送出マシンとして「Ch1のみ」で賄えますし、要は工夫次第。
一方の「CQマシン化」はCh1のメッセージを繰り返し送出するもので、とりあえず1-9秒間隔で送出できるようにしました。この間隔時間は「Ch0」に1文字で入れるようにし、書換操作が同じようにできる形にまとめました。
まぁ、ここまで作り込んでおけばかなり活躍して貰えそうです。修理から戻ってきたIC-821での送信確認@ダミーも完了し、キーイングも問題なしです

実は、ブレッドボードでお茶を濁していた発振器もケースに入れてみました。メッセージ書換にはリグのサイドトーンでも十分ですが、ちょっとデバッグには手間だったため金曜の晩に急造し、昨日の午前中と夜の「エレキーの仕上げ工程」で参入・・・もっと早く作っておいた方がよかったかな


秋月の100円ケースに入れましたが、取り回しは確実にスッキリ。相変わらず小型スピーカ接続にしてあります。入力を少し工夫すると、格好の「導通テスタ」になりそうですから、様子を見てさらに改造するかも

これで、ひとまずこのエレキーのプログラム作成は終了としますが、次回はもう少し本格的なものをこしらえようかと思っています。LCDを付けないとEEPROM書換が難儀・・・と思っていましたが、今回の方法でもいけそうなんで、音モニタできる機能とメッセージを多くする工夫をしつつ、押しボタンを増やして操作性を上げたもの・・・この辺りで十分かと思えてきました。
なお、このちっこいPICに組み込んだプログラムについては、要点をポツポツと披露しようと思っていますので、興味のある方は「Don't miss it

懲りずにエレキーのバージョンアップ
2013-09-18
何やら取り憑かれたように、夜な夜なエレキーの改良を進めていたりします
やはり、メッセージキーヤー機能の「完璧なる具備」を目指し、台風到来の三連休も暇を見つけてはあれこれ構想を練っていましたが、漸く「大団円」に向かっています。

これまでのデバッグではTM-x55のサイドトーンを使っていましたが、台風の最中に「やっぱ、低周波発振器が要る
」と思い、買っておいたはずのLMC555を探しても見当たらず・・・結局、このエレキーと同じPICで方形波発振器を作り、ブレッドボードに組み立ててしまいました。低周波出力の直後にコンデンサによる簡単なLPFを付けると、前にBPFを組み込んでいたスピーカで結構いい音がしますし、圧電素子(ブザーじゃないですよ)でも音が小さいだけでちゃんとモニタできるものが完成。TS-590のサイドトーンを信じて
で800Hzへの合わせ込み(うねりが小さくなるところへの追い込み)をプログラム論理で行い、まずまずの出来映えになりました。
実は、エレキーの方はPICのプログラムメモリ限界が近づいてきたため、またしても重箱の隅を突くような作業を経て、何とか256バイトほどまで空き領域を拡げる一方、とりあえず「8Ch」のEEPROM上のメモリ領域を準備、PICkit3で書き込む際にEEPROMの所定位置にメッセージを書き込んで、各Chが正しく動作するところまで確認。その後、個々のCh書き換えをどうするか考えた挙げ句、以下のような手順で行うようなプログラムを追加作成しました。
1) 赤青ボタン両方を押しながら電源ONでメッセージ書き換えモードへ移行
2) エレキーが「?」を送出してメモリ番号投入待ちへ
3) 0-7の数字をモールス符号でパドル入力して書き換えChを指定
4) きちんと読み取れるとエレキーが「R」を送出、文字や範囲外の数字なら「?」を送出して再度待ち状態へ
5) Chが決まると1文字パドルで入力する毎に青ボタン押下、正しく検出すると「R」、変な文字なら「?」を送出
6) パドルからの文字入力直後に赤ボタンを押すと、「R」送出後、その文字の後ろに「1文字空白」が挿入される
7) そのChの文字数最大、或いはパドル入力せずに赤ボタンを押すと、書き換えたChのメッセージを一通り送出して終了
・・・と書くのは簡単なんですが、パドル操作の「記録」、符号からアルファベットor数字の逆引きなどの処理を狭いプログラムエリアに押し込むのは結構大変でした。結果的に元々のプログラム部分には、そんなに大袈裟な改造は必要無く、ほぼ独立した機能を追加するイメージで済みました。
序でに、設定した送出速度を記憶しておき、上記の書き換え処理中はこのエレキーの最低速度(15WPM)にして入力ミスを減らし、終わったら元の速度に戻すようにしました。このスピード感覚は、最初に送出される「?」で何となく掴んでおくとスムーズに行きます。
ちなみにこの記録方式は、前述したように「タイミング論理による記録」でなく「パドル操作を記録」していますので、入力された文字が正しく認識されれば、きちんとした符号になって送信されます。ここがミソかも
まぁ、8ピンPICにC言語では無理なプログラミングと思ったら、案外行けちゃってます。後は、CQマシーンとして「n秒後に繰り返す機能」が入れば殆ど「パーフェクト」でないかな
結局、何だかんだと機能追加していたら「本気モード」になってしまいました
こうなると「サイドトーンを付けなかった」のがちと痛いですが、メッセージ書き換え機能付きミニ・キーヤーが完成しそうですよ


これまでのデバッグではTM-x55のサイドトーンを使っていましたが、台風の最中に「やっぱ、低周波発振器が要る


実は、エレキーの方はPICのプログラムメモリ限界が近づいてきたため、またしても重箱の隅を突くような作業を経て、何とか256バイトほどまで空き領域を拡げる一方、とりあえず「8Ch」のEEPROM上のメモリ領域を準備、PICkit3で書き込む際にEEPROMの所定位置にメッセージを書き込んで、各Chが正しく動作するところまで確認。その後、個々のCh書き換えをどうするか考えた挙げ句、以下のような手順で行うようなプログラムを追加作成しました。
1) 赤青ボタン両方を押しながら電源ONでメッセージ書き換えモードへ移行
2) エレキーが「?」を送出してメモリ番号投入待ちへ
3) 0-7の数字をモールス符号でパドル入力して書き換えChを指定
4) きちんと読み取れるとエレキーが「R」を送出、文字や範囲外の数字なら「?」を送出して再度待ち状態へ
5) Chが決まると1文字パドルで入力する毎に青ボタン押下、正しく検出すると「R」、変な文字なら「?」を送出
6) パドルからの文字入力直後に赤ボタンを押すと、「R」送出後、その文字の後ろに「1文字空白」が挿入される
7) そのChの文字数最大、或いはパドル入力せずに赤ボタンを押すと、書き換えたChのメッセージを一通り送出して終了
・・・と書くのは簡単なんですが、パドル操作の「記録」、符号からアルファベットor数字の逆引きなどの処理を狭いプログラムエリアに押し込むのは結構大変でした。結果的に元々のプログラム部分には、そんなに大袈裟な改造は必要無く、ほぼ独立した機能を追加するイメージで済みました。
序でに、設定した送出速度を記憶しておき、上記の書き換え処理中はこのエレキーの最低速度(15WPM)にして入力ミスを減らし、終わったら元の速度に戻すようにしました。このスピード感覚は、最初に送出される「?」で何となく掴んでおくとスムーズに行きます。
ちなみにこの記録方式は、前述したように「タイミング論理による記録」でなく「パドル操作を記録」していますので、入力された文字が正しく認識されれば、きちんとした符号になって送信されます。ここがミソかも

まぁ、8ピンPICにC言語では無理なプログラミングと思ったら、案外行けちゃってます。後は、CQマシーンとして「n秒後に繰り返す機能」が入れば殆ど「パーフェクト」でないかな


こうなると「サイドトーンを付けなかった」のがちと痛いですが、メッセージ書き換え機能付きミニ・キーヤーが完成しそうですよ

エレキーの「ー」 (了)
2013-09-14
TM-x55兄弟に相応しいミニ・エレキーがようやく完成しました
また何かに気づいてプログラムの改良はやるかも知れませんが、一応「Ver 1.0」扱いとしてみました。
◆ 諸元
ちょっとまじめな諸元です
◆ 回路図とハードウェアのポイント
回路図は以下の通りです。

PICのリーク電流は非常に小さいため、安定に動く程度のプルアップ抵抗値(10KΩ)としましたが、キーイング時は0.3乃至0.6mAを消費します。チャタ防止用には0.0022μFの積層セラコンを入れましたが、10KΩとの組み合わせで特に問題は起きていません。暇になったら波形観測してみて、もう少し大きな値のプルアップ抵抗でいけないか、次の「本格エレキー」の参考にしよう・・・って、いつになるんだろう
キーイング回路は、手持ちでhFEが一番大きかったNPNタイプでオープンコレクタとし、逆接保護用に古~いダイオードを入れておきました。相手が真空管リグでなければこの辺りは選択肢も広いんで、手持ちの「古めの半導体」を消費するには打って付けかも知れません。ちなみに、このトランジスタのhFEは実測で450以上ありましたから、多分20mA程度のキーイングは可能、キーイング時の(このトランジスタに関わる)消費電流もかなり小さくできた(50μAくらいかな
)と思います。
キーイング時の消費電流が最大でも1mA程度であることと、電源が「電池」であることから、パスコンはPICの安定動作用の0.1μFのみにしました。また、「MODE」はトグルスイッチで動作切り替えするだけのため、「チャタ取り」(セラコン)は省略しました。
まぁ総じて、普通~の回路に落ち着きました
◆ ソフト処理のポイント
(1) 状態遷移表
今回は「状態遷移表」(状態と発生イベントのマトリクス)を作り、キーイング検出や各種のタイマーON/OFFが設計してあります。状態遷移表云々は他に譲りますが、要は極力「if 文」が無いように設計しました。こうすることで、この表との睨めっこでデバッグが机上(と言ってもExcelですが・・・)で粗方終えられて非常に楽になります。
また、掛け算命令が処理時間を引っ張らぬよう、「ビットシフト」で済ますことができる演算に収束させるようにしました。例えば変数nの値を5倍したければ、「nを2ビット左シフトしたものにnを足す」といった方法です。これにより、妙な演算ライブラリが展開されず、かつ速度も稼げます。
状態遷移表も、イベント数を2のべき乗・・・といってもあんまり大きな数にはできないんですが、ひとまず「最大8」と決め、「状態番号を3ビット左シフト+イベント番号」で処理分岐できるようにしました。if 文いらずで結構いい感じです・・・って、あんまり伝わらないかな
見てもあんまり参考にならないと思いますが、キーヤー処理の状態遷移表を・・・きゃ~ハズカスィ

ちなみに、割込処理からのイベント受付には簡単なキューを設け、その中にイベント番号を放り込んで割込処理は終了し、メインループの中でイベントを拾うようにしています。ですから、タイマが比較的正確に割り込みを発生させても、メイン処理でそれを認識するまでに少しタイムラグが出てしまいますが、毎度同程度のラグに落ち着くためこの辺りは目を瞑っています。
また、メインループも「何もしないとき」・・・要は、上の状態遷移表にある「空き」の時はSleepしていますので、待機時間が支配的なエレキーの処理の作りとしては十分かと思います。
(2) メッセージキーヤー機能の工夫
もう一つのポイントは、最後に盛り込んだ「メッセージキーヤー機能」です。これは当初、2つのタクタイルスイッチの各々にメッセージを括り付けで考えていたんですが、これらのスイッチを押しながら立ち上げることで、幾つかのメッセージを付け替えようとを思いつき、結局6通りのメッセージを切り替えられるようにしました。

タクタイルスイッチの横のトグルスイッチは、写真の状態ではメッセージキーヤー機能、向こうに倒すと速度調整(青が低速、赤が高速)になるスイッチですが、電源ON時にこのトグルスイッチの位置と青・赤のタクタイルの押下状態によって6種類のメッセージが選べるようにしました。青と赤の同時押下を加えると全部で8通りになるんですが、まぁそこまではしませんでした。
この機能は、当初は「QRPでS&P主体なら要らないか・・・」とも思ったんですが、V/UHFで5W運用では案外呼ばれるかも知れず(っていうか、この間の6&Dでは呼ばれたし・・・)、付けてしまうと結構便利そうです。一丁前に「CQマシーン」にもなってしまいました
◆ 総括
PICを用いた作り物は2作目ですが、やはりC言語の開発効率の良さは素敵だなぁ・・・と思いました。無償版でプログラムが冗長になってしまう部分は、メモリの大きいPICを使うようにすればよく、結構いろいろなものが簡単に作れそうです。
また、プラケースはハンドドリル1本で加工できちゃう手軽さもますます気に入りました。裏面にきちんと銅箔テープを貼れば、小物であればある程度安定したものが作れそうですし、色・形のバリエーションも沢山ありますから、今後も多用すること間違いなしですね。
ちょっとした作り物のつもりがここ1週余りは「帰ってきたらやる作業」となり、結構夜更かしもしましたが、まぁまぁの完成度で締め括れました。実戦のACAGが待ち遠しいなぁ

◆ 諸元
ちょっとまじめな諸元です

項目 | 内容 | 備考 |
動作仕様 | スクイーズモードB | |
長短点メモリ | 有り | |
メモリ禁止 | 短点の50% | 余計な長短点送出防止 |
ウエイト | 長点:短点 1:3固定 | |
メッセージ 送出機能 | 6メッセージ内蔵 同時使用2パターン | 電源投入時に選択 プログラムでプリセット |
送信速度 | 15-40WPM | スイッチ操作により送信中 でも可変可能 |
KEY出力 | オープンコレクタ | 20mAまでキーイング可能 |
電源 | 単4×2本 | |
消費電流 | 待機時:22uA 送信時:1.1mA Max | 送信時平均0.7mA程度 |
◆ 回路図とハードウェアのポイント
回路図は以下の通りです。

PICのリーク電流は非常に小さいため、安定に動く程度のプルアップ抵抗値(10KΩ)としましたが、キーイング時は0.3乃至0.6mAを消費します。チャタ防止用には0.0022μFの積層セラコンを入れましたが、10KΩとの組み合わせで特に問題は起きていません。暇になったら波形観測してみて、もう少し大きな値のプルアップ抵抗でいけないか、次の「本格エレキー」の参考にしよう・・・って、いつになるんだろう

キーイング回路は、手持ちでhFEが一番大きかったNPNタイプでオープンコレクタとし、逆接保護用に古~いダイオードを入れておきました。相手が真空管リグでなければこの辺りは選択肢も広いんで、手持ちの「古めの半導体」を消費するには打って付けかも知れません。ちなみに、このトランジスタのhFEは実測で450以上ありましたから、多分20mA程度のキーイングは可能、キーイング時の(このトランジスタに関わる)消費電流もかなり小さくできた(50μAくらいかな

キーイング時の消費電流が最大でも1mA程度であることと、電源が「電池」であることから、パスコンはPICの安定動作用の0.1μFのみにしました。また、「MODE」はトグルスイッチで動作切り替えするだけのため、「チャタ取り」(セラコン)は省略しました。
まぁ総じて、普通~の回路に落ち着きました

◆ ソフト処理のポイント
(1) 状態遷移表
今回は「状態遷移表」(状態と発生イベントのマトリクス)を作り、キーイング検出や各種のタイマーON/OFFが設計してあります。状態遷移表云々は他に譲りますが、要は極力「if 文」が無いように設計しました。こうすることで、この表との睨めっこでデバッグが机上(と言ってもExcelですが・・・)で粗方終えられて非常に楽になります。
また、掛け算命令が処理時間を引っ張らぬよう、「ビットシフト」で済ますことができる演算に収束させるようにしました。例えば変数nの値を5倍したければ、「nを2ビット左シフトしたものにnを足す」といった方法です。これにより、妙な演算ライブラリが展開されず、かつ速度も稼げます。
状態遷移表も、イベント数を2のべき乗・・・といってもあんまり大きな数にはできないんですが、ひとまず「最大8」と決め、「状態番号を3ビット左シフト+イベント番号」で処理分岐できるようにしました。if 文いらずで結構いい感じです・・・って、あんまり伝わらないかな

見てもあんまり参考にならないと思いますが、キーヤー処理の状態遷移表を・・・きゃ~ハズカスィ


ちなみに、割込処理からのイベント受付には簡単なキューを設け、その中にイベント番号を放り込んで割込処理は終了し、メインループの中でイベントを拾うようにしています。ですから、タイマが比較的正確に割り込みを発生させても、メイン処理でそれを認識するまでに少しタイムラグが出てしまいますが、毎度同程度のラグに落ち着くためこの辺りは目を瞑っています。
また、メインループも「何もしないとき」・・・要は、上の状態遷移表にある「空き」の時はSleepしていますので、待機時間が支配的なエレキーの処理の作りとしては十分かと思います。
(2) メッセージキーヤー機能の工夫
もう一つのポイントは、最後に盛り込んだ「メッセージキーヤー機能」です。これは当初、2つのタクタイルスイッチの各々にメッセージを括り付けで考えていたんですが、これらのスイッチを押しながら立ち上げることで、幾つかのメッセージを付け替えようとを思いつき、結局6通りのメッセージを切り替えられるようにしました。

タクタイルスイッチの横のトグルスイッチは、写真の状態ではメッセージキーヤー機能、向こうに倒すと速度調整(青が低速、赤が高速)になるスイッチですが、電源ON時にこのトグルスイッチの位置と青・赤のタクタイルの押下状態によって6種類のメッセージが選べるようにしました。青と赤の同時押下を加えると全部で8通りになるんですが、まぁそこまではしませんでした。
この機能は、当初は「QRPでS&P主体なら要らないか・・・」とも思ったんですが、V/UHFで5W運用では案外呼ばれるかも知れず(っていうか、この間の6&Dでは呼ばれたし・・・)、付けてしまうと結構便利そうです。一丁前に「CQマシーン」にもなってしまいました

◆ 総括
PICを用いた作り物は2作目ですが、やはりC言語の開発効率の良さは素敵だなぁ・・・と思いました。無償版でプログラムが冗長になってしまう部分は、メモリの大きいPICを使うようにすればよく、結構いろいろなものが簡単に作れそうです。
また、プラケースはハンドドリル1本で加工できちゃう手軽さもますます気に入りました。裏面にきちんと銅箔テープを貼れば、小物であればある程度安定したものが作れそうですし、色・形のバリエーションも沢山ありますから、今後も多用すること間違いなしですね。
ちょっとした作り物のつもりがここ1週余りは「帰ってきたらやる作業」となり、結構夜更かしもしましたが、まぁまぁの完成度で締め括れました。実戦のACAGが待ち遠しいなぁ
