【ArduinoNiclaVision】开箱贴
关于摔倒的检测:

六、技术难点与心得:
Aruino Nicla Vision本身是一款非常紧凑的开发板,但功能非常强大。本次体验只探索了其中的一小部分功能。在测试WiFi模块功能的时候,总是烧录失败,后来发现需要预先烧录一个固件才可以。耗费了点时间。其次MAX30102的输出有时候波动比较大,后续可以考虑使用相关的滤波算法来获取更加准确的输出。
在开发的过程中也遇到了一些问题,都记录在了过程贴中。整个系统的集成是比较顺利的,得益于Arduino 完善的开发生态。
再次感谢EEPW与得捷提供的本次体验机会,希望这个活动越办越好!
源码:
#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <Arduino_LSM6DSOX.h>
#include "MAX30105.h"
#include "heartRate.h"
#include <WiFi.h>
#include "secrets.h"
#include "ThingSpeak.h" // always include thingspeak header file after other header files and custom macros
#include <PubSubClient.h>
//----------------------------OLED Related Start -------------------------------------------------------------------
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels
#define OLED_RESET -1 // Reset pin # (or -1 if sharing Arduino reset pin)
#define SCREEN_ADDRESS 0x3C ///< See datasheet for Address; 0x3D for 128x64, 0x3C for 128x32
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
MAX30105 particleSensor;
const byte RATE_SIZE = 4; //Increase this for more averaging. 4 is good.
byte rates[RATE_SIZE]; //Array of heart rates
byte rateSpot = 0;
long lastBeat = 0; //Time at which the last beat occurred
float beatsPerMinute;
int beatAvg;
//----------------------------MQTT Related Start -------------------------------------------------------------------
char ssid[] = SECRET_SSID; // your network SSID (name)
char pass[] = SECRET_PASS; // your network password
int keyIndex = 0; // your network key Index number (needed only for WEP)
WiFiClient client;
unsigned long myChannelNumber = SECRET_CH_ID;
const char* myWriteAPIKey = SECRET_WRITE_APIKEY;
//MQTT
PubSubClient MqttClient(client); // 定义PubSubClient的实例
const char* mqtt_server = "test.mosquitto.org"; // hivemq 的信息中转服务
const unsigned short mqtt_server_port = 1883;
const char* pubTOPIC = "digikey/heartbeat"; // 发布信息主题
const char* pubTOPICSpO2 = "digikey/spo2"; // 发布信息主题
const char* client_id = "smartband"; // 标识当前设备的客户端编号
uint8_t data[2];
unsigned char temp[10];
const long interval = 20000;
unsigned long previousMillis = 0;
void printWifiStatus() {
/* -------------------------------------------------------------------------- */
// print the SSID of the network you're attached to:
Serial.print("SSID: ");
Serial.println(WiFi.SSID());
// print your board's IP address:
IPAddress ip = WiFi.localIP();
Serial.print("IP Address: ");
Serial.println(ip);
// print the received signal strength:
long rssi = WiFi.RSSI();
Serial.print("signal strength (RSSI):");
Serial.print(rssi);
Serial.println(" dBm");
}
void setup() {
Serial.begin(115200);
// Wait for display
delay(500);
// SSD1306_SWITCHCAPVCC = generate display voltage from 3.3V internally
if (!display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS)) {
Serial.println(F("SSD1306 allocation failed"));
for (;;)
; // Don't proceed, loop forever
}
// Show initial display buffer contents on the screen --
// the library initializes this with an Adafruit splash screen.
display.display();
delay(2000); // Pause for 2 seconds
display.clearDisplay();
display.setTextSize(1); // Normal 1:1 pixel scale
display.setTextColor(SSD1306_WHITE); // Draw white text
display.setCursor(0, 0); // Start at top-left corner
display.println(F("Hello, world!"));
display.setTextColor(SSD1306_BLACK, SSD1306_WHITE); // Draw 'inverse' text
display.println(3.141592);
display.setTextSize(2); // Draw 2X-scale text
display.setTextColor(SSD1306_WHITE);
display.print(F("0x"));
display.println(0xDEADBEEF, HEX);
display.display();
delay(2000);
//begin
// Initialize sensor
if (!particleSensor.begin(Wire, I2C_SPEED_FAST)) //Use default I2C port, 400kHz speed
{
Serial.println("MAX30105 was not found. Please check wiring/power. ");
while (1)
;
}
Serial.println("Place your index finger on the sensor with steady pressure.");
particleSensor.setup(); //Configure sensor with default settings
particleSensor.setPulseAmplitudeRed(0x0A); //Turn Red LED to low to indicate sensor is running
particleSensor.setPulseAmplitudeGreen(0); //Turn off Green LED
//end
//Init IMU:
if (!IMU.begin()) {
Serial.println("Failed to initialize IMU!");
while (1)
;
}
Serial.print("Accelerometer sample rate = ");
Serial.print(IMU.accelerationSampleRate());
Serial.println(" Hz");
Serial.println();
Serial.println("Acceleration in g's");
Serial.println("X\tY\tZ");
pinMode(LED_BUILTIN, OUTPUT);
//WiFi.mode(WIFI_STA);
// Connect or reconnect to WiFi
if (WiFi.status() != WL_CONNECTED) {
Serial.print("Attempting to connect to SSID: ");
Serial.println(SECRET_SSID);
while (WiFi.status() != WL_CONNECTED) {
WiFi.begin(ssid, pass); // Connect to WPA/WPA2 network. Change this line if using open or WEP network
Serial.print(".");
delay(5000);
}
Serial.println("\nConnected.");
}
Serial.println("You're connected to the network");
Serial.println(ssid);
printWifiStatus();
Serial.println();
ThingSpeak.begin(client); // Initialize ThingSpeak
MqttClient.setServer(mqtt_server, mqtt_server_port); //设定MQTT服务器与使用的端口,1883是默认的MQTT端口
Serial.println("UART, ThingSpeak, MQTT init done");
}
void reconnect() {
while (!MqttClient.connected()) {
Serial.print("Attempting MQTT connection...");
// Attempt to connect
if (MqttClient.connect(client_id)) {
Serial.println("connected");
// 连接成功时订阅主题
//MqttClient.subscribe(TOPIC);
} else {
Serial.print("failed, rc=");
Serial.print(MqttClient.state());
Serial.println(" try again in 5 seconds");
// Wait 5 seconds before retrying
delay(5000);
}
}
}
long lastMsg = 0;
char msg[50];
int value = 0;
float x, y, z;
void loop() {
static uint16_t tempData = 0;
unsigned long currentMillis = millis();
long irValue = particleSensor.getIR();
if (checkForBeat(irValue) == true) {
//We sensed a beat!
long delta = millis() - lastBeat;
lastBeat = millis();
beatsPerMinute = 60 / (delta / 1000.0);
if (beatsPerMinute < 255 && beatsPerMinute > 20) {
rates[rateSpot++] = (byte)beatsPerMinute; //Store this reading in the array
rateSpot %= RATE_SIZE; //Wrap variable
//Take average of readings
beatAvg = 0;
for (byte x = 0; x < RATE_SIZE; x++)
beatAvg += rates[x];
beatAvg /= RATE_SIZE;
}
}
Serial.print("IR=");
Serial.print(irValue);
Serial.print(", BPM=");
Serial.print(beatsPerMinute);
Serial.print(", Avg BPM=");
Serial.print(beatAvg);
if (irValue < 50000)
Serial.print(" No finger?");
Serial.println();
if (IMU.accelerationAvailable()) {
IMU.readAcceleration(x, y, z);
if (fabs(x) >= 0.2) {
Serial.println("***********Falling Down. Warning!****************");
Serial.print(x);
Serial.print('\t');
Serial.print(y);
Serial.print('\t');
Serial.println(z);
//Write to OLED:
display.clearDisplay();
display.setTextSize(2); // Normal 1:1 pixel scale
display.setTextColor(SSD1306_WHITE); // Draw white text
display.setCursor(0, 20); // Start at top-left corner
display.print(F("Fall Down"));
display.display();
}
}
/**************************MQTT******************************/
if ((currentMillis - previousMillis >= interval) && ((beatAvg >= 50) && (beatAvg <= 150))) {
previousMillis = currentMillis;
//Write to OLED:
display.clearDisplay();
display.setTextSize(1); // Normal 1:1 pixel scale
display.setTextColor(SSD1306_WHITE); // Draw white text
display.setCursor(0, 0); // Start at top-left corner
display.print(F("Heart/Min: "));
//display.setTextColor(SSD1306_BLACK, SSD1306_WHITE); // Draw 'inverse' text
display.println(beatAvg);
// display.setTextSize(2); // Draw 2X-scale text
// display.setTextColor(SSD1306_WHITE);
// display.print(F("0x"));
// display.println(0xDEADBEEF, HEX);
display.display();
digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN));
Serial.println("Sending message to topic: ");
// set the fields with the values
ThingSpeak.setField(1, beatAvg);
ThingSpeak.setField(2, irValue);
ThingSpeak.setStatus("HeartBeat_SpO2");
int x = ThingSpeak.writeFields(myChannelNumber, myWriteAPIKey);
if (x == 200) {
Serial.print("------------Channel update successful----Value: ");
//Serial.print(tempValtoIOT);
Serial.println(" -------------------.");
} else {
Serial.println("Problem updating channel. HTTP error code " + String(x));
}
if (!MqttClient.connected()) {
reconnect();
}
MqttClient.loop();
//byte outmsg_heart = data[0];
snprintf(msg, 50, "%ld bps", beatAvg);
if (MqttClient.publish(pubTOPIC, msg)) {
Serial.println("Publish Topic:");
Serial.println(pubTOPIC);
Serial.println("Publish message:");
Serial.println(msg);
} else {
Serial.println("Message Publish Failed.");
}
snprintf(msg, 50, "%ld %%", irValue);
if (MqttClient.publish(pubTOPICSpO2, msg)) {
Serial.println("Publish Topic:");
Serial.println(pubTOPICSpO2);
Serial.println("Publish message:");
Serial.println(msg);
} else {
Serial.println("Message Publish Failed.");
}
}
}
我要赚赏金
