C++/CLI. Write to buffer (change cout on char buffer) and get string data from char buffer

Работая над проектом возникла необходимость в перехвате (громко сказано) стандартного вывода ( printf() ) для анализа того, с чем же приходилось работать. Далеко не копая, воспользовался "C"-шной функцией - sprintf(). Здесь небольшой faq. Данная функция на выходе все кладет в буфер. Приведу примерчик:

#include <stdio.h>

int main( void )
{
   char  buffer[200];
   int   j;
   


   /* Format and print various data: */
   j  = sprintf( buffer,     "   First string\n");
   j += sprintf( buffer + j, "   Second string\n");
   

   printf( "Output:\n%s\ncharacter count = %d\n", buffer, j );
}

 

 

 

 
В итоге имеем:

Output:

First string

Second string

character count = 25

 

 

 

 
 То, что нужно. Далее снова появилась мини-задачка: буфер - он и в Африке буфер, мне нужны были содержащиеся в нем данные, в частности - все "пойманные" строки. Их нужно было извлечь. Так как проект разрабатывался с помощью Microsoft Visual C++ 9.0 Express Edition (этого было достаточно :) ), то для сие нужды воспользовался методом gcnew String() (в следствие C++/CLI).
Он нужен для convert from 'char *' to 'System::String ^' . И снова пример:

// some code

char buffer[16];
String ^str;

sprintf(buffer, "Testing...\0");
   
str = gcnew String(buffer);
this->textBox1->AppendText(str);

// some code

И о чудо, я вновь "вижу" :)
Кстати, скоро новый год, еще  21 день. Заранее всех с наступающим :)

JavaScript. Несложное создание гистограмм

Учитывая, что сейчас многие пользуются блого-сервисами (blogger, tumblr, livejournal, etc.), могут возникнуть потребности в создании гистограмм. Мы же любим, когда данные можно "потрогать". Использование PHP в этом случае затруднено. Поэтому самый простой способ - создание гистограмм на JavaScripte с помощью CSS-стилей. Сразу отмечу, что сие способ описан в руководстве Флэнагана по JavaScript (со своими изменениями).
Основную работу будет выполнять js-файл - BarChart.js (см. листинг ниже). На входе он ожидает данные в виде массива, значения которого он аккуратно заклыдывает в гистограмму, которую выдает на выходе. Все очень просто. Ниже представлен один из примеров гистаграммы (Test chart).
Получаемые гистограммы легко инсталлируются в веб-странички. При этом можно входные данные сделать динамичными, так сказать - поставить на поток, что должно сделать динамичным и саму гистограмму. Ниже представлены листинги индексной html-странички и BarChart.js.
 
index.html
 
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<!-- Без объявления DOCTYPE в IE рисунок будет выглядеть неправильно -->
<html>
<head>
<script src="BarChart.js"></script> <!-- Подключить библиотеку -->
<script>
function drawChart() {
var data = [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,50,50,50,5,5,5,5,5,5,5,5,50,6,6,7,7,7,60,8];
var chart = makeBarChart(data, 300, 300);
var container = document.getElementById("chartContainer");
container.appendChild(chart);
}
</script>
</head>
<body onload="drawChart( )">
<h2>Test chart</h2><!-- Заголовок гистограммы -->
<div id="chartContainer"><!-- Здесь рисуется гистограмма --></div>
<!-- Подпись под гистограммой -->
<i>Test chart</i>
</body>
</html>
 
BarChart.js
 
 /**
* BarChart.js:
* В этом файле содержится определение функции makeBarChart(), которая
* создает гистограмму для вывода содержимого массива data[].
* Общий размер гистограммы определяется необязательными аргументами
* width и height, которые учитывают пространство, необходимое для рамок
* гистограммы и внутренних отступов. Необязательный аргумент barcolor
* определяет цвет столбиков. Функция возвращает созданный ею элемент
* <div>, таким образом, вызывающий сценарий может манипулировать
* этим элементом, например, изменять величину отступов. Вызывающий
* сценарий должен вставить в документ полученный от функции элемент,
* чтобы сделать его видимым.
**/
function makeBarChart(data, width, height, barcolor) {
 // Предусмотреть значения по умолчанию для необязательных аргументов
 if (!width) width = 500;
 if (!height) height = 350;
 if (!barcolor) barcolor = "blue";
 // Аргументы width и height определяют общий размер гистограммы.
 // Чтобы получить размер создаваемого элемента, необходимо вычесть
 // из этих значений толщину рамок и величину отступов.
 width -= 24; // Вычесть 10px отступа и 2px толщины рамки слева и справа
 height -= 14; // Вычесть 10px отступа сверху и 2px толщины рамки сверху и снизу
 // Создать элемент для размещения гистограммы. Обратите внимание:
 // гистограмма позиционируется в относительных координатах, т. е.
 // в ней могут располагаться дочерние элементы с абсолютным
 // позиционированием, и отображаться при этом в нормальном потоке
 // вывода элементов документа.
 var chart = document.createElement("div");
 chart.style.position = "relative"; // Относительное позиционирование
 chart.style.width = width + "px"; // Ширина гистограммы
 chart.style.height = height + "px"; // Высота гистограммы
 chart.style.border = "solid black 1px"; // Определить рамку
 chart.style.paddingLeft = "10px"; // Добавить отступ слева
 chart.style.paddingRight = "10px"; // Справа
 chart.style.paddingTop = "10px"; // Сверху
 chart.style.paddingBottom = "0px"; // Но не снизу
 chart.style.backgroundColor = "white"; // Фон гистограммы - белый
 // Рассчитать ширину каждого столбика

 //var barwidth = Math.floor(width/data.length);
 var barwidth = 1;

 // Отыскать наибольшее число в массиве data[]. Обратите внимание
 // на грамотное использование функции Function.apply().
 var maxdata = Math.max.apply(this, data);
 // Масштабирующий множитель: scale*data[i] дает высоту столбика
 var scale = height/maxdata;
 // Обойти в цикле массив с данными и создать столбики для всех элементов
 for(var i = 0; i < data.length; i++) {
  var bar = document.createElement("div"); // Создать столбик
  var barheight = data[i] * scale; // Рассчитать высоту
  bar.style.position = "absolute"; // Уст. размер и положение
  bar.style.left = (barwidth*i+1+10)+"px"; // Добавить рамку столбика
  // и отступ
  bar.style.top = height-barheight+10+"px";// Добавить отступ
  // гистограммы
  bar.style.width = (barwidth-2) + "px"; // -2 - рамка столбика
  bar.style.height = (barheight-1) + "px"; // -1 - рамка сверху
  if (data[i] >= 50) bar.style.border = "solid red 1px"; // Стиль рамки столбика при значениях более 50
  if (data[i] < 50) bar.style.border = "solid blue 1px"; // Стиль рамки столбика при значениях менее 50
  bar.style.backgroundColor = barcolor; // Цвет столбика
  bar.style.fontSize = "0px"; // Учесть особенность IE
  chart.appendChild(bar); // Добавить столбик
  // в гистограмму
 }
 // В заключение вернуть элемент с гистограммой
 return chart;
}


Все представленные листинги можно скачать здесь. Всем удачи.

 

C++. Simple displaying a Message Box

Простой способ создания диалоговоко окошка.

Для более подробного ознакомления - MessageBox function (Windows), Message Box Example (C++) (Windows) и Using Dialog Boxes (Window).

Немного кода (скачать):

#include <windows.h>

int DisplayResourceNAMessageBox() {
    int msgboxID = MessageBox(
        NULL,
        (LPCWSTR)L"Are you sitting down for an hour. Quickly raise your ass and go a walk",
        (LPCWSTR)L"Health timer",
        MB_OK
    );
    return msgboxID;
}

int main() {
 DisplayResourceNAMessageBox();
 return 0;
}

Ну и как всегда - удачи!

RSLogix5000. Создание массива. Объяснение на пальцах.

Как создать массив в RSLogix 5000? Очень просто. Есть два пути. По-крайней мере известных мне: - 1) Создать соответствующий тег в общем списке всех тегов контроллера (Control Tags); - 2) завести непосредственно в программе и далее правым кликом выбрать - `создать`. Ниже на пальцах на скриншотах показаны ориентиры в этом нелегком деле (выбран первый способ). Use it!
Step 1

Step 2

Step 3

Step 4

Step 5

Промышленное программирование. Введение. PLC/RSLogix5000/Archestra

Промышленное программирование.


Что же это такое? С чем приходиться больше сталкиваться: больше с промышленностью или с программированием? Лично у меня на это свой ответ: все зависит от технологии конкретного производства и, конечно, от степени внедренности на предприятии it-технологий. Также для меня стало очевидно, что круг вопросов программирования становится иным, весь фокус ложится именно на разработку промышленной логики (алгоритм) и визуализацию данной логики (по-сути - разработка интерфейса, позволяющего пользователю взаимодествовать с данной логикой в рамках технологических процессов). С этой точки зрения, промышленное программирование эквивалентно классическому: также - разработка алгоритма и также - разработка интерфейсной части. Но инструменты (язык) при этом свои, а ведь именно инструмент накладывает свои отпечатки на образ мышления. Думать по "С++" - ному - не то что думать по "PHP" - шному. Уверен, что Вы со мной согласитесь. Это же относится и к промышленному программированию.

Разработка помышленной логики (алгоритм).

Для кодинга в этом направлении используются свои языки. Все зависит от того, какой контроллер используется на предприятии. В моем случае - RSLogix, скорее это даже не язык, а среда разработки - RSLogix 5000 (разработка компании Rockwell Automation) для контроллеров производителя Allen Bredly (Allen Bredly Programmable Controller).




В  RSLogix реализованы три подхода в программировании:
1 - Ladder Diagram (по-сути - RAD (от англ. rapid application development — быстрая разработка приложений));
2 - Function Block (графичский подход, ориентировано больше на инженеров по микроэлектронике);
3 - Structered Text (можно сказать - Паскаль в действии);
В большей степени на практике использую именно первый подход - Ladder Diagram. Ниже представлен небольшой пример программы: каждые 0,1 секунду контроллер считывает внешний сигнал - Signal - и записывает полученные значения в одномерный массив test[i]. И так - 10 раз. Программа конечно несложная, скорее - наглядная.
Сам по себе, синтаксис паскалеподобный.
Типы данных представлены не только такими как - bool, int, dint (double int), string, real (аналог float), timer, но и специфичными - alarm, hmi_button, etc.
Максимальная допустимая к созданию размерность массива - `3`мерная (Array Dimensions). Если в Паскале мы имеем дело с процедурой, то здесь представлены `Add-on`ы (Control module), в которых есть как внешние (Parameters), так и внутренние (Local Tags) члены, есть возможность назначить модификаторы доступа как в классах ООП (required, visibility).
Раасматривать другие возможности здесь не буду, просто скажу, что все, что есть в обычном программировании - есть и здесь, плюс свои "штучки".

Вообще, когда начинаешь программировать, то приходиться работать с 1) со множеством сигналов от различных датчиков, устройств, моторов, клапанов, ну и прочего оборудования и 2) центром всего - контроллером. Когда мы сидим за ноутом или компом и программируем, то часто не берем в счет то, что мы также обращаемся к микрокотроллеру - центральному процессору. Для высокоуровневых языков с ООП подходом - нормально, но если взять ассемблер - без этого никак. Ниже представлен промышленный контроллер. Протокол общения - сетевой стандарт - tcp/ip.



 










Для контоллеров Siemens используется Simatic Step7. Подходы теже самые, но со своими нюансами.

Визуализация промышленной логики (графический интерфейс пользователя).

 "Общение" программы с конечным пользователем происходит на уровне интерефейса, в большей степени - графическом интерфейсе. В промышленном программировании - конечным пользователем является так называемый - оператор, причем так звучит должность человека на фабрике. Все серьезно :) Отсюда понятно, что интерефейс должен быть интуитивно понятным, а значит - графическим (70 % информации "бежит" по глазам). Поэтому приходиться решать и чисто дизайнерские задачи. Для наглядности приведен скриншотик рабочей зоны вот такого вот интефейса.

Вообще, система визуализации в промышленности именуется SCADA (аббр. от англ. supervisory control and data acquisition, диспетчерское управление и сбор данных). На самом деле, визуализация - это не просто создание интерфеса, это система сбора, управления и вывода данных. У нас на фабрике используется системная платформа - Archestra SCADA компании Invensys Systems. Также есть альтернативные системы, например - Elipse.

Стоит отметить и еще одну вещь. Теги (англ. tag — ярлык, этикетка, бирка; метить). После знакомства с промышленным программированием, понятие тега встречается практически на всех этапах. Для меня тег - не просто какая-то высокоуровневая метка, это носитель информационных единиц (true/false), также и носитель физических данных между контроллером и человеком. Своего рода теговый мостик (Tags bridge). Ниже представлены модели взаимодействия контроллера со SCADA с одной стороны, и с другой - датчиками, моторами, клапанами и другими устройствами.


Вот такое небольшое введение в промышленное программирование. Всем удачи :)