Hello!
I have a problem with the subject. I’ve been already searching through google and this forum, but haven’t really managed yet, although I think I am on the right track…
I’m sorry for the long code snippets, but I was a bit unsure what to leave out. The dynamic allocation is naturally almost in the end of the second code…
Here’s a code which I got up running nicely, after carefully reading this article: Arduino the Object Way
const unsigned FADE_INTERVAL_MS = 10; // some parameters for timing..
const unsigned SENSE_INTERVAL_MS = 10;
class Sensor {
const int sensorScale = 4;
const int accTh = 10;
const int velTh = 200;
const byte inputPin;
int value;
unsigned long PREV_SENSE_MS = 0;
protected:
virtual void lightOn(int value) = 0;
virtual void lightDim(int value) = 0;
public:
Sensor(byte attachTo) :
inputPin(attachTo) // initialize pin for sensor
{
}
void setup() {
value = readValue(); // read the sensors output for the first time
}
void loop() {
int preValue = value;
int delta;
if (millis() - PREV_SENSE_MS >= SENSE_INTERVAL_MS) { // do not read the sensor on every round or the delta never rises
PREV_SENSE_MS += SENSE_INTERVAL_MS;
value = readValue();
}
delta = value - preValue; // delta is the "acceleration" of the sensor
if (delta > accTh && value >= velTh) { // on fast changes turn the LED on immediately
lightOn(value);
} else if (value < velTh) { // fade out completely, if below threshold
if (value >= 0) lightDim(0);
} else if (abs(delta) < accTh && value >= velTh) { // otherwise follow the sensor value
lightDim(value);
}
}
int readValue() {
int state = analogRead(inputPin) / 4; // scale the raw value roghly
return state;
}
};
class Led {
const byte outPin;
int brightness;
unsigned long PREV_FADE_MS = millis();
byte fadecycle = 0;
public:
Led(byte attachTo) :
outPin(attachTo) // initialize pin for LED
{
}
void setup() {
pinMode(outPin, OUTPUT); // define pin
analogWrite(outPin, 0); // turn the LED off
brightness = 0;
}
void loop()
{
if (millis() - PREV_FADE_MS >= FADE_INTERVAL_MS) { // makes fadig visible
PREV_FADE_MS += FADE_INTERVAL_MS;
fadecycle = 1;
} else {
fadecycle = 0;
}
}
void lightOn(int intensity) { // immediate full
brightness = intensity;
analogWrite(outPin, brightness);
}
void lightDim(int intensity) { // dimming the LED
if (brightness < intensity && fadecycle == 1) {
brightness++;
} else if (brightness > intensity && fadecycle == 1) {
brightness--;
} else if (brightness == intensity) {
brightness = intensity;
}
analogWrite(outPin, brightness);
}
};
class LedControlSensor: public Sensor {
Led &led; // initialize a reference to led
public:
LedControlSensor(byte attachToPin, Led &attachToLed) :
Sensor(attachToPin), // initialize a sensor
led(attachToLed) // define corresponding led for a sensor
{
}
protected:
void lightOn(int intensity) {
led.lightOn(intensity);
}
void lightDim(int intensity) {
led.lightDim(intensity);
}
};
const byte ledCount = 3;
Led leds[] = {
Led(11),
Led(9),
Led(10)
};
LedControlSensor sensors[] = {
LedControlSensor(A0, leds[0]),
LedControlSensor(A1, leds[1]),
LedControlSensor(A2, leds[2])
};
void setup() {
Serial.begin(9600); //
for (byte i = 0; i < ledCount; i++) {
sensors[i].setup();
leds[i].setup();
}
pinMode(13, OUTPUT); // for debugging...
digitalWrite(13, 0); //
}
void loop() {
for (byte i = 0; i < ledCount; i++) {
sensors[i].loop();
leds[i].loop();
}
}
I am quite happy with this, and I dare to say I uderstand 99% of it…
Here’s the same code, but I wondered if I could do this with dynamic allocation (just in case if I ever run into situation where I want to use loads of sensors or leds or actually anything…) The code compiles, yet it doesn’t do anything. I think it must be something with theses pointers pointing to god-knows-where, but here I lost the track myself… As source I used mainly the article mentioned before and this discussion on the forum: https://forum.arduino.cc/index.php?topic=590953.0
const unsigned FADE_INTERVAL_MS = 10;
const unsigned SENSE_INTERVAL_MS = 10;
class Runnable {
public:
virtual void setup() = 0;
virtual void loop() = 0;
};
class Sensor: public Runnable {
const int sensorScale = 4;
const int accTh = 10;
const int velTh = 150;
const byte inputPin;
int value;
unsigned long PREV_SENSE_MS = 0;
protected:
virtual void lightOn(int value) = 0;
virtual void lightDim(int value) = 0;
public:
Sensor(byte attachTo) :
inputPin(attachTo) // initialize pin for sensor
{
}
void setup() {
value = readValue(); // read the sensors output for the first time
}
void loop() {
//
}
int readValue() {
//
}
};
class Led: public Runnable {
const byte outPin;
int brightness;
unsigned long PREV_FADE_MS = millis();
byte fadecycle = 0;
public:
Led(byte attachTo) :
outPin(attachTo) // initialize pin for LED
{
}
void setup() {
//
}
void loop()
{
//
}
void lightOn(int intensity) {
//
}
void lightDim(int intensity) {
//
}
};
class LedControlSensor: public Sensor {
Led &led; // initialize a reference to led
public:
LedControlSensor(byte attachToPin, Led &attachToLed) :
Sensor(attachToPin), // initialize a sensor
led(attachToLed) // define corresponding led for a sensor
{
}
protected:
void lightOn(int intensity) {
led.lightOn(intensity);
}
void lightDim(int intensity) {
led.lightDim(intensity);
}
};
const byte ledCount = 3;
const byte runners = ledCount * 2;
byte LED_OUTPINS[] = {11, 9, 10};
byte SENSOR_PINS[] = {A0, A1, A2};
Runnable **runMe;
void setup() {
Serial.begin(9600);
pinMode(13, OUTPUT);
digitalWrite(13, 0);
byte runnerIndex = 0;
runMe = new Runnable*[runners];
for (byte i = 0; i < ledCount; i++) {
runMe[runnerIndex] = new Led(LED_OUTPINS[i]);
runnerIndex++;
}
for (byte i = 0; i < ledCount; i++) {
runMe[runnerIndex] = new LedControlSensor(SENSOR_PINS[i], runMe[i]);
runnerIndex++;
}
for (byte i = 0; i < runners; i++) {
runMe[i]->setup();
}
}
void loop() {
for (byte i = 0; i < ledCount; i++) {
runMe[i]->loop();
}
}
I appreciate your help! Also if you have suggestions and intrest in how to improve the code (please explain also why…), I’d love to hear them!
Toni.