Skip to content

Commit 1d8ed5b

Browse files
committed
Introducing hardware dimmer using analogWrite()
1 parent 30a6c6e commit 1d8ed5b

File tree

3 files changed

+232
-3
lines changed

3 files changed

+232
-3
lines changed

src/Dimmer.h

+3-3
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
*
66
* Author: Balazs Kelemen
77
* Contact: [email protected]
8-
* Copyright: 2012 Balazs Kelemen
8+
* Copyright: 2020 Balazs Kelemen
99
* Copying permission statement:
1010
This file is part of SoftTimer.
1111
@@ -42,7 +42,7 @@ class Dimmer : public Task
4242
/**
4343
* We use the SoftPwmTask for dimming.
4444
* pwm - The predefined SoftPwm task.
45-
* frequencyMs - Milliseconds will be passed in the OFF->ON->OFF cicle.
45+
* frequencyMs - Milliseconds will be passed in the OFF->ON->OFF cycle.
4646
* stepCount - Steps should be perform between a full ON-OFF state.
4747
*/
4848
Dimmer(SoftPwmTask* pwm, int frequencyMs, byte stepCount = DEFAULT_STEP_COUNT);
@@ -82,7 +82,7 @@ class Dimmer : public Task
8282
void revertDirection();
8383

8484
/**
85-
* Milliseconds will be passed in the OFF->ON->OFF cicle.
85+
* Milliseconds will be passed in the OFF->ON->OFF cycle.
8686
*/
8787
void setFrequency(int frequencyMs);
8888

src/HardDimmer.cpp

+108
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
/**
2+
* File: HardDimmer.cpp
3+
* Description:
4+
* SoftTimer library is a lightweight but effective event based timeshare solution for Arduino.
5+
*
6+
* Author: Balazs Kelemen
7+
* Contact: [email protected]
8+
* Copyright: 2012 Balazs Kelemen
9+
* Copying permission statement:
10+
This file is part of SoftTimer.
11+
12+
SoftTimer is free software: you can redistribute it and/or modify
13+
it under the terms of the GNU General Public License as published by
14+
the Free Software Foundation, either version 3 of the License, or
15+
(at your option) any later version.
16+
17+
This program is distributed in the hope that it will be useful,
18+
but WITHOUT ANY WARRANTY; without even the implied warranty of
19+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20+
GNU General Public License for more details.
21+
22+
You should have received a copy of the GNU General Public License
23+
along with this program. If not, see <http://www.gnu.org/licenses/>.
24+
25+
*/
26+
27+
#include "SoftTimer.h"
28+
#include "HardDimmer.h"
29+
30+
HardDimmer::HardDimmer(int pwmPin, int frequencyMs) : Task(10, &(HardDimmer::step))
31+
{
32+
this->_pwmPin = pwmPin;
33+
this->direction = DIMMER_DIRECTION_HIGH;
34+
this->value = 0;
35+
pinMode(this->_pwmPin, OUTPUT);
36+
this->stepCount = DEFAULT_STEP_COUNT;
37+
38+
this->setFrequency(frequencyMs);
39+
}
40+
41+
42+
void HardDimmer::startPulsate() {
43+
this->stopOnLimit = false;
44+
analogWrite(this->_pwmPin, (int)this->value);
45+
SoftTimer.add(this);
46+
}
47+
48+
void HardDimmer::hold() {
49+
SoftTimer.remove(this);
50+
}
51+
52+
void HardDimmer::off() {
53+
this->hold();
54+
digitalWrite(this->_pwmPin, LOW);
55+
SoftTimer.remove(this);
56+
}
57+
58+
void HardDimmer::revertDirection() {
59+
this->direction *= -1;
60+
}
61+
62+
void HardDimmer::setFrequency(int frequencyMs) {
63+
this->_stepLevel = (float)(this->_topLevel - this->_bottomLevel) / (float)this->stepCount;
64+
this->periodMicros = (float)frequencyMs * 500.0 / (float)this->stepCount;
65+
/*
66+
Serial.print("Dimmer");
67+
Serial.print(this->_pwmPin);
68+
Serial.print(": stepLevel= ");
69+
Serial.print(this->_stepLevel);
70+
Serial.print(", periodMicros= ");
71+
Serial.println(this->periodMicros);
72+
*/
73+
}
74+
75+
byte HardDimmer::getUpperLimit() {
76+
return 255;
77+
}
78+
79+
80+
void HardDimmer::step(Task* task)
81+
{
82+
HardDimmer* dimmer = (HardDimmer*)task;
83+
84+
boolean isOnLimit = false;
85+
86+
dimmer->value += dimmer->direction * dimmer->_stepLevel;
87+
if((dimmer->direction < 0) && (dimmer->value < dimmer->_bottomLevel)) {
88+
dimmer->value = dimmer->_bottomLevel;
89+
dimmer->direction *= -1; // -- next time go in the other direction
90+
isOnLimit = true;
91+
} else if((dimmer->direction > 0) && (dimmer->value > dimmer->_topLevel)) {
92+
dimmer->value = dimmer->_topLevel;
93+
dimmer->direction *= -1; // -- next time go in the other direction
94+
isOnLimit = true;
95+
}
96+
97+
// Serial.print("Dimmer");
98+
// Serial.print(dimmer->_pwmPin);
99+
// Serial.print(" = ");
100+
// Serial.println((int)dimmer->value);
101+
analogWrite(dimmer->_pwmPin, (int)dimmer->value);
102+
103+
if(isOnLimit && dimmer->stopOnLimit) {
104+
SoftTimer.remove(dimmer);
105+
}
106+
107+
}
108+

src/HardDimmer.h

+121
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
/**
2+
* File: HardDimmer.h
3+
* Description:
4+
* SoftTimer library is a lightweight but effective event based timeshare solution for Arduino.
5+
*
6+
* Author: Balazs Kelemen
7+
* Contact: [email protected]
8+
* Copyright: 2020 Balazs Kelemen
9+
* Copying permission statement:
10+
This file is part of SoftTimer.
11+
12+
SoftTimer is free software: you can redistribute it and/or modify
13+
it under the terms of the GNU General Public License as published by
14+
the Free Software Foundation, either version 3 of the License, or
15+
(at your option) any later version.
16+
17+
This program is distributed in the hope that it will be useful,
18+
but WITHOUT ANY WARRANTY; without even the implied warranty of
19+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20+
GNU General Public License for more details.
21+
22+
You should have received a copy of the GNU General Public License
23+
along with this program. If not, see <http://www.gnu.org/licenses/>.
24+
25+
*/
26+
27+
#ifndef HARDDIMMER_H
28+
#define HARDDIMMER_H
29+
30+
#include "Task.h"
31+
#include "SoftPwmTask.h"
32+
#include "Arduino.h"
33+
34+
#define DIMMER_DIRECTION_HIGH 1
35+
#define DIMMER_DIRECTION_LOW -1
36+
37+
#define DEFAULT_STEP_COUNT 8
38+
39+
/**
40+
* HardDimmer should be a drop in replacement for Dimmer,
41+
* expect for the constructor.
42+
*/
43+
class HardDimmer : public Task
44+
{
45+
public:
46+
/**
47+
* We use the SoftPwmTask for dimming.
48+
* pwm - The predefined SoftPwm task.
49+
* frequencyMs - Milliseconds will be passed in the OFF->ON->OFF cycle.
50+
*/
51+
HardDimmer(int pwmPin, int frequencyMs);
52+
53+
/**
54+
* Start an unlimited pulsation from the current value on, in the current direction.
55+
*/
56+
void startPulsate();
57+
58+
/**
59+
* Hold current PWM value on the output.
60+
*/
61+
void hold();
62+
63+
/**
64+
* Stop PWM, and set output to LOW.
65+
*/
66+
void off();
67+
68+
/**
69+
* Make the dimming to change direction.
70+
*/
71+
void revertDirection();
72+
73+
/**
74+
* Milliseconds will be passed in the OFF->ON->OFF cycle.
75+
*/
76+
void setFrequency(int frequencyMs);
77+
78+
/**
79+
* Get the upper level of the pwm.
80+
*/
81+
byte getUpperLimit();
82+
83+
void setBottomLevel(byte value = 0)
84+
{
85+
this->_bottomLevel = value;
86+
}
87+
void setTopLevel(byte value = 255)
88+
{
89+
this->_topLevel = value;
90+
}
91+
92+
/**
93+
* Current dim level PWM value. Note that the value should be between bottomLevel and topLevel.
94+
*/
95+
float value;
96+
97+
/**
98+
* Stop if zero, or pwm->upperLimit is reached.
99+
*/
100+
boolean stopOnLimit;
101+
102+
/**
103+
* Can be one of DIMMER_DIRECTION_HIGH or DIMMER_DIRECTION_LOW.
104+
*/
105+
char direction;
106+
107+
/**
108+
* Level-arranging steps should be performed within each full OFF->ON change. Will be applied if setFrequency() is called.
109+
*/
110+
byte stepCount;
111+
112+
private:
113+
int _pwmPin;
114+
float _stepLevel;
115+
static void step(Task* me);
116+
float _topLevel = 255;
117+
float _bottomLevel = 0;
118+
};
119+
120+
#endif
121+

0 commit comments

Comments
 (0)