first commit

This commit is contained in:
Jérôme Delacotte
2025-03-06 11:15:32 +01:00
commit 7b30d6e298
5276 changed files with 2108927 additions and 0 deletions

View File

@@ -0,0 +1,201 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "{}"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright {yyyy} {name of copyright owner}
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

View File

@@ -0,0 +1,52 @@
# TriacDimmer
An arduino library for controlling a triac dimmer.
This library was designed to perform phase-control dimming control on a triac dimming circuit,
leveraging the ATmega328p's built-in timer peripheral to perform all time-critical functionality directly in hardware,
without the need to spend CPU time on an expensive control loop.
Note that this library is intended to control mains AC power.
Make sure you understand the risks and take appropriate precautions before working with mains AC.
The phase offsets are calculated based on the _measured_ mains frequency,
so this code will work regardless of 50/60Hz or any other frequency.
This includes correcting for any inaccuracies in the arduino's oscillator or the mains frequency.
This library was developed specifically for the Krida 2 CH Dimmer
([amazon](https://www.amazon.com/Dimmer-Module-Controller-Arduino-Raspberry/dp/B06Y1GVG26),
[alibaba](https://mdwdz.en.alibaba.com/product/60670737878-804998378/2CH_AC_LED_Light_Dimmer_Module_Controller_Board.html),
[inmojo](http://www.inmojo.com/store/krida-electronics/item/2-channel-ac-led-bulb-dimmer-module-v2/)),
and has been tested to work with the RobotDyn AC Dimmer
([robotdyn](https://robotdyn.com/ac-light-dimmer-module-1-channel-3-3v-5v-logic-ac-50-60hz-220v-110v.html)),
and should work fine with other phase-control dimming circuits that output a positive edge on their sync signal.
See [the example](examples/basic_example/basic_example.ino) for an example of how to use the library.
The library methods themselves are documented in [the library header](src/TriacDimmer.h).
This library **requires** the use of certain pins.
Pin 8 _must_ be used as the sync input, and pins 9 and 10 are the only pins that can be used as channel outputs.
This library _will not work_ on any other pins, period.
![fritzing diagram](fritzing.png)
## Flickering, and How to Fix It
If you experience issues with flickering, there are a handful of parameters you can pass to `begin` that can be adjusted depending on what sort of flickering you have.
By default, with no arguments the library uses these values as defaults:
```cpp
TriacDimmer::begin(pulse_length = 20, min_trigger = 2000, on_thresh = 2, off_thresh = 0.01)
```
First off, if you experience flickering regardless of the brightness value you set, increase `pulse_length` from the default `20` to a larger value like `50` or `100` until `TriacDimmer::setBrightness(pin, 0.5);` results in a stable glow.
Once it's stable at 0.5, set the brightness 1.0 (`TriacDimmer::setBrightness(pin, 1.0);`) and check for flickering.
There shouldn't be any, but if there is you can increase `min_trigger` from the default `2000` to perhaps `3000` or `4000` until the flickering stops.
If you're still experiencing flickering no matter how large `min_trigger` is, you can also try setting `on_thresh` to below the highest brightness level that causes flickering. This shouldn't normally be necessary though, as adjusting `min_trigger` should normally be enough.
The last step is to figure out the lowest brightness value can sustain without flickering.
By default the library is set to cut off completely for brightness values smaller than `0.01`, but if you still see flickering at `0.015` or `0.02` you can try setting `off_thresh` to a value that's larger than that.
If you've tried all of these steps and you still get flickering, consider opening an issue.
Make sure to include as much information about your setup as you can, including the specific dimmer board you're using.
Also, if you have access to an oscilliscope, screenshots are always helpful in trying to diagnose flickering.

View File

@@ -0,0 +1,70 @@
/*
Basic Example.
This sketch alternately fades two lights in and out, using a
digital mains AC dimmer switch board.
This sketch is meant to be used with one of these boards, or
something similar:
https://www.amazon.com/Dimmer-Module-Controller-Arduino-Raspberry/dp/B06Y1GVG26
https://mdwdz.en.alibaba.com/product/60670737878-804998378/2CH_AC_LED_Light_Dimmer_Module_Controller_Board.html
http://www.inmojo.com/store/krida-electronics/item/2-channel-ac-led-bulb-dimmer-module-v2/
While this sketch is meant to be used with a dual-channel dimmer,
it can also control just a single channel (just leave the second
channel disconnected).
Note that the circuit here uses high-voltage mains AC power - make
sure you understand the risks and take appropriate precautions.
The circuit:
* Pin 8 is connected to the dimmer 'sync' pin.
* Pin 9 is connected to the dimmer 'ch 1' pin.
* Pin 10 is connected to the dimmer 'ch 2' pin.
* The dimmer power input is connected to mains AC power.
* The dimmer channel 1 and channel 2 outputs are connected
to lightbulbs or other devices.
Created 2017-02-23
By Anson Mansfield
*/
#include <TriacDimmer.h>
// arduino pins
unsigned char sync = 8; //sync pin
unsigned char channel_1 = 9; // channel 1 pin
unsigned char channel_2 = 10; // channel 2 pin
void setup() {
// initialize the dimmer library.
TriacDimmer::begin();
}
void loop() {
// gradually increase brightness over time
for(float brightness = 0.00; brightness < 1.00; brightness += 0.01){
// set channel 1 to the brightness value:
TriacDimmer::setBrightness(channel_1, brightness);
// invert brightness for channel 2:
TriacDimmer::setBrightness(channel_2, 1 - brightness);
delay(20);
}
// and back down - decrease brightness over time
for(float brightness = 1.00; brightness > 0.00; brightness -= 0.01){
// set channel 1 to the brightness value:
TriacDimmer::setBrightness(channel_1, brightness);
// invert brightness for channel 2:
TriacDimmer::setBrightness(channel_2, 1 - brightness);
delay(20);
}
}

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 181 KiB

View File

@@ -0,0 +1,22 @@
#######################################
# Syntax Coloring Map
#######################################
#######################################
# Classes and datatypes (KEYWORD1)
#######################################
TriacDimmer KEYWORD1
detail KEYWORD1
#######################################
# Methods and functions (KEYWORD2)
#######################################
begin KEYWORD2
end KEYWORD2
setBrightness KEYWORD2
getCurrentBrightness KEYWORD2
disable KEYWORD2
######################################
# Constants/defines (LITERAL1)
#######################################

View File

@@ -0,0 +1,10 @@
name=TriacDimmer
version=1.1.0
author=Anson Mansfield <anson.mansfield@gmail.com>
maintainer=Anson Mansfield <anson.mansfield@gmail.com>
sentence=A library for controlling a triac dimmer.
paragraph=Uses the advanced capabilities of the Timer 1 perhipheral to offload all timing code from the CPU, resulting in much more accurate timing than is possible normally.
category=Device Control
url=https://github.com/AJMansfield/TriacDimmer
architectures=avr
includes=TriacDimmer.h

View File

@@ -0,0 +1,197 @@
#include "TriacDimmer.h"
#include <Arduino.h>
#include <assert.h>
#include <util/atomic.h>
uint16_t TriacDimmer::detail::pulse_length;
uint16_t TriacDimmer::detail::min_trigger;
float TriacDimmer::detail::on_thresh;
float TriacDimmer::detail::off_thresh;
volatile bool TriacDimmer::detail::ch_A_en;
volatile uint16_t TriacDimmer::detail::ch_A_up;
volatile uint16_t TriacDimmer::detail::ch_A_dn;
volatile uint16_t ch_A_dn_buf;
volatile bool TriacDimmer::detail::ch_B_en;
volatile uint16_t TriacDimmer::detail::ch_B_up;
volatile uint16_t TriacDimmer::detail::ch_B_dn;
volatile uint16_t ch_B_dn_buf;
uint16_t last_icr = 0;
volatile uint16_t TriacDimmer::detail::period = 16667;
void TriacDimmer::begin(uint16_t pulse_length, uint16_t min_trigger, float on_thresh, float off_thresh){
// Don't need atomic writes since the ISRs haven't started yet.
TriacDimmer::detail::pulse_length = pulse_length;
TriacDimmer::detail::min_trigger = min_trigger;
TriacDimmer::detail::on_thresh = on_thresh;
TriacDimmer::detail::off_thresh = off_thresh;
TCCR1A = 0;
TCCR1B = _BV(ICNC1) //input capture noise cancel
| _BV(ICES1) //positive edge
| _BV(CS11); // /8 prescaler
pinMode(8, INPUT);
TIFR1 = _BV(ICF1); //clear IC interrupt flag
TIMSK1 = _BV(ICIE1); //enable input capture interrupt
}
void TriacDimmer::end(){
TIMSK1 = 0; //disable the interrupts first!
TIFR1 = 0xFF; //clear all flags
TCCR1A = 0; //clear to reset state
TCCR1B = 0;
}
void TriacDimmer::setBrightness(uint8_t pin, float value){
assert(pin == 9 || pin == 10);
if (value > TriacDimmer::detail::on_thresh) {
digitalWrite(pin, HIGH);
TriacDimmer::disable(pin);
} else if (value < TriacDimmer::detail::off_thresh) {
digitalWrite(pin, LOW);
TriacDimmer::disable(pin);
} else {
if ((pin & 0x01) == 0x01){ // if (pin == 9){
TriacDimmer::detail::setChannelA(1 - value);
TriacDimmer::detail::ch_A_en = true;
} else { // if (pin == 10){
TriacDimmer::detail::setChannelB(1 - value);
TriacDimmer::detail::ch_B_en = true;
}
}
pinMode(pin, OUTPUT); // only set to output once configured.
}
void TriacDimmer::disable(uint8_t pin) {
assert(pin == 9 || pin == 10);
if ((pin & 0x01) == 0x01){ // if (pin == 9){
TriacDimmer::detail::disableChannelA();
} else { // if (pin == 10){
TriacDimmer::detail::disableChannelB();
}
}
float TriacDimmer::getCurrentBrightness(uint8_t pin){
assert(pin == 9 || pin == 10);
if ((pin & 0x01) == 0x01){ // if (pin == 9){
return 1 - TriacDimmer::detail::getChannelA();
} else { // if (pin == 10){
return 1 - TriacDimmer::detail::getChannelB();
}
}
void TriacDimmer::detail::setChannelA(float value){
uint16_t p, u, d;
ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
// Don't need atomic read for pulse_length or min_trigger since they're not updated from an ISR.
p = TriacDimmer::detail::period;
}
u = p * value;
d = constrain(u + TriacDimmer::detail::pulse_length, TriacDimmer::detail::min_trigger, p);
ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
TriacDimmer::detail::ch_A_up = u;
TriacDimmer::detail::ch_A_dn = d;
}
}
void TriacDimmer::detail::setChannelB(float value){
uint16_t p, u, d;
ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
// Don't need atomic read for pulse_length or min_trigger since they're not updated from an ISR.
p = TriacDimmer::detail::period;
}
u = p * value;
d = constrain(u + TriacDimmer::detail::pulse_length, TriacDimmer::detail::min_trigger, p);
ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
TriacDimmer::detail::ch_B_up = u;
TriacDimmer::detail::ch_B_dn = d;
}
}
float TriacDimmer::detail::getChannelA(){
uint16_t p, u;
ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
p = TriacDimmer::detail::period;
u = TriacDimmer::detail::ch_A_up;
}
return (float)p / u;
}
float TriacDimmer::detail::getChannelB(){
uint16_t p, u;
ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
p = TriacDimmer::detail::period;
u = TriacDimmer::detail::ch_B_up;
}
return (float)p / u;
}
void TriacDimmer::detail::disableChannelA(){
TriacDimmer::detail::ch_A_en = false;
TCCR1A &=~ _BV(COM1A0) | _BV(COM1A1);
}
void TriacDimmer::detail::disableChannelB(){
TriacDimmer::detail::ch_B_en = false;
TCCR1A &=~ _BV(COM1B0) | _BV(COM1B1);
}
ISR(TIMER1_CAPT_vect){
TIMSK1 &=~ (_BV(OCIE1A) | _BV(OCIE1B)); //clear interrupts, in case they haven't run yet
TCCR1A &=~ (_BV(COM1A0) | _BV(COM1B0));
TCCR1C = _BV(FOC1A) | _BV(FOC1B); //ensure outputs are properly cleared
OCR1A = ICR1 + TriacDimmer::detail::ch_A_up;
OCR1B = ICR1 + TriacDimmer::detail::ch_B_up;
ch_A_dn_buf = TriacDimmer::detail::ch_A_dn;
ch_B_dn_buf = TriacDimmer::detail::ch_B_dn;
TCCR1A |=
( TriacDimmer::detail::ch_A_en ? _BV(COM1A0) | _BV(COM1A1) : 0 ) |
( TriacDimmer::detail::ch_B_en ? _BV(COM1B0) | _BV(COM1B1) : 0 ); //set OC1x on compare match, only if enabled
TIFR1 = _BV(OCF1A) | _BV(OCF1B); //clear compare match flags
TIMSK1 |= _BV(OCIE1A) | _BV(OCIE1B); //enable input capture and compare match interrupts
TriacDimmer::detail::period = ICR1 - last_icr;
last_icr = ICR1;
if((signed)(TCNT1 - OCR1A) >= 0){
TCCR1C = _BV(FOC1A); //interrupt ran late, trigger match manually
}
if((signed)(TCNT1 - OCR1B) >= 0){
TCCR1C = _BV(FOC1B); //interrupt ran late, trigger match manually
}
}
ISR(TIMER1_COMPA_vect){
TIMSK1 &=~ _BV(OCIE1A); //disable match interrupt
TCCR1A &=~ _BV(COM1A0); //clear OC1x on compare match
OCR1A = last_icr + ch_A_dn_buf;
if((signed)(TCNT1 - OCR1A) >= 0){
TCCR1C = _BV(FOC1A); //interrupt ran late, trigger match manually
}
}
ISR(TIMER1_COMPB_vect){
TIMSK1 &=~ _BV(OCIE1B); //disable match interrupt
TCCR1A &=~ _BV(COM1B0); //clear OC1x on compare match
OCR1B = last_icr + ch_B_dn_buf;
if((signed)(TCNT1 - OCR1B) >= 0){
TCCR1C = _BV(FOC1B); //interrupt ran late, trigger match manually
}
}

View File

@@ -0,0 +1,191 @@
/**
* @file TriacDimmer.h
* @brief Contains header information for the TriacDimmer library.
* @author Anson Mansfield
* @date 2017-02-23
*/
#ifndef TriacDimmer_h
#define TriacDimmer_h
#include <Arduino.h>
/**
* @brief Contains all the library functions.
* This namespace contains the library's public API suitable for general use.
* Implementation details and more technical API functions are in TriacDimmer::detail.
*/
namespace TriacDimmer {
/**
* @brief Initializes the library.
* @param pulse_length How long the trigger pulses should be, in half-microseconds.
* @param min_trigger Minimum offset from beginning of phase to end of trigger pulse to ensure triac latches.
* @param on_thresh Brightness threshold where the light will be turned on completely. >1 means disabled.
* @param off_thresh Brightness threshold where the light will be turned off completely. <0 means disabled.
* This method initializes the library, setting up the timer and enabling the corresponding interrupts.
*/
void begin(uint16_t pulse_length = 20, uint16_t min_trigger = 2000, float on_thresh = 2.0, float off_thresh = 0.01);
/**
* @brief Stops the library
* This method stops the library, disabling the interrupts and resetting the timer configuration.
*/
void end();
/**
* @brief Sets the current brightness.
* @param pin The pin controlling the desired channel. Only pins 9 and 10 are supported.
* @param value The desired brightness, from 0.0 to 1.0.
* This method enables library control of the given output pin and sets the brightness.
*/
void setBrightness(uint8_t pin, float value);
/**
* @brief Disables and detaches the pin from the library.
* @param pin The pin to relenquish control of.
* This method disables control of the given pin and stops the library from controlling it.
* Note that both pins start disabled; in order to enable them you can call `setBrightness`.
*/
void disable(uint8_t pin);
/**
* @brief Gets the currently-set brightness.
* @param pin The pin controlling the desired channel. Only pins 9 and 10 are supported.
* This method retrieves the brightness for the channel controlled by the indicated pin.
*/
float getCurrentBrightness(uint8_t pin);
/**
* @brief Contains lower-level API functions.
* This namespace contains lower level API functions that can be used to more directly control the
* pulse waveform.
*/
namespace detail {
/**
* @brief Sets channel A phase angle.
* @param value The phase angle, 0.0 fires immediately, 1.0 fires one period later.
* This method directly sets the phase angle used to control brightness on channel A (pin 9).
* Note that this method does not enable the pin if it is disabled.
*/
void setChannelA(float value);
/**
* @brief Sets channel B phase angle.
* @param value The phase angle, 0.0 fires immediately, 1.0 fires one period later.
* This method directly sets the phase angle used to control brightness on channel B (pin 10).
* Note that this method does not enable the pin if it is disabled.
*/
void setChannelB(float value);
/**
* @brief Gets channel A phase angle.
* This method directly retrieves the phase angle used to control brightness on channel A (pin 9).
*/
float getChannelA();
/**
* @brief Gets channel B phase angle.
* This method directly retrieves the phase angle used to control brightness on channel B (pin 10).
*/
float getChannelB();
/**
* @brief Disables channel A.
* This method disables timer control of channel A (pin 9). Set `ch_A_en` to re-enable.
*/
void disableChannelA();
/**
* @brief Disables channel B.
* This method disables timer control of channel B (pin 10). Set `ch_A_en` to re-enable.
*/
void disableChannelB();
/**
* @brief Stores the configured pulse length.
*/
extern uint16_t pulse_length;
/**
* @brief Stores the configured minimum trigger time.
*/
extern uint16_t min_trigger;
/**
* @brief Stores the configured minimum trigger time.
*/
extern float on_thresh;
/**
* @brief Stores the configured minimum trigger time.
*/
extern float off_thresh;
/**
* @brief Stores whether channel A is enabled.
*/
extern volatile bool ch_A_en;
/**
* @brief Stores the channel A positive edge delay
*/
extern volatile uint16_t ch_A_up;
/**
* @brief Stores the channel A negative edge delay
*/
extern volatile uint16_t ch_A_dn;
/**
* @brief Stores whether channel B is enabled.
*/
extern volatile bool ch_B_en;
/**
* @brief Stores the channel B positive edge delay
*/
extern volatile uint16_t ch_B_up;
/**
* @brief Stores the channel B negative edge delay
*/
extern volatile uint16_t ch_B_dn;
/**
* @brief Stores the computed pulse period.
*/
extern volatile uint16_t period;
}
namespace util {
}
};
/* @breif This interrupt sets the output pulses to start at the appropriate time.
*
* This interrupt sets the output pulses to begin at the appropriate time, sets up the
* interrupts that will configure the pulse end, and computes the time since the last pulse.
*/
ISR(TIMER1_CAPT_vect);
/* @breif This interrupt sets the output A pulse to end at the appropriate time.
*
* This interrupt sets the output A pulse to end at the appropriate time, and manually triggers the
* end in case the interrupt ran late.
*/
ISR(TIMER1_COMPA_vect);
/* @breif This interrupt sets the output B pulse to end at the appropriate time.
*
* This interrupt sets the output B pulse to end at the appropriate time, and manually triggers the
* end in case the interrupt ran late.
*/
ISR(TIMER1_COMPB_vect);
#endif