Arduino UNO R4 Wifi 및 Sensirion SHT40을 사용한 온도 그래프
Arduino Uno의 최신 버전인 R4 Wifi의 LED 매트릭스를 사용하여 SHT40에서 읽은 현재 온도를 그래프로 표시해 보겠습니다.
데모 설명
이 글을 쓰는 시점을 기준으로 아두이노 UNO 제품군의 최신 버전인 R4는 R4 Minima와 R4 WiFi의 두 가지 버전으로 출시됩니다. WiFi 연결 외에도 R4 WiFi는 8x12 LED 매트릭스를 제공하여 아두이노 IDE의 시리얼 플로터처럼 센서의 과거 값을 표시하는 데 매우 적합합니다.
이 예에서는 Sensirion SHT40 습도 및 온도 센서의 온도 신호를 사용하고 있지만, 이를 시각화하고 싶은 신호로 변환하는 것은 매우 쉽습니다.
아두이노의 텍스트 방향과 동일하게, 즉 USB 포트가 왼쪽을 향하도록 행렬을 사용하기로 했습니다. Y축은 온도를, X축은 시간을 나타내며, 가장 최근 값은 가장 오른쪽 열에, 새로운 값은 이전 값을 왼쪽으로 "밀어냅니다".
8개 LED의 Y축 해상도를 고려하면 현재 값을 표시할 수 있는 해상도가 제한적입니다. 따라서 다음과 같은 기본 매개변수를 정의했습니다.
#1: 기준값(즉, 그래프에서 가장 낮은 값을 정의하는 값)은 시작 시 측정된 온도에서 작은 비율을 뺀 값을 기준으로 합니다.
#2: 표시되는 범위는 몇 도에 불과합니다.
이렇게 하면 센서에 바람을 불거나 센서를 만졌을 때 나타나는 변화를 볼 수 있고, 시간이 지나면 신호가 0에 가까운 값으로 회복되는 것을 볼 수 있습니다.
범위 또는 기준선을 조정하려면 이 튜토리얼의 2부인 소프트웨어 심층 분석을 확인하세요. 여기서 이러한 범위 또는 기준선이 표시되는 방법과 위치에 대해 자세히 설명합니다.
아두이노를 매우 차가운 환경에서 시작했다가 더 따뜻한 환경으로 이동하거나, 그 반대로 이동하면 모든 값이 표시 범위를 벗어날 수 있습니다. 이 경우, 리셋 버튼을 누르면 기준 온도가 다시 계산됩니다.
하드웨어 설정
이 하드웨어는 Arduino UNO R4 WiFi를 사용합니다. SHT4x 제품군의 모든 센서(예: SHT40/41/43/45)를 사용할 수 있습니다.
제 설정에서는 Adafruit의 SHT40 브레이크아웃 보드를 사용했고, I2C 연결을 위해 QWIIC 커넥터를 통해 연결했습니다.
참고: SHT40을 QWIIC 커넥터 대신 핀 헤더에 연결하면 I2C 포트가 에서 로 변경됩니다 Wire1. Wire이 방법을 알아보려면 이 튜토리얼의 2부인 소프트웨어 심층 분석을 참조하세요.
소프트웨어 설정
소프트웨어를 설치하려면 Arduino IDE가 필요하며, 여기에서 다운로드할 수 있습니다 . 설치가 완료되면 Arduino UNO R4용 보드 패키지를 설치해야 할 수 있습니다. 설치가 완료되면 UNO R4가 연결된 보드와 포트를 설정합니다. 다음 단계로 넘어가기 전에 테스트 스케치를 실행하여 모든 것이 예상대로 작동하는지 확인하는 것이 좋습니다. 이 단계에 도움이 필요하면 'UNO R4 WiFi 시작하기' 튜토리얼을 참조하세요 .
UNO R4가 설치되고 실행되면 SHT40 센서와 통신하는 라이브러리를 설치할 수 있습니다. 설치하려면 Tools 메뉴에서 를 선택하세요 Manage Libraries.... 나타나는 검색 필드에 를 입력 Sensirion i2c sht4x하면 다음과 같은 화면이 표시됩니다(사용 중인 Arduino IDE 버전과 운영 체제에 따라 약간 다를 수 있습니다).
다음으로, 설치를 선택하세요. 종속성도 설치할지 여부를 묻는 대화 상자가 나타납니다.
여기에서는 Install All필요한 라이브러리가 모두 설치되어 있는지 확인하세요.
데모를 만들려면 File > New SketchArduino에서 실행할 수 있는 새 프로그램을 선택하세요.
마지막으로, 이 링크 로 github에서 데모 파일을 열고 , 해당 파일에서 모든 내용을 복사한 다음, 마지막 단계에서 만든 새 스케치의 내용을 복사한 코드로 바꿉니다.
프로그램을 실행하려면 업로드 버튼(오른쪽을 가리키는 화살표)을 누르거나 .을 사용하세요 Sketch > Upload.
UNO R4 및 SHT40을 사용한 온도 그래프 - 소프트웨어 심층 분석
LED 매트릭스 튜토리얼을 따라가며 소프트웨어를 자세히 설명합니다.
기준선 계산 및 표시 범위 설명
8단계의 제한된 범위 때문에, 현재 온도 값을 기준으로 Y축에서 가장 작은 값을 나타내는 초기 기준선을 계산하기로 했습니다. Y축 원점이 실제 온도보다 약간 낮도록 1보다 작은 계수로 조정했습니다. 표시되는 최대 Y값의 경우, 기준선에 미리 정의된 범위를 추가하기만 하면 됩니다.
이 두 값의 기본값은 스케치 맨 위에 다음과 같이 정의되어 있습니다.
static const uint8_t TEMP_RANGE = 5;
...
static const double BASELINE_SCALE_FACTOR = 0.98;
TEMP_RANGE는 섭씨 온도이므로 섭씨 5도 또는 화씨 9도를 표시합니다. 두 값을 변환하려면 다음 공식을 사용할 수 있습니다.
Tf = Tc * 9 / 5
그리고
Tc = Tf * 5 / 9
따라서 범위를 화씨 10도로 지정하려면 10 * 5 / 9 = 5.556을 계산한 다음 6으로 반올림하면 됩니다. 나중에 더 나은 근사값을 제공하기 위해 TEMP_RANGE를 부동 소수점 유형으로 업데이트할 수도 있습니다.
그러면 최소값과 최대값을 계산하는 것은 매우 간단할 것입니다.
// Calculate min value (baseline)
bool baselineInitialized = false;
while (!baselineInitialized) {
if (!Sht4xMeasureHighPrecision()) {
delay(500);
continue;
}
minVal = (uint8_t)(BASELINE_SCALE_FACTOR * temperature);
maxVal = minVal + TEMP_RANGE;
Serial.print("minValue: ");
Serial.println(minVal);
baselineInitialized = true;
}
판독 주파수
판독 빈도는 REFRESH_DELAY 변수에 정의되어 있으며, 이 변수는 측정 간격을 정의합니다. 데이터 스크롤 속도를 높이려면 이 상수를 줄이고, 스크롤 속도를 늦추려면 값을 높이세요.
static const uint8_t REFRESH_DELAY = 250;
이 변수는 밀리초 단위의 지연을 나타냅니다. 250ms는 대략 4Hz에 해당하지만, 센서 판독 및 LED 매트릭스 업데이트에 약간의 시간이 소요되고 이 시간이 지연 시간에 더해지므로 실제로는 약간 더 짧을 것입니다. 이 문제는 해당 코드의 지속 시간을 측정하고 지연 상수에서 빼면 해결할 수 있습니다.
I2C 포트 변경
Arduino UNO R4 WiFi에는 두 개의 I2C 인터페이스가 있습니다. 하나는 핀 헤더( Wire)를 통해 액세스하고, 다른 하나는 QWIIC 커넥터( Wire1)를 통해 액세스합니다. 기본적으로 스케치는 를 사용하도록 구성되어 있습니다 Wire1. 이를 변경하려면 SHT_I2C_INTERFACE 상수를 수정하면 됩니다.
static TwoWire& SHT_I2C_INTERFACE = Wire1; // Wire1 = Uno R4 QWIIC port
insert_right(...) 함수의 'fill' 매개변수
데이터 행렬을 업데이트하는 함수에는 기본값 이 .인 불길한 fill매개변수가 있습니다 true. 이 변수는 각 값을 단일 "픽셀"로 표시할지, 아니면 다음과 같이 채워진 막대 차트로 표시할지 결정합니다.
전체 동작 코드는 아래와 같습니다. 코드 출처를 확인하세요.
/*
* Copyright (c) 2023 Johannes Winkelmann, jw@smts.ch
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files
* (the “Software”), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge,
* publish, distribute, sublicense, and/or sell copies of the Software,
* and to permit persons to whom the Software is furnished to do so, subject
* to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
* THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
/*
* Usage:
* Connect your SHT40 to the QWIIC socket on the Arduino. If you're not
* using the QWIIC connector, adapt the 'SHT_I2C_INTERFACE' variable below
*
* After startup, the lowest row should barely come on. If you blow on the
* sensor to warm it up, you should see the signal rise
*
* To reset the baseline value, simply reset the board
*
* Description:
* This is an demo showing how to use the LED matrix of an Arduino Uno R4
* Wifi to display the signal from a Sensirion SHT4x humidity temperature
* sensor
*
* The orientation is such that the LED matrix is in landscape orientation,
* meaning that there are 12 values, with a resolution of 8 bars each.
* Furthermore, the most recent value is inserted on the right. 'Right' in
* this case is based on the text on the Arduino PCB, i.e. the orientation
* is such that the USB port of the board is looking to the left
*
* Note that since the vertical resolution is just 8 bars, I've opted to
* choose an initial baseline in the init() function, and only show a
* limited range. The range displayed is defined as
* min value: 'BASELINE_SCALE_FACTOR' * baseline value
* max value: min value + TEMP_RANGE
*
* Note that internally, all values are in degree celsius, although since
* the intention is to display the variation, the unit used should have
* no practical impact
*
* Dependencies:
* This demo uses the 'Sensirion I2C SHT4x' library available via the
* Arduino IDE Library Manager, or from
* https://github.com/Sensirion/arduino-i2c-sht4x
*/
#include <Arduino.h>
#include <Wire.h>
#include "SensirionI2CSht4x.h"
#include "Arduino_LED_Matrix.h"
// ----------------------------------------
// Configuration
static const uint8_t COLUMNS = 12;
static const uint8_t ROWS = 8;
uint8_t frame[ROWS][COLUMNS] = { 0 };
static const uint8_t TEMP_RANGE = 5;
static const uint8_t REFRESH_DELAY = 250;
static const double BASELINE_SCALE_FACTOR = 0.98;
static TwoWire& SHT_I2C_INTERFACE = Wire1; // Wire1 = Uno R4 QWIIC port
// ----------------------------------------
// Global variables
ArduinoLEDMatrix matrix;
SensirionI2CSht4x sht4x;
// display range; adjusted in setup()
uint8_t minVal = 0;
uint8_t maxVal = 100;
// SHT4x sensor values
float temperature = 0.0;
float humidity = 0.0;
// error messages
uint16_t error;
char errorMessage[128];
// ----------------------------------------
// helper functions
void ledPanic()
{
uint8_t offFrame[ROWS][COLUMNS] = { 0 };
uint8_t onFrame[ROWS][COLUMNS] = { 0 };
std::fill_n(&onFrame[0][0], ROWS*COLUMNS, 1);
while (true) {
matrix.renderBitmap(onFrame, ROWS, COLUMNS);
delay(500);
matrix.renderBitmap(offFrame, ROWS, COLUMNS);
delay(500);
}
}
// shift bar chart one column to the left, and add the new value in the rightmost column
// note: "left" and "right" are defined based on the PCB silkscreen text
void insert_right(uint8_t frame[ROWS][COLUMNS], uint8_t value, bool fill = true)
{
// shift all rows to the left
for (int columns = 1; columns < COLUMNS; ++columns) {
for (int rows = 0; rows < ROWS; ++rows) {
frame[rows][columns-1] = frame[rows][columns];
}
}
// add new value as the rightmost column
for (int rows = 0; rows < ROWS; ++rows) {
frame[ROWS-1-rows][COLUMNS-1] = fill ? ((value-1) >= rows) : ((value-1) == rows);
}
}
/*
* Run a high precision measurement on SHT4x sensor
* @return bool: true on succes, false if measurement failed.
*/
bool Sht4xMeasureHighPrecision()
{
error = sht4x.measureHighPrecision(temperature, humidity);
if (error) {
Serial.println("Error in measureHighPrecision() during baseline calculation; retry");
errorToString(error, errorMessage, 256);
Serial.println(errorMessage);
return false;
}
return true;
}
// ----------------------------------------
// main code
void setup()
{
matrix.begin();
SHT_I2C_INTERFACE.begin();
Serial.begin(115200);
while (!Serial) {
// let serial console settle
delay(100);
}
uint32_t serialNumber;
sht4x.begin(SHT_I2C_INTERFACE);
// probe sensor by reading serial number
error = sht4x.serialNumber(serialNumber);
if (error) {
Serial.print("SHT4x initializationfailed. Sketch halted\n");
errorToString(error, errorMessage, 128);
Serial.println(errorMessage);
ledPanic();
}
// Calculate min value (baseline)
bool baselineInitialized = false;
while (!baselineInitialized) {
if (!Sht4xMeasureHighPrecision()) {
delay(500);
continue;
}
minVal = (uint8_t)(BASELINE_SCALE_FACTOR * temperature);
maxVal = minVal + TEMP_RANGE;
Serial.print("minValue: ");
Serial.println(minVal);
baselineInitialized = true;
}
}
void loop()
{
delay(REFRESH_DELAY);
if (!Sht4xMeasureHighPrecision()) {
// measurement failed, try again later.
return;
}
// Update display matrix
uint8_t displayValue = (uint8_t)((temperature - minVal) / (maxVal - minVal) * ROWS);
insert_right(frame, displayValue, true);
matrix.renderBitmap(frame, ROWS, COLUMNS);
}
'아두이노우노 R4' 카테고리의 다른 글
Arduino Uno R4 Wifi의 LED 매트릭스를 시계열 그래프로 사용하는 데모 (3) | 2025.07.01 |
---|---|
Arduino를 사용하여 ESP32 보드에 FreeRTOS 구현하기 개요 (5) | 2025.06.30 |
Arduino를 사용하여 ESP32 보드에 FreeRTOS 구현하기 2 (5) | 2025.06.30 |
Arduino를 사용하여 ESP32 보드에 FreeRTOS 구현하기 1 (1) | 2025.06.30 |
Arduino를 사용하여 ESP32 보드에 FreeRTOS 구현하기 4 (3) | 2025.06.30 |
Arduino를 사용하여 ESP32 보드에 FreeRTOS 구현하기 3 (1) | 2025.06.30 |
Request Sensor Data via SMS using Arduino and SIM900 GSM Shield (0) | 2025.04.22 |
Lora 모듈: 15km 거리에서 릴레이 켜기 (0) | 2025.03.24 |
더욱 좋은 정보를 제공하겠습니다.~ ^^