# data[].attributes.headline
Це все, що я можу зр

# data[].attributes.body
Це все, що я можу зробити(((, бо не має даних
P.S.: Анна

# data[].attributes.attachment_link.readable_text
Іноді потрібно не зчитуючи детальну інформацію з безлічі датчиків, просто оцінити поточний стан системи і динаміку зміни її стану за якийсь період. От і мені захотілося зробити пристрій, що показує зміни даних з датчиків у вигляді красивих картинок невеликих діаграм, які можна переглянути у вікні браузера мобільних пристроїв або комп'ютера, підключені в локальну мережу. При цьому визначальним фактором була мінімальна вартість і простота реалізації.

Після перебору різних варіантів рішення цієї задачі звернув увагу на мікроконтролери Arduino. Плюсом даних пристроїв є простота отримання необхідного "залізного" функціоналу шляхом простого з'єднання елементів. Наприклад, для отримання можливості з'єднання з локальною мережею досить на основну плату надіти зверху плату мережевого адаптера. Головне, щоб при цьому збіглися відповідні роз'єми.

Сигнал з датчика надходить на аналоговий вхід мікроконтролера, обробляється, наприклад, усереднюється за необхідні, раніше встановлені інтервали часу. Мікроконтролер містить програмне забезпечення, що реалізує http-сервер, на запит з браузера клієнта видає в локальну мережу html-сторінку з інформацією від датчика. Таким чином, будь-який пристрій, що має веб-браузер, наприклад, смартфон підключений до локальної мережі, має можливість перегляду графіка.

Апаратна частина перетворювача складається з двох частин: плати Arduino Uno, що включає процесор Atmega328, і Ethernet шилда. Були випробувані обидва типи наявних в колекції Arduino Ethernet-шилдов на ІС ENC28j60 і на W5100.
Можливості вебсервера вкрай обмежені розміром доступної пам'яті плати Arduino і архітектурою мережевої плати, але вдалося написати скетч, який працює з обома Ethernet-шилдами.

Програмне забезпечення (скретч) для arduino розроблене для двох різних умов застосування. У першому випадку передбачалося, що клієнти, які дані, що мають доступ в інтернет, що дозволяє використовувати зовнішні бібліотеки для візуалізації. При використанні бібліотеки для побудови гістограм від Google зовнішній вигляд сторінки, одержуваної від Arduino, може бути таким:

Скетч для виведення даних у вигляді діаграми c Ethernet шилдом на базі чіпа W5100 представлений нижче. При бажанні використовувати плату з чіпом ENC28J60 необхідно просто розкоментувати 1 рядок і закоментувати наступні 2 рядки скетчу. У програмі застосовані методи оптимізації використання пам'яті процесора для того, щоб максимально звільнити оперативну пам'ять і домогтися надійної роботи програми на обох типах мережевих адаптерів.

скетч гістограми//виведення даних за допомогою web-сервера у вигляді гістограми
// автор А. Коновалов 2015 р.
//#include <UIPEthernet.h> //для роботи з ENC28J60
#include <Ethernet.h>
#include <SPI.h
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
IPAddress ip(192,168,26,15);

EthernetServer server(80);
const char str1[] PROGMEM = "<!DOCTYPE html>";
const char str2[] PROGMEM = " ";
const char str12[] PROGMEM = " ";

const char* const string_table[] PROGMEM = {str1, str2, str3, str4, str5, str6, str7};
const char* const string_table2[] PROGMEM = {str8, str9, str10, str11, str12};
char myChar;
char buffer[80];

unsigned long previousMillis1 = 0;// посл момент часу
unsigned long previousMillis2 = 1;// посл момент часу
unsigned long previousMillis3 = 1;// посл момент часу

long OnTime2 = 60000; // хвилина
long OnTime3 = 1800000; // півгодини
int In_sec = 0; // відлік за сек
int In_min = 0; // відлік за хв
int In_half = 0; // відлік за півгодини

long Sum_min = 0; // сума за хв
long Sum_half = 0; // сума за півгодини
float Sum_base_min = 0;
float Sum_base_half = 0;
int i,j,k =0;

void setup()
{
// start the Ethernet connection and the server:
Ethernet.begin(mac, ip);
server.begin();

}
//unsigned long begMillis = millis();// поч час в мс
void loop()
{
unsigned long currentMillis = millis();// тек час в мс

In_sec = analogRead(0);
Sum_min = Sum_min + (currentMillis - previousMillis1) * In_sec;
In_min = (Sum_min + Sum_base_min ) / (OnTime2 * i + currentMillis - previousMillis2);
Sum_half = Sum_half + (currentMillis - previousMillis1) * In_sec;
In_half = (Sum_half + Sum_base_half) / (OnTime3 * j + currentMillis - previousMillis3);
previousMillis1 = currentMillis; // запам'ятовуємо момент часу

if(currentMillis - previousMillis2 >= OnTime2)
{ i=1;
Sum_base_min = Sum_min;
previousMillis2 = currentMillis; // запам'ятовуємо момент часу
Sum_min = 0;
}
if(currentMillis - previousMillis3 >= OnTime3)
{ j=1;
Sum_base_half = Sum_half;
previousMillis3 = currentMillis; // запам'ятовуємо момент часу
Sum_half = 0;
}

EthernetClient client = server.available();
if (client) {
boolean currentLineIsBlank = true;
while (client.connected()) {
if (client.available()) {
char c = client.read();
if (c == '\n' && currentLineIsBlank) {
for (int i = 0; i < 7; i++)
{
strcpy_P(buffer, (char*)pgm_read_word(&(string_table[i])));
client.print(buffer);
delay( 500 );
}
client.print("['Enter 1', ");
client.print(In_sec);
client.print(", ");
client.print(In_min);
client.print(", ");
client.print(In_half);
client.print( "],]);");

В даному скетчі зчитуються дані з нульового аналогового входу і проводиться їх усереднення за півгодинний і хвилинний інтервал. При запиті з http клієнта за адресою 192.168.26.15 ці дані виводяться у вигляді гістограми. Зрозуміло, перед завантаженням даної програми необхідно ввести потрібну адресу вашої локальної мережі.

При бажанні можна також виводити дані з arduino у вигляді лінійних графіків:

Скетч для такого подання даних представлений нижче:

скетч з лінійним графіком//виведення даних за допомогою web-сервера у вигляді графіків
// автор А. Коновалов 2015 р.
//#include <UIPEthernet.h>
#include <Ethernet.h>
#include <SPI.h>
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
IPAddress ip(192,168,26,15);

EthernetServer server(80);
const char str1[] PROGMEM = "<!DOCTYPE html>";
const char str2[] PROGMEM = " ";
const char str12[] PROGMEM = " ";

const char* const string_table[] PROGMEM = {str1, str2, str3, str4, str5, str6, str7};
const char* const string_table2[] PROGMEM = {str8, str9, str10, str11, str12};
char myChar;
char buffer[80];

unsigned long previousMillis1 = 0;// посл момент часу
unsigned long previousMillis2 = 1;// посл момент часу
unsigned long previousMillis3 = 1;// посл момент часу

long OnTime2 = 60000; // хвилина
long OnTime3 = 600000; // півгодини
int In_sec = 0; // відлік за сек
int In_min = 0; // відлік за хв
int In_half = 0; // відлік за півгодини

long Sum_min = 0; // сума за хв
long Sum_half = 0; // сума за півгодини
float Sum_base_min = 0;
float Sum_base_half = 0;
int i,j,k =0;

void setup()
{
// start the Ethernet connection and the server:
Ethernet.begin(mac, ip);
server.begin();

}
//unsigned long begMillis = millis();// тек час в мс
void loop()
{
unsigned long currentMillis = millis();// тек час в мс

In_sec = analogRead(0);
Sum_min = Sum_min + (currentMillis - previousMillis1) * In_sec;
In_min = (Sum_min + Sum_base_min ) / (OnTime2 * i + currentMillis - previousMillis2);
Sum_half = Sum_half + (currentMillis - previousMillis1) * In_sec;
In_half = (Sum_half + Sum_base_half) / (OnTime3 * j + currentMillis - previousMillis3);
previousMillis1 = currentMillis; // запам'ятовуємо момент часу

if(currentMillis - previousMillis2 >= OnTime2)
{ i=1;
Sum_base_min = Sum_min;
previousMillis2 = currentMillis; // запам'ятовуємо момент часу
Sum_min = 0;
}
if(currentMillis - previousMillis3 >= OnTime3)
{ j=1;
Sum_base_half = Sum_half;
previousMillis3 = currentMillis; // запам'ятовуємо момент часу
Sum_half = 0;
}

EthernetClient client = server.available();
if (client) {
// an http request ends with a blank line
boolean currentLineIsBlank = true;
while (client.connected()) {
if (client.available()) {
char c = client.read();
if (c == '\n' && currentLineIsBlank) {

for (int i = 0; i < 7; i++)
{
strcpy_P(buffer, (char*)pgm_read_word(&(string_table[i]))); // Necessary casts and dereferencing, just copy.
client.print(buffer);
delay( 500 );
}

client.print("['Enter 1', ");
client.print(In_sec);
client.print(", ");
client.print(In_min);
client.print(", ");
client.print(In_half);
client.print( "],]);");

for (int i = 0; i < 5; i++)
{
strcpy_P(buffer, (char*)pgm_read_word(&(string_table2[i]))); // Necessary casts and dereferencing, just copy.
client.print(buffer);
delay( 500 );
}

break;
}
if (c == '\n') {
// you're starting a new line
currentLineIsBlank = true;
}
else if (c != '\r') {
// you've gotten a character on the current line
currentLineIsBlank = false;
}
}
}
// give the web browser time to receive the data
delay(1);
// close the connection:
client.stop();
}
}

Крім того, з чистої цікавості, у рамках дослідження можливостей застосування бібліотеки google був написаний скетч, що дозволяє виводити інформацію у вигляді аналогового вимірювального приладу. Він дозволяє швидко оцінити поточне значення сигналу.

скетч з приладом//виведення даних за допомогою web-сервера у вигляді приладу
// автор А. Коновалов 2015 р.
//#include <UIPEthernet.h>
#include <Ethernet.h>
#include <SPI.h>

byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
IPAddress ip(192,168,26,15);

EthernetServer server(80);
const char str1[] PROGMEM = "<!DOCTYPE html>";
const char str2[] PROGMEM = " ";
const char str12[] PROGMEM = " ";

const char* const string_table[] PROGMEM = {str1, str2, str3, str4, str5, str6, str7};
const char* const string_table2[] PROGMEM = {str8, str9, str10, str11, str12};
char myChar;
char buffer[80];

int In_sec = 0; // відлік за сек
int i,j,k =0;

void setup()
{
// start the Ethernet connection and the server:
Ethernet.begin(mac, ip);
server.begin();

}
//unsigned long begMillis = millis();// тек час в мс
void loop()
{
In_sec = analogRead(0);
EthernetClient client = server.available();
if (client) {
// an http request ends with a blank line
boolean currentLineIsBlank = true;
while (client.connected()) {
if (client.available()) {
char c = client.read();
if (c == '\n' && currentLineIsBlank) {

for (int i = 0; i < 7; i++)
{
strcpy_P(buffer, (char*)pgm_read_word(&(string_table[i]))); // Necessary casts and dereferencing, just copy.
client.print(buffer);
delay( 500 );
}

client.print(In_sec);
client.print("]]);");

for (int i = 0; i < 5; i++)
{
strcpy_P(buffer, (char*)pgm_read_word(&(string_table2[i]))); // Necessary casts and dereferencing, just copy.
client.print(buffer);
delay( 500 );
}

break;
}
if (c == '\n') {
// you're starting a new line
currentLineIsBlank = true;
}
else if (c != '\r') {
// you've gotten a character on the current line
currentLineIsBlank = false;
}
}
}
// give the web browser time to receive the data
delay(1);
// close the connection:
client.stop();
}
}

У разі, якщо для читання даних з датчиків немає можливості використовувати пристрої, пов'язані з інтернетом, випробуваний інший спосіб побудови діаграм Arduino, заснований на використанні Scalable Vector Graphic (SVG).

Т. к. потрібно просто оцінити динаміку зміни параметрів, то в результаті виконання нижчеподаного скетчу при запиті даних з ардуїнов, на екрані браузера побачимо наступну диаграммку:

Один погляд на диаграммку дозволяє зрозуміти динаміку зміни параметра за певні раніше інтервали часу.

Скетч наведено нижче:

скетч SVG графік//виведення даних за допомогою web-сервера у вигляді гістограми
// автор А. Коновалов 2015 р.

//#include <UIPEthernet.h>
#include <Ethernet.h>
#include <SPI.h>

byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
IPAddress ip(192,168,26,15);

EthernetServer server(80);
const char str1[] PROGMEM = "";
const char str2[] PROGMEM = "/>";
const char str4[] PROGMEM = "";
char myChar;
int out;

unsigned long previousMillis1 = 0;// посл момент часу
unsigned long previousMillis2 = 1;// посл момент часу
unsigned long previousMillis3 = 1;// посл момент часу

long OnTime2 = 60000; // хвилина
long OnTime3 = 600000; // півгодини
int In_sec = 0; // відлік за сек
int In_min = 0; // відлік за хв
int In_half = 0; // відлік за півгодини

long Sum_min = 0; // сума за хв
long Sum_half = 0; // сума за півгодини
float Sum_base_min = 0;
float Sum_base_half = 0;
int i,j,k =0;

Ethernet.begin(mac, ip);
server.begin();

}
//unsigned long begMillis = millis();// тек час в мс
void loop()
{
unsigned long currentMillis = millis();// тек час в мс

In_sec = analogRead(0);
Sum_min = Sum_min + (currentMillis - previousMillis1) * In_sec;
In_min = (Sum_min + Sum_base_min ) / (OnTime2 * i + currentMillis - previousMillis2);
Sum_half = Sum_half + (currentMillis - previousMillis1) * In_sec;
In_half = (Sum_half + Sum_base_half) / (OnTime3 * j + currentMillis - previousMillis3);
previousMillis1 = currentMillis; // запам'ятовуємо момент часу

if(currentMillis - previousMillis2 >= OnTime2)
{ i=1;
Sum_base_min = Sum_min;
previousMillis2 = currentMillis; // запам'ятовуємо момент часу
Sum_min = 0;
}
if(currentMillis - previousMillis3 >= OnTime3)
{ j=1;
Sum_base_half = Sum_half;
previousMillis3 = currentMillis; // запам'ятовуємо момент часу
Sum_half = 0;
}

EthernetClient client = server.available();
if (client) {
// an http request ends with a blank line
boolean currentLineIsBlank = true;
while (client.connected()) {
if (client.available()) {
char c = client.read();
if (c == '\n' && currentLineIsBlank) {

for (k = 0; k < strlen(str1); k++)
{
myChar = pgm_read_byte_near(str1 + k);
client.print(myChar);
}

for (k = 0; k < strlen(str2); k++)
{
myChar = pgm_read_byte_near(str2 + k);
client.print(myChar);
}
out = 200 - In_sec/3;
client.print(out);
client.print(" 100,");
client.print(out);
client.print(" 250,");
out = 200 - In_min/3;
client.print(out);
client.print(" 300,");
out = 200 - In_half/3;
client.print(out);

for (k = 0; k < strlen(str3); k++)
{
myChar = pgm_read_byte_near(str3 + k);
client.print(myChar);
}
client.println();
client.print(In_sec);
client.println();
client.print(In_min);
client.println();
client.print(In_half);
for (k = 0; k < strlen(str4); k++)
{
myChar = pgm_read_byte_near(str4 + k);
client.print(myChar);
}
break;
}

if (c == '\n') {
// you're starting a new line
currentLineIsBlank = true;
}
else if (c != '\r') {
// you've gotten a character on the current line
currentLineIsBlank = false;
}
}
}
// give the web browser time to receive the data
delay(1);
// close the connection:
client.stop();
}
}

Наведені вище скетчі показують, як найпростішими засобами, без використання додаткового обладнання та програмних засобів, наприклад, веб-сервера і серверних додатків обробки даних, отримати прийнятний в умовах експлуатації вид відображення інформації з датчиків. Звичайно, при даному способі передачі даних необхідно наявність локальної мережі і для роботи мобільних пристроїв, Wi-Fi доступ в цю мережу.

При написанні скетчів велику допомогу надало керівництво для розробника, а також стаття на Хабре "Знайомство з SVG-графікою".
Бібліотека UIP не входить в стандартний набір, але може бути завантажена тут
Сподіваюся, спираючись на наведені мною приклади скетчів і посилання на навчальні матеріали вам буде легко змусити Arduino виводити графіки в тому вигляді, який вам більше сподобається.

Джерело: Хабрахабр

# data[].attributes.attachment_link.keywords[]
дані з arduino у вигляді діаграм і графіків

# data[].attributes.attachment_link.keywords[]
для початківців

# data[].attributes.attachment_link.keywords[]
візуалізація даних

# data[].attributes.attachment_link.keywords[]
візуалізація

# data[].attributes.attachment_link.keywords[]
графіки і діаграми

# data[].attributes.attachment_link.title
Дані з Arduino у вигляді діаграм і графіків

# data[].attributes.attachment_link.description
Іноді потрібно не зчитуючи детальну інформацію з безлічі датчиків, просто оцінити поточний стан системи і динаміку зміни її стану за якийсь період. От і мені захотілося зробити пристрій, що показує зміни даних з датчиків у вигляді красивих картинок невеликих діаграм, які можна переглянути у вікні браузера мобільних пристроїв або комп'ютера, підключені в локальну мережу.

# data[].attributes.headline
	сучасні інформаційні технології у професійній діяльності: як вони змінюють професію;	комп'ютер майбутнього: перші кроки чи далекі перспективи;	програми для роботи з текстом: чи є альтернатива;	надбудови табличного процесора: користь для користувача чи зайвий застосунок;	редактори комп'ютерної графіки: нові інструменти для майбутнього художника;	фрактали – це математика чи інформатика;	вікісайти: основи конструювання та приклади застосувань;	Офіс 365: сховище чи онлайнові офісні програми;	робототехніка: як знання інформатики допоможуть керувати роботом;	3D-моделювання: програми та реалізація.

# data[].attributes.subject
	сучасні інформаційні технології у професійній діяльності: як вони змінюють професію;	комп'ютер майбутнього: перші кроки чи далекі перспективи;	програми для роботи з текстом: чи є альтернатива;	надбудови табличного процесора: користь для користувача чи зайвий застосунок;	редактори комп'ютерної графіки: нові інструменти для майбутнього художника;	фрактали – це математика чи інформатика;	вікісайти: основи конструювання та приклади застосувань;	Офіс 365: сховище чи онлайнові офісні програми;	робототехніка: як знання інформатики допоможуть керувати роботом;	3D-моделювання: програми та реалізація.

# data[].attributes.headline
Робити власний сайт

# data[].attributes.subject
Робити власний сайт

# data[].attributes.headline
векторна графіка

# data[].attributes.subject
векторна графіка