Программа для связи с Arduino

Тема в разделе "Arduino & Shields", создана пользователем Макси, 30 сен 2017.

  1. Макси

    Макси Нуб

    Добрый день.
    Ребята поскажите как с терминала отпралять команду на com-port в который подключена ардуино?
    Дело вот в чем пробую сделать машинку управляемую с компьютера. Клавишами w s a d (как в играх =) ). Так вот написал скетч и через монитор порта отправляю команды,это оно отрабатывает на ура. Но хочется сделать чтобы работало по нажатию клавиши, тоесть пока её держу двигатели работаю отпускаю, не работаю. Думаю это сделать отдельной прогой на С посылающую в терминал состояние клавишь... Или это дело можно както сделать по другому?
     
  2. Igor68

    Igor68 Гуру

    Если умеете на PC открывать com-порт и работать с ним, то в чём проблема? Думаю на ардуино Вы сделали часть так сказать связи, насколько понятно из вопроса Вам надо что-то со стороны PC? Вам действительно надо со стороны PC? Дать пример? У Вас VisualStudio (для C)под Windows или Для Debian(Linux)?
     
    Макси нравится это.
  3. rkit

    rkit Гуру

    Сесть, прочитать документацию к своей ОС по работе с COM, по работе с клавиатурой, и написать программу.
     
  4. Igor68

    Igor68 Гуру

    вот как пример открытия порта (простите вырвал из своего):
    Код (C++):
    //==== PortOpen ===
    BOOL MRTUPortOpen(int port, int baud, UCHAR parity, UCHAR databits, UCHAR stopbit)
    {
        DWORD dwError;//,dwThreadID;
      DCB PortDCB;
      COMMTIMEOUTS CommTimeouts;
      HANDLE hPort;
      //
      if(port == 1)
          hPort = CreateFile(TEXT("COM1:"), // Pointer to the name of the port
                          GENERIC_READ | GENERIC_WRITE,
                                        // Access (read-write) mode
                          0,            // Share mode
                          NULL,         // Pointer to the security attribute
                          OPEN_EXISTING,// How to open the serial port
                          0,            // Port attributes
                          NULL);        // Handle to port with attribute
                                        // to copy
      else if(port == 2)
          hPort = CreateFile(TEXT("COM2:"), // Pointer to the name of the port
                          GENERIC_READ | GENERIC_WRITE,
                                        // Access (read-write) mode
                          0,            // Share mode
                          NULL,         // Pointer to the security attribute
                          OPEN_EXISTING,// How to open the serial port
                          0,            // Port attributes
                          NULL);        // Handle to port with attribute
                                        // to copy
       else if(port == 3)
          hPort = CreateFile(TEXT("COM3:"), // Pointer to the name of the port
                          GENERIC_READ | GENERIC_WRITE,
                                        // Access (read-write) mode
                          0,            // Share mode
                          NULL,         // Pointer to the security attribute
                          OPEN_EXISTING,// How to open the serial port
                          0,            // Port attributes
                          NULL);        // Handle to port with attribute
                                        // to copy
       else if(port == 4)
          hPort = CreateFile(TEXT("COM4:"), // Pointer to the name of the port
                          GENERIC_READ | GENERIC_WRITE,
                                        // Access (read-write) mode
                          0,            // Share mode
                          NULL,         // Pointer to the security attribute
                          OPEN_EXISTING,// How to open the serial port
                          0,            // Port attributes
                          NULL);        // Handle to port with attribute
                                        // to copy
       else
           return FALSE;

      // If it fails to open the port, return FALSE.
      if ( hPort == INVALID_HANDLE_VALUE )
      {
        // Could not open the port.
        //MessageBox (hMainWnd, TEXT("Unable to open the port"),
        //            TEXT("Error"), MB_OK);
        dwError = GetLastError ();
        return FALSE;
      }

      PortDCB.DCBlength = sizeof (DCB);

      // Get the default port setting information.
      GetCommState (hPort, &PortDCB);

      // Change the DCB structure settings.
      PortDCB.BaudRate = baud;              // Current baud
      PortDCB.fBinary = TRUE;               // Binary mode; no EOF check
      PortDCB.fParity = FALSE; //TRUE;               // Enable parity checking
      PortDCB.fOutxCtsFlow = FALSE;         // No CTS output flow control
      PortDCB.fOutxDsrFlow = FALSE;         // No DSR output flow control
      PortDCB.fDtrControl = DTR_CONTROL_ENABLE;
                                            // DTR flow control type
      PortDCB.fDsrSensitivity = FALSE;      // DSR sensitivity
      PortDCB.fTXContinueOnXoff = FALSE;//TRUE;     // XOFF continues Tx
      PortDCB.fOutX = FALSE;                // No XON/XOFF out flow control
      PortDCB.fInX = FALSE;                 // No XON/XOFF in flow control
      PortDCB.fErrorChar = FALSE;           // Disable error replacement
      PortDCB.fNull = FALSE;                // Disable null stripping
      PortDCB.fRtsControl = RTS_CONTROL_ENABLE;
                                            // RTS flow control
      PortDCB.fAbortOnError = FALSE;        // Do not abort reads/writes on
                                            // error
      PortDCB.ByteSize = databits;//8;                 // Number of bits/byte, 4-8
      PortDCB.Parity = parity; //NOPARITY;            // 0-4=no,odd,even,mark,space
      PortDCB.StopBits = stopbit;//ONESTOPBIT;        // 0,1,2 = 1, 1.5, 2

      // Configure the port according to the specifications of the DCB
      // structure.
      if (!SetCommState (hPort, &PortDCB))
      {
        // Could not create the read thread.
        //MessageBox (hMainWnd, TEXT("Unable to configure the serial port"),
        //            TEXT("Error"), MB_OK);
        dwError = GetLastError ();
        return FALSE;
      }

      // Retrieve the time-out parameters for all read and write operations
      // on the port.
      GetCommTimeouts (hPort, &CommTimeouts);

      // Change the COMMTIMEOUTS structure settings.
      CommTimeouts.ReadIntervalTimeout = MAXDWORD;
      CommTimeouts.ReadTotalTimeoutMultiplier = 0;
      CommTimeouts.ReadTotalTimeoutConstant = 0;
      CommTimeouts.WriteTotalTimeoutMultiplier = 10;
      CommTimeouts.WriteTotalTimeoutConstant = 1000;

      // Set the time-out parameters for all read and write operations
      // on the port.
      if (!SetCommTimeouts (hPort, &CommTimeouts))
      {
        // Could not create the read thread.
        //MessageBox (hMainWnd, TEXT("Unable to set the time-out parameters"),
        //            TEXT("Error"), MB_OK);
        dwError = GetLastError ();
        return FALSE;
      }

      // Direct the port to perform extended functions SETDTR and SETRTS
      // SETDTR: Sends the DTR (data-terminal-ready) signal.
      // SETRTS: Sends the RTS (request-to-send) signal.
      //========
      EscapeCommFunction (hPort, CLRDTR);
      EscapeCommFunction (hPort, CLRDTR);

      // Create a read thread for reading data from the communication port.
      //if (hReadThread = CreateThread (NULL, 0, PortReadThread, 0, 0,
      //                                &dwThreadID))
      //{
      //  CloseHandle (hReadThread);
      //}
      //else
      //{
        // Could not create the read thread.
        //MessageBox (hMainWnd, TEXT("Unable to create the read thread"),
        //            TEXT("Error"), MB_OK);
        //dwError = GetLastError ();
        //return FALSE;
      //}

      if(port == 1)
          ModbusRTU1.hPort = hPort;
      else if(port == 2)
          ModbusRTU2.hPort = hPort;
      else if(port == 3)
          ModbusRTU3.hPort = hPort;
      else if(port == 4)
          ModbusRTU4.hPort = hPort;
      //
      return TRUE;
    }
    тут открытие порта (я делал Modbus RTU)
    Делал для Windows CE(UNO-1019).
    Или кинуть весь проект, а Вы вырвете всё, что надо?
     
    Последнее редактирование: 30 сен 2017
    arkadyf и Макси нравится это.
  5. Макси

    Макси Нуб

    Я под linux-ом, да со стороны ардуино все готово. Я не знаю как работать с ком портом, гдеб библиотеку какую взять. вроде нашел https://github.com/todbot/arduino-serial но вкурить как она работает пока не могу
     
  6. Igor68

    Igor68 Гуру

    для линукс ещё проще и демократичнее:
    Код (C++):
    int IA241sopen(int port, uint mode, int baud, int parity, int databits, int stopbit)
    {
        int fd;
        int i, table_size= 23;
        //unsigned int mode = RS485_2WIRE_MODE;
        char device[ 80];
        struct termios tio;
        //===== speed tables ======
        int speed_table1[]={ 0, 50, 75, 110, 134, 150, 200, 300,
                     600, 1200, 1800, 2400, 4800, 9600,
                     19200, 38400, 57600, 115200, 230400,
                     460800, 500000, 576000, 921600};
        int speed_table2[]={ B0, B50, B75, B110, B134, B150, B200, B300,
                     B600, B1200, B1800, B2400, B4800, B9600,
                     B19200, B38400, B57600, B115200, B230400,
                     B460800, B500000, B576000, B921600};
        //=========================
        for( i= 1; i< table_size; i++)    ///< i start from 1, bellow 50 will be set to B0
            if( speed_table1[ i] >= baud)
                break;
        //cfsetispeed( &newtio[ port], speed_table2[ i]);
        //cfsetospeed( &newtio[ port], speed_table2[ i]);
        //tcsetattr( fd, TCSANOW, &newtio[ port]);
        //
        //if( fd_map[ port] != -1)        ///< port already opened
            //return SERIAL_ERROR_OPEN;

        sprintf( device, "/dev/ttyM%d", port);
        fd = open( device, O_RDWR);
        if( fd <0)
        {
            //printf("open error !!!");
            //getchar();
            return IA241_SERIAL_ERROR_OPEN;
        }
        //
        ioctl( fd, MOXA_SET_OP_MODE, &mode);
        fd_map[ port]= fd;
        bzero( &tio, sizeof(tio));        ///< clear struct for new port settings
        tio.c_iflag = 0;
        tio.c_oflag = 0;
        tio.c_cflag = speed_table2[ i];// | CS8 | CREAD | CLOCAL;
        tio.c_lflag = 0;
        tio.c_cc[ VTIME] = 0;            ///< inter-character timer unused
        tio.c_cc[ VMIN] = 1;            ///< blocking read until 1 character arrives
        //tcgetattr( fd, &(oldtio[ port]));    ///< save current serial port settings
        //newtio[port]= tio;
        //newtio[port].c_cflag |= CRTSCTS;
        //newtio[port].c_cflag |= CS8;
        if( parity == 0)
        {
            newtio[ port].c_cflag &= ~PARENB;
            newtio[ port].c_iflag &= ~INPCK;
        }
        else if( parity == 1)
        {
            newtio[ port].c_cflag |= PARENB;
            newtio[ port].c_cflag |= PARODD;
            newtio[ port].c_iflag |= INPCK;
        }
        else if( parity == 2)
        {
            newtio[ port].c_cflag |= PARENB;
            newtio[ port].c_cflag &= ~PARODD;
        }
        else if( parity == 3)
        {
            newtio[ port].c_cflag &= ~PARENB;
            newtio[ port].c_cflag &= ~CSTOPB;
        }
        else if( parity == 4)
        {
            newtio[ port].c_cflag |= CSTOPB;
            newtio[ port].c_cflag &= ~PARENB;
            newtio[ port].c_iflag &= ~INPCK;
        }

        if( databits == 5)
            newtio[ port].c_cflag |= CS5;
        else if( databits == 6)
            newtio[ port].c_cflag |= CS6;
        else if( databits == 7)
            newtio[ port].c_cflag |= CS7;
        else if( databits == 8)
            newtio[ port].c_cflag |= CS8;

        if( stopbit == 1)
            newtio[ port].c_cflag &= ~CSTOPB;
        else if( stopbit == 2)
            newtio[ port].c_cflag |= CSTOPB;

        tcflush( fd, TCIFLUSH);
        tcsetattr( fd, TCSANOW, &newtio[ port]);
        //
        tcflush(fd, TCIOFLUSH);
        //tcsetattr( fd, TCSANOW, &newtio[port]);
        //
        //tcflow(fd,TCOON);
        cfsetispeed( &newtio[ port], speed_table2[ i]);
        cfsetospeed( &newtio[ port], speed_table2[ i]);
        tcsetattr( fd, TCSANOW, &newtio[ port]);
        //
        return 0;
    }

    int    IA241sclose( int port)
    {
        int fd = IA241sfindFD( port);

        if( fd < 0)            ///< error
            return fd;

        tcsetattr( fd, TCSANOW, &(oldtio[ port]));
        close( fd);

        fd_map[ port]= -1;

        return IA241_SERIAL_OK;
    }
     
    Тут правда для moxa как пример... но для открытия порта никаких библиотек не надо. В /dev надо только найти ваше tty устройство. Вот от подключенной прямо сейчас моха uc7112plus:
    Код (Bash):
    www-data@Moxa:~/ramdisk$ ls /dev
    console    ipsec      mmc2       mtd3       mtdblock2  mxmisc     ptyp0      ptyp5      ram0       rtc        swtd       tty3       tty8       ttyp0      ttyp5      urandom
    cua0       kmem       mmc3       mtd4       mtdblock3  net        ptyp1      ptyp6      ram1       sda        tty        tty4       tty9       ttyp1      ttyp6      zero
    cua1       mem        mtd0       mtd5       mtdblock4  null       ptyp2      ptyp7      ram2       sda1       tty0       tty5       ttyM0      ttyp2      ttyp7
    dio        mmc        mtd1       mtdblock0  mtdblock5  ppp        ptyp3      ptyp8      ram3       sda2       tty1       tty6       ttyM1      ttyp3      ttyp8
    initctl    mmc1       mtd2       mtdblock1  mxcrypto   pts        ptyp4      ptyp9      random     shm        tty2       tty7       ttyS0      ttyp4      ttyp9
    www-data@Moxa:~/ramdisk$
     
    скажу, что в коде применено имя устройства dev/ttyM<XXX> понятно, что <XXX> это номер. Посмотрите по ls /dev. И про разрешения не надо забывать:
    Код (Bash):
    www-data@Moxa:~/ramdisk$ ls /dev -al
    drwxr-xr-x    5 root     root         2048 Jun  5  2009 .
    drwxr-xr-x   15 root     root            0 Jan  1  1970 ..
    crwxrwxrwx    1 root     root       5,   1 Sep 30 16:53 console
    crwxrwxrwx    1 root     root       5,  64 Jan  1  1970 cua0
    crwxrwxrwx    1 root     root       5,  65 Jan  1  1970 cua1
    crwxrwxrwx    1 root     root      10, 104 Jan  8  2006 dio
    prw-r--r--    1 root     root            0 Jan  1  1970 initctl
    crwxrwxrwx    1 root     root      36,  10 Jan  1  1970 ipsec
    crwxrwxrwx    1 root     root       1,   2 Jan  1  1970 kmem
    crwxrwxrwx    1 root     root       1,   1 Jan  1  1970 mem
    brwxrwxrwx    1 root     root     121,   0 Dec 12  2005 mmc
    brwxrwxrwx    1 root     root     121,   1 Dec 12  2005 mmc1
    brwxrwxrwx    1 root     root     121,   2 Dec 12  2005 mmc2
    brwxrwxrwx    1 root     root     121,   3 Dec 12  2005 mmc3
    crwxrwxrwx    1 root     root      90,   0 Jan  1  1970 mtd0
    crwxrwxrwx    1 root     root      90,   2 Jan  1  1970 mtd1
    crwxrwxrwx    1 root     root      90,   4 Jan  1  1970 mtd2
    crwxrwxrwx    1 root     root      90,   6 Jan  1  1970 mtd3
    crwxrwxrwx    1 root     root      90,   8 Dec 14  2005 mtd4
    crwxrwxrwx    1 root     root      90,  10 Dec 14  2005 mtd5
    brwxrwxrwx    1 root     root      31,   0 Jan  1  1970 mtdblock0
    brwxrwxrwx    1 root     root      31,   1 Jan  1  1970 mtdblock1
    brwxrwxrwx    1 root     root      31,   2 Jan  1  1970 mtdblock2
    brwxrwxrwx    1 root     root      31,   3 Jan  1  1970 mtdblock3
    brwxrwxrwx    1 root     root      31,   4 Dec 14  2005 mtdblock4
    brwxrwxrwx    1 root     root      31,   5 Dec 14  2005 mtdblock5
    crw-r--r--    1 root     root      11, 131 Dec  5  2006 mxcrypto
    crwxrwxrwx    1 root     root      10, 105 Feb 14  2006 mxmisc
    drwxrwxrwx    2 root     root         1024 Jan 29  2007 net
    crwxrwxrwx    1 root     root       1,   3 Jan  1  1970 null
    crwxrwxrwx    1 root     root     108,   0 Jan  1  1970 ppp
    drwxr-xr-x    2 root     root            0 Jan  1  1970 pts
    crwxrwxrwx    1 root     root       2,   0 Oct  1 01:36 ptyp0
    crwxrwxrwx    1 root     root       2,   1 Jan  1  1970 ptyp1
    crwxrwxrwx    1 root     root       2,   2 Jan  1  1970 ptyp2
    crwxrwxrwx    1 root     root       2,   3 Jan  1  1970 ptyp3
    crwxrwxrwx    1 root     root       2,   4 Jan  1  1970 ptyp4
    crwxrwxrwx    1 root     root       2,   5 Jan  1  1970 ptyp5
    crwxrwxrwx    1 root     root       2,   6 Jan  1  1970 ptyp6
    crwxrwxrwx    1 root     root       2,   7 Jan  1  1970 ptyp7
    crwxrwxrwx    1 root     root       2,   8 Jan  1  1970 ptyp8
    crwxrwxrwx    1 root     root       2,   9 Jan  1  1970 ptyp9
    brwxrwxrwx    1 root     root       1,   0 Jan  1  1970 ram0
    brwxrwxrwx    1 root     root       1,   1 Jan  1  1970 ram1
    brwxrwxrwx    1 root     root       1,   2 Jan  1  1970 ram2
    brwxrwxrwx    1 root     root       1,   3 Jan  1  1970 ram3
    crwxrwxrwx    1 root     root       1,   8 Jan  1  1970 random
    crwxrwxrwx    1 root     root      10, 135 Dec 27  2005 rtc
    brwxrwxrwx    1 root     root       8,   0 Dec 30  2005 sda
    brwxrwxrwx    1 root     root       8,   1 Dec 30  2005 sda1
    brwxrwxrwx    1 root     root       8,   2 Dec 30  2005 sda2
    drwxrwxrwt    2 root     root           40 Sep 30 16:07 shm
    crwxrwxrwx    1 root     root      10, 106 Feb 15  2006 swtd
    crwxrwxrwx    1 root     root       5,   0 Sep 30 16:53 tty
    crwxrwxrwx    1 root     root       4,   0 Jan  1  1970 tty0
    crwxrwxrwx    1 root     root       4,   1 Jan  1  1970 tty1
    crwxrwxrwx    1 root     root       4,   2 Jan  1  1970 tty2
    crwxrwxrwx    1 root     root       4,   3 Jan  1  1970 tty3
    crwxrwxrwx    1 root     root       4,   4 Jan  1  1970 tty4
    crwxrwxrwx    1 root     root       4,   5 Jan  1  1970 tty5
    crwxrwxrwx    1 root     root       4,   6 Jan  1  1970 tty6
    crwxrwxrwx    1 root     root       4,   7 Jan  1  1970 tty7
    crwxrwxrwx    1 root     root       4,   8 Jan  1  1970 tty8
    crwxrwxrwx    1 root     root       4,   9 Jan  1  1970 tty9
    crwxrwxrwx    1 root     root      30,   0 Feb  7  2007 ttyM0
    crwxrwxrwx    1 root     root      30,   1 Feb  7  2007 ttyM1
    crwxrwxrwx    1 root     root       4,  64 Jan  1  1970 ttyS0
    crw-------    1 root     root       3,   0 Oct  1 01:36 ttyp0
    crwxrwxrwx    1 root     root       3,   1 Jan  1  1970 ttyp1
    crwxrwxrwx    1 root     root       3,   2 Jan  1  1970 ttyp2
    crwxrwxrwx    1 root     root       3,   3 Jan  1  1970 ttyp3
    crwxrwxrwx    1 root     root       3,   4 Jan  1  1970 ttyp4
    crwxrwxrwx    1 root     root       3,   5 Jan  1  1970 ttyp5
    crwxrwxrwx    1 root     root       3,   6 Jan  1  1970 ttyp6
    crwxrwxrwx    1 root     root       3,   7 Jan  1  1970 ttyp7
    crwxrwxrwx    1 root     root       3,   8 Jan  1  1970 ttyp8
    crwxrwxrwx    1 root     root       3,   9 Jan  1  1970 ttyp9
    crwxrwxrwx    1 root     root       1,   9 Jan  1  1970 urandom
    crwxrwxrwx    1 root     root       1,   5 Jan  1  1970 zero
    www-data@Moxa:~/ramdisk$
     
    На moxa два com порта как ttyM0 и ttyM1. Пример в виде проекта надо?
     
    Последнее редактирование: 30 сен 2017
    arkadyf и Макси нравится это.
  7. Igor68

    Igor68 Гуру

    Вот кстати для малины Raspbian... но аналогично и в Debian на PC:
    Код (C++):
    int MRTU_Connect(char* strPort)
    {
        fd = open(strPort, O_RDWR | O_NOCTTY | O_NDELAY);
        //
        if (fd == -1) {
                perror(strPort);
                return -1;
            }
        //
        if (tcgetattr(fd, &serial) < 0) {
                perror("Getting configuration");
                return -1;
            }
        // Set up Serial Configuration
    /*        serial.c_iflag = 0;
            serial.c_oflag = 0;
            serial.c_lflag = 0;
            serial.c_cflag = 0;
            serial.c_cc[VMIN] = 0;
            serial.c_cc[VTIME] = 0;
    */

            serial.c_cflag = B9600| CS8 | CREAD;
            tcsetattr(fd, TCSANOW, &serial); // Apply configuration
        //
        return 0;
    }
    Простите... совсем забыл про подключения заголовочных файлов и глобальных параметров:
    Код (C++):
    //mrtu.c
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <unistd.h>
    #include <fcntl.h>
    #include <termios.h>
    #include "mrtu.h"
    #include "types.h"

    int    fd;
    struct termios serial;
    U8    rxbuf[_szbuf];
    U8    txbuf[_szbuf];
     
    Если что надо скажИте. ОтвЕчу.
     
    Последнее редактирование: 30 сен 2017
    arkadyf и Макси нравится это.
  8. Igor68

    Igor68 Гуру

    Простите... ещё - тот порт, если по USB-SERIAL будет ttyUSB<n>, где n-номер по ls /dev
     
    arkadyf и Макси нравится это.
  9. Макси

    Макси Нуб

    Спасибо сейчас буду смотреть
     
  10. Макси

    Макси Нуб

    А может какой нибудь пример есть с передачей и приемом данных?
     
  11. Igor68

    Igor68 Гуру

    Вы готовы вырвать то, что надо из проекта? Сейчас скину проект. Надо будет поясню. Не ругайте за что-нибудь.
     
  12. Макси

    Макси Нуб

    Кидайте, хоть глазком глянуть как гуру пишут :)
     
  13. Igor68

    Igor68 Гуру

    Не ругайте, но там работа с ардуино из малины (Raspbian)
    MRTU_Pi.zip
    Найдёте работу с последовательным портом. Поверьте правила те же, что и с Debian на ПК.
     

    Вложения:

    • MRTU_Pi.zip
      Размер файла:
      62,9 КБ
      Просмотров:
      277
    arkadyf и Макси нравится это.
  14. Igor68

    Igor68 Гуру

    Я не гуру и не круче, чем Вы. Всё познаётся. Только если не понятно - надо оказывать помощь по возможности. Всё поясню!
     
    Макси нравится это.
  15. Макси

    Макси Нуб

    Спассибо. Буду смотреть. :)
     
  16. Igor68

    Igor68 Гуру

    Упростит если Вы применяете QtCreator... ну не как метод, а как для окончательного решения или реализации.