130
edits
| No edit summary | No edit summary | ||
| Line 1: | Line 1: | ||
| [[ | |||
| ---- | |||
| Source code Arduino: | |||
| Arduino.ino: | |||
| <pre> | |||
| #include "Unit.h" | |||
| #include "RunningAverage.h" | |||
| #include "StopWatch.h" | |||
| bool doprint=true; | |||
| const int threshold=20; | |||
| const int neg_threshold=-10; | |||
| const int array_size=15; | |||
| const int fill_array=200; | |||
| unsigned int grow_time=36000; | |||
| unsigned int break_time=7200; | |||
| unsigned int wait_time=1200; | |||
| const int unit_one_sensor=A0; | |||
| const int unit_two_sensor=A1; | |||
| const int unit_thr_sensor=A2; | |||
| int unit_one_plus=4; | |||
| int unit_one_minus=5; | |||
| int unit_two_plus=6; | |||
| int unit_two_minus=7; | |||
| int unit_thr_plus=8; | |||
| int unit_thr_minus=9; | |||
| Unit one(unit_one_sensor, unit_one_minus, unit_one_plus, 1, threshold, array_size, fill_array); | |||
| Unit two(unit_two_sensor, unit_two_minus, unit_two_plus, 2, threshold, array_size, fill_array); | |||
| Unit thr(unit_thr_sensor, unit_thr_minus, unit_thr_plus, 3, threshold, array_size, fill_array); | |||
| void setup(){ | |||
|   pinMode(unit_one_minus,OUTPUT);  | |||
|   pinMode(unit_one_plus,OUTPUT);  | |||
|   pinMode(unit_two_minus,OUTPUT); | |||
|   pinMode(unit_two_plus,OUTPUT);  | |||
|   pinMode(unit_thr_minus,OUTPUT);  | |||
|   pinMode(unit_thr_plus,OUTPUT); | |||
|   Serial.begin(19200); | |||
|   Serial.println("burnout_011");  | |||
|   one.wachse(); | |||
|   two.wachse(); | |||
|   thr.wachse(); | |||
| } | |||
| void loop(){ | |||
|  /* | |||
|   one.run(); | |||
|   two.run(); | |||
|   thr.run(); | |||
|   */ | |||
|   one.run_timed(grow_time, break_time, wait_time); | |||
|   two.run_timed(grow_time, break_time, wait_time); | |||
|   thr.run_timed(grow_time, break_time, wait_time); | |||
|   if(doprint) | |||
|   {   | |||
|     one.do_print(); | |||
|     two.do_print(); | |||
|     thr.do_print(); | |||
|     Serial.println();  | |||
|   } | |||
|   delay(1); | |||
| } | |||
| </pre> | |||
| Unit.h | |||
| <pre> | |||
| #ifndef Unit_h | |||
| #define Unit_h | |||
| #include "RunningAverage.h" | |||
| #include "StopWatch.h" | |||
| class Unit | |||
| { | |||
| public:   | |||
|   Unit(void); | |||
|   Unit(int const& sensor, int const& minus, int const& plus, int const& unitid, int const& threshold, int const& size, int const& fillarray); | |||
|   ~Unit();   | |||
|   void wachse(); | |||
|   void breche(); | |||
|   void warte(); | |||
|   int state(); | |||
|   void run(); | |||
|   void run_timed(unsigned int const& grow_time, unsigned int const& break_time, unsigned int const& wait_time); | |||
|   void emergency_break(); | |||
|   void do_print(); | |||
|   void fill_spaces(int const& value); | |||
| private:   | |||
|   int m_sensor; | |||
|   int m_relais_minus;   | |||
|   int m_relais_plus;   | |||
|   int m_state; | |||
|   int m_unitid; | |||
|   int m_threshold; | |||
|   int m_fillarray; | |||
|   RunningAverage m_RA; | |||
|   RunningAverage m_delta_RA; | |||
|   StopWatch m_sw; | |||
|   int m_readings; | |||
| }; | |||
| #endif | |||
| </pre> | |||
| Unit.cpp | |||
| <pre> | |||
| #include "Unit.h" | |||
| #include "RunningAverage.h" | |||
| #include "StopWatch.h" | |||
| #include <Arduino.h> | |||
| Unit::Unit(int const& sensor, int const& r_minus, int const& r_plus, int const& unitid, int const& threshold, int const& size, int const& fillarray) | |||
| { | |||
|   m_sensor=sensor; | |||
|   m_relais_minus = r_minus; | |||
|   m_relais_plus = r_plus; | |||
|   m_unitid=unitid; | |||
|   m_threshold=threshold; | |||
|   m_state=0;   | |||
|   m_fillarray=fillarray; | |||
|   m_sw.start(); | |||
|   m_RA.init(size); | |||
|   m_delta_RA.init(size); | |||
|   digitalWrite(m_relais_minus, HIGH); | |||
|   digitalWrite(m_relais_plus, HIGH);   | |||
| } | |||
| Unit::~Unit() | |||
| { | |||
| } | |||
| void Unit::wachse() | |||
| {     | |||
|   digitalWrite(m_relais_minus, LOW); | |||
|   digitalWrite(m_relais_plus, HIGH);   | |||
|   m_state=1; | |||
| } | |||
| void Unit::breche() | |||
| { | |||
|   digitalWrite(m_relais_minus, HIGH); | |||
|   delay(10); | |||
|   digitalWrite(m_relais_plus, LOW); | |||
|   m_state=2; | |||
| } | |||
| void Unit::warte() | |||
| { | |||
|   digitalWrite(m_relais_minus, HIGH); | |||
|   digitalWrite(m_relais_plus, HIGH); | |||
|   m_state=3; | |||
| } | |||
| int Unit::state() | |||
| { | |||
|   return m_state; | |||
| } | |||
| void Unit::run() | |||
| { | |||
|   m_readings=analogRead(m_sensor); | |||
|   emergency_break(); | |||
|   m_RA.addValue(m_readings); | |||
|   m_delta_RA.addValue(m_readings-m_RA.getAverage()); | |||
|   if(m_fillarray>0) | |||
|   { | |||
|     m_fillarray--; | |||
|   } | |||
|   else if(m_readings<=1000) | |||
|   {	 | |||
|     if(m_delta_RA.getAverage()>m_threshold) | |||
|     { | |||
|       breche(); | |||
|     } | |||
|     if(m_delta_RA.getAverage()<(-m_threshold)) | |||
|     { | |||
|       wachse(); | |||
|     } | |||
|   } | |||
| } | |||
| void Unit::run_timed(unsigned int const&  grow_time, unsigned int const& break_time, unsigned int const& wait_time) | |||
| { | |||
|   m_readings=analogRead(m_sensor); | |||
|   emergency_break(); | |||
|   m_RA.addValue(m_readings); | |||
|   m_delta_RA.addValue(m_readings-m_RA.getAverage()); | |||
|   if(m_fillarray>0) | |||
|   { | |||
|     m_fillarray--; | |||
|   } | |||
|   else if(m_readings<=1000) | |||
|   {	 | |||
|     if(m_delta_RA.getAverage()>m_threshold) | |||
|     { | |||
|       breche(); | |||
|       m_sw.reset(); | |||
|       m_sw.start(); | |||
|     } | |||
|     if(m_delta_RA.getAverage()<(-m_threshold)) | |||
|     { | |||
|       wachse(); | |||
|       m_sw.reset(); | |||
|       m_sw.start(); | |||
|     } | |||
|     if(m_state==1 && m_sw.elapsed()>grow_time) | |||
|     { | |||
|       breche(); | |||
|     } | |||
|     if(m_state==2 && m_sw.elapsed()>break_time) | |||
|     { | |||
|       wachse(); | |||
|     } | |||
|     if(m_state==3 && m_sw.elapsed()>wait_time) | |||
|     { | |||
|       wachse(); | |||
|     } | |||
|   } | |||
| } | |||
| void Unit::do_print() | |||
| { | |||
|   Serial.print(" unit"); | |||
|   Serial.print(m_unitid); | |||
|   Serial.print(": "); | |||
|   Serial.print(m_state); | |||
|   fill_spaces(m_readings); | |||
|   Serial.print(m_readings); | |||
|   Serial.print("  "); | |||
|   fill_spaces(m_delta_RA.getAverage()); | |||
|   Serial.print(m_delta_RA.getAverage()); | |||
|   Serial.print("#"); | |||
|   fill_spaces(m_fillarray); | |||
|   Serial.print(m_fillarray); | |||
|   Serial.print("->"); | |||
|   fill_spaces(m_sw.elapsed()); | |||
|   Serial.print(m_sw.elapsed()); | |||
| } | |||
| void Unit::emergency_break() | |||
| { | |||
|   if(m_readings>1000 && m_readings < 1010) | |||
|   { | |||
|     Serial.print(" | "); | |||
|     Serial.print(m_readings); | |||
|     Serial.print("  "); | |||
|     Serial.print("HIGH"); | |||
|     Serial.print(" E_1 UNIT"); | |||
|     Serial.print(m_unitid); | |||
|     Serial.print(": "); | |||
|     Serial.print(m_state); | |||
|     Serial.print(" | "); | |||
|     breche(); | |||
|     m_sw.reset(); | |||
|     m_sw.start(); | |||
|   } | |||
|   if(m_readings>=1010) | |||
|   { | |||
|     Serial.print(" # "); | |||
|     Serial.print(m_readings); | |||
|     Serial.print(" # "); | |||
|     Serial.print("HIGH"); | |||
|     Serial.print(" E_2 UNIT"); | |||
|     Serial.print(m_unitid); | |||
|     Serial.print(": "); | |||
|     Serial.print(m_state); | |||
|     Serial.print(" # "); | |||
|     wachse(); | |||
|     delay(10); | |||
|     breche(); | |||
|     m_sw.reset(); | |||
|     m_sw.start(); | |||
|   } | |||
|   if(m_readings>1022) | |||
|   { | |||
|     Serial.print(" | "); | |||
|     Serial.print(m_readings); | |||
|     Serial.print("  "); | |||
|     Serial.print("HIGH"); | |||
|     Serial.print(" E_3 UNIT"); | |||
|     Serial.print(m_unitid); | |||
|     Serial.print(": "); | |||
|     Serial.print(m_state); | |||
|     Serial.print(" | "); | |||
|     warte(); | |||
|     m_sw.reset(); | |||
|     m_sw.start(); | |||
|   } | |||
| } | |||
| void Unit::fill_spaces(int const& value) | |||
| { | |||
|   if(value<1000 && value>=0) | |||
|   { | |||
|     Serial.print(" "); | |||
|     if(value<100) | |||
|     { | |||
|       Serial.print(" "); | |||
|       if(value<10) | |||
|       { | |||
|         Serial.print(" "); | |||
|       } | |||
|     } | |||
|   } | |||
|   if(value>-1000 && value<0) | |||
|   { | |||
|     if(value>-100) | |||
|     { | |||
|       Serial.print(" "); | |||
|       if(value>-10) | |||
|       { | |||
|         Serial.print(" "); | |||
|       } | |||
|     } | |||
|   } | |||
| } | |||
| </pre> | |||
| RunningAverage.h | |||
| <pre> | |||
| #ifndef RunningAverage_h | |||
| #define RunningAverage_h | |||
| //  | |||
| //    FILE: RunningAverage.h | |||
| //  AUTHOR: Rob dot Tillaart at gmail dot com | |||
| // PURPOSE: RunningAverage library for Arduino | |||
| //     URL: http://playground.arduino.cc/Main/RunningAverage | |||
| // HISTORY: See RunningAverage.cpp | |||
| // | |||
| // Released to the public domain | |||
| // | |||
| // backwards compatibility | |||
| // clr() clear() | |||
| // add(x) addValue(x) | |||
| // avg() getAverage() | |||
| #define RUNNINGAVERAGE_LIB_VERSION "0.2.02" | |||
| class RunningAverage  | |||
| { | |||
| public: | |||
|   RunningAverage(); | |||
|   RunningAverage(int); | |||
|   ~RunningAverage(); | |||
|   void clear(); | |||
|   void init(int n); | |||
|   void addValue(int); | |||
|   int getAverage(); | |||
|   void fillValue(int, int); | |||
| protected: | |||
|   int _size; | |||
|   int _cnt; | |||
|   int _idx; | |||
|   int _sum; | |||
|   int * _ar; | |||
| }; | |||
| #endif | |||
| // END OF FILE | |||
| </pre> | |||
| RunningAverage.cpp | |||
| <pre> | |||
| //  | |||
| //    FILE: RunningAverage.cpp | |||
| //  AUTHOR: Rob Tillaart | |||
| // VERSION: 0.2.02 | |||
| // PURPOSE: RunningAverage library for Arduino | |||
| // | |||
| // The library stores the last N individual values in a circular buffer,  | |||
| // to calculate the running average.  | |||
| // | |||
| // HISTORY:  | |||
| // 0.1.00 - 2011-01-30 initial version | |||
| // 0.1.01 - 2011-02-28 fixed missing destructor in .h | |||
| // 0.2.00 - 2012-??-?? Yuval Naveh added trimValue (found on web) | |||
| //          http://stromputer.googlecode.com/svn-history/r74/trunk/Arduino/Libraries/RunningAverage/RunningAverage.cpp | |||
| // 0.2.01 - 2012-11-21 refactored | |||
| // 0.2.02 - 2012-12-30 refactored trimValue -> fillValue | |||
| // | |||
| // Released to the public domain | |||
| // | |||
| #include "RunningAverage.h" | |||
| #include <stdlib.h> | |||
| RunningAverage::RunningAverage() | |||
| { | |||
| } | |||
| RunningAverage::RunningAverage(int n) | |||
| { | |||
|   _size = n; | |||
|   _ar = (int*) malloc(_size * sizeof(int)); | |||
|   clear(); | |||
| } | |||
| RunningAverage::~RunningAverage() | |||
| { | |||
|   free(_ar); | |||
| } | |||
| // resets all counters | |||
| void RunningAverage::clear()  | |||
| {  | |||
|   _cnt = 0; | |||
|   _idx = 0; | |||
|   _sum = 0.0; | |||
|   for (int i = 0; i< _size; i++) _ar[i] = 0.0;  // needed to keep addValue simple | |||
| } | |||
| void RunningAverage::init(int n) | |||
| { | |||
|   _size = n; | |||
|   _ar = (int*) malloc(_size * sizeof(int)); | |||
|   clear(); | |||
| } | |||
| // adds a new value to the data-set | |||
| void RunningAverage::addValue(int f) | |||
| { | |||
|   _sum -= _ar[_idx]; | |||
|   _ar[_idx] = f; | |||
|   _sum += _ar[_idx]; | |||
|   _idx++; | |||
|   if (_idx == _size) _idx = 0;  // faster than % | |||
|   if (_cnt < _size) _cnt++; | |||
| } | |||
| // returns the average of the data-set added sofar | |||
| int RunningAverage::getAverage() | |||
| { | |||
|   if (_cnt == 0) return 0; // NaN ?  math.h | |||
|   return _sum / _cnt; | |||
| } | |||
| // fill the average with a value | |||
| // the param number determines how often value is added (weight) | |||
| // number should preferably be between 1 and size | |||
| void RunningAverage::fillValue(int value, int number) | |||
| { | |||
|   clear(); | |||
|   for (int i = 0; i < number; i++)  | |||
|   { | |||
|     addValue(value); | |||
|   } | |||
| } | |||
| // END OF FILE | |||
| </pre> | |||
| Stopwatch.h | |||
| <pre> | |||
| #ifndef StopWatch_h | |||
| #define StopWatch_h | |||
| //  | |||
| //    FILE: StopWatch.h | |||
| //  AUTHOR: Rob Tillaart | |||
| // PURPOSE: Simple StopWatch library for Arduino | |||
| // HISTORY: See StopWatch.cpp | |||
| //     URL: http://playground.arduino.cc/Code/StopWatchClass | |||
| // | |||
| // Released to the public domain | |||
| // | |||
| #define STOPWATCH_LIB_VERSION "0.1.03" | |||
| #if ARDUINO >= 100 | |||
| #include "Arduino.h" | |||
| #else | |||
| #include "WProgram.h" | |||
| #endif | |||
| class StopWatch  | |||
| { | |||
| public: | |||
|   enum State {  | |||
|     RESET, RUNNING, STOPPED   }; | |||
|   enum Resolution {  | |||
|     MILLIS, MICROS, SECONDS   }; | |||
|   StopWatch(enum Resolution res = SECONDS); | |||
|   void start(); | |||
|   void stop();  | |||
|   void reset(); | |||
|   unsigned long value(); | |||
|   unsigned long elapsed() {  | |||
|     return value();  | |||
|   }; | |||
|   bool isRunning(); | |||
|   enum State state(); | |||
|   enum Resolution resolution() {  | |||
|     return _res;  | |||
|   }; | |||
| private: | |||
|   enum State _state; | |||
|   enum Resolution _res; | |||
|   unsigned long _starttime; | |||
|   unsigned long _stoptime; | |||
|   unsigned long (*_gettime)(void); | |||
|   static unsigned long seconds() {  | |||
|     return millis()/1000;  | |||
|   }; | |||
| }; | |||
| #endif | |||
| // END OF FILE | |||
| </pre> | |||
| StopWatch.cpp | |||
| <pre> | |||
| //  | |||
| //    FILE: StopWatch.cpp | |||
| //  AUTHOR: Rob Tillaart | |||
| // VERSION: 0.1.03 | |||
| // PURPOSE: Simple StopWatch library for Arduino | |||
| // | |||
| // The library is based upon millis() and therefore | |||
| // has the same restrictions as millis() has wrt overflow. | |||
| // | |||
| // HISTORY:  | |||
| // 0.1.00 - 2011-01-04 initial version | |||
| // 0.1.01 - 2011-01-04 Added better state | |||
| // 0.1.02 - 2011-06-15 Added state() + #defines + lib version | |||
| // 0.1.03 - 2012-01-22 Added several improvements | |||
| //             By mromani & Rob Tillaart | |||
| //  | |||
| // Released to the public domain | |||
| // | |||
| #include "StopWatch.h" | |||
| StopWatch::StopWatch(enum Resolution res) | |||
| { | |||
|   _res = res; | |||
|   switch(_res) { | |||
|   case MICROS: | |||
|     _gettime = micros; | |||
|     break; | |||
|   case MILLIS: | |||
|     _gettime = millis; | |||
|     break; | |||
|   case SECONDS: | |||
|     _gettime = seconds; | |||
|     break; | |||
|   default:   | |||
|     _gettime = millis; | |||
|     break; | |||
|   } | |||
|   reset(); | |||
| } | |||
| void StopWatch::reset() | |||
| { | |||
|   _state = StopWatch::RESET; | |||
|   _starttime = _stoptime = 0; | |||
| } | |||
| void StopWatch::start() | |||
| { | |||
|   if (_state == StopWatch::RESET || _state == StopWatch::STOPPED) | |||
|   { | |||
|     _state = StopWatch::RUNNING; | |||
|     unsigned long t = _gettime(); | |||
|     _starttime += t - _stoptime; | |||
|     _stoptime = t; | |||
|   } | |||
| } | |||
| unsigned long StopWatch::value() | |||
| { | |||
|   if (_state == StopWatch::RUNNING) _stoptime = _gettime(); | |||
|   return _stoptime - _starttime; | |||
| } | |||
| void StopWatch::stop() | |||
| { | |||
|   if (_state == StopWatch::RUNNING) | |||
|   { | |||
|     _state = StopWatch::STOPPED; | |||
|     _stoptime = _gettime(); | |||
|   } | |||
| } | |||
| bool StopWatch::isRunning() | |||
| { | |||
|   return (_state == StopWatch::RUNNING); | |||
| } | |||
| enum StopWatch::State StopWatch::state() | |||
| { | |||
|   return _state; | |||
| } | |||
| // END OF FILE | |||
| </pre> | |||
edits