スマホ充電器つけっぱなしでもリチウムイオン電池を長持ちさせる充電システムを製品化してみた


##はじめに
必要に駆られて ありもので作った[スマホ充電器つけっぱなしでもリチウムイオン電池を長持ちさせる充電システム](https://qiita.com/tomonnn1/items/9121d2ec68779bb1ef7e/)について
[秋葉原ロボット部](https://qiita.com/organizations/akb-robot/)でプレゼンした際に、「これイイね、作って売ったら～」って言われてその気になってみました　^^;
#製品化のために行ったアップデート
##動作の安定化
試作品を数か月使ってきて、スマホのローバッテリーアラートが鳴らなくてタイマーが起動しないことがありました
「バッテリーHD」というバッテリー監視アプリを見つけスマホにインストールしてバッテリー低下レベル設定をしたところ、安定して稼働するようになりました
![battap0.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/106489/254b6602-7072-9698-b951-159b6ba84121.jpeg)
このアプリはバッテリー低下レベル設定を5％毎に複数設定や、イヤホンジャックでもアラートを鳴らす設定ができます
今回は低下レベル40%～5%まで5%毎に全部アラート設定しました
![battap1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/106489/c6d4e8dd-99af-3de5-6efe-cf4251b2ab4f.jpeg)
記録グラフも％、電圧、温度など豊富で使いやすいのでおすすめです
![battap21.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/106489/0801b788-eb86-2bfb-41fb-4013ee860fdd.jpeg)
このグラフでは、バッテリーが10%から充電を始めた時の経過を確認しています
一回当たりの充電時間2時間で私の環境(スマホと充電器アダプタの組合せ)では16%程度充電され、3回充電を繰りかえし40%を越えたところで定常状態に入った事がみてとれます
![battap22.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/106489/04d5d0c9-0081-bf21-6669-6b1d3cc6dadd.jpeg)
バッテリー電圧グラフからは、最高で4Vより高い電圧はかかっていませんでした
![battap23.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/106489/b52cf8be-4276-a6d3-d378-ae0813e0329d.jpeg)
またスマホ内部温度グラフからも、最高で23℃以下で運用できており、ダメージの少ない運用ができている事が確認できました

##ハードウエアの見直し
手近なハードでエイヤと試作したものでしたので、部品点数・外観・コストなどを考慮して設計しなおします
###マイコン
スマホイヤホンアナログ入力 、USB電源スイッチデジタル出力、動作確認LEDデジタル出力 、内臓クロック という条件で、半導体不足のおり、在庫の中から小さくて安い「なんちゃってATMEGA88」な[LGT8F88DS20](https://www.avrfreaks.net/sites/default/files/forum_attachments/lgt8fx8d-series-databook-v1.0.5%20%281%29.pdf)を採用します
![lgt8f88ssop20.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/106489/28eb7de2-7dc2-6385-124e-d695903aeaf0.jpeg)
試作では 手持ちの["なのぼ～どAG"](https://tiisai.dip.jp/?page_id=935)に載っている マイク入力増幅・整流・フィルタ回路を流用しており、部品10点ほど使っています
![NBAGmic.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/106489/cf70b43d-0160-f338-4474-4d9a57ae5ae2.png)
![nbagmod.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/106489/e9c9960a-6cf2-f67e-2d01-1771ae04a12d.jpeg)
これをpull-down抵抗とDCカットのコンデンサの2点に削減し、ソフトで測定値を整形します。
I/Oの部品を極力減らし、回路図は以下のようになりました
![timer-schs.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/106489/825a4858-d2af-19ab-986a-aa6c714a18e6.png)
SSOP20ピンマイコン、チップ部品5点、USBコネクタまで削減しました
###ケース
日常で安全に使えるようにコンパクトなケースに収めます
USBコネクタの中に基板を収納すればローコストでコンパクト♪
![LGT8F88ds20.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/106489/3930f494-d5f3-6348-311a-75b1a5b8c36c.jpeg)
ケースからUSB電源アダプタへの給電ジャックとスマホのイヤホンジャックケーブルを引き出します
![usbcase.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/106489/d5ff6dba-182d-a578-bc80-b908240c86a9.jpeg)
回路図と外形が決まったところで基板を設計します
![chargetimer.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/106489/32e1fd04-a823-32d7-752d-a08683ac10a5.png)
実装部分のサイズは10mm x 16mm
片面では実装密度が高く手はんだが難しそうなので、両面実装にしました
##ソフトウエア開発環境
試作時と同様にArduino IDEを用い、LGT8Fx用の定義を追加して開発します
Arduino IDEからLGT8FxD用の書込器でマイコンに書込み、動作確認を行います
今回はbootloader経由のアップロードはハードから省略しており、bootloaderは書込みません
![debug.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/106489/dd90ea30-9f79-99ee-d3d7-3a6a1a611e6f.jpeg)
ArduinoIDEでのデバッグ用にマイコンのシリアルポートをUSBシリアルモジュールに接続します
内部状態をシリアルポートに出力してArduinoのターミナルソフトで確認しながら進めていきました
![debug.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/106489/73ec22ad-8a80-8205-2b25-8828a9e62456.png)
ArduinoIDEのグラフターミナルで変動する音声振幅信号を時系列で観測できたので、プログラム作成の助けになりました
##ソフトウエアアップデート
現在のスケッチを説明します

定義部、初期化部
タイマー時間設定は1時間に初期設定しています
1,2,3,4時間いずれかに設定でき、電源投入時のLED点滅数で表わされます
電源投入時にアナログ信号があった場合、時間設定が1時間長く変更されます
設定値はマイコンの不揮発性メモリに記録され、電源切れても保持されます

```c++:chargetimer.ino
/*
  SmartPhone Charge Timer
  Andriod Battery charging TIMER
  Charge two hour when battery alart ring. 
  Long life floating charging between 40% and 60%
  by @tomonnn1
  
*/

#include <EEPROM.h>

int ledPin = 3;    // LED connected to digital pin 3
int USBPin = 2;    // USB Power p-ch FET connected to digital pin 2
int DELEYMINS = 60;  // 1 hour timer

int max,min,sensorValue,test=0;

// the setup routine runs once when you press reset:
void setup() {
  // pullup all port except A0 pin
  for(int i=0; i<14; i++) pinMode(i,INPUT_PULLUP);
  for(int i=15; i<30; i++) pinMode(i,INPUT_PULLUP);
  // initialize serial  at 9600 bps for status debug
  Serial.begin(9600);
  pinMode(USBPin, OUTPUT);  
  digitalWrite(USBPin, HIGH);   // turn the USB power off
  analogWrite(ledPin,0);  // turn the LED off

  analogRead(A0);  // dummy read
  delay(500);
  max=min= analogRead(A0);  // initialize max,min
  Serial.println(max);

  // read timer length setting from EEPROM
  // 0=1hour, 1=2hour, 2=3hour, 3=4hour)
  int n = EEPROM[1];
  // if analog input is loud, increment timer setting
  if(readPeak(20)>100){
    EEPROM[1] = ++n ;
    test=1;
  }
  if(n > 3) EEPROM[1] = n = 0; // adjust setting value 
  Serial.print("EEPROM=");
  Serial.println(n);
  blink(n+1,200);
  if(test == 1) delay(5000);
  delay(100);
}

```

LED点滅表示
点滅回数と明るさを指定します

```c++:blink（　）
void blink(int n,int lit) {
  for(int i=0; i<n; i++) {
    analogWrite(ledPin,lit);
    delay(200);
    analogWrite(ledPin,0);
    delay(200);
  }
}

```

アナログ信号処理
ハードウエアを簡素化した分 アナログ信号の処理を追加しました
12bitアナログ信号を 10 x n 回読込み、前回ピーク値を越えていたら
前回ピーク値との差分の1/3だけ更新する事でノイズを低減します
10回サンプル毎にピーク値を減らしてホールドしている値を減衰させます
最大値と最小値の差分を振幅として返しています

```c++:readPeak（　）

// read analog 10*n times for peak value
int readPeak(int n) {
  for(int j=0; j<n; j++){
    // decrease peak value with each interval
    max-=5;min+=5;
//    min = max = analogRead(A0);
    for(int i=0; i<10; i++) {
      // read the input on analog pin 0:
      sensorValue = analogRead(A0);
      delay(1);
//      Serial.println(sensorValue);
      // set peak value
      if(sensorValue>max) max+=(sensorValue-max)/3;
      if(sensorValue<min) min-=(min-sensorValue)/3;
    }
  }
  return(max-min);
}  
```

充電タイマー
USB電源を入れて、t時間ループ待ち、USB電源を切ります
タイマー動作中はLEDが一秒毎に点滅します
最初はつきっぱなしで、残り時間に応じて点灯幅が減っていきます

```c++:usbpower（　）

// USB power on timer for "t" hour
void usbpower(int t) { 
  Serial.print("USBPower-ON");
  digitalWrite(USBPin,LOW );   // turn the USB power on 
  analogWrite(ledPin,200);   // turn LED on
  // start timer
  for( int m=0; m< DELEYMINS*t; m++) {
    int rate = (long)16*m/t ; // 1/1000 duration
    Serial.println(m);
    // wait for a minits
    for( int s=0; s<60; s++) { 
//DEBUG    for( int s=0; s< 1; s++) { 
      // wait for a second with LED blink
      analogWrite(ledPin,(1000-rate)/16+1);
      delay(1001-rate);
      analogWrite(ledPin,0);
      delay(rate);
      }
  }
  digitalWrite(USBPin, HIGH);   // turn the USB power off
  analogWrite(ledPin,0);   // turn LED off 
//  delay(1000);               // wait for 1 second
}

```

メイン


入力信号の振幅がしきい値を越えたら充電タイマーを起動します

```c++:loop（　）

// main loop
void loop() {
  int peak = readPeak(1);
  Serial.println(peak);  // print out the peak value
  analogWrite(ledPin,(peak)/20);  // lit LED indicater
  // peak exceed watermark ?
  if((peak)>100) usbpower(EEPROM[1]+1);
  delay(10);
  max=min= analogRead(A0);

}
```

##次は製造に取りかかります
ここまで、初版開発と動作確認まで完了しました
次に量産試作の部材を中国通販Aliexpressで発注します
![ali.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/106489/a50ebb3d-9902-fbdb-df78-2daf6662014b.png)
基板は,1枚10cm x 10cmに50個を並べて(panelize),折切り線(V-cut)、各基板右側の外形斜め部分は溝切(milling)指定しています![timer10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/106489/cc2b147e-cafa-d366-ff20-79899192ee32.png)
今回Elecrowに10枚を注文しました、500セット分の基板が届いたら怒涛の手はんだ製造が始まります
基板到着まで10日間ほどかかりますので、在庫部材の加工やマイコン書込みなどを仕込んでおきます

年内に頒布始めたいと思っていますが　さてどうなるでしょう
顛末について、次回をお楽しみに　／~~