Как изменить скорость передачи для устройства LoRa?

У меня есть устройство LoRa, которое использует скорость передачи данных по умолчанию 57600 бод на USB-порту Raspberry Pi. Я хотел бы поэкспериментировать с более высокой последовательной скоростью передачи данных. Инструкции по изменению скорости передачи данных после выхода из спящего режима устройства приведены в таблице данных:

введите здесь описание изображения

У меня есть одна серьезная проблема в том, что я не знаю, что такое «код прерывания» в связи через последовательный порт. Я пробовал разные вещи, в том числе следующее (где usb_port - файловый дескриптор открытого порта):

ioctl(usb_port, TCSBRK, 0);

а также

std::string msg;
msg="0X00";
write(usb_port, msg.c_str(), msg.size());

Все безуспешно. Может ли кто-нибудь взглянуть на эту функцию C ++ и сказать мне, где я могу ошибиться?

В другом месте документации указано, что запись «0x55» запускает настройку автоматического определения скорости при выходе из спящего режима.

Примечание: файловый дескриптор радиоустройства «/ dev / ttyUSBPort1» - это ссылка на / dev / ttyUSB0, которая настроена с использованием последовательного правила udev.

const char* radiodevice = "/dev/ttyUSBPort1";
int openPort(void) {
    struct termios tty;
    memset(&tty, 0, sizeof tty);
    if ((usb_port = open(radiodevice, O_RDWR | O_NOCTTY | O_SYNC))>=0) {// | O_NOCTTY | O_SYNC
        std::cout << "DEVICE OPENED: " << radiodevice << " handle number: " << usb_port << std::endl;
    } else {
        fprintf(stderr, "unable to open serial radiodevice");
        return -1;
    }
    if(tcgetattr(usb_port, &tty) != 0) {
        printf("Error %i \n", errno);
    }
    cfsetispeed(&tty, B57600);
    cfsetospeed(&tty, B57600);
    tty.c_cflag     &=  ~PARENB;            // Make 8n1
    tty.c_cflag     &=  ~CSTOPB;
    tty.c_cflag     &=  ~CSIZE;
    tty.c_cflag     |=  CS8;
    tty.c_cflag     &=  ~CRTSCTS;           // no flow control
    tty.c_cc[VMIN]   =  0;                  // read doesn't block
    tty.c_cc[VTIME]  =  5;                  // 0.5 seconds read timeout
    tty.c_iflag &= ~ISTRIP;
    tty.c_iflag &= ~INLCR;
    tty.c_iflag &= ~IGNCR;
    tty.c_iflag &= ~ICRNL;
    tty.c_oflag &= OPOST;
    tty.c_lflag &= ICANON;
    tcflush(usb_port,TCIOFLUSH);
    usleep(10000);
    if (tcsetattr(usb_port, TCSANOW, &tty) != 0) {
        printf("Error %i\n", errno);
    }

    //FLASH UNIT LED LIGHTS TO CONFIRM INITIAL CONNECTION
    std::string msg="sys set pindig GPIO11 1\r\n";
    write(usb_port, msg.c_str(), msg.size());
    usleep(1000000);
    msg="sys set pindig GPIO11 0\r\n";
    write(usb_port, msg.c_str(), msg.size());
    usleep(10000);

    //WRITE SLEEP COMMAND TO DEVICE FOR 0.5 SECONDS
    std::cout << "WRITING SLEEP COMMAND" << std::endl;
    msg="sys sleep 5000\r\n";//
    write(usb_port, msg.c_str(), msg.size());
    usleep(100000);

    //ATTEMPT TO SEND BREAK COMMAND
    ioctl(usb_port, TCSBRK, 0);
    usleep(500000);

    //RESET SERIAL BAUD RATE
    cfsetispeed(&tty, B115200);
    cfsetospeed(&tty, B115200);

    //SET DEVICE TO AUTO-BAUD RATE DETECTION
    std::cout << "SENDING 0x55" << std::endl;
    msg="0x55";
    write(usb_port, msg.c_str(), msg.size());
    usleep(2000000);

    //FLASH UNIT LED LIGHTS TO CONFIRM FINAL CONNECTION AT NEW BAUD RATE
    std::cout << "BLINKING LIGHTS" << std::endl;
    msg="sys set pindig GPIO11 1\r\n";
    write(usb_port, msg.c_str(), msg.size());
    usleep(1000000);
    msg="sys set pindig GPIO11 0\r\n";
    write(usb_port, msg.c_str(), msg.size());

    return usb_port;
}

person Max    schedule 13.04.2020    source источник
comment
подтяните линию данных к тому же напряжению, что и стартовый бит, на период времени символа, может быть дольше .... при 57600 бод, это будет 200 микросекунд или больше   -  person jsotola    schedule 13.04.2020
comment
@jsotola, что вы имеете в виду под этим кодом? Итак, что используется вместо ioctl (usb_port, TCSBRK, 0) ;?   -  person Max    schedule 13.04.2020
comment
я не смотрел на код ... Я только говорю, что такое разрыв последовательной связи ... возможно, что устройство LoRa действительно имеет последовательность символов разрыва, как у старых модемов ... для модема, перерыв +++ ... не помешало бы попробовать это   -  person jsotola    schedule 13.04.2020
comment
Да, есть отдельное упоминание о низком уровне вывода UART_RX, о чем, я думаю, вы и говорите. Однако в прошивке этот вывод недоступен для вывода низкого уровня ... что странно. В соответствии с документацией доступны выводы GPIO0-GPIO13, UART_CTS, UART_RTS, TEST0, TEST1.   -  person Max    schedule 13.04.2020
comment
Break - это условие, а не символ. Это возможность передачи UART, доступная через последовательный терминал ioctl () и функцию POSIX.   -  person sawdust    schedule 17.04.2020


Ответы (1)


Для тех, кто, возможно, будет искать это решение в будущем, вот как я выполнил задачу по установке устройства LoRa в автоматический режим передачи и открытия порта с новой скоростью передачи:

    int openPort(void) {
        struct termios tty;
        memset(&tty, 0, sizeof tty);
        //OPEN PORT WITH DEFAULT BAUD RATE 57600
        if ((usb_port = open(radiodevice, O_RDWR | O_NOCTTY | O_SYNC))>=0) {// | O_NOCTTY | O_SYNC
            std::cout << "DEVICE OPENED: " << radiodevice << " handle number: " << usb_port << std::endl;
        } else {
            fprintf(stderr, "unable to open serial radiodevice");
            return -1;
        }
        if(tcgetattr(usb_port, &tty) != 0) {
            printf("Error %i \n", errno);
        }
        cfsetispeed(&tty, B57600);
        cfsetospeed(&tty, B57600);
        tty.c_cflag     &=  ~PARENB;            // Make 8n1
        tty.c_cflag     &=  ~CSTOPB;
        tty.c_cflag     &=  ~CSIZE;
        tty.c_cflag     |=  CS8;
        tty.c_cflag     &=  ~CRTSCTS;           // no flow control
        tty.c_cc[VMIN]   =  0;                  // read doesn't block
        tty.c_cc[VTIME]  =  5;                  // 0.5 seconds read timeout
        tty.c_iflag &= ~ISTRIP;
        tty.c_iflag &= ~INLCR;
        tty.c_iflag &= ~IGNCR;
        tty.c_iflag &= ~ICRNL;
        tty.c_oflag &= OPOST;
        tty.c_lflag &= ICANON;
        tcflush(usb_port,TCIOFLUSH);
        //usleep(10000);
        if (tcsetattr(usb_port, TCSANOW, &tty) != 0) {
            printf("Error %i\n", errno);
        }

        //FLASH UNIT LED LIGHTS TO CONFIRM INITIAL CONNECTION
        std::string msg="sys set pindig GPIO11 1\r\n";
        write(usb_port, msg.c_str(), msg.size());
        usleep(1000000);
        msg="sys set pindig GPIO11 0\r\n";
        write(usb_port, msg.c_str(), msg.size());
        usleep(10000);

        //WRITE SLEEP COMMAND TO DEVICE FOR 0.5 SECONDS
        std::cout << "WRITING SLEEP COMMAND" << std::endl;
        msg="sys sleep 5000\r\n";
        write(usb_port, msg.c_str(), msg.size());
        usleep(100000);

        close(usb_port);

        //OPEN PORT AT NEW BAUD RATE
        if ((usb_port = open(radiodevice, O_RDWR | O_NOCTTY | O_SYNC))>=0) {// | O_NOCTTY | O_SYNC
            std::cout << "DEVICE OPENED: " << radiodevice << " handle number: " << usb_port << std::endl;
        } else {
            fprintf(stderr, "unable to open serial radiodevice");
            return -1;
        }
        if(tcgetattr(usb_port, &tty) != 0) {
            printf("Error %i \n", errno);
        }

        //RESET SERIAL BAUD RATE
        cfsetispeed(&tty, B230400);<---SET NEW BAUD RATE VALUE
        cfsetospeed(&tty, B230400);<---SET NEW BAUD RATE VALUE
        tty.c_cflag     &=  ~PARENB;            // Make 8n1
        tty.c_cflag     &=  ~CSTOPB;
        tty.c_cflag     &=  ~CSIZE;
        tty.c_cflag     |=  CS8;
        tty.c_cflag     &=  ~CRTSCTS;           // no flow control
        tty.c_cc[VMIN]   =  0;                  // read doesn't block
        tty.c_cc[VTIME]  =  5;                  // 0.5 seconds read timeout
        tty.c_iflag &= ~ISTRIP;
        tty.c_iflag &= ~INLCR;
        tty.c_iflag &= ~IGNCR;
        tty.c_iflag &= ~ICRNL;
        tty.c_oflag &= OPOST;
        tty.c_lflag &= ICANON;
        tcflush(usb_port,TCIOFLUSH);
        usleep(10000);
        if (tcsetattr(usb_port, TCSANOW, &tty) != 0) {
            printf("Error %i\n", errno);
        }

        //SEND BREAK COMMAND
        std::cout << "SENDING BREAK COMMAND" << std::endl;
        tcsendbreak(usb_port, 0);
        usleep(10000);

        //SET DEVICE TO AUTO-BAUD RATE DETECTION
        msg = "U";//CORRESPONDS TO DOCUMENTED CHARACTER 0x55
        write(usb_port, msg.c_str(), msg.size());

        //FLASH UNIT LED LIGHTS TO CONFIRM FINAL CONNECTION AT NEW BAUD RATE
        std::cout << "BLINKING LIGHTS" << std::endl;
        msg="sys set pindig GPIO11 1\r\n";
        write(usb_port, msg.c_str(), msg.size());
        usleep(1000000);
        msg="sys set pindig GPIO11 0\r\n";
        write(usb_port, msg.c_str(), msg.size());

        return usb_port;
    }
person Max    schedule 15.04.2020
comment
Ваши настройки termios бессмысленны. tty.c_oflag &= OPOST и tty.c_lflag &= ICANON; действительно то, что вы хотите? Это не устанавливает и не очищает канонические режимы; это сохраняет только те режимы, которые уже существуют. Значения VMIN и VTIME имеют значение только в (входном) неканоническом режиме. Какие режимы вы используете, а точнее собираетесь использовать? - person sawdust; 17.04.2020
comment
@sawdust Если честно, понятия не имею. Это работает, но я уверен, что его можно значительно улучшить. Вы рекомендуете полностью удалить флаг ICANON? - person Max; 23.04.2020