January 9, 2015

Зчитування даних за допомогою Arduino та Processing. Обробка їх у R

Сьогодні хочу зробити невеличкий огляд того, як можна використовувати Arduino та Processing для збирання статистичних даних, а після цього обробляти ці дані за допомогою R.
Для демонстрації збирання статистики я за допомогою ультразвукового датчика HC-SR04 фіксую, коли колеги проходят перед моїм робочим столом. Додаткову корисну інформацію про те, як схрестити Arduino, Processing та R я взяв звідси.

Arduino


Ось схема для Arduino Uno
image

Якщо хтось проходить перед столом спрацьовує спікер (і лампочка).

Скетч для Arduino знаходиться тут.

Тут необхідно врахувати кілька моментів

  1. Використовується бібліотека NewPing, її потрібно проінсталювати до вашого Arduino середовища і перезапустити IDE
  2. Щоб мінімізувати хибні спрацювання, я перевіряю наявність сигналу кілька разів поспіль. Див. функцію pingConfirms. Треба сказати, що надійність спрацювання ще далека від ідеалу: то сигнал спрацьовує по декілька разів за один прохід, то пропускає проходи. Проте для наших наочних цілей це не дуже суттєво
  3. Зверніть увагу на константу MAX_DISTANCE, вона задає максимальу відстань до якої датчик буде спрацьовувати.
  4. Найважливіший момент: дані до комп’ютера передаються через серійний порт. Щоб відрізнити дебажний вивід перед даними я вивожу "$data:", цей текст я сприймаю як маркер даних, які будуть додаватись до CSV файлу, тому якщо даних більше одного, можна їх розділяти комою
  5. В нашому випадку в якості даних передається відстань в сантиметрах, але рельно нас це значення не буде цікавити, ми будемо просто групуваи дані за кількістю

Processing


В цьому проекті Processing 2 я буду використовувати вийнятково для зчитування даних з серійного порта (USB) і дописування їх до CSV файлу. Ви можете також вискористовувати Processing для візуализації своїх даних, проте тут графики я малюватиму за допомогою R.
Середовище Processing дуже схоже на середовище Arduino, але мова Java-подібна. Універсальний скетч для зчитування данных з Arduino тут.
Спочатку вам потрібно запустити скетч, він виведе в консоль список всіх доступних серіальних портів, знайдіть порт, на якому працює Arduino, візьміть його порядковий номер (нумерація починається з нуля) і пропишіть його в константу mySerialPort, після цього скетч потрібно перезапустити і він почне збирати дані. Зверніть також увагу на шлях до файлу у скетчі, куди записуються дані

String filePath = sketchPath("../../data/data.csv");


Функція sketchPath створить шлях відносно папки в якій знаходиться скетч. Якщо файлу нема - він створиться, якщо вже є - до нього будуть додаватись рядки. Автоматично першим елементом в кожному рядку CSV файлу буде timestamp (кількість мілісекунд після 1970-01-01).

R


Для обробки даних і відображення графіків я використовую статистичний пакет R.
Після інсталяції R системм можна увійти в інтерактивний режим за допомогою однобуквенної команди R. (Щоб вийти з інтеактивного режиму введіть q().
Я написав невеличкий скрипт, який

  1. Зчитує дані з CSV файлу в пам’ять.
  2. Вирізає дані потрібного часового інтервалу: для цього підправте змінні startDate і endDate
  3. Підрховує число проходжень у кожнмоу з 10-хвилининх інтервалів. Можна інтервал зменити, він заданий у змінній period, це значення в секундах
  4. Малює стовпчиковий графік.

image
Для запуска всього цього зробіть таке:
  1. З консолі запустить команду R
  2. Задайте шлях до каталога, в якому знаходиться ваш data.csv файл:
    setwd("/home/solvek/projects/electronics/counter/data")
    

  3. Запустіть R скрипт:
    source("../plotchart.R")
    

    Тут шлях до скрипта вказаний відносно вищезаданого каталогоа даних

Святковий бонус


Можливо ви вже звернули увагу на те, що спікер видає сигнал з тональністю, котра залежить від відстані, на якій проходять повз датчик. Таким чином з Arduino можна зробити примітивний музичний інструмент:

Ось перероблений для цього скетч. Схемку змінювати не потрібно.

7 comments:

Андрей Жидков said...

Добрый день. Пытаюсь использовать Ваш скетч. Программист я нулевой, поэтому разбираюсь "методом тыка". Ардуино подключен к СОМ5. Выводит инфу с магнитометра. Сейчас гонит в порт "$data:" и напряженность магнитного поля по одной оси. Монитор Ардуино их видит. Заставить Процессинг писать в файл не могу.
Помогите, пожалуйста.

Sergi Adamchuk said...

Андрію,
ви пробували переконатись, що процесінг отримує дані з сом порта?
Якщо впевнені, що дані читаються з порта - перевірте шлях до файлу, куди вони записуються.

Андрей Жидков said...

Доброго дня Сергію!
Ні, я зовсім не впевнений, що процесінг бачить порт. В цьому і проблема.
Коли я пишу у строку:
int mySerialPort = 0; // Change this to the port number of the Arduino
Замість "0" "5" - номер порта Адруіно.
я отримую помилку: ArrayIndexOutOfBoundsException: 5
курсор при цьому стає на строку:
myPort = new Serial(this, Serial.list()[mySerialPort], baudRate);
Файл нормально створюється, але в нього нічого не пишеться.
Якщо, я залищаю int mySerialPort = 0; помилки немає, але в нижньо вікні є повідомлення
COM3 COM5
File path: D:\sketch_150803a\data.csv
І у окремому вікні ReadLine стоїть 0

Андрей Жидков said...

Не зрозумів, чи лишив я комент. Я ставлю номер порта 5, яле вилазить якась похибка. Як переконатися, що я отримую дані з порта?

Андрей Жидков said...

А як мені в цьому переконатися?

Sergi Adamchuk said...

Ви можете виводити значення за допомогою println в консоль. Тоді ви зможете бачити, що відбувається всередині програми процесінг.
Але зараз я хочу трохи спростити проект - викинути processing i R, а читати дані за допомогою макроса Excel (ще не впевнений що це можливо)

Андрей Жидков said...

Нажаль я зовсім не програмую в процесинг, тому, все це для мене мало що дає. Макрос під ексель було б дуже цікаво. Для обробки даних дуже зручно. Але і це я не зможу написати. Дякую, буду шукати того, хто зможе вирішити мою проблему далі.