Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: Драйвер для ОРС  (Прочитано 24249 раз)
0 Пользователей и 1 Гость смотрят эту тему.
voron
Интересующийся

ua
Offline Offline

« : 03-08-2010 21:00 » 

       У меня есть вопросы по UNIОРС - может посоветуете как выкрутится...
Вопрос состоит в том чтобы сделать драйвер для устройства RS232 (Контроллер WE2108) .
Есть пример но в нем не ясно ОРС берет функции передачи в порт на себя или нужно все формировать Не понял.
 Коротко драйвера еще не делал.
 Все очень туго...
 И еще придется потом расширяться до 11 устройств (конвертеры в RS485) Я шокирован!
 
 - Помогите пожалуйста  Да-да

Записан
Ochkarik
Модератор

ru
Offline Offline
Пол: Мужской

« Ответ #1 : 04-08-2010 05:27 » 

вы про это  и это?
а зачем вам свой драйвер, чем вам штатный  не угодил?
вам вообще API достаточно будет...
PS там сейчас win98 ставят?
PPS выкладывайте пример...
« Последнее редактирование: 04-08-2010 05:45 от Ochkarik » Записан

RTFM уже хоть раз наконец!  RTFM :[ ну или хотя бы STFW...
voron
Интересующийся

ua
Offline Offline

« Ответ #2 : 04-08-2010 07:34 » 

вы про это  и это?
а зачем вам свой драйвер, чем вам штатный  не угодил?
Цитата


Его и хочу изменить  Улыбаюсь Кажется все просто только опыта не хватает  Уже туплю




Добавлено через 4 дня, 2 часа, 51 минуту и 56 секунд:
Вот пример:
Код:
/*
(C) Fastwel Inc. 1999

Демонстрационная реализация user-defined DLL для
универсального OPC сервера. Может служить "болванкой"
для разработки настоящего сервера.

ВНИМАНИЕ!
  В данном примере предполагается, что в адресном пространстве сервера
  (видимом клиентам через IBrowseServerAddressSpace) будет задано одно
  "устройство" с несколькими группами тегов. Более "продвинутый"
  (но и более сложный) пример с несколькими устройствами
  находится в файле dataserv.cpp.
*/


#include "windows.h"
#include "dataserv.h"
#include <math.h>
#include <process.h>
#include <stdio.h>

#define MAX_TAG 5

// Массивы тегов, видимых OPC-сервером
// (для простоты они одинаковой длины,
//  в реальности, массивы, конечно, будут разные)

TAnTag AnTag[MAX_TAG];
TBitTag BitTag[MAX_TAG];
TIntTag IntTag[MAX_TAG];

// структура, рассказывающая OPC-серверу, где находятся массивы тегов...

TDataForOPCServer DataForOpc={1,MAX_TAG,AnTag,MAX_TAG,BitTag,MAX_TAG,IntTag,0};

// ... и функция, возвращающая OPC-серверу указатель на эту структуру:


__declspec( dllexport )
const TDataForOPCServer * PASCAL GetDataForOPCServer()
{
  return &DataForOpc;
};


//===  Функции изменения тегов разного типа: ==================

//    функция для изменения значения аналогового тега

__declspec( dllexport )
unsigned char PASCAL SetAnTagValue(
       unsigned  number, // номер тега в массиве
       float value            // новое значение параметра
    )
{
  if(number<0 || number>=MAX_TAG)
      return FALSE;
  AnTag[number].value=value;

    // здесь по идее нужно записать значение в реальное
    // физическое устройство. При неудаче вернуть FALSE.
  return TRUE;
};

//---------------------------------------------------------------------------
//    функция для изменения значения битового тега

__declspec( dllexport )
unsigned char PASCAL SetBitTagValue(
       unsigned  number, // номер тега в массиве
       unsigned char value    // новое значение параметра
       )
{
  if(number<0 || number>=MAX_TAG)
      return FALSE;
  BitTag[number].value=value;
    // здесь по идее нужно записать значение в реальное
    // физическое устройство. При неудаче вернуть FALSE.
  return TRUE;
};

//---------------------------------------------------------------------------
//    функция для изменения значения целого тега

__declspec( dllexport )
unsigned char PASCAL SetIntTagValue(
       unsigned  number, // номер тега в массиве
       int value    // новое значение параметра
       )
{
  if(number<0 || number>=MAX_TAG)
      return FALSE;
  IntTag[number].value=value;
    // здесь по идее нужно записать значение в реальное
    // физическое устройство. При неудаче вернуть FALSE.
  return TRUE;
};

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

float Dt= (float)0.01;
float Tt;

// Главная рабочая нить  DLL, в которой должен происходить опрос
// устройства и обновление значений в массивах тегов:

void WorkingThread( void *dummy ) // Thread function
{
  while(1)
  { int i;
    Sleep(100); // пауза 0,1 секунды
    // Заснуть на некоторое время надо обязательно,
    // иначе эта нить не даст житья OPC-серверу и другим приложениям!
    // (можно заснуть на меньший период, допустимо до 10 ms)
    Tt=Tt+Dt;
    if(Tt>10)
      Tt=Tt-(float)3.1415926*3;
    for(i=1; i != MAX_TAG; i++)  // Для демонстрационных
      // целей мы не изменяем тег No 1, чтобы в него можно
      // было спокойно записывать значения из OPC-клиентов
    {
      // симулируем изменение значений:
      AnTag[i].value= (float)sin(Tt+i);
      BitTag[i].value= (AnTag[i].value>0)? 1:0;
      IntTag[i].value= (int)(AnTag[i].value * 10);
      // Вместо симуляции в реальном сервере здесь
      // должен происходить опрос устройства и обновление
      // значений
    };
  };
};


//---------------------------------------------------------------------------
// Класс, конструктор которого запускает рабочую нить DLL
// (это можно делать и из DLLEntryPoint по DLL_PROCESS_ATTACH,
// но через конструктор объекта, кажется, удобнее)

class MyWorkingThread
{
 public:

  MyWorkingThread() // Все делает конструктор:
  {

    // Заполняем массив имен тегов для OPC-сервера:
    for(int i=0; i != MAX_TAG; i++)
    {
     char s[64]="";
     char ss[64]="";
     char sss[64]="";

     char* prefix= (i<MAX_TAG/2)? "unit1." : "unit2.";
      // Демонстрация того, как действует символ "." (точка)
      // внутри имени тега. Если, например, имя тега имеет вид
      // unit1.tag1, то OPC сервер создаст группу тегов unit1
      // (внутри устройства) и добавляет тег tag1 (уже без префикса)
      // в эту группу. Таким образом можно структурировать пространство
      // имен. Более глубокие уровни вложенности не поддерживаются
      //(то есть точка в имени, если она есть, должна быть только одна)
     sprintf(s,"%sanalog_%d",prefix,i);
     sprintf(ss,"%sbit_%d",prefix,i);
     sprintf(sss,"%sint_%d",prefix,i);
     AnTag[i].setName(s);
     BitTag[i].setName(ss);
     IntTag[i].setName(sss);
    };
    // Создаем рабочую нить:
    _beginthread( WorkingThread, 0, NULL );
  };
};

//=========================================================

/*
   инициализация статического объекта, конструктор которого
   сразу после загрузки DLL создает рабочую нить
   (чтобы не возиться с DLLEntryPoint - хотя это, конечно,
   дело разработчика):
*/
MyWorkingThread* mythread=new MyWorkingThread;

Добавлено через 9 часов, 17 минут и 45 секунд:
вы про это  и это?

Да !!!!!!!! Это все будет работать на ХР  Да-да
« Последнее редактирование: 04-08-2010 16:52 от voron » Записан
Ochkarik
Модератор

ru
Offline Offline
Пол: Мужской

« Ответ #3 : 04-08-2010 17:16 » 

чтобы что нибудь поменять (тем более штатный драйвер) надо сначала понять - чем он вас не устраивает?)

а насчет штатного....и в чем проблема? А черт его знает... поиск уже отменили? Быть такого не может
http://www.google.ru/search?hl=ru&lr=&newwindow=1&q=API+windows+com+%D0%BF%D0%BE%D1%80%D1%82&aq=f&aqi=&aql=&oq=&gs_rfai=
и шлите туда команды вашей  WE2108, дел то...Ага

интерфейс OPC библиотеки - описаниеу вас есть) тем более рыба...
« Последнее редактирование: 08-08-2010 19:58 от Ochkarik » Записан

RTFM уже хоть раз наконец!  RTFM :[ ну или хотя бы STFW...
voron
Интересующийся

ua
Offline Offline

« Ответ #4 : 04-08-2010 18:21 » 

Главное правильно поставить вопрос! Спасибо за ссылку!
 Буду продолжать разбираться...

Добавлено через 20 дней, 20 часов, 26 минут и 39 секунд:
Вот нашел здесь http://www.pcports.ru/SerialGate.php библиотеку. Буду пытаться сегодня лепить драйвер Улыбаюсь
« Последнее редактирование: 25-08-2010 14:47 от voron » Записан
Ochkarik
Модератор

ru
Offline Offline
Пол: Мужской

« Ответ #5 : 25-08-2010 15:11 » 

 Жжешь
эта библиотека - из разряда "люди, где можно найти компонент Hello World, для delphi?"(с)
« Последнее редактирование: 25-08-2010 15:14 от Ochkarik » Записан

RTFM уже хоть раз наконец!  RTFM :[ ну или хотя бы STFW...
voron
Интересующийся

ua
Offline Offline

« Ответ #6 : 25-08-2010 15:59 » 

Улыбаюсь)

Добавлено через 1 день, 16 часов, 11 минут и 51 секунду:
Вот что получается:

Код:
#include "windows.h"
#include "dataserv.h"
#include "SerialGate.h"

//#include <math.h>
#include <iostream>
#include <conio.h>
#include <process.h>
#include <stdio.h>
#include <string.h>


#define MAX_TAG 1  //для начала взял 1 тег

TAnTag AnTag[MAX_TAG];

// структура, рассказывающая OPC-серверу, где находятся массивы тегов...

//TDataForOPCServer DataForOpc={1,MAX_TAG,AnTag,MAX_TAG,BitTag,MAX_TAG,IntTag,0};
TDataForOPCServer DataForOpc={1,MAX_TAG,AnTag,0};//Подправил структуру

// ... и функция, возвращающая OPC-серверу указатель на эту структуру:

__declspec( dllexport )
const TDataForOPCServer * PASCAL GetDataForOPCServer()
{
  return &DataForOpc;
};

//===  Функции изменения тегов аналог. типа: ==================

//    функция для изменения значения аналогового тега

__declspec( dllexport )
unsigned char PASCAL SetAnTagValue(
       unsigned  number, // номер тега в массиве
       float value            // новое значение параметра
    )
{
  if(number<0 || number>=MAX_TAG)
      return FALSE;
  AnTag[number].value=value;
//<<<<<<<<ВНИМАНИЕ<<<<<<<<<<<<

    int port = 1;
int rate = 9600;

SerialGate sg;

bool res = sg.Open(port, rate);
if(res == false)
{return 0;}

while(true)
{
char sbuf[13] ="S98;MSV?;S00;";
for(int i; i<strlen(sbuf)+1; i++)
{char c=sbuf[i];

sg.Send(&c, sizeof(c));

if(i == strlen(sbuf)+1) break;}
}

sg.Close();

  return TRUE;
  else
  return FALSE;
};


// Главная рабочая нить  DLL, в которой должен происходить опрос
// устройства и обновление значений в массивах тегов:

void WorkingThread( void *dummy ) // Thread function
{
 int port = 1;
 int rate = 9600;

      SerialGate sg;

bool res = sg.Open(port, rate);
if(res == false){return 0;}

char buf[30];
int dwBytesRead = 0;
bool terminate  = false;
while(!terminate)
{  
 Sleep(100); // пауза 0,1 секунды
    // Заснуть на некоторое время надо обязательно,
    // иначе эта нить не даст житья OPC-серверу и другим приложениям!
    dwBytesRead = sg.Recv(buf, sizeof(buf));

for(int j = 0; j < dwBytesRead; j++)
{
if((buf[j+1]<'0')||(buf[j+1]>'9'));
//неправильный формат
float eror=0;
AnTag[i].value=(float)eror;
else
{
         for(int i=1; i != MAX_TAG; i++)
     AnTag[i].value=(float)atof(buf);

if(buf[j] == 'LF'){terminate = true; break;}
}
   }
}
sg.Close();
}

//---------------------------------------------------------------------------
// Класс, конструктор которого запускает рабочую нить DLL
// (это можно делать и из DLLEntryPoint по DLL_PROCESS_ATTACH,
// но через конструктор объекта, кажется, удобнее)

class MyWorkingThread
{
 public:

  MyWorkingThread() // Все делает конструктор:
  {

    // Заполняем массив имен тегов для OPC-сервера:
    for(int i=0; i != MAX_TAG; i++)
    {
     char s[64]="";
    

     char* prefix= (i<MAX_TAG/2)? "unit1." : "unit2.";
      // Демонстрация того, как действует символ "." (точка)
      // внутри имени тега. Если, например, имя тега имеет вид
      // unit1.tag1, то OPC сервер создаст группу тегов unit1
      // (внутри устройства) и добавляет тег tag1 (уже без префикса)
      // в эту группу. Таким образом можно структурировать пространство
      // имен. Более глубокие уровни вложенности не поддерживаются
      //(то есть точка в имени, если она есть, должна быть только одна)
     sprintf(s,"%sanalog_%d",prefix,i);
    
     AnTag[i].setName(s);
    
    };
    // Создаем рабочую нить:
    _beginthread( WorkingThread, 0, NULL );
  };
};

//=========================================================

/*
   инициализация статического объекта, конструктор которого
   сразу после загрузки DLL создает рабочую нить
   (чтобы не возиться с DLLEntryPoint - хотя это, конечно,
   дело разработчика):
*/
MyWorkingThread* mythread=new MyWorkingThread;
//////////////////////////////////////////////////////////////////////////////

Я подозреваю что контр. ничего не поймет.
 Скорее всего нужно будет перевести в hex запрос и c ответом шаманить.
Надеюсь до 13 сентября успею

« Последнее редактирование: 27-08-2010 08:11 от voron » Записан
Ochkarik
Модератор

ru
Offline Offline
Пол: Мужской

« Ответ #7 : 27-08-2010 08:12 » 

что сказать.... пробуйте! если не получится курите мануалы)))
PS но есть ошибки в цикле SetAnTagValue() Ага и еще один  "забубух" очень забавный... там же)
PPS кстати рекомендую при форматировании кода пользоваться либо табами либо пробелами - но чем нибудь одним. а то вот так вот потом перемешивается...  
и кстати, перед тем как сервер писать - лучше сначала com-управление проверить. а то непонятно будет, где ошибки искать)
« Последнее редактирование: 27-08-2010 19:45 от Ochkarik » Записан

RTFM уже хоть раз наконец!  RTFM :[ ну или хотя бы STFW...
voron
Интересующийся

ua
Offline Offline

« Ответ #8 : 28-08-2010 10:09 » 

Еще не пробовал этот вариант. Прибор на работе. Но когда пробовал сервер "сериал-гейтовский" то все запросы игнорировались - отсюда мысль насчет формата.
PS в прошлом году как-то еще тогда просто ради интереса делал приложение на делфях - оно просто сбрасывало в файл hex ответ, а на  Label прописывал преобразователь char. И все улыбались - тогда. А сейчас так не катит "спиногрызы".
Увлекся. Суть в том что работало. Правда запрос был через edit.
Записан
Ochkarik
Модератор

ru
Offline Offline
Пол: Мужской

« Ответ #9 : 28-08-2010 17:01 » 

ниииче не понял)
Записан

RTFM уже хоть раз наконец!  RTFM :[ ну или хотя бы STFW...
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #10 : 28-08-2010 17:25 » 

Ochkarik, попробуй альт+стрелку влево Под столом
Записан

Ochkarik
Модератор

ru
Offline Offline
Пол: Мужской

« Ответ #11 : 28-08-2010 18:49 » 

Алексей1153++, пробовал, в хроме не работает Не могу...
Записан

RTFM уже хоть раз наконец!  RTFM :[ ну или хотя бы STFW...
voron
Интересующийся

ua
Offline Offline

« Ответ #12 : 16-01-2011 07:42 » 

Ничего не вышло.
Ochkarik, а "есть ошибки в цикле SetAnTagValue() Ага и еще один  "забубух" очень забавный... там же)" -  не могли бы вы по подробнее показать на ошибки

Добавлено через 15 минут и 6 секунд:
С начала разберусь с СОМ-портом. Затем перейду к драйверу. Рассчитываю на вашу поддержку
« Последнее редактирование: 16-01-2011 07:57 от voron » Записан
Ochkarik
Модератор

ru
Offline Offline
Пол: Мужской

« Ответ #13 : 30-01-2011 00:16 » 

Код:
while(true)
{
char sbuf[13] ="S98;MSV?;S00;";
for(int i; i<strlen(sbuf)+1; i++)
{
                      char c=sbuf[i];
     sg.Send(&c, sizeof(c));
     if(i == strlen(sbuf)+1)
                          break;
                }
}
Записан

RTFM уже хоть раз наконец!  RTFM :[ ну или хотя бы STFW...
resource
Молодой специалист

ru
Offline Offline
Пол: Мужской

« Ответ #14 : 31-01-2011 02:06 » 

признаюсь, не перечитывал весь топик, но вот это выглядит лишним
Код:
      if(i == strlen(sbuf)+1)
                          break;

А вот i нужно инициализировать.

ЗЫ может я просто не въехал
Записан
Ochkarik
Модератор

ru
Offline Offline
Пол: Мужской

« Ответ #15 : 31-01-2011 09:56 » 

resource, угу) а про внешний while(true), что думаешь?)
Записан

RTFM уже хоть раз наконец!  RTFM :[ ну или хотя бы STFW...
resource
Молодой специалист

ru
Offline Offline
Пол: Мужской

« Ответ #16 : 31-01-2011 15:16 » 

Ну я просто думал, что может я чего-то недопонимаю. Такое ощущение что этим break'ом хотели выйти из while. Об этом только гадать можно, но надо ли  Улыбаюсь
Записан
Ochkarik
Модератор

ru
Offline Offline
Пол: Мужской

« Ответ #17 : 31-01-2011 15:20 » 

ага, я и говорю, "забубух" с ошибками)
Записан

RTFM уже хоть раз наконец!  RTFM :[ ну или хотя бы STFW...
voron
Интересующийся

ua
Offline Offline

« Ответ #18 : 12-05-2011 17:53 » new

Всем спасибо! Разобрался с драйвером. SerialGate не использовал
Записан
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines