|
|
Line 12: |
Line 12: |
| 3x Resitor 2.2Ω<br> | | 3x Resitor 2.2Ω<br> |
| 6x Relais<br> | | 6x Relais<br> |
| ----
| |
|
| |
| '''Diagram''':
| |
|
| |
| [[File:diagram_cb.png|frameless|800px]]
| |
|
| |
|
| |
|
| ---- | | ---- |
|
| |
|
| '''Code''':
| | [[Technical documentation]] |
| | |
| 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>
| |