LINUX.ORG.RU

Fileevent в Tcl


0

1

Не могу разобраться с сабжем. Сейчас общаюсь с ком-портом посредством постоянного поллинга. Работает, но остается ощущение «неправильности». Стоит задача сделать нечто вроде конечного автомата: подаю модему команду, и в зависимости от его ответа выполняю разные действия. С помощью fileevent пытаюсь сделать так:

 
set status 0
set serial [open /dev/ttyS0 r+]
fconfigure $serial -mode "9600,n,8,1" -blocking 0 -buffering none -translation binary
fileevent $serial readable [list serial_receiver $serial]

proc serial_receiver { chan } {
	global status
     if { [eof $chan] } {         
         catch {close $chan}
         return
     }
     set data [read $chan]
     set size [string length $data]	 
 }
 
 switch $status {
		0	{
				puts -nonewline $serial "AT\r"
				set status 1
			}
		1	{
				puts -nonewline $serial "ATI\r"
				set status 2
			}
		2	{
				puts -nonewline $serial "AT+CREG?\r"
				set status 3
			}
		3	{
				puts -nonewline $serial "AT+CPIN?\r"
				set status 0
			}		
	 }
 

В порт подается только первая команда — и все. Что я делаю не так?

Ответ на: комментарий от jtootf

В порт подается только первая команда — и все

то есть?

Ну, в результате работы скрипта в порт подается AT, модем отвечает ОК — и все, ко второму этапу (подаче команды ATI) скрипт не переходит.

Пробовал вставлять switch в тело обработчика serial_receiver — результат тот же.

decadent ()
proc serial_receiver { chan } {
    if { [eof $chan] } {         
         catch {close $chan}
         return
    }
    # чтение ответа
    ...
    # обработка ответа
    ...
    # если нужно, посылка новой команды или запроса
    ...
}
anonymous ()

Ну, в результате работы скрипта в порт подается AT, модем отвечает ОК

Еще. Если скрипт сразу же завершается (не используешь Tk), то в конец скрипта добавь строку типа «vwait forever».

anonymous ()

как минимум наверное нижепроцитированный кусок должен быть обёрнут в цикл. Хотя и с циклом смысл в нём небольшой :)

switch $status {
      0   {
            puts -nonewline $serial "AT\r"
            set status 1
         }
      1   {
            puts -nonewline $serial "ATI\r"
            set status 2
         }
      2   {
            puts -nonewline $serial "AT+CREG?\r"
            set status 3
         }
      3   {
            puts -nonewline $serial "AT+CPIN?\r"
            set status 0
         }   
}

MKuznetsov ★★★★★ ()
Ответ на: комментарий от anonymous
 
proc serial_receiver { chan } {
    if { [eof $chan] } {         
         catch {close $chan}
         return
    }
    # чтение ответа
    ...
    # обработка ответа
    ...
    # если нужно, посылка новой команды или запроса
    ...
}

Спасибо, похоже, что в таком виде работает.

decadent ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.