Опубликовано

Arduino плюс Excel — сбор и хранение данных

По материалам книги В. Яценкова «Здоровье, спорт и окружающая среда в проектах Arduino» (глава 5. «Визуализация данных»)

Здоровье

Несмотря на широкое распространение облачных технологий и развитие систем обработки данных, в научных исследованиях и на производстве до сих пор часто применяется сбор, хранение и обмен данными в виде файлов Microsoft Excel. Если контроллер Arduino или другой прибор подключен к компьютеру через последовательный порт, можно без труда организовать автоматическое заполнение таблицы Excel, причем с поддержкой различных команд со стороны контроллера: заполнение ячеек, чтение ячеек, выбор рабочего листа таблицы, прокрутка листа и многое другое.

Компания Parallax Software разработала специальное расширение (plugin) PLX-DAQ для автоматического заполнения таблиц Excel данными, которые поступают от приборов через последовательный порт. Несколько лет назад официальная поддержка этого расширения была прекращена. Но энтузиасты платформы Arduino не просто продолжили его поддержку, а выпустили в 2016 году новую версию расширения, которая совместима с последними 64-битовыми версиями MS Office и Windows 10.

На официальном форуме Arduino создана специальная тема, посвященная этому расширению. Она расположена по адресу http://forum.arduino.cc/index.php?topic=437398.0. В первое сообщение темы разработчик регулярно добавляет ссылки на самую свежую версию расширения. На момент работы над книгой была доступна версия PLX-DAQ 2.11.

Расширение не требует установки и представляет собой файл Excel с присоединенным макросом на языке VBA (Visual Basic for Applications). Пользователь открывает файл, разрешает выполнение макросов и открывает последовательный порт, через который поступают данные из контроллера Arduino.

Строка сообщения Arduino содержит команды и данные. Макрос расширения считывает строку из последовательного порта, выполняет команды и сохраняет данные в ячейки таблицы. Макрос может отправить данные из таблицы Excel в Arduino в ответ на запрос контроллера.

Установка расширения на компьютер

Скачайте архив с самой новой версией расширения. Распакуйте его в удобное место. Архив состоит из следующих файлов:

  • PLX-DAQ-v2.11.xlsm — исходный шаблон файла Excel с макросом. Вы можете скопировать этот файл в другой каталог и переименовать или сохранить под другим именем;
  • PLX-DAQ-v2-DefaultSketch.ino — демонстрационный скетч Arduino, который содержит почти все возможные команды;
  • Beginners Guide to PLX DAQ v2 (rev1).doc — руководство пользователя;
  • PLX-DAQ-v2-AutoGrapher-RandomValue.ino — демонстрационный скетч с генератором случайных чисел и рисованием графика в реальном времени;
  • PLX-DAQ-v2-AutoGrapher-RandomValue.xlsm — файл Excel с примером данных для демонстрационного скетча.

Запуск расширения

Откройте файл шаблона. Для запуска расширения необходимо разрешить выполнение макросов (рис. 5.5). Нажмите кнопку Параметры и в открывшемся окне настроек выберите опцию Разрешить это содержимое. Если макрос не запустился автоматически, нажмите кнопку с надписью Open PLX DAQ UI в верхней части шаблона.

exclamation Готовый файл Excel c встроенным макросом PLX-DAQ (файл DustSensorTest.xlsm) можно найти в сопровождающем книгу электронном архиве (см. приложение 1). https://bhv.ru/product/zdorove-sport-i-okruzhayushhaya-sreda-v-proektah-arduino/

По соображениям безопасности не рекомендуется глобально разрешать выполнение произвольных макросов в общих настройках Excel. Лучше потратить несколько секунд на включение макросов по запросу.

5-5

Рис. 5.5. Запрос системы безопасности на разрешение запуска макросов

Рабочее окно и органы управления

После запуска макроса нажмите на кнопку Display direct debug, чтобы открыть поле, в которое выводятся поступающие данные и команды (рис. 5.6).

5-6

Рис. 5.6. Окно макроса PLX-DAQ

  • Port — номер порта, к которому подключен контроллер Arduino;
  • Baud — скорость соединения, бод;
  • Connect — установить соединение с портом;
  • Pause logging / Resume logging — приостановить запись данных;
  • Reset Timer — сбросить таймер макроса. Таймер используется для подстановки меток времени в таблицу и измерения продолжительности работы макроса Excel;
  • Clear Columns — удаляет все данные из столбцов таблицы. Заголовки столбцов сохраняются;
  • Display / Hide direct debug — показывает или прячет текстовое поле в правой части окна. В текстовом поле отображаются поступающие команды;
  • Sheet name to post to — отображает список доступных листов текущей книги Excel. Данные будут сохраняться в лист, который выбран в списке. В документе такой лист обозначен опцией ActiveSheet. После добавления, удаления или переименования листов обязательно нажмите кнопку Load для обновления списка;
  • Controller Messages — отображает последнее сообщение, поступившее от контроллера. Обычно сообщения меняются очень часто, поэтому их удобнее наблюдать в окне Direct Debug Window;
  • Reset on Connect — обычно при подключении к порту происходит автоматический сброс контроллера. Эта опция позволяет отключить автоматический сброс, если нельзя прерывать работу контроллера;
  • Custom Checkbox 1/2/3 — пользовательские опции для управления работой контроллера. Arduino может задать подписи к флажкам в окне макроса, читать состояние флажков и выполнять определенные действия в зависимости от их наличия;
  • Log incoming data? — запись входящего потока данных от контроллера в окно отладки. Уберите этот флажок, если возникают проблемы с быстродействием макроса;
  • Log outgoing data? — запись исходящего потока данных из макроса в контроллер. Уберите этот флажок, если возникают проблемы с быстродействием макроса;
  • Log system messages? — запись системной информации Excel (например, сообщений об ошибках). Уберите этот флажок, если возникают проблемы с быстродействием макроса;
  • Add timestamp? — добавление метки времени к каждой записи лога. Полезно для отладки;
  • кнопка => — увеличивает размер окна отладки;
  • кнопка <= — уменьшает размер окна отладки;
  • Clear — удаляет все записи в окне отладки.
exclamation Не перемещайте окно макроса во время записи данных. Это может привести к сбою работы Excel и потере данных.

Формат строки данных Arduino

Строка команд выводится в порт командой Serial.println(). Для правильного обмена данными между Arduino и макросом расширения строка должна иметь строго определенный формат. Вот пример стандартной строки:

Serial.println( (String) “DATA,DATE,TIME,” + millis() );

Команды строки данных можно условно разделить на основные группы:

  • настройка и передача данных — команды для форматирования листа и передачи данных;
  • специальные команды и управление — команды для переключения между листами и использования управляющих полей Custom Checkbox для Arduino;
  • рабочая книга Excel — команды для управления процессом записи данных или сохранения рабочей книги;
  • прочие команды — дополнительные команды, которые не имеют важного прикладного значения.

Рассмотрим подробнее эти группы команд.

Команды настройки и передачи данных

  • CLEARSHEET — полностью очищает рабочий лист (включая загловки столбцов!). Эта команда должна быть первой в любом скетче.

Пример: Serial.println(“CLEARSHEET”);

  • CLEARDATA — очищает только данные (начиная со второй строки таблицы).

Пример: Serial.println(“CLEARDATA”);

  • LABEL — устанавливает заголовки столбцов в первой строке таблицы.

Пример: Serial.println(“LABEL, Temperature, Humidity, Lightness”);

  • DATA — самая главная и важная команда. Служит для передачи данных из Arduino в активный лист книги Excel. Вы можете передавать произвольные данные, но должны разделить данные запятыми и обеспечить совпадение количества столбцов данных и количества заголовков.

Зарезервированные слова DATE, TIME и TIMER распознаются макросом и заменяются на соответствующие значения: слово DATE — на текущую системную дату компьютера (например, 15.09.2018), слово TIME — на текущее системное время (например, 15:32:17), слово TIMER — на продолжительность текущего сеанса работы макроса в секундах (например, 1458).

В строку можно добавить ключевое слово AUTOSCROLL_XX. Распознав это слово, макрос автоматически прокручивает текущий лист так, чтобы в нижней части таблицы всегда были пустые строки. Число XX указывает, сколько строк с данными следуют выше последней строки с данными, — например, AUTOSCROLL_20.

Специальные команды и управление

  • CELL,SET — вводит произвольное значение в указанную ячейку таблицы. Можно работать как с активным листом (ActiveSheet), так и с любым другим листом.

Пример для активного листа: Serial.println(“CELL,SET,C9,myValue”);

Эта команда вводит значение myValue в ячейку С9 активного листа.

Пример для произвольного листа:

Serial.println(“CELL,SET, ONSHEET,mySheet,C,9,myValue”);

Эта команда вводит значение myValue в ячейку C9 листа с названием mySheet.

exclamation Внимание!При высоких скоростях обмена могут возникнуть проблемы с обработкой команды SET — макрос не будет успевать ее выполнить. В таком случае уменьшите скорость передачи данных или введите небольшую задержку перед командой. Обычно достаточно задержки в диапазоне 3–100 мс (например, delay(10)).
  • CELL,GET — извлекает данные из указанной ячейки и передает их в Arduino. Например, можно заранее сохранить в таблицу последовательность значений температуры и времени, а термостат на основе Arduino будет поочередно считывать значения и выдерживать указанную температуру в течение заданного промежутка времени. Аналогичным образом можно управлять различными технологическими процессами — от координатного станка до инкубатора.
exclamation Контроллер Arduino должен не только отправить команду запроса, но и прочитать строку ответа. Тип данных ответа может быть Integer (целое число) или String (строка). Вы должны быть уверены, что макрос отправит именно строку, если Arduino ждет строку, и целое число, если Arduino ждет число.Используйте для чтения ответа одну из следующих команд:

Serial.readStringUntil(10);

Serial.readStringUntil(10).toInt();

Serial.readStringUntil(10).toFloat();

Число 10 в коде ASCII означает конец строки, поэтому следует использовать только это число.

Пример кода Arduino:

int myData;

Serial.println(“CELL,GET,C9”); // команда чтения из ячейки C9

myData = Serial.readStringUntil(10).toInt(); // получение ответа

Пример чтения содержимого ячейки C9 из произвольного листа mySheet:

Serial.println(“CELL,GET,FROMSHEET,mySheet,C,9”);

exclamation Внимание!При высоких скоростях обмена могут возникнуть проблемы с обработкой команды GET — макрос не будет успевать ее выполнить. В таком случае уменьшите скорость передачи данных или введите небольшую задержку перед командой. Обычно достаточно задержки в диапазоне 3–100 мс (например, delay(10)).
  • ROW — вы можете явно задать значение указателя строки, с которой будете работать. Например, когда записаны 20 строк данных, вы можете сбросить указатель до значения 2 и начать сначала заполнение строк.

Примеры команд:

Serial.println(“ROW,SET,2”);

Serial.println(“ROW,GET”);

int myRow = Serial.readStringUntil(10).toInt();

  • CUSTOMBOX1 / CUSTOMBOX2 / CUSTOMBOX3 — вы можете задать подпись к опции, снять или установить флажок и прочитать состояние опции (булево значение false / true).

Примеры:

Serial.println(“CUSTOMBOX1,LABEL,LED Light”);

Serial.println(“CUSTOMBOX1,GET”);

boolean myV=CheckValue = Serial.readStringUntil(10).toInt();

  • CLEARRANGE — очищает заданный диапазон строк (range) активного листа.

Пример: Serial.println(“CLEARRANGE,B,10,D,20”);

  • RESETTIMER — сбрасывает счетчик продолжительности работы расширения.

Пример: Serial.println(“RESETTIMER”);

Рабочая книга Excel

  • PAUSELOGGING / RESUMELOGGING / STOPLOGGING — пауза записи данных / возобновление записи / прекращение записи. Разумеется, расширение продолжит «слушать» и выполнять поступающие команды, даже если запись данных в ячейки приостановлена или прекращена.

Пример: Serial.println(“PAUSELOGGING”);

  • SAVEWORKBOOK — сохраняет рабочую книгу Excel под текущим именем. Команда полезна, если вы записываете данные в течение длительного времени и хотите периодически сохранять файл с данными.
  • SAVEWORKBOOKAS — сохраняет рабочую книгу Excel под заданным именем. По умолчанию новый файл сохраняется в тот же каталог, где находился исходный файл, но вы можете задать новый каталог в строке имени файла.

Пример сохранения в текущий каталог:

Serial.println(“SAVEWORKBOOKAS,MyNewWorkbookName”);

Пример сохранения в подкаталог с именем mySubfolder:

Serial.println(“SAVEWORKBOOKAS,mySubfolder\Workbookname”);

  • FORCEEXCELQUIT — опасная команда! Немедленно прекращает работу Excel! Обязательно сохраните рабочую книгу перед отправкой этой команды.

Пример: Serial.println(“FORCEEXCELQUIT”);

Прочие команды

  • BEEP — всего лишь заставляет компьютер издать короткий звуковой сигнал встроенным звукоизлучателем материнской платы или корпуса. Полезно, если надо привлечь внимание пользователя, когда достигнуто определенное значение величины, которую вы измеряете.

Пример: Serial.println(“BEEP”);

  • MSG — помещает заданный текст в метку сообщения Controller Message в окне расширения.

Пример: Serial.println(“MSG,Put your text here”);

  • DONE — принудительно передает содержимое буфера последовательного порта со стороны Excel.
  • GETRANDOM — передает случайное число из Excel в Arduino. Это полезная команда, потому что Arduino не может самостоятельно генерировать случайные числа. Функции random() в Arduino требуется инициализация генератора случайных чисел начальным значением при помощи функции randomSeed(value). Если начальное значение будет повторяться, то и вся последовательность полученных псевдослучайных чисел тоже будет повторяться. Обычно генератор случайных чисел Arduino инициализируют случайным значением, прочитанным с «висящего в воздухе» аналогового входа. Но если все входы заняты, начальное значение можно получить из Excel.

Пример:

Serial.println(“GETRANDOM,-31313,32323”);

int rndseed = Serial.readStringUntil(10).toInt();

randomSeed(rndseed);

Serial.println( (String) “1st number: “ + random(0, 50));

Serial.println( (String) “2nd number: “ + random(0, 50));

Serial.println( (String) “3rd number: “ + random(0, 50));

Демонстрационный скетч PLX–DAQ

Демонстрационный скетч, приведенный в листинге 5.5, основан на коде скетча из комплекта поставки расширения PLX-DAQ v.2.11. Скетч содержит почти все доступные команды для работы с таблицей Excel.

Загрузите скетч в плату Arduino. Откройте исходный шаблон файла Excel из комплекта поставки расширения. В поле Port введите номер последовательного порта, к которому подключена плата. Остальные настройки не меняйте. Нажмите кнопку Display direct debug в окне расширения. Затем нажмите кнопку Connect. Если все работает правильно, контроллер перезагрузится, и в окне отладки побегут строки команд и служебных сообщений, а таблица будет заполняться значениями.

Обратите внимание, что изменились подписи к флажкам. Поставьте флажок Quit at 450. Как только значение счетчика скетча достигнет 450 (или уже превысило 450 на момент установки флажка) Excel сохранит файл под новым именем и прекратит работу.

Откройте сохраненный файл и посмотрите содержимое листов. Во втором листе с именем Further list должна быть заполнена ячейка G11.

Листинг 5.5. Пример работы с расширением PLX–DAQ

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
int i = 0;
 
void setup() {
 
// последовательный порт на скорости 9600
Serial.begin(9600);
//Serial.println("CLEARDATA"); // очистка листа со строки 2
Serial.println("CLEARSHEET"); // очистка листа со строки 1
// определяем пять столбцов с именами "Date", "Time", "Timer", "Counter" и "millis"
Serial.println("LABEL,Date,Time,Timer,Counter,millis");
// задаем подписи к трем флажкам (только латинские символы)
Serial.println("CUSTOMBOX1,LABEL,Stop logging at 250?");
Serial.println("CUSTOMBOX2,LABEL,Resume log at 350?");
Serial.println("CUSTOMBOX3,LABEL,Quit at 450?");
// ставим флажки в первое и второе поля
Serial.println("CUSTOMBOX1,SET,1");
Serial.println("CUSTOMBOX2,SET,1");
Serial.println("CUSTOMBOX3,SET,0");
}
 
void loop() {
// выводим в таблицу данные и команду прокрутки
Serial.println( (String) "DATA,DATE,TIME,TIMER," + i++ + "," + millis() + ",AUTOSCROLL_20" );
// альтернативный способ вывода строки по частям
/* Serial.print("DATA,DATE,TIME,TIMER,");
Serial.print(i++);
Serial.print(",");
Serial.println(millis());
Serial.print(",");
Serial.println("SCROLLDATA_20"); */
// стираем некоторые ячейки (прямоугольник от B10 до D20)
if (i == 100)
Serial.println("ClearRange,B,10,D,20");
// звуковой сигнал, если i==150
if (i == 150)
Serial.println("BEEP");
// читаем целое число из ячейки E4
// в листе с заданным именем если i==200
if (i == 200)
{
// запрашиваем данные из листа
Serial.println("CELL,GET,FROMSHEET,Further sheet,E,4");
// короткий вариант для чтения из текущего листа
// Serial.println("CELL,GET,E4");
// получаем ответ Excel
 
int readvalue = Serial.readStringUntil(10).toInt();
// Выводим значение в окно отладки
Serial.println( (String) "Value of cell E4 is: " + readvalue);
}
 
// проверяем значение CUSTOMBOX1
// если флажок установлен, приостанавливаем запись
if (i == 250)
{
Serial.println("CUSTOMBOX1,GET");
int stoplogging = Serial.readStringUntil(10).toInt();
// выводим сообщение в окно отладки
Serial.println( (String) "Value of stoplogging/checkbox is: " + stoplogging);
if (stoplogging)
Serial.println("PAUSELOGGING");
}
// запрашиваем случайное число из компьютера если i==300
if (i == 300)
{
 
Serial.println("GETRANDOM,-4321,12345");
 
// случайное число от -4321 до 12345
 
int rndseed = Serial.readStringUntil(10).toInt();
 
// выводим сообщение в окно отладки
Serial.println( (String) "Got random value '" + rndseed + "' from Excel" );
}
// теперь возвобновляем запись если i==350 и стоит флажок CUSTOMBOX2
if (i == 350)
{
Serial.println("CUSTOMBOX2,GET");
int resumelogging = Serial.readStringUntil(10).toInt();
if (resumelogging)
Serial.println("RESUMELOGGING");
}
// запись в заданную ячейку G10 текущего листа
// и ячейку G11 произвольного листа
if (i == 400)
{
 
// активный лист по умолчанию
Serial.println("CELL,SET,G10,400 test 1 string");
// лист с именем "Further sheet"
Serial.println("CELL,SET,ONSHEET,Further sheet,G,11,400 test 2");
}
 
// если i&gt;=450 и установлен флажок CUSTOMBOX3
// сохраняем файл под другим именем и закрываем Excel
if (i &gt;= 450)
 
{
Serial.println("CUSTOMBOX3,GET");
if (Serial.readStringUntil(10).toInt()) {
Serial.println("SAVEWORKBOOKAS,450-Lines-File");
Serial.println("FORCEEXCELQUIT");
}
else
Serial.println("No forced Excel quit requested!");
}
}
Добавить комментарий