这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 活动中心 » 板卡试用 » 【ArduinoNiclaVision】过程贴

共1条 1/1 1 跳转至

【ArduinoNiclaVision】过程贴

工程师
2025-12-28 17:13:40     打赏

本文记录开发Arduino Nicla Vision的详细过程。

项目目标是设计一个简易的健康装置,具体功能:

  1. 可以测量心率,测量结果要通过OLED进行显示并通过Wi-Fi发送到MQTT云平台ThingSpeak。

  2. 可以检测摔倒,并通过屏幕进行提示。

一、OLED驱动

本次使用的屏幕是之前参加MAX78000智能手环时候购买的Seeed的SSD1315屏幕。

产品链接:https://wiki.seeedstudio.com/Grove-OLED-Yellow&Blue-Display-0.96-SSD1315_V1.0/

image.png

驱动使用的是Adafruit的SSD1306:

image.png

包含头文件:

#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

要留意器件的真实地址:

#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);

显示测试:

  // 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();


显示效果:

image.png

二、MAX30102驱动

驱动采用SPAKFUN的max3010x库,由于这个模块也是IIC接口,所以可以与OLED共用一组IIC。

image.png


包含头文件:

#include "MAX30105.h"
#include "heartRate.h"


定义相关参数:

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;

初始化传感器:

  // 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

结果测试:

image.png

三、Wi-Fi驱动与ThingSpeak云平台连接

这块开发板开机自带Micropython的固件,要使用Arduino开发其Wi-Fi组件,需要一些特殊操作。

首先打开例程:

image.png



然后编译,烧录:

image.png

然后烧录后,重启。查看串口输出:

image.png

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库。

image.png


之后在头文件中包含如下头文件:

#include <WiFi.h>
#include "secrets.h"
#include "ThingSpeak.h"  // always include thingspeak header file after other header files and custom macros
#include <PubSubClient.h>

其中secrets.h中有WiFi名称与密码。还有ThingSpeak的channel的api key。

ThingSpeak初始化与PubSubClient库的初始化:

ThingSpeak.begin(client);                             // Initialize ThingSpeak
MqttClient.setServer(mqtt_server, mqtt_server_port);  //设定MQTT服务器与使用的端口,1883是默认的MQTT端口

上传数据到thingSpeak云平台:

    // 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));
    }

测试结果:本周日12月28日下午5点的数据被实时上传到ThingSpeak云平台。

image.png


本次OLED屏幕显示:

image.png

关于摔倒的检测,记录开发板正常放置时候的三轴数据,然后模拟开发板坠落,获取此时的三轴数据,然后在代码中对比进行输出。

开发板自带了三轴加速度计,需要包含如下头文件:

#include <Arduino_LSM6DSOX.h>

初始化IMU:

  //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");

检测代码:

  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();
    }
  }

测试结果:当开发板下落时候,串口检测到异常,通过串口输出。image.png

开发过程中也遇到了一些错误,记录如下:

Snipaste_2025-12-21_14-46-15.png

解决办法:使用itoa代替ltoa。

itoa(value, valueString, 10);



共1条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]