Hackster is hosting Hackster Holidays, Ep. 7: Livestream & Giveaway Drawing. Watch previous episodes or stream live on Friday!Stream Hackster Holidays, Ep. 7 on Friday!
Amir Kazemi
Published © GPL3+

ATtiny13-Based, Key-Controlled Simple Dimmer

A tiny dimmer with corrected output for resistive loads. Controlled with 3 keys and showing current value on 8 tiny colored LEDs.

BeginnerFull instructions provided5 hours1,738
ATtiny13-Based, Key-Controlled Simple Dimmer

Things used in this project

Hardware components

Microchip Technology microchip - ATtiny13
×1
74hc164
×1
Triac
×1

Software apps and online services

Microchip Studio
Microchip Studio

Story

Read more

Schematics

schematic

Code

Main.c

C/C++
the main code
#define KEY_DN		0
#define KEY_UP		1
#define KEY_SET		2
#define KEY_NO		3

#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
#include <avr/eeprom.h>

#include "aux_source.h"
#include "shiftreg.h"
uint8_t	dim_data;
bool deviceOn = true;
const uint16_t Dimmers[8] = { 0, 253, 369, 468, 531, 631, 850, 1000 };

int main()
{
	init_IO();
	dim_data = eeprom_read_byte(0);
	if (dim_data > 7)	dim_data = 7;
	tsr_shiftOut((1 << (dim_data + 1)) - 1);
	_delay_ms(250);
	while(1)
	{
		uint8_t  key = ReadKeys();
		if (deviceOn)
		{
			if (key != KEY_NO && key != KEY_SET)
			{
				if (key == KEY_DN)
				{
					if (dim_data > 0)	dim_data--;
				}
				else if (key == KEY_UP)
				{
					if (dim_data < 7)	dim_data++;
				}
				tsr_shiftOut((1 << (dim_data + 1)) - 1);
				eeprom_write_byte(0, dim_data);
				_delay_ms(100);
			}
		}
		if (key == KEY_SET)
		{
			deviceOn = !deviceOn;
			if (deviceOn)	tsr_shiftOut((1 << (dim_data + 1)) - 1);
			else			tsr_shiftOut(0);
			_delay_ms(800);
		}
	}
}



void sup_delay(uint16_t del)
{
	while (del--)
	{
		_delay_us(10);
	}
}

ISR(INT0_vect)
{
	if (deviceOn)
	{
		if (dim_data != 7)
		{
			//wait according to the Dimming table
			sup_delay(Dimmers[dim_data]);
			//fire triac
			PORTB |= (1 << PORTB0);
			_delay_us(30);
			PORTB &= ~(1 << PORTB0);
		}
		else
		{
			PORTB |= (1 << PORTB0);
			_delay_us(30);
			PORTB &= ~(1 << PORTB0);
		}
	}
}

peripheral init

C/C++
peripheral inits
#include "aux_source.h"

void init_IO()
{
	//B0 for triac fire, B3,B4 for shift register control
	DDRB	= (1 << DDB0) | (1 << DDB3) | (1 << DDB4);
	
	//pull-up the ADC
	PORTB	|= (1 << PORTB2);
	ADMUX	= (1 << ADLAR) | 1;
	DIDR0	= (1 << ADC1D);
	ADCSRA	= (1 << ADEN) | (1 << ADSC) | 5;
	while (!(ADCSRA & (1 << ADIF))) ;
	ADCSRA	|= (1 << ADIF);
		
	//enable external interrupts for both edges
	MCUCR	= 1;
	GIMSK	= (1 << INT0);
	sei();	
}


uint8_t ReadKeys()
{	
	ADCSRA	|= (1 << ADSC);
	while (!(ADCSRA & (1 << ADIF))) ;
	ADCSRA	|= (1 << ADIF);
	return ((ADCH * 3 + 80) / 256) ;
}

shift register library

C/C++
#include "shiftReg.h"


uint8_t tsr_buff[DAT_SZ_BYTE] = { 0 };


void tsr_initIO(void)
{
	CLK_DAT_LATCH_OUT_INIT;
	CLK_OUT_LO;
	DAT_OUT_LO;
	LATCH_OUT_LO;
}

void tsr_shiftBuffer(void)
{
	uint8_t j = 0;
	
	while (j < DAT_SZ_BYTE)
	{
		tsr_shiftOut(tsr_buff[j]);
		j++;
	}
	
}

void tsr_shiftOut(uint8_t tsr_var)
{
	uint8_t i = 0b10000000;
	LATCH_OUT_LO;
	while (i != 0)
	{
		if (tsr_var & i)	DAT_OUT_HI;
		else			DAT_OUT_LO;
		CLK_DELAY;
		CLK_OUT_HI;
		CLK_DELAY;
		CLK_OUT_LO;
		CLK_DELAY;
		i	= i >> 1;
	}
}

void tsr_latchOut(void)
{
	LATCH_OUT_HI;
}

void sr_setBit(uint32_t srBuffBit, bool srBuffVal)
{
	uint8_t q = srBuffBit/8;
	uint8_t r = srBuffBit%8;
	if(srBuffVal)	tsr_buff[q] |= (1<<r);
	else					tsr_buff[q] &=~(1<<r);
}

shift register header

C/C++
#ifndef __SHIFTREG_H__
#define __SHIFTREG_H__

#include <avr/io.h>
#include <util/delay.h>

#define CLK_DAT_LATCH_OUT_INIT		DDRB	|= (1 << DDB3) | (1 << DDB4)

#define CLK_OUT_HI	PORTB	|= (1<<PORTB3)
#define CLK_OUT_LO	PORTB	&=~(1<<PORTB3)
#define CLK_OUT_TOG PINB	|= (1<<PINB3)
#define DAT_OUT_HI	PORTB	|= (1<<PORTB4)
#define DAT_OUT_LO	PORTB	&=~(1<<PORTB4)
#define LATCH_OUT_HI
#define LATCH_OUT_LO

#define DAT_SZ_BYTE	1
#define CLK_DELAY	


#define DAT_SZ_BYTE	1


extern uint8_t tsr_buff[DAT_SZ_BYTE];


void tsr_initIO(void);
void tsr_shiftOut(uint8_t tsr_var);
void tsr_latchOut(void);
void tsr_setBit(uint32_t srBuffBit, bool srBuffVal);
void tsr_shiftBuffer(void);


#endif

peripheral init header

C/C++
#pragma once

#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
#include "shiftreg.h"

void init_IO();
uint8_t ReadKeys();

Credits

Amir Kazemi
4 projects • 3 followers
Material science engineering MSc nano material researcher

Comments