Created
September 27, 2017 08:55
-
-
Save ttatsf/4186400f7cf43cf68cc6df16194e65c9 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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