Как мне прочитать вывод программы на с ++? - PullRequest
0 голосов
/ 22 мая 2018

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

Код выводит что-то вроде этого (Кодв C ++)

________________________| RUBIK'S CUBE SOLVER |________________________

Input :

enter code here

White Side : Red Side : Orange Side : Blue Side : Green Side : Yellow Side : 
-------------------------------------------------

Turn these sides of the Cube in Clockwise Direction by 90 degrees in this exact order...

Yellow
Yellow
White
Orange

...

Вот фрагмент кода, я подумал, могу ли я добавить какую-то функцию, которая читает «cout» и отправлять ее непосредственноarduino

  if (choice=='w')

{
cout<<"White"<<endl;
swap(white[7],white[3]);
swap(white[6],white[4]);
swap(white[0],white[2]);
swap(white[7],white[5]);
swap(white[0],white[4]);
...

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

1 Ответ

0 голосов
/ 25 мая 2018

Пожалуйста, не публикуйте повторяющиеся вопросы.

  1. Вывод вашего решателя (цветовых команд) не имеет особого смысла

    дасту вас головные боли на стороне MCU .Лучше использовать стандартные обозначения команд вращения L,R,U,D,F,B, как здесь

    rotations

    Вы можете различать направления CW / CCW , используя строчные / прописные буквы.Таким образом, вы точно знаете, какой срез и в каком направлении вращаться.

    Запуск кода решателя непосредственно на MCU может быть медленным (особенно если он основан на жанрах & test + backtracking).В случае простого человека, как решатель (как я использовал в ссылке выше) MCU вычислительная мощность должна быть более чем достаточно.

  2. Теперь, как кормитьваши данные из решателя (предполагается, что Windows PC) в MCU?

    Самый простой способ - использовать RS232 , но для этого вам нужен преобразователь напряжения, например MAX232 (вашПлата MCU , вероятно, имеет ее или использует какой-либо чип USB в качестве USB2RS232 преобразователя в TTL напряжениях типа FTDI илиеще один маленький MCU ).

    Итак, вам нужно написать парсер, который будет принимать ваш файл (или поток или что-то еще) на стороне ПК (может быть тем же исполняемым файлом, где вырешить) преобразовать команды в один тип char U,D,L,R,F,B и отправить их в RS232 .

    То же самое можно сделать с USB , но это намного сложнее из-занужно для драйверов и многое другое на стороне ПК и MCU , что не очень хорошоИдея начать с новичка.

    В Windows вы просто открываете файл, например COM1, задаете его свойства и читаете / записываете свои вещи из / в него (так же, как это будет файл).Вот небольшой Win32 C ++ / VCL lib port.h, который я написал давным-давно для таких вещей:

    //---------------------------------------------------------------------------
    //--- port class ver: 2.0 ------------------------------------------------
    //---------------------------------------------------------------------------
    #ifndef _port_h
    #define _port_h
    //---------------------------------------------------------------------------
    class port
            {
    public: HANDLE       hnd;
            DWORD        error;
            DWORD        rlen,wlen;
            DCB          rs232_state;
            COMMPROP     properties;
            COMMTIMEOUTS timeouts;
            COMSTAT      stat;
            port();
            ~port();
            int  open(AnsiString name);
            void close();
            int  get_stat();        // err,stat
            int  get_timeouts();    // timeouts
            int  set_timeouts();
            int  get_properties();  // properties
            int  get_rs232_state(); // rs232_state
            int  set_rs232_state();
            void rst_rs232_state();
            void out(BYTE data)  { WriteFile(hnd,&data,1,&wlen,NULL); }
            void in (BYTE *data) { ReadFile (hnd, data,1,&rlen,NULL); }
            void in (char *data) { ReadFile (hnd, data,1,&rlen,NULL); }
            void out(BYTE *data,DWORD len) { WriteFile(hnd,data,len,&wlen,NULL); }
            void in (BYTE *data,DWORD len) { ReadFile (hnd,data,len,&rlen,NULL); }
            };
    //---------------------------------------------------------------------------
    port::port()
            {
            rlen=0;
            wlen=0;
            error=0;
            hnd=(void*)0xFFFFFFFF;
            rst_rs232_state();
            }
    //---------------------------------------------------------------------------
    port::~port()
            {
            close();
            }
    //---------------------------------------------------------------------------
    int port::open(AnsiString name)
            {
            close();
            error=0;
            rlen=0;
            wlen=0;
            hnd=CreateFile( name.c_str(),GENERIC_READ | GENERIC_WRITE,0,NULL,OPEN_ALWAYS,0,NULL);
            error=GetLastError();
            if ((DWORD)hnd==0xFFFFFFFF) return 0;
            get_timeouts();
            get_properties();
            get_rs232_state();
    
            timeouts.ReadIntervalTimeout;
            timeouts.ReadTotalTimeoutMultiplier;
            timeouts.ReadTotalTimeoutConstant;
            timeouts.WriteTotalTimeoutMultiplier;
            timeouts.WriteTotalTimeoutConstant;
    
            properties.wPacketLength;
            properties.wPacketVersion;
            properties.dwServiceMask;
            properties.dwReserved1;
            properties.dwMaxTxQueue;
            properties.dwMaxRxQueue;
            properties.dwMaxBaud;
            properties.dwProvSubType;
            properties.dwProvCapabilities;
            properties.dwSettableParams;
            properties.dwSettableBaud;
            properties.wSettableData;
            properties.wSettableStopParity;
            properties.dwCurrentTxQueue;
            properties.dwCurrentRxQueue;
            properties.dwProvSpec1;
            properties.dwProvSpec2;
            properties.wcProvChar[1];
    
            return 1;
            }
    //---------------------------------------------------------------------------
    void port::close()
            {
            if ((DWORD)hnd==0xFFFFFFFF) return;
            CloseHandle(hnd);
            error=GetLastError();
            hnd=(void*)0xFFFFFFFF;
            }
    //---------------------------------------------------------------------------
    int port::get_stat()
            {
            if ((DWORD)hnd==0xFFFFFFFF) return 0;
            DWORD err;
            if (ClearCommError(hnd,&err,&stat)) return 1;
            error=GetLastError();
            return 0;
            }
    //---------------------------------------------------------------------------
    int port::get_timeouts()
            {
            if ((DWORD)hnd==0xFFFFFFFF) return 0;
            if (GetCommTimeouts(hnd,&timeouts)) return 1;
            error=GetLastError();
            get_stat();
            return 0;
            }
    //---------------------------------------------------------------------------
    int port::set_timeouts()
            {
            if ((DWORD)hnd==0xFFFFFFFF) return 0;
            if (SetCommTimeouts(hnd,&timeouts)) return 1;
            error=GetLastError();
            get_stat();
            return 0;
            }
    //---------------------------------------------------------------------------
    int port::get_properties()
            {
            if ((DWORD)hnd==0xFFFFFFFF) return 0;
            if (GetCommProperties(hnd,&properties)) return 1;
            error=GetLastError();
            get_stat();
            return 0;
            }
    //---------------------------------------------------------------------------
    int port::get_rs232_state()
            {
            if ((DWORD)hnd==0xFFFFFFFF) return 0;
            if (GetCommState(hnd,&rs232_state)) return 1;
            error=GetLastError();
            get_stat();
            return 0;
            }
    //---------------------------------------------------------------------------
    int port::set_rs232_state()
            {
            if ((DWORD)hnd==0xFFFFFFFF) return 0;
            if (SetCommState(hnd,&rs232_state)) return 1;
            error=GetLastError();
            get_stat();
            return 0;
            }
    //---------------------------------------------------------------------------
    void port::rst_rs232_state()
            {
            rs232_state.BaudRate    = CBR_9600;
            rs232_state.ByteSize    = 8;
            rs232_state.Parity      = NOPARITY;
            rs232_state.StopBits    = ONESTOPBIT;
            rs232_state.fOutxCtsFlow= FALSE;
            rs232_state.fOutxDsrFlow= FALSE;
            rs232_state.fOutX       = FALSE;
            rs232_state.fInX        = FALSE;
            rs232_state.fBinary     = FALSE;
            rs232_state.fRtsControl = RTS_CONTROL_DISABLE;
            }
    //---------------------------------------------------------------------------
    //---------------------------------------------------------------------------
    //---------------------------------------------------------------------------
    #endif
    //---------------------------------------------------------------------------
    

    Единственный материал, который он использует из VCL , этоAnsiString, который является строковым типом данных с индексным доступом, индексированным с 1 вместо 0.AnsiString s; s.c_str(); просто возвращает указатель char*, так что вы можете напрямую перенести все это на char* или тип строки, который есть в вашем распоряжении.

    При работе с RS232 вы должны принятьИмейте в виду, что вам нужна какая-то синхронизация, потому что другая сторона никогда не узнает, получает ли она данные с начала или некоторые данные были отправлены уже до инициализации.Поэтому вы должны добавить некоторые команды начала / окончания в ваш поток решателя.

    Вы также можете одновременно читать и записывать RS232 , но вам нужно использовать потоки для правильной реализации.Вот как я обычно это делаю:

    #include <windows.h>
    //typedef uint32_t DWORD;           // uncomment this if no DWORD type is present
    //typedef uint16_t WORD;            // uncomment this if no WORD type is present
    //typedef uint8_t BYTE;             // uncomment this if no BYTE type is present
    #include "port.h"
    
    port com;
    const int _timeout=1;
    const BYTE _id_timeout=0;
    unsigned char q;
    
    // init or reconnect
    com.open("COM1"); // use number of your COM port to use can be different than 1 especially for USB converters see device manager)
    com.timeouts.ReadIntervalTimeout        =_timeout;
    com.timeouts.ReadTotalTimeoutMultiplier =_timeout;
    com.timeouts.ReadTotalTimeoutConstant   =_timeout;
    com.timeouts.WriteTotalTimeoutMultiplier=_timeout;
    com.timeouts.WriteTotalTimeoutConstant  =_timeout;
    com.set_timeouts();
    com.rs232_state.BaudRate=CBR_9600;
    com.set_rs232_state();
    
    // write
    q='L';
    com.out(q);
    
    // read (this can freeze if no data in RS232 and timeout set too big)
    q=_id_timeout;
    com.in (&q);
    if (q==_id_timeout) /* do something if timeout*/ ;
    else /* handle valid data*/ ;
    
    // exit
    com.close();
    

    Если ваша среда не знает BYTE, WORD, DWORD, измените их с помощью uint8_t, uint16_t, uint32_t или используйте typedef. WinAPI функции должны включать windows.h.

    . Как я уже говорил, помните, что чтение порта COM без фактической отправки данных с другой стороны может заморозить ваш код, так чтоЛучше разделять операции чтения и записи на потоки или иметь короткие тайм-ауты и учитывать потерю данных из-за зависаний.

    Перед переходом на MCU вам следует проверить, является ли ваш ПККод стороны работает (так как вы можете гораздо легче отладить сторону PC , чем сторону MCU ).Итак, кодовый эмулятор вашего MCU , который будет читать RS232 фид из вашего решателя и печатать его где-нибудь как консоль или что-то еще, чтобы вы могли видеть, верны ли данные.Затем подключите RS232 по шлейфу (контакты RxD и Txd по короткому замыканию проводом) ...

  3. Код на стороне MCU

    должен делать более или менее то же самое, но у вас нет winapi в вашем распоряжении, поэтому вам нужно использовать фреймворк, который у вас есть.Большинство MCU перегружены iostream на RS232 , поэтому вы просто используете cin/cout вместо всего этого.Я не кодирую в Arduino framework (я использую C ++ ( GCC ) для MCU s) и там RS232 / UART доступ зависит от MCU архитектура и версия микросхемы, поэтому они не могут вам помочь.

    Важно помнить, что вам нужно настроить протокол RS232 так же, как на стороне ПК.Таким образом, такое же количество пусков / остановов / битов четности, та же BaudRate и т. Д ...

...