Bike Light

From OmegaV-wiki
Jump to: navigation, search
Bike Light
The Bike Light is a simple circuit based on the AVR ATtiny 85, a chocksensor, and a photodiode. The chocksensor triggers if the bike is moving and the photodiode is used to check whether it is light or dark outside. The AVR gathers the data and turns the on LEDs only if the bike is both moving and it is dark.


Picture of the circuit with labels
The schematic


Developers


Source code for ATtiny 85

<source lang=c> /* Sykellys v.1.0 Av Egil Fykse 13.10.2009

  • /
  1. include <util/delay.h>
  2. include <avr/io.h>
  3. include <avr/interrupt.h>
  4. include <util/delay.h>
  5. include <stdio.h>
  6. include <inttypes.h>
  1. define LED1 PB4 //Define pins
  2. define LED2 PB0
  3. define SHOCK PB1
  4. define PHOTO_OUT PB3
  5. define PHOTO_IN PB2
  1. define DARK_DELAY 100
  2. define LIGHT_LEVEL 400
  3. define MEASURE_INTERVAL 50


volatile unsigned int darkCount = DARK_DELAY; volatile unsigned int lightLevel; volatile unsigned char sleeping = 0; volatile unsigned int measureCount = 100; volatile unsigned char blink = 1;

void myInit(){ sei(); //Turn on interrupt

//Timer0 setup: TCCR0B |= (1<<CS02)|(1<<CS00); //prescaling TIMSK |= (1<<TOIE0); //Timer/Counter0 Overflow Interrupt Enable


TCCR1 |= (1<<CS13)|(0<<CS12)|(1<<CS11)|(1<<CS10); //prescaling TIMSK |= (1<<TOIE1); //Timer/Counter1 Overflow Interrupt Enable


DDRB |= (1<<LED1)|(1<<LED2)|(1<<PHOTO_OUT); //Output


GIMSK |= (1<<PCIE);

PCMSK |= (1<<PCINT1);


PORTB |= (1<<SHOCK); PORTB |= (1<<PHOTO_OUT);


//ADC ADMUX = 0b1;


ADCSRA |= (1<<ADPS2)|(1<<ADPS1)|(1<<ADPS0); //Prescalar div factor =128

MCUCR |= (1<<SE)|(1<<SM1); }

uint16_t ReadADC() {

//PRR ^= (1<<PRADC); //Start Single conversion ADCSRA = (1<<ADEN)|(1<<ADSC);

//Wait for conversion to complete while(!(ADCSRA & (1<<ADIF)));

//Clear ADIF by writing one to it //Note you may be wondering why we have write one to clear it //This is standard way of clearing bits in io as said in datasheets. //The code writes '1' but it result in setting bit to '0' !!! uint16_t result = ADC;

ADCSRA|=(1<<ADIF);

return(result); }


int main(void) {

myInit();

while (1){

if (darkCount == 0) {

blink = 0;


PORTB &= ~(1<<PHOTO_OUT); sleeping = 1; asm("SLEEP"); }

if (blink){ PORTB |= (1<<LED1)|(1<<LED2); _delay_ms(500); PORTB &= ~((1<<LED1)|(1<<LED2)); _delay_ms(500); }

} return 0; }


ISR(TIMER0_OVF_vect) { if (darkCount > 0) { darkCount--; } }


ISR(TIMER1_OVF_vect) { if (measureCount < MEASURE_INTERVAL) { measureCount++; } else { lightLevel = ReadADC(); measureCount = 0;

} }


ISR(PCINT0_vect) { if (sleeping) { PORTB |= (1<<PHOTO_OUT); sleeping = 0; lightLevel = ReadADC(); }

darkCount = DARK_DELAY; if (lightLevel < LIGHT_LEVEL) { blink = 1;

} }



</source>