Форум программистов, компьютерный форум, киберфорум
C/С++ под Linux
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.83/6: Рейтинг темы: голосов - 6, средняя оценка - 4.83
1 / 1 / 0
Регистрация: 14.08.2017
Сообщений: 61

Подключение LinPAC LP-5231 к ПК через Com-Port

10.04.2023, 09:26. Показов 1369. Ответов 8

Студворк — интернет-сервис помощи студентам
Всем доброго времени суток!
У меня имеется промышленный ПК LinPAC LP-5231 и обычный компьютер.
На LinPAC стоит Linux, на обычном стоит винда.
Мне нужно заставить их дружить через com-port. Вроде бы и дружат, но как-то не серьёзно.
Код на си под Linux:
Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <poll.h>
#include <fcntl.h>
#include <termios.h>
#include <errno.h>
 
int sp485;
int count485;
 
int main()
{
    unsigned char read485[4096];
 
    struct termios tty485;
    sp485 = open("/dev/ttyS3", O_RDWR | O_NONBLOCK | O_NOCTTY | O_NDELAY);
 
    //fcntl(sp485, F_SETFL, O_NDELAY, O_NONBLOCK);
    fcntl(sp485, F_SETFL, 0);
    if(tcgetattr(sp485, &tty485) != 0)
    {
        printf("Error %i from tcgetattr: %s\n", errno, strerror(errno));
        return 1;
    }
 
    tty485.c_cflag &= ~PARENB;
    tty485.c_cflag &= ~CSTOPB;
    tty485.c_cflag &= ~CSIZE;
    tty485.c_cflag |= CS8;
    tty485.c_cflag &= ~CRTSCTS;
    tty485.c_cflag |= (CREAD | CLOCAL);
 
    tty485.c_lflag &= ~ICANON;
    tty485.c_lflag &= ~ECHO;
    tty485.c_lflag &= ~ECHOE;
    tty485.c_lflag &= ~ECHONL;
    tty485.c_lflag &= ~ISIG;
 
    tty485.c_iflag &= ~(IXON | IXOFF | IXANY);
    tty485.c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR | ICRNL);
 
    tty485.c_oflag &= ~OPOST;
    tty485.c_oflag &= ~ONLCR;
 
    tcflush(sp485, TCIFLUSH);
 
    tty485.c_cc[VMIN] = 0;
    tty485.c_cc[VTIME] = 0;
 
    cfsetispeed(&tty485, B9600);
    cfsetospeed(&tty485, B9600);
 
    if(tcsetattr(sp485, TCSANOW, &tty485) != 0)
    {
        printf("Error %i from tcsetattr: %s\n", errno, strerror(errno));
        return 1;
    }
 
    //count485 = read(sp485, &read485, 32);
 
    struct pollfd mypoll;
 
    memset(&mypoll, 0, sizeof(poll));
    //mypoll.fd = 0;
    mypoll.fd = sp485;
    mypoll.events = POLLIN;
 
    int ret = 0;
    int q;
 
    while(1)
    {
        poll(&mypoll, 1, 2);
        if(mypoll.revents & POLLIN)
        {
            ret = read(sp485, read485, 32);
            //for(q = 0; q < ret; q++)
            //{
                //printf("%x ", read485[q]);
            //}
            printf("ret: %d\n", ret);
            fflush(stdout);
 
            count485 += ret;
            if(count485 == 24)
            {
                write(sp485, read485, 24);
                count485 = 0;
             }
 
            //printf("\n");
        }
        else
        {
//          fflush(stdout);
            //printf("");
        }
    }
 
 
    return 0;
}
Linux занимается принятием данных...
Код на винде пишу на шарпе:
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
 
using System.IO.Ports;
using System.Threading;
 
namespace com
{
    public partial class Form1 : Form
    {
        SerialPort SP232;
        SerialPort SP485;
 
        public Form1()
        {
            InitializeComponent();
 
            //SP232 = new SerialPort();
            SP485 = new SerialPort();
 
            //SP232.PortName = "COM7";
            //SP232.BaudRate = 230400;
 
            SP485.PortName = "COM3";
            SP485.BaudRate = 9600;
            SP485.Parity = Parity.None;
            SP485.DataBits = 8;
            SP485.StopBits = StopBits.One;
        }
 
        private void btn232_Click(object sender, EventArgs e)
        {
            
        }
 
        private void btn485_Click(object sender, EventArgs e)
        {
            byte[] buff = new byte[24] { 0x58, 0xA2, 0, 0x55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0 };
 
            for(; ; )
            {
                SP485.Write(buff, 0, 24);
                Thread.Sleep(5000);
            }
            
        }
 
        private void com232_485open_Click(object sender, EventArgs e)
        {
            //SP232.Open();
            SP485.Open();
        }
 
        private void com232_485close_Click(object sender, EventArgs e)
        {
            //SP232.Close();
            SP485.Close();
        }
 
        private void sp485_read_Click(object sender, EventArgs e)
        {
            string answer = SP485.ReadExisting();
            MessageBox.Show(answer);
        }
    }
}
Объявилась такая проблема, что при отправке с винды 24х байт в линукс, в терминале линукс переменная ret пишется не 1 раз с количеством байт 24, а два раза, сначала 16 и сразу за ней 8. Т.е. получается, что приходит сначала 16, потом 8, да в сумме 24, но это как-то не то.
И там и там стоит скорость 9600.

А теперь самое интересное, если я со стороны винды понижаю скорость до 4800 или со стороны линукса повышаю до 19200, то всё работает как надо. Как так? Почему на 9600 оно не может работать?

На линуксе пробовал конфигурировать порт через stty на 9600 и это не помогает.

Со стороны винды стоит свисток USB-Serial CH340.
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
10.04.2023, 09:26
Ответы с готовыми решениями:

Подключение к Arduino через com-port
Здравствуйте! С com портами я не работал, что то оттуда отсюда взял и получил что то, но конечно же это не работает, пожалуйста направьте...

Подключение проекта на C# к Proteus через Com-Port
Всем привет! Делаю проект по заданию в колледже &quot;Умный дом&quot;, первоначальной задачей было привязать включение/выключение света к кнопкам...

RS-232 Подключение к com port
Всем добрый день . Пишу программу для автоматизации теста на устройстве через rs-232 . 1)Не могу открыть сессию через созданный мной...

8
Windows must die
676 / 860 / 103
Регистрация: 23.11.2021
Сообщений: 5,090
Записей в блоге: 18
10.04.2023, 09:43
Ядро же буферизует, поэтому нет вообще смысла ожидать, что у тебя "за один присест" придет именно нужное количество байт.
Просто заведи отдельный поток на считывание. Копи данные в циклический буфер, а как дойдешь до разделителя — выставляй флаг готовности принятой строки, чтобы в другом потоке можно было их принять. И лучше данные передавать в строковой форме, тогда можно их завершать обычным "\n". В случае с бинарными придется или городить задержки (как в доисторическом убогом модбасе, которым вменяемые люди в 21 веке точно пользоваться не будут), либо вводить условные разделители и надеяться, что в потоке данных их не встретится.

P.S. А какой смысл два компа связывать по 485? Чем тебя ethernet не устраивает? Открой сокет, настрой его SEQ_PACKET, и будет тебе атомарность передачи (если, конечно, не попытаешься слишком много данных отправлять).
0
1 / 1 / 0
Регистрация: 14.08.2017
Сообщений: 61
10.04.2023, 10:12  [ТС]
Спасибо за быстрый ответ.

Связываю, потому что на винде эмулирую устройство которое будет подключаться к линуксу. Мне нужно данные получать в бинарном виде, как я это в шарпе и отправляю.
Почему тогда, если я с винды отправляю 16 или меньше байт, то ret мне показывает то число, которое я отправляю с винды, а если больше 16, то разделяется сообщение на 16 + остаточные байты? Как это так ядро буфферизирует и строго на 16 байт первые?
0
Evg
Эксперт CАвтор FAQ
 Аватар для Evg
21281 / 8305 / 637
Регистрация: 30.03.2009
Сообщений: 22,660
Записей в блоге: 30
10.04.2023, 10:27
Цитата Сообщение от uswer312 Посмотреть сообщение
Почему тогда, если я с винды отправляю 16 или меньше байт, то ret мне показывает то число, которое я отправляю с винды, а если больше 16, то разделяется сообщение на 16 + остаточные байты?
Ответ на вопрос "почему" тебе ничего не даст. По большому счёту в такой манере работает любая передача данных, в том числе и из файла в память. Процесс чтения данных никогда не должен закладываться на то, что если передано 16 байт, то будет получено 16 байт за раз. Чтение всегда нужно строить в предположении, что поток данных будет разбит на куски заранее неизвестного размера. Именно поэтому интерфейсы типа read возвращают количество прочитанных байт. Так было во все времена и на всех операционных системах, может быть кроме каких-то маргинальных
0
Windows must die
676 / 860 / 103
Регистрация: 23.11.2021
Сообщений: 5,090
Записей в блоге: 18
10.04.2023, 11:20
Если это устройство - разрабатываемое кем-то из вашей команды, то лучше сразу поменять протокол на текстовый, чтобы в будущем не было геморроя. Или завершать каждую посылку, скажем, числом 0xDEADBEEF и т.п.
Но нельзя надеяться на то, что при напряженном обмене данными пакеты будут передаваться атомарно.

Не по теме:

Я вот намучился с убогим модбасом: есть мастер, есть слейв. А с компьютера мне нужно читать протокол и выставлять в сеть данные. И вот как раз из-за убогости модбаса очень часто возникает ситуация, когда принимается часть пакета (т.к. ядро-то буферизует данные, ему плевать на эти задержки в 3.5 символа и т.п.). Надо будет делать аппаратный преобразователь modbus-usb (готовый вряд ли пойдет: у них протоколы обычно совершенно невменяемые, а многие еще и только под форточками работают).

0
 Аватар для Azathtot
754 / 351 / 90
Регистрация: 07.01.2023
Сообщений: 1,451
10.04.2023, 12:28
Цитата Сообщение от Eddy_Em Посмотреть сообщение
Я вот намучился с убогим модбасом: есть мастер, есть слейв. А с компьютера мне нужно читать протокол и выставлять в сеть данные.
Странно. Никогда ни с modBUS ни с Wake проблем не было. Даже если пакет погрызли сетевые мыши, то CRC не сходится, и отбрасываем его, и запрашиваем этот регистр/койл по новой
0
Windows must die
676 / 860 / 103
Регистрация: 23.11.2021
Сообщений: 5,090
Записей в блоге: 18
10.04.2023, 13:12
Azathtot, ключевая фраза: пассивно слушаем линию! Когда пакеты слишком часто бегают, невозможно определить, где начало! Нужно на STM32 делать преобразователь. Там заодно практически аппаратно модбас можно реализовать.

Не по теме:

и лишний раз пожелаю всего плохого идиотам, которые в 21 веке пихают в новые железки протокол, разработанный для аналоговых телефонных сетей 50 лет назад!

0
10.04.2023, 13:25

Не по теме:

... - сказал фанат KOI8-R, появившейся 30 лет назад для 8-битных компьютеров.

0
10.04.2023, 16:07

Не по теме:

Цитата Сообщение от Eddy_Em Посмотреть сообщение
и лишний раз пожелаю всего плохого идиотам, которые в 21 веке пихают в новые железки протокол, разработанный для аналоговых телефонных сетей 50 лет назад!
Ты сейчас наехал на всех АСУшников и КИПовцев сразу, как и на отрасль пром. оборудования автоматизации. ModBus - это признанный стандарт в промю электронике. А учитывая срок службы железок там измеряется десятками лет никто не будет этот протокол выкидывать.

0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
10.04.2023, 16:07
Помогаю со студенческими работами здесь

Активное подключение к фтп. PORT
Форумчане, прошу вашей помощи, пишу фтп клиент на с++, с использованием только библиотеки WinSock.h (класс FTP юзать нельзя) и возникла...

Интернет через VPN соединение как через прокси в формате IP:PORT
Keenetic Extra (KN-1711) Подскажите как настроить или хотя бы как правильно называется (в каком направлении искать) следующее: В...

Через что предпочтительнее подключить монитор, через HDMI или Display Port?
Ребят, всем привет!) Подскажите, через что предпочтительнее подключить монитор, через HDMI или Display Port? Доп. инф., если...

Переподключить подключение POTS модема, навешенного на com port
Вкратце нужно просто организовать на vbs переконнект подключения pots модема для начала я полезла в класс win32_networkadapter...

3.95 LCD модуль (parallel port) подключение к ESP 32
Доброго дня, господа! Достался мне дисплей 3.95 дюйма, на чипе ST7796S. (посмотреть его можно тут:...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
9
Ответ Создать тему
Новые блоги и статьи
Отправка уведомления на почту при изменении наименования справочника
Maks 24.03.2026
Программная отправка письма электронной почты на примере изменения наименования типового справочника "Склады" в конфигурации БП3. Перед реализацией необходимо выполнить настройку системной учетной. . .
модель ЗдравоСохранения 5. Меньше увольнений- больше дохода!
anaschu 24.03.2026
Теперь система здравосохранения уменьшает количество увольнений. 9TO2GP2bpX4 a42b81fb172ffc12ca589c7898261ccb/ https:/ / rutube. ru/ video/ a42b81fb172ffc12ca589c7898261ccb/ Слева синяя линия -. . .
Midnight Chicago Blues
kumehtar 24.03.2026
Такой Midnight Chicago Blues, знаешь?. . Когда вечерние улицы становятся ночными, а ты не можешь уснуть. Ты идёшь в любимый старый бар, и бармен наливает тебе виски. Ты смотришь на пролетающие. . .
Контроль уникальности заводского номера - вариант №2
Maks 24.03.2026
В отличие от предыдущего варианта добавлено прерывание циклов, также добавлены новые переменные для сохранения контекста ошибки перед прерыванием цикла: Процедура ПередЗаписью(Отказ, РежимЗаписи,. . .
SDL3 для Desktop (MinGW): Вывод текста со шрифтом TTF с помощью библиотеки SDL3_ttf на Си и C++
8Observer8 24.03.2026
Содержание блога Финальные проекты на Си и на C++: finish-text-sdl3-c. zip finish-text-sdl3-cpp. zip
Жизнь в неопределённости
kumehtar 23.03.2026
Жизнь — это постоянное существование в неопределённости. Например, даже если у тебя есть список дел, невозможно дойти до точки, где всё окончательно завершено и больше ничего не осталось. В принципе,. . .
Модель здравоСохранения: работники работают быстрее после её введения.
anaschu 23.03.2026
geJalZw1fLo Корпорация до введения программа здравоохранения имела много невыполненных работниками заданий, после введения программы количество заданий выросло. Но на выплатах по больничным это. . .
Контроль уникальности заводского номера - вариант №1
Maks 23.03.2026
Алгоритм контроля уникальности заводского (или серийного) номера на примере нетипового документа выдачи шин для спецтехники с табличной частью, разработанного в конфигурации КА2. Данные берутся из. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru