BPLightContraption
 All Classes Namespaces Files Functions Variables Macros Pages
Classes | Macros | Functions | Variables
triaclight.c File Reference

Main functions for the microcontroller. More...

#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#include "serial.h"
#include "commands.h"
#include "bits.h"
Include dependency graph for triaclight.c:

Go to the source code of this file.

Classes

struct  PowerUnit
 A struct representing a controllable power output. More...
 
struct  DimmerClock
 A struct for a clock used for dimming a PowerUnit. More...
 

Macros

#define NULL   0x0
 
#define BUFSIZE   64
 The size of the command received buffer (in bytes) More...
 
#define PULSE_WIDTH   3 /* microseconds */
 Pulse width required to turn on the triac, in microseconds. More...
 
#define ONETWENTYHERTZ   16667ul
 The number of clock ticks for half of a 60Hz sine wave. More...
 

Functions

uint8_t ReadNextBuff (void)
 Read the next entry in the input buffer. More...
 
void WriteNextBuff (const uint8_t c)
 Write the next entry in the input buffer. More...
 
uint8_t StartDimming (volatile struct PowerUnit *pu, uint8_t level)
 Start dimming a power unit at the given level. More...
 
void StopDimming (volatile struct PowerUnit *pu)
 Stops dimming on a given PowerUnit. More...
 
void TurnOn (volatile struct PowerUnit *pu)
 Completely turns on a PowerUnit. More...
 
void TurnOff (volatile struct PowerUnit *pu)
 Completely turns off a PowerUnit. More...
 
uint8_t Level (volatile struct PowerUnit *pu, uint8_t level)
 Change the dimming level of a PowerUnit. More...
 
uint8_t ProcessCommand (uint8_t command)
 Process a command stored in the buffer. More...
 
void NewDimmerClock (volatile struct DimmerClock *dim, volatile uint8_t *interruptreg, uint8_t interruptbit, volatile uint16_t *comparereg)
 Creates a new dimmer clock object. More...
 
void NewPowerUnit (volatile struct PowerUnit *pu, uint8_t id, volatile uint8_t *portreg, uint8_t portbit)
 Creates a new PowerUnit object. More...
 
int main (void)
 Main loop of the microcontroller. More...
 
 ISR (TIMER4_CAPT_vect)
 Interrupt routine for zero-cross. More...
 
 ISR (TIMER1_COMPA_vect)
 Timer interrupt for phase-shifting. More...
 
 ISR (TIMER1_COMPB_vect)
 Timer interrupt for phase-shifting. More...
 
 ISR (TIMER1_COMPC_vect)
 Timer interrupt for phase-shifting. More...
 
 ISR (TIMER3_COMPA_vect)
 Timer interrupt for phase-shifting. More...
 
 ISR (TIMER3_COMPB_vect)
 Timer interrupt for phase-shifting. More...
 
 ISR (TIMER3_COMPC_vect)
 Timer interrupt for phase-shifting. More...
 
 ISR (USART0_RX_vect)
 

Variables

const uint16_t levelarray [101]
 Integers representing the fraction of 2^16 for the different levels. More...
 
struct PowerUnit punits [PU_COUNT]
 
struct DimmerClock dimclocks [DIMMER_COUNT]
 
volatile uint16_t zerocrossstamp [2]
 The times from the zero-crossing timer represing the falling edge [0] and the rising edge [1]. More...
 
volatile uint8_t serbuffer [BUFSIZE]
 A buffer for receiving input from the serial port. More...
 
volatile uint8_t curRead
 Index to be read next in the input buffer (serbuffer) More...
 
volatile uint8_t curWrite
 Index to be written next in the input buffer (serbuffer) More...
 

Detailed Description

Main functions for the microcontroller.

Author
Benjamin Pritchard (ben@b.nosp@m.enny.nosp@m.p.org)

Definition in file triaclight.c.

Macro Definition Documentation

#define BUFSIZE   64

The size of the command received buffer (in bytes)

Note that the buffer is index using a uint8_t. Therefore, BUFSIZE must be less than or equal to 256

Definition at line 24 of file triaclight.c.

#define NULL   0x0

Definition at line 17 of file triaclight.c.

#define ONETWENTYHERTZ   16667ul

The number of clock ticks for half of a 60Hz sine wave.

Definition at line 35 of file triaclight.c.

#define PULSE_WIDTH   3 /* microseconds */

Pulse width required to turn on the triac, in microseconds.

Should be as short as possible

Definition at line 31 of file triaclight.c.

Function Documentation

ISR ( TIMER4_CAPT_vect  )

Interrupt routine for zero-cross.

This gets run on a rising or falling edge (dependong on register TCCR4B, bit ICES4). It records the timestamp in zerocrossstamp.

After detecting a rising edge, it adjusts the counters for the dimmer clocks to what would be expected so that they remain in sync.

Definition at line 617 of file triaclight.c.

ISR ( TIMER1_COMPA_vect  )

Timer interrupt for phase-shifting.

Gets run when the pulse must be sent to the triac to turn on the circuit. The value at which this gets called is set with Level()

Definition at line 662 of file triaclight.c.

ISR ( TIMER1_COMPB_vect  )

Timer interrupt for phase-shifting.

Gets run when the pulse must be sent to the triac to turn on the circuit. The value at which this gets called is set with Level()

Definition at line 670 of file triaclight.c.

ISR ( TIMER1_COMPC_vect  )

Timer interrupt for phase-shifting.

Gets run when the pulse must be sent to the triac to turn on the circuit. The value at which this gets called is set with Level()

Definition at line 678 of file triaclight.c.

ISR ( TIMER3_COMPA_vect  )

Timer interrupt for phase-shifting.

Gets run when the pulse must be sent to the triac to turn on the circuit. The value at which this gets called is set with Level()

Definition at line 686 of file triaclight.c.

ISR ( TIMER3_COMPB_vect  )

Timer interrupt for phase-shifting.

Gets run when the pulse must be sent to the triac to turn on the circuit. The value at which this gets called is set with Level()

Definition at line 694 of file triaclight.c.

ISR ( TIMER3_COMPC_vect  )

Timer interrupt for phase-shifting.

Gets run when the pulse must be sent to the triac to turn on the circuit. The value at which this gets called is set with Level()

Definition at line 702 of file triaclight.c.

ISR ( USART0_RX_vect  )

Definition at line 714 of file triaclight.c.

Here is the call graph for this function:

uint8_t Level ( volatile struct PowerUnit pu,
uint8_t  level 
)

Change the dimming level of a PowerUnit.

Bug:
Sometimes the light will flash momentarily. This is possibly due to some timing issues when changing the level while the timer is still running (ie there is a timer interrupt at an inopportune time, or the compare value changes at a bad time)

Definition at line 298 of file triaclight.c.

Here is the call graph for this function:

Here is the caller graph for this function:

int main ( void  )

Main loop of the microcontroller.

This loop sets up the power units and dimmer clocks, initializes the serial port, as well as sets up the input pin and interrupt for the zero-crossing timer. It also initializes the command buffer and sends an identification string to the PC program.

After that, it enters a loop, waiting for commands to be written to the command buffer (serbuffer) and executes ProcessCommand() if necessary.

Definition at line 486 of file triaclight.c.

Here is the call graph for this function:

void NewDimmerClock ( volatile struct DimmerClock dim,
volatile uint8_t *  interruptreg,
uint8_t  interruptbit,
volatile uint16_t *  comparereg 
)

Creates a new dimmer clock object.

For a description of the parameters, see the details for the DimmerClock struct

Definition at line 443 of file triaclight.c.

Here is the caller graph for this function:

void NewPowerUnit ( volatile struct PowerUnit pu,
uint8_t  id,
volatile uint8_t *  portreg,
uint8_t  portbit 
)

Creates a new PowerUnit object.

For a description of the parameters, see the details for the PoerUnit struct

Definition at line 460 of file triaclight.c.

Here is the caller graph for this function:

uint8_t ProcessCommand ( uint8_t  command)

Process a command stored in the buffer.

The command is given by the only parameter, and any further information is obtained directly from the buffer

This function also returns the appropriate response through the serial port

Definition at line 343 of file triaclight.c.

Here is the call graph for this function:

Here is the caller graph for this function:

uint8_t ReadNextBuff ( void  )

Read the next entry in the input buffer.

This takes care of wrapping around the end of the buffer

Definition at line 157 of file triaclight.c.

Here is the caller graph for this function:

uint8_t StartDimming ( volatile struct PowerUnit pu,
uint8_t  level 
)

Start dimming a power unit at the given level.

Finds the next available dimmer. If no dimmer is available, it returns RES_NODIMMER. Otherwise, returns RES_SUCCESS.

Note
pu->dimmer should be checked for NULL prior to calling this

(dim->comparereg) = (((uint32_t)pgm_read_word(&levelarray[level]) * (uint32_t)ONETWENTYHERTZ) >> 16);

Definition at line 190 of file triaclight.c.

Here is the caller graph for this function:

void StopDimming ( volatile struct PowerUnit pu)

Stops dimming on a given PowerUnit.

Note
This does not turn off the pin - it may be left on!

Definition at line 232 of file triaclight.c.

Here is the caller graph for this function:

void TurnOff ( volatile struct PowerUnit pu)

Completely turns off a PowerUnit.

This will force the output on the IO pin to be set continuously to 0

(pu->dimmer->comparereg) = 65535;

Definition at line 271 of file triaclight.c.

Here is the call graph for this function:

Here is the caller graph for this function:

void TurnOn ( volatile struct PowerUnit pu)

Completely turns on a PowerUnit.

This will force the output on the IO pin to be set continuously to 1

(pu->dimmer->comparereg) = 1000;

Definition at line 248 of file triaclight.c.

Here is the call graph for this function:

Here is the caller graph for this function:

void WriteNextBuff ( const uint8_t  c)

Write the next entry in the input buffer.

This takes care of wrapping around the end of the buffer

Definition at line 175 of file triaclight.c.

Here is the caller graph for this function:

Variable Documentation

volatile uint8_t curRead

Index to be read next in the input buffer (serbuffer)

Definition at line 147 of file triaclight.c.

volatile uint8_t curWrite

Index to be written next in the input buffer (serbuffer)

Definition at line 150 of file triaclight.c.

struct DimmerClock dimclocks[DIMMER_COUNT]

Definition at line 133 of file triaclight.c.

const uint16_t levelarray[101]
Initial value:
=
{
65535,57934,55907,54462,53297,52300,51419,50621,49889,49208,
48568,47964,47390,46841,46314,45807,45317,44842,44381,43933,
43495,43068,42650,42240,41838,41443,41055,40672,40295,39923,
39556,39193,38834,38479,38127,37778,37432,37089,36748,36409,
36072,35737,35403,35071,34740,34410,34080,33752,33424,33096,
32768,32440,32112,31784,31456,31126,30796,30465,30133,29799,
29464,29127,28788,28447,28104,27758,27409,27057,26702,26343,
25980,25613,25241,24864,24481,24093,23698,23296,22886,22468,
22041,21603,21155,20694,20219,19729,19222,18695,18146,17572,
16968,16328,15647,14915,14117,13236,12239,11074,9629,7602,
00000
}

Integers representing the fraction of 2^16 for the different levels.

The level (as a %) is given as the index. This is normalized so that the precentage represent the percentage output power, rather than the percent phase-shift for the sine wave.

For a given percentage, the level is stored as the fraction of 2^16, rather than the fraction of 100. This gets multiplied by ONETWENTYHERTZ and then divided by 2^16, allowing only bit shift operations and not floating point math.

Note
I don't have much in ram at the moment. this may be moved to PROGMEM eventually
Warning
I don't remember exactly how I did this...

Definition at line 56 of file triaclight.c.

struct PowerUnit punits[PU_COUNT]

Definition at line 130 of file triaclight.c.

volatile uint8_t serbuffer[BUFSIZE]

A buffer for receiving input from the serial port.

Definition at line 144 of file triaclight.c.

volatile uint16_t zerocrossstamp[2]

The times from the zero-crossing timer represing the falling edge [0] and the rising edge [1].

Definition at line 141 of file triaclight.c.