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
+