2021年8月24日火曜日

6809SBCボードやFM-7にArduinoを接続してRTCやLCDを制御

 6809SBCボードとFM-7にArduinoを接続してRTCやLCDを制御してみました

現在では様々なセンサー等が気軽に入手できて、電子工作好きには楽しい時代ですが、シングルボードマイコンやFM-7などにもそれらのセンサーを接続してみたいと考えていました。

今までにも、6809/6802Dualボードに搭載しているPIA(6821)を利用してRTC(ZS-042)を接続して、Flex9の起動時に時刻を自動的に読み込ませて、起動時の時刻の手入力を省略したりしていましたが(下記のブログで紹介)、もっと他のセンサーなども接続したいと思うようになりました。

  2018年11月3日のブログ「PIAのみでRTCからの時刻の読み書きができました」

上記のPIAにRTCを接続した際には、I2Cによる通信プログラムをアセンブラで作成しましたのでかなり時間がかかりました。センサー毎にアセンブラによるプログラムを作成するのは非現実的ですので、間にArduinoのようなマイコンを挟めばよいのではないかと思いつきました。手持ちには数種類のマイコンがありますが、とりあえず最も手軽そうなArduinoで始めて性能に不満が出たら他のマイコンに置き換えれば良いと思って始めましたが、思ったよりも難しくて一ヶ月余りもかかってしまいました。

難しかったのは、6809側ではアセンブラによるプログラムでI2C通信するのですが、それに対するArduino側のC++(?)のプログラムの応答との関係が良く分からないことでした。

とりあえず、Arduinoを通してRTCとLCDを制御できましたので報告します。

全体の接続を下に示します。6821PIAとArduino間をハードI2Cで通信し、Arduinoと各センサー間はソフトI2Cで通信します。ソフトI2CではArduinoがマスターにしかなれないのでこのような構成となりました。



接続図

(1)ハードの設定

実際の実験の様子です。上部に見えるのが6809/6802Dualボードで、下にあるのがArduinoとセンサーです。


実験風景

ブレッドボード上の中央がRTC(ZS-042)、右が8桁x2行のLCD(AQM0802A)で、RTCから読んだ日時を表示しています。どちらも5V版なので、Arduinoに直結できています。またI2Cのプルアップ抵抗は、ハードI2C側は6821内部の抵抗を、ソフトI2C側はArduino内部の抵抗を利用していますので、単純にセンサーをArduinoに接続するだけで済んでいます。
(左のセンサーは他の実験のもので無関係です。)

センサー部のアップ


6809/6802Dualボードに接続した場合の結果です。アセンブラによるプログラムでArduinoに指示を送り、ArduinoがRTCを読んで結果を送ってきています。(とりあえずの実験なので単純にデータを順に表示していますが、左から年月日と時分秒です。)


6809/6802Dualボードによる結果


続いて、FM-7でも同様な実験を行ってみました。


右に装着されているのが6821PIAボード



使用したのは、以前報告したブログ「FM-7/77用拡張PIAボードとP-ROMライタ」(2020年6月26日)で製作したP-ROMライタ用の6821PIAボードです。



FM-7用6821PIAボード


6809ボードで用いたアセンブラプログラムをサブルーチン化して、F-BASICのプログラムから呼び出す形で使用しています。F-BASICのプログラムはサブルーチンを呼び出すことと結果を表示するためだけに用いています。

FM-7による結果


(2)プログラム作成

プログラム作成上で私が引っかかった点を列挙します。

1.ソフトI2CではArduinoはマスターにしかなれず、スレーブにはなれない。

 → 最初は6809側をソフトI2Cで、センサー側をハードI2Cでと考えていたのですが、結局、逆にせざるを得ませんでした。

2.RTC(ZS-042)の制御ICであるDS3231用のライブラリDS3231.hはI2Cのアドレスを決め打ちしておりソフトI2Cには対応していない(ようです)。

 → ライブラリを使わずに直接DS3231のレジスタを操作することになりました。

3.Arduinoで標準のWire.hでの割り込み関数 Wire.onRequest(requestEvent); や Wire.onReceive(receiveEvent); を6809ボードからのアセンブラプログラムでどうしたら起動させることができるか。また、Wire.requestFrom(ID, no); は使えないが、その代わりにどのようにしたらリクエストできるのか。

 → 6809側からArduinoに何かのデータを書き込むと onReceive関数が反応するので、この receiveEvent関数内で送られてきたデータを読み込んで(必要がないので)捨てる。6809側にデータを送り返す作業は onRequest関数で呼び出される requestEvent関数内で行うという形で通信することができました。(receiveEvent関数では6809側に送り返すことはできませんでした。)


参考までに6809側のプログラムのソースを示します。

 


以上、あちこち引っかかりながらも何とか目的を達することができましたが、次に何とかしたいと考えているのは、Windows側からUSBを通してArduinoにデータを送り、それをさらに6809/6802DualボードやFM-7に送ることです。

とりあえず、現在の状態でのプログラム(6809側のSBC_I2C.txtとそのバイナリ、Arduino側のsbc_i2c.ino、FM-7用のFBI2C、FBI2CSUBとその保存形式のFBI2CSUB2の6本)をOneDriveに上げておきます。