Skip to content

Instantly share code, notes, and snippets.

@ffedoroff
Last active December 28, 2015 16:09
Show Gist options
  • Save ffedoroff/7527455 to your computer and use it in GitHub Desktop.
Save ffedoroff/7527455 to your computer and use it in GitHub Desktop.
arduino.cpp
// есть базовый класс 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
#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