Arduino NANO (6) Heart rate sensor

Arduinoセンサーキットに、Heart rate sensorある。

血中ヘモグロビンの近赤外線吸収の性質を利用して脈拍パルス検出するらしい。

Arduinoとの接続は3線(GND、VCC、アナログ入力)のみ。

「参考1」をみて、まず簡単の試す。ただA0の値を表示。

// Pulse Monitor Test Script
int sensorPin = 0;
void setup() {
   Serial.begin(9600);
}
void loop ()
{
   while(1)
   {
     Serial.print(analogRead(sensorPin));
     Serial.print('\n');
   }
}

指先センサー装着

シリアルプロッターに見える上昇カーブ

安定した状態これはなにもわからない

指はセンサーから離れる時の下降カーブ。

「参考1」を参考して、Smoothingしても、同じ判別不能。困った。

#define samp_siz 4
#define rise_threshold 5
// Pulse Monitor Test Script
int sensorPin = 0;
void setup() {
   Serial.begin(9600);
}
void loop ()
{
   float reads[samp_siz], sum;
   long int now, ptr;
   float last, reader, start;
   float first, second, third, before, print_value;
   bool rising;
   int rise_count;
   int n;
   long int last_beat;
   for (int i = 0; i < samp_siz; i++)
     reads[i] = 0;
   sum = 0;
   ptr = 0;
   while(1)
   {
     // calculate an average of the sensor
     // during a 20 ms period (this will eliminate
     // the 50 Hz noise caused by electric light
     n = 0;
     start = millis();
     reader = 0.;
     do
     {
       reader += analogRead (sensorPin);
       n++;
       now = millis();
     }
     while (now < start + 20);  
     reader /= n;  // we got an average
     // Add the newest measurement to an array
     // and subtract the oldest measurement from the array
     // to maintain a sum of last measurements
     sum -= reads[ptr];
     sum += reader;
     reads[ptr] = reader;
     last = sum / samp_siz;
     // now last holds the average of the values in the array
     // check for a rising curve (= a heart beat)
     if (last > before)
     {
       rise_count++;
       if (!rising && rise_count > rise_threshold)
       {
         // Ok, we have detected a rising curve, which implies a heartbeat.
         // Record the time since last beat, keep track of the two previous
         // times (first, second, third) to get a weighed average.
         // The rising flag prevents us from detecting the same rise 
         // more than once.
         rising = true;
         first = millis() - last_beat;
         last_beat = millis();
         // Calculate the weighed average of heartbeat rate
         // according to the three last beats
         print_value = 60000. / (0.4 * first + 0.3 * second + 0.3 * third);
         Serial.print(print_value);
         Serial.print('\n');
         third = second;
         second = first;
       }
     }
     else
     {
       // Ok, the curve is falling
       rising = false;
       rise_count = 0;
     }
     before = last;
     ptr++;
     ptr %= samp_siz;
   }
}

こんな図形になって、周囲の雑音とか酷いかな?

参考:

  1. https://www.hackster.io/Johan_Ha/from-ky-039-to-heart-rate-0abfca

Arduino NANO (5) MAX30102 Pulse Ox Sensor

試み

MAX30102 というPulse Ox Sensorを利用して、脈拍と酸素濃度を測る試み。

MAX30100の実例が多いが、MAX30102の実例が少ない。

プログラム

「参考1」のSparkFunのライブラリを利用する。そのライブラリはMAX30105(R,G,IR LED)用だが、MAX30102(欠Green LED)でも利用できる。

OLED表示するため、「参考2」の表示部分を合体した。なんとなく、バグがある様な気がする。

// Sample implementation of the MAX30100 PulseOximeter
// Using the following module
// http://www.ebay.com/itm/-/391709438817?ssPageName=STRK:MESE:IT
// can not gaurantee if the app will work with other implementations of the module. 

//#include "MAX30100_PulseOximeter.h"
#include <U8g2lib.h>
#include <Wire.h>
#include "MAX30105.h"
#include "heartRate.h"

#define REPORTING_PERIOD_MS     500

 U8G2_SSD1306_128X32_UNIVISION_F_HW_I2C u8g2(U8G2_R0);

// PulseOximeter is the higher level interface to the sensor
// it offers:
//  * beat detection reporting
//  * heart rate calculation
//  * SpO2 (oxidation level) calculation
//PulseOximeter pox;
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;

//byte pulseLED = 13; //Must be on PWM pin
//byte readLED = 11; //Blinks with each data read
//
bool calculation_complete=false;
bool calculating=false;
bool initialized=false;
byte beat=0;

void show_beat() 
{
  u8g2.setFont(u8g2_font_cursor_tf);
  u8g2.setCursor(8,10);
  if (beat==0) {
    u8g2.print("_");
    beat=1;
  } 
  else
  {
    u8g2.print("^");
    beat=0;
  }
  u8g2.sendBuffer();
}

void initial_display() 
{
  if (not initialized) 
  {
    u8g2.clearBuffer();
    show_beat();
    u8g2.setCursor(24,12);
    u8g2.setFont(u8g2_font_profont15_mr);
    u8g2.print("Place finger");  
    u8g2.setCursor(0,30);
    u8g2.print("on the sensor");
    u8g2.sendBuffer(); 
    initialized=true;
  }
}

void display_calculating(int j)
{
  if (not calculating) {
    u8g2.clearBuffer();
    calculating=true;
    initialized=false;
  }
  show_beat();
  u8g2.setCursor(24,12);
  u8g2.setFont(u8g2_font_profont15_mr);
  u8g2.print("Measuring..."); 
  u8g2.setCursor(0,30);
  u8g2.print(beatsPerMinute);
  u8g2.print(" Bpm");
  u8g2.sendBuffer();
}

void display_values()
{
  u8g2.clearBuffer();
  u8g2.setFont(u8g2_font_profont15_mr);
 
  u8g2.setCursor(0,30);
  u8g2.print(beatsPerMinute);
  u8g2.print(" Bpm _ ");
  u8g2.setCursor(65,30);  
  u8g2.print(beatAvg);
  u8g2.sendBuffer();
}

void setup()
{
    Serial.begin(115200);
    
//    pinMode(pulseLED, OUTPUT);
//    pinMode(readLED, OUTPUT);

    u8g2.begin();

    // Initialize sensor
    if (!particleSensor.begin(Wire, I2C_SPEED_FAST)) //Use default I2C port, 400kHz speed
    {
      Serial.println(F("MAX30105 was not found. Please check wiring/power."));
      while (1);
    }    

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


void loop()
{

  long irValue = particleSensor.getIR();
  float temperature = particleSensor.readTemperature();
//  digitalWrite(readLED, !digitalRead(readLED)); //Blink onboard LED with every data read

  if (checkForBeat(irValue) == true)
  {
    calculation_complete=true;
    calculating=false;
    initialized=false;

//    digitalWrite(pulseLED, !digitalRead(pulseLED)); //Blink onboard LED with every Beat
    //We sensed a beat!
    long delta = millis() - lastBeat;
    lastBeat = millis();

    if (delta < 10000) {
      beatsPerMinute = 60 / (delta / 1000.0);
    } else {
      calculation_complete=false;
      beatsPerMinute=0;
      initial_display();
    }
    
    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;
      display_values();
    }
  } else {
    if (irValue < 50000) {
      calculating=false;
      initial_display();
    } else {
      display_calculating(5);
    }
  }

  Serial.print("IR=");
  Serial.print(irValue);
  Serial.print(", BPM=");
  Serial.print(beatsPerMinute);
  Serial.print(", Avg BPM=");
  Serial.print(beatAvg);
  Serial.print(", initialized=");
  Serial.print(initialized);
  Serial.print(", calculating=");
  Serial.print(calculating);
  Serial.print(", calculation_complete=");
  Serial.print(calculation_complete);
  Serial.println();



}

 

実験

かなり不安定の感じがする。

 

一応、形はできたが、

しかし、脈拍捉えるのは稀て、今回も失敗して。。。

参考

  1. https://learn.sparkfun.com/tutorials/max30105-particle-and-pulse-ox-sensor-hookup-guide
  2. https://www.hackster.io/umar-sear/arduino-heart-rate-monitor-a8e9e1
  3. https://www.hackster.io/AAKS/max30100-and-blynk-0f58f4

Arduino NANO (4) Piezoelectric sensor

なぜ

Piezoelectric sensorを利用して、住宅内の音声、振動から年配者の介護の補助を考えている。

Piezoelectric sensorが取った情報をAD変換して、簡単にWemosで処理すると思ったが、いろいろ意外なところで躓いた。

何か類似する、簡単に検証できる例がないか探した。

取り込み

「参考1」から、普通のPiezoelectric sensorで、簡単に脈拍を取れると、魅力と思った。

必要な部品が揃うまで時間がかかったが、一応出来た。

いろいろと試したところ

拡大写真

取れた波形。「参考1」の波形には似ているは、DC成分あるから、取り除くが課題。

参考

  1. http://www.ohnitsch.net/2015/03/18/measuring-heart-rate-with-a-piezoelectric-vibration-sensor/

WeMos (b10) ADS1115 Oscilloscope

前回WeMos (b9) ADS1115 for A/Dで数値の表示ができたが、Oscilloscopeのような表示すべく、改造を試み。
しかし、2月から、WeMos miniの開発中も頻繁にリブートしています。デバイストライバのバージョンを変えたり、OSを変えたりしても改善しない。

そのため、このプログラムは未完成のまま放置。

/*
This is set up to use a 128x64 I2C screen, as available
here: http://www.banggood.com/buy/0-96-oled.html
For wiring details see http://youtu.be/XHDNXXhg3Hg
*/
#include <SPI.h>
#include <Wire.h>
#include <limits.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <Adafruit_ADS1015.h>
#include <math.h>
#define WINDOW_SIZE 128
Adafruit_ADS1115 ads;  /* Use this for the 16-bit version */
//Adafruit_ADS1015 ads;     /* Use thi for the 12-bit version */
#define OLED_RESET 0    // 4
Adafruit_SSD1306 display(OLED_RESET);
#if (SSD1306_LCDHEIGHT != 64)
//  error("Height incorrect, please fix Adafruit_SSD1306.h!");
#endif
/********************************************/
#define CHARWIDTH           5
#define CHARHEIGHT          8
#define AXISWIDTH           (2 + 1)                   // axis will show two-pixel wide graph ticks, then an empty column
#define VISIBLEVALUEPIXELS  (128 - AXISWIDTH)         // the number of samples visible on screen
#define NUMVALUES           (2 * VISIBLEVALUEPIXELS)  // the total number of samples (take twice as many as visible, to help find trigger point
#define TRIGGER_ENABLE_PIN       D6  // 2 set this pin high to enable trigger
#define SCREEN_UPDATE_ENABLE_PIN D8  // 3 set this pin high to freeze screen
byte values[NUMVALUES];           // stores read analog values mapped to 0-63
int pos = 0;                      // the next position in the value array to read
int count = 0;                    // the total number of times through the loop
unsigned long readStartTime = 0;  // time when the current sampling started
int sampleRate = 1;              // A value of 1 will sample every time through the loop, 5 will sample every fifth time etc.
// Draws the graph ticks for the vertical axis
void drawAxis()
{
  // graph ticks
  for (int x = 0; x < 2; x++) {
    display.drawPixel(x,  0, WHITE);
    display.drawPixel(x, 13, WHITE);
    display.drawPixel(x, 26, WHITE);
    display.drawPixel(x, 38, WHITE);
    display.drawPixel(x, 50, WHITE);
    display.drawPixel(x, 63, WHITE);
  }
}
// Draws the sampled values
void drawValues()
{
  int start = 0;
  if ( digitalRead(TRIGGER_ENABLE_PIN) ) {
    // Find the first occurence of zero
    for (int i = 0; i < NUMVALUES; i++) {
      if ( values[i] == 0 ) {
        // Now find the next value that is not zero
        for (; i < NUMVALUES; i++) {
          if ( values[i] != 0 ) {
            start = i;
            break;
          }
        }
        break;
      }
    }
    // If the trigger point is not within half of our values, we will
    // not have enough sample points to show the wave correctly
    if ( start >= VISIBLEVALUEPIXELS )
      return;
  }
  for (int i = 0; i < VISIBLEVALUEPIXELS; i++) {
    display.drawPixel(i + AXISWIDTH, 63 - (values[i + start]), WHITE);
  }
}
// Shows the time taken to sample the values shown on screen
void drawFrameTime(unsigned long us)
{
  display.setCursor(9 * CHARWIDTH, 7 * CHARHEIGHT - 2); // almost at bottom, approximately centered
  display.print(us);
  display.println(" us");
}
/********************************************/
void setup() {
  // The ADC input range (or gain) can be changed via the following
  // functions, but be careful never to exceed VDD +0.3V max, or to
  // exceed the upper and lower limits if you adjust the input range!
  // Setting these values incorrectly may destroy your ADC!
  //                                                                ADS1015  ADS1115
  //                                                                -------  -------
     ads.setGain(GAIN_TWOTHIRDS);  // 2/3x gain +/- 6.144V  1 bit = 3mV      0.1875mV (default)
  // ads.setGain(GAIN_ONE);        // 1x gain   +/- 4.096V  1 bit = 2mV      0.125mV
  // ads.setGain(GAIN_TWO);        // 2x gain   +/- 2.048V  1 bit = 1mV      0.0625mV
  // ads.setGain(GAIN_FOUR);       // 4x gain   +/- 1.024V  1 bit = 0.5mV    0.03125mV
  // ads.setGain(GAIN_EIGHT);      // 8x gain   +/- 0.512V  1 bit = 0.25mV   0.015625mV
  // ads.setGain(GAIN_SIXTEEN);    // 16x gain  +/- 0.256V  1 bit = 0.125mV  0.0078125mV
  ads.begin();
  // Set up the display
  display.begin(SSD1306_SWITCHCAPVCC, 0x3C); // Initialize with the I2C addr 0x3D (for the 128x64)
  display.setTextColor(WHITE);
  pinMode(TRIGGER_ENABLE_PIN, INPUT);
  pinMode(SCREEN_UPDATE_ENABLE_PIN, INPUT);
}
/********************************************/
void loop() {
  // If a sampling run is about to start, record the start time
  if ( pos == 0 )
    readStartTime = micros();
  // If this iteration is one we want a sample for, take the sample
  if ( (++count) % sampleRate == 0 )
    values[pos++] = (ads.readADC_SingleEnded(0)>> 7) / 3; // shifting right by 4 efficiently maps 0-1023 range to 0-63
//    values[pos++] = analogRead(0) >> 4; // shifting right by 4 efficiently maps 0-1023 range to 0-63
  // If we have filled the sample buffer, display the results on screen
  if ( pos >= NUMVALUES ) {
    // Measure how long the run took
    unsigned long totalSampleTime = (micros() - readStartTime) / 2;     // Divide by 2 because we are taking twice as many samples as are shown on the screen
    if ( !digitalRead(SCREEN_UPDATE_ENABLE_PIN) ) {
      // Display the data on screen
      display.clearDisplay();
      drawAxis();
      drawValues();
      drawFrameTime(totalSampleTime);
      display.display();
    }
    // Reset values for the next sampling run
    pos = 0;
    count = 0;
  }
}

 

Arduino NANO (3) SSH1106 & Walking bitmap

経緯

ちょっと大き目のOLEDが欲しくて、1.3 InchのOLEDを注文した。

ただもの挿し替えて使えると思って、届いてわかったが、コントローラーは別物。SH1106というものを使われ、U8g2libライブラリをインストールして利用する。

Display OLED via I2C (SH1106)

実際参考サイトを見ながら、試してみる。

うまく表示できた。

しかしコントローラーが特殊のため、使用例がほとんど無いので、用途が限定。

Script – Walking bitmap

#include <Arduino.h>
#include <U8g2lib.h>

#ifdef U8X8_HAVE_HW_SPI
#include <SPI.h>
#endif
#ifdef U8X8_HAVE_HW_I2C
#include <Wire.h>
#endif
 
U8G2_SH1106_128X64_NONAME_F_HW_I2C u8g(U8G2_R0, /* reset=*/ U8X8_PIN_NONE);
// U8GLIB_SH1106_128X64 u8g(U8G_I2C_OPT_NONE); // I2C / TWI  
 
const uint8_t bm[] PROGMEM = {
  0b00011000,
  0b00111100,
  0b01111110,
  0b11111111,
  0b11111111,
  0b01111110,
  0b00111100,
  0b00011000
};
 
static int WIDTH=128;
static int HEIGHT=64;
 
int x, y;
 
void setup(void) {
  u8g.begin();
  x = 0;
  y = 0;
}
 
void loop(void) {
 
  u8g.firstPage();  
  do {
    u8g.drawBitmap( x, y, 1, 8, bm);
  } while( u8g.nextPage() );
  
  delay(100);
 
  x += 8;
  if( x >= WIDTH){
    x = 0;
    y += 8;
    if( y >= HEIGHT){
      y = 0;
    }
  }
}

参考

WeMos (b9) ADS1115 for A/D

ADS1115とは

ADS1115 とは4チャンネル16bit  A/D 。I2C接続なので、OLEDと共に、WeMos に接続して利用してみる。

結線

SCL, SDA自由に変更可能。U8g2初期化コマンドでSetupする。

code

#include <Wire.h>
#include <Adafruit_ADS1015.h>
#include <U8g2lib.h>
#include <math.h>
#define WINDOW_SIZE 128
Adafruit_ADS1115 ads;  /* Use this for the 16-bit version */
//Adafruit_ADS1015 ads;     /* Use thi for the 12-bit version */
// Sets up the display to be the 128px x 32px display
U8G2_SSD1306_128X32_UNIVISION_F_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE, /* clock=*/ SCL, /* data=*/ SDA);
void setup(void)
{
  Serial.begin(9600);
  Serial.println("Hello!");
  Serial.println("Getting differential reading from AIN0 (P) and AIN1 (N)");
  Serial.println("ADC Range: +/- 6.144V (1 bit = 3mV/ADS1015, 0.1875mV/ADS1115)");
  // The ADC input range (or gain) can be changed via the following
  // functions, but be careful never to exceed VDD +0.3V max, or to
  // exceed the upper and lower limits if you adjust the input range!
  // Setting these values incorrectly may destroy your ADC!
  //                                                                ADS1015  ADS1115
  //                                                                -------  -------
  ads.setGain(GAIN_TWOTHIRDS);  // 2/3x gain +/- 6.144V  1 bit = 3mV      0.1875mV (default)
  // ads.setGain(GAIN_ONE);        // 1x gain   +/- 4.096V  1 bit = 2mV      0.125mV
  // ads.setGain(GAIN_TWO);        // 2x gain   +/- 2.048V  1 bit = 1mV      0.0625mV
  // ads.setGain(GAIN_FOUR);       // 4x gain   +/- 1.024V  1 bit = 0.5mV    0.03125mV
  // ads.setGain(GAIN_EIGHT);      // 8x gain   +/- 0.512V  1 bit = 0.25mV   0.015625mV
  // ads.setGain(GAIN_SIXTEEN);    // 16x gain  +/- 0.256V  1 bit = 0.125mV  0.0078125mV
  // Initialize the display
  u8g2.begin();
  ads.begin();
}
// Function to print ${value} with a specific number of ${digits}
void print_digits(double value, short unsigned digits){
  double av = abs(value);
  value = av;
  while(av > 10){
    digits--;
    av/=10;
  }
  u8g2.print(value, digits - 1);
}
int16_t results[WINDOW_SIZE] = {0};
int current_result = 0;
void loop(void)
{
 int time = millis();
  /* Be sure to update this value based on the IC and the gain settings! */
  //float   multiplier = 3.0F;    /* ADS1015 @ +/- 6.144V gain (12-bit results) */
  float multiplier = 0.1875F; /* ADS1115  @ +/- 6.144V gain (16-bit results) */
  double voltage_multiplier = 5333;
  for (int i = 0; i < 16; i++){
    results[current_result] = ads.readADC_Differential_0_1();
    current_result++;
    current_result = current_result % WINDOW_SIZE;
  }
  double result = 0;
  int i;
  for (i = 0; i < WINDOW_SIZE; i++){
    result = result + results[i];
  }
  result = result / (double) WINDOW_SIZE;
  /*Serial.print("Differential: "); Serial.print(results); */
   //Serial.print("(");
   Serial.println(result * multiplier, 5);
   //Serial.println("mV)");
  u8g2.firstPage();
  do {
    // this is where the values get printed to the display
    //u8g2.setFont(u8g2_font_logisoso32_tr); // large 32px tall font
    // other font options can be found at https://github.com/olikraus/u8g2/wiki/fntlistall
    u8g2.setFont(u8g2_font_6x12_tn);
    if (result > 0){
      u8g2.setCursor(0,16);
      u8g2.print("+");
    } else {
      u8g2.setCursor(0,26);
      u8g2.print("-");
    }
    u8g2.setFont(u8g2_font_fur20_tr); // large 20px tall font
    u8g2.setCursor(7,26 );
    double volts = result / voltage_multiplier;
    print_digits(volts, 5);
    u8g2.print("V");
  } while ( u8g2.nextPage() );
  int d = (1000 / 16) - (millis() - time);
  if (d > 0){
    delay(d);
  }
}

 

動作確認

しかし、テスト結果は、思う通りにならない。
表示は0.0000V、1.0000V、ー1.0000V、の感じで、小数点以下は0000となっている。どうして?
大変の曲がり道して、わかったのは、OLEDの定義が間違え、「U8G2_SH1106_128X64_NONAME_F_HW_I2C」になって、その影響で、読み取り数字が変に。
 

「U8G2_SSD1306_128X32_UNIVISION_F_HW_I2C」で定義を直したら、普通にA/D変換の結果が表示が出来た。

参考

IoT 見守りデバイスの開発

見守りIoTデバイスは、ウェアフリー生体センサ・シート型圧電センサと開発ボード、電源で構成された。

シート型圧電センサ

本研究では体動がなく静かな状態で得られた生体信号を分析対象とする。センサは敏感すぎて 体動があると、振幅が大大き過ぎになり、それらが検出できなくなる。

図 4.2 センサシートと開発ボード

今回使用したシート型圧電センサの外形寸法(31cm×34cm)により、椅子の座面に敷いた 状態で測定することにした(図 3.2 右側)。座り状態で安定しやすくなり、血圧や脈拍も測 定しやすくなる。本センサでは 得られた信号は呼吸成分や心拍成分でできている。

見守り開発ボード

 

見守り開発ボードにはA/D変換モジュールADS1115、ESP8266マイクロコントローラ内蔵の開発ボードWeMos D1 Miniと、OLED表示モジュール SSD1306が含まれる。

WeMos D1 MiniとはESP8266をメインチップとして、CH340のUSBシリアル変換チップを組み合わせた開発ボードだ。ESP8266マイクロコントローラはWi-Fiネットワークに接続し、簡単なTCP/IP接続を行うことができる。

 

ADS1115は可変ゲインアンプ付き、4チャンネル内蔵の16bit  A/D コンバータ。I2Cというシリアル通信方法で開発ボードに接続する。

 

SSD1306は小型 解像度128×64 OLED ディスプレイである。こちらもI2Cというシリアル通信方法で開発ボードに接続する。

図 4.3 見守りIoTボード

 

UPDとの通信はUPD APIを利用する。データをUPDへ送信と、UPDから見守り開発ボードへの管理コマンド受信に利用されている。送受信データのTAGは、複数の個体を区別するため、マイクロコントローラのMACアドレスの一部を利用する。例えば見守りIoTボードのMACアドレス下6桁は37cb33のマイクロコントローラに対して、ゲインを4に設定する場合は、TAGは gain-37cb33 である。

 

ウェアフリー生体センサからのデータをサンプリング周波 数 100Hz でデータを取得し、A/D変換して保存する。一定期間のデータを収集したら、まとめてUPDへ送信する。データサンプルは付録1を参照。一度にデータの収集できる期間は、見守りデバイスマイクロコントローラの内蔵メモリの容量による。

ESP8266マイクロコントローラの場合、メモリのリミットにより、6 秒間のデータの蓄積、送信できた。プログラムの最適化により、より長い期間のデータの蓄積、送信も可能である。

図 4.4 ケースにいれた見守りIoTボード

 

見守りIoTボードUPDから見守りデバイスへの管理コマンドの受信も可能である。

ADS1115は可変ゲインアンプであり、現在実装したコマンドはそのゲインの設定である。次はADS1115のゲインを指示するコマンドのサンプルである。

 

“VALUE” “gain-37cb33” “4”

われわれ開発した見守りIoTデバイスのプログラムはGitHubのリポジトリを参照する。

Arduino NANO (1) AD8232 Heart Rate Monitor

経緯

IoT材料を探しに、AD8232 Heart Rate Monitor パーツを購入しました。

添付資料は何もないので、ネットで検索したら、結構出ました。

目の動きも検出できる、いろいろできそう。

回路

参考資料は、Arduino NANOを利用するので、そのままの回路を組み立てる予定。成功したら、ESP8266,ESP32に移植するつもり。

The detailed specification of the Arduino Nano board is as follows:

    • Microcontroller ATmega328
    • Operating Voltage (logic level): 5 V
    • Input Voltage (Recommended): 7-12 V
    • Input Voltage (limits): 6-20 V
    • Digital I/O Pins : 14 (of which 6 provide PWM Output)
    • Analog Input Pins: 8
    • DC Current per I/O Pin: 40 mA
    • Flash Memory 32 KB (ATmega328) of which 2 KB used by bootloader
    • SRAM: 2 KB (ATmega328)
    • EEPROM: 1 KB (ATmega328)
  • Clock Speed: 16 MHz
  • Measurements: 0.73″ x 1.70″

Arduino NANOとAD8232をつないて、LCDまたはOLEDで表示するつもりだが、安定した結果は出ないので、部品の問題か、ソフトウェアの問題か、解決に難航。

部品を買い増すして、検証する予定。

スケッチ

参考資料

  1. https://learn.sparkfun.com/tutorials/ad8232-heart-rate-monitor-hookup-guide