LCD でストリームIOを使えるようにしてみた

mbedのコンパイラはちゃんとC++してるってことに今頃になって気づいた。new,deleteとか使えるし、ストリームIOも使える。
(今まで気づいてなかったのは arduinoが C++ベースなのに new,deleteとかが使えなかったというイメージが染みついてるせいかなあ)

というわけで TextLCDライブラリで ostreamを使えるようにするクラスを書いてみました(ライブラリサンプル

予想はしてたけど、やっぱりメモリは食いますねえ…書いたコードの量はほんの僅かなのにリンクされるC++の標準ライブラリが大きいみたいだな。 このサンプルプログラムをmbed1768でコンパイルして flashが53.1k、RAMが12.4k。LPC1768ならOKなんだけど、トラ技ARMライタ(LPC11U35) だと RAM不足でリンクが出来ない。LPC1114に至ってはFlashすら足りない(^^;)

でもね、やっぱりストリームIOが使えるってのは色々と便利なんだよね。一度 hogestream << foo_object みたいなのを作ってしまえば LCDでも SDFileSystemでも stringstreamでもそのまま使えるとかね。
てか、根がソフト屋だからなのか、こっちのほうがプログラミングしてて楽しい(^_^)

2016/07/30追記 その1
秋月のPICを使ったI2C液晶で使えるようにした。TextLCD_I2C_N ではそれっぽい指定が出来るようになっているのだが、これが動作しない。正常に動作するライブラリ(ACM1602NI)を見つけたので、それを取り込んだ。
lcd_ostream は TextLCD_Baseを継承したクラスにしか適用できないものだったのだが、ACM1602NIは TextLCD_Baseは継承していない。しかし必要なメンバ関数(putc(),locate(),cls())は持っている。こういう場合 C++にはテンプレートという強力な武器がある(^_^) …というわけで lcd_ostream をテンプレート化することで解決した。
前バージョンとの互換性を保つためクラス名を TextLCD_ostream に変えて lcd_ostream は TextLCD_ostream<TextLCD_Base> への typedef とした。

ちなみに、この液晶って発売されたときは画期的だったんだけど、今はもっと安いI2C液晶が出てるし、買う人はほとんどいないだろうね。その点じゃあんまり意味のない改良なんだけど(^^;)、公開されているディスプレイ系のライブラリでは、 ACM1602NIみたいに TextLCDを継承はしていないけど、メンバ関数の名前は TextLCDに合わせてあるというものが結構ある。それらには全て TextLCD_ostream が適用できるはずなので、きっと無駄な改良ではないと思う(^_^)

2016/07/30追記 その2
STM32 Nucleo-L476RG を買ったので、こいつでも動くようにした。
メモリは大量に載っているボードなので普通に動くだろうと思ったら…リンクエラーが出てコンパイルが出来ない(^^;)
調べてみたら、このボードでは mbedコンパイラは標準ライブラリに MicroLib というのを使うらしい。このライブラリはコードサイズを小さくするために C言語の規格を一部満たしていない。このため std::iostreamを使うとリンクエラーになる。mbed LPC1768だと MicroLibではなく standard lib ってのを使うのでエラーが出ない。オフライン開発環境なら MicroLibと standard lib のどちらを使うのかを選べたりするんだけど、mbedコンパイラではライブラリの選択とかはないみたい。

解決策を探したら「ダミー関数を書いちゃう」ってのが見つかったので、それを取り入れてみた。リンクエラーになる関数は istream(入力)で使われるものなので、出力しかしない TextLCD_ostreamなら、これでOKみたいだ。
でも Nucleo-L476RGでコンパイルすると RAMを100K以上使っちゃう。これは MicroLibで無理矢理使おうとしているせいだろうなあ…一応動くけど潜在的なバグとかもありそうだな(^^;)


Please log in to post comments.