Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > .NET Frameworks (точка нет фреймворки) > C# (си шарп)
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 20.11.2013, 21:07   #1
alexandrusankov
Новичок
Джуниор
 
Регистрация: 20.11.2013
Сообщений: 2
По умолчанию c# + банальное чтение com port

Доброго вечера, товарищи. Подскажите пожалуйста, по такому вот, несложному вопросу.
Имеется устройство, оно общается с ПК через com(rs232), протокол modbus rtu.
Запускаю штатное ПО, включаю portmon и читаю.
Пытаюсь повторить то же самое на c# - не получается
Могу сформировать запрос, и отправить его, но прочитать - не получается.
Т.е. есть готовый класс SerialPort, подозреваю, что все делается не очень сложно.
Итак, лог портмона ()
Код:
		
IOCTL_SERIAL_SET_BAUD_RATE	MxserB00P000	SUCCESS	Rate: 9600	
IOCTL_SERIAL_CLR_RTS		MxserB00P000	SUCCESS		
IOCTL_SERIAL_CLR_DTR		MxserB00P000	SUCCESS		
IOCTL_SERIAL_SET_LINE_CONTROL	MxserB00P000	SUCCESS	StopBits: 1 Parity: EVEN WordLength: 8	
IOCTL_SERIAL_SET_CHAR		MxserB00P000	SUCCESS	EOF:78 ERR:0 BRK:0 EVT:0 XON:11 XOFF:13	
IOCTL_SERIAL_SET_HANDFLOW	MxserB00P000	SUCCESS	Shake:0 Replace:0 XonLimit:256 XoffLimit:256	
IOCTL_SERIAL_SET_TIMEOUTS	MxserB00P000	SUCCESS	RI:50 RM:2 RC:500 WM:1000 WC:1000	
IRP_MJ_WRITE			MxserB00P000	SUCCESS	Length 8: 01 03 04 D6 00 22 25 1B 	
IRP_MJ_READ			MxserB00P000	SUCCESS	Length 73: 01 03 44 01 1C 78 6B F3 FC 00 D4 00 C2 00 BC 00 B8 00 BC 00 C6 	
IOCTL_SERIAL_WAIT_ON_MASK	MxserB00P000	SUCCESS		
IOCTL_SERIAL_GET_COMMSTATUS	MxserB00P000	SUCCESS		
IOCTL_SERIAL_WAIT_ON_MASK	MxserB00P000	SUCCESS
У меня есть вот что :
Код:
1 |  class Program
2 |  {
3 |   static void Main(string[] args)
4 |   {
5 |    SerialPort myPort = new SerialPort("COM2", 9600, Parity.None, 8, StopBits.One);
6 |    myPort.ReadBufferSize = 1024;
7 |    myPort.WriteBufferSize = 1024;
8 |    byte[] ask = {0x01, 0x03, 0x04, 0xD6, 0x00, 0x22, 0x25, 0x1B};
9 |    myPort.Open();
10|    myPort.Write(ask, 0, ask.Length);
11|    myPort.Close();
12|    Console.Read();
13|   }
14|  }
То есть формирую запрос, и отправляю. В портмоне вижу, что он вроде как отправляется. Но вот как прочитать? Пробовал вот так :
myPort.ReadLine - но программа висит, и в логах портмона тишина.
Какой нюанс я могу пропустить?
P.s. впервые в С#
P.s.s - ответ всегда содержит определенное кол-во байт (21)

Последний раз редактировалось alexandrusankov; 20.11.2013 в 21:09.
alexandrusankov вне форума Ответить с цитированием
Старый 21.11.2013, 07:25   #2
simples
Форумчанин
 
Регистрация: 03.10.2013
Сообщений: 142
По умолчанию

Цитата:
Сообщение от alexandrusankov Посмотреть сообщение
IOCTL_SERIAL_SET_LINE_CONTROL MxserB00P000 SUCCESS StopBits: 1 Parity: EVEN WordLength: 8

Код:
5 |    SerialPort myPort = new SerialPort("COM2", 9600, Parity.None, 8, StopBits.One);
Не знаю поможет или нет - но вижу отличия.
simples вне форума Ответить с цитированием
Старый 21.11.2013, 08:48   #3
raxp
Старожил
 
Регистрация: 29.09.2009
Сообщений: 9,713
По умолчанию

Сформируйте одинаковые запросы и приложите логи вашей и типовой утилиты в теме, сравним.
Разработки и научно-технические публикации :: Видеоблог :: Твиттер
Radar systems engineer & Software developer of industrial automation
raxp вне форума Ответить с цитированием
Старый 21.11.2013, 10:29   #4
alexandrusankov
Новичок
Джуниор
 
Регистрация: 20.11.2013
Сообщений: 2
По умолчанию

Ок, хорошо. Вот логи портмона, как работает штатная утилита :
Код:
IOCTL_SERIAL_SET_BAUD_RATE	MxserB00P000	SUCCESS	Rate: 9600	
IOCTL_SERIAL_CLR_RTS		MxserB00P000	SUCCESS		
IOCTL_SERIAL_CLR_DTR		MxserB00P000	SUCCESS		
IOCTL_SERIAL_SET_LINE_CONTROL	MxserB00P000	SUCCESS	StopBits: 1 Parity: EVEN WordLength: 8	
IOCTL_SERIAL_SET_CHAR		MxserB00P000	SUCCESS	EOF:78 ERR:0 BRK:0 EVT:0 XON:11 XOFF:13	
IOCTL_SERIAL_SET_HANDFLOW	MxserB00P000	SUCCESS	Shake:0 Replace:0 XonLimit:256 XoffLimit:256	
IOCTL_SERIAL_SET_TIMEOUTS	MxserB00P000	SUCCESS	RI:50 RM:2 RC:500 WM:1000 WC:1000	
IRP_MJ_WRITE			MxserB00P000	SUCCESS	Length 8: 01 03 04 D6 00 22 25 1B 	
IRP_MJ_READ			MxserB00P000	SUCCESS	Length 73: 01 03 44 01 1C 78 6B F3 FC 00 D4 00 C2 00 BC 00 B8 00 BC 00 C6 	
IOCTL_SERIAL_WAIT_ON_MASK	MxserB00P000	SUCCESS		
IOCTL_SERIAL_GET_COMMSTATUS	MxserB00P000	SUCCESS		
IOCTL_SERIAL_WAIT_ON_MASK	MxserB00P000	SUCCESS
Вот, моё поделие, где я пытаюсь изобразить тоже самое :

Код:
SerialPort port = new SerialPort("COM2", 9600, Parity.Even, 8, StopBits.One);
            port.Open();
            byte[] out_buff = {0x01, 0x03, 0x04, 0xD6, 0x00, 0x22, 0x25, 0x1B};
            byte[] in_buff = new byte[21];
            port.Write(out_buff,0,out_buff.Length);
            port.Read(in_buff, 0, 21);
            port.Close();
И собственно, что происходит когда стартует моя программа :
Код:
IOCTL_SERIAL_SET_BAUD_RATE	MxserB00P000	SUCCESS	Rate: 9600	
IOCTL_SERIAL_CLR_RTS	MxserB00P000	SUCCESS		
IOCTL_SERIAL_CLR_DTR	MxserB00P000	SUCCESS		
IOCTL_SERIAL_SET_LINE_CONTROL	MxserB00P000	SUCCESS	StopBits: 1 Parity: EVEN WordLength: 8	
IOCTL_SERIAL_SET_CHAR	MxserB00P000	SUCCESS	EOF:1a ERR:3f BRK:3f EVT:1a XON:11 XOFF:13	
IOCTL_SERIAL_SET_HANDFLOW	MxserB00P000	SUCCESS	Shake:0 Replace:4 XonLimit:1024 XoffLimit:1024	
IOCTL_SERIAL_CLR_DTR	MxserB00P000	SUCCESS		
IOCTL_SERIAL_SET_TIMEOUTS	MxserB00P000	SUCCESS	RI:-1 RM:-1 RC:-2 WM:0 WC:0	
IOCTL_SERIAL_SET_WAIT_MASK	MxserB00P000	SUCCESS	Mask: RXCHAR RXFLAG CTS DSR RLSD BRK ERR RING 	
IOCTL_SERIAL_SET_QUEUE_SIZE	MxserB00P000	SUCCESS	InSize: 4096 OutSize: 2048	
IRP_MJ_WRITE	MxserB00P000	SUCCESS	Length 8: 01 03 04 D6 00 22 25 1B 	
IOCTL_SERIAL_WAIT_ON_MASK	MxserB00P000	SUCCESS		
IRP_MJ_READ	MxserB00P000	SUCCESS	Length 1: 01 	
IOCTL_SERIAL_GET_COMMSTATUS	MxserB00P000	SUCCESS		
IOCTL_SERIAL_WAIT_ON_MASK	MxserB00P000	SUCCESS
Не понимаю, ведь в первом примере вижу, что программа принимает 21 байт.
У меня же, вместо 21 байт, приходит 1
alexandrusankov вне форума Ответить с цитированием
Старый 21.11.2013, 11:01   #5
raxp
Старожил
 
Регистрация: 29.09.2009
Сообщений: 9,713
По умолчанию

...приводите полный код с настройками порта, а то вы там с маской химичите перед открытием. Да и читать желательно в потоке, а у вас сразу после отсылки читается, возможна ситуация, когда все данные не успеют прийти.

Код:
System.IO.Ports.SerialPort serialPort1 = new System.IO.Ports.SerialPort();
serialPort1.PortName = "COM2"; //Настройки порта
serialPort1.BaudRate = 9600;
serialPort1.DataBits = 8;
serialPort1.Parity = System.IO.Ports.Parity.Even;
serialPort1.StopBits = System.IO.Ports.StopBits.One;
//serialPort1.DtrEnable = true;
//serialPort1.RtsEnable = false;
serialPort1.ReadTimeout = (500);
serialPort1.WriteTimeout = (500);
Разработки и научно-технические публикации :: Видеоблог :: Твиттер
Radar systems engineer & Software developer of industrial automation

Последний раз редактировалось raxp; 21.11.2013 в 11:09.
raxp вне форума Ответить с цитированием
Старый 21.11.2013, 11:19   #6
alexusankov
Пользователь
 
Регистрация: 04.01.2011
Сообщений: 66
По умолчанию

Цитата:
Сообщение от raxp Посмотреть сообщение
...приводите полный код с настройками порта, а то вы там с маской химичите перед открытием. Да и читать желательно в потоке, а у вас сразу после отсылки читается, возможна ситуация, когда все данные не успеют прийти.
Дак, это и есть полный код, с масками и прочим - ничего не делаю
По ссылке - полный лог портмона штатной утилиты - http://zalil.ru/34824276
Я впервые работаю с rs232, могу упускать банальные вещи просто.
Не понимаю, почему в штатном логе есть вот это :
Код:
IRP_MJ_READ			MxserB00P000	SUCCESS	Length 73: 01 03 44 01 1C 78 6B F3 FC 00 D4 00 C2 00 BC 00 B8 00 BC 00 C6
Длинна - 73, а требуется (и приходит) всего 21 байт?

Последний раз редактировалось alexusankov; 21.11.2013 в 11:23.
alexusankov вне форума Ответить с цитированием
Старый 28.11.2013, 08:12   #7
alexusankov
Пользователь
 
Регистрация: 04.01.2011
Сообщений: 66
По умолчанию

P.s. с вышестоящим вроде разобрался, экспериментальным путем.
Теперь ситуация такова : есть 2 кнопки, первая передает запрос, вторая считывает данные.
программе нужно было около 500-700 мс, чтобы дождаться ответа от железяки.
Вопрос - как поступают в этих случаях? Ставить как либо программно паузу?
В какую сторону гуглить?
alexusankov вне форума Ответить с цитированием
Старый 28.11.2013, 14:50   #8
simples
Форумчанин
 
Регистрация: 03.10.2013
Сообщений: 142
По умолчанию

Я бы прицепил свой обработчик к событию SerialPort.DataReceived и там обрабатывал полученные данные.
simples вне форума Ответить с цитированием
Старый 29.11.2013, 09:08   #9
alexusankov
Пользователь
 
Регистрация: 04.01.2011
Сообщений: 66
По умолчанию

Цитата:
Сообщение от simples Посмотреть сообщение
к событию SerialPort.DataReceived
Поговаривают, что DataReceived - богомерзкий костыль, и может не сработать - а такой вариант недопустим.
И все же товарищи, после отправки запроса всегда же нужно дать время железяке подумать. Как поступают в этом случае?
alexusankov вне форума Ответить с цитированием
Старый 29.11.2013, 10:36   #10
eval
Подтвердите свой е-майл
 
Регистрация: 29.08.2012
Сообщений: 4,011
По умолчанию

Цитата:
Поговаривают, что DataReceived - богомерзкий костыль, и может не сработать - а такой вариант недопустим.
нц и как поступают те что поговаривают?
eval вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Com port Эрвин1233 Visual C++ 1 29.06.2013 23:58
Банальное обновление программы. qwizz Общие вопросы Delphi 7 08.04.2013 09:44
ip:port Reglament_ Работа с сетью в Delphi 3 29.12.2011 18:50
com port чтение запись delphi SonicBob Помощь студентам 5 15.11.2011 10:20
Банальное равенство парсинга bulldog5293 Общие вопросы Delphi 2 29.03.2011 00:29