「ソフトウェアー・エンジニアリング」カテゴリーアーカイブ

ソフトウェアー関係の話題など・・

最近は、github にプッシュしてます~

汎用的なMakefile

主に更新を続けている Git なのだけど、ちょっとした工夫で、開発環境が
より良くなる事は多い。

以前から、Makefile を少しづつアップデートをし続けて、現在に至ってい
る。
知り合いに、cmake を使うと柔軟で便利と言われていて、確かにそうだけど、
そこは天邪鬼な自分、「make」だけで何とかならないか・・・
※cmake を使って Makefile を作る手間が面倒

gcc のビルドだと、最初に「configure」を動かして、ビルドのオプション
を設定し、必要な中間ファイルを作成したりして、最終的に「Makefile」が
作成される。

また、Windows、OS-X を主なプラットホームにしているので、どちらでも遜
色無く機能してもらい、一元管理したい。

結局、「Makefile」だけの工夫で、全てまかなえている。
・従属規則を自動で生成する事
・コンパイルして生成したオブジェクトを1つのディレクトリーに集約する事
・リリース、デバッグなどのビルド切り替えが出来る事
・基本「make」だけタイプすれば、全てが生成できる事

ユーザーが記述すべき部分:

#=======================================================#
#                                                       #
#   RL78 Makefile                                       #
#                                                       #
#=======================================================#
TARGET      =    lcd_filer_sample
DEVICE      =    R5F100LGAFB
FATFS_VER   =    ff12a
BUILD       =    release
VPATH       =    ../
ASOURCES    =    common/start.s
CSOURCES    =    common/init.c \
                 common/vect.c \
                 common/option_bytes.c \
                 $(FATFS_VER)/src/ff.c \
                 $(FATFS_VER)/src/option/unicode.c \
                 common/time.c
PSOURCES    =    main.cpp \
                 common/font6x12.cpp

これは、「RL78/G13」の「Makefile」の先頭部分ではあるが、基本的に、ソース
コードの指定だけすれば良い。
従属規則は、自動で生成される。
「ASOURCES」はアセンブラのソース
「CSOURCES」は C 用ソース
「PSOURCES」は C++ 用ソースとなっている。
バックスラッシュで改行をエスケープして、1行に1ファイルとしている。
※この方が見やすいし、再利用する場合に利便性が高い。

「VPATH」は特別な変数で、この場合、一つ手前のディレクトリー以下にあるファ
イルを参照出来るようにしている。
※「VPATH」の値には make がサーチするディレクトリのリストを指定します。

「BUILD」に「release」とすれば、リリースビルド、「debug」とすればデバッグ
ビルドとなる。
生成されたオブジェクトは、「release」又は「debug」ディレクトリーが作られて
その中に全て格納される。
この中には、従属規則のパスが記述されたファイル、「source.d」も格納される。

新しいプロジェクトでは、Makefile をコピーして、必要な部分を少し編集すれば
良く、IDE でプロジェクトを再設定するより簡単だとおもう、この辺りも、IDE を
使わない理由の一つだと思う。

デバッグとリリース時のコンパイラオプションの違い:

ifeq ($(BUILD),debug)
    POPT += -g
    COPT += -g
    PFLAGS += -DDEBUG
    CFLAGS += -DDEBUG
endif

ifeq ($(BUILD),release)
    PFLAGS += -DNDEBUG
    CFLAGS += -DNDEBUG
endif

ビルド・ディレクトリーが「release」か、「debug」で、コンパイル・オプション
を切り替えている。

従属規則の自動生成:
これが、一番のキモとも言える、従属規則は、ソースコードでインクルードされた
全てのファイルパスを示したもので、この規則を使って、「make」がファイルの更
新が起こった場合に自動で対応するソースをコンパイルする事が出来る。

この規則を自分で記述するのは愚かと思えるくらい面倒で、ソースのインクルード
を増やしたり減らしたりする度に記述をやりなおさないとならないし、インクルー
ドを全て巡らないとならない。
※大抵、make の入門編などでは、これを入力させるように説明している事が多い。

そこで、これらを、ソースコードから辿って、自動で生成する事にした。
以前は、専用コマンド「makedepend」を使っていたが、gcc に「-MM」というオプ
ションがありこれにより、ソースコードがインクルードしているファイルをリスト
出来る、ただし、gcc が出力するパスは、完全では無い為、「sed」を使って、完
全なパスを生成するように工夫している。

$(BUILD)/%.d: %.c
    mkdir -p $(dir $@); \
    $(CC) -MM -DDEPEND_ESCAPE $(COPT) $(CFLAGS) $(APPINCS) $< \
    | sed 's/$(notdir $*)\.o:/$(subst /,\/,$(patsubst %.d,%.o,$@) $@):/' > $@ ; \
    [ -s $@ ] || rm -f $@

※ C ソース用

$(BUILD)/%.d: %.cpp
    mkdir -p $(dir $@); \
    $(CP) -MM -DDEPEND_ESCAPE $(POPT) $(PFLAGS) $(APPINCS) $< \
    | sed 's/$(notdir $*)\.o:/$(subst /,\/,$(patsubst %.d,%.o,$@) $@):/' > $@ ; \
    [ -s $@ ] || rm -f $@

※ C++ ソース用
※「DEPEND_ESCAPE」は、特定のヘッダーで、従属規則が正しく生成できない場合に、
それをエスケープする。

release/main.o release/main.d: main.cpp ../G13/system.hpp ../common/io_utils.hpp \
 ../common/port_utils.hpp ../G13/port.hpp ../common/fifo.hpp \
 ../common/uart_io.hpp ../G13/sau.hpp ../G13/intr.hpp \
 ../common/itimer.hpp ../G13/timer.hpp ../common/task.hpp \
 ../common/adc_io.hpp ../G13/adc.hpp ../common/delay.hpp \
 ../common/format.hpp ../common/monograph.hpp ../common/font6x12.hpp \
 ../common/kfont12.hpp ../ff12a/src/ff.h ../ff12a/src/integer.h \
 ../ff12a/src/ffconf.h ../common/sdc_io.hpp ../ff12a/mmc_io.hpp \
 ../common/csi_io.hpp ../ff12a/src/diskio.h ../common/string_utils.hpp \
 ../common/time.h ../common/filer.hpp ../common/bitset.hpp \
 ../common/switch_man.hpp ../chip/ST7565.hpp

※これは、自動で生成された、「main.cpp」の従属規則「release/main.d」

プラットホーム毎の違いを吸収する:

ifeq ($(OS),Windows_NT)
SYSTEM := WIN
else
  UNAME := $(shell uname -s)
  ifeq ($(UNAME),Linux)
    SYSTEM := LINUX
  endif
  ifeq ($(UNAME),Darwin)
    SYSTEM := OSX
    OSX_VER := $(shell sw_vers -productVersion | sed 's/^\([0-9]*.[0-9]*\).[0-9]*/\1/')
  endif
endif

この判定で、変数「SYSTEM」にOSの属性が代入される。
又、「OSX」の場合、「OSX_VER」にバージョン番号が代入される。

RL78/G13でWAVプレイヤーとLCD表示を合体させてみた

前回、大きなプログラムが動かない場合がある不具合の原因を取り除いて
から、信頼性が向上した為、ようやく不安無く大きなプログラムを作る事
ができるようになった。

そこで、以前に作ったWAVプレイヤーに、LCDファイラーなどを合体
させて、単独で機能するプレイヤーにアップデートしてみた。

   text    data     bss     dec     hex filename
  85991     112    3744   89847   15ef7 wav_play_sample.elf

かなり巨大になり、書き込み時間もそれなりにかかるようになった・・・
RAMは、合計4Kバイト程、スタックに最大1Kくらいは使うと思うの
で5K程、まだまだ余裕がある、思った程消費していない。
プログラムは、「15EF7」だけど、実際には0x3000から始まる
ので、96K程消費している。
R5F100LGAFB (FLASH:128K, RAM:12K, DATA-FLASH:8K) @340
は、バランスが良いデバイスなのかもしれない。

RL78のI/Oを制御するテンプレートクラスは、このような場合にリ
ソースの割り当てが柔軟なので、かなり楽が出来る、しかも、余分なコー
ドが入らないから、高速に動作し、メモリーの節約にもなる。
やはり C++ は組み込みマイコンに適した言語なのだと思える。

※ファイル選択の様子
img_0840s

起動時:
・左ボタンでファイラー起動
・十字ボタンの上下でファイルを選択
・十字ボタンの右で、再生(ディレクトリーの場合は、移動)
・十字ボタンの左で、ディレクトリーを戻る
・右ボタンで、ディレクトリー連続再生

再生中:
・十字ボタンの右で、次の曲
・十字ボタンの左で、曲の先頭
・左ボタンで一時停止

※再生中
img_0841s
※WAVファイルには、TAG情報が含まれているので、それを表示してい
る。

再生中に、経過時間を表示したいが、16ビットステレオの44.1KHz
では、ループに余裕が無く、LCDの書き換えをリアルタイムに行なえない。
SPI通信をDMAにするとか、時分割処理が必要なので、この機能は現在
は実装していない、そのうち対応したい。

外部に接続した、ターミナルには、経過時間(1秒毎)を表示している。
また、ターミナルからの操作も常に受け付ける。

RL78/G13 WAVプレイヤー

RL78/G13によるシリーズ・スイッチの判定

このネタは、良くある複数スイッチを抵抗ネットワークでデコードして、1本
のポートで読み込む為のガジェットで目新しさはあまり無い。

原理と動作は、分圧する抵抗を適切に選んで、直線性を維持する事で(直線性
が確かならデコードするソフトが楽なだけではあるけども・・)、かなり多く
のスイッチをデコードする事が可能となる、ただし、入力は排他的で、上位の
スイッチが常に優先される仕様となる。
※A/D変換の分解能を10ビットとした場合、抵抗ネットワークの直線性誤
差が+-10%の範囲なら5個のスイッチを認識できる事になる。
(計算方法が間違ってるかもしれないが・・)
※又、一般に流通している抵抗値には、限りがあるので、微妙な抵抗値を使っ
たネットワークは作りにくい為、あまり多くのスイッチを並べる事は難しいと
思われる。

方向スイッチ:
dir_switch
※試作では、6.8Kが無かったので、3.3Kを2個直列にした。

変形として、ネットワークのトポロジーを変えて、複数同時押しが可能なよう
なものも作れる、ただし、多くのスイッチを判定するのはより難しくなる。

スイッチ判定:

    enum class SWITCH : uint8_t {
        RIGHT,
        UP,
        DOWN,
        LEFT,
        A,
        B
    };

    // 4つのスイッチ判定(排他的)
    auto val = adc_.get(2);
    val >>= 6;   // 0 to 1023
    val += 128;  // 閾値のオフセット(1024 / 4(SWITCH) / 2)
    val /= 256;  // デコード(1024 / 4(SWITCH)

    switch_bits tmp;
    if(val < 4) {
        tmp.set(static_cast(val));
    }

ABスイッチ:
ab_switch
※もっと賢い抵抗値の選び方もあると思うので、参考程度に・・

    // 2つのスイッチ判定(同時押し判定)
    val = adc_.get(3);
    val >>= 6;  // 0 to 1023
    if(val < 256) {
        tmp.set(SWITCH::A);
        tmp.set(SWITCH::B);
    } else if(val < 594) {
        tmp.set(SWITCH::A);
    } else if(val < 722) {
        tmp.set(SWITCH::B);
    }

img_0837s

RL78/G13 A/D スイッチ・サンプル

RL78/G13、LCDへの漢字表示(ファイラー)

かなり昔にAVRマイコンで、データロガーを作成した時、既に漢字の表示
は対応していたが、RL78でも漢字に対応した。

表示フォントは12ピクセルを使う。
これは、表示の限界(難しい漢字は、判読出来ないが・・)少しでも情報量
を多くしたいのが理由としてある、16ピクセルの方が判読しやすいが、表
示のバランス的には12ピクセルの方が好みな感じ。

但し、いくつか制限がある、漢字のビットマップフォントを置く容量が無い
為、どこか別途、配置する必要がある。
※RL78(256Kデバイスなら、Flashに置く事が可能)
・12ピクセルフォントで、136キロバイト程の容量が必要。
・1MビットのEEPROMにも入らない。
・SDカードを接続するシステムなら、SDカード上に漢字ビットマップを
置く事で、描画が可能。
・キャッシュを設ける事で描画パフォーマンスを最適化。

12ピクセルのフリーフォントは色々あるけれども、今回は、蕨12を使った。
フォントデータはBDF形式なので、展開して、バイナリーデータにする。
この際、SJIS形式の並びとした、そうする事で、効率良く配置でき、無駄
が比較的少ない。
SJISのコードから、漢字のリニアアドレスを得る関数として、以下のコード
を使う。

static uint16_t sjis_to_liner_(uint16_t sjis)
{
    uint16_t code;
    uint8_t up = sjis >> 8;
    uint8_t lo = sjis & 0xff;
    if(0x81 <= up && up <= 0x9f) {
        code = up - 0x81;
    } else if(0xe0 <= up && up <= 0xef) {
        code = (0x9f + 1 - 0x81) + up - 0xe0;
    } else {
        return 0xffff;
    }
    uint16_t loa = (0x7e + 1 - 0x40) + (0xfc + 1 - 0x80);
    if(0x40 <= lo && lo <= 0x7e) {
        code *= loa;
        code += lo - 0x40;
    } else if(0x80 <= lo && lo <= 0xfc) {
        code *= loa;
        code += 0x7e + 1 - 0x40;
        code += lo - 0x80;
    } else {
        return 0xffff;
    }
    return code;
}

BDF形式を展開して、バイナリーデータを作成するアプリケーションは、以前に
作成した「bmc」を使う。
ビットマップ変換
この変換プログラムをコンパイルするには、mingw64 か、OS-X(Linux)で行なう必
要がある、詳細は、glfw3_app を参照して欲しい。

また、バイナリーデータは、蕨12フォントSJISバイナリーに置いてある。

漢字表示のアプリとして、ファイラーを作成した。
RL78/G13 SD カード LCD ファイラー

img_0833s
img_0832s
SDカード上のファイル選択の様子:
・LCDの横幅を超えるファイルは、自動でスクロールする。
・選択中は、反転表示。
・ディレクトリーの移動が可能。

RL78/G13の gcc での最適化に関するトラブル

LCDに表示するプログラムを実装するようになって、何か、正しく動かない事
が、頻発してきた。
※実際は、以前から、あったのだが、何かの拍子に直ったりする為、原因を究明
出来ないでいた。
よくよく調べると、最適化オプション「-Os」を使う場合に、起こる事がある事が
判った。
-O1、-O2 では発生しない為、とりあえず、-O2 を使っていたのだが、プログラム
の容量が増してくると、そうもいかなくなってくる。

そこで、コードを簡単に追ってみると、スタック領域に配置された変数にアクセス
する場合に、スタックのアドレス計算を間違っているような挙動だった。

これは、コンパイラの問題のように思うが、RL78のコード生成部分を追って、
修正するには、スキルと時間が足りないように思う。
それと、コンパイラのバグと思っていた事が、実際には、実装の問題である事は、
良くある話でもある。
そこで、回避策を色々試してみた結果、コンパイラオプション「-flto」を追加す
る事で回避出来ているように思う。

詳細に調べた結果、RAMの初期状態に依存していただけだった。
通常「.bss」セクションは「0」クリアするが、「.data」セクションは、何かの
値をロードするので、そのままな状態になっている、これが、問題のようで、
ロードしない場所は「0」クリアする必要がある。
そこで、リセット時、全てのRAMを全て「0」クリアするコードを追加した。

;; clear all RAM
    sel     rb0    ; bank 0
    movw    hl, #__datastart
LC0:
    movw    ax, #0
    movw    [hl], ax
    incw    hl
    incw    hl
    movw    ax, hl
    cmpw    ax, #__stack
    bnz	    $LC0

※レジスタ・バンクは触らない。
この変更で、怪しい挙動は、無くなったようではある。

ただ、コンパイラを作りなおす必要がある。
コンパイラは作り直さなくても大丈夫と判った、でも、4.9.4 の方が、ほんの
少しは、最適化が良いのかもしれないので、4.9.4 にするのはやぶさかでは無い。

※最近、gcc-4.9.3 から、gcc-4.9.4 に移ったので、その過程で、ビルドオプシ
ョンを精査した。

--enable-multilib --enable-lto

を追加する。
※「multilib」は以前は「disable」であったが一応「enable」とした。

「-flto」は、LTO(Link Time Optimization)を有効にするオプションで、これによ
り翻訳単位を超えた最適化が可能になる。
これは、gcc-4.8.x から、追加された機能のようだが、RL78 と、gcc-4.9.4 の場
合は、常に「有効」にする必要があるのかもしれない。
※指定しないと、「有効」になっているようである。

とりあえず、現状で、これで回避できているようではある・・・

RL78/G13にモノクログラフィックスLCDを接続する

以前に Aitendo さんで買った LCD は、色々イマイチの部分があり、どうしようか悩
んでいたが、RSオンラインで、新品のLCDでもをそこそこの値段で売っている事
を発見して、試しに買ってみた。

小規模なマイコンで、簡単なユーザーインターフェースを実装する場合、何か表示装
置が必要で、グラフィックス液晶は、その候補の一つと思う。
RL78では、メモリーがそこそこあるので、128×64ピクセル程度のモノカラ
ー液晶なら、漢字も表示できるので、大抵のアプリケーションにマッチする。

今回実験した液晶は、バックライトは無いものの、850円くらいで購入でき、(
2000円くらいで、表示面積が大きいタイプもある)3.3V動作が可能なタイプ
で、消費電力も少ない。

128×64(バックライト無し)@833円

128×64(バックライト有り)@917円

接続ピンのピッチが1.27mmだったので、変換基板と追加回路を組み込んだ。
img_0827s

コントローラーは、ST7565Rで、データバスが8ビットだけど、シリアル変換
モードがあり、SPI通信で接続出来る。
RSオンラインで用意されている資料では、不明な点が多かったが、ネットを探して、
表示に必要な外部回路(主にコンデンサの接続方法等)を探して、接続した。

SPI通信、参考回路:
64128

以前に作成した、サンプルコードを、多少修正(主に制御ポートの定義)したら、問
題無く動作した。
ST7565のコードは、ネットで見つけた物を改造したもので、Aitendo の液晶で
は不安定で、正しく動作しなかったが、この液晶では、何の問題も無く綺麗に動作す
る。
※やはり、ジャンクは、ジャンクと言う事なのかもしれない。

img_0830s

SSD1306コントローラー使用のOLED:
img_0831s

RL78との接続:

    /CS  ---> P53       (36)
    A0   ---> P50       (33)
    SD   ---> P13/SO20  (43)
    SCL  ---> P15/SCK20 (41) 
    /RES ---> /RESET    ( 6)

※ソースコードには、ST7565、SSD1306どちらか片方を有効にする定義
がある。

LCD サンプル

format クラスでの IEEE754 フォーマットの表示

C++ では、printf を使わない文化がある。

これは、スタックベースの可変引数では、安全性が確保出来ない事に由来する。

その為、C++ では、printf が便利な事は判っていても、それから離れて、std::cout
関係のクラスを実装する事となったと思う。
ただ、典型的な C のプログラマーは、C++ 上でのプログラムでも、「std::cout」
が使いにくいと言い、printf を使い続ける輩が後を絶たない。
「std::cout」も馴れてしまえば、そうそう使いにくいものでも無いと思うが、それ
でも、printf にある、柔軟性やコンビニエンス的な使いかってには、敵わない。

boost では、printf の使いやすさと安全性を網羅した format クラスが作られた。
これにより、C++ でも、printf と遜色無い、利便性を手に入れたと思える。

小規模な組み込みマイコンでも、やはり、安全性が無い printf は使いたくは無い。
※printf のフォーマットと引数の不整合は、最悪の場合、プログラムがクラッシュ
する、ある程度は、コンパイラが不整合を検証しているが、完全には出来ないので、
多くの組み込みメーカーではデバッグ以外では使わない事が普通で、リリースビルド
では、「#define」を使って「printf」を消している。

boost::format クラスは、iostream に依存していて、非常に多くのリソースを消費
してしまう為、限られたメモリーしか無いようなマイコンでは、使う事が出来ない。
また、「float、double」を使わない場合に余分なコードを節約したい等、カスタム
したい場合もある。

組み込みでも、C 言語ベースのシステムでは、printf も多くのメモリーを消費する
為、多くの人が、廉価版の printf を実装して使う事が多いが、それに習って、C++
なので、boost::format の廉価版を実装してみた。
C++ では、演算子をオーバーロードして、全く別の機能として使う事が出来る。
これを利用して、「%」記号(通常は、整数の剰余)をオーバーロードして、引数を
受け取るようにしている。

不整合が起こった場合は、「例外」をスローするのが普通であるが、それは、別の問
題を含んでしまう為、エラーステータスによる処理を行なっている。

独自 format なので、拡張して、固定小数点の表示、二進数表示などを取り入れている。
又、内部から、sprintf を呼ぶような事も行なわない、純粋な物を実装したい。

以前は、整数表示や文字列表示などの機能しか実装していなかったが、float の表示
が必要な事は結構ある。
そこで、IEEE754 の表示が出来るように拡張してみたのだが、仕様が複雑で、難解
な部分が多く、現状では、全ての仕様を満足するまでには完成度は高く無いものの、
ある程度は、正しく表示できるのようになった。
以下のような方針で実装してみた。

・内部で float の計算を行なわない。(整数のみの計算で行なう)
・なるべくメモリーの消費を抑える。
・なるべく printf の仕様に準拠する。

printf では、float、double の区別は無く、基本的に、float は double にキャス
トされて内部処理される。
newlib の該当する部分を読んでみたが、あまりに複雑で、部分を抜き出して簡単に
使えそうも無い事から、自分で考えながら実装してみた。
その為、無駄な部分や間違いがあるかもしれない。

固定小数点表示:
組み込みでは、A/D 変換した値や温度など表示する場合など、シフトしたり掛けたり
割ったりして、実数部と小数部を分けて整数で表示する事が良くある。
そこで、もっと簡単に扱えるように固定小数点表示をサポートしている。

    int32_t val = 4096;
    utils::format("FixedPoint: %5.3:12y\n") % val;
    val = 6372;
    utils::format("FixedPoint: %5.3:12y\n") % val;
    utils::format("FixedPoint: %5.2:12y\n") % val;

FixedPoint:  1.000
FixedPoint:  1.556
FixedPoint:  1.56

・上の例では、全体5桁(小数点含む)、小数部3桁、小数点以下12ビットとして
表示する。
・内部では、小数部+1桁目を四捨五入して丸めて表示する。(この仕様は、printf
の IEEE754 表示に準拠している)

IEEE754 サポートが必要無い場合は、ソースの頭で、以下のようにコメントアウトする
事で大幅にメモリーを節約できる。(その場合でも、固定小数点表示はサポートされる)

// #define WITH_FLOAT_FORMAT

※現状では、「double」の80ビットフォーマットをサポートしていない。

※R8C、RL78、RX マイコンで利用でき、もちろん、他のプラットホームでもコンパイル
できれば、利用可能と思う。

RL78/common/format.hpp

追記修正:
printf の桁数指定を勘違いしていた為、改めて、仕様を読み直し、printf に準拠する
ように修正を加えた。

RL78/G13でタッチセンサー実験

以前にSDカードを接続する実験をしていた時、入力ポートのプルアップ抵抗設定
を間違えて、オープン状態になっていた、配線チェックの為、配線に指を近づけた
らカードが検出され、LEDが点滅するような状態だった。
それで、バグに気がついた。

この件に伴い、「入力ポートのインピーダンスは高いなぁー」と感じた。
※あたりまえなんだけど・・・

この件で、静電容量の微小な変化を使ったタッチスイッチを実験してみる事にした。

原理は簡単で、微小な静電容量を積分時間によって判定するもので、RL78のル
ープカウントを積分時間とする方式。

・タッチパッドは、10mm四方の銅版を使い、上に絶縁の為、ポリイミドテープ
を貼ってある。
・この銅版に1Mオームの抵抗を繋ぎ、プルアップしておく。
・等価的には、この銅版は、微小なコンデンサと考える事が出来る。
・指で「触る」事で、微小な容量が変化するものと思われる。

評価方法:
・まず、ポートを出力に設定して、「0」を設定し、等価コンデンサを放電する。
・次に、ポートを入力に設定して、「1」になるまでのループ数をカウントする。
・このループ数の違いにより、開放された状態と、触っている状態を判断できる。
・電源投入時、開放状態のカウントを計り、基準にする。
※この値は、安定しているので、一度基準が判ればよい。

実験結果:
実験すると、開放時は「50」くらいで、触ると、80~300くらいまで変化す
る事を確認。
指を近づけると、「60」くらいになるので、60以下は無視する。

ただ、かなりバタつくので、触った瞬間と離した瞬間を正確に判断するには、多少
の工夫が必要。

IMG_0823s

静電容量は、タッチパッドの作り方で、変化し、微妙な値が大きく影響するので、
再現性は低いかもしれない。

タッチスイッチ・サンプル

RL78/G13でA/D変換を使う

RL78/G13には、10ビット(8ビット)のA/D変換が付いてる。
変換時間もかなり速くて、最大だと、2.125uS。

・入力は最大12チャネル(64ピン版の場合)
・サンプル&ホールド回路も内臓
・入力チャネルを、基準電圧源の「+」、「-」に切り替えが出来る
・内臓電圧リファレンス(1.45V)に切り替えできる
※1.023Vが便利だと思うが・・

経験的に、AVRより、国産のマイコン内臓のA/Dの方が、変換精度が高く、
ノイズに強いと思う。
※AVRは、サンプルホールドが無いので入力信号によっては変換誤差が大きい。
ただ、10ビットは多少物足りない、12ビットは欲しいところ。

少し意外なのは、ルネサス(日立)系では、A/D入力は、入力ポートにしか転用
出来ないものだが、RL78では、入出力に設定出来る点が、利便性が高い。

国産マイコンのA/D変換は、変換開始のトリガーを色々選べるとか、かなり細か
い設定が可能なので、クラスでそれらを全てサポートする場合は、設計が難しい。
今回は、チャネルを選んで、変換するだけの、淡白な機能しか実装していない。
※必要に応じて、メソッドを追加したいと思う。

IMG_0821s

A/D変換サンプル

RL78/G13で BMP180 温度、圧力センサーの値を読む

以前に、Amazon で買った、中華の安い Arduino 系モジュール。
I2C接続の温度、圧力センサー、BOSHのBMP180を買って、積んでいたのだけど、
気晴らしに、ちょっと動作確認をしてみた。

Arduino 系の I2C モジュールは、ピンアサインがまちまちで、以前に使った DS3231 RTC と
は違うアサインになってて、何とも言えない脱力感・・・

ネットを探すと、Arduino のスケッチが沢山見つかるので、それをコピペして、C++ のクラス
を実装した。
※必要な部分だけ浮動小数点を使い、他は整数計算で行なっているものや、全て浮動小数点で
行なっている物など、様々なスケッチ、さらに、スケッチはほぼC++なんだけど、C的に書
かれているとか、色々だった。
RL78/G13なので、なるべく計算負荷が少なくて、精度を確保してある物を切り貼りし
た。
※BMP180の、補正は、以外と複雑で難解

動かしてみると、温度は、大体合っているようなので、とりあえず、「良し」として、プッシ
ュした。

ただ、utils::format クラスでは、まだ浮動小数点の表示をサポートしていない為、結果が浮
動小数点で返ってくるものは確認していない。

IMG_0820s

BMP180 温度、圧力センサーサンプル

-----
IEEE754 のバイナリーパターンを、10進に変換する部分を独自に実装してみたい、これは、
「課題」みたいなもので、面白そうでもある。
・整数計算だけで行なう。
・「printf」で可能な表現を全て備えたい。
・コンパクトに実装したい。
以前に実装しようと試みたけど、中途になっている・・・
これにそろそろ本格的に挑まないといけない・・・