Diese beiden nachfolgenden Beispielprogramme demonstrieren wie einfach sich Bewegung mit einem Bewegungsmelder auswerten lassen. Als Controllerboard wurde wieder ein RN-AVR Universal mit Mega 644 genutzt, es geht natürlich bei allen anderen ähnlich. Als Bewegungssensor haben ich den nachfolgenden PIR SE10 benutzt, hiermit geht es besonders einfach und zudem reicht die übliche Versorgungsspannung des Boards völlig aus.
Bild hier  


Angeschlossen habe ich den PIR indem ich den Alarmkontakt auf PA0 (ADC0) gelegt habe. GND mit GND und +DC mit der Batteriespannung (in meinem Fall 4 Mignon Batterien) PIN POW bei RN-AVR Universal, verbunden habe.
Zwischen PA0 und +3V oder POW (Batteriespannung) muss wieder ein Pullup-Widerstand, ich habe 33k Widerstand verwendet.
Im ersten Programm frage ich einfach kontinuierlich die Spannung an PA0 ab. Wenn sich nichts bewegt, liegt dieser Wert in der regel immer bei 1023 (Maximum). Sobald ein niedrigerer Wert gemessen wird, wurde eine Bewegung erkannt und über RS232 ausgegeben.
Diese einfache Form der Abfrage funktioniert bei diesem Sensor eigentlich schon sehr zuverlässig. Will man kleinen Bewegungen ausschließen, so könnte man natürlich auch noch eine zweite Messung zeitlich verzögert nach der ersten durchführen. Durch den Abstand der Messungen und je näher der ADC-Wert der 0 kommt, könnte man also auch kleinere Bewegungen ignorieren, in der Regel ist das aber oft garnicht nötig.


Code:
'##############################################################
'bewegungssensor1.bas
'
'Ein kleines Testprogramm für RN-AVR UNIVERSAL (ATMega644)
'und Bewegungssenor PIR SE10 von Robotikhardware.de
'Das Programm demonstriert wie man mit einem kleinem
'kompakten PIR-Sensor Bewegung in einem Raum erkennen kann
'Sobald die geringste Bewegung erkannt wird, wird dies über RS232 ausgegeben
'Die Led leuchtet ebenfalls bei Bewegung auf
'
' (c) Frank Brall 2013
'Weitere Beispiele auf DVD von robotikhardware.de
'oder im www.Roboternetz.de und rn-wissen.de


'######################################################################


'Portbelegung:
'PIR SE10 Alarmkontakt an PA0
'PIR GND nach GND
'PIR + nach POW+ (Batterie 4 Mignon)
'Pullup-Widerstand 33k von PA0 nach POW+
'Werteausgabe über RS232/USB




Declare Function PIRAbfragen()  as byte




$programmer = 12                    'MCS USB  (Zeile weglassen wenn anderer Programmer)
$prog &HFF , &HFF , &HD9 , &HFE      'Fusebits richtig programmieren (Quarz ein,Jtag aus)


$regfile = "m644pdef.dat" ' oder $regfile = "m644def.dat"
$framesize = 64
$swstack = 64
$hwstack = 64


$crystal = 8000000                                          'Quarzfrequenz




Config Pind.6 = Output                                      'LED
Led1 Alias Portd.6




Config Pina.0 = Input
Config Adc = Single , Prescaler = auto , Reference = INTERNAL_1.1






dim bewegung as byte


Start Adc
wait 3  '2 Sekunden warten - kalibrierung Sensor auf Hintergrund
Do
    bewegung= PIRAbfragen()
    if bewegung=1 then print "Bewegung wurde erkannt !"
    waitms 100
Loop






Function PIRAbfragen()  as byte
local adcwert as  Integer


    adcwert=Getadc(0)
    if adcwert<1023 then
      bewegung=1
      Led1=0
    else
      bewegung=0
      Led1=1
    endif
end function

Der Nachteil des oberen Programmes war die Tatsache das der Port PA0 praktisch ständig gemessen werden musste, das Programm konnte zwischendrin praktisch nichts anderes machen denn sonst hätte es eventuell eine Bewegung verpasst.
Daher gibt es noch eine zweite Lösung. Hier verwenden wir den "Pin Change Interrupt". Dieser Interrupt steht bei neueren Atmel Controllern an jedem PIN zur Verfügung. Pegeländerungen an einem Pin führen somit automatisch zu einem Interrupt. Dies nutzen wir hier bei PA0 aus, denn dafür steht der Interrupt PCINT0 zur Verfügung. Immer wenn der Pegel wechselt, wird in die Interrupt-Routine gesprungen. Dort schaun wir nur noch mal ob der Pin PA0 jetzt wirklich auf Low liegt, wenn ja setzen wir die Variable Bewegung auf 1. Unser Hauptprogramm kann in der Zeit soviel andere Dinge machen wie es Lust hat, es muss nur ab und zu, wenn es Zeit hat, mal prüfen ob die variable Bewegung vielleicht auf 1 steht. Dann kann es auf die Bewegung wie von euch gewünscht reagieren. Erst nach dieser Reaktion setzt es Bewegung wieder auf 0 zurück. Der Vorteil, das Programm wird also nicht aufgehalten und trotzdem wird keine Bewegung übersehen!
Obwohl wir hier keinen ADC nutzen, funktioniert auch dieses verfahren bei oberen Sensor äußerst zuverlässig.
Wer Lust hat kann das natürlich auch noch Ausbauen und im Interrupt die Spannung an PA0 messen um eventuell über Stärke der Bewegung schließen zu können. Da gewöhnlich eine Bewegung zu mehreren Interrupts führt, könnte man natürlich auch die Interrupts zählen und daraus auf die Art und Stärke der Bewegung schließen zu können. Ich denke das Prinzip ist klar geworden.

Code:
'##############################################################
'bewegungssensor2_pinchange.bas
'
'Ein kleines Testprogramm für RN-AVR UNIVERSAL (ATMega644)
'und Bewegungssenor PIR SE10 von Robotikhardware.de
'Das Programm demonstriert wie man mit einem kleinem
'kompakten PIR-Sensor Bewegung in einem Raum erkennen kann
'Sobald die geringste Bewegung erkannt wird, wird dies über RS232 ausgegeben
'
'Der Vorteil dieses Programmes ist, das der Bewegungsmelder nicht
'ständig abgefragt werden muss, da der Pin Change Interrupt
'ausgenutzt wird. Der Controller kann also nebenher etwas anderes machen.
'Die Led leuchtet ebenfalls bei Bewegung auf
'
' (c) Frank Brall 2013
'Weitere Beispiele auf DVD von robotikhardware.de
'oder im www.Roboternetz.de und rn-wissen.de


'######################################################################


'Portbelegung:
'PIR SE10 Alarmkontakt an PA0
'PIR GND nach GND
'PIR + nach POW+ (Batterie 4 Mignon)
'Pullup-Widerstand 33k von PA0 nach POW+
'Werteausgabe über RS232/USB




Declare Function PIRAbfragen()  as byte




$programmer = 12                    'MCS USB  (Zeile weglassen wenn anderer Programmer)
$prog &HFF , &HFF , &HD9 , &HFE      'Fusebits richtig programmieren (Quarz ein,Jtag aus)


$regfile = "m644pdef.dat" ' oder $regfile = "m644def.dat"
$framesize = 64
$swstack = 64
$hwstack = 64


$crystal = 8000000                                          'Quarzfrequenz




Config Pind.6 = Output                                      'LED
Led1 Alias Portd.6




Config Pina.0 = Input
PIR Alias Pina.0




On Pcint0 Isr_Bewegung
Enable Pcint0
Pcmsk0 = &B00000001  'Interrupt für PIN PA0 PCINT0 zulassen
enable interrupts




dim bewegung as byte


led1=1 'led aus
wait 3  '2 Sekunden warten - kalibrierung Sensor auf Hintergrund
Do


    if bewegung=1 then
      print "Bewegung wurde erkannt !"
      wait 2  'Warten
      bewegung=0 'Gemerkte Bewegung zurückstellen da ausgewertet
      led1=1 'led wieder aus
    endif
    waitms 500
Loop








'Diesser Interrupt wird ausgelöst wenn PIR Bewegung meldet
'genauer gesagt: wenn PA0 den Pegel wechselt
Isr_Bewegung:
  if PIR=0 then
    bewegung=1
    Led1=0 'led ein
  endif
return