• Sky
  • Blueberry
  • Slate
  • Blackcurrant
  • Watermelon
  • Strawberry
  • Orange
  • Banana
  • Apple
  • Emerald
  • Chocolate
  • Charcoal
Welcome to OpenComputers

Register now to gain access to all of our features. Once registered and logged in, you will be able to contribute to this site by submitting your own content or replying to existing content. You'll be able to customize your profile, receive reputation points as a reward for submitting content, while also communicating with other members via your own private inbox, plus much more!

This message will be removed once you have signed in.

  • Announcements

    • Lizzy Trickster

      Latest Stable OpenComputers Version   11/26/16

      The latest released version of OpenComputers is version 1.6.1 for MC 1.7.10, 1.8.9, 1.9.4 & 1.10.2. See more information here! Beta/Dev builds can be found at the Jenkins Build Server (ci.cil.li)
  • 0
deace_nuts

Motion sensor isn't working

Question

I have this script that I wrote to control a piston door via redstone and on the other side of the door I have a motion sensor to open the piston door (toggle the redstone signal on). For some reason the motion sensor isn't doing anything, though. I know it's something I did, I'm new to LUA.

 

local component = require("component")
local sides = require("sides")
local event = require("event")
local gpu = component.gpu
local term = require("term")
local rs = component.redstone


-- Config
local delay = 5


while true do
  -- GUI
  term.clear()
  gpu.setForeground(0x00FF00)
  print("--------------------------- ToNELvision MICROSYTEMS ---------------------------\n")

  gpu.setForeground(0xFFFFFF)
  print("Welcome. Please enter one of the displayed commands. It may take a few seconds for the command to be interpreted.\n")

  gpu.setForeground(0xE6AB38)
  print("Open") 
  print("Close")

  gpu.setForeground(0xFFFFFF)

  term.setCursor(1,9)
  local input=io.read()
  if input == "Open" then
     rs.setOutput(side.right, 15)
     os.sleep(delay)
     rs.setOutput(side.right, 0)
  else
     wrong = true
  end


  -- Motion Sensor
  local id, _, x, y, entityName = event.pull("motion")
  rs.setOutput(sides.right, 15)
  os.sleep(delay)
  rs.setOutput(sides.right, 0)
end

 

Share this post


Link to post
Share on other sites

13 answers to this question

  • 1

I'm sorry for the headache rather than the help..

local component = require("component")
local sides = require("sides")
local event = require("event")
local term = require("term")
local thread = require("thread")
local rs = component.redstone
local gpu = component.gpu


-- Config
local delay, isOpen = 5, (rs.getOutput(sides.right) > 0) and true or false
local timer = nil

term.clear()
term.setCursor(1, 1)
gpu.setForeground(0x00FF00)
print("--------------------------- ToNELvision MICROSYTEMS ---------------------------\n")
gpu.setForeground(0xFFFFFF)
print("Welcome. Please enter one of the displayed commands. It may take a few seconds for the command to be interpreted.\n")
gpu.setForeground(0xE6AB38)
print("Open\nClose")
term.setCursor(1, 9)


local inputThread
inputThread = thread.create(function()
    while true do
      local input = term.read(nil, false)
      if type(input) == "string" then
        input = input:sub(1, -2)
      elseif type(input) == "boolean" and input == false then
        print("interrupted")
        inputThread:kill()
      end
      
      term.clearLine()
      
      if input == "open" or input == "Open" then
        if not isOpen then
          rs.setOutput(sides.right, 15)
          isOpen = true
          if timer then event.cancel(timer) end
          timer = event.timer(delay, function()
              if isOpen then
                rs.setOutput(sides.right, 0)
                isOpen = false
                timer = nil
              end
            end)
        end
      elseif input == "close" or input == "Close" then
        if isOpen then
          rs.setOutput(sides.right, 0)
          event.cancel(timer)
          isOpen = false
        end
      elseif input == "quit" or input == "Quit" then
        inputThread:kill()
      end
    end
  end)

local motionThread = thread.create(function()
    while true do
      local _, _, x, y, name = event.pull("motion")
      if not isOpen then
          rs.setOutput(sides.right, 15)
          isOpen = true
          if timer then event.cancel(timer) end
          timer = event.timer(delay, function()
              if isOpen then
                rs.setOutput(sides.right, 0)
                isOpen = false
                timer = nil
              end
            end)
      else
        event.cancel(timer)
        timer = event.timer(delay, function()
              if isOpen then
                rs.setOutput(sides.right, 0)
                isOpen = false
                timer = nil
              end
            end)
      end
    end
  end)

thread.waitForAny({inputThread, motionThread})
print("\nProgram Exit")
os.exit()

Tested... sorry for the headache... :P 

Share this post


Link to post
Share on other sites
  • 1
local component = require("component")
local sides = require("sides")
local event = require("event")
local term = require("term")
local thread = require("thread")
local rs = component.redstone
local gpu = component.gpu


-- Config
local delay = 5

local function open()
  rs.setOutput(sides.right, 15)
  os.sleep(delay)
  rs.setOutput(sides.right, 0)
end


local inputThread
inputThread = thread.create(function()
    while true do
      term.clear()
      term.setCursor(1, 1)
	  gpu.setForeground(0x00FF00)
	  print("--------------------------- ToNELvision MICROSYTEMS ---------------------------\n")
	  gpu.setForeground(0xFFFFFF)
	  print("Welcome. Please enter one of the displayed commands. It may take a few seconds for the command to be interpreted.\n")
      gpu.setForeground(0xE6AB38)
      print("Open\nClose")
      term.setCursor(1, 9)
      
      local input = term.read()
      if input == "open" or input == "Open" then
        open()
      elseif input == "quit" or input == "Quit" then
        inputThread:kill()
      end
    end
  end)

local motionThread = thread.create(function()
    while true do
      local _, _, x, y, name = event.pull("motion")
      open()
    end
  end)

thread.waitForAny({inputThread, motionThread})
print("\nProgram Exit")

This is and example using payonels thread api. I haven't used it yet myself but it is very powerful. Hats off to payonel for this one.

If this example has a bug, (its untested), lets me know the error and ill try to remedy it..

Edited by Molinko
edited to fix open().

Share this post


Link to post
Share on other sites
  • 0

The motion sensor must be in line of sight. Solid blocks and maybe even doors will keep the motion sensor from triggering. From a glance the code seems like it should work as expected...

Share this post


Link to post
Share on other sites
  • 0
45 minutes ago, Molinko said:

The motion sensor must be in line of sight. Solid blocks and maybe even doors will keep the motion sensor from triggering. From a glance the code seems like it should work as expected...

hmm, then maybe the sensitivity is too low? How can I change that?

The sensitivity is fine actually. I don't know what's up with it. I ran it as it's own script and it worked (mind you it didn't keep a solid redstone output, so the piston kept moving.) so maybe it has something to do with how I structured it. Is it my "While true do"?

Share this post


Link to post
Share on other sites
  • 0
8 hours ago, Gorzoid said:

io.read() is a blocking call, you either need to remove that input or use one of the coroutine APIs like threads to run both at the "same" time.

I replaced io.read() with event.pull() and now the motion sensor works perfectly. Though now I can't enter anything to open the door, so clearly I used the wrong call, right?

Share this post


Link to post
Share on other sites
  • 0
6 hours ago, Molinko said:

local component = require("component")
local sides = require("sides")
local event = require("event")
local term = require("term")
local thread = require("thread")
local rs = component.redstone
local gpu = component.gpu


-- Config
local delay = 5

local function open()
  rs.setOutput(side.right, 15)
  os.sleep(delay)
  rs.setOutput(side.right, 0)
end


local inputThread
inputThread = thread.create(function()
    while true do
      term.clear()
      term.setCursor(1, 1)
	  gpu.setForeground(0x00FF00)
	  print("--------------------------- ToNELvision MICROSYTEMS ---------------------------\n")
	  gpu.setForeground(0xFFFFFF)
	  print("Welcome. Please enter one of the displayed commands. It may take a few seconds for the command to be interpreted.\n")
      gpu.setForeground(0xE6AB38)
      print("Open\nClose")
      term.setCursor(1, 9)
      
      local input = term.read()
      if input == "open" or input == "Open" then
        open()
      end
      
      if input == "quit" or input == "Quit" then
        inputThread:kill()
      end
    end
  end)

local motionThread = thread.create(function()
    while true do
      local _, _, x, y, name = event.pull("motion")
      open()
    end
  end)

thread.waitForAny({inputThread, motionThread})
print("\nProgram Exit")

This is and example using payonels thread api. I haven't used it yet myself but it is very powerful. Hats off to payonel for this one.

If this example has a bug, (its untested), lets me know the error and ill try to remedy it..

Wow, thank you so much for doing this! Though it looks like for some reason it can't find the thread library, is that a non-included library?

sddsdsdssd.PNG

Share this post


Link to post
Share on other sites
  • 0

The thread library is included in later versions of openos. Check the forums for openos updater. Download it with internet card. Install it. Lemme know how it goes. :)

 

Share this post


Link to post
Share on other sites
  • 0
1 hour ago, Molinko said:

The thread library is included in later versions of openos. Check the forums for openos updater. Download it with internet card. Install it. Lemme know how it goes. :)

 

I see, I've noticed that the motion sensor works, but neither Open nor Quit does anything.

Share this post


Link to post
Share on other sites
  • 0
3 hours ago, deace_nuts said:

I see, I've noticed that the motion sensor works, but neither Open nor Quit does anything.

I edited the original script in my post. I'm confident I fixed open() however I'm not sure if threads can call thread:kill() from within themselves.. So quitting may still be bugged :/

Share this post


Link to post
Share on other sites
  • 0
27 minutes ago, Molinko said:

I edited the original script in my post. I'm confident I fixed open() however I'm not sure if threads can call thread:kill() from within themselves.. So quitting may still be bugged :/

Open and quit still don't do anything.

Share this post


Link to post
Share on other sites
  • 0
18 hours ago, Molinko said:

I'm sorry for the headache rather than the help..


local component = require("component")
local sides = require("sides")
local event = require("event")
local term = require("term")
local thread = require("thread")
local rs = component.redstone
local gpu = component.gpu


-- Config
local delay, isOpen = 5, (rs.getOutput(sides.right) > 0) and true or false
local timer = nil

term.clear()
term.setCursor(1, 1)
gpu.setForeground(0x00FF00)
print("--------------------------- ToNELvision MICROSYTEMS ---------------------------\n")
gpu.setForeground(0xFFFFFF)
print("Welcome. Please enter one of the displayed commands. It may take a few seconds for the command to be interpreted.\n")
gpu.setForeground(0xE6AB38)
print("Open\nClose")
term.setCursor(1, 9)


local inputThread
inputThread = thread.create(function()
    while true do
      local input = term.read(nil, false)
      if type(input) == "string" then
        input = input:sub(1, -2)
      elseif type(input) == "boolean" and input == false then
        print("interrupted")
        inputThread:kill()
      end
      
      term.clearLine()
      
      if input == "open" or input == "Open" then
        if not isOpen then
          rs.setOutput(sides.right, 15)
          isOpen = true
          if timer then event.cancel(timer) end
          timer = event.timer(delay, function()
              if isOpen then
                rs.setOutput(sides.right, 0)
                isOpen = false
                timer = nil
              end
            end)
        end
      elseif input == "close" or input == "Close" then
        if isOpen then
          rs.setOutput(sides.right, 0)
          event.cancel(timer)
          isOpen = false
        end
      elseif input == "quit" or input == "Quit" then
        inputThread:kill()
      end
    end
  end)

local motionThread = thread.create(function()
    while true do
      local _, _, x, y, name = event.pull("motion")
      if not isOpen then
          rs.setOutput(sides.right, 15)
          isOpen = true
          if timer then event.cancel(timer) end
          timer = event.timer(delay, function()
              if isOpen then
                rs.setOutput(sides.right, 0)
                isOpen = false
                timer = nil
              end
            end)
      else
        event.cancel(timer)
        timer = event.timer(delay, function()
              if isOpen then
                rs.setOutput(sides.right, 0)
                isOpen = false
                timer = nil
              end
            end)
      end
    end
  end)

thread.waitForAny({inputThread, motionThread})
print("\nProgram Exit")
os.exit()

Tested... sorry for the headache... :P 

That works fantastic, thank you! :D

Share this post


Link to post
Share on other sites
  • 0
On 09/08/2017 at 10:08 PM, Molinko said:

I edited the original script in my post. I'm confident I fixed open() however I'm not sure if threads can call thread:kill() from within themselves.. So quitting may still be bugged :/

Why not just return

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now