Hier sind mal die Quelldateien des Moduls zur Helligkeitsmessung.

Erklären tu ich mal nix... Falls was unklar ist, kannst ja fragen (bevor ich hier ins Blaue rein was erkläre und mir den Wolf tippsle )

Es ist als Anregung gedacht. "Out of the Box" wird es wohl eh nicht laufen...

hell.h
Code:
#ifndef _HELL_H_
#define _HELL_H_

extern void hell_init();
extern void hell_intro();
extern uint8_t hell_loop();
extern void hell_mess_start();

#define HELL_MAX 0x1ff

enum
{
	HS_IDLE, // inaktiv
	HS_AWAIT_INTRO, // warten auf Schedule von timer1-job
	HS_AWAIT_PATTERN_GAP, // warten auf Loch im Anzeigen-MUX
	HS_MESS,
	HS_MESS_OK,
	HS_MESS_TIMEOUT,
	HS_MESS_DONE
};

#define HELL_NWERT 16

typedef struct
{
	uint8_t debug;
	uint8_t state;
	uint16_t icr1;
	uint16_t max;
	uint16_t wert;	
	uint8_t count;
} hell_t;

extern hell_t hell;

#endif // _HELL_H_
hell.c
Code:
#include <AVR.h>
#include <avr/delay.h>

#include "ports.h"
#include "pattern.h"
#include "timer1-job.h"
#include "hell.h"
#include "main.h"

hell_t hell;

void hell_init()
{
	hell.state = HS_IDLE;
	// AIN+ als Eingang
	MAKE_IN (PORT_AIN0); 
	CLR (PORT_AIN0); 
	// disable AC (ACD = 1)
	// AC Input Capture on -> disconnect from Input Capture of Timer/Counter1
	// AIN0(+) = kein Bandgap
	ACSR = (0 << ACD) | (0 << ACIC) | (0 << ACBG); 
	
	// AC MUX enable (AC-Input = ADC-MUX-Output, falls ADC disabled)
	SFIOR |=  (1 << ACME);
	ADMUX = 0x7 & PORTC_AIN1;
}

void hell_intro()
{
	hell.state = HS_AWAIT_PATTERN_GAP;
	hell.max = HELL_MAX;
}

void hell_mess_start()
{
	SET_ANODES;
	
	hell.state = HS_MESS;
	hell.debug = 0;
	// Kathoden wurden in pattern::pattern_out() gesetzt.
	
	// enable AC (ACD = 0)
	// AC Input Capture on -> connect to Input Capture of Timer/Counter1
	// AIN0(+) = kein Bandgap
	ACSR = (0 << ACD) | (1 << ACIC) | (0 << ACBG); 
	
	// stop timer1
	// disconnect timer1 from output pin OC, no PWM
	TCCR1A = 0;
	TCCR1B = (1 << ICNC1) | (1 << ICES1);

	// Load capacity via AIN- push-pull
	
	cli();
	
	OCR1A = hell.max;	

	// Reset Timer1
	TCNT1 = 0;
	
	// PortC.x Pegel
	_delay_loop_1 (30);
	
	// enable Input Capture Interrupt
	TIMSK |= (1 << TICIE1) | (1 << OCIE1A);
	
	// start timer 1 at 1/64 (011)
	// no clear on compare match
	// noise cancel
	// input capture edge = raising (mess = AIN(-))
	// don't change ICNC1 and ICES1 i.o. not to trigger an IRQ
	
	// clear Timer1 Flags
	TIFR = TIFR_T1;
	
	TCCR1B = (1 << ICNC1) | (1 << ICES1) | (1 << CS11) | (1 << CS10);
	
	// here we go! 
	// start discharging via external resistor
	// AIN- to high Z
	MAKE_IN (PORTC_AIN1); 
	CLR (PORTC_AIN1); 
	
	sei();
}


uint8_t hell_loop()
{
	if (hell.state <= HS_MESS)
		return T1_CLAIM;
		
	if (hell.state == HS_MESS_TIMEOUT)
		hell.icr1 = hell.max;

	hell.state = HS_MESS_DONE;
	
	// disconnect InCapt1 from AC
	ACSR = (0 << ACD) | (0 << ACIC); 
	
	return T1_DONE;
}

SIGNAL (_handle_icp1_oc1a)
{
	hell.icr1 = ICR1;

	uint8_t state = HS_MESS_TIMEOUT;
	
	if (ACSR & (1 << ACIC))
		state = HS_MESS_OK;
	
	hell.state = state;

	SET (PORTC_AIN1); 
	MAKE_OUT (PORTC_AIN1); 
	
	TIMSK &= ~TIMSK_T1;
}

// Bit ACIS in ACSR merkt, ob ein Overflow (OC1A) auftrat,
// denn beim Betreten der ISR wird das OCF1A gelöscht.
void __attribute__((naked))
SIG_OUTPUT_COMPARE1A()
{
	cbi (ACSR, ACIC);
	rjmp (_handle_icp1_oc1a);
}


void __attribute__((naked))
SIG_INPUT_CAPTURE1()
{
	rjmp (_handle_icp1_oc1a);
}