Oxymètre et arduino

1 arduino nano v3

3 résistances 4.7 kO

1 écran 0.96″ I2C IIC Serial 128X64 128*64 Blue OLED

0.96" I2C IIC Serial 128X64 128*64 Blue OLED LCD LED Display Module for Arduino

MAX30100 MAX30102 Heart Rate Breakout Sensor Blood Oxygen Transducer for Arduino

MAX30100 MAX30102 Heart Rate Breakout Sensor Blood Oxygen Transducer for Arduino

Installer les libs :

[root@10-83-102-17 SSD1306Ascii]# more library.properties
name=SSD1306Ascii
version=1.3.0
author=Bill Greiman fat16lib@sbcglobal.net
maintainer=Bill Greiman fat16lib@sbcglobal.net
sentence=Text display on small momochrome OLED modules.
paragraph=A basic SSD1306 text only library optimized for minimum memory usage.
category=Display
url=https://github.com/greiman/SSD1306Ascii
architectures=*

[root@10-83-102-17 libraries]# more MAX30100lib/library.properties
name=MAX30100lib
version=1.2.1
author=OXullo Intersecans x@brainrapers.org
maintainer=OXullo Intersecans x@brainrapers.org
sentence=Maxim-IC MAX30100 heart-rate sensor driver and pulse-oximetry components
paragraph=This library exposes most of the features of the MAX30100 and offers a modular approach to calculate pulse rate and SpO2
category=Sensors
url=https://github.com/oxullo/Arduino-MAX30100
architectures=*

#include <Wire.h>
#include "MAX30100_PulseOximeter.h"
#include "SSD1306Ascii.h"
#include "SSD1306AsciiWire.h"

#define REPORTING_PERIOD_MS     1000

// PulseOximeter is the higher level interface to the sensor
// it offers:
//  * beat detection reporting
//  * heart rate calculation
//  * SpO2 (oxidation level) calculation

PulseOximeter pox;
SSD1306AsciiWire oled;

uint32_t tsLastReport = 0;

// Callback (registered below) fired when a pulse is detected
void onBeatDetected()
{
    Serial.println("Beat!");
}

void setup()
{
    Serial.begin(115200);

oled.begin(&Adafruit128x64, 0x3C);
  Serial.println("ok2");
  oled.setFont(Arial14);
    Serial.print("Initializing pulse oximeter..");

    // Initialize the PulseOximeter instance
    // Failures are generally due to an improper I2C wiring, missing power supply
    // or wrong target chip
    if (!pox.begin()) {
        Serial.println("FAILED");
        for(;;);
    } else {
        Serial.println("SUCCESS");
    }

    // The default current for the IR LED is 50mA and it could be changed
    //   by uncommenting the following line. Check MAX30100_Registers.h for all the
    //   available options.
    pox.setIRLedCurrent(MAX30100_LED_CURR_7_6MA);

    // Register a callback for the beat detection
    pox.setOnBeatDetectedCallback(onBeatDetected);
}

void loop()
{
    // Make sure to call update as fast as possible
    pox.update();

    // Asynchronously dump heart rate and oxidation levels to the serial
    // For both, a value of 0 means "invalid"
    if (millis() - tsLastReport > REPORTING_PERIOD_MS) {
        Serial.print("Heart rate:");
        Serial.print(pox.getHeartRate());
        Serial.print("bpm / SpO2:");
        Serial.print(pox.getSpO2());
        Serial.println("%");
        printToScreen();
        tsLastReport = millis();
    }
}


void printToScreen() {
  oled.clear();
  oled.setCursor(0,0);
   oled.print(F("HR: ")); oled.println(pox.getHeartRate(), DEC);
    oled.print(F("SPO2: ")); oled.println(pox.getSpO2(), DEC);
  }

Spectre fréquence et RPI4

dongle usb micro

pip3 install pyalsaaudio
176 pip3 install matplotlib
178 pip3 install scipy

#!/usr/bin/python3

# display sound spectral view with scipy FFT and matplotlib
#   here sound source is the system microphone with ALSA (channel 1)

from collections import deque
import struct
import sys
import threading
import alsaaudio
import matplotlib.pyplot as plt
import matplotlib.animation as animation
import numpy as np
from scipy.fftpack import fft

import time,datetime

# some const
# 44100 Hz sampling rate (for 0-22050 Hz view, 0.0227ms/sample)
SAMPLE_FREQ = 44100
# 66000 samples buffer size (near 1.5 second)
#NB_SAMPLE = 66000
NB_SAMPLE = 100000

f=open('data.txt','a')

class Sampler(threading.Thread):
    def __init__(self, cardindex=-1):
        # init thread
        threading.Thread.__init__(self)
        self.daemon = True
        # init ALSA audio
        self.inp = alsaaudio.PCM(alsaaudio.PCM_CAPTURE, alsaaudio.PCM_NORMAL, cardindex=cardindex)
        # set attributes: Mono, frequency, 16 bit little endian samples
        self.inp.setchannels(1)
        self.inp.setrate(SAMPLE_FREQ)
        self.inp.setformat(alsaaudio.PCM_FORMAT_S16_LE)
        self.inp.setperiodsize(512)
        # sample FIFO
        self._s_lock = threading.Lock()
        self._s_fifo = deque([0] * NB_SAMPLE, maxlen=NB_SAMPLE)

    def get_sample(self):
        with self._s_lock:
            return list(self._s_fifo)

    def run(self):
        while True:
            # read data from device
            l, data = self.inp.read()
            if l > 0:
                # extract and format sample (normalize sample to 1.0/-1.0 float)
                raw_smp_l = struct.unpack('h' * l, data)
                #print(data)
                #raw_smp_l=data
                smp_l = (float(raw_smp / 32767) for raw_smp in raw_smp_l)
                    self._s_fifo.extend(smp_l)
            else:
                print('sampler error occur (l=%s and len data=%s)' % (l, len(data)))


def plot_anim(i):
    # read samples
    samples = spr.get_sample()
    # compute FFT
    y_freq = fft(samples)
    # frequency axe in Hz:
    # 0.0 to max frequency (= sample rate/2), number of step is half of NB_SAMPLE
    x_freq = np.linspace(0.0, SAMPLE_FREQ // 2, NB_SAMPLE // 2)

    # level axe at each frequency:
    # yf between 0.0 and 1.0 for every xf step
    y_level = 1.0 / (NB_SAMPLE / 2) * np.abs(y_freq[0:NB_SAMPLE // 2]) * 100
    # wipe and redraw
    ax1.clear()
    ax1.set_xlabel('Frequency (Hz)')
    ax1.set_xlim(0,1000)
    ax1.set_ylabel('Level (%)')
    ax1.plot(x_freq, y_level, 'b', lw=2)
    # find higher level frequency
    index_max = np.argmax(y_level)
    
    freq_max = x_freq[index_max]
    if  freq_max > 600 and freq_max < 800 :
        f.write(str(datetime.datetime.utcnow().strftime("%Y%m%d %H:%M:%S"))+','+str(freq_max)+','+str(y_level[index_max])+'\n')
        f.flush()


    print('max level at f=%i Hz (lvl=%.02f %%)' % (freq_max, y_level[index_max]))
    #print('sample: max %.04f, min %.04f' % (max(samples), min(samples)))

if __name__ == '__main__':
    # start sound sampler thread
    spr = Sampler(2)
    spr.start()
    # init a dynamic plotter
    fig, (ax1) = plt.subplots(nrows=1, ncols=1)
    fig.canvas.set_window_title('Sound spectral view')
    ani = animation.FuncAnimation(fig, plot_anim, interval=1000)
    plt.show()

https://www.szynalski.com/tone-generator/

RPI4 et NTP

vi /etc/systemd/timesyncd.conf


timedatectl set-ntp true

root@raspberrypi:/home/pi# cat /etc/systemd/timesyncd.conf
#  This file is part of systemd.
#
#  systemd is free software; you can redistribute it and/or modify it
#  under the terms of the GNU Lesser General Public License as published by
#  the Free Software Foundation; either version 2.1 of the License, or
#  (at your option) any later version.
#
# Entries in this file show the compile time defaults.
# You can change settings by editing this file.
# Defaults can be restored by simply deleting this file.
#
# See timesyncd.conf(5) for details.

[Time]
#NTP=
#FallbackNTP=0.debian.pool.ntp.org 1.debian.pool.ntp.org 2.debian.pool.ntp.org 3.debian.pool.ntp.org
#RootDistanceMaxSec=5
#PollIntervalMinSec=32
#PollIntervalMaxSec=2048

Servers=ntp.laas.fr

Session du lundi 13 janvier 2020 18h

 

Quand ça ne marche pas, que faire ? debug

Faire marcher le composant / shield DHT11 (capteur de température et d’humidité)

Comparison of three pin DHT11 vs four pin DHT11

How to Set Up the DHT11 Humidity Sensor on an Arduino

Installer la librairie ci-dessous :

DHTLib

Faire le montage :

http://www.circuitbasics.com/wp-content/uploads/2015/10/Arduino-DHT11-Tutorial-3-Pin-DHT11-Wiring-Diagram.png

Code :

#include <dht.h>

dht DHT;

int DHT11_PIN=7;

void setup(){
  Serial.begin(9600);
}

void loop()
{
  int chk = DHT.read11(DHT11_PIN);
  Serial.print(chk);
  Serial.print(",Temperature = ");
  Serial.print(DHT.temperature);
  Serial.print(",Humidity = ");
  Serial.println(DHT.humidity);
  delay(2000);
}

 

Les valeurs de la température et de l’humidité doivent s’afficher sur la console.

0,Temperature = 21.00,Humidity = 52.00
0,Temperature = 21.00,Humidity = 52.00
0,Temperature = 21.00,Humidity = 52.00
0,Temperature = 21.00,Humidity = 52.00
0,Temperature = 21.00,Humidity = 51.00
0,Temperature = 21.00,Humidity = 51.00
0,Temperature = 21.00,Humidity = 51.00
0,Temperature = 21.00,Humidity = 51.00
-1,Temperature = 21.00,Humidity = 51.00