Segnetics

Вернуться   Segnetics > Форум Segnetics > Вопросы о SMH-2G(i)

Вопросы о SMH-2G(i) Здесь всё, что касается работы контроллера SMH-2G(i).

Ответ
 
Опции темы Поиск в этой теме Опции просмотра
Старый 29.06.2012, 17:31   #1
AlexSE
Новичок
 
Регистрация: Jun 2012
Сообщения: 20
Благодарил(а): 0 раз(а)
Поблагодарили: 0 раз(а) в 0 сообщениях
По умолчанию Срочно! Помогите! О разделяемой памяти!

Всем добрый день!
Нужна помощь, может быть кто-нибудь у же сталкивался с проблемой вывода данных!
Apache установлен на контроллере.
Пробовал двумя способами:

1 способ:
Через функцию shmop взаимодействовать с памятью.
Взял адреса из файла load_files.srv. Он туда их автоматом прописывает.
<?php
// отрытие
$shm_id = shmop_open(0xa0a8h, "c", 0644, 100);

if(!$shm_id)
{
echo "Ошибка при открытии.\n";
}

// Получаем размер сегмента разделяемой памяти
$shm_size = shmop_size($shm_id);
// Считываем
$my_data = shmop_read($shm_id, 0, $shm_size);
if(!$my_string)
{
echo "Ошибка при попытке чтения разделяемой памяти\n";
}
echo " ".$my_data."\n";
//закрываем
shmop_close($shm_id);
?>

как бы работает- но выводит пустоту
Тогда я решил поэкспериментировать и взял адрес из переменных modbus
- вообще не работает(в плане того, что даже просто текст не выводит).

2 способ:
Мне предложили чтобы прога на С записывала в файл , а потом уже от туда читать
Как описано в мануале написали на С и добавили запись в файл залили в контроллер
код:

#include "shm.hpp"
#include <stdio.h>
#include <time.h>
#include <unistd.h>
#include <signal.h>
#include <rlserial.h>

int main()
{
Shm mymem("./load_files.srv"); //Инициализация переменных разделяемой памяти
FILE *file;

struct timespec tv;//Структура для задания временных интервалов
tv.tv_sec = 0;
tv.tv_nsec = 1000000000; //(наносекунд) задержка в 1 сек
// хотя лучше сделать столько-же, сколько период обновления на веб-морде (!)

while (1) // Бесконечный цикл
{
if ((file = fopen("result.txt","w")) == NULL)
{
printf("Can't open file\n");
exit(-1);
} else {
fprintf (file, "<?xml version=\"1.0\" encoding=\"cp1251\">");
fprintf (file, "<result>");
fprintf (file, "<bases>");

nanosleep(&tv, NULL); //выполняем задержку для экономии ресурсов

//================================================== ==================//
// mem_tech - температура наружняя //
//================================================== ==================//
if ( mymem.getType("mem_tech") == FLOAT )
{
float mem_tech = mymem.getFloat("mem_tech");
fprintf(file,"<base>mem_tech = %f</base>",mem_tech);
} else {
fprintf(file,"<base>ERROR: mem_tech has type
%d</base>",mymem.getType("mem_tech"));
exit(-1);
}

//================================================== ==================//
// mem_in - температура канала //
//================================================== ==================//
if ( mymem.getType("mem_in") == FLOAT )
{
float mem_in = mymem.getFloat("mem_in");
fprintf(file,"<base>mem_in = %f</base>",mem_in);
} else {
fprintf(file,"<base>ERROR: mem_in has type
%d</base>",mymem.getType("mem_in"));
exit(-1);
}

//================================================== ==================//
// mem_out - температура обр_воды //
//================================================== ==================//
if ( mymem.getType("mem_out") == FLOAT )
{
float mem_out = mymem.getFloat("mem_out");
fprintf(file,"<base>mem_out = %f</base>",mem_out);
} else {
fprintf(file,"<base>ERROR: mem_out has type
%d</base>",mymem.getType("mem_out"));
exit(-1);
}

//================================================== ==================//
// mem_room - температура помещения //
//================================================== ==================//
if ( mymem.getType("mem_room") == FLOAT )
{
float mem_room = mymem.getFloat("mem_room");
fprintf(file,"<base>mem_room = %f</base>",mem_room);
} else {
fprintf(file,"<base>ERROR: mem_room has type
%d</base>",mymem.getType("mem_room"));
exit(-1);
}


fprintf (file, "</bases>");
fprintf (file, "</result>");
fclose(file);
}
}
}

Но почему-то он записывает в файл "-1"

От сюда можно сделать вывод - он не берет значения! Почему?

Подскажите что делать? Как дальше жить?
AlexSE вне форума   Ответить с цитированием
Старый 02.07.2012, 09:18   #2
AlexSE
Новичок
 
Регистрация: Jun 2012
Сообщения: 20
Благодарил(а): 0 раз(а)
Поблагодарили: 0 раз(а) в 0 сообщениях
По умолчанию Ответ: Срочно! Помогите! О разделяемой памяти!

Расскажу более подробно мою задачу!

Дело в том, что мне нужно вывести данные о состоянии системы на сайт, чтобы любой кто имеет доступ к этому, мог посмотреть данные о температуре, авариях, какие устройства на данный момент включены, а также мог запустить или остановить устройства, внести корректировки в некоторые данные(например какая температура должна поддерживаться в помещении)

Так вот, как я понимаю есть 2 способа(какой из них лучше и практичнее я не знаю, мне просто нужен способ рабочий , чтобы реализовать свою задачу о выводе и редактирования некоторых данных):

1 способ: взаимодействие напрямую php и smlogix через shared memory(схему смотрим ниже-shmop)
задача:
вывести температуру помещения на встроенный сайт
В проект я добавил mem-блок "mem_room", залил на контроллер-написал код(смотрим выше, адрес памяти взял из файла load_files.srv)
И пока не получается вывести это. Может быть, я что-то не то делаю, подскажите.

2 способ написать программу , которая будет брать данные shared memory и записывать в xml файл постоянно - далее с помощью технологии ajax выводить это на сайт (схема ниже - xml)

В проект я добавил mem-блок "mem_room", залил на контроллер. Через виртуальную машину написал программу на С (код выше)- залил на контроллер.
И на это я и застопорился. Так вот он создает файл, но почему- то записывает туда -1. Подскажите, почему так?

Заранее благодарен!
Миниатюры
Нажмите на картинку для увеличения

Название:  xml.JPG
Просмотров: 106
Размер:  14.3 Кбайт   Нажмите на картинку для увеличения

Название:  shmop.JPG
Просмотров: 75
Размер:  11.7 Кбайт  
AlexSE вне форума   Ответить с цитированием
Старый 02.07.2012, 11:31   #3
Arsie
Сотрудник Segnetics
 
Аватара для Arsie
 
Регистрация: Jan 2006
Адрес: Russia, SPb
Сообщения: 18 020
Благодарил(а): 15 раз(а)
Поблагодарили: 655 раз(а) в 599 сообщениях
По умолчанию Ответ: Срочно! Помогите! О разделяемой памяти!

Цитата
Сообщение от AlexSE
Заранее благодарен!
Вообще, первое что бросается в глаза: "$shm_id = shmop_open(0xa0a8h, "c", 0644, 100);" - ошибки у вас уже с самого начала.

Нужен не адрес, а "ключ файла", который генерится специальной функцией, которую для пхп я не знаю.

В "обычной жизни" она называется ftokey или как-то похожим образом.

Ну и вот: http://ru2.php.net/manual/ru/function.shmop-open.php


__________________
Программа делает то что написал программист, а не то что он хотел.

Добро всегда побеждает зло. Кто победил - тот и добрый.
Arsie сейчас на форуме   Ответить с цитированием
Старый 02.07.2012, 16:17   #4
Antistatic
Новичок
 
Регистрация: May 2010
Сообщения: 26
Благодарил(а): 0 раз(а)
Поблагодарили: 0 раз(а) в 0 сообщениях
По умолчанию Ответ: Срочно! Помогите! О разделяемой памяти!

Из того что делал я в качестве эксперимента:
1) Пишем программу на С++ для смлоджика которая является сервером разделяемых переменных по стандартному сокету.

2) В скрипте php открываем сокет, подключаемся к нашему серверу, делаем запрос

3) сервер отвечает, результат = значение нашей переменной.

Запрос для переменной может быть простой текстовый вида "Get01", "Get02" и тд. Впринципе можно передавать и массивом сразу все переменные.
Antistatic вне форума   Ответить с цитированием
Старый 03.07.2012, 12:34   #5
AlexSE
Новичок
 
Регистрация: Jun 2012
Сообщения: 20
Благодарил(а): 0 раз(а)
Поблагодарили: 0 раз(а) в 0 сообщениях
Smile Ответ: Срочно! Помогите! О разделяемой памяти!

Спасибо за ответы! Будем пробовать! Потом обязательно отпишусь! Будут идеи с удовольствием выслушаю
AlexSE вне форума   Ответить с цитированием
Старый 03.07.2012, 13:07   #6
Antistatic
Новичок
 
Регистрация: May 2010
Сообщения: 26
Благодарил(а): 0 раз(а)
Поблагодарили: 0 раз(а) в 0 сообщениях
По умолчанию Ответ: Срочно! Помогите! О разделяемой памяти!

По поводу записи в файл. Делал запись и чтение параметров из файла, у меня работало, но были проблемы с обновлением данных (т.е) скорость работы оставляла желать лучшего, да и ресурс памяти контроллера убивается очень быстро.

По поводу чтения разделяемой памяти не уверен что апач вообще корректно будет работать с смлоджиком.

Оптимальным решением было написание именно простенького однопоточного сервера (1 слушатель и 1 клиент) обрабатывающий запросы "Set" и "Get" (часа 2-3 на написание и отладку).

+:
1) Простота
2) Надежность
3) Универсальность

-:
1) Относительно низкая скорость работы, время ответа на один запрос около 50 мс. (Хотя можно добиться и большего быстродействия, при уменьшении времени основного цикла)



Для месье знающих толк в извращениях)) можно посоветовать прикрутить библиотеку ModbusTCP слэйв к апачу (ну либо написать её самому)
Antistatic вне форума   Ответить с цитированием
Старый 04.07.2012, 12:00   #7
AlexSE
Новичок
 
Регистрация: Jun 2012
Сообщения: 20
Благодарил(а): 0 раз(а)
Поблагодарили: 0 раз(а) в 0 сообщениях
По умолчанию Ответ: Срочно! Помогите! О разделяемой памяти!

Кто может объяснить мне:

Есть функция float getFloat(const char * name, float val), она
вызывает get() с определенным набором параметров, а get() натравливает
IsFound() на поиск имени переменной в map , которая собирается с
ини-файла.
Собирается все отлично, переменные, их тип и адреса видны в файлике
load_files.srv. НО!

Когда мы начинаем брать значения этих переменных (хоть по имени, хоть
по номеру из этого файла) - нам возвращают -1 в первом случае и NULL
во втором.

Тут и начинается самое интересное:

- В смлоджик имена менял (на всякий) - ноль эмоций
- Контроллер рестартил
- Наткнулся на кучу ерроров нетбинс (IDE на убунте), которая не может
распарсить итераторы у мапа (хотя на это можно положить)
- Обнаружил очень интересную фичу: раньше итемы в листе собирали с
чарами, а теперь решили собрать со стрингом. На всякий, оставив
комментами старые методы. Если честно, возвращать обратно чары не вижу
смысла (см. про NULL в ответ на запрос по номеру переменной), но
интересен сам факт - видимо с именами проблемы уже были.

#include "shm.hpp"

int main()
{
Shm mymem("./load_files.srv"); //Инициализация переменных разделяемой памяти
//FILE *file;

struct timespec tv;//Структура для задания временных интервалов
tv.tv_sec = 0;
tv.tv_nsec = 100000000; //(наносекунд) задержка в 1 сек
// хотя лучше сделать столько-же, сколько период обновления на веб-морде (!)


if (( mymem.getType("mem_tech") == FLOAT ) && \
( mymem.getType("mem_in") == FLOAT ) && \
( mymem.getType("mem_out") == FLOAT ) && \
( mymem.getType("mem_room") == FLOAT ))
for (int i=0;i<50;i++) // Бесконечный цикл
{
/*if ((file = fopen("result.txt","w")) == NULL)
{
printf("Can't open file\n");
exit(-1);
} else {
fprintf (file, "<?xml version=\"1.0\" encoding=\"cp1251\">");
fprintf (file, "<result>");
fprintf (file, "<bases>");*/

nanosleep(&tv, NULL); //выполняем задержку для экономии ресурсов

//================================================== ==================//
// mem_tech - температура наружняя //
//================================================== ==================//
float mem_tech = mymem.getFloat(6);
//fprintf(file,"<base>mem_tech = %f</base>",mem_tech);
printf("<base>mem_tech = %3.6f</base>\n",mem_tech);

//================================================== ==================//
// mem_in - температура канала //
//================================================== ==================//
float mem_in = mymem.getFloat(7);
//fprintf(file,"<base>mem_in = %f</base>",mem_in);
printf("<base>mem_in = %f</base>\n",mem_in);

//================================================== ==================//
// mem_out - температура обр_воды //
//================================================== ==================//
float mem_out = mymem.getFloat(8);
//fprintf(file,"<base>mem_out = %f</base>",mem_out);
printf("<base>mem_out = %f</base>\n",mem_out);

//================================================== ==================//
// mem_room - температура помещения //
//================================================== ==================//
float mem_room = mymem.getFloat(9);
//fprintf(file,"<base>mem_room = %f</base>",mem_room);
printf("<base>mem_room = %f</base>\n",mem_room);

/*fprintf (file, "</bases>");
fprintf (file, "</result>");
fclose(file);
}*/

printf("=====\n");
} else {
//fprintf(file,"<base>ERROR: mem_tech has type %d</base>",mymem.getType("mem_tech"));
printf("ERROR: mem_tech has type %d\n",mymem.getType("mem_tech"));
//fprintf(file,"<base>ERROR: mem_in has type %d</base>",mymem.getType("mem_in"));
printf("ERROR: mem_in has type %d\n",mymem.getType("mem_in"));
//fprintf(file,"<base>ERROR: mem_out has type %d</base>",mymem.getType("mem_out"));
printf("ERROR: mem_out has type %d\n",mymem.getType("mem_out"));
//fprintf(file,"<base>ERROR: mem_room has type %d</base>",mymem.getType("mem_room"));
printf("ERROR: mem_room has type %d\n",mymem.getType("mem_room"));
exit(-1);
}
printf("DONE\n");
}


Собственно вопрос: в каком случае вашими нативными методами
нельзя взять перменные? (хотелось бы МАКСИМАЛЬНО подробно)
AlexSE вне форума   Ответить с цитированием
Старый 04.07.2012, 14:58   #8
Antistatic
Новичок
 
Регистрация: May 2010
Сообщения: 26
Благодарил(а): 0 раз(а)
Поблагодарили: 0 раз(а) в 0 сообщениях
По умолчанию Ответ: Срочно! Помогите! О разделяемой памяти!

Что сразу бросается в глаза.

Цитата
Сообщение от AlexSE
tv.tv_nsec = 100 000 000; //(наносекунд) задержка в 1 сек
и
for (int i=0;i<50;i++) // Бесконечный цикл
Задержка совсем не 1 сек , а 0,1. (10^-1) так как наносекунда 10^-9

Цикл ни разу не бесконечный, а длится 5 сек.

В связи с этим, проверьте что за это время переменные принимают какие то осмысленные значения. Используйте вызов функций вида GetFloat("Название переменной"). Проверьте на переменных другого типа-Short, Long.
Antistatic вне форума   Ответить с цитированием
Старый 04.07.2012, 18:00   #9
AlexSE
Новичок
 
Регистрация: Jun 2012
Сообщения: 20
Благодарил(а): 0 раз(а)
Поблагодарили: 0 раз(а) в 0 сообщениях
По умолчанию Ответ: Срочно! Помогите! О разделяемой памяти!

Да просто комменты не убрал со старого цикла.

> проверьте что за это время переменные принимают какие то осмысленные значения
свой проект я запускаю при старте процесса logix, и дополнительно запускаю руками - поэтому переменные явно успевают стать осмысленными.

Так а толку от других типов? Мне нужны градусы с большой точность. Целочисленным типом здесь делать нечего, даже если он заработает.
AlexSE вне форума   Ответить с цитированием
Ответ

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра

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

BB code is Вкл.
[IMG] код Вкл.
HTML код Выкл.


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Распределение памяти в контроллере tvf Вопросы о программировании 48 25.09.2018 11:31
Вопрос по разделяемой памяти oiv_1968 Вопросы о SMH-2G(i) 2 06.02.2017 22:47
Составление карты памяти ПЧ sbatrov Связь с внешним миром 6 29.10.2015 16:38
Достаточно ли размера модуля памяти для сохранения проекта? asen Вопросы о Pixel 5 07.10.2015 17:11
Очистить модуль памяти (решено) gregorysoft Вопросы о Pixel 13 29.08.2014 16:10


Часовой пояс GMT +4, время: 11:42.


Версия vBulletin: 3.8.3
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Segnetics 2005 - 2023