Lux metre devresi attiny26-16 ışık ölçümü

Lux metre devresi atmel attiny26-16 mikrodenetleyici üzerine kurulu led display üzerinde lux değerini görüntülüyor ledler 2sk1061 mosfetler ile sürülmüş. İlginç bir uygulama tüm kaynak dosyalar (pcb, şema, kod) paylaşılmış ayrıca devrenin kalibrasyon bilgileride verilmiş
Lux metre devre şeması;
Dosya ve detaylar (ingilizce): Lux Meter
The Lux Meter is usually used to measure illumination. The illumination is how level of luminous flux is falling on a surface area. The luminous flux is visible component that is defined in radiant flux (light power) divided by relative sensitivity of human eyes over the visible spectrum. This means the Lux is well fit to light level from sense of human eyes.
lux.c yazılımı;
/*--------------------------------------------------*/ /* Lux meter control program (C)ChaN, 2005 */ #include <avr/io.h> #include <avr/signal.h> #include <avr/interrupt.h> #include <avr/pgmspace.h> #include <avr/eeprom.h> #include <string.h> #include "xitoa.h" #define SYSCLK 1000000 /* Bit definition for status flags */ #define F_800 (_BV(0)) // 800 Hz timer event #define F_LVD (_BV(1)) // Low battery #define F_POW (_BV(2)) // Power event #define F_PB (_BV(3)) // Power button /*------------------------------------------------*/ /* Global variables */ uint8_t Leds[5]; // LED display buffer volatile uint8_t flags; // Status flags volatile uint16_t OffTimer; // Auto power off timer uint32_t Gain[2]; uint16_t Ofs20; /*------------------------------------------------*/ /* Interval Timer (800Hz) */ SIGNAL(SIG_OVERFLOW1) { static uint8_t bltimer; // LED blink timer static uint8_t Col; // Dynamic scan pointer if(++Col >= sizeof(Leds)) Col = 0; PORTA &= 0b00000100; PORTB = 0; bltimer++; if((bltimer & 7) == 0) { // Check power button every 8 (100/sec) PORTA |= _BV(3); DDRA &= ~_BV(3); DDRA &= ~_BV(3); DDRA &= ~_BV(3); if(PINA & _BV(3)) { flags |= F_PB; } else { if(flags & F_PB) flags |= F_POW; flags &= ~F_PB; } PORTA &= 0b00000100; DDRA |= _BV(3); } if((bltimer & 0xC0) || !(flags & F_LVD)) // Blink control PORTB = Leds[Col]; PORTA |= (0b00001000 << Col); if(--OffTimer == 0) flags |= F_POW; // Auto power-off timer flags |= F_800; } /* Character output function for LED display (called by xitoa module) */ void putled(char c) { static uint8_t wp; // Write index static const prog_uint8_t seg7[] // Segment pattern = {0x7E, 0x30, 0x6D, 0x79, 0x33, 0x5B, 0x5F, 0x70, 0x7F, 0x7B, 0}; if(c == 'r') { // Return index to left wp = 0; return; } c -= '0'; // Put a segment pattern into display buffer if((uint8_t)c > 9) c = 10; Leds[wp++] = pgm_read_byte(&seg7[(uint8_t)c]); } void delay (uint16_t dly) { do { cli(); flags &= ~F_800; sei(); while((flags & F_800) == 0); } while(--dly); } uint16_t adconv(uint8_t ch) { ADMUX = ch; ADCSR = 0b11010011; while(bit_is_clear(ADCSR, ADIF)); return ADC; } /*------------------------------------------------*/ /* Main Process */ int main(void) { uint16_t n, d; uint32_t v, u; /* Initialize ports */ PORTA = 0b00000100; DDRA = 0b11111110; PORTB = 0b00000101; DDRB = 0b01111111; /* Start TC1 with 800Hz OC-A */ OCR1C = SYSCLK/8/800-1; TCCR1B = _BV(CTC1) | 0b0100; TIMSK = _BV(TOIE1); eeprom_read_block(Gain, 0, sizeof(Gain)); xfunc_out = putled; // Join xitoa molule and my output function OffTimer = 48000; // Auto power off timer (60sec) sei(); /* Lamp test */ memset(Leds, 0x7F, sizeof(Leds)); delay(400); delay(10); Ofs20 = adconv(0x80 + 13); delay(10); cli(); PORTA &= 0b00000100; PORTB = 0b00000101; DDRB = 0b01111010; DDRB = 0b01111010; DDRB = 0b01111010; /* MOSI is tied to GND. Low range calibration (1250 lux at -100 mV) */ if((PINB & _BV(0)) == 0) { adconv(0x80 + 11); Gain[0] = 1250 * 65536 / (uint32_t)(adconv(0x80 + 11) - Ofs20); eeprom_write_block(Gain, 0, sizeof(Gain)); Leds[0] = 0; } /* SCK is tied to GND. High range calibration (12500 lux at -1 V) */ if((PINB & _BV(2)) == 0) { adconv(0x80 + 0); Gain[1] = 12500 * 65536 / (uint32_t)(adconv(0x80 + 0)); eeprom_write_block(Gain, 0, sizeof(Gain)); Leds[1] = 0; } DDRB = 0b01111111; sei(); /* Measurement loop continued until any power event occure */ while(!(flags & F_POW)) { v = 0; for(n = 0; n < 256; n++) // 256 times averaging to filter-out flicker { d = adconv(0x80 + 11); while(!(flags & F_800)); cli(); flags &= ~F_800; sei(); d = adconv(0x80 + 11); if(d < 1023) { d -= Ofs20; u = Gain[0]; } else { d = adconv(0x80 + 0); u = Gain[1]; } d = (u * (uint32_t)d) >> 16; v += d; } /* Refresh lux value */ xputc('r'); xitoa(v / 256, 10, 5); /* Check battrey voltage */ DDRA &= ~_BV(1); d = adconv(0x80 + 1); cli(); if(d >= 23) flags &= ~F_LVD; else flags |= F_LVD; sei(); DDRA |= _BV(1); } /* Power off */ memset(Leds, 0, sizeof(Leds)); // Clear display PORTA &= ~_BV(2); // Release power hold for(;;); }
Yazar: gevv
Yazarımızın 320volt.com Blog üzerinde şu an okuduğunuz yazı dahil 1955 yazısı bulunmaktadır. Yazarımız hakkında bilgileri ve diğer yazılarını görmek için bakınız; gevv











