Перейти к содержимому
  • 0
Koteyk0o

Cетевая карта и редстоун

Вопрос

В общем когда в комп по сети отправлена команда "LampON", то он должен мигать лампой которая подключена к нему бандлед кабелем.

Команда принимается, все ок, но это нельзя выключить

когда подается команда "LampOFF" компьютер на нее не реагирует, пока не убьешь цикл мигания

В чем косяк?

Подскажите пожалуйста, какая у меня ошибка в моем коде  говнокоде))

local component = require("component")
local event = require("event")
local m = component.modem 
local rs = component.redstone

m.open(27) -- открываем порт 

rs.setBundledOutput(4,0,0) -- вырубаем все сигналы
rs.setBundledOutput(4,3,0)
rs.setBundledOutput(4,9,0)
rs.setBundledOutput(4,15,0)
rs.setBundledOutput(4,1,0)
rs.setBundledOutput(4,4,0)
rs.setBundledOutput(4,14,0)
rs.setBundledOutput(4,6,0)
os.sleep(0.2)
m.broadcast(80,'Компьютер загружен') -- сообщаем главному компьютеру о загрузке

while true do
local _, _, from, port, _, message = event.pull("modem_message")
print("Got a message from " .. from .. " on port " .. port .. ": " .. tostring(message))

if message == 'LampON' then -- значение переменной 1
lampstatus = 1
end

if message == 'LampOFF' then -- значение переменной 0
lampstatus = 0
end

while lampstatus > 0 do -- если переменная больше нуля, то мигаем
rs.setBundledOutput(4,4,255)
os.sleep(0.4)
rs.setBundledOutput(4,4,0)
os.sleep(0.3)
end

end
Изменено пользователем Koteyk0o

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Рекомендуемые сообщения

  • 0

И слипы тут использовать уже нельзя иначе событие от модема может быть пропущено. Таймаут должен задаваться первым параметром функции pull.

Т.е. алгоритм должен быть где то таким:

while true do
  Ждем событие от модема в течение времени 0.5 сек
  Если пришло "LampON", blink = true
  Если пришло "LampOFF", blink = false
  Если blink == true             -- настоящие программеры пишут просто blink --
     изменяем состояние лампы    -- именно изменяем, а не включаем, ждем, выключаем и снова ждем --
  иначе выключаем лампу
end

А можно использовать слушателя или многопоточность, но это на крайний случай.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
  • 0

Когда твоя программа входит в цикл мигания - она там и остаётся. Потому что цикл while выполняется, пока верно его условие. А условие не становится неверным, и соответственно, цикл повторяется вновь, и вновь, и вновь.

 

Предлагаю заменить цикл на условие - if lampstatus > 0 then. Тогда лампа мигнёт один раз, и вернётся у прослушиванию эвентов и сможет услышать эвент от модема на выключение, если что.

А чтобы лампа мигала постоянно, предлагаю снизить время ожидания эвентов в том случае, если выполняется условие мигания. Тогда программа будет проверять эвенты, мигать, потом снова проверять эвенты, потом снова мигать.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
  • 0

А чтобы лампа мигала постоянно, предлагаю снизить время ожидания эвентов в том случае, если выполняется условие мигания. Тогда программа будет проверять эвенты, мигать, потом снова проверять эвенты, потом снова мигать.

Спасибо за разъяснение, но как я понимаю она будет мигать тогда, когда будет команда на включение

И выходит придется постоянно подавать команду на включение?

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
  • 0

Спасибо за разъяснение, но как я понимаю она будет мигать тогда, когда будет команда на включение

И выходит придется постоянно подавать команду на включение?

 

Нет. У тебя же есть флаг, который отвечает за то, что хранит инфу о том, надо мигать или нет.

Тут можно даже использовать логическое значение: local blink = false.

Когда получаешь соообщение на включение - переключаешь флаг на true.

 

А дальше главный цикл начинает выглядеть так (условно):

 

* проверили эвенты

* если эвент на включение - blink = true

* если эвент на выключение - blink = false

* if blink then  мигаем один раз  end

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
  • 0

Нет. У тебя же есть флаг, который отвечает за то, что хранит инфу о том, надо мигать или нет.

Тут можно даже использовать логическое значение: local blink = false.

Когда получаешь соообщение на включение - переключаешь флаг на true.

 

А дальше главный цикл начинает выглядеть так (условно):

 

* проверили эвенты

* если эвент на включение - blink = true

* если эвент на выключение - blink = false

* if blink then  мигаем один раз  end

В таком случае лампа мигает один раз, и на этом все

А необходимо сделать так, что когда blink = true лампа мигает бесконечное кол-во раз, пока не будет эвента на выключение, то-есть blink = false

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
  • 0

В таком случае лампа мигает один раз, и на этом все

А необходимо сделать так, что когда blink = true лампа мигает бесконечное кол-во раз, пока не будет эвента на выключение, то-есть blink = false

 

Ты меня не слушаешь.

blink - это не эвент. Это переменная с флагом. Она сохраняет своё состояние. Пока в переменной находится значение true - лампа будет мигать.

Потому что главный цикл повторяется снова и снова.

А чтобы главный цикл повторялся без задержек - тебе надо модифицировать вызов event.pull() и добавить туда ограничение на время.

Тогда функция будет ждать эвентов пару десятых секунды, затем завершаться, потом будет мигать лампа (один раз), потом снова будет пара десятых секунды ожидания эвентов - а потом снова одно мигание. И так пока ты не сменишь значение флага.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
  • 0

Ты меня не слушаешь.

blink - это не эвент. Это переменная с флагом. Она сохраняет своё состояние. Пока в переменной находится значение true - лампа будет мигать.

Потому что главный цикл повторяется снова и снова.

А чтобы главный цикл повторялся без задержек - тебе надо модифицировать вызов event.pull() и добавить туда ограничение на время.

Тогда функция будет ждать эвентов пару десятых секунды, затем завершаться, потом будет мигать лампа (один раз), потом снова будет пара десятых секунды ожидания эвентов - а потом снова одно мигание. И так пока ты не сменишь значение флага.

Что blink это не эвент а переменная это я понял, просто не так выразился

Я имел ввиду то, что когда эвент blinkOFF, то переменной blink присваивается значение false

 

добавил в event.pull таймаут 0.5 секунд, но все равно комп отказывается видеть команду на выключение, и из-за этого не присваивает переменной blink значение false, и мигание просто не отключается

чувствую себя тупым(((

local component = require("component")
local event = require("event")
local m = component.modem 
local rs = component.redstone
 
m.open(27) -- открываем порт 
 
rs.setBundledOutput(4,0,0) -- вырубаем все сигналы
rs.setBundledOutput(4,3,0)
rs.setBundledOutput(4,9,0)
rs.setBundledOutput(4,15,0)
rs.setBundledOutput(4,1,0)
rs.setBundledOutput(4,4,0)
rs.setBundledOutput(4,14,0)
rs.setBundledOutput(4,6,0)
os.sleep(0.2)
m.broadcast(80,'Компьютер загружен') -- сообщаем главному компьютеру о загрузке
 
while true do
local _, _, from, port, _, message = event.pull(0.5,modem_message)
print('message= ',message)
 
if message == 'LampON' then -- значение переменной 1
local blink = true
end
 
if message == 'LampOFF' then -- значение переменной 0
local blink = false
end
 
if blink == true then -- если переменная больше нуля, то мигаем
rs.setBundledOutput(4,4,255)
os.sleep(0.4)
rs.setBundledOutput(4,4,0)
os.sleep(0.3)
end
 
end
Изменено пользователем Koteyk0o

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
  • 0

if message == 'LampON' then -- значение переменной 1

local blink = true

end

if message == 'LampOFF' then -- значение переменной 0

local blink = false

end

зачем переменную  blink делаешь локальной? Она существует только в пределах ифа где объявлена.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
  • 0

И слипы тут использовать уже нельзя иначе событие от модема может быть пропущено. Таймаут должен задаваться первым параметром функции pull.

Т.е. алгоритм должен быть где то таким:

while true do
  Ждем событие от модема в течение времени 0.5 сек
  Если пришло "LampON", blink = true
  Если пришло "LampOFF", blink = false
  Если blink == true             -- настоящие программеры пишут просто blink --
     изменяем состояние лампы    -- именно изменяем, а не включаем, ждем, выключаем и снова ждем --
  иначе выключаем лампу
end

А можно использовать слушателя или многопоточность, но это на крайний случай.

Спасибо, понял

Получается когда лампа мигает с помощью слипов, и приходит событие от модема, то оно просто пропускается из-за сна системы

Спасибо большое за помощь

Изменено пользователем Koteyk0o

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить на вопрос...

×   Вы вставили отформатированное содержимое.   Удалить форматирование

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отобразить как ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.


×
×
  • Создать...