This is a read-only snapshot of the ComputerCraft forums, taken in April 2020.
Cavious's profile picture

Multi-Monitor "monitor_touch" Event Issue

Started by Cavious, 18 June 2014 - 06:36 PM
Cavious #1
Posted 18 June 2014 - 08:36 PM
To Whomever Can Assist,

I am working on a multi-monitor input program and peripheral set. Each monitor should be able to perform the same task, and will display the same information. However, I am running into an issue where I can't get an os.eventPull out of any of my monitors.

What I Know
I am already under the impression that with a single monitor, if I want input(xPos and yPos) all I need to do is call those variables.

The Question
Is this the same thing for the multi-monitors? Or do I NEED to pull the event from specific "sides"(aka monitors on the network). They all do the same thing, a simple keypad, but for some reason I can't get a response out of any of them now.


Here is an example of what I've got:


function redNetSend()
local password = {r = 0, g = 0, b = 0}

local monOne = peripheral.wrap("monitor_0")
local monTwo = peripheral.wrap("monitor_1")
local monThree = peripheral.wrap("monitor_2")
local monFour = peripheral.wrap("monitor_3")

monOne.setTextScale(0.5)
monTwo.setTextScale(0.5)
monThree.setTextScale(0.5)
monFour.setTextScale(0.5)

while(true) do
  monOne.clear()
  monTwo.clear()
  monThree.clear()
  monFour.clear()
 
  drawImage(monOne, ".background", 1, 1)
  drawImage(monTwo, ".background", 1, 1)
  drawImage(monThree, ".background", 1, 1)
  drawImage(monFour, ".background", 1, 1)
 
  drawText(monOne, "SUBMIT", 5, 8, colors.orange, colors.white)
  drawText(monTwo, "SUBMIT", 5, 8, colors.orange, colors.white)
  drawText(monThree, "SUBMIT", 5, 8, colors.orange, colors.white)
  drawText(monFour, "SUBMIT", 5, 8, colors.orange, colors.white)
 
  event, side, xPos, yPos = os.pullEvent("monitor_touch")
 
  if(yPos >= 3 or yPos < 6 and xPos == 3 or xPos == 4) then
   password["r"] = "1"
   --FUNCTION HERE
  elseif(yPos >= 3 or yPos < 6 and xPos == 7 or xPos == 8) then
   password["g"] = "1"
   --FUNCTION HERE
  elseif(yPos >= 3 or yPos < 6 and xPos == 11 or xPos == 12) then
  password["b"] = "1"
   --FUNCTION HERE
  elseif(yPos == 8 and xPos >= 5 or xPos < 11) then
   drawText(monOne, "SUBMIT", 5, 8, colors.yellow, colors.white)
   drawText(monTwo, "SUBMIT", 5, 8, colors.yellow, colors.white)
   drawText(monThree, "SUBMIT", 5, 8, colors.yellow, colors.white)
   drawText(monFour, "SUBMIT", 5, 8, colors.yellow, colors.white)
  
   rednet.send(databaseServer, "id_door_topside::"..password[r]..password[g]..password[b])
  
   local id, message, protocol = rednet.receive()
   if(message == ".successful") then
    redstone.setOutput(side, true)
    os.sleep(10)
    if(redstone.getOutput(side) == true) then
	 redstone.setOutput(side, false)
    end
   end
  
   os.sleep(1)
   --FUNCTION HERE
  end
end
end

There is a lot more to the program, and the function is being called by the Parallel API. I'll include the remainder of the lua file in a link via pastebin, just encase the issue I am running into is somewhere else.

http://pastebin.com/xziyE8cW

Thank you in advance,

Donald R. Valverde (Cavious)
Edited on 18 June 2014 - 08:32 PM
Lyqyd #2
Posted 18 June 2014 - 10:10 PM
What evidence are you basing your assertion that you aren't getting events on? Your conditionals for button clicks are flawed and the initial conditional that sets password.r will always be the one that gets executed. You should be using ands instead of ors in those conditionals.
Cavious #3
Posted 18 June 2014 - 10:28 PM
The following are locations as to where the buttons are drawn. I should of included, my buttons are not term drawn, and are instead cutouts using the "paint" program. I draw them on there and then print the buttons to the screen using my drawText function.

I noticed that not one of the monitors will change whenever I press the "SUBMIT" location/button. I have them set to change color(From Orange to Yellow) whenever I press those coords as an indicator.

  event, side, xPos, yPos = os.pullEvent("monitor_touch")
 
  if(yPos >= 3 or yPos < 6 and xPos == 3 or xPos == 4) then
   password["r"] = "1"
   --FUNCTION HERE
  elseif(yPos >= 3 or yPos < 6 and xPos == 7 or xPos == 8) then
   password["g"] = "1"
   --FUNCTION HERE
  elseif(yPos >= 3 or yPos < 6 and xPos == 11 or xPos == 12) then
  password["b"] = "1"
   --FUNCTION HERE
  elseif(yPos == 8 and xPos >= 5 or xPos < 11) then
   drawText(monOne, "SUBMIT", 5, 8, colors.yellow, colors.white)
   drawText(monTwo, "SUBMIT", 5, 8, colors.yellow, colors.white)
   drawText(monThree, "SUBMIT", 5, 8, colors.yellow, colors.white)
   drawText(monFour, "SUBMIT", 5, 8, colors.yellow, colors.white)
  
   rednet.send(databaseServer, "id_door_topside::"..password[r]..password[g]..password[b])
  
   local id, message, protocol = rednet.receive()
   if(message == ".successful") then
    redstone.setOutput(side, true)
    os.sleep(10)
    if(redstone.getOutput(side) == true) then
	 redstone.setOutput(side, false)
    end
   end
  
   os.sleep(1)
   --FUNCTION HERE
  end

Since the buttons I have down are three(3) rows by two(2) columns I need those locations if pressed to respond to the IF statements. I've done something similar to this on another program is and it works gloriously.

From the feel of the program it's almost like it doesn't know what monitor to accept the xPos or yPos information from. I tried changing it but still no monitor responds to the event. So far my issue isn't with the drawn button displacement as much as it is with getting an event. I setup a seperate monitor and attempted to get debug information from it. I set the monitor to receive the xPos and yPos, but it doesn't receive anything.

Example of my buttons:
===================
| [ ] [ ] [ ] |
| [ ] [ ] [ ] |
| [ ] [ ] [ ] |
| |
| [SUBMIT] |
| |
===================
If you know of a way to improve button events, I am always open to suggestions.
Edited on 18 June 2014 - 08:31 PM
Cavious #4
Posted 19 June 2014 - 12:16 AM
I see what you are saying about the conditionals. I didn't even notice. The yPos needed to be an "and" whereas I had a "or".

Disregard my question unless you have some advise as to how to improve what I have written. Sadly, my company, we host a server called GotBawlz, and I was doing all this in survival mode, and… *Boom* went the dynamite, as a creeper blew my entire setup away. Just glad pastebin can't be blown up by a creeper.

I'll set the title as solved, as I have no way of testing my program at the moment.

Thank you for your help Lyqyd.
Edited on 18 June 2014 - 10:40 PM
Agoldfish #5
Posted 19 June 2014 - 12:33 AM
Thank you for your help Lyqyd*.
Cavious #6
Posted 19 June 2014 - 12:41 AM
Thank you for your help Lyqyd*.

Good save… lol
theoriginalbit #7
Posted 19 June 2014 - 03:37 AM
Just glad pastebin can't be blown up by a creeper.
neither do the files on the server. you can always locate the computers files in the world save under the `computer` folder.
Bomb Bloke #8
Posted 19 June 2014 - 03:45 AM
When you get a monitor_touch event, that includes data indicating which monitor it came from. Given that you knew the identity of the monitor when you wrapped it, when dealing with multiple monitors at once you merely need to compare these identities to ensure you're paying attention to the correct one.

For example, when I wrap a monitor, I store the name of its "side" within the table that's returned. (It's doesn't have to go in there specifically, I just see that as the most suitable place for it.) The code's along these lines:

local mon1 = peripheral.wrap("monitor_0")
mon1.side = "monitor_0"

Now when I go to check a given click, I might use code along these lines:

event, side, xPos, yPos = os.pullEvent("monitor_touch")  -- This responds to a touch from any connected display, wrapped or otherwise.

if yPos >= 3 and yPos < 6 and (xPos == 3 or xPos == 4) and side == mon1.side then

Both of the scripts linked in my signature have similar sorts of examples, though they're geared for single-monitor situations (the idea being to ignore clicks from any connected monitors that the scripts aren't rendering to).

By the by, I'm fairly sure you're not wanting to do this:

event, side, xPos, yPos = os.pullEvent("monitor_touch")
.
.
.
redstone.setOutput(side, true)
Edited on 19 June 2014 - 01:50 AM
Cavious #9
Posted 19 June 2014 - 09:25 PM
The issue I ran into with detecting the side, is they are all on a wired network. Therefore the side is relative to the side the modem is on. Given they all have a name("monitor_0", etc..), I figured I could get them to work individually.

Once I got them rebuilt they worked well. I didn't even notice I set the conditionals to 'or' rather then the needed 'and'. Error on my part of course.

Thanks to you all for assistance,

Donald R. Valverde (Cavious)
chrdov #10
Posted 19 June 2014 - 10:04 PM
do you know why the side parameter in "monitor_touch" exists? It exists so that you can check to see if the name/side matches a given string.

For Example, Assuming you have 2 monitors, one named monitor_0, one named monitor_1:


while true do
event, side, xTouched, yTouched = os.pullEvent("monitor_touch")
if side == "monitor_0" then
-- Code Goes Here
elseif side == "monitor_1" then
-- Code Goes Here
end

edit: Too late, I guess.
Edited on 19 June 2014 - 08:05 PM