バッテリー充電アラームを作り直す

バッテリーの充電状態を随時チェックするため、従来の自作プログラムを捨てて、新規に作り直すことにした

従来はロボの電源ON時のみ充電状態をチェック
 これまでは、加速度センサの出力値が電源電圧に依存して変化するのを逆手にとって、電源ON直後のロボ直立状態でセンサ出力値が所定値を超えるとアラームを発するようにプログラムしていて、これはこれで用を為した
しかし、加速度センサでにロボの姿勢制御をしようとすると話が違ってくる。センサの出力値を元に前傾・後傾を補正するには、センサ出力の電源電圧依存性を排除する必要がある。そのため、電源電圧を常時測定して加速度センサの出力値を補正することにし、それなら、とバッテリー充電状態も電源電圧で直接判定することにした。
電圧測定用のI/F回路を作る

  1. Robonovaマニュアル(注)の95ページに掲載のI/F回路図は、電源電圧(Vcc)を1/2に分圧して測定用に供給する簡単なものだが、多くの先達が指摘するように誤りと思われる。まったく何てことだ!
    注)製品サポート終了しており、日本語版は既にネット上に見当たらない
    ずいぶん昔に同図をチラ見したときは、「Vccの測定に使う基準電位はVccの変動に影響されないの?」と訝しく思いつつも、「CPUの内部で発生する基準電圧を利用しているのかも」と思い直してそのままにしていた。今回、更にCPUボードの回路図を見ると、ATmega128L(CPU)の<b>AREF</b>ピンがVccに直結されているので、CPUの内部基準電圧は利用されていない。

    そこで、この電圧測定は次の2点に注意する必要がある
    1. Robonovaマニュアル回路図が示す電源電圧「Vcc」ではなく、バッテリー給電圧「V+」を1/2に分圧して測定する
       Vccが電圧測定の基準電位なので、Vcc自体の電圧変化をまともに測定できるはずがない。V+ならVccが5vに維持されている限り、その変動を測定できるはずだ
    2. V+の電圧降下が一定以上進むとVccも5v以下になり、そうなるとV+測定値は信用できない
       基準電圧(Vcc)が低下すると、V+測定値は見かけ上、実際より高い電圧になるはず。従って、Vcc=5vを維持できるV+の最低電圧を検出する必要がある。

  2. 上記のに対処した回路図を右上段に示す。抵抗値は手持ち部品で間に合わせるため、マニュアルの抵抗値と違う値になっただけである。また、AD6は加速度センサーを接続中なのでAD7を使うことにした。
    この回路をCPUボードに取付けたのが右中段の写真で、手前のAD7ポートから伸びる黒白配線の先の黒い熱収縮チューブ内に抵抗器が納まっている。AD7ポートと、その直下の位置にあるサーボ制御用ポートの2つを使う、不経済なハードである。ちなみに、このI/F回路のGND接続先は、CPUボードのプリント配線パターンにもよるが、電流アース/電圧アースの考え方でいくとAD7のGNDピンを使うべきと思う。
    また、(B)についてはプログラム側で対処することに。それに必要な判定基準を知るため、手持ちのバッテリー5個をサンプルに、拙作の izakRemoconを使って、ロボ直立時のAD6値(=加速度センサー値)とAD7値(=V+値)を調べた結果が表1。なお、調査時点の各バッテリー使用状態はまちまちである。No.5のバッテリーは、AD6値から判断して放電が進んでいるが、AD7値はNo.1よりも高くなっており、これが上記の状態と思われる。
 
 
表1
 No.  AD(6)  AD(7)  V+計算値
 1  67-68 157-158   6.13-6.17
 2  62-64 166-167  6.48-6.52 
 3  61-63 168-171  6.56-6.68 
 4  62-63 163-164  6.37-6.41 
 5 73-76  161-162  6.29-6.33 

プログラムを書く
バッテリーチェックは、ロボ起動時および操作パッドからの直接指定により実行させることにする。
ロボ動作によりバッテリーが消費されVcc電圧が低下すると、ロボが同じ姿勢でも加速度センサ値が増大するので、起動時の加速度センサ値とVcc値を記憶して動作中の加速度センサ値の補正に利用する。
また、上記(B)で述べたようにロボを長期間放置して自然放電が進んでしまうと、正しく電圧チェックできないので、加速度センサ値も一緒にチェックする。

変数の説明
ロボ起動時の加速度センサー値を記憶させる変数がGRV_initialである。
変数RR_BUFはロボが受信する1バイト命令を格納するシステム変数RRのコピーである。

処理の説明
メインループに入る前の初期処理で、変数GRV_initialを初期化してからバッテリーチェックのサブルーチンを呼出す。
メインループの中では、ラベルREMGET以下の処理で、キー操作別の処理に分岐し、この例ではK7にバッテリーチェックを割り当てている。

サブルーチンのパッテリーチェックは、電源ON直後に呼出されたとき(Grv_initial=0のとき)、加速度センサー値AD(6)を取得し一時保存存する。電源ON時にロボが初期直立姿勢をとることを前提に、この時の加速度センサー値が閾値以上だと、V+測定値に関係なくラベルBAT_LOWにジャンプしてアラーム処理をする。
それ以外の場合、V+の測定値AD(7)と閾値を比較し、電圧が正常ならBAT_OKにジャンプ、低ければBAT_LOWに進む。

アラーム処理(BAT_LOW)は、LED10回点滅と並行して警告音を発する。そして、電源ON直後ならプログラムを終了し、それ以外の場合は呼出し元(メインループ)に復帰する。これは、ロボが移動中にバッテリー不足を検出した場合、そこでいきなり停止したら具合悪かろうと考えたからである。

バッテリーの電圧が問題ない場合(BAT_OK)は、ロボの電源ON直後なら一時保存しておいた加速度センサー値をGRV_initialにセットし、さもなければ直ちに呼び出し元(メインループ)に復帰する。
'変数定義
DIM RR AS BYTE
DIM RR_BUF AS BYTE
DIM GRV AS BYTE 'gravity
DIM GRV_initial AS BYTE 'GRV value at PowerOn
DIM DEG AS INTEGER
CONST AD_BAT_LOW = 158 'V+ = 6.1v
CONST GRV_BAT_LOW = 70
 '初期処理〜メインループ
GRV_initial = 0
GOSUB BATTERY_CHECK
       (中略)
MAIN: 'メインループ開始
'-----------------------------
REMGET: 'キー入力値の取得とアクション分岐処理
  RR_BUF = RR
  RR = 0
       (中略)
  ON RR_BUF GOTO main_exit,K1,K2,K3,.....
main_exit:
  IF RR_BUF > 50 THEN RETURN
GOTO MAIN 'メインループ終端

'メインループが呼出すサブルーチン群(抜粋)
k7: ' キー入力値=7のときの分岐先
  GOSUB BATTERY_CHECK
  GOTO main_exit

BATTERY_CHECK: 'Battery check
  IF GRV_initial = 0 THEN 'PowerON check
    DEG = 0
    FOR i = 1 TO 5
      GRV = AD(6)
      DELAY 20 '20ms * 5times = 100ms
      DEG = DEG + GRV 'add 5 times
    NEXT i
    DEG = DEG / 5 'get mean value

    IF DEG > GRV_BAT_LOW THEN GOTO BAT_LOW
  ENDIF

  AZ = AD(7) 'V+ voltage
  IF AZ >= AD_BAT_LOW THEN GOTO BAT_OK

BAT_LOW:
  FOR i = 1 TO 10
    OUT 52, 1 'LED off
    DELAY 200
    MUSIC "A"
    OUT 52, 0 'LED on
    DELAY 200
  NEXT i

  IF GRV_initial = 0 THEN END

  RETURN

BAT_OK:
  IF GRV_initial = 0 THEN
    GRV_initial = DEG
  ENDIF

  RETURN

残課題
今回作成した電圧測定機能はVccが5vを切ると使えない。これを解決するには、CPU内で発生する基準電圧を利用すればよいが、ロボのCPUボードを改造する気はないので、他のに小型のATMEL社CPUを外付けしてはどうかと考えている。

※この記事が何かのお役にたつことを願っていますが、記事内容についてのいかなる保証もしません