Skip to content

Commit

Permalink
Merge pull request circuitar#7 from circuitar/count_wave_mode
Browse files Browse the repository at this point in the history
Count mode
  • Loading branch information
lfchavier committed Sep 22, 2015
2 parents f90a4f1 + 8d9b396 commit 70c9c37
Show file tree
Hide file tree
Showing 2 changed files with 91 additions and 62 deletions.
119 changes: 71 additions & 48 deletions src/Dimmer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,17 @@
#include "Dimmer.h"

// Time table to set triacs
static uint8_t triacTime[] ={
160, 146, 142, 138, 134, 132, 130, 128, 126, 124,
122, 121, 120, 118, 117, 116, 114, 113, 112, 111,
110, 109, 108, 107, 106, 105, 104, 103, 102, 101,
100, 99, 98, 97, 96, 95, 94, 93, 92, 91,
90, 89, 88, 87, 86, 85, 84, 83, 82, 81,
80, 79, 78, 77, 76, 75, 74, 73, 72, 71,
70, 69, 68, 67, 66, 65, 64, 63, 62, 61,
60, 59, 58, 57, 56, 55, 54, 53, 52, 51,
50, 48, 47, 46, 45, 44, 42, 41, 40, 38,
36, 34, 32, 30, 28, 26, 24, 22, 18, 12, 6
static int triacTime[] ={
147, 142, 139, 136, 133, 131, 129, 127, 125, 124,
122, 121, 119, 118, 116, 115, 114, 113, 112, 111,
110, 108, 107, 106, 105, 104, 103, 102, 102, 101,
100, 99, 98, 97, 96, 95, 94, 93, 93, 92,
91, 90, 89, 88, 88, 87, 86, 85, 84, 83,
83, 82, 81, 80, 79, 78, 77, 77, 76, 75,
74, 73, 72, 71, 71, 70, 69, 68, 67, 66,
65, 64, 63, 62, 61, 60, 59, 58, 57, 56,
55, 54, 53, 51, 50, 49, 48, 46, 45, 43,
42, 40, 38, 36, 34, 31, 28, 24, 19, 0
};

static Dimmer* dimmmers[MAX_TRIAC]; // Pointers to all registered dimmer objects
Expand All @@ -36,7 +36,7 @@ void callZeroCross(){
}

void callTriac(){
// Process ISR for all configured dimmer lights at about 20KHz
// Process ISR for all configured dimmer lights at about 20KHz
for (uint8_t i = 0; i < dimmerCount; i++) {
dimmmers[i]->triac();
}
Expand All @@ -48,35 +48,43 @@ ISR(TIMER2_COMPA_vect) {
}

// Class Constructor
Dimmer::Dimmer(uint8_t triacPin, uint8_t mode, uint8_t resolution, uint8_t value, bool state){
if (mode == RAMP_MODE && resolution == 1)
resolution = 200; // starting resolution for ramp mode

this->triacPin = triacPin;
this->operationMode = mode;
this->countResolution = resolution;
this->lampValue = value;
this->lampState = state;
this->msCounter = 0;
this->rampCounter = 0;

// Register dimmer object
dimmmers[dimmerCount++] = this;
Dimmer::Dimmer(uint8_t triacPin, uint8_t mode, uint8_t value, bool state, uint16_t resolution){
if (dimmerCount < MAX_TRIAC){
if (mode == RAMP_MODE){
this->lampValue = value;
this->lampValueRamp = 0;
}
else{
this->lampValueRamp = value;
}

this->triacPin = triacPin;
this->operationMode = mode;
this->lampState = state;
this->countResolution = resolution;
this->msCounter = 0;
this->rampCounter = 0;

// Register dimmer objects
dimmmers[dimmerCount++] = this;
}
}

bool Dimmer::begin(){
pinMode(triacPin, OUTPUT);

if(!started){
halfCycleCounter = 0;
pinMode(zeroCrossPin, INPUT);
attachInterrupt(zeroCrossInt, callZeroCross, RISING);
// Setup Timer2 to fire every 50ms
started = true;
}

if(operationMode != COUNT_MODE){
// Setup Timer2 to fire every 50us
TCCR2A = 0x02; // CTC mode
TCCR2B = 0x02; // prescaler=8
TIMSK2 = 0x02; // Timer2 Compare Match Interrupt Enable
OCR2A = 49; // Compare value
started = true;
OCR2A = 99; // Compare value
}
}

Expand Down Expand Up @@ -105,30 +113,40 @@ uint8_t Dimmer::getValue(){
}
}

void Dimmer::set(uint8_t value, uint8_t state){
void Dimmer::set(uint8_t value){
if (operationMode == RAMP_MODE){
lampValue=value;
}
else{
lampValueRamp=value;
pulses = 0;
pulseCount = 0;
}
}

if (state != -1){
lampState = (bool) state;
}
void Dimmer::set(uint8_t value, bool state){
set(value);
lampState = state;
}

void Dimmer::zeroCross(){
if (operationMode == COUNT_MODE) {
if (halfCycleCounter < lampValueRamp / countResolution && lampState) {
if (pulses >= 0x8000000000000000 && pulseCount > 0){ // Check the MSB bit
pulseCount--;
}

pulses = pulses << 1;

if (lampValueRamp > pulseCount * 1.5625){
digitalWrite(triacPin, HIGH);
//if (pulseCount < 32){ // check upper boundary
pulses++;
pulseCount++;
//}
} else {
digitalWrite(triacPin, LOW);
}

if (++halfCycleCounter >= 100 / countResolution) {
halfCycleCounter = 0;
}
// NORMAL OR RAMP MODE
} else {
// Clear counter
msCounter=0;
Expand All @@ -140,18 +158,23 @@ void Dimmer::zeroCross(){
void Dimmer::triac(){
if (operationMode != COUNT_MODE) {
msCounter++;
rampCounter++;
// With ramp mode
if (operationMode == RAMP_MODE && rampCounter % countResolution == 0 ) {
rampCounter=0;
if(lampValueRamp > lampValue)
lampValueRamp--;
else if(lampValueRamp < lampValue)
lampValueRamp++;

//With ramp mode
if (operationMode == RAMP_MODE){
rampCounter++;
if(rampCounter % countResolution == 0 ) {
rampCounter=0;
if(lampValueRamp > lampValue){
lampValueRamp--;
}
else if(lampValueRamp < lampValue){
lampValueRamp++;
}
}
}

if(lampValueRamp > 0 && lampState){
if(triacTime[ lampValueRamp ] == msCounter){
if(triacTime[lampValueRamp-1] <= msCounter){
digitalWrite(triacPin, HIGH);
}
}
Expand Down
34 changes: 20 additions & 14 deletions src/Dimmer.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
* Copyright (c) 2015 Circuitar
* This software is released under the MIT license. See the attached LICENSE file for details.
*/

#ifndef DIMMER_H
#define DIMMER_H

Expand Down Expand Up @@ -34,7 +35,7 @@
#define COUNT_MODE 2

/**
* Possible light state for the dimmer library.
* Possible light states for the dimmer.
*/
#define OFF 0
#define ON 1
Expand All @@ -55,19 +56,17 @@ class Dimmer
* NORMAL_MODE: Uses timer to apply only a percentage of the AC power to the light.
* RAMP_MODE: Same as in normal mode, but it applies a ramp effect to the light.
* COUNT_MODE: Counts AC waves and applies full waves from time to time. @see resolution
* @param resolution IN COUNT MODE:
* divided prescalar to define how many pulses to count.
* if resolution is 1 the mode counts 100 pulses, if resolution is 2
* the mode counts 50 pulses, and so on.
*
* IN RAMP MODE:
* Controlls the speed of the ramp when changing values.
* @param value initial intensity in percentage of the dimmed light.
* Minimum is 0 and maximum is 100. Default is 50%.
* @param state initial state of the light. Possible states: ON or OFF. Default is OFF.
* @param resolution Applied only in RAMP_MODE
* Controlls the speed of the ramp when changing values.
* If resolution is 200 the lamp goes from 0% to 100% in one second.
* Maximum value: 65535. Default value is 300.
*
* @see begin()
*/
Dimmer(uint8_t triacPin, uint8_t mode = NORMAL_MODE, uint8_t resolution = 1, uint8_t value=50, bool state = OFF);
Dimmer(uint8_t triacPin, uint8_t mode = NORMAL_MODE, uint8_t value=50, bool state = ON, uint16_t resolution = 300);

/**
* Initializes the module.
Expand Down Expand Up @@ -105,23 +104,30 @@ class Dimmer
*/
uint8_t getValue();

/**
* Sets the value of the light.
* @param value the value of the dimm light. Values from 0 to 100.
*/
void set(uint8_t value);

/**
* Sets the value and the state of the light.
* @param value the value of the dimm light. Values from 0 to 100.
* @param state the state of the light. ON or OFF.
*/
void set(uint8_t value, uint8_t state = -1);
void set(uint8_t value, bool state);

private:
uint8_t operationMode;
uint8_t countResolution;
uint8_t halfCycleCounter;
uint16_t countResolution;
uint64_t pulses = 0;
uint8_t pulseCount = 0;
uint8_t triacPin;
uint8_t lampValue;
uint8_t lampValueRamp;
bool lampState;
unsigned int msCounter;
unsigned int rampCounter;
uint8_t msCounter;
uint16_t rampCounter;

void zeroCross();
void triac();
Expand Down

0 comments on commit 70c9c37

Please sign in to comment.