ATMega8 auto-calibratable photosensor

Embedded Systems Topics
Post Reply
User avatar
SemiconductorCat
Major
Major
Posts: 455
Joined: Mon Aug 22, 2011 8:42 pm
Location: currently in hyperspace

ATMega8 auto-calibratable photosensor

Post by SemiconductorCat » Sun Feb 09, 2014 8:05 pm

Hi I'm using ATMega8 on this project.

Code: Select all

/* 
    TO COMPILE 
     avr-gcc -g -Os -mmcu=atmega8 -c serial.c
     avr-gcc -g -mmcu=atmega8 -o serial.elf serial.o
     avr-objcopy -j .text -j .data -O ihex serial.elf serial.hex

   TO FLASH:
      avrdude -p m8 -P usb -c usbasp -Uflash:w:serial.hex:i 
      [@Mr. Thisara: please ignore the warning messages , refer drawing 1 for schematic.]
      Turns on the impression solonoid when paper cut the photo-resistor.
      Replace the old analog preset and auto calibrate .

     (c) Udara Type Setting Panadura.

*/
#define F_CPU 16000000UL 

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


void bit_set_portb(int bit)
{
  int mask = (1<<bit);
  PORTB = PORTB | mask;

}



int is_bit_set_portb(int bit)
{
  
  int mask = (1<<bit);
  int val = PINB & mask ;
  if( val ==0)
  {
    return 0; 
  }
  
  return 1;
}



void adc_init(void){
 
 ADCSRA |= ((1<<ADPS2)|(1<<ADPS1)|(1<<ADPS0));    //16Mhz/128 = 125Khz the ADC reference clock
 ADMUX |= (1<<REFS0);                //Voltage reference from Avcc (5v)
 ADCSRA |= (1<<ADEN);                //Turn on ADC
 ADCSRA |= (1<<ADSC);                //Do an initial conversion because this one is the slowest and to ensure that everything is up and running
}

uint16_t read_adc(uint8_t channel){
 ADMUX &= 0xF0;                    //Clear the older channel that was read
 ADMUX |= channel;                //Defines the new ADC channel to be read
 ADCSRA |= (1<<ADSC);                //Starts a new conversion
 while(ADCSRA & (1<<ADSC));            //Wait until the conversion is done
 return ADCW;                    //Returns the ADC value of the chosen channel
}



void main()
{
   adc_init();

  /* set port B I/O directions */
  /* PB1 - calibration progress LED */
  /* PB2 - calibration finished LED */
  /* PB3 - going to solonoid */
  /* PB4 - input , calibration switch */
  /* ADC0 - going to LDR input , LDR is pulled up with a 10K */
  DDRB = 0b00000111;
  bit_clear_portb(1);
  bit_set_portb(0);
  

  int idle_value ;
  int delta ; 
  _delay_ms(500);
  idle_value = read_adc(0);
  _delay_ms(500);  
  bit_set_portb(1);
  bit_clear_portb(0);
  
      static int analog_reading ;
  while(1){
    if(is_bit_set_portb(3)) /* PB3 is the calibration push button */
    {
      bit_clear_portb(1);
      bit_set_portb(0);
      _delay_ms(500);
      idle_value = read_adc(0);
      _delay_ms(500);  
      bit_set_portb(1);
      bit_clear_portb(0);
      continue;
    }
    

    /* read the analog again */
    analog_reading = read_adc(0);

    delta = analog_reading ^ idle_value ;
    if( delta >70){ /* magic value 70 means ,if we found more than 70 delta it should trigger */
      bit_set_portb(2); // PB2 is going to solonoid //
    }else{
      bit_clear_portb(2); 
    }
    _delay_ms(50); // * avoid some race conditions and bouncing effects */
  }
}

My question are bellow.

* ATMega8 costs around 160/-Rs on the local market. What I need is a cheaper device , I know I could do this with pure analog design. But I also heard that there are very cheap micro-controllers there too. I'm planing on ATiny series.
I just need 3 GPIO and one analog input for this. I also need to know how much ?

* My second question is to implement the soft start solenoid algorithm. Where I could have two thread , one thread would read the analog value on that LDR connected pin and then change the state variable on thread 2. Then thread 2 will generate soft PWM on the solonoid. Is that a good design? So that I need to keep a sine table inside the micro-controller?
Any other better way to do this?

* As you could see I have hardcoded the delta value to trigger and the debouncing time too.
I've taken these values by experimenting. Is any dynamic method to get these values like auto calibration?
Post Reply

Return to “Embedded Systems”