Выбор порта
Бывают платформы с несколькими последовательными портами. Число последовательных портов, доступных на вашей платформе, можно получить через свойство ser.numofports.
Поскольку портов может быть несколько, при изменении свойств или вызове методов нужно указывать, к какому порту вы обращаетесь. Это делается через свойство ser.num. Например:
ser.mode = PL_SER_MODE_WIEGAND
Можете ли вы сказать, к какому последовательному порту относится приведённый выше оператор? Платформа тоже не может. Поэтому правильный синтаксис такой:
ser.num = 0
ser.mode = PL_SER_MODE_WIEGAND
Теперь платформа знает, с каким портом вы работаете. После того как селектор порта задан (через ser.num), все последующие методы и свойства относятся к этому порту. Таким образом:
ser.num = 0
ser.enabled = 1
ser.baudrate = 1
ser.bits = 1 ' etc
События, генерируемые объектом ser., не разделены по портам. Такое событие, как on_ser_data_arrival, обслуживает все последовательные порты вашей платформы. Поэтому при входе в обработчик события объекта ser. селектор порта автоматически переключается на номер порта, на котором произошло событие:
sub on_ser_data_arrival
dim s as string
s = ser.getdata(255) ' Note that you did not have use ser.num before this statement.
end sub
Из-за этого автоматического переключения, когда обработчик события последовательного порта завершается, свойство ser.num сохраняет новое значение (ничто не возвращает его обратно). Это нужно учитывать при обработке других событий, которые используют последовательный порт (но сами не являются событиями последовательного порта). Другими словами, свойство ser.num следует задавать явно при входе в такой обработчик события, потому что до этого события оно могло быть изменено автоматически. Для наглядности:
sub on_sys_init ' This is always the first event executed.
ser.num = 0 ' Supposedly, this would make all subsequent properties and methods refer to this port.
end sub
sub on_ser_data_arrival ' Then, supposing this event executes.
dim s as string
s = ser.getdata(255) ' However, this event happens on the second port. So now ser.num = 1.
end sub
sub on_sock_data_arrival ' And then this socket event executes.
ser.txclear ' You meant to do this for ser.num = 0 (as specified at on_sys_init). But now port.num was changed to 1.
' You did not explicitly specify a ser.num here, and now the tx buffer for the wrong port is cleared. Oops.
end sub
Те же меры предосторожности нужны при использовании doevents. Дело в том, что doevents позволяет выполняться другим событиям, поэтому могут выполниться события объекта ser. и изменить ser.num.
Подытожим: текущее значение ser.num может изменить только одно из двух: (1) ручное изменение или (2) событие последовательного порта. И нельзя считать, что номер остался прежним, если вы задали его где-то в другом месте (потому что с тех пор могло произойти событие последовательного порта).
Указание номера порта для платформы с одним портом может показаться лишним, но оно делает вашу программу переносимой. Позже вам будет проще перенести её на платформу с несколькими портами.