Показано с 1 по 5 из 5

Тема: ПР-200 + драйвер шагового двигателя

  1. #1

    По умолчанию ПР-200 + драйвер шагового двигателя

    Добрый день!

    Подскажите пожалуйста разрабатываем систему на основе ПР-200 сможет ли данный прибор управлять драйвером
    https://electroprivod.ru/smsd-4.2rs.htm

    протокол RS-485 не стакдартный, не MOДБАС , похоже ASKII

    посмотрите пожалуйста структуру посылки, по зубам ли это ПР-200?

  2. #2

    По умолчанию

    Нет, на ПР-200 вы не сформируете отправку таких команд


    Для ПР подойдёт драйвер Onitex OSM-42RA

    ну или вообще-то надо понимать какая задача ставится, может вы и дискретными выходами обойдётесь, запишите программу в SMSD и будете её вызывать замыкая Пуск, и возвращать в начало командой Поиск 0.
    Последний раз редактировалось glazastik; 28.05.2021 в 11:41.

  3. #3
    Пользователь Аватар для petera
    Регистрация
    06.05.2011
    Адрес
    Минск
    Сообщений
    3,840

    По умолчанию

    Когда-то на СП300 хотел сделать программатор контроллера ШД https://owen.ru/forum/showthread.php...l=1#post244671
    Некий гибрид гипертерминала и OSM Programmer.
    Захват-1.png
    Скрытый текст:
    Последний раз редактировалось petera; 28.05.2021 в 11:55.
    Мой канал на ютубе
    https://www.youtube.com/c/ПетрАртюков
    Библиотека ГМ для СП300
    https://disk.yandex.com/d/gHLMhLi8x1_HBg

  4. #4

    По умолчанию

    Не ну в случае если СП300 общается с драйвером через modbus это я ещё понимаю.
    Но если надо сформировать ASCII команду и отправить её? СП разве на такое способна? Через макросы только если?

  5. #5
    Пользователь Аватар для petera
    Регистрация
    06.05.2011
    Адрес
    Минск
    Сообщений
    3,840

    По умолчанию

    Цитата Сообщение от glazastik Посмотреть сообщение
    Не ну в случае если СП300 общается с драйвером через modbus это я ещё понимаю.
    Но если надо сформировать ASCII команду и отправить её? СП разве на такое способна? Через макросы только если?
    Ну да, на Си есть прямой доступ к порту, можно любой протокол написать.
    Пример - гипертерминал в СП https://owen.ru/forum/showthread.php...l=1#post246881
    Код:
    /*
                                                    Макрос "ТЕРМИНАЛ"
    
                                              (с) petera для форума ОВЕН
    
     */
    
    // Used PSW Adr ---------------------
    #define SetupAdr        259
    #define KbdStatusAdr    260
    #define inAdr           300                 // (DWord) !!!
    #define bufAdr          500                 // buffer uses (lTotal x cTotal) Regs.!!!
    //-----------------------------------------------------------------------------------
    #define KbdStatus   PSW[KbdStatusAdr]       /* В битах этого регистра - состояние управляющих кнопок клавиатуры (Shift, Ctrl, Repead),
                                                   индикаторов "Прием", "Передача" и бит разрешения работы макроса */
    #define Setup       PSW[SetupAdr]           // Настройки режимов приема и передачи
    #define Input       PSW[inAdr]              // Буфер для приема символов с клавиатуры
    #define dwInput     *(DWORD*)(PSW + inAdr)  // -- // -- в формате DWord
    #define buffer      PSW[bufAdr]             /*Начальный адрес области регистров PSW из которых сделано текстовое окно терминала
                                                 для окна терминала будет занято (lTotal x cTotal) регистров PSW */
    
    //---Макро для чтения бит регистра Setup---------------------------------------------------------
    #define GetSetupStatus(bitno) ((Setup) & (1 << (bitno)))
    //---------------------------- назначение бит регистра Setup
    #define CRLFreceive     0   //При вводе с клавиатуры дополнять символ CR символом LF(перевод строки)
    #define CRLFsend        1   //Дополнять символ CR, полученный от удаленного терминала, символом LF(перевод строки)    
    #define BS_BSsend       3   //Передавать символ "backspace"(BS) как комбинацию из "BS"+"пробел"+"BS"
    #define Echo            4   /*Включить режим "Эхо". В режиме "Эхо" все денные,принятые от удаленного терминала
                                   тут же отправляются обратно, после чего обрабатываются и выводятся на экран */  
    #define Visible         5   /*"Показывать введенные символы". Символы, вводимые с клавиатуры, отправляются удаленному
                                   терминалу и также отображаются в окне. Если Visible=FALSE, то символы, вводимые с клавиатуры,
                                   отправляются удаленному терминалу, но на экран не выводятся.*/
    //---Макро для инверсии бит -------------------------------------------------------------------
    #define ReversPSB(PSB_No)     PSB[(PSB_No) / 8] ^= (1 << ((PSB_No) % 8)) /* В дополнение к существующим SetPSB(PSB_No) и ResetPSB(PSB_No)
                                                                              этот макро выполняет инверсию заданного PSB
        Пример:
        ReversPSB(256);                                                      *
    
    #define ReversBit(reg, bitno) ((reg) ^= (1 << (bitno)))                  //
    //---Макро для работы с битами регистра KbdStatus-----------------------------------------------
    #define GetKbdStatus(bitno)   ((KbdStatus) & (1 << (bitno)))
    #define ResetKbdStatus(bitno) ((KbdStatus) &= ( ~ (1 << ((bitno)))))
    #define SetKbdStatus(bitno)   ((KbdStatus) |= ( 1 << ((bitno))))
    //---------------------------- назначение бит регистра KbdStatus
    #define Shift           0       // Нажата кнопка Shift
    #define Ctrl            1       // Нажата кнопка Ctrl
    #define Repead          2       // Нажата кнопка Rep - повторение символов при вводе
    #define RunEnable       3       // Работа приема и передачи разешена 
    #define receiver        4       // Состояние индикатора "Прием"
    #define sender          5       // Состояние индикатора "Передача"
    #define ClrScreen       6       // Команда "Очистить экран"
    
    //------------------------------------------------------------------
    const int lTotal = 18;          // Количество строк в окне терминала
    const int cTotal = 80;          // Количество символов в одной строке
    const int tabs = 8;             // Кратность (в символах) позиций табуляции
    
    static int cCount, lCount;      // Номер текущей позиции в строке и Номер текущей строки
    static char savMark;            /* Сохраненный код символа, который скрыт курсором
                                       т.к. курсор может перемещаться на экране не только вперед, но и вверх,
                                       вниз и назад, то перед перемещением курсора в другую позицию необходимо
                                       сохранять код символа в том знакоместе, в котором окажется курсор после перемещения.
                                       И при последующем перемещании курсора возвращать сохраненный символ в знакоместо
                                       ранее занимаемое курсором */
                                    /* Курсор - мигающий символ '_', указывает знакоместо в окне терминала,
                                       в которое будет вводится очередной символ. Координаты курсора однозначно
                                       определяются переменными cCount и lCount */
    static BOOL init;               // Флаг инициализации(устанавливается после первого вызова макроса)
    
    BYTE byReceive[3] = {0x00};     /* Буфер приема для СОМ порта
                                       буфер приема имеет и второе назначение. Т.к. все, что пришло в буфер приема
                                       от удаленного терминала безусловно должно быть выведено на экран.
                                       Чтобы использовать этот же фрагмент кода вывода на экран и для вывода символов,
                                       вводимых с клавиатуры, буфер приема будет использован и при вводе данных с клавиатуры */
    BYTE bySend[3] = {0x00};        // Буфер передачи для СОМ порта
    BYTE *pBuff;                    // Указатель адреса символа в памяти регистров, отображаемых в окне терминала
    int i, count, tmp;
    BOOL flagSend, flagVisible;     // флаги - требуется вывод в СОМ порт, требуется вывод на экран
    
    //--------------------------------------------------------------------
    //pBuff = (BYTE *)&buffer + lCount * cTotal + cCount; //Установить указатель в текущую позицию курсора
    //--------------------------------
    
    //if ((lCount == 0) && (cCount == 0) && (savMark == 0)) { //Clr Screen.
    if (GetKbdStatus(ClrScreen) || !init) {	//Clr Screen
        ResetKbdStatus(ClrScreen);              //Сбросить бит команды
        init = TRUE;                                   
        memset(&buffer, ' ', cTotal * lTotal);  //Во все байты всех регистров отображаемых в окне терминала
        savMark = ' ';                          //будут записаны коды пробела - произойдет "очистка" окна терминала
        lCount = cCount = 0;                    //курсор в правый верхний угол окна терминала
        pBuff = (BYTE *)&buffer;                //Установить указатель на начало буфера окна
    
    }
    else pBuff = (BYTE *)&buffer + lCount * cTotal + cCount; //Установить указатель в текущую позицию курсора
    
    //-------------------------------
    if (!GetKbdStatus(RunEnable)) {             //Если работа макроса запрещена, то
        ResetKbdStatus(Repead);                 //"отжать" кнопку "rep"
        ResetKbdStatus(sender);                 //Выключить индикатор "Передача"
        ResetKbdStatus(receiver);               //Выключить индикатор "Прием"
        dwInput = 0;                            //Очистить буфер клавиатуры
        *pBuff = savMark;                       //Восстановить символ, скрытый курсором
        return;                                 //Завершить работу макроса
    }
    //-----------------------------
    flagSend = GetSetupStatus(Echo);            //Получить состояние настроек "Эхо" и "Показывать введенные символы"
    flagVisible = GetSetupStatus(Visible);
    
    Enter(PLC);                                 //Открыть порт PLC
    count = Receive(PLC, byReceive, 3, 100, 12);/*Читать 3 байта, TimeOut=100мс, TimeOutBytes=12мс(что это за зверь я не знаю)
                                                  значения тайм-аутов подбирал методом "научного тыка" на скорости 57600.
                                                  возможно, что при уменьшении скорости до 9600 TimeOut немного увеличить.
                                                  Макрос с TimeOut=100 будет работать и на скорости 115200,если в гипертерминале Windows
                                                  не зажимать клавиши до автоповтора, т.к. в редких случаях единичные символы
                                                  при приеме могут "проглатываться". Передедача из панели на 115200 без нареканий.*/  
    if (count == NULL) {                        //Если ничего не пришло, то проверить наличие символов в буфере клавиатуры
        if (dwInput == 0) {                     //Если и в буфере клавиатуры пусто
            flagSend = flagVisible = FALSE;     //то ничего не отправлять и ничего не выводить на экран
            count = 0;
        }
        else {                                  //А если кто-то нажимал кнопки клавиатуры, то
            SetKbdStatus(sender);               //Включить индикатор "Передача"
            ResetKbdStatus(receiver);           //Выключить индикатор "Прием""
            memcpy(&byReceive, &Input, 3);      /*Копировать три байта из буфера клавиатуры в буфер передачи
                                                  последующие манипуляции будем проводить с содержимым буфера передачи
                                                  его же в дальнейшем будем отправлять через СОМ порт и выводить на экран */
            //Проверить состояние управляющих кнопок 
            if (GetKbdStatus(Shift)) {                                       //Если нажата кнопка Shift
                if (((byReceive[0] >= 0x41) && (byReceive[0] <= 0x5A)) ||    //и введен код заглавной латинской буквы
                    ((byReceive[0] >= 0x61) && (byReceive[0] <= 0x7A)) ||    // или строчной латинской буквы
                     (byReceive[0] >= 0xC0))  ReversBit(byReceive[0], 5);    // или любой русской буквы, то поменять заглавную на строчную или наоборот
                else if ((byReceive[0] == 0xA8) ||                           // если введен код Ё или ё
                         (byReceive[0] == 0xB8)) ReversBit(byReceive[0], 4); // то и их поменять местами            
            }
            if (GetKbdStatus(Ctrl)) {      //Если нажата кнопка Ctrl, то заменить ЛАТИНСКИЕ БУКВЫ на управляющие коды
                if (((byReceive[0] >= 0x41) && (byReceive[0] <= 0x5A)) ||
                    ((byReceive[0] >= 0x61) && (byReceive[0] <= 0x7A)))  byReceive[0] = byReceive[0] & 0x1F;
                else  byReceive[0] = 0;    // Если это были не буквы, то ничего не отправлять и не выводить
            }
            //Возможно нужно изменить способ передачи символов CR(ctrl+M /Enter) или backspace - (ctrl+H /Delete)
            if (GetSetupStatus(CRLFsend) && (byReceive[0] == 0x0D)) byReceive[1] = 0x0A;    //Если нужно, то к CR добавить LF
            else if (GetSetupStatus(BS_BSsend) && (byReceive[0] == 0x08)) {                 //Если нужно, то к BS 
                byReceive[1] = 0x20;                                                        //добавить ' '
                byReceive[2] = 0x08;                                                        //и ещё один BS
            }
            count = strlen(byReceive);          //Возможно длина посылки теперь будет другой
            memcpy(&bySend, &byReceive, count); //Копировать то, что на вводили с клавиатуры в буфер передачи  
            flagSend = TRUE;                    //Разрешить передачу удаленному терминалу
                if (! GetKbdStatus(Repead)) {   //Если кнопка повтора не нажата, то 
                    dwInput = 0;                //очистить буфер клавиатуры
                    ResetKbdStatus(Ctrl);       //"отжать" кнопку Ctrl
                    ResetKbdStatus(Shift);      //"отжать" кнопку Shift 
                }                               /*А если кнопка повтора нажата, то код введенного символа и модификаторы Ctrl и Shift
                                                 запомнятся и будут заново отправлены в следующем цикле выполнения макроса */
            }
    }
    //Сюда попали, минуя обработку буфера клавиатуры, если буфер чтения СОМ порта не пустой
    else { 
        ResetKbdStatus(sender);                 //Выключить индикатор "Передача"
        SetKbdStatus(receiver);                 //Включить индикатор "прием"
        flagVisible = TRUE;                     //Выводить на экран содержимое буфера приема
        memcpy(&bySend, &byReceive, count);     //Копировать в буфер передачи из буфера приема все принятые символы
                                                //в неизменном виде на случай необходимости Эха удаленному терминалу
        if (GetSetupStatus(CRLFreceive) && (byReceive[0] == 0x0D)) {//Если нужно, то в буфере приема к полученным CR добавить LF
            byReceive[Min(2, count)] = 0x0A;
            count = Min(3, count+1);
        }
    }
    //------------------------------------
    // В эту точку можем попасть или после приема данных от удаленного терминала или после ввода символов с клавиатуры
    // и всегда если буфер приема из СОМ порта был пуст и буфер клавиатуры тоже пуст
    if ((count != NULL) && flagSend) {  //отправка данных удаленному терминалу необходима если есть, что отправлять и 
                                        //если, например включен флаг Эхо
        Send(PLC, bySend, count);       //отправка даанных удаленному терминалу
    }
    Leave(PLC);                         //Закрыть СОМ порт   
    //------------------------------------
    //Эта часть программы - вывод информации на экран
    if ((count == 3) && (byReceive[0] == 0x1B) && flagVisible) {    //Если в буфере приема три символа и код первого символа 0x1B
                                                                    // то в буфере Escape последовательность
            *pBuff = savMark;                               //восстановить в текущем знакоместе символ скрытый курсором 
            tmp = MAKEWORD(byReceive[2], byReceive[1]);     //Собрать два оставшихся в буфере символа "в кучку"
            switch (tmp) {
                case 0x5B41:    //Up                        //Это кнопка стрелка вверх
                    if (lCount != 0) {                      //Пока не достигнем верха окна терминала
                        lCount--;                           //переместим курсор в ту же позицию вышележащей строки
                        pBuff = pBuff - cTotal;             //пересчитать адрес нового положения курсора
                    }
                    break;
                case 0x5B42:    //Down                      //Это кнопка стрелка вниз
                    if (lCount != lTotal -1) {              //Пока не достигнем низа окна терминала
                        lCount++;                           //переместим курсор в ту же позицию нижележащей строки
                        pBuff = pBuff + cTotal;             //пересчитать адрес нового положения курсора
                    }
                    break;
                case 0x5B44:    //Left                      //Это кнопка стрелка влево
                    if (cCount != 0) {                      //Пока не достигнем левого края окна терминала
                        cCount--;                           //переместим курсор на одну позицию влево в той же строке
                        pBuff --;                           //пересчитать адрес нового положения курсора
                    }
                    break;
                case 0x5B43:    //Right                     //Это кнопка стрелка вправо
                    if (cCount != cTotal - 1) {             //Пока не достигнем правого края окна терминала
                        cCount++;                           //переместим курсор на одну позицию вправо в той же строке
                        pBuff++;                            //пересчитать адрес нового положения курсора
                    }
                    break;
                case 0x5B48:    //Home                      //Это кнопка Домой, т.е. 
                    lCount = 0;                             //переместить курсор в левый верхний угол окна терминала
                    cCount = 0;
                    pBuff = (BYTE *)&buffer;                //пересчитать адрес нового положения курсора (указатель на начало буфера)
                    break;
                case 0x5B4B:    //End                       //Кнопка End
                    *pBuff = ' ';                           //В позиции курсора записать пробел
                    memset(pBuff, ' ', cTotal - cCount);    //Удалить все символы от текущего положения курсора до донца строки
                    break;
            }
            savMark = *pBuff;                               //Сохранить символ в знакоместе экрана, на которое теперь будет указывать курсор
    }
    else if ((count != NULL) && flagVisible) {              //А если в буфере не оказалось Escape последовательность, а он не пустой
        for (i=0; i<count; i++) {                           //то будем выводить по очереди все символы, которые обнаружим в буфере
            *pBuff = savMark;                               //восстановить в текущем знакоместе символ скрытый курсором 
            switch (byReceive[i]) {                         //кроме печатных символов в буфере могут находится управляющие символы
                                                            //некоторые из управляющих символов используются для управления выводом
                case 0x07:                                  //Bell - (ctrl+G). Удаленный терминал может прислать звуковой сигнал
                    Beep();                                 //и если звук в панели не запрещен (PFW[2] == 0), то услышим короткий Бип
                    break;
                case 0x8:                                   //backspace - (ctrl+H /Delete)
                    if (cCount != 0) {                      //если курсор не в начале строки
                        cCount--;                           //то прееместить его на одно знакоместо влево
                        pBuff--;                            //пересчитать адрес нового положения курсора
                    }
                    break;
                case 0x9:                                   //Tab - (ctrl+I) Табуляция - перемещение курсора вправо до ближайшей позиции кратной "tabs"
                    if (cCount < (cTotal - tabs)) {         //Если до конца строки осталось болше чем значение "tabs"
                        tmp = tabs - cCount % tabs;         //то подсчитать сколько символов от текущего положения курсора до до ближайшей позиции кратной "tabs"
                        cCount = cCount + tmp;              //переместить курсор в новую позицию
                        pBuff = pBuff + tmp;                //пересчитать адрес нового положения курсора
                    }
                    else {                                  //если до конца строки символов осталось меньше чем значение "tabs"
                        tmp = cTotal -1 - cCount;           //то подсчитать сколько их осталось
                        cCount = cTotal-1;                  //и новое положение курсора, в этом случае, однозначно д.б. в конце строки
                        pBuff = pBuff + tmp;                //пересчитать адрес нового положения курсора
                    }
                    break;
                case 0xA:                                   //LF - line feed (ctrl+J). Перевод строки
                    lCount++;                               //переместим курсор в ту же позицию нижележащей строки
                    pBuff = pBuff + cTotal;                 //пересчитать адрес нового положения курсора
                    break;
                case 0xD:                                   //CR - carriage return (ctrl+M /Enter). Возврат каретки
                    cCount = 0;                             //переместим курсор в начало текущей строки
                    pBuff = (BYTE *)&buffer + lCount * cTotal;//пересчитать адрес нового положения курсора
                    break;
    //следующие три управляющих кода пока не используются
                case 0x03:        //ETX - end of text (ctrl+C) 
                case 0x04:        //EOT - end of transmission (ctrl+D)
                case 0x1A:        //ctrl+Z (SUB -substitute)
    //А теперь выводим печатные символы
                default:
                    *pBuff = byReceive[i];                  //очередной символ из буфера приема поместить по адресу курсора
                    pBuff++;                                //декремент указателя адреса
                    cCount++;                               //переместить курсор в следующую позицицию строки
                    break;
            }
            savMark = *pBuff;                               //Сохранить символ в знакоместе экрана, на которое теперь будет указывать курсор
        }
    }
    //----------------------------------------------------------------------
    if (cCount >= cTotal) {                                 //если текущее(расчетное) положение курсора оказалось больше чем символов в одной строке
        cCount =0;                                          //то курсор переместить в начало следующей строки
        lCount++;
    }
    if (lCount >= lTotal) {                                      //если после этого нмер текущей строки стал больше чем есть строк в окне терминала
        memmove(&buffer, &buffer+cTotal/2, ((lTotal-1)*cTotal)); //по переписать все содержимое строк начиная со второй и по последнюю в начало буфера окна
        lCount=lTotal-1;                                         //теперь номер текущей строки будет на 1 меньше, чем общее количество строк
        memset(&buffer+(lTotal-1) * cTotal/2, ' ', cTotal);      //освободившуюся последнюю строку очистить (заполнить пробелами)
        savMark = ' ';                                           //естественно новый смвол скрытый курсором будет - пробел
    }
    //---------------------------------------------------------------------
    //Мигающий курсор
    if (GetPSBStatus(4)) *pBuff = '_';           //0,5 сек показывать курсор '_'   
    else                 *pBuff = savMark;       //0,5 сек показывать символ, скрытый курсором
    //-----------------------------------------
    Скрытый текст:

    Обмен текстовыми сообщениями(ASCII) между панелью и стандартным гипертерминалом Windows.
    Работу терминала можно протестировать если подключить панель к СОМ порту компьютера (можно и через переходник RS232/USB) простым трехпроводным кабелем
    2 <------> 3
    3 <------> 2
    5 <------> 5
    И запустить в Widows программу HyperTerminal.

    Панель СП300 даже больше чем просто панель.
    Тетрис на СП300 - https://owen.ru/forum/showthread.php...l=1#post340895
    ВИДЕО:
    Последний раз редактировалось petera; 28.05.2021 в 14:45.
    Мой канал на ютубе
    https://www.youtube.com/c/ПетрАртюков
    Библиотека ГМ для СП300
    https://disk.yandex.com/d/gHLMhLi8x1_HBg

Похожие темы

  1. Ответов: 6
    Последнее сообщение: 31.08.2020, 12:09
  2. Подбор оборудования для шагового двигателя
    от Дмитрий520 в разделе Подбор Оборудования
    Ответов: 49
    Последнее сообщение: 23.04.2017, 19:34
  3. Подключение шагового двигателя
    от kat в разделе ПЛК1хх
    Ответов: 7
    Последнее сообщение: 12.11.2015, 23:23
  4. Работа шагового двигателя 100 к-м
    от drfalk в разделе ПЛК1хх
    Ответов: 5
    Последнее сообщение: 20.09.2011, 12:11

Ваши права

  • Вы не можете создавать новые темы
  • Вы не можете отвечать в темах
  • Вы не можете прикреплять вложения
  • Вы не можете редактировать свои сообщения
  •