diff --git a/src/Dimmer.h b/src/Dimmer.h index daab89d..cc844cc 100644 --- a/src/Dimmer.h +++ b/src/Dimmer.h @@ -5,7 +5,7 @@ * * Author: Balazs Kelemen * Contact: prampec+arduino@gmail.com - * Copyright: 2012 Balazs Kelemen + * Copyright: 2020 Balazs Kelemen * Copying permission statement: This file is part of SoftTimer. @@ -42,7 +42,7 @@ class Dimmer : public Task /** * We use the SoftPwmTask for dimming. * pwm - The predefined SoftPwm task. - * frequencyMs - Milliseconds will be passed in the OFF->ON->OFF cicle. + * frequencyMs - Milliseconds will be passed in the OFF->ON->OFF cycle. * stepCount - Steps should be perform between a full ON-OFF state. */ Dimmer(SoftPwmTask* pwm, int frequencyMs, byte stepCount = DEFAULT_STEP_COUNT); @@ -82,7 +82,7 @@ class Dimmer : public Task void revertDirection(); /** - * Milliseconds will be passed in the OFF->ON->OFF cicle. + * Milliseconds will be passed in the OFF->ON->OFF cycle. */ void setFrequency(int frequencyMs); diff --git a/src/HardDimmer.cpp b/src/HardDimmer.cpp new file mode 100644 index 0000000..8ff1c73 --- /dev/null +++ b/src/HardDimmer.cpp @@ -0,0 +1,108 @@ +/** + * File: HardDimmer.cpp + * Description: + * SoftTimer library is a lightweight but effective event based timeshare solution for Arduino. + * + * Author: Balazs Kelemen + * Contact: prampec+arduino@gmail.com + * Copyright: 2012 Balazs Kelemen + * Copying permission statement: + This file is part of SoftTimer. + + SoftTimer is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +*/ + +#include "SoftTimer.h" +#include "HardDimmer.h" + +HardDimmer::HardDimmer(int pwmPin, int frequencyMs) : Task(10, &(HardDimmer::step)) +{ + this->_pwmPin = pwmPin; + this->direction = DIMMER_DIRECTION_HIGH; + this->value = 0; + pinMode(this->_pwmPin, OUTPUT); + this->stepCount = DEFAULT_STEP_COUNT; + + this->setFrequency(frequencyMs); +} + + +void HardDimmer::startPulsate() { + this->stopOnLimit = false; + analogWrite(this->_pwmPin, (int)this->value); + SoftTimer.add(this); +} + +void HardDimmer::hold() { + SoftTimer.remove(this); +} + +void HardDimmer::off() { + this->hold(); + digitalWrite(this->_pwmPin, LOW); + SoftTimer.remove(this); +} + +void HardDimmer::revertDirection() { + this->direction *= -1; +} + +void HardDimmer::setFrequency(int frequencyMs) { + this->_stepLevel = (float)(this->_topLevel - this->_bottomLevel) / (float)this->stepCount; + this->periodMicros = (float)frequencyMs * 500.0 / (float)this->stepCount; + /* + Serial.print("Dimmer"); + Serial.print(this->_pwmPin); + Serial.print(": stepLevel= "); + Serial.print(this->_stepLevel); + Serial.print(", periodMicros= "); + Serial.println(this->periodMicros); + */ +} + +byte HardDimmer::getUpperLimit() { + return 255; +} + + +void HardDimmer::step(Task* task) +{ + HardDimmer* dimmer = (HardDimmer*)task; + + boolean isOnLimit = false; + + dimmer->value += dimmer->direction * dimmer->_stepLevel; + if((dimmer->direction < 0) && (dimmer->value < dimmer->_bottomLevel)) { + dimmer->value = dimmer->_bottomLevel; + dimmer->direction *= -1; // -- next time go in the other direction + isOnLimit = true; + } else if((dimmer->direction > 0) && (dimmer->value > dimmer->_topLevel)) { + dimmer->value = dimmer->_topLevel; + dimmer->direction *= -1; // -- next time go in the other direction + isOnLimit = true; + } + + // Serial.print("Dimmer"); + // Serial.print(dimmer->_pwmPin); + // Serial.print(" = "); + // Serial.println((int)dimmer->value); + analogWrite(dimmer->_pwmPin, (int)dimmer->value); + + if(isOnLimit && dimmer->stopOnLimit) { + SoftTimer.remove(dimmer); + } + +} + diff --git a/src/HardDimmer.h b/src/HardDimmer.h new file mode 100644 index 0000000..e9f9d76 --- /dev/null +++ b/src/HardDimmer.h @@ -0,0 +1,121 @@ +/** + * File: HardDimmer.h + * Description: + * SoftTimer library is a lightweight but effective event based timeshare solution for Arduino. + * + * Author: Balazs Kelemen + * Contact: prampec+arduino@gmail.com + * Copyright: 2020 Balazs Kelemen + * Copying permission statement: + This file is part of SoftTimer. + + SoftTimer is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +*/ + +#ifndef HARDDIMMER_H +#define HARDDIMMER_H + +#include "Task.h" +#include "SoftPwmTask.h" +#include "Arduino.h" + +#define DIMMER_DIRECTION_HIGH 1 +#define DIMMER_DIRECTION_LOW -1 + +#define DEFAULT_STEP_COUNT 8 + +/** + * HardDimmer should be a drop in replacement for Dimmer, + * expect for the constructor. + */ +class HardDimmer : public Task +{ + public: + /** + * We use the SoftPwmTask for dimming. + * pwm - The predefined SoftPwm task. + * frequencyMs - Milliseconds will be passed in the OFF->ON->OFF cycle. + */ + HardDimmer(int pwmPin, int frequencyMs); + + /** + * Start an unlimited pulsation from the current value on, in the current direction. + */ + void startPulsate(); + + /** + * Hold current PWM value on the output. + */ + void hold(); + + /** + * Stop PWM, and set output to LOW. + */ + void off(); + + /** + * Make the dimming to change direction. + */ + void revertDirection(); + + /** + * Milliseconds will be passed in the OFF->ON->OFF cycle. + */ + void setFrequency(int frequencyMs); + + /** + * Get the upper level of the pwm. + */ + byte getUpperLimit(); + + void setBottomLevel(byte value = 0) + { + this->_bottomLevel = value; + } + void setTopLevel(byte value = 255) + { + this->_topLevel = value; + } + + /** + * Current dim level PWM value. Note that the value should be between bottomLevel and topLevel. + */ + float value; + + /** + * Stop if zero, or pwm->upperLimit is reached. + */ + boolean stopOnLimit; + + /** + * Can be one of DIMMER_DIRECTION_HIGH or DIMMER_DIRECTION_LOW. + */ + char direction; + + /** + * Level-arranging steps should be performed within each full OFF->ON change. Will be applied if setFrequency() is called. + */ + byte stepCount; + + private: + int _pwmPin; + float _stepLevel; + static void step(Task* me); + float _topLevel = 255; + float _bottomLevel = 0; +}; + +#endif +