-
Notifications
You must be signed in to change notification settings - Fork 35
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Introducing hardware dimmer using analogWrite()
- Loading branch information
Showing
3 changed files
with
232 additions
and
3 deletions.
There are no files selected for viewing
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -5,7 +5,7 @@ | |
* | ||
* Author: Balazs Kelemen | ||
* Contact: [email protected] | ||
* 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); | ||
|
||
|
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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: [email protected] | ||
* 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 <http://www.gnu.org/licenses/>. | ||
*/ | ||
|
||
#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); | ||
} | ||
|
||
} | ||
|
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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: [email protected] | ||
* 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 <http://www.gnu.org/licenses/>. | ||
*/ | ||
|
||
#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 | ||
|