Skip to content

Instantly share code, notes, and snippets.

@ttatsf
Created September 27, 2017 08:55
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ttatsf/4186400f7cf43cf68cc6df16194e65c9 to your computer and use it in GitHub Desktop.
Save ttatsf/4186400f7cf43cf68cc6df16194e65c9 to your computer and use it in GitHub Desktop.
#include <FlexiTimer2.h>
constexpr auto LED_PIN ( 13 );
constexpr auto NUM_BATTERIES ( 4 );
constexpr auto START_VALUE ( 205 ); // 1.0v
constexpr auto THRESHOLD_H ( 307 ); // 1.5v
constexpr auto THRESHOLD_L ( 205 ); // 1.0v
constexpr auto ALMOST_ZERO ( 21 ); // 0.1v
//平滑化する関数オブエクト。Batteryのメンバ関数として使う。
class Smooth {
private:
int smoothPrev = START_VALUE ;
public:
auto operator()( const int DATA ) -> int {
constexpr auto RATE ( 30 );
return smoothPrev = ( RATE * DATA + ( 100 - RATE ) * smoothPrev ) / 100;
}
};
// Battery構造体の定義
struct Battery{
const int NUM;
const int INPIN;
const int OUTPIN;
bool isReset;
bool toGo;
// データが範囲外なら放電をoffにする。ほとんど0になったらリセットし、範囲内に入ったら放電on。
auto doByData( const int DATA ) -> int{
if( DATA < THRESHOLD_H && DATA > THRESHOLD_L ) {
if( isReset ) {
toGo = true;
isReset = false;
digitalWrite( OUTPIN, HIGH );
return DATA;
}
return DATA;
}else if ( DATA < ALMOST_ZERO ) {
isReset = true;
return DATA;
}else {
toGo = false;
digitalWrite( OUTPIN, LOW );
return DATA;
}
}
Smooth smooth;
Battery(int num, int inPin, int outPin ) : NUM ( num )
, INPIN ( inPin )
, OUTPIN ( outPin )
, isReset ( true )
, toGo ( false ) {
}
};
// Batteryの配列を作る
volatile Battery BATTERIES[ NUM_BATTERIES ] { Battery( 1, A1, 2 )
, Battery( 2, A2, 3 )
, Battery( 3, A3, 4 )
, Battery( 4, A4, 5 )
};
// データをボルトに変換する。
auto dataToVolt( const int DATA ) -> float{
return (float)map( DATA, 0, 1023, 0, 5000) / 1000.0;
}
// Batteryの番号、放電の状態、電圧を表示する。
auto sPrint( volatile const Battery& b, const int DATA ) -> int{
Serial.print("NO.");
Serial.print( b.NUM );
if( b.isReset ){Serial.print(" RESET ");}
else if( b.toGo ) {Serial.print(" GO ");}
else{ Serial.print(" STOP ");}
Serial.print( dataToVolt( DATA ), 2 );
Serial.print("v ");
return DATA;
}
// 割り込みに登録する処理。バッテリーを読み、平滑化、放電を管理、状態表示する。
auto controlDischarge()->void{
for( auto&& b : BATTERIES ){
sPrint( b , b.doByData( b.smooth( analogRead( b.INPIN )
) ) );
}
Serial.println();
}
// 放電中の電池の番号を点滅表示する。
auto flashWhenGo(volatile const Battery& b, const int LED_PIN ) -> void {
if( b.toGo ){
for( int i = 0; i < b.NUM; i++ ){
digitalWrite( LED_PIN, HIGH );
delay( 50 );
digitalWrite( LED_PIN, LOW );
delay( 150 );
}
delay( 200 );
}
}
void setup() {
pinMode( LED_PIN, OUTPUT );
for( const auto& b: BATTERIES ){
pinMode( b.OUTPIN, OUTPUT );
digitalWrite( b.OUTPIN, true );
}
FlexiTimer2::set(1000, 1.0/1000, controlDischarge); // call every 1000 1ms "ticks"
FlexiTimer2::start();
Serial.begin(9600);
}
void loop() {
for( auto&& b : BATTERIES ){
flashWhenGo( b, LED_PIN );
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment