Передача данных в com порт

Модератор: Fastman

Правила форума
Убедительная просьба юзать теги [code] при оформлении листингов.
Сообщения не оформленные должным образом имеют все шансы быть незамеченными.
x(mxcrew)
рядовой
Сообщения: 28
Зарегистрирован: 2008-12-10 11:52:41

Передача данных в com порт

Непрочитанное сообщение x(mxcrew) » 2009-06-08 12:22:41

Есть у меня на работе электронные весы, данные на которые отправляются и принимаются через com порт. Под каждыми весами стоит комп с winxp, на нем 1С, в которой формируется список товаров которые нужно передать на эти весы. Список сохраняется в текстовой файлик и в дальнейшем программкой написанной в Дельфях отправляется на эти самые весы (исходников ее нет).
Пытаюсь написать программку под FreeBsd которая бы делала то же самое. Отправляла данные из файлика на весы.
Но пока что все бестолку.
Проблема в том что С++ я начал изучать неделю назад и именно ради того чтобы написать эту программу. Так что не бейте больно, а лучше направьте в правильном направлении (что где почитать).
Сейчас пытаюсь просто написать программку которая передаст в эти весы просто один товар.

В инструкции ест вот такие вот строки
Обмен осуществляется через интерфейс RS-232, скорость обмена 9600 Бод. Прием и передача
байта осуществляется последовательным потоком 11 бит: 1 стартовый бит, 8 бит данных (младши-
ми битами вперед), 9-ый бит данных 0 или 1, 1 стоповый бит.
Передачу информации по протоколу 0 всегда начинает ЭВМ с команды синхронизации, в кото-
рой восемь бит данных содержат номер весов (от 0 до 99), а девятый бит данных устанавливается
в 1. Все остальные команды и данные передаются с девятым битом данных, равным 0.

как установить передачу по 8 бит данных я понял

Код: Выделить всё

// размер передаваемых данных - 8 байт
//newOptions.c_cflag &= ~CSIZE; 
newOptions.c_cflag |= CS8;

стоповый бит вроде тоже

Код: Выделить всё

// число стоп- битов =1
newOptions.c_cflag &= ~CSTOPB;
а вот как сделать чтобы каждый девятый бит вначале был 0 а в последующих 1 не пойму.

Хостинговая компания Host-Food.ru
Хостинг HostFood.ru
 

Услуги хостинговой компании Host-Food.ru

Хостинг HostFood.ru

Тарифы на хостинг в России, от 12 рублей: https://www.host-food.ru/tariffs/hosting/
Тарифы на виртуальные сервера (VPS/VDS/KVM) в РФ, от 189 руб.: https://www.host-food.ru/tariffs/virtualny-server-vps/
Выделенные сервера, Россия, Москва, от 2000 рублей (HP Proliant G5, Intel Xeon E5430 (2.66GHz, Quad-Core, 12Mb), 8Gb RAM, 2x300Gb SAS HDD, P400i, 512Mb, BBU):
https://www.host-food.ru/tariffs/vydelennyi-server-ds/
Недорогие домены в популярных зонах: https://www.host-food.ru/domains/

paradox
проходил мимо
Сообщения: 11620
Зарегистрирован: 2008-02-21 18:15:41

Re: Передача данных в com порт

Непрочитанное сообщение paradox » 2009-06-08 12:59:21

я про девятый бит тоже ничего не слышал

вот например описание кратко
хоть и под линукс
http://www.opennet.ru/docs/RUS/serial_guide/

x(mxcrew)
рядовой
Сообщения: 28
Зарегистрирован: 2008-12-10 11:52:41

Re: Передача данных в com порт

Непрочитанное сообщение x(mxcrew) » 2009-06-08 13:34:32

paradox писал(а):я про девятый бит тоже ничего не слышал

вот например описание кратко
хоть и под линукс
http://www.opennet.ru/docs/RUS/serial_guide/
читал, читаю, пытаюсь понять (собственно с этого руководства все выше перечисленное и брал)

вот взял лог с ком порта считал - во время отправки товара программой из под windows

Код: Выделить всё

0       0.00005923      vesi.exe        IRP_MJ_CREATE   Serial2 SUCCESS Options: Open
1       0.00000419      vesi.exe        IOCTL_SERIAL_GET_BAUD_RATE      Serial2 SUCCESS
2       0.00000223      vesi.exe        IOCTL_SERIAL_GET_LINE_CONTROL   Serial2 SUCCESS
3       0.00000223      vesi.exe        IOCTL_SERIAL_GET_CHARS  Serial2 SUCCESS
4       0.00000223      vesi.exe        IOCTL_SERIAL_GET_HANDFLOW       Serial2 SUCCESS
5       0.00000223      vesi.exe        IOCTL_SERIAL_GET_BAUD_RATE      Serial2 SUCCESS
6       0.00000223      vesi.exe        IOCTL_SERIAL_GET_LINE_CONTROL   Serial2 SUCCESS
7       0.00000196      vesi.exe        IOCTL_SERIAL_GET_CHARS  Serial2 SUCCESS
8       0.00000223      vesi.exe        IOCTL_SERIAL_GET_HANDFLOW       Serial2 SUCCESS
9       0.00000810      vesi.exe        IOCTL_SERIAL_SET_BAUD_RATE      Serial2 SUCCESS Rate: 9600
10      0.00000447      vesi.exe        IOCTL_SERIAL_SET_RTS    Serial2 SUCCESS
11      0.00000475      vesi.exe        IOCTL_SERIAL_SET_DTR    Serial2 SUCCESS
12      0.00000391      vesi.exe        IOCTL_SERIAL_SET_LINE_CONTROL   Serial2 SUCCESS StopBits: 1 Parity: MARK WordLength: 8
13      0.00000251      vesi.exe        IOCTL_SERIAL_SET_CHAR   Serial2 SUCCESS EOF:0 ERR:0 BRK:0 EVT:0 XON:11 XOFF:13
14      0.00000447      vesi.exe        IOCTL_SERIAL_SET_HANDFLOW       Serial2 SUCCESS Shake:1 Replace:40 XonLimit:2048 XoffLimit:512
15      0.00000363      vesi.exe        IOCTL_SERIAL_PURGE      Serial2 SUCCESS Purge: TXCLEAR RXCLEAR
16      0.00000363      vesi.exe        IOCTL_SERIAL_SET_WAIT_MASK      Serial2 SUCCESS Mask: RXCHAR
17      0.09715034      vesi.exe        IOCTL_SERIAL_WAIT_ON_MASK       Serial2 SUCCESS
18      0.00000587      vesi.exe        IOCTL_SERIAL_GET_BAUD_RATE      Serial2 SUCCESS
19      0.00000251      vesi.exe        IOCTL_SERIAL_GET_LINE_CONTROL   Serial2 SUCCESS
20      0.00000251      vesi.exe        IOCTL_SERIAL_GET_CHARS  Serial2 SUCCESS
21      0.00000223      vesi.exe        IOCTL_SERIAL_GET_HANDFLOW       Serial2 SUCCESS
22      0.00000223      vesi.exe        IOCTL_SERIAL_GET_BAUD_RATE      Serial2 SUCCESS
23      0.00000196      vesi.exe        IOCTL_SERIAL_GET_LINE_CONTROL   Serial2 SUCCESS
24      0.00000223      vesi.exe        IOCTL_SERIAL_GET_CHARS  Serial2 SUCCESS
25      0.00000223      vesi.exe        IOCTL_SERIAL_GET_HANDFLOW       Serial2 SUCCESS
26      0.00000866      vesi.exe        IOCTL_SERIAL_SET_BAUD_RATE      Serial2 SUCCESS Rate: 9600
27      0.00000475      vesi.exe        IOCTL_SERIAL_SET_RTS    Serial2 SUCCESS
28      0.00000447      vesi.exe        IOCTL_SERIAL_SET_DTR    Serial2 SUCCESS
29      0.00000363      vesi.exe        IOCTL_SERIAL_SET_LINE_CONTROL   Serial2 SUCCESS StopBits: 1 Parity: MARK WordLength: 8
30      0.00000251      vesi.exe        IOCTL_SERIAL_SET_CHAR   Serial2 SUCCESS EOF:0 ERR:0 BRK:0 EVT:0 XON:11 XOFF:13
31      0.00000447      vesi.exe        IOCTL_SERIAL_SET_HANDFLOW       Serial2 SUCCESS Shake:1 Replace:40 XonLimit:2048 XoffLimit:512
32      0.00003324      vesi.exe        IRP_MJ_WRITE    Serial2 SUCCESS Length 1: .
33      0.00000866      vesi.exe        IOCTL_SERIAL_GET_COMMSTATUS     Serial2 SUCCESS
34      0.00000643      vesi.exe        IRP_MJ_READ     Serial2 SUCCESS Length 1: w
35      0.00000643      vesi.exe        IOCTL_SERIAL_GET_BAUD_RATE      Serial2 SUCCESS
36      0.00000279      vesi.exe        IOCTL_SERIAL_GET_LINE_CONTROL   Serial2 SUCCESS
37      0.00000251      vesi.exe        IOCTL_SERIAL_GET_CHARS  Serial2 SUCCESS
38      0.00000223      vesi.exe        IOCTL_SERIAL_GET_HANDFLOW       Serial2 SUCCESS
39      0.00000223      vesi.exe        IOCTL_SERIAL_GET_BAUD_RATE      Serial2 SUCCESS
40      0.00000223      vesi.exe        IOCTL_SERIAL_GET_LINE_CONTROL   Serial2 SUCCESS
41      0.00000223      vesi.exe        IOCTL_SERIAL_GET_CHARS  Serial2 SUCCESS
42      0.00000223      vesi.exe        IOCTL_SERIAL_GET_HANDFLOW       Serial2 SUCCESS
43      0.00000838      vesi.exe        IOCTL_SERIAL_SET_BAUD_RATE      Serial2 SUCCESS Rate: 9600
44      0.00000447      vesi.exe        IOCTL_SERIAL_SET_RTS    Serial2 SUCCESS
45      0.00000447      vesi.exe        IOCTL_SERIAL_SET_DTR    Serial2 SUCCESS
46      0.00000363      vesi.exe        IOCTL_SERIAL_SET_LINE_CONTROL   Serial2 SUCCESS StopBits: 1 Parity: SPACE WordLength: 8
47      0.00000251      vesi.exe        IOCTL_SERIAL_SET_CHAR   Serial2 SUCCESS EOF:0 ERR:0 BRK:0 EVT:0 XON:11 XOFF:13
48      0.00000447      vesi.exe        IOCTL_SERIAL_SET_HANDFLOW       Serial2 SUCCESS Shake:1 Replace:40 XonLimit:2048 XoffLimit:512
49      0.00003241      vesi.exe        IRP_MJ_WRITE    Serial2 SUCCESS Length 1: .
50      0.02783817      vesi.exe        IOCTL_SERIAL_WAIT_ON_MASK       Serial2 SUCCESS
51      0.00000782      vesi.exe        IOCTL_SERIAL_GET_COMMSTATUS     Serial2 SUCCESS
52      0.00000698      vesi.exe        IRP_MJ_READ     Serial2 SUCCESS Length 1: .
53      0.02748115      vesi.exe        IOCTL_SERIAL_WAIT_ON_MASK       Serial2 SUCCESS
54      0.00003967      vesi.exe        IRP_MJ_WRITE    Serial2 SUCCESS Length 3: ..!
55      0.06833466      vesi.exe        IRP_MJ_WRITE    Serial2 SUCCESS Length 61: ..p...)............ ............ ... 72,5%% ..................
56      0.00000615      vesi.exe        IOCTL_SERIAL_GET_COMMSTATUS     Serial2 SUCCESS
57      0.00000698      vesi.exe        IRP_MJ_READ     Serial2 SUCCESS Length 1: .
58      0.06379554      vesi.exe        IOCTL_SERIAL_WAIT_ON_MASK       Serial2 SUCCESS
59      0.00000559      vesi.exe        IOCTL_SERIAL_GET_COMMSTATUS     Serial2 SUCCESS
60      0.00000698      vesi.exe        IRP_MJ_READ     Serial2 SUCCESS Length 1: .
61      0.07910223      vesi.exe        IOCTL_SERIAL_WAIT_ON_MASK       Serial2 CANCELLED
62      0.00000643      vesi.exe        IRP_MJ_CLEANUP  Serial2 SUCCESS
63      0.01544386      vesi.exe        IRP_MJ_CLOSE    Serial2 SUCCESS

paradox
проходил мимо
Сообщения: 11620
Зарегистрирован: 2008-02-21 18:15:41

Re: Передача данных в com порт

Непрочитанное сообщение paradox » 2009-06-08 13:40:57

а сама программа большая?


paradox
проходил мимо
Сообщения: 11620
Зарегистрирован: 2008-02-21 18:15:41

Re: Передача данных в com порт

Непрочитанное сообщение paradox » 2009-06-08 13:48:06

закинь на фтп
погляжу на досуге

x(mxcrew)
рядовой
Сообщения: 28
Зарегистрирован: 2008-12-10 11:52:41

Re: Передача данных в com порт

Непрочитанное сообщение x(mxcrew) » 2009-06-08 13:56:24

вот файлик
vesi.exe.bz2
(213.86 КБ) 92 скачивания
а вот обработка в 1С которая подготавливает и передает txt (
vesi.txt
(210 байт) 81 скачивание
)шку этой програмке

Код: Выделить всё

Процедура ПередатьНаВесы()
  таблицаДляВесов.Выбратьстроки();
  tx=создатьобъект("текст");
  while таблицаДляВесов.получитьстроку()=1 do             
  	 t=строка(таблицаДляВесов.Кодплу);
  	 while СтрДлина(t)<3 do
  	 	t="0"+t;
  	 enddo;	
     t2=сокрлп(строка(таблицаДляВесов.кодтов));
  	 while СтрДлина(t2)<5 do
  	 	t2="0"+t2;
  	 enddo;	
     t3=сокрлп(строка(таблицаДляВесов.Цена*100));
  	 while СтрДлина(t3)<6 do
  	 	t3="0"+t3;
  	 enddo;	

  	 
  	 t=t+":"+t2+":"+t3+":"+лев(строка(таблицаДляВесов.Тов),48)+" ";
  	 tx.ДобавитьСтроку(t);
  	
  enddo;                  
  tx.ДобавитьСтроку("--");
  tx.Записать("c:\vesi.txt");      
  t="vesi.exe "+константа.Порт_для_весов+" "+весы.номер+" 05 c:\vesi.txt" ;
  ЗапуститьПриложение(t);

x(mxcrew)
рядовой
Сообщения: 28
Зарегистрирован: 2008-12-10 11:52:41

Re: Передача данных в com порт

Непрочитанное сообщение x(mxcrew) » 2009-06-08 13:59:58

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

http://www.massa.ru/images/vpt-ie.zip

paradox
проходил мимо
Сообщения: 11620
Зарегистрирован: 2008-02-21 18:15:41

Re: Передача данных в com порт

Непрочитанное сообщение paradox » 2009-06-08 14:12:32

ой не
там гребаный делфи
ну его в баню =)

я думал хотя бы VC

paradox
проходил мимо
Сообщения: 11620
Зарегистрирован: 2008-02-21 18:15:41

Re: Передача данных в com порт

Непрочитанное сообщение paradox » 2009-06-08 14:23:26

В инструкции ест вот такие вот строки
Обмен осуществляется через интерфейс RS-232, скорость обмена 9600 Бод. Прием и передача
байта осуществляется последовательным потоком 11 бит: 1 стартовый бит, 8 бит данных (младши-
ми битами вперед), 9-ый бит данных 0 или 1, 1 стоповый бит
имелось ввиду 9ый бит с начала включая старторый бит

зы
какой то вася инструкцию писал
или блондинка

x(mxcrew)
рядовой
Сообщения: 28
Зарегистрирован: 2008-12-10 11:52:41

Re: Передача данных в com порт

Непрочитанное сообщение x(mxcrew) » 2009-06-08 16:09:28

сейчас я блондинКО - непойму как это сделать :cz2:

paradox
проходил мимо
Сообщения: 11620
Зарегистрирован: 2008-02-21 18:15:41

Re: Передача данных в com порт

Непрочитанное сообщение paradox » 2009-06-08 16:16:45

в байте из 8 бит
один бит должен быть 1
остальные номер

x(mxcrew)
рядовой
Сообщения: 28
Зарегистрирован: 2008-12-10 11:52:41

Re: Передача данных в com порт

Непрочитанное сообщение x(mxcrew) » 2009-06-10 11:19:49

Я так понимаю, что для того чтобы он посылал данные именно так, нужно установить опции для порта

Код: Выделить всё

Отсутствие проверки на четность (8N1):
options.c_cflag &= ~PARENB
options.c_cflag &= ~CSTOPB
options.c_cflag &= ~CSIZE;
options.c_cflag |= CS8;
чтобы было
Передачу информации по протоколу 0 всегда начинает ЭВМ с команды синхронизации, в которой восемь бит данных содержат номер весов (от 0 до 99), а девятый бит данных устанавливаетсяв 1.
А потом сменить опции на ... , а вот на что не знаю - в руководстве есть еще:

Проверка на четность (7E1):
Проверка на нечетность (7O1):
Пробел (space parity) бита четности устанавливается также как и отсутствие проверки на четность (7S1):

чтобы выполнялось:

Код: Выделить всё

Все остальные команды и данные передаются с девятым битом данных, равным 0.
и почему мне кажется, что я написал чушь :oops:

x(mxcrew)
рядовой
Сообщения: 28
Зарегистрирован: 2008-12-10 11:52:41

Re: Передача данных в com порт

Непрочитанное сообщение x(mxcrew) » 2009-06-10 13:35:26

на данный момент получилась вот такая вот программа

Код: Выделить всё

#include <stdio.h> /* Standard input/output definitions */
#include <string.h> /* String function definitions */
#include <unistd.h> /* UNIX standard function definitions */
#include <fcntl.h> /* File control definitions */
#include <errno.h> /* Error number definitions */
#include <termios.h> /* POSIX terminal control definitions */
#include <iostream>

using namespace std;
int main(void)
{
int n;
int fd; /* File descriptor for the port */
char buf[200];
struct termios options;

fd = open("/dev/cuad0", O_RDWR | O_NOCTTY | O_NONBLOCK);
if (fd == -1) perror("open_port: Unable to open /dev/cuad0 - ");
else
{
fcntl(fd, F_SETFL, 0);

tcgetattr(fd, &options);
cfmakeraw(&options);

/************************************************************************/
// c_cflag
 options.c_cflag |= PARENB;
 options.c_cflag |= PARODD;
 options.c_cflag &= ~CSTOPB;

 options.c_cflag &= ~CSIZE;
 options.c_cflag |= CS8;

 options.c_iflag |= (INPCK);

cfsetispeed(&options, B9600);
cfsetospeed(&options, B9600);

tcsetattr(fd, TCSAFLUSH, &options);
tcflush(fd, TCIOFLUSH); /**/


// Main code
buf[0]=0;
n = write(fd, buf, 1);
usleep(150000);
cout << "Written:" << n << '\n';
usleep (150000);
read(fd,buf,1);
cout << "Readen:" << int(buf[0]) << '\n';

buf[0]=0x01;
n = write(fd, buf, 1);
usleep(150000);
cout << "Written:" << n << '\n';
usleep (150000);
read(fd,buf,1);
cout << "Readen:" << int(buf[0]) << '\n';

buf[0]=0;
buf[1]=60;

n = write(fd, buf, 2);
usleep(150000);
cout << "Written:" << n << '\n';
usleep (150000);
read(fd,buf,3);
cout << "Readen:" << int(buf[0]) << '\n';



close(fd);
}
}
результат ее работы такой

Код: Выделить всё

Written:1
Readen:0
Written:1
Readen:1
Written:2
Readen:0
при этом то что ожидалось с весами не происходит

алгоритм по которому делалась программа
1.jpg