Connecting Ultrasonic sensor to trigger Servo moto...
# help
d
import gpio import i2c import gpio.pwm TRIGGER ::= 21 ECHO ::= 22 measure_distance trigger echo: trigger_start := Time.monotonic_us trigger.set 1 while Time.monotonic_us < trigger_start + 10: // Do nothing while waiting for the 10us. trigger.set 0 while echo.get != 1: null echo_start := Time.monotonic_us while echo.get == 1: null echo_end := Time.monotonic_us diff := echo_end - echo_start return diff / 58 main: trigger := gpio.Pin TRIGGER --output echo := gpio.Pin ECHO --input while true: print "measured $(measure_distance trigger echo)cm" sleep --ms=50 if measure_distance trigger echo = 20: print "DOOR OPEN" else: print "DOOR LOCKED" servo := gpio.Pin 14 generator := pwm.Pwm --frequency=50 channel := generator.start servo --duty_factor=0.075 sleep --ms=10 // https://github.com/toitlang/toit/issues/518 // Max angle. channel.set_duty_factor 0.125 sleep --ms=2000 // Min angle. channel.set_duty_factor 0.025 sleep --ms=200
f
Please use tripple backticks to make the code look nicer:
Copy code
text in tripple ` looks like code.
You should be able to edit your post.
Now to making that program work: - do you read the distance correctly? You have a
print
there. Does it show the distance correctly? If the
DOOR OPEN
and
DOOR LOCKED
are shown correctly, then you are almost there.
You just need to use that information for an angle (== duty factor) of the servo.
Wait. I can see that the code won't work.
measure_distance trigger echo = 20
is an assignment, not a comparison.
You need to write
(measure_distance trigger echo) == 20
d
we are also getting an error when we jag monitor, because it says failed due to bad authentication, so it wont even print
this is the new error we are receiving
f
Jaguar seems to work just fine.
However, the program you are writing still has errors, and can't be compiled yet.
After the condition (
== 20
) you are now missing a
:
.
d
its supposed to an automatic door system
f
I understand.
Try with the following code. I didn't actually test it, so there might still be bugs in there.
Copy code
main:
  trigger := gpio.Pin TRIGGER --output 
  echo := gpio.Pin ECHO --input

  servo := gpio.Pin 14
  generator := pwm.Pwm --frequency=50
  channel := generator.start servo --duty_factor=0.075
  
  while true:
    distance := measure_distance trigger echo
    print "measured $(distance)cm"

    if distance <= 200:
      print "DOOR OPEN"
      channel.set_duty_factor 0.125  // Max angle.
    else: 
      print "DOOR LOCKED"
      channel.set_duty_factor 0.025   // Min angle.

    // The sleep can be lower (or even be removed), but while
    // we are printing, we don't want the loop to run too
    // quickly.
    sleep --ms=500
d
now it compiling without errors but it does not seem to trigger the hardware
f
Start your main with a
print "starting"
.
This way you know if the program is arriving correctly.
Either way: what's the output of the console/monitor?
d
thats the result when i jag monitor
f
ok. But what happens now, if you take another terminal and do
jag run
(while
jag monitor
is still running).
d
when i do that, it prints starting
and thats all
f
So it only prints the first line of your
main
?
where you have
print "starting"
?
d
nope actually its reads the whole code but it runs it once and if the distance is not wat we specified it prints door locked yet we want it to loop until it reads the specified distance and then open the door and after it locks it back.
f
Can you show me the code you are using now?
d
import gpio import i2c import gpio.pwm TRIGGER ::= 21 ECHO ::= 22 measure_distance trigger echo: trigger_start := Time.monotonic_us trigger.set 1 while Time.monotonic_us < trigger_start + 10: // Do nothing while waiting for the 10us. trigger.set 0 while echo.get != 1: null echo_start := Time.monotonic_us while echo.get == 1: null echo_end := Time.monotonic_us diff := echo_end - echo_start return diff / 58 main: print "starting" trigger := gpio.Pin TRIGGER --output echo := gpio.Pin ECHO --input while true: print "measured $(measure_distance trigger echo)cm" sleep --ms=50 if (measure_distance trigger echo) == 200: print "DOOR OPEN" else: print "DOOR LOCKED" servo := gpio.Pin 14 generator := pwm.Pwm --frequency=50 channel := generator.start servo --duty_factor=0.075 sleep --ms=10 // Max angle. channel.set_duty_factor 0.125 sleep --ms=2000 // Min angle. channel.set_duty_factor 0.025 sleep --ms=200
and its also not triggering the servo motor
f
Please send code in triple quotes.
you can edit your post to put the code into quotes.
Otherwise it's hard to see indentation.
d
"""import gpio import i2c import gpio.pwm TRIGGER ::= 21 ECHO ::= 22 measure_distance trigger echo: trigger_start := Time.monotonic_us trigger.set 1 while Time.monotonic_us < trigger_start + 10: // Do nothing while waiting for the 10us. trigger.set 0 while echo.get != 1: null echo_start := Time.monotonic_us while echo.get == 1: null echo_end := Time.monotonic_us diff := echo_end - echo_start return diff / 58 main: print "starting" trigger := gpio.Pin TRIGGER --output echo := gpio.Pin ECHO --input while true: print "measured $(measure_distance trigger echo)cm" sleep --ms=50 if (measure_distance trigger echo) == 200: print "DOOR OPEN" else: print "DOOR LOCKED" servo := gpio.Pin 14 generator := pwm.Pwm --frequency=50 channel := generator.start servo --duty_factor=0.075 sleep --ms=10 // https://github.com/toitlang/toit/issues/518 // Max angle. channel.set_duty_factor 0.125 sleep --ms=2000 // Min angle. channel.set_duty_factor 0.025 sleep --ms=200"""
f
You have to use backticks:
Copy code
` (three times)
I sent a screenshot earlier.
d
Copy code
import gpio
import i2c
import gpio.pwm

TRIGGER ::= 21
ECHO ::= 22

measure_distance trigger echo: 
  trigger_start := Time.monotonic_us 
  trigger.set 1
  while Time.monotonic_us < trigger_start + 10:
     // Do nothing while waiting for the 10us.
  trigger.set 0

  while echo.get != 1: null 
  echo_start := Time.monotonic_us
  while echo.get == 1: null

  echo_end := Time.monotonic_us 
  diff := echo_end - echo_start 
  return diff / 58

main:
  print "starting"
  trigger := gpio.Pin TRIGGER --output 
  echo := gpio.Pin ECHO --input
  while true:
    print "measured $(measure_distance trigger echo)cm"
    sleep --ms=50

    if (measure_distance trigger echo) == 200:
      print "DOOR OPEN"

    else: 
      print "DOOR LOCKED"

  servo := gpio.Pin 14

  generator := pwm.Pwm --frequency=50

  channel := generator.start servo --duty_factor=0.075

  sleep --ms=10 
  // https://github.com/toitlang/toit/issues/518


  // Max angle.

  channel.set_duty_factor 0.125

  sleep --ms=2000


  // Min angle.

  channel.set_duty_factor 0.025

  sleep --ms=200
finally
f
🙂
That code should run the distance measurement every 50ms and print "DOOR OPEN" or "DOOR LOCKED" continuously.
depending on whether the distance is more or less than 200cm.
Is that correct?
Should also print the measured distance before the "DOOR ..." line.
d
yes but we want the servo motor to move when its open and close when its locked
f
I understand.
d
the code is just measuring and printing
f
That's because the rest (servo code) is outside the
while true
loop.
and is thus never reached.
You need to put the servo code into the while body.
d
now we want if the distance criteria is not met to open the door, we want the sensor to stay locked but the sensor to keep measuring until an object is with in range to trigger an opening
f
it should do that already.
It's continuously measuring the distance and updating accordingly.
You could introduce a boolean state, to only set the generator's duty_factor when the state changes, but it doesn't really cost to set the factor to the same value it already is.
That said: if you keep a boolean variable, you could only print "DOOR OPEN" or "DOOR LOCKED" when the state changes.
Also: you probably want to avoid to be in a state where the distance is just about 200cm and changes very frequently.
So you should maybe open the door when something is closer than 190cm, but only close it when you measure something more than 210cm away.
d
but the door doesnt close after it opens, we want it to close after 180ms
how can it get closed when something is 210cm away
f
Just to summarize:
the code is running and continuously printing "DOOR OPEN" or "DOOR LOCKED".
But the servo is not changing according to the state?
d
the code is running perfectly, well the servo opens but does not close back after the object is through
f
So when the code prints "DOOR LOCKED" the servo does not move?
d
yes
f
please show me again the code you are using.
d
sorry no, the code prints open but does not close back after that
f
What about the distance measurement?
Do you see the measured distance change?
d
yes
somewhere its now showing brown out detector triggered
f
That means that not enough power is provided, or that you have a short-circuit.
can be a bad USB cable too.
d
okay
f
So you see the distance that is measured going from above 200cm to below 200cm, but it's still printing "DOOR OPEN" ?
Another reason for brown-out is if you set the duty-factor to a value that blocks the servo motor.
The servo can only work in a certain range, and if you use values that are out of that range it will consume too much current.
d
its now working well sir
thanks alot