1. Обязательно представиться на русском языке кириллицей (заполнить поле "Имя").
  2. Фиктивные имена мы не приветствуем. Ивановых и Пупкиных здесь уже достаточно.
  3. Не писать свой вопрос в первую попавшуюся тему - вместо этого создать новую тему.
  4. За поиск, предложение и обсуждение пиратского ПО и средств взлома - бан без предупреждения.
  5. Рекламу и частные объявления "куплю/продам/есть халтура" мы не размещаем ни на каких условиях.
  6. Перед тем как что-то написать - читать здесь и здесь, а студентам - обязательно здесь.
  7. Не надо писать в ЛС администраторам свои технические вопросы. Администраторы форума отлично знают как работает форум, а не все-все контроллеры, о которых тут пишут.

Помогите дилетанту

Обсуждение вопросов, не относящихся ни к одному из других подразделов

Модератор: kirillio

Ответить

Автор темы
Бурлак
здесь недавно
здесь недавно
Сообщения: 32
Зарегистрирован: 07 ноя 2012, 11:16
Имя: Моисеев Владимир Николаевич
Страна: Россия
город/регион: п. Редкино

Re: Помогите дилетанту

Сообщение Бурлак »

>Василий Иванович » 18 янв 2013, 20:35
>... А вот читается этот код конкретно тяжелее ...
Да, чтение листинга программы на ассемблере дело не для слабонервных. Но если структурировать, выделить и собрать код в подпрограммы и создать библиотеки с хорошим описанием назначения подпрограммы (функции), описать входные и выходные параметры, то можно работать, например в случае бортовых систем.
Но и чтение листинга программы на SIMATIC SCL тоже не вдохновляет. Чтобы быть правильно понятым, приведу листинги двух функционально тождественных программ:
На STL

Код: Выделить всё

FUNCTION "DItoWTS" : WORD
//TITLE = 
//-- Формируем локальный вектор wTS из системного DI.

AUTHOR  : Burlak
FAMILY  : STL_LM
NAME    : DItoWTS
VERSION : 01.00

  VAR_INPUT 
    N      : INT;             //-- Размер локального вектора дискретных входов 
    vecAdr : POINTER;  //-- Указатель на вектор адресов дискретных входов 
  END_VAR 

  VAR_TEMP 
    i     : INT;            //-- Параметр цикла       
    DB_NO : WORD;   //-- Номер блока данных
    SysDI : DWORD;   //-- Указатель на системный вектор дискретных входов 
    wx    : WORD;      //-- Сдвиг единицы
    v     : WORD;       //-- Динамика результата 
  END_VAR 

BEGIN 
  L P#vecAdr; LAR1;               //-- Косвенный доступ к POINTER
  L W[AR1,P#0.0]; T DB_NO;   //-- Получим номер блока данных        
  OPN DB[DB_NO];	            //-- Откроем блок данных (DB or NOP)
  L D[AR1, P#2.0]; LAR1;        //-- Адрес вектора адресов бит вектора дискретных входов процесса
  
  L 1; T wx;                            //-- Храним сдвиг единицы
  L 0; T v;                              //-- Начальное значение
  L N;		            //-- Параметр цикла - размер локального вектора дис. состояния	
  Cicl: 
    T #i;                                 //-- i <-- ACCU1
    L W[AR1,P#0.0]; T SysDI;   //-- SysDI:=адрес бита вектора дискретных входов процесса    
    SET; A I[SysDI];                 //-- Получим значение дискретного хода процесса
    JCN Prod;
      L wx; L v; OW; T v;         //-- Обработка, если единица (true) 
    Prod:
    +AR1 P#2.0;                     //-- Следующая компонента вектора адресов 
    L wx; SLW 1; T wx;          //-- Сдвиг единицы влево 
    L #i;						
  LOOP Cicl;                        //-- Цикл DO..END
  L v; T RET_VAL; 
  BE;
END_FUNCTION  
и на SCL

Код: Выделить всё

//======================================================
TYPE "UDT_ANY" 
  TITLE  ='структура ANY-указателя' 
  FAMILY : 'LIB_PTR' 
  AUTHOR : Mayasin 
  VERSION: 1.0 
  STRUCT 
    id:   BYTE;       //код 
    tp:   BYTE;       //тип 
    sz:   INT;         //размер 
    blk:  WORD;     //номер блока данных 
    area: DWORD;  //указатель на область 
  END_STRUCT 
END_TYPE 

//-------------------------------------------

FUNCTION DItoWTS : WORD
TITLE = 'формирование локального вектора текущего дискретного состояния' 
FAMILY: LIB_LM 
VERSION : '1.0' 
AUTHOR : Mayasin_Burlak 

  VAR_INPUT 
    N      : INT;      //-- Размер локального вектора дискретных входов 
    vecAdr : ANY;  //-- Указатель на вектор адресов дискретных входов 
  END_VAR 

  VAR_TEMP 
    i : INT;     //-- Параметр цикла
    j : INT;     //-- Индекс байта      
    k : INT;     //-- Индекс бита
    l : INT;      //-- Номер бита в системном векторе дискретного состояния     
    w : INT;    //-- Сдвиг единицы
    v : WORD; //-- Результат
    s : INT;     //-- Смещение в verAdr  
    //укзатели в виде структур 
    pva: ANY; 
    ptr AT pva: UDT_ANY; 
  END_VAR 

  BEGIN
    w :=1;
    v :=0;
    i :=0;
    pva := vecAdr;
    s   := DWORD_TO_INT(SHR(in:=SHL(in:=ptr.area, n:=8),n:=11));
    WHILE (i < N) DO
      l:=WORD_TO_INT(WORD_TO_BLOCK_DB(ptr.blk).dw[s]);
      k:=l MOD 8;
      j:=l DIV 8; 
      IF I[j,k]=1 THEN
        v:=v OR INT_TO_WORD(w);
      END_IF;
      w:=w*2; 
      s:=s+2;
      i:=i+1; 
    END_WHILE;
    DItoWTS:=v;  
END_FUNCTION
Их функциональное назначение - формирование локального вектора дискретного состояния объекта, путем "надергивания" значений из неупорядоченного системного дискретного вектора процесса и упорядочивая их.
Большой разницы в читабельности этих текстов я не нахожу, но если код на ассемблере два раза компактнее и на порядок быстрее, то можно, затратив несколько больше времени, написать инструкции абстрактной машины и на ассемблере, например, для бортовых систем. Ничего криминального в этом нет.

С уважением, Владимир.
p.s. Помогать или не помогать мне, это личное дело каждого

Автор темы
Бурлак
здесь недавно
здесь недавно
Сообщения: 32
Зарегистрирован: 07 ноя 2012, 11:16
Имя: Моисеев Владимир Николаевич
Страна: Россия
город/регион: п. Редкино

Re: Помогите дилетанту

Сообщение Бурлак »

Коллеги! Нужна помощь.
Подскажите, как программно изменить цикл опроса тега?

С уважением, Владимир.

Автор темы
Бурлак
здесь недавно
здесь недавно
Сообщения: 32
Зарегистрирован: 07 ноя 2012, 11:16
Имя: Моисеев Владимир Николаевич
Страна: Россия
город/регион: п. Редкино

Re: Помогите дилетанту

Сообщение Бурлак »

>Бурлак » 28 янв 2013, 08:34
>Подскажите, как программно изменить цикл опроса тега?

Отвечаю на свой же вопрос. Может кому и сгодится.
В процессе взаимодействия ПО оператора на компьютере под WinCC и ПО управления роботом (технологическим процессом) на контроллере в моем варианте задействованы два тега - двунаправленный (компьютер <--> контроллер) тег mZrd1/1.wdCmd(Unsigned 16-bit Value - команды оператора) и однонаправленный (компьютер <-- контроллер) тег mZrd1/tgpCon (Raw Data Type - получение контекста робота).
Физически функционал взаимодействия оператора с роботом реализован в виде экранной формы WinCC. В случае линии сборки специзделий таких экранных форм 11. Обычно в автоматическом режиме на экране дисплея отображается обобщенная форма, связанная с возможными не штатными ситуациями и именно эта активная форма задает темп опроса тегов (0.5 сек).
При нештатной ситуации оператор вызывает форму взаимодействия с конкретным механизмом, и именно она будет задавать темп обмена тегами (0.5 сек). Предыдущая форма переходит в неактивное состояние с периодом опроса (2-4 сек).

Вот как это реализовано:
1. П/п работы с тегами:
============================================================

Код: Выделить всё

'-- Запись в тег
Function fSetTag(Byval tgName, Byval tgValue)
  Dim oX
  Err.Clear
  Set oX = HMIRuntime.Tags(tgName)  '-- объект для работы с тегом процесса команд оператора
  oX.Write tgValue,1
  oX.Read
  fSetTag = oX.LastError Or oX.QualityCode
End Function

'-- Чтение тега
Function fGetTag(Byval tgName, Byref tgValue)
  Dim oX, x
  Err.Clear
  Set oX = HMIRuntime.Tags(tgName)  '-- объект для работы с тегом процесса команд оператора
  oX.Read 1
  x= oX.Value
  tgValue = x  
  fGetTag = oX.QualityCode 
End Function
2. Работа с графическим элементом формы - реализация динамики опроса тега
==========================================================================

Код: Выделить всё

'== Обработка свойства 
'-- <Object Properties> --> <Properties> -->
'-- <Rectangle> --> <Colors> --> <Border Color>
'-- активация события
Function BorderColor_Trigger(ByVal Item)
  '-- Тригер цикла чтения тегов робота
  '-- Активизируем событие
  If Item.BorderBackColor = RGB(0,0,0) Then
    Item.BorderBackColor=RGB(1,1,1)
  Else  
    Item.BorderBackColor=RGB(0,0,0)
  End If
End Function

'== Обработка события 
'-- <Object Properties> --> <Event> -->
'-- <Rectangle> --> <Miscellaneous> --> <Object Change>
'--
Sub OnObjectChanged(ByVal Item)                                                                                                                   
  Dim oX,oY,i,j,vx
  
  '-- Если объект изменил цвет холста под бордюром, 
  '-- то пришло время опроса тегов контроллера
  If Item.BorderBackColor=puls_rr Then Exit Sub '-- Еще не время опроса тегов контроллера     
  puls_rr=Item.BorderBackColor

  '-- Время опроса тегов ?
  '-- реализация счетчика
  tgSchk=tgSchk-1
  If tgSchk > 0 Then Exit Sub
  tgSchk=tgPar
   
  '-- Тик-Так (Мигание) графического элемента режима работы
  If ((iTikTak_rr > 0) And (iTikTak_rr < 4)) Then '-- Тик-Так есть и не квитирован
    iTikTak_rr = iTikTak_rr Xor 1
    If (iTikTak_rr Mod 2) = 0 Then
      Item.BackColor = colTak_rr
    Else '-- Так
      Item.BackColor = colTik_rr
    End If  
  End If
  
  On Error Resume Next    '-- Обработка ошибок программистским кодом
  
  '== Обработка команд оператора
  '-- Читаем и анализируем тег команд оператора
  If fGetTag(TGP_CMD,wdCmd) <> 128 Then '-- Ошибка связи с контроллером 
    If iTikTak_sv=0 Then '-- Тик-Так не запущен
      colTik_sv=colNSK
      iTikTak_sv=3
    End If  
    Exit Sub
  End If 
  '-- Связь есть
  'colTik_sv=colButton
  'iTikTak_sv=0
  
  ObrCmd() '-- Обработка состояния исполнения команд оператора  
  
  '-- Читаем и анализируем тег контекста робота
  If fGetTag(TGP_CON,aCon) <> 128 Then '-- Ошибка связи с контроллером 
    If iTikTak_sv=0 Then '-- Тик-Так не запущен
      colTik_sv=colNSK
      iTikTak_sv=3
    End If  
    Exit Sub
  End If 

  '-- Связь есть
  Set oX=ScreenItems("rtg_Связь")
  oX.BackColor=colButton
  colTik_sv=colButton
  iTikTak_sv=0

  '== Обработка контекста
  
  '-- Структура контекста
  '  wdAU     :WORD - Вектор управления 
  '  wdTS     :WORD - Вектор текущего состояния
  '  wdNS     :WORD - Шаг: Вектор начального состояния
  '  wdOS     :WORD - Вектор ожидаемого состояния
  '  wdMS     :WORD - Вектор маски состояния
  '  wdTO     :WORD - TimeOut
  '  wdDTS    :WORD - Дополнение текущего состояния
  '  wdShag   :WORD - Номер шага
  '  wdRAI    :WORD - Регистр адреса инструкции 
  '  wdTest   :WORD - Тест-параметр 
  '== Структура wdDTS - Дополнение текущего состояния:
  '  15 бит (32768) - режим работы (1 - автоматический, 0 - ручной)
  '  14 бит (16384) - рабочий цикл (1 - да, 0 - завершён)
  '  13 бит (8192)  - не штатная ситуация (1 - да, 0 - нет)
  '  12 бит (4096)  - состояние конвейера (1 - рабочий ход, 0 - стоит)


  '-- Распаковка параметров контекста робота
  wdAU   = (aCon(0)*256) + aCon(1)
  wdTS   = (aCon(2)*256) + aCon(3)
  wdNS   = (aCon(4)*256) + aCon(5)
  wdOS   = (aCon(6)*256) + aCon(7)
  wdMS   = (aCon(8)*256) + aCon(9)
  wdTO   = (aCon(10)*256)+ aCon(11)
  wdDTS  = (aCon(12)*256) + aCon(13)
  If (aCon(8) And 128) <> 0 Then
    wdDTS  = wdDTS Or CMD_DO
  End If 
  intDTS=wdDTS
  wdNSH  = (aCon(14)*256)+ aCon(15)
  intNSH = wdNSH 
  wdRAI  = (aCon(16)*256)+ aCon(17)
  wdTest = (aCon(18)*256)+ aCon(19)

  '-- Обработка длительности шага
  Set oY=ScreenItems("iof_Timeout")
  oY.OutputValue = wdTO 

  '-- Обработка номера шага. Режим АУ?
  If (wdDTS And RR_RAU) <> 0 Then
    '-- Да. Автоматический режим
    Set oX=ScreenItems("st_ТШЦ")
    Set oY=ScreenItems("cmb_Шаг")
    oY.SelIndex=wdNSH+1
    oX.Text = oY.SelText
  End If
  '-- Обработка адреса инструкции
  Set oY=ScreenItems("iof_РАИ")
  oY.OutputValue = wdRAI 

  '-- Обработка Test-папаметра
  Set oY=ScreenItems("iof_Тест")
  oY.OutputValue = wdTest 

  . . .
3. Настройки формы
Все настройки экранной формы работы с оператором производятся при обработке события загрузки формы.
Ответить

Вернуться в «Общие вопросы»