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

Wireless modem transmit help

Started by yhm, 06 November 2013 - 05:40 AM
yhm #1
Posted 06 November 2013 - 06:40 AM
I am going to make a station which, when an empty cart comes, the computer will automatically sleep for 60 seconds, with a message printed to the monitor every 10 seconds. After 60 seconds, the computer should be able to emit a redstone signal so that the cart will depart.



In the above picture, you can see there is two computers, labeled as computer A and B. When an empty cart arrives, there will be a redstone signal to the front of the computer A. Then, computer A will transmit a message through the wireless modem attached to its back to computer B. The message is Display. Computer B will listen for the message. Then, computer B will output the sentence "x seconds left to departure.". The sentence will be outputted to the monitor attached to its back and outputted at 60, 50, 40, 30, 20, 10 and 0 second(s) left. After outputting, computer B will send a message to computer A. The message is 0. When computer A receives the message, computer A sends a redstone signal to its left side, which is the thing in the lower left corner in the above picture.

Problem:
Both computers have NO communication between each other. Computer B cannot receive any message from computer A (tested by echo checking e.g. outputting message to console), thus computer B cannot send any message to computer A also.

Program codes:
For computer A (program name is depart)

local modem = perihperal.wrap("back")
modem.open(1)
function listen()
modem.transmit(1, 1, "Display")
local event, modemSide, senderChannel, replyChannel, message, senderDistance = os.pullEvent("modem_message")
if message == "0" then
  redstone.setOutput("left", true)
  os.sleep(0.5)
  redstone.setOutput("left", false)
end
end
function execute()
if redstone.getInput("front") == true then
  listen()
end
while true do
  r = os.pullEvent()
  if r == "Redstone" then
   if redstone.getInput("front") == true then
	listen()
   end
  end
end
end
function waitForEsc()
while true do
  local e, key = os.pullEvent("key")
  if key ~= 1 then
   return true
  end
end
end
parallel.waitForAny(function() execute() end, function() waitForEsc() end)

For computer B (program name is departout)

local modem = peripheral.wrap("right")
local monitor = peripheral.wrap("back")
modem.open(1)
function out(count)
monitor.write(count, "seconds left to departure.")
end
function rstick()
local counter = 60
while counter > 0 do
  out(count)
  os.sleep(10)
  counter = counter - 10
end
modem.transmit(1, 1, "0")
end
function execute()
while true do
  local event, modemSide, senderChannel, replyChannel, message, senderDistance = os.pullEvent("modem_message")
  if message = "Display" then
   rstick()
  end
end
end
function waitForEsc()
while true do
  local e, key = os.pullEvent("key")
  if key ~= 1 then
   return true
  end
end
end
parallel.waitForAny(function() execute() end, function() waitForEsc() end)

Thank you very much for helping.
Lyqyd #2
Posted 06 November 2013 - 08:36 PM
Split into new topic.
spdkils #3
Posted 06 November 2013 - 11:20 PM
Why are you not just looping redstone.getInput("front")?

why pull the event, and pull the front, and do one with a loop and the other without?

function execute()
if redstone.getInput("front") == true then
  listen()
end
while true do
  r = os.pullEvent()
  if r == "Redstone" then
   if redstone.getInput("front") == true then
		listen()
   end
  end
end
end

Simplify


function execute()
while true do
   if redstone.getInput("front") == true then
		listen()
   end
end
end

or just do it with an event


function execute()
while true do
r = os.pullEvent('redstone') --@ note the lack of a capital R!
if r then
   if redstone.getInput("front") == true then
		listen()
   end
end
end
end

Also, I'm not really sure why have have listen broken out at all. it's only doing 1 thing. I would have both those in 1 loop. and while we're at it? Why not handle the break too?


function execute()
while true do
tEvent = {os.pullEvent()}
if tEvent[1] == 'redstone' then
   if redstone.getInput("front") == true then
		-- nothing we ALWAYS listening.
   end
elseif tEvent[1] == 'modem_message' then
  modem.transmit(1, 1, "Display")
if tEvent[5] == 0 then
  redstone.setOutput("left", true)
  os.sleep(0.5)
  redstone.setOutput("left", false)
end
elseif tEvent[1] == 'key' and tEvent[2] ~= 1 then
return true
end
end
end

Now I didn't check my code, but it seems far easier to just have a single event loop, and do what you need in response to any of the events, just using elseIf.
Edited on 06 November 2013 - 10:33 PM
yhm #4
Posted 07 November 2013 - 06:54 AM
Why are you not just looping redstone.getInput("front")?

why pull the event, and pull the front, and do one with a loop and the other without?

function execute()
if redstone.getInput("front") == true then
  listen()
end
while true do
  r = os.pullEvent()
  if r == "Redstone" then
   if redstone.getInput("front") == true then
		listen()
   end
  end
end
end

Simplify


function execute()
while true do
   if redstone.getInput("front") == true then
		listen()
   end
end
end

or just do it with an event


function execute()
while true do
r = os.pullEvent('redstone') --@ note the lack of a capital R!
if r then
   if redstone.getInput("front") == true then
		listen()
   end
end
end
end

Also, I'm not really sure why have have listen broken out at all. it's only doing 1 thing. I would have both those in 1 loop. and while we're at it? Why not handle the break too?


function execute()
while true do
tEvent = {os.pullEvent()}
if tEvent[1] == 'redstone' then
   if redstone.getInput("front") == true then
		-- nothing we ALWAYS listening.
   end
elseif tEvent[1] == 'modem_message' then
  modem.transmit(1, 1, "Display")
if tEvent[5] == 0 then
  redstone.setOutput("left", true)
  os.sleep(0.5)
  redstone.setOutput("left", false)
end
elseif tEvent[1] == 'key' and tEvent[2] ~= 1 then
return true
end
end
end

Now I didn't check my code, but it seems far easier to just have a single event loop, and do what you need in response to any of the events, just using elseIf.

Firstly, I want to sicerely thank you for your help. My logic is really bad.
Since the server is closed now, I will have to wait for the server to open so that I can test your code.
Your code is far simpler than my code, and I am quite sure that your code will be likely to succeed.
If there is any problem, please do not mind me replying or PM to you.
Once again I appreciate your help very much.
Nickinator68 #5
Posted 12 November 2013 - 05:05 AM
So I'm not so great at ComputerCraft yet but I did notice a lot easier of a fix then this other guy proposed. I noticed that you spelled peripheral as "perihperal" in your first line of code on Computer A. Sometimes the lamest mistakes can get the best of anyone. It's like forgetting a negative when doing a huge math problem… makes you feel cheated. Anyway, I hope that helps.
tchoutchawn #6
Posted 13 November 2013 - 01:03 AM
Just a quick hint: If you can, you should use the monitor instead of a second computer just to show a message. Also, it would be easier especially with wired modems.


01  local event, modemSide, senderChannel, replyChannel, message, senderDistance = os.pullEvent("modem_message")
02  if message (((=))) "Display" then
03   rstick()
04  end

On line 02, the "=" won't do what you want, change it for "==".


01  local event, modemSide, senderChannel, replyChannel, message, senderDistance = os.pullEvent("modem_message")
02  if message == "Display" then
03   rstick()
04  end
yhm #7
Posted 16 November 2013 - 08:07 AM
So I'm not so great at ComputerCraft yet but I did notice a lot easier of a fix then this other guy proposed. I noticed that you spelled peripheral as "perihperal" in your first line of code on Computer A. Sometimes the lamest mistakes can get the best of anyone. It's like forgetting a negative when doing a huge math problem… makes you feel cheated. Anyway, I hope that helps.

Just a quick hint: If you can, you should use the monitor instead of a second computer just to show a message. Also, it would be easier especially with wired modems.


01  local event, modemSide, senderChannel, replyChannel, message, senderDistance = os.pullEvent("modem_message")
02  if message (((=))) "Display" then
03   rstick()
04  end

On line 02, the "=" won't do what you want, change it for "==".


01  local event, modemSide, senderChannel, replyChannel, message, senderDistance = os.pullEvent("modem_message")
02  if message == "Display" then
03   rstick()
04  end

Sorry for my late reply.
As I type the code from my Minecraft to this forum in a fast pace, sometimes I may type the words wrongly in the code here but not in Minecraft (since if I spell the words wrongly / missing "=", the compiler should warn me (like "then expected" etc.)
After double checking, I have made sure that I have two "=" s and "peripheral" is spelt correctly.
But anyway I will be aware of this kind of typo next time. Thank you for reminding me.
Edited on 16 November 2013 - 07:10 AM