• Willkommen im Geoclub - dem größten deutschsprachigen Geocaching-Forum. Registriere dich kostenlos, um alle Inhalte zu sehen und neue Beiträge zu erstellen.

Reaktives Licht mit Atmel AVR

radioscout

Geoking
Ich habe noch 4 unbenutzte VALVO ORP69 Fotowiderstände (die, die früher in den Fernsehgeräten zur automatischen Anpassung des Kontrates an die Umgebungshelligkeit benutzt wurden) in der Bastelkiste liegen.
Da ich sicher keine alten TVs mehr repariere und der LDR auch selten defekt ist, würde ich die für die, die sich haben wollen, in einen Cache legen.
Interesse?
 

KrasserMann

Geocacher
Windi schrieb:
Ich war gestern Abend im dunklen Wald und hab die LDR-Variante unter Realbedingungen getestet. Ich kann nur sagen: Oberaffenmegageil.
Selbst mit einer nicht fokussierenden Aldi-1W-Funzel funzt es auf über 50 Meter problemlos.
Mit meiner Mag 5D hab ich es "nur" bis 250 Meter getestet da die Kinder nölig waren und mich meine Frau zum Abbruch des Tests "gebeten" hat. Dürfte damit aber bestimmt auch problemlos auf 400-500 Meter gehen.

Hallo Windi würdest du mir deinen Versuchsaufbau zum Nachbau und Feldtest zur verfügung stellen.

Hab mit dem Amtel Rekativlicht von Dir auf LED Basis an meinem Nachtcache
große Probleme mit der empfindlichkeit und würd den gerne langsam publishen lassen.

Da käm mir das gerad recht.

Danke, Martin
 

derhexer

Geocacher
Hallo,
nachdem nun die RTC den atmega schlafen legt und der Stromverbrauch tagsüber (den Nachtbereich kann man nun parametrieren) auf unter 12µA sinkt, gehe ich nun von 9V auf 3V runter, dann kann ich auf den MAX603 verzichten.
Morgen bzw. übermorgen bekomme ein paar Fototransistoren. Mal sehen wieviel "Saft" ich dann nochmals einsparen kann... der atmega88 wird nun durch einen atmega168 ersetzt 8).

Viele Grüße
derhexer
 

Windi

Geoguru
derhexer schrieb:
Hallo,
nachdem nun die RTC den atmega schlafen legt und der Stromverbrauch tagsüber (den Nachtbereich kann man nun parametrieren) auf unter 12µA sinkt, gehe ich nun von 9V auf 3V runter, dann kann ich auf den MAX603 verzichten.
Morgen bzw. übermorgen bekomme ein paar Fototransistoren. Mal sehen wieviel "Saft" ich dann nochmals einsparen kann... der atmega88 wird nun durch einen atmega168 ersetzt 8).

Mit dem Tiny bin ich herunten bis auf 5µA bei 3 Volt.
Du schreibst immer 9 Volt. Hast Du die direkt angeschlossen?
Laut Datenblatt beträgt die Versorgungsspannung maximal 5,5 Volt.
 

Windi

Geoguru
derhexer schrieb:
Deine 5µA sind nicht ganz richtig, denn Du pulst permanent für die Messung und dann steigt das Mittel gewaltig an.... oder?
Laut Digitalmultimeter hab ich ein Mittel von 5µA.
Ich habe mit dem LDR und dem Vorwiderstand einen extrem hochohmigen Spannungsteiler. Dessen Stromaufnahme beträgt bei Tag im schlechtesten Fall 6,4e-7 A. Den bräuchte man eigentlich gar nicht mehr pulsen.
Die 5µA sind also "Normalbetrieb".
Ich schicke den Prozessor wann immer möglich zum Schlafen und wecke ihn zur Abfrage immer nur kurz auf. Das bringt schon einiges an Stromersparniss.
Ich werd mal schnell den aktuellen Schaltplan mit dem LDR zeichnen und dann hier einstellen.
 

derhexer

Geocacher
Ooops,
jetzt habe ich mal den MAX603 gezogen und 3V direkt angeklemmt...
Tagsüber (wenn die RTC den atmega noch nicht aufgeweckt hat) unter 1µA !!! ...
 

derhexer

Geocacher
Wenn das Dein Mittel incl. Messaufwand ist, dann ist das schon sehr pasabel. Wenn ich die Fototransitoren habe, werde ich versuchen, den atmega damit aufzuwecken, d.h. der schläft dann permanent und wird nur durch Licht geweckt. Ob das funktioniert, weiss ich aber noch nicht...
 

Windi

Geoguru
Hier mal die aktuelle Schaltung sowie das aktuelle Programm.
Der LDR-Vorwiderstand muss je nach LDR-Typ angepasst werden. Einfach mal mit ein paar hochohmigen Werten testen welche am Besten gehen. Er muss auf alle Fälle kleiner sein als der Dunkelwiderstand des LDR.

Kurz zur Funktion:

Der LDR und der Vorwiderstand bilden einen hochohmigen Spannungsteiler. Über PB0 wird der Spannungsteiler immer nur dann mit Strom versorgt wenn tatsächlich eine Messung stattfindet. Die Stromaufnahme des Spannungsteilers ist allerdings so gering dass man darauf eigentlich verzichten könnte.
Ist es dunkel wird der LDR hochohmig und an PB4 liegt low an. Fällt Licht auf den LDR wird er niederohmig und es liegt High an.
Die Grenzen für Low und High verschieben sich proportional zur Versorgungsspannung, d.h. selbst bei schwächeren Batterien funktioniert es so (hoffentlich).
Das Programm ist im Vergleich zur LED-only-Variante nahezu gleich geblieben. Lediglich einen extra Schlafmodus habe ich hinzugefügt den man aber auch dem LED-Programm spendieren könnte. Wird 200 Zyklen lang "hell" gemessen geht der Prozessor für 8 Sekunden in den Schlafmodus. Das ist die längste Zeit die mit dem Watchdog-Timer realisierbar ist. Nach diesen 8 Sekunden wacht er kurz auf und misst erneut. Ist es immer noch hell schläft er für weitere 8 Sekunden.
Ist es dunkel geht er in den normalen Betriebszustand über (eine Messung alle 125 ms).

Die Reichweite ist damit absolut gigantisch. Es hängt jedoch auch vom verwendeten LDR ab. Sehr gute Ergebnisse hab ich mit dem Typ A1060 (Conrad-Nr. 183563-66) gemacht.

Hier der Schaltplan:


und hier das aktuelle Programm:

Code:
'============================================================
'
' ******************************************************
' ***                                                ***
' *** Reaktiv-Tiny mit Watchdog-Abschaltung und LDR  ***
' ***      von Sir Vivor und Windi                   ***
' ***                                                ***
' ******************************************************
'
' µC: ATtiny13
' +Ub: 3,00 V
' I: 5 µA im Leerlauf
'
'============================================================

$regfile = "ATtiny13.DAT"
$crystal = 16000                                            'Frequenz des internen Oszillators

Config Portb = &B00001001                                   'Pinb.0 und 3 auf 'Ausgang', Rest auf 'Eingang' schalten
Portb = 0
Stop Adc                                                    'A/D-Wandler abschalten, um Strom zu sparen
Stop Ac                                                     'Analog-Komparator abschalten, um Strom zu sparen

Wdtcr = &B11010011                                          'Watchdog definieren: 0.125 Sekunden, Interrupt auslösen, kein Reset
Enable Interrupts                                           'Interrupts freigeben


Dim A As Byte
Dim B As Byte
Dim C As Byte
Dim Ldr As Bit
Dim Hell As Bit
Dim Hell_2 As Byte

Do
    Gosub Ldr_abfrage
    If Ldr = 1 Then Hell = 1                                'Bei Licht Merker setzen
    If Hell = 1 And B < 255 Then B = B + 1                  'Wenn Merker gesetzt wurde, Zähler für Lichtdauer erhöhen (bis max. 255)
    If B > 200 Then Gosub Abschalten                        'Schlafmodus wenn es zu lange am Stück hell ist
    If Ldr = 0 And Hell = 1 And B < 30 Then                 'Wenn es wieder dunkel ist und der Lichtimpuls nur kurz war
       Hell_2 = 0                                           'zweiten Hell-Merker setzen
       For C = 0 To 5                                       'und 5 mal abfragen
         Gosub Ldr_abfrage
         If Ldr = 1 Then Hell_2 = Hell_2 + 1                'ob es auch wieder dunkel ist
       Next C
       If Hell_2 = 0 Then Gosub Blinken                     'erst dann blinken
       Hell = 0
       B = 0
    End If

    If Ldr = 0 Then                                         'Bei Dunkelheit Merker und Zähler für Lichtdauer löschen
      Hell = 0                                              'damit sich das Programm nicht aufhängt
      B = 0
    End If
Loop



Ldr_abfrage:
    Portb.0 = 1                                             'Spannung auf LDR geben
    Reset Watchdog                                          ' Kurz warten bis sich alles eingeschwungen hat
    Powerdown
    Ldr = Pinb.4                                            'LDR abfragen
    Portb.0 = 0                                             'Spannung von LDR wieder wegnehmen
    Return



Blinken:                                                    'LED blinken lassen
    For A = 1 To 10
        Portb.3 = 1
        Reset Watchdog
        Powerdown
        Portb.3 = 0
        Reset Watchdog
        Powerdown
        Next A
Return



Abschalten:                                                 'Prozessor für 8 Sekunden schlafen lassen
Wdtcr = &B11110001
Reset Watchdog
Powerdown
Wdtcr = &B11010011
Return

End

Nachtrag: Im Programm war ein Fehler drin da ich auf Low abgefragt habe und nicht auf High. So wie es jetzt da steht passt es aber.
 

Windi

Geoguru
derhexer schrieb:
Tagsüber (wenn die RTC den atmega noch nicht aufgeweckt hat) unter 1µA !!! ...
Wie schaffst Du das nur?
Selbst bei 16 kHz Taktfrequenz und wenn der Prozessor im Schlafmodus ist komme ich nicht unter 5µA.
 

derhexer

Geocacher
Das liegt daran, dass Deiner nicht wirklich "fest" schläft... ich fahre Power-down Mode (lt. Datasheet 0.1 µA). Mein Multimeter zeigt immer nur 0 oder 1µA an, da es nicht weniger messen mag :( ...

Diesen Sleep-Mode kannst Du leider nicht verwenden, da bei Dir die MPU immer laufen muss. Meine MPU wird per RTC aufgeweckt (INT0-Pegel).
 

derhexer

Geocacher
Gerade habe ich mal Dein Programm und das Datenblatt des tiny13 angesehen. Laut Programm fährst Du "kurz" PowerDown, der ist bei Deinem tiny13 mit < 0.1 µA angegeben....

Wieso schluckt Deiner dann soviel?
 

Windi

Geoguru
derhexer schrieb:
Gerade habe ich mal Dein Programm und das Datenblatt des tiny13 angesehen. Laut Programm fährst Du "kurz" PowerDown, der ist bei Deinem tiny13 mit < 0.1 µA angegeben....

Wieso schluckt Deiner dann soviel?
Ich vermute mal durch den internen Taktgeber. Was anderes kommt eigentlich nicht mehr in Frage.
< 0.1 µA gelten aber auch nur für 1,8 Volt Versorgungsspannung.
 

derhexer

Geocacher
Windi schrieb:
Ich vermute mal durch den internen Taktgeber. Was anderes kommt eigentlich nicht mehr in Frage.

Das glaube ich nicht, denn ich verwende auch meine innere Uhr... vielleicht treibt der Basic-Unterbau irgendeinen Unsinn...

Hier mal mein main-Schnipsel

Code:
#include "types.h"
#include "LED.h"
#include "DS1337.h"

#define MINDARKCOUNT	 200 // Min. Anzahl von Dunkelmessungen bis auf "nun is finster" umgeschaltet wird
#define MAXFLASHDURATION 5   // Max. Dauer eines externen Weckimpulses (kurzer Flash einer Taschenlampe)

const char szDefMsg[] PROGMEM = "derhexer\0";

CCommLED led    (&DDRD, &PORTD, &PIND, PD0, PD1);	
CLED     ledOK  (&DDRD, &PORTD, PD4);
CLED     ledRED (&DDRB, &PORTB, PB1);
CSpeaker speaker(&DDRC, &PORTC, PC3);
CDS1337  rtc;

PORT8    g_bGoSleep;

ISR(INT1_vect) {
	rtc.ClearAlarm1();
	ledOK.Flash(20);
	g_bGoSleep = true;
}

ISR(INT0_vect) {
	rtc.ClearAlarm2();
	ledRED.Flash(20);
}

int main(void) {
	BYTE  i;
	EVENT event;

	g_bSleep = false;
	
	ADCSRA &= ~(1<<ADEN); //Analog-to-Digital disabled
	ACSR  |= (1<<ACD);	   //Analog Comparator disabled
	CLKPR = 0x80;
	CLKPR = 0x02;
	
	EICRA = 0x00;
	EIMSK = 0x03;
		
	//fdevopen(my_putc, 0);
	ledRED.Flash();
	ledOK.Flash();
	led.Flash();
	
	DelayMS(200);
	ledRED = true;	 ledOK = true;  led = true;
	DelayMS(200);
	ledRED = false; ledOK = false; led = false;
	
	DelayMS(200);

	if (rtc.GetCurrentTime()) {
		if (rtc.GetYear() < 2006) {
			rtc.SetDateTime(2006,9,25,14,25,0); //test...			
			led.Blink(20,50);
		}
		else
		{
			char szBuf[10];
			itoa(rtc.GetSecond(), szBuf, 10);
			ledOK.Blink(rtc.GetSecond() % 10);
		}
		rtc.SetAlarm1OncePerMinute(30);
		rtc.SetAlarm2OncePerMinute();
		led.Blink(1);
	}
	else
		ledRED.Blink(20,50);

	sei();

	set_sleep_mode(SLEEP_MODE_PWR_DOWN);
	sleep_enable();	
	sleep_cpu();

	if (! ReadEvent(0, event)) //Read EEPROM Data
		InitEvent(event);
		
	char buf[sizeof(EVENT)+1];	
	for(int i = 0; i < 10; i ++) {  
		if (led.Receive(buf, sizeof(buf)))
		{		
			if (InitEvent(event, buf)) {			
				StoreEvent(0, event); //Save EEPROM Data				
				ledOK.Blink(1);
				break;
			}	
		}
		ledRED.Blink(1);
	}

	for(;;) {
		for (i = 0; i < MINDARKCOUNT; i ++)  //Warten bis es Dunkel ist
		{
			if (g_bGoSleep) {			
				g_bGoSleep = false;				
				sleep_cpu();
			}
			if (!(i % 5))
				ledRED.Flash(10);
			if (led.IsThereSomeLight())
				i = 0;
		}
		ledRED.Blink(1,100);
		
		while (!led.IsThereSomeLight());  //Warten bis das erste Licht auftaucht
		
		ledOK.Blink(1,100);
		
		if (event.Trigger & eShortFlash)   //Soll nur auf Flashes reagiert werden
		{
			for (i = 0; i < MAXFLASHDURATION; i ++)
			{
				if (! led.IsThereSomeLight())
					break;
			}
			if (i >= MAXFLASHDURATION) //war das mehr als nur ein Flash???
				continue;  
		}
		
		switch (event.Output)
		{
		case eBlinkCommLED:
			led.Blink(event.Pulses, event.PulseDuration*100);
			break;
		case eBlinkOK:
			ledOK.Blink(event.Pulses, event.PulseDuration*100);
			break;
		case eBlinkRED:
			ledRED.Blink(event.Pulses, event.PulseDuration*100);
			break;
		case eBlinkSpeaker:
			speaker.Blink(event.Pulses, event.PulseDuration*100);
			break;
		case eMorseCommLED:
			led.Morse(event);
			break;
		case eMorseOK:
			ledOK.Morse(event);
			break;
		case eMorseRED:
			ledRED.Morse(event);
			break;
		case eMorseSpeaker:
			speaker.Morse(event);
			break;
		}
	}
	return(0);
}
 

Windi

Geoguru
derhexer schrieb:
Windi schrieb:
Ich vermute mal durch den internen Taktgeber. Was anderes kommt eigentlich nicht mehr in Frage.

Das glaube ich nicht, denn ich verwende auch meine innere Uhr... vielleicht treibt der Basic-Unterbau irgendeinen Unsinn...

Habs gefunden:
Laut Datenblatt (Fig. 77) müssten es 4µA sein und nicht 0,1µA da ja der WD-Timer weiterläuft.
 

derhexer

Geocacher
Das ist auch bei höheren Spannungen besser... bei 3Volt immer noch unter 0.2µA....

Bei Dir "frisst" die Watchdog den Strom, denn die "braucht bei 3V unter 4 µA.
 

Windi

Geoguru
derhexer schrieb:
Bei Dir "frisst" die Watchdog den Strom, denn die "braucht bei 3V unter 4 µA.
Dafür spare ich mir zusätzliche Bauteile. Ich denke die Stromaufnahme ist so gering dass ich mir über die Batterielebensdauer in den nächsten paar Jahren keine Gedanken machen muss.
 

Windi

Geoguru
derhexer schrieb:
Naja... warte mal den Winter ab. Da wird es sehr eng für jeden von uns.
Ein anderes Reaktivlicht von mir hängt schon seit dem letzten Winter. Damit gab es nie Probleme. Man muss halt gute Batterien verwenden.
Ich habe die Schaltungen bei mir auch schon mehrere Tage im Gefrierfach gehabt. Hat alles problemlos funktioniert.
 
Oben