Canada
Asked — Edited
Resolved Resolved by Rich!

Trying To Get A Pir Working

I feel like a blind man wandering around in the bush at night hoping to find my way home!

So here's where I'm at with this project, I've put some comments in so you can see what I'm trying to accomplish. Any and all help will be appreciated.



:loop
#timer to power down
$x = 0
RepeatUntil($x = 30)
$x++
Sleep(1000)

EndRepeatUntil
repeatUntil(1=2)

#what to do when timer gets to 30

set(D2,OFF)
#$x = GetDigital(D2)
ControlCommand("Script Manager", ScriptStart, "power down")#do this once

sleep(5000) 
WaitForChange(GetDigital(D2))
sleep(5000)

#do this when the PIR is triggered after "power down"

$motion=getDigital(D2)
IF($motion=1) #pin went high
ControlCommand("Script Manager", ScriptStart, "Power up")#do this once
endif

#do this if PIR is triggered anytime after it has powered up

$motion=getdigital(D2)
if($motion=1)
#stay powered up - need something here - what?
sleep(10000)
EndIf

# if Pir is not triggered in 30 sec start the timer again

If($x = 30)
GoTo(loop)
endif
EndRepeatUntil


Thanks

PS. I would pay money to go to a course somewhere to learn EZ-Robot scripting!


ARC Pro

Upgrade to ARC Pro

Synthiam ARC Pro is a new tool that will help unleash your creativity with programming robots in just seconds!

United Kingdom
#1  

No need to pay money dude, I'm usually around to answer pretty quickly on here and if I'm not Richard R is getting the hang of things too and seem to be on here as much as me these days:)

To be honest I'd prefer (well, love to actually) rewrite this one (including comments and explanations to help you understand it all) however that'll have to wait until I finish work but to get it straight can you confirm the operation and order of.

Presumably it's this;

Robot sleeps until awoken by PIR sensor?

Robot powered up manually first time. Robot detects movement via PIR After 30 seconds of inactivity robot moves to low power state while still checking for movement On detection of movement robot wakes up After 30 seconds of inactivity robot moves to low power state while still checking for movement and so on

I'll knock something up quickly later.

#2  

Yes Rich, you have the jest of it. I'm away for the weekend so no rush. Going to Calgary -maybe I'll stop in at the mothership and say Hi. Thanks for your help

United Kingdom
#3  

I realised while writing this that I haven't written much for a while so it may be a little rusty or there may be some commands which can be written better but here is an example to get you going.

All scripts I assumed would be in "Script Manager", if they are separate scripts or your rename Script Manager you need to check the ControlCommands()

This will use three scripts. One for monitoring of the PIR over a period of roughly 30 seconds. One will shut down to low power mode and monitor the PIR waiting for motion and the last will Power Up the robot and start the monitoring.

Until all three scripts are written/added you may get some errors if you try to run them as the scripts will not exist.

First start with the power up script.

# Place holder for power up
# Enter power up commands here


# Start monitoring
ControlCommand("Script Manager", ScriptStart, "Monitor")

This will turn on all functions you need to have turned on and then start the "Monitor" script in Script Manager. It's this script which you would want in your "init" script which is run on connection.

It's a very basic script which shouldn't need any more explanation than this.

Next we need the "Monitor" script.

# Monitor for movement for 30 seconds

# Set a lable for the start
:start

# Reset the counter
$Monitor_Counter = 0

# Repeat
RepeatUntil($Monitor_Counter = 30)

# Increase the counter by 1
$Monitor_Counter++

# Check for detection on PIR - since we need to check 5 times per second use repeat

# checking counter needed
$Monitor_Check_Counter = 0

RepeatUntil($Monitor_Check_Counter = 5)
# Add 1 to the check counter
$Monitor_Check_Counter++

# Check the status of the digital port
$PIR = GetDigital(D1)
# Check if it is high or low and take action
IF($PIR = 1)
  # Motion detected, return to start
  Goto(start)
EndIf
# Note - no else or elseif required since nothing happens if motion isnt detected

# Wait a while to save system resources
Sleep(200)
EndRepeatUntil

# 1 second has passed by this point
# repeat 30 times
EndRepeatUntil

# 30 seconds passed - Enter low power plus monitoring mode
ControlCommand("Script Manager", ScriptStart, "LowPowerMonitoring")

# End the script
HALT()

The comments in the script should explain each part of it. The HALT() at the end is optional. Without it the script will just stop anyway however I have included it as I like to use HALT() and it also should indicate where the script will end. When motion is detected the script will jump back up to the start rather than continue in it's current Repeat loop. Next time the Repeat loops are run the counters are reset to 0 so the time is reset to 0.

When the time runs out without motion detected the script starts up the LowPowerMonitoring script and this one ends.

So now, all that is left is the low power monitoring script;

# Enter your low power mode commands here



# Once in low power mode wait for a change on the PIR digital port
WaitForChange(GetDigital(D0))

# Power up robot
ControlCommand("Script Manager", ScriptStart, "PowerUp")

# And end this script
HALT()

Another very simple script. The start needs editing for your low power commands, control commands to shut off or pause functions etc.

Then it sits there monitoring the digital port (D0 in this case, edit to suit). When it changes, i.e. when there is motion it uses ControlCommand to start up the Power Up script again. The power up script starts the monitoring script and we have an endless circle.

Hopefully that should get you going:)

#4  

Thanks Rich, I'll run it when I get back. Just dropped in at EZ-Robot here in Calgary, nice bunch of people!

#5  

@Rich, Thanks for the code it works great! Now I have to figure out how to actually "power down" and "power up" the servos.

Thanks again, Bob

United Kingdom
#6  

Power down is easy

ReleaseAll(0)

Presuming it's on board 0. If on another board change the 0. If multiple boards put each board on a new line i.e.

ReleaseAll(0)
ReleaseAll(1)
ReleaseAll(2)

If you only want to power down a specific servo use

Release(D0)

Or multiple servos

Release(D0)
Release(D1)
Release(D2)

Or multiple servos across multiple boards

Release(0.D0)
Release(1.D3)
Release(2.D6)
Release(2.D7)
Release(4.D20)
#7  

To further what @Rich said... Once you release your servos you will have to reset servo speed if you are using anything other than full speed....

#8  

Thanks, makes sense. So now I have been playing around and I switched the PIR input port from "D2" to "ADC7". I have changed the references to the port in the script, now when to script runs, it skips the "LowPowerMonitoring" and goes directly the "Power Up" script. It worked fine when using "D2", I changed ports because all of my digital ports are in use.

#9  

@bhouston... Digital will return a value of 1 or 0 (true or false)... whereas 8 bit analog will be something like 0 - 255... So when reading analog you should assume the PIR has been activated if the adc7 value is greater than say something like 100... The number may vary so you will need to test this...

#10  

@Richard R, I have tried several different settings - none make a difference. Any other thoughts?

#11  

Can you try changing part of your code your code to this?


# Check the status of the analog port
$PIR = GetADC(ADC7)
# Check if it is high or low and take action
IF($PIR >100)
 # Motion detected, return to start
 Goto(start)
EndIf

#12  

@Richard R, Tried that at different values - no change

United Kingdom
#13  

Can the PIR work on the analogue ports? Check it's datasheet (post it's datasheet if unsure). Bearing in mind that the Analogue ports are 3.3v regulated which may not be enough voltage to power the PIR or may cause problems if there isn't enough current available.

If not, you may need to build a small circuit to make it work for ADC.

#14  

Try this in a separate script and see what values $pir are giving you... wave your hand in front of the pir detector and see what happens to the value of $PIR


repeatuntil(1=2)
$PIR = GetADC(ADC7)
print($PIR)
sleep(3000) #give time for the PIR to rearm
endrepeatuntil

United Kingdom
#15  

Or add the ADC graph, value or meter control;)

#16  

@Rich... bite me LOL.... Forgot about the analog value control. That's much easier... I have some PIRs from Parallax Inc and I have them working on both analog and digital ports... Saying that however, @bhouston does not have the same PIRs so you may be right, the ones he has may not work via analog...

#17  

I plugged in a Parallex PIR and watched it on the "Read ADC" and the "ADC Graph".When on low it shows .35V and some chatter on the bottom line of the graph. When it is triggered it goes to 2.5V and up the the line second from the top on the graph.

I have tried all sorts of different setting and nothing makes a difference. The"Monitoring" script goes to the "LowPowerMonitoring" script and then immediately to the "Power up" script . I have put in a delay in the "LowPowerMonitoring" script, to give the PIR time to reset. That did not make a difference, either.

#18  

Use the ADC value control instead...That will give you the actual value instead of a reference voltage... This way you can see at what point (actual value) where the PIR is triggered... Then use that value in your code.... Also run the monitoring code within the script and look at the script flow... see at what line (and if there is an error) the script decides to jump to power up script. This might help you figure out why it is bypassing some of your code... Another tip is to add print() statements here and there so you can check values as the code runs....

#19  

@Richard R When the PIR is low the value is 25 when it is triggered it goes to 195.I set the high to be >190. I put "print()" in both the monitor script and the lowpowermonitoring script and if reads >25 in both. As usual still not working.

Watching the LowPowermonitor script run, it runs through the script - does not "WaitForChange" Prints >25

United Kingdom
#20  

If the value is fluctuating while low (as I believe you said it is "chattering" on the low end) then WaitForChange() wont be waiting long as the value will be changing and the script will be assuming the chatter is motion being detected.

You could do it slightly differently and add in another script that's always running which checks the ADC value and if it's above a certain value it sets a variable, if below it changes the variable... i.e.


:loop
#Fetch ADC value
$PIR = GetADC(ADC7)

If($PIR > 200)
  $motion = 1
Else
  $motion = 0
EndIF

Sleep(100)
Goto(loop)

When the PIR is triggered it will set $motion to 1. When it's not then $motion is reset to 0

You can then use $motion in your original script to replace the GetDigital() command

#21  

Thanks Rich, I applied your new script and it senses the change as does the "Monitoring script" but nothing happens. I must have something out of place in the "monitoring script" below;


# Monitor for movement for 30 seconds

# Set a lable for the start
:start

# Reset the counter
$Monitor_Counter = 0

# Repeat
RepeatUntil($Monitor_Counter = 30)

# Increase the counter by 1
$Monitor_Counter++

# Check for detection on PIR - since we need to check 5 times per second use repeat

# checking counter needed
$Monitor_Check_Counter = 0

RepeatUntil($Monitor_Check_Counter = 5)
# Add 1 to the check counter
$Monitor_Check_Counter++

# Check the status of the digital port
# Check the status of the ADC port
#$PIR = GetDigital(D2)
$PIR = GetADC(ADC7)

# Check if it is high or low and take action
IF($PIR > 195)

 $motion = 1
Else
 $motion = 0
#EndIF
 # Motion detected, return to start
 Goto(start)
Endif
# Note - no else or elseif required since nothing happens if motion isnt detected
print($PIR)
# Wait a while to save system resources
Sleep(200)
EndRepeatUntil

# 1 second has passed by this point
# repeat 30 times
EndRepeatUntil



# 30 seconds passed - Enter low power plus monitoring mode
ControlCommand("Script Manager", ScriptStart, "LowPowerMonitoring")

# End the script
HALT()

#22  

Hi Rich, when you get a chance, could you have a look at this for me. Thanks

United Kingdom
#23  

Yeah, sorry run out of time yesterday.


# Monitor for movement for 30 seconds

# Set a lable for the start
:start

# Reset the counter
$Monitor_Counter = 0

# Repeat
RepeatUntil($Monitor_Counter = 30)

# Increase the counter by 1
$Monitor_Counter++

# Check for detection on PIR - since we need to check 5 times per second use repeat

# checking counter needed
$Monitor_Check_Counter = 0

RepeatUntil($Monitor_Check_Counter = 5)
# Add 1 to the check counter
$Monitor_Check_Counter++

# Check the status of the ADC port
$PIR = GetADC(ADC7)

# Check if it is high or low and take action
# Convert ADC to simple high/low
IF($PIR > 195)
$motion = 1
Else
$motion = 0
EndIF

IF($motion = 1)
# Motion detected, return to start
Goto(start)
Endif
# Note - no else or elseif required since nothing happens if motion isnt detected
print($PIR)
# Wait a while to save system resources
Sleep(200)
EndRepeatUntil

# 1 second has passed by this point
# repeat 30 times
EndRepeatUntil



# 30 seconds passed - Enter low power plus monitoring mode
ControlCommand("Script Manager", ScriptStart, "LowPowerMonitoring")

# End the script
HALT()

This is all from memory and without ARC. It looked like you had it detecting motion when there was none and vice versa. This was causing it to reset the timer and start again.

You could remove the whole converting it to 0 or 1 though, it's pretty redundant.

# Monitor for movement for 30 seconds

# Set a lable for the start
:start

# Reset the counter
$Monitor_Counter = 0

# Repeat
RepeatUntil($Monitor_Counter = 30)

# Increase the counter by 1
$Monitor_Counter++

# Check for detection on PIR - since we need to check 5 times per second use repeat

# checking counter needed
$Monitor_Check_Counter = 0

RepeatUntil($Monitor_Check_Counter = 5)
# Add 1 to the check counter
$Monitor_Check_Counter++

# Check the status of the ADC port
$PIR = GetADC(ADC7)


IF($PIR > 195)
# Motion detected, return to start
Goto(start)
Endif
# Note - no else or elseif required since nothing happens if motion isnt detected
print($PIR)
# Wait a while to save system resources
Sleep(200)
EndRepeatUntil

# 1 second has passed by this point
# repeat 30 times
EndRepeatUntil



# 30 seconds passed - Enter low power plus monitoring mode
ControlCommand("Script Manager", ScriptStart, "LowPowerMonitoring")

# End the script
HALT()

#24  

Thanks Rich, I made those changes, however, it did not work as expected. I noticed that the "LowPowerMonitor" script ran thru to the end and stopped, so I added in a "GoTo" command and I worked, BUT now everytime the PIR is triggered it runs thru the "PowerUp" command. After Power Up it returns to the "monitor" script though.


# Enter your low power mode commands here

sayezb("i am powering down")
:start
# Once in low power mode wait for a change on the PIR ADC port
WaitForChange(GetADC(ADC7))
$PIR = GetADC(ADC7)
If($PIR > 180)
$motion = 1
#print($PIR)

# Power up robot
Sleep(2000)
ControlCommand("Script Manager", ScriptStart, "Power Up")
EndIf
Goto(start)
# And end this script
#HALT()

Thanks, we are getting closer. Thanks for the nice comments you said about my project.

#25  

@ Rich - I got it working! I put in an If and a ElseIf and it's working! Here's what I ended up with;


# Enter your low power mode commands here

sayezb("i am powering down")
:start

# Once in low power mode wait for a change on the PIR ADC port
#WaitForChange(GetADC(ADC7))
$PIR = GetADC(ADC7)
If($PIR > 180)
$motion = 1
#print($PIR)

# Power up robot
Sleep(2000)
ControlCommand("Script Manager", ScriptStart, "Power Up")

EndIf
sleep(3000)
If($motion = 1)
ControlCommand("Script Manager", ScriptStart, "Monitor")
elseif($motion = 0)
Goto(start)
Endif


# And end this script
HALT()

Thanks again for everyone's help. Standby though, I'm working on another script, so you know I'll be calling on the community for help.