navigationGo.pngQuick Navigation
allprojects32.pngAll projects
hardware32.pngHardware
links32.pngLinks

favoriteStar32.pngTop projects
Alan numitron clock
Clapclap 2313/1386
SNES Pi Webserver
USB Volume/USB toys
Smokey amp
Laser cutter
WordClock
ardReveil v3
SNES Arcade cabinet
Game boy projects
cameleon
Home Presence Detector

github32.pngGitHub
AlanFromJapan

navigationMail.pngContact me

alanfjmail.png
3flags.pngWho's Alan?


Akizukidenshi
Elec-lab
Rand Nerd Tut
EEVblog
SpritesMods
AvrFreaks
Gameboy Dev
FLOZz' blog
Switch-science
Sparkfun
Suzusho
Datasheet Lib
Reddit Elec
Ermicro
Carnet du maker (fr)

attiny13

Last update: Thu Jun 5 22:25:40 2025
pinout13large.png

Memo fact sheet

  • Code : 1024 Bytes / EEPROM : 64 Bytes / RAM : 64 Bytes
  • It has 4 ADC- Analog to Digital Converter !
  • Default speed : internal oscillator 9.6 MHz, alternate is 4.8Mhz. The internal oscillator has always proven to be very imprecise, so adjust it, tweak your timings or use an external crystal.
  • Homepage http://www.atmel.com/devices/attiny13.aspx

Links


Samples

Blink


/* includes */
#include "avr/io.h"
#include "util/delay.h"
 
/*
 main function
*/
int main(void) {
 
    /*factory settings is to divide internal clock 8MHz by 8.
    don't, and just run at 8 MHz (set the clock divider to 1 so no effect) */
    CLKPR = (1 < < CLKPCE);
    CLKPR = 0; /* Divide by 1 */
 
    /* port B pins 0-5 go OUTPUT */
    DDRB = 0xFF;
 
    while (1==1){
        /*all on*/
        PORTB = 0xFF;
 
        /*wait a little*/
        _delay_ms(500);
 
        /*all off*/
        PORTB = 0x00;
 
        /*wait again*/
        _delay_ms(200);
 
    }
}

PWM

See http://avrbasiccode.wikispaces.com/
// includes
#include 
#include 
#include 
 
//
// main function
//
int main(void) {
 
    //factory settings is to divide internal clock 8MHz by 8.
    //don't, and just run at 8 MHz (set the clock divider to 1 so no effect)
    CLKPR = (1<<CLKPCE);
    CLKPR = 0; // Divide by 1 
 
    //port B pins 0-5 go OUTPUT
    DDRB = 0xFF;
 
//PWM : Use this line...
TCCR0A |= ((1 << COM0A1) | (1 << COM0A0) // COM0A1 - COM0A0 (Set OC0A on Compare Match, clear OC0A at TOP)
 | (1 << WGM01) | (1 << WGM00)); // WGM01 - WGM00 (set fast PWM)
 
//...or those lines. No (noticeable) difference.
    /* Set Fast PWM mode. */
    //TCCR0A |= (1<
    /* Clear 0C0A on compare. */
    //TCCR0A |= (1<
 
 
    /* Start timer, no prescaling. */
    TCCR0B |= (1<<CS00);
    //initial PWM value is 0
    OCR0A = 0x00;
 
    while (1==1){
        for (int i=0; i < 255; i %20%20){
            OCR0A = i;
            _delay_ms(5);
        }
 
        for (int i=0; i < 255; i %20%20){
            OCR0A = 255-i;
            _delay_ms(5);
        }
 
    }
}

Soft PWM on 3%20 pins


Pick 3 pins, assign to each a 8bit desired value [0-255], loop and light them for a small quantum of time △ (like 50 us). In my implementation, current turn a byte that keeps on incrementing and overflowing between 0 and 255.
  • Starting at current turn==0 when you light everybody on (turn pins HIGH).
  • When the current turn (a byte that keeps on rolling between 0 and 255) reaches the desired value, turn that pin LOW.
  • At each turn pause a little time (△) for the POV and increment current turn
Therefore a pin that has a duty of 25% = 256 * 0.25 = 64 will be HIGH for 64 * △ = 3,200 us = 3.2 ms and LOW for (256-64) * △ = 192 * △ = 9.6 ms over a total cycle of 12.8 ms (). You have a nice PWM of 78Hz, and with your Attiny running at 8 MHz with the internal oscillator it's piece of cake for it. You can even find a little time every n cycles in between (who said with an interrupt ?) to read the ADC value of the LM35 and convert that to a color. Don't read the LM35 too often, it's useless. Maybe once every few seconds is more than plainly sufficient.


    uint8_t vRGBCurrentRound = 0;
    while(1)
    {
        //todo : put this in an interrupt?
        if (vRGBCurrentRound == 0){
            /*
            //make pins B0-2 high
            PORTB = 
                (1 << PORTB0) 
                | (1 << PORTB1)
                | (1 << PORTB2)
                ;
            */
 
            PORTB = 0x00;
            if (mRGB[0] > 0)
                PORTB |= (1 << PORTB0);
            if (mRGB[1] > 0)
                PORTB |= (1 << PORTB1);
            if (mRGB[2] > 0)
                PORTB |= (1 << PORTB2);        
        }
 
 
        if (vRGBCurrentRound == mRGB[0] && vRGBCurrentRound != 255){
            PORTB &= ~(1 << PORTB0);
        }
 
        if (vRGBCurrentRound == mRGB[1] && vRGBCurrentRound != 255){
            PORTB &= ~(1 << PORTB1);
        }
 
        if (vRGBCurrentRound == mRGB[2] && vRGBCurrentRound != 255){
            PORTB &= ~(1 << PORTB2);
        }
 
        //and the POV
        _delay_us(50);
        vRGBCurrentRound%20%20;
    }
All content on this site is shared under the MIT licence (do what u want, don't sue me, hat tip appreciated)
electrogeek.tokyo ~ Formerly known as Kalshagar.wikispaces.com and electrogeek.cc (AlanFromJapan [2009 - 2025])