Last active
December 28, 2015 16:09
-
-
Save ffedoroff/7527455 to your computer and use it in GitHub Desktop.
arduino.cpp
This file contains hidden or 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
| // есть базовый класс BaseSensor и есть у него наследники SonicSensor и остальные... | |
| // у них у всех есть public: virtual void init() {} | |
| // я точно проверил, что virtual не забыл | |
| // объявляю все красиво и удобно для меня | |
| BaseSensor sensors[] = { | |
| SonicSensor ("s0", 13, 12, 55, 5000, 0), | |
| SonicSensor ("s1", 11, 55, 5000, 0), | |
| SonicSensor ("s2", 10, 55, 5000, 0), | |
| SonicSensor ("s3", 9, 45, 5000, 0), | |
| ButtonSensor ("b01", 8, 10, 100, 0), | |
| ButtonSensor ("b02", 7, 10, 100, 0), | |
| BoolSensor ("m1", 6, 5000, 0), | |
| BoolSensor ("m2", 5, 5000, 0), | |
| BoolSensor ("m3", 4, 5000, 0), | |
| BoolSensor ("m4", 3, 5000, 0), | |
| }; | |
| // пытаюсь вызвать метод init() | |
| sensors[2].init(); // ОШИБКА! вызывается метод init не у наследника (SonicSensor), а у базового класса (BaseSensor) | |
| // но если попробовать объявить по другому, то все работает | |
| SonicSensor obj_b("tmp", 12, 1, 2, 3); | |
| BaseSensor &obj_a = obj_b; | |
| obj_a.init(); // ТУТ ВСЕ ПРАВИЛЬНО. Вызывается метод init у наследника (SonicSensor), а не у базового класса (BaseSensor) | |
| // ВОПРОС - как мне красиво в массиве инициализировать всех наследников? | |
| // Проект на Arduino и там есть всякие ограничения | |
| // operators new and delete not supported | |
| // не работает так-же std::vector | |
| // подробнее про ограничения Arduino: http://stackoverflow.com/questions/461836/arduino-c-code-can-you-use-virtual-functions-and-exceptions |
This file contains hidden or 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 "Arduino.h" | |
| using namespace std; | |
| typedef unsigned char byte; | |
| // Base class for sensors | |
| class BaseSensor | |
| { | |
| public: | |
| //bool is_sonic; | |
| byte pin; // arduino pin | |
| byte bit_position; // position bit in output result | |
| const char* name; // name (will be used for debug) | |
| unsigned short int ddos; // ddos filter in MS | |
| bool last_value; // last bool value | |
| unsigned long last_time; // time when sensor trigger event last time | |
| const char* get_name() { | |
| return name; | |
| } | |
| virtual bool is_sonic() {return false;}; // is it sonic sensor or not | |
| virtual void init() { | |
| last_value = 0; | |
| last_time = 0; | |
| //is_sonic = false; | |
| Serial.println("init of base "+as_string()); | |
| }; // init pins, values, etc | |
| virtual bool process(bool ret, unsigned long time) {}; // process logic | |
| virtual String as_string(){ | |
| String ret = ""; | |
| ret+= name; ret+= ", "; | |
| ret+= pin; ret+= ", "; | |
| ret+= ddos; ret+= ", lv="; | |
| ret+= last_value; ret+= ", "; | |
| ret+= last_time; ret+= ", bp="; | |
| ret+= bit_position; ret+= ", son="; | |
| ret+= is_sonic(); | |
| return ret; | |
| } | |
| BaseSensor(const char* name_, byte pin_, unsigned short int ddos_, byte bit_position_) { | |
| name = name_; | |
| pin = pin_; | |
| ddos = ddos_; | |
| bit_position = bit_position_; | |
| } | |
| virtual ~BaseSensor() {} | |
| protected: | |
| unsigned long last_changed; // when changed last time | |
| }; | |
| // Ultrasonic sensor | |
| class SonicSensor: public BaseSensor | |
| { | |
| public: | |
| //SonicSensor(byte, byte, unsigned short int, unsigned short int, byte); | |
| byte pin_trigger; // arduino trigger pin (optional) | |
| unsigned short int disatance; // min distance to trigger SM | |
| byte state; // 0=init 1=time 2=completed, | |
| //unsigned int micros_duration; // duration in microseconds | |
| unsigned short int last_raw_value; // last distance in SM | |
| virtual void init() { | |
| BaseSensor::init(); | |
| if (pin_trigger < 255) { | |
| //pinMode(pin_trigger, OUTPUT); | |
| } | |
| //pinMode(pin, INPUT); // echo pin | |
| this->ddos = 77; | |
| Serial.println("init of SONIC!!! "+as_string()); | |
| } | |
| long send_trigger_sound() { | |
| if (pin_trigger < 255) { | |
| digitalWrite(pin_trigger, LOW); | |
| delayMicroseconds(2); | |
| digitalWrite(pin_trigger, HIGH); | |
| delayMicroseconds(10); | |
| digitalWrite(pin_trigger, LOW); | |
| } | |
| // skip echo response track if ddos | |
| if (millis()-last_time>ddos) { | |
| last_raw_value = disatance; | |
| state = 2; | |
| } else { | |
| last_raw_value = 0; | |
| state = 0; | |
| } | |
| last_value = false; | |
| } | |
| bool process_echo(unsigned long trigMicros, unsigned long maxSonicDelay) { | |
| if (state < 2) { // if sensor not processed | |
| unsigned long duration = micros()-trigMicros; | |
| if (duration > maxSonicDelay) { | |
| last_raw_value = disatance; | |
| state = 2; | |
| last_value = false; | |
| } else if (digitalRead(pin) == LOW) { // low | |
| if (state == 1) { // if low AFTER high | |
| last_raw_value = (duration/2) / 35; | |
| state = 2; | |
| last_value = last_raw_value <= disatance; | |
| } | |
| } else if (state == 0) { // first high | |
| state = 1; | |
| //sonicVals[i][1] = micros(); //don't know what is it... | |
| } | |
| delayMicroseconds(50); | |
| } | |
| return state == 2; | |
| } | |
| virtual bool is_sonic() {return true;}; | |
| SonicSensor(const char* name_, byte pin_echo_, unsigned short int disatance_, unsigned short int ddos_, byte bit_position_) : | |
| BaseSensor(name_, pin_echo_, ddos_, bit_position_) { | |
| SonicSensor(name_, 255, pin_echo_, disatance_, ddos_, bit_position_); | |
| } | |
| SonicSensor(const char* name_, byte pin_trigger_, byte pin_echo_, unsigned short int disatance_, unsigned short int ddos_, byte bit_position_) : | |
| BaseSensor(name_, pin_echo_, ddos_, bit_position_) { | |
| pin_trigger = pin_trigger_; | |
| disatance = disatance_; | |
| } | |
| }; | |
| // PIR sensors, etc. | |
| class BoolSensor: public BaseSensor | |
| { | |
| public: | |
| virtual void init() { | |
| BaseSensor::init(); | |
| //Serial.println("init of BOOL!!! "+as_string()); | |
| //pinMode(pin, INPUT); | |
| } | |
| virtual bool process(bool ret, unsigned long time) { | |
| if (time-last_time > ddos) { | |
| if (digitalRead(pin) == HIGH) { | |
| return true; | |
| } | |
| } | |
| return ret; | |
| } | |
| BoolSensor(const char* name_, byte pin_, unsigned short int ddos_, byte bit_position_) : | |
| BaseSensor(name_, pin_, ddos_, bit_position_) { | |
| } | |
| }; | |
| // button sensor | |
| class ButtonSensor: public BoolSensor | |
| { | |
| public: | |
| byte hold_time; // how long should value holds to trigger event | |
| ButtonSensor(const char* name_, byte pin_, byte hold_time_, unsigned short int ddos_, byte bit_position_) : | |
| BoolSensor(name_, pin_, ddos_, bit_position_) { | |
| hold_time = hold_time_; | |
| } | |
| }; | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment