Создадим автоматический счетчик отжиманий на основе Ардуино с использованием датчика приближения Kemet SS-430.
Комплектующие
Мы будем использовать ряд комплектующих для нашего счетчика отжиманий на Ардуино.
Компоненты оборудования
- Датчик приближения KEMET Electronics (пироэлектрический бесконтактный инфракрасный датчик) × 1
- Arduino Uno × 1
- Шилд Arduino WiFi × 1
- Шилд Seeed Grove для Arduino Nano × 1
- Светодиод Seeed Grove RGB Led V2.0 × 1
- Спикер Seeed Grove × 1
Программное обеспечение
Дополнительно
- 3D-принтер (не обязательно)
Идея проекта
Интеллектуальные инструменты IoT (интернета-вещей) для фитнеса набирают все большую популярность. Особенно это стало очевидным после того, как компания Pelaton вышла на IPO. Рынок спортивных гаджетов растет каждый день.
Сейчас мы можем отслеживать поездки на велосипеде с помощью Pelaton, а бег или ходьбу с помощью fitbit. Но, к сожалению, некоторые базовые упражнения, такие как отжимания, создатели устройств и приложений обходят стороной.
В этом уроке мы создаем прототип счетчика отжиманий, используя пирометрический датчик Kemet и Arduino.
Шаг 1. Собираем схему
Для этого проекта мы будем использовать Arduino Uno, Wifi шилд и шилд Grove для того, чтобы мы могли добавить дополнительные датчики.
Еще мы должны собрать корпус, либо его распечатать на принтере, например, от thingsverse. Благодаря 3D-печати мы сможем создать базовый корпус.
После того, как все сделано, у нас должно быть что-то вроде этого.
Соединяем все комплектующие, и получаем в итоге:
Назначение контактов справа налево : контакт 1 - питание, контакт 5 - заземление, контакт 4 - Vout.
После того как все сделано, мы сможем перейти к следующему шагу.
Шаг 2. Тестирование датчика
Мы можем сначала попробовать программу с официального сайта:
int Pyro = A1; unsigned long PyroRead = 0; unsigned long IR_threshold = 198000; // Note: SS-430 has two pulses of 200msec per detection. // IR_threshold is in microsec (usec), therefore 198msec threshold int LED = 7; int Detected = LOW; int IR_sensed = 0; void setup() { pinMode (7, OUTPUT); //LED Connected to Pin 7 pinMode (A1,INPUT); // IR Sensor connected to A1 } void loop() { while ((IR_sensed < 2)){ //Break after 2 good triggers PyroRead = pulseIn(A1, HIGH); //Measure trigger point if(PyroRead > IR_threshold){ //Make sure trigger is over 198msec) IR_sensed++; //Mark as a good trigger } } if (Detected == HIGH){ // Turn LED OFF if it was previous ON Detected = LOW; digitalWrite(7, LOW); } else { Detected = HIGH; // Turn LED ON if it was previous OFF digitalWrite(7, HIGH); } PyroRead = 0; // Reset readings IR_sensed = 0; delay(1000); // Accept triggers after a second
Но, как мы можем увидеть как-то всё не очень работает. Это связано с чувствительностью датчика. Но на этом этапе мы должны хотя бы просто понимать, что датчик подключен и работает правильно.
Схема на этом этапе будет такая:
Шаг 3. Kemet SS-430 линзы
Как мы видели из предыдущего шага, сенсор реагирует на всё из-за своей чувствительности. Нам нужны дополнительные линзы, чтобы сенсор действовал правильно.
Для теста мы поместили кусок акрила, покрывающий сам датчик и использовали тот же кодом. Мы получали гораздо более точные показания.
Можно добавить еще ограничитель в виде коробки с отверстием, чтобы блокировать все остальные углы при отслеживании отжимания.
Шаг 4. Хранение данных
Теперь, когда датчик работает, и мы можем отследить отжимания, нам нужно сохранить прогресс тренировки. Один из самых простых способов - использовать firebase от Google.
Мы рассмотрим использование firebase в очень простом варианте. Создаем проект и далее создаем базу данных с тестовой средой.
Далее начните сбор отжиманий - Start a collection.
Затем мы можем добавить нашу схему, которая будет включать в себя счетчик отжиманий и временные отметки (timestamp).
Когда все будет сделано, у нас будет нормальная настроенная базы данных.
Вам также понадобится ключ служебной учетной записи (service account key), генерируемый через firebase. Пожалуйста, не загружайте этот ключ в репозиторий, так как это ключ безопасности.
Как только он подключится, мы можем создать локальный "ретранслятор" на нашем сервере, чтобы выполнить передачу через базу.
const http = require('http'); const url = require('url'); const querystring = require('querystring'); // Import Admin SDK var admin = require("firebase-admin"); var serviceAccount = require("path/to/serviceAccountKey.json"); admin.initializeApp({ credential: admin.credential.cert(serviceAccount), databaseURL: "https://databaseName.firebaseio.com" }); // Get a database reference to our blog var db = admin.database(); var ref = db.ref("pushup"); ref.once("value", function(snapshot) { console.log(snapshot.val()); }); const hostname = '192.168.1.12'; const port = 3000; const server = http.createServer((req, res) => { const queryObject = url.parse(req.url,true).query; var dt = new Date(); var utcDate = dt.toUTCString(); if(queryObject != null && queryObject.pushup != null) { console.log(queryObject.pushup); var newPostRef = ref.push().set({ count: queryObject.pushup, time: utcDate }); var postId = newPostRef.key; console.log(postId); console.log(utcDate); } //console.log(querystring.parse(queryObject)); res.statusCode = 200; res.setHeader('Content-Type', 'text/plain'); res.end('Hello World'); }); server.listen(port, hostname, () => { console.log(`Server running at http://${hostname}:${port}/`); });
Просто запустите:
node app.js
Шаг 5. Интеграция Arduino
Теперь, когда мы можем считать свои отжимания и хранить данные о них, пришло время собрать всё вместе.
Во-первых, нам нужно использовать Wi-Fi Arduino для подключения к Интернету.
#include <WiFi.h> char ssid[] = "yourNetwork"; // your network SSID (name) char pass[] = "12345678"; // your network password int status = WL_IDLE_STATUS; // the Wifi radio's status void setup() { // initialize serial: Serial.begin(9600); // attempt to connect using WPA2 encryption: Serial.println("Attempting to connect to WPA network..."); status = WiFi.begin(ssid, pass); // if you're not connected, stop here: if ( status != WL_CONNECTED) { Serial.println("Couldn't get a wifi connection"); while(true); } // if you are connected, print out info about the connection: else { Serial.println("Connected to network"); } } void loop() { // do nothing }
Теперь мы также добавляем зеленый светодиод, зуммер и кнопку. В настройках у нас всё это должно быть. Как только Wi-Fi подключен, мы можем моргнуть зеленым светодиодом 3 раза.
void setup() { // declare the ledPin as an OUTPUT: Serial.begin(115200); pinMode(ledPin, OUTPUT); pinMode(greenledPin, OUTPUT); pinMode(buzzerPin, OUTPUT); pinMode (sensorPin, INPUT); // IR Sensor connected to A1 pinMode (buttonPin, INPUT); // Button Pin // attempt to connect using WPA2 encryption: Serial.println("Attempting to connect to WPA network..."); status = WiFi.begin(ssid, pass); // if you're not connected, stop here: if ( status != WL_CONNECTED) { Serial.println("Couldn't get a wifi connection"); while(true); } // if you are connected, print out info about the connection: else { Serial.println("Connected to network"); //connected to network, blink it 3 times digitalWrite(greenledPin, HIGH); delay(500); digitalWrite(greenledPin, LOW); delay(500); digitalWrite(greenledPin, HIGH); delay(500); digitalWrite(greenledPin, LOW); delay(500); digitalWrite(greenledPin, HIGH); delay(500); digitalWrite(greenledPin, LOW); } }
Следующая часть - зуммер. Каждый раз, когда вы выполняете отжимание, зуммер будет подавать звуковой сигнал, чтобы напомнить вам, что вы закончили отжимание. Счетчик отжиманий также будет использоваться для отправки информации.
if (Detected == HIGH) { // Turn LED OFF if it was previous ON Detected = LOW; digitalWrite(ledPin, LOW); digitalWrite(buzzerPin, HIGH); delay(200); digitalWrite(buzzerPin, LOW); pushupCount += 1; } else { Detected = HIGH; // Turn LED ON if it was previous OFF digitalWrite(ledPin, HIGH); }
Кнопка используется для загрузки информации на локальный сервер и отправки ее в firebase. Мы также чистим флаг pushupCount, так как отправляем эту информацию на сервер.
while ((IR_sensed < 2)) { //Break after 2 good triggers PyroRead = pulseIn(sensorPin, HIGH); //Measure trigger point Serial.println(PyroRead); // stop the autonomous robot if (PyroRead > IR_threshold) { //Make sure trigger is over 198msec) IR_sensed++; //Mark as a good trigger } buttonState = digitalRead(buttonPin); if (buttonState == HIGH) { // turn LED on: digitalWrite(greenledPin, HIGH); String tmp; tmp = String(pushupCount); Serial.println("\nStarting connection to server..."); // if you get a connection, report back via serial: if (client.connect(server, 3000)) { Serial.println("connected to server"); // Make a HTTP request: client.println("GET /?pushup=" + tmp + " HTTP/1.1"); client.println("Host: 192.168.1.12"); client.println("Connection: close"); client.println(); } digitalWrite(greenledPin, LOW); pushupCount = 0; } }
Когда все датчики подключены, всё должно выглядеть примерно так:
Итоговый результат
На этом всё. Следите за новыми уроками, делитесь ими в соц. сетях!