RaspberryPi[23] Raspberry PiリチウムUPS拡張ボードPart2

色々考えたあげくやはり、電源復旧後にラズパイを自動立上させるためには、他人に頼まないとできないようです。なぜなら、ラズパイはshutdown した後に再度立ち上げるためには、電源を抜き差ししてあげる必要があります。運よく、この拡張ボードはラズパイに供給する電源のオンオフスイッチがあるうえ、外部スイッチもつけることができるようにコネクタが付いています。

思想はこんな感じです。↓

拡張ボードから出力される状態を示すシリアル通信をESP32で受信して、GOODとNGを検出して、NG(供給電源断)の場合にラズパイに知らせて、shutdown コマンドを発行させる。ラズパイのshutdown完了をESP32で検出して、ラズパイの電源を別回路で切る。

供給電源の復旧もシリアル通信を監視しておき、GOODが検出されたら、ESP32で検出してラズパイに電源を供給させる。これで、ラズパイが起動するはずです。

ESPからラズパイに電源断を知らせるのとshutdown完了は、IOピンのL-HIGHで行おうと思っています。シリアル通信を使うほどでもないですから。18PINは付属しているPYTHONプログラム shutdown_check.py で使っているのでそのPINとプログラムを使えば、楽ができます。

以下は、ESP32でGOOD、NGを判別するESP32のプログラムです。一文字ずつ確認して、GOとNGの文字が電文で確認されることで、GOODとNGを判断しています。ついでに、バッテリー容量も切り出しているので、バッテリー容量でshutdownさせることも可能です。

ちなみに拡張ボードのシリアル端子のRXはRXにつなげを言うことですので、拡張ボードから見ればTXになります。

#define RX_PIN 16
#define TX_PIN 17
#define REQ_SHUTDOWN_PIN 5
#define READ_SHUTDOWN_PIN 18

char inByte;
char cap_data[128];
char data[128];
int lf_flag = false;
int i;
int j;
int stat = 0;
int req_shutdown_tgl = false;


void setup() {
  // initialize both serial ports:
  Serial.begin(115200);
  Serial2.begin(9600);

  pinMode(REQ_SHUTDOWN_PIN, OUTPUT);
  pinMode(READ_SHUTDOWN_PIN, INPUT);
  digitalWrite(REQ_SHUTDOWN_PIN, LOW);

  lf_flag = false;
  i = 0;
}

int A_flag = false;
int N_flag = false;
int G_flag = false;

int good = false;
int cap_read_flag = false;

void loop() {
  int cap;

  if (Serial2.available()) {
    inByte = Serial2.read();

    //   Serial.printf(":0x%x %c\n", inByte, inByte);

    if (lf_flag == true) {
      data[i] = inByte;
      i++;

      if (cap_read_flag == true) {
        if ((inByte >= 0x30) && (inByte >= 0x30)) {
          cap_data[j] = inByte;
          j++;
        }
        if (inByte == 0x2c) {
          cap_data[j] = '\0';
          cap_read_flag = false;
          A_flag = false;
        }
      }

      if (inByte == 0x47) G_flag = true; //G
      if (inByte == 0x4e) N_flag = true; //N
      if (inByte == 0x41) A_flag = true; //A
      if ((inByte == 0x50) && (A_flag == true)) { // AP found
        cap_read_flag = true;
        j = 0;
      }

      if ((N_flag == true) && (inByte == 0x47)) good = false; //NG found
      if ((G_flag == true) && (inByte == 0x4F)) good = true; //GO found

    }

    if (inByte == 0xa) { // LF
      lf_flag = true;
      G_flag = false;
      N_flag = false;
      A_flag = false;

      data[i] = inByte;
      i = 0;
      if (stat == 1) {
        cap = atoi(cap_data);
        Serial.printf("%s good:%d cap:%d\n", data, good, cap);

        if (good == false) {
          if (req_shutdown_tgl == true) {
            digitalWrite(REQ_SHUTDOWN_PIN, HIGH);
            req_shutdown_tgl = false;
          } else {
            digitalWrite(REQ_SHUTDOWN_PIN, LOW);
            req_shutdown_tgl = true;
          }
        } else {
          digitalWrite(REQ_SHUTDOWN_PIN, HIGH);
        }
      }
      stat = 1;
    }
  }
}

スライドSWの横にあるコネクタは外部SWと書かれています。シルクを見ると上からLED+ GND SW+ GNDとなっています。githubのマニュアルでは外部SW用のコネクタはついていないようです。マニュアルが古いのでしょう。この外部SWを使うときは隣のスライドSWをオフにしておかないと外付けSWは機能しません。外付けSWのSW+とGNDをつなぐとラズパイに電源が供給されます。しかし、このSWはOHHにすると自分も死にます。拡張ボードも死ぬのでシリアル通信も止まります。拡張ボードに電源が供給されるようになるとまたボードが復活します。ESP32にSWの制御させるのは良いのですが、SWをオフにすると自分の電源も断たれます。これがどうもESP32を不安定にさせるようです。なので、直接SWを制御するのは止めて、ラズパイの電源だけ切るようにします。ちなみに、シリアル端子の横にある+5VとGNDはラズパイに電源を供給することができます。なので、USB-Cは使わずにこの線でON-OFFさせればよいことになります。

たまに、拡張ボードからのシリアルデータが化けます。その時は、一旦リチューム電池を外して強制リセットかけると治りますが、運用中に落ちると厄介なので、データが来なくなったらまた再度ラズパイを断ちあげてリチューム電池を消費させないとだめかもしれません。

charset=InvalidCharsetId