2018年5月3日木曜日

ArduinoでSin波形を出力させる

アナログ出力のために
Arduino UNOにはアナログ出力がないので、デジタル出力をアナログに変換する。
外部にDAコンバータを用意する方法もあるが、簡易にはデジタル出力を利用して抵抗でDA変換をしてみる。
この辺は以下のサイトが詳しい。
http://mitt.la.coocan.jp/pic/pic7_16.html

8ビットのDA変換をするために、D2〜D9を使って図のような回路を組んだ。


予めSinの計算をして、配列に格納しておいたデータを使ったが、周期は13ms(約77Hz)となった。その都度Sinの計算をしたときには67ms(約15Hz)であった。



スケッチの一部を書くと、


予め計算していたSinData[kakudo]の8bitデータ(0x0000〜0x00ff)を、1ビットずつデジタル出力にHIGH,またはLOWで書き出す方法である。

スケッチを工夫して速度を上げる
デジタル出力にパラレルに出力できたらいいのに、と思っていたら、ちゃんとあった。
上と同じ内容を次のように変更。


PORTDはデジタル出力の0から7だが、0と1はシリアル通信に使われているので、2bitシフトして使っている。その分PORTBで2ビットを出力している。

このプログラムでSin波を出力させると、Sin波形の途中に異なった値のデータが、ヒゲのように出てしまう。原因はPORTDとPORTBの出力に時間差があるためで、アナログ値がその間本来と異なった値となってしまったため。
途中にヒゲが出ている
PORTDとPORTBの出力時間差を極力減らすため、次のように変更する。


PORTDとPORTBの出力の時間差が原因であることを確認するために、②を挿入してみた。
②がないと、ヒゲはほとんどなく、②を入れると、その時間だけ異なったデータが出る。
ヒゲがなくきれいな波形となる
 これによるSin波の周期は1.1ms、周波数は約910Hzである。forループ1回あたり(1度あたり)約3μsであるので、このくらいが限界かもしれない。周波数を上げるためには、5度おきに間引いて計算するなどが考えられるが、当然波形としては段差が目立ってきたなくなる。
5度おきに計算。階段状になる。

外部のDAコンバータ、MCP4726(12bit)を使用した場合


インターフェースはI2Cで、速さが100kHz、400kHz、3.4MHzと3段階あるようだが、その設定の仕方がよくわからない。しかし実際にSCL波形をオシロスコープで見ると、10μs周期なので、100kHzでの通信と考えられる。
予めSinθの計算をしたうえで出力させたが、12ビットで転送時間もかかるのか、出力の周期は115ms(約8.7Hz)となり、とても遅い。(単純計算では1度あたり320μsかかったことになる。通信量からするとこんなものか。)ただ、波形としてはヒゲもなく大変きれいである。0.5度ごとに計算して出力させるともっときれいになるだろう。

12ビットのDACなので、1度につき2バイト使って360度計算すると、RAMの54%を使ってしまった。
波形はヒゲもなくきれい。しかし遅い。




インターフェースをSPIにしてみる
I2Cは100kHzに対し、SPIは数十Mbpsも可能というので、次のような回路を組んでみた。

シフトレジスタは別基板に作った
シフトレジスタ74HC595を使ってデータを転送し、その出力を抵抗でDA変換するものである。ラッチで一斉にデータが変わるので、ヒゲは出ない。
このICは秋月電商で販売している7セグメントLED用に使われているもので、SPI.transfer()のコマンドでデータを転送する。
スピードアップのため、予めSinθを計算させておいてSinData[]に保存、その後順に出力する。

この結果、Sin波形の周期は約4.5ms(222Hz)となった。ラッチの周期は12μsだが、8ビットのデータ転送自体は2μsで終了している。digitalWriteの時間が結構かかっているようだ。

そこで、digitalWriteの代わりにPORTBコマンドを使ってみたのが以下のプログラムである。


ラッチにD10を使用しているので、直接制御している。

この結果、Sin波の周期は1.1msと、Arduinoのデジタル出力に直接抵抗をつけた場合(PORTコマンド使用)とほとんど変わらなくなった。ラッチの周期は3μsである。波形としては当然ヒゲもなくきれいなSin波になっている。

信号のタイミングを見ると、上がラッチ出力で、下がシリアルデータである。ラッチをLにした後、シリアルデータを出力。8ビットのデータを約2μsで送出し、その後ラッチをHにすることで、シフトレジスタの出力が変化する。

Raspberry-Pai と Arduinoで簡易オシロスコープを作る

九州工業大学から、Arduinoを使った簡易オシロスコープが公表されており、実際に試した人が多かったのでトライしてみた。しかし、なかなかすんなりとは行かなかったので、メモとして記録しておく。

九州工業大学から公表されているページは次の通り。
http://www.iizuka.kyutech.ac.jp/faculty/physicalcomputing/pc_kitscope/


これに従って作業を進めれば良いだけのことだが、PCとArduinoを組み合わせてオシロスコープにするので、PC側の表示画面も用意しないといけない。これはProcessingを使って作られているとのこと。
Arduinoは今Raspberry-Paiで動いているので問題ないが、ProcessingをRaspberry-Paiで動かす必要がある。
まずはProcessingのインストールから。

ダウンロードは
https://processing.org/download/
から行う。
ラズパイなので、LinuxARMv6hf を選択するが、すぐ寄付のページになってしまう。寄付をせずにダウンロードもできるようだが、どこからどう進むのかが全くわからない。「寄付をせずにダウンロード」といったチェックマークも見当たらない。ネット上で探してみると、すんなりダウンロードできた例もあり(ほとんどがそうだろうが)、ブラウザによって違いがあるのかもしれない。ちなみに手元のスマホでやってみたら、同じように寄付のページは出るものの、並行してダウンロードが行われていた。もしかしてと思って見たが、Daunloadsのホルダーには、それらしきファイルは見当たらなかった。

結局「LinuxARMv6hf」にマウスのカーソルを持っていって右クリック、メニューから「リンクのアドレスをコピー」を選択して、新しいタブでアドレスを指定してダウンロードを行った。
ダウンロードしようとすると、この寄付の画面が出て、寄付をしないと進めない?
カーソルを「LinuxARMv6hfに合わせたら、右クリックでメニューを表示させ、
「リンクのアドレスをコピー」を選択。新しいタブに貼り付けてダウンロードを行う。

ラズパイへのインストールは不慣れで苦労したが、単に勉強不足というだけのこと。結局問題なくインストールが完了し、デスクトップ上にアイコンもできた。立ち上げてみると、ArduinoのIDEのような感じでスケッチの書き込みウィンドウが立ち上がる。

続いてProcessing、Arduinoのスケッチをダウンロードする。九州工業大学のページにはダウンロードのアイコンがあるので、そこをクリックする。しかし・・・。
「サーバーへのリクエストは拡張機能によってブロックされています。」
という表示が出てダウンロードできない。
このメッセージで検索をして解決法を探した。その結果ブラウザの「Chromiumの設定」メニューから、「その他のツール」→「拡張機能」を選択すると、いくつかのアイコンが並んでいて、その一つ「uBlock Origin 1.15.2」の「有効」についているチェックを外すことでダウンロードができるようになった。

ダウンロードできない

uBlock Origin 1.15.2」の「有効」についているチェックを外す








後はダウンロードしたProcessing、Arduinoのそれぞれのスケッチを動かすだけだが、Processingでオシロスコープのスケッチを立ち上げた状態では、Arduinoのボード書き込みがエラーとなった。止めたらOKだったので、余計なプログラムは止めてボードの書き込みをする必要があるようだ。
arduinoを動作させていないと、この画面が出る

オシロスコープとして使うためには、Arduinoに若干の配線が必要のようだが、とりあえずPCの表示も含めて動きそうかどうかはボードを繋いだだけで確認できる。

使用環境
Raspberry Pai3 ModelB V1.2(Raspbian
Arduino UNO(互換品KumanUNO)、nano(互換品Elegoo) ボードバージョン1.6.20で使用。(1.6.21ではnanoへの書き込みがエラーになるため)

オシロスコープらしくする
Arduino Nanoをケースに入れ、BNCのコネクタをつけてみたのが下の写真。ケースは100円ショップにあったカードケース。測定用ケーブルはアマゾンから2本347円で購入した、先端がミノムシクリップになっているもの。(クリップは付替え)

ケースは105X75X30mmのカードケース
Arduinoで発生させたSin波形を測定中。
これは外部にDAコンバータをつけたもの。


実際に波形を表示させてみる
やはりArduinoでスケッチを作り、サイン波形を出力させたものを表示してみた。
Digital OUTを8ビット使い、抵抗で簡易にDAコンバートしたものである。
(詳細は別途)
1度ごとに計算しているので波形が階段状になっているのがわかる。
波形出力は0〜5Vだが、抵抗で1/2にして入力している。
デジタルオシロなので、波形がチラチラすることもない。アナログのオシロで同じ波形を見ると、周期が長いので画面がチラチラする。

スケッチの作りがよくないので、Sin波形の所々にヒゲが出ている。アナログのオシロだとヒゲはほとんど見えない。(出ていても輝度が薄くなってわからない)
サイン波形の周期は約67msとなっていて(10ms/div)、周波数にすると、約15Hzである。スケッチでいちいちSinθの計算をしつつ、D2〜D9に1ビットずつ順番に出力しているので、こんなに遅くなっている。
ArduinoでSin波形や三角波を出力させる方法は、外部にDAコンバータをつけるなど、もっといいやり方があると思う。(別途実験をしている)
ただ、実際に出力波形を測定に使うのであれば、プログラマブルオシレータなどの専用の発振器を使用するのが現実的。

INA219にはまる

 INA219電流センサーの互換品を買う。 互換品 オリジナル Adafruit Industries(エイダフルート) 商品レビューで評判が良くない。不良品が多すぎるという。 とはいえ全体の購入者数からすれば一部の人の評価だろうから、まあ大丈夫だろうと買う。 オリジナルの値段の...