PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Attiny13 Bewegungsmeldersignal auswerten



mirco99
23.09.2008, 15:51
Hi,
ich habe in meinem Flur einen selbstgebauten LED Spiegel mit Bewegungsmelder. War sündhaft teuer.
Mein Problem ist, seit dem ich meinen Wlan Router und mein Telefon im Flur habe, schaltet sich der Spiegel schonmal öfters kurz ein.

Die Zeitschaltung funktioniert mit einem Schmitt Trigger und nem Kondensator. Der Bewegungsmelder hat einen 5 V TTl Ausgang.

Jetzt soll er wieder richtig funktionieren und bekommt einen Microcontroller.

Ich möchte das er bei Bewegungserkennung 3- 5 Minuten einschaltet und danach aus. Werden in einer bestimmten Zeit zu viele Bewegungen registriert, soll er für ca 20 Minuten ausgeschaltet bleiben.

Irgendwie finde ich nicht den richtigen Ansatz.
Hier mal mein Programm. Ich bin sicher es gibt eine ganz einfache Lösung.

Wie
Wenn in 5 Minuten 20 x einschalten kommt, dann für 20 Minuten aus.

Ich danke euch.


$regfile = "attiny13.dat"
$crystal = 1000000

Ddrb = &B11101111 'Pin PB4 Eingang Rest Ausgang

Dim Stufe1 As Byte
Dim Zaehler As Word
Dim Tilt As Word
Declare Sub Unterprogramm
Config Adc = Single , Prescaler = Auto
Start Adc

'schalte den Timer1 ein
Config Timer0 = Timer , Prescale = 256 'timer 1 0 bis 65535 Zählen Taktfrequenz durch 256 =1000000/256=3906,25 Hz
Enable Timer0 ' 65536 - 3906 = 61630
On Timer0 Isr_von_timer1 'verzweige bei Timer1 überlauf zu Isr_von_Timer0
Enable Interrupts
Timer0 = 0 'Leider Nur 8 Bit Timer Bis 255 Ca 15 X Interrupt = 1 Sekunde '61630





Do


If Stufe1 = 2000000 And Portb.4 = 1 Then 'nach 2000000 bewegungsmeldungen/Programmdurchläufen und eingang eingeschaltet Ausgang aus
Portb.3 = 0
Stufe1 = 0
Zaehler = 61 'Zähler auf 61 Setzen um Auszeit zu zählen
End If
If Portb.4 = 1 Then 'wenn Eingang auf 1 Pin B4 auf 1
Portb.3 = 1
Stufe1 = Stufe1 + 1 'Einschalthäufigkeit zählen
Gosub Unterprogramm
End If

Loop


Sub Unterprogramm

If Zaehler = 900 Then ' nach 60 sekunden ausschalten
Portb.3 = 0
Zaehler = 0
End If



If Zaehler = 4500 Then 'nach 5 Minuten ausgeschaltet auch wenn eine Bewegung erfasst wird
Zaehler = 0 'wieder in den normalen Modus
End If







End Sub




End

Isr_von_timer1: 'ISR von Timer1
Timer0 = 0
Zaehler = Zaehler + 1

Return

Sauerbruch
24.09.2008, 08:16
...wieso hast Du denn für diese Anwendung ausgerechnet den einzigen (!) Controller mit nur einem Timer ausgsucht? :-b

Aber auch damit könnte es klappen. Die Aufgabe müsste nur noch etwas genauer beschrieben sein.
Nach ca. 20 Bewegungen innerhalb einer bestimmten Zeit (welche?) soll das Licht ausgehen, o.k. Ansonsten soll es 3-5 Minuten anbleiben, auch o.k.

Was aber soll passieren, wenn z.B. jede Minute eine Bewegung detektiert wird? Soll es dann nach 5 Bewegungen (d.h. 5 Minuten) ausgehen? Oder 5 Minuten nach der letzten detektierten Bewegung? Oder wie oder was?

mirco99
24.09.2008, 09:07
Hi Sauerbruch,
naja ich habe von diesen Controllern halt noch welche und er ist sehr klein und einfach zu löten. Ich muss die Schaltung in den Holzrahmen einbauen können. Da hat die Schreinerei nur ne flache Nut Platz gelassen.

Ich habe festgestellt, das die Steuerung wenn Sie anfängt ohne Bewegung zu schalten sich irgendwie nicht mehr einkriegt. Das heisst der Spiegel bleibt dann auch schonmal ne Stunde an und flackert nur kurz aus und wieder an. Je nachdem wie lange der Bewegungsmelder die 5 Volt geschickt hat und der Kondensator sich aufladen konnte.
Ich gehe davon aus das die Funkstrahlung meines Routers/ Telefon in die Verstärkerschaltung des Bewegungsmelders einstrahlt. So wird der Kondensator nicht richtig geladen und der Spiegel schaltet dann auch schneller wieder ab, geht dann aber wieder sofort an als wenn er sich aufschwingen würde.

Also müsste ich in einer bestimmten Zeit die Einschaltimpulse zählen und wenn der Wert zum Beispiel in 5 Minuten höher ist als 10, soll der Spiegel für 20 Minuten aus bleiben.

Das Problem in meinem Programm ist das in jedem Programmlauf wenn das Licht eingeschaltet ist hochgezählt wird. Also sinnlos.

Kann ich Flanken zählen lassen ? Wenn ja wie heisst der Befehl?

Danke schonmal für deine Antwort.

Sauerbruch
24.09.2008, 09:20
Kann ich Flanken zählen lassen ? Wenn ja wie heisst der Befehl?


Klar: Du legst die Flanke auf einen Interupt-fähigen Eingang, d.h. entweder INT0 (=PINB.1), oder an einen der PCINT-Eingänge (PINB.0, 1, 2, 3 oder 4). In der Interrupt-Routine lässt Du dann eine Variable um 1 hochzählen - fertig!

Bei den PinChange-Interrupts (PCINT) musst Du nur bedenken, dass sie jeden Flankenwechsel zählen (also beim Ein- und Ausschalten des Signals).

Welcher der PinChange-Interrupts aktiviert sein soll (denn es sollen ja sicherlich nicht alle Pins den Interrupt auslösen), legst Du im PCMSK-Register fest.

Gruß & Co,

Daniel

mirco99
24.09.2008, 10:43
Okay ich würde es dann so machen (habe gerade die suche gefragt):

Nur Pinb.1 kann int0

PCMSK = &B0000010 ' Pin B1 als interrupt /brauche ich das Register bei int0?
INT0 = Portb.1 'ist das so richtig?




Int0_ISR: Ist das der richtige isr Name? wie deklariere ich Ihn?
If Pinb.1=1 then 'abfrage nach steigender Flanke
..... (was auch immer getan werden soll)
.....
End if
Return


Ich habe hier in der Firma kein bascom, daher kann ich es nicht testen oder rantasten.
Muss ich bei int0 das Register trotzdem schreiben?
Woher weiss das Programm das beim Interrupt nach int0_isr gesprungen werden soll?

Sauerbruch
24.09.2008, 11:02
Für den "klassischen" Interrupt INT0 brauchst Du das PCMSK-Register nicht. Dafür ist er immer fest mit PinB1 verbunden.

Alles wissenswerte gibt´s in der Bascom-Hilfe, für erste Aktivitäten in der Firma ( =P~ ) aber schon mal soviel vorweg:



Config Int0 = rising 'steigende Flanke
On Int0 Weizenkeim 'Man kann seine ISR´s nennen wie man möchte...
Enable Int0 'extrem wichtig: Interrupt 0 muss aktiviert werden!
Enable interrupts 'auch extrem wichtig: Interrupts müssen "global" freigegeben werden!

Do
...
...
Loop

Weizenkeim:
... 'was auch immer hier geschehen soll
...
...
return


Klar?

mirco99
24.09.2008, 11:25
=D> SUUUUUUUPER DANKE =D>

Ich verstehe nur nicht wie man auf weizenkeim kommt :lol:

Ich danke dir

hunni
29.09.2008, 14:54
versuchs mal mit n atmega8 der is genauso teuer, hat zwei timer und is nich viel größer, dann haste nich so die probelme

Sauerbruch
30.09.2008, 08:59
is nich viel größer

na ja - immerhin 3 mal so groß...

In ´nem Tiny 15, 25, 45 oder 85 hättest Du auch 2 Timer - und das bei 8 Pins.

hunni
30.09.2008, 14:59
ja gut hast recht.

mirco99
06.10.2008, 11:02
So habe mein Problem jetzt gelöst.
Ich habe mir das Signal für die Bewegung genauer angeschaut und festgestellt, das nach fast jedem Aussachlten der LED´s der Bewegungsmelder nochmals ein bis 2 mal kurz ein Signal ausgibt.
Dieses Signal brauch ich nur zu unterdrücken.
Aber jetzt habe ich dank euch wieder was gelernt.

mirco99
07.10.2008, 14:21
Also es ist mir ja jetzt schon ein wenig peinlich aber warum funktioniert
dieses programm nicht?

Über einem Mäuseklavier gebe ich über 3 Pins die Vergleichsgröße Dip an.
En an Pin B4 eine 1 dann Pin B3 an.

Zähler von timer wird mit Dip Wert verglichen und schaltet bei erreichen des vorgegebenen wertes Pin B3 aus.

Die Schaltung macht was sie will. hängt der Eingang in der Luft flackert die LED Beleuchtung. Lege ich 5 Volt an bleibt sie an.
Lege ich 0 Volt an passiert mal garnichts oder sie geht aus.

Kann mir mal jemand das Brett vom Kopf schlagen ?






$regfile = "attiny13.dat"
$crystal = 4800000

Ddrb = &B11101000 'Pin PB4 Eingang Melder PB0-3 Eingang Dip Schalter Rest Ausgang


Dim Zaehler As Integer
Dim Dip As Integer 'Leider Nur 8 Bit Timer Bis 255 Ca 15 X Interrupt = 1 Sekunde '61630

On Timer0 Ontimer0 'verzweige bei Timer1 überlauf zu Isr_von_Timer0
Config Timer0 = Timer , Prescale = 64
Enable Timer0
Enable Interrupts 'schalte den Timer0 ein

'Timer0 = 0




Zaehler = 0
'---------------------------DIP Schalter Abfrage------------------------------
If Pinb.0 = 1 Then 'dipschalter 1
Dip = 3
End If

If Pinb.1 = 1 Then 'dip2
Dip = 10
End If

If Pinb.2 = 1 Then 'dip3
Dip = 10000
End If
'---------------------------DIP Schalter Abfrage------------------------------



Do
If Pinb.4 = 1 Then
Pinb.3 = 1
End If
'Wait 3




If Zaehler > Dip Then
Zaehler = 0
Pinb.3 = 0
' Wait 3
End If
Loop



Ontimer0: 'ISR von Timer1
Zaehler = Zaehler + 1
Return

Dirk
07.10.2008, 18:02
Hallo mirco99,

welche Timer-Frequenz möchtest du denn haben?

Bei einem 8-Bit-Timer, deiner angegebenen Quarzfrequenz von 4,8 MHz (wo gibts denn den Quarz?) und dem Prescaler 64 erhalte ich eine Timer-Frequenz von 75000 Hz. Deine Integer-Zählvariablen reichen da gerade mal eine fünftel Sekunde, bevor sie überlaufen. :idea:

Gruß Dirk

mirco99
07.10.2008, 18:57
Hallo Dirk,
die 4,8 Mhz hat der Attiny 13 intern als Standart gesetzt.
Ich benutze keinen Quarz.
Über die Zeiten habe ich mir noch keine großen gedanken gemacht.
Die Software müsste halt nur sofort wieder ausschalten, weil der Zähler größer als der Dip Wert ist Und da der Zähler dann auf 0 gesetzt wird, kann er auch nicht überlaufen. Oder habe ich da einen Denkfehler?
Ich wollte den Controler auf 128kHz stellen. Danach war er nicht mehr programmierbar. Mit der jetzigen Taktrate schaffe ich 4,7 kHz Überlauffrequenz bei Prescale = 1024.

Warum schaltet der Controler dann nicht sofort ab und macht nur nicht nachvollziehbare sachen?

Ich habe zwischen Eingang und Masse einen Kondensator geschaltet, so das der Eingang etwas beruhigt wird.

Warum schaltet die Beleuchtung obwohl der Eingang auf 0V liegt nicht immer ab?Ich werde den Timerüberlauf in der Frequenz über die Software Teilen.

Aber der Code ist doch sonst in Ordnung oder ?
Warum erreiche ich den Controler nicht mehr wenn er auch 128kHz laufen soll?

Sauerbruch
07.10.2008, 18:58
...ich weiß auch noch was! =P~


En an Pin B4 eine 1 dann Pin B3 an

Wenn Du damit meinst, dass B3 auf High gehen soll, wenn an B4 ein High-Signal anliegt, dann steckt hier der Fehler:



If Pinb.4 = 1 Then
Pinb.3 = 1
End If


Und zwar in der 2. Zeile - finden musst Du ihn aber selber 8-[

Außerdem klingt Flackern in der Luft ganz schwer nach fehlendem PullUp-Widerstand. Wenn Du keinen Hardware-Widerstand verlötet hast, schreib´ doch mal die Zeile

PortB.4=1

rein.

Und wieso setzt Du den Vergleichswert Dip auf 10.000, wenn der Timer nur bis 255 zählen kann?

Gruß & Co.,

Daniel

Sauerbruch
07.10.2008, 19:12
O.k. - meine letzte Frage war blöde... Du vergleichst Dip ja mit der Integer-Variablen Zähler. Das passt.

Dafür ist der gleiche Fehler hier nochmal - diesmal aber in Zeile 3:


If Zaehler > Dip Then
Zaehler = 0
Pinb.3 = 0


Mit 4,8 MHz und einem Prescaler von 64 läuft der Timer0 aber ca. 290 mal pro Sekunde über. Während der ersten 3 Wait-Sekunden erreicht "Zähler" also schon mal einen Wert von knapp 1000.

Kannst Du vielleicht nochmal so ansatzweise erklären, was das Programm machen soll??

mirco99
08.10.2008, 07:59
Hi Daniel,

der Timer zählt bis 255 und springt dann in die isr. Dort wird dann x um eins erhöht.
Mit dem fehlenden Pull up oder pull down Widerstand hast du recht. Den habe ich aber mit Absicht nicht angebracht, da die Beleuchtung bei freiem Pin an bleiben müsste ohne sichtbares flackern. Später schliesse ich eine ttl Logic von einem Bewegungsmelder an.

Der Wait Befehl ist ausgeklammert!

Ich habe mit Pin und Port rumexperimentiert.
Wann muss man Pin und wann Port schreiben?


Nochmal zum Verständniss

Ich habe einen bewegungsmelder,der bei Bewegung für ca. 1 Sekunde ein High ausgibt. Der Controler soll jetzt einen Verbraucher so lange einschalten wie die Dip Schaltereinstellung ist.
Also ist es ein Zeitschalter it ein und Ausgang und Zeitvorgabe.

Pinb.4 ist der Eingang
Pinb.3 ist der Ausgang

Aber ich denke eine Abfrage macht man mit dem Befehl pin und Ausgänge mit Port. Stimmt das?

mirco99
08.10.2008, 08:56
Ich habe das problem gelöst

es war tatsächlich eine pin und port Frage.
Das habe ich dazu gefunden

Bascom ist da nicht ganz konsequent (find' ich)

Im Progranmm, auf jeden Fall und immer (spezial lassen wa weg):
IF PIND.0 = 1 THEN PORTD.1 = 0

Beim CONFIG dagegen etwas strange:

Geht es ums ganze Port
CONFIG PORTB = Input / Output

Geht es aber um einzelne Pins, dann
CONFIG PINB.1 = Input / Output

Danke

Sauerbruch
08.10.2008, 11:29
Ja - das mit den PINs und PORTs ist am Anfang etwas babylonisch

Deshalb arbeite ich als einfach strukturierter Mensch auch am liebsten direkt mit den DDR-Registern.

Falls Du das Kommunikationsproblem bei 128kHz Taktfrequenz noch nicht gelöst haben solltest: Die Programmierung des Controllers sollte mit einer Taktfrequenz erfolgen, der weniger als 1/4 des Controller-Taktes ist. In diesem Fall also unter 32 kHz. Ich weiß ja nicht, womit Du den Controller "brennst" - aber da solltest Du mal fahnden. Übliche Frequenzen im Bereich mehrerer 100 kHz liegen da deutlich zu hoch.

Bei 128 kHz Taktfrequenz und einem Prescaler von 1024 hättest Du nämlich nur noch alle 0,5 Sekunden einen Überlauf - da wäre das Berechnen des Vergleichswertes recht komfortabel.

mirco99
10.10.2008, 12:01
Hi,
ich programmiere mit nem selbstgebauten paralell Programmer mit einem Verstärker Baustein, weiss nicht mehr welchen ich da genommen habe.
Die brenngeschwindigkeit kann mann dann doch nur noch in der Bascom Software einstellen aber wo ?

Naja habe den nicht mehr programmierbaren Attiny nen Kumpel mitgegeben, der hat in der Firma ein Programmiergerät, wo man auf knopfdruck die Standarteinstellungen zurückbringt.

Mein Spiegel läuft jetzt wunderbar, mit soft start. Es passte keine programmierzeile mehr in den Speicher. Das erste mal das ich einen Controller vollgeschrieben habe. Bei diesem Modell ja auch keine Kunst =P~

Sauerbruch
10.10.2008, 14:42
Schön, dass der Spiegel funktioniert - und ein nicht ganz vollprogramnmmierter Mikrocontroller wäre ja auch Verschwendung =P~

Ich brenne nicht mit bascom, und habe auf den ersten Blick auch nichts gefunden, wo man den Brenn-Takt einstellen kann. Muss aber gehen - vielleicht weiß ja jemand anders in dieser Sache weiter.

Bin erstmal offline - schönes Wochenende!

Daniel