Hi all,
I have a project for temperature control equipped with SpO2 sensor AFE4490, temperature sensor DS18B20. I have a problem because the sampling rate is 750ms or 12-bit which causes a delay in serial.print. is there a solution to this problem?
depends on how you wrote the code. please post it
this my code
#include <SPI.h>
#include "protocentral_afe44xx.h"
#include <EEPROM.h>
#include "fis_header.h"
// #include <TimerOne.h>
afe44xx_data data_modul1;
afe44xx_data data_modul2;
// Konfigurasi pin untuk modul 1
#define AFE44XX_CS_PIN_1 7
#define AFE44XX_PWDN_PIN_1 4
AFE44XX afe44xx_modul1(AFE44XX_CS_PIN_1, AFE44XX_PWDN_PIN_1, &data_modul1);
// Konfigurasi pin untuk modul 2
#define AFE44XX_CS_PIN_2 6
#define AFE44XX_PWDN_PIN_2 9
AFE44XX afe44xx_modul2(AFE44XX_CS_PIN_2, AFE44XX_PWDN_PIN_2, &data_modul2);
#define BUFFER_ENABLE_1 14 // Pin untuk mengontrol OE Buffer Modul 1
#define BUFFER_ENABLE_2 15 // Pin untuk mengontrol OE Buffer Modul 2
#define NOISE_BASELINE 2096921 // Nilai saat sensor tidak dipasang
#define NOISE_THRESHOLD 0.05 // Toleransi 5%
#include <OneWire.h>
#include <DallasTemperature.h>
#define ONE_WIRE_BUS 12
const int pwmout = 13; //PIN OUTPUT PWM
// Number of inputs to the fuzzy inference system
const int fis_gcI = 2;
// Number of outputs to the fuzzy inference system
const int fis_gcO = 1;
// Number of rules to the fuzzy inference system
const int fis_gcR = 25;
FIS_TYPE g_fisInput[fis_gcI];
FIS_TYPE g_fisOutput[fis_gcO];
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensor(&oneWire);
int32_t heart_rate_prev1 = 0;
int32_t spo2_prev1 = 0;
int32_t heart_rate_prev2 = 0;
int32_t spo2_prev2 = 0;
volatile bool ppgReady = false;
volatile float filtered_signal1;
volatile float filtered_signal2;
float tmp = 32.00;
float tskin = 34.00;
float spopre = 96.00;
float spopost = 92.00;
int hrpre = 85;
int hrpost = 82;
float weight = 2.5;
int kp = 1.5;
int ki = 3;
int kd = 4;
int pwm = 255;
float ppg1 = 100;
float ppg2 = 50;
int e = 1;
int ec = 2;
// Flag status sensor
bool sensorSkinTerhubung = false;
float alpha = 0.2;
float smoothedSkinTemp;
double Thermister(int RawADC) {
double skin;
skin = log(((10240000 / RawADC) - 10000));
skin = 1 / (0.001129148 + (0.000234125 + (0.0000000876741 * skin * skin)) * skin);
skin = skin - 278.45; // Convert Kelvin to Celsius
return skin;
}
const int storedskin = 25;
float skins[storedskin];
unsigned char skinIndex = 0;
float totalskin;
//double bacaSKIN() {
// totalskin = totalskin - skins[skinIndex];
// unsigned int tadc = analogRead(A0);
// if (tadc < 1 || tadc > 1000) { // Jika sensor dicabut
// return false; // Mengembalikan NAN untuk mendeteksi masalah
// }
//
// // double suhuSkin = Thermister(tadc);
////
//// if (isnan(skins[skinIndex])) { // Validasi jika suhu NAN
//// return NAN;
//// }
// // if (tadc > 1000) {
// // return false;
// // }
// skins[skinIndex] = Thermister(tadc);
// totalskin = totalskin + skins[skinIndex];
// skinIndex = skinIndex + 1;
// // totalskin -= skins[skinIndex]; // Kurangi nilai lama
// // skins[skinIndex] = suhuSkin; // Tambahkan nilai baru
// // totalskin += skins[skinIndex];
// if (skinIndex >= storedskin) {
// skinIndex = 0;
// }
//
// return (totalskin / storedskin) + 64.9;
//}
double bacaSKIN() {
unsigned int tadc = analogRead(A0);
if (tadc < 1 || tadc > 1000) {
return NAN;
}
double suhuSkin = Thermister(tadc);
if (isnan(suhuSkin)) {
return NAN;
}
// Terapkan Exponential Moving Average (EMA)
smoothedSkinTemp = (alpha * suhuSkin) + ((1 - alpha) * smoothedSkinTemp);
return smoothedSkinTemp + 65.8;
}
volatile float suhu2 = 0.0;
volatile bool readyToRead = false; // Flag untuk pengecekan data
double skinTemp;
float suhu, skin, varset;
float targetTemperature = 0.0; // Suhu target default
float currentTemperature = 0.0;
float pwmOutput;
float pwmPercentage;
String mode = "Manual"; // 'M' for Manual (DS18B20), 'A' for Auto (YSI400) // Default setpoint
String sensorType = "D"; // D untuk DS18B20, Y untuk YSI400
bool heaterState = false; // Heater state
unsigned long previousMillis = 0;
unsigned long previousWaktu = 0;
float error, errorx;
float derivativeError;
unsigned long timeDifference;
unsigned long previousTime = 0; // Waktu sebelumnya
float previousError = 0.0; // Nilai error sebelumnya
unsigned long deltaTime = 1000; // Interval waktu (dalam milidetik)
float cumError, rateError, lastError, currentError;
float input, output, Denormalisasi;
/// Nilai STDev, Rata-rata Data Input dan Output
float STDevOut = 0.943180689, MeanOut = 0.938902743;
int Pembulatan;
static unsigned long waktu, waktu1;
// Koefisien Notch Filter (50 Hz) dari MATLAB
float b_notch[3] = {0.979483, -0.605354, 0.979483};
float a_notch [3] = {1.00000, -0.605354, 0.958966};
// Koefisien LPF Order 2, Fc = 15 Hz (dari MATLAB)
float b_lpf[3] = {0.0675, 0.1350, 0.0675};
float a_lpf[3] = {1.0000, -1.1429, 0.4128};
// Buffer untuk Notch dan LPF
float x_notch1[3] = {0}, y_notch1[3] = {0}; // Modul 1
float x_lpf1[3] = {0}, y_lpf1[3] = {0}; // Modul 1
float x_notch2[3] = {0}, y_notch2[3] = {0}; // Modul 2
float x_lpf2[3] = {0}, y_lpf2[3] = {0}; // Modul 2
// Fungsi Notch Filter untuk Modul 1
float applyNotch1(float x_in) {
x_notch1[2] = x_notch1[1]; x_notch1[1] = x_notch1[0]; x_notch1[0] = x_in;
y_notch1[2] = y_notch1[1]; y_notch1[1] = y_notch1[0];
y_notch1[0] = b_notch[0] * x_notch1[0] + b_notch[1] * x_notch1[1] + b_notch[2] * x_notch1[2]
- a_notch[1] * y_notch1[1] - a_notch[2] * y_notch1[2];
return y_notch1[0];
}
// Fungsi Notch Filter untuk Modul 2
float applyNotch2(float x_in) {
x_notch2[2] = x_notch2[1]; x_notch2[1] = x_notch2[0]; x_notch2[0] = x_in;
y_notch2[2] = y_notch2[1]; y_notch2[1] = y_notch2[0];
y_notch2[0] = b_notch[0] * x_notch2[0] + b_notch[1] * x_notch2[1] + b_notch[2] * x_notch2[2]
- a_notch[1] * y_notch2[1] - a_notch[2] * y_notch2[2];
return y_notch2[0];
}
// Fungsi LPF untuk Modul 1
float applyLPF1(float x_in) {
x_lpf1[2] = x_lpf1[1]; x_lpf1[1] = x_lpf1[0]; x_lpf1[0] = x_in;
y_lpf1[2] = y_lpf1[1]; y_lpf1[1] = y_lpf1[0];
y_lpf1[0] = b_lpf[0] * x_lpf1[0] + b_lpf[1] * x_lpf1[1] + b_lpf[2] * x_lpf1[2]
- a_lpf[1] * y_lpf1[1] - a_lpf[2] * y_lpf1[2];
return y_lpf1[0];
}
// Fungsi LPF untuk Modul 2
float applyLPF2(float x_in) {
x_lpf2[2] = x_lpf2[1]; x_lpf2[1] = x_lpf2[0]; x_lpf2[0] = x_in;
y_lpf2[2] = y_lpf2[1]; y_lpf2[1] = y_lpf2[0];
y_lpf2[0] = b_lpf[0] * x_lpf2[0] + b_lpf[1] * x_lpf2[1] + b_lpf[2] * x_lpf2[2]
- a_lpf[1] * y_lpf2[1] - a_lpf[2] * y_lpf2[2];
return y_lpf2[0];
}
// Koefisien High-Pass Filter (2 Hz, Fs = 250 Hz)
float b_hpf[3] = {0.9831, -1.9662, 0.9831};
float a_hpf[3] = {1.0000, -1.9660, 0.9662};
// Buffer untuk HPF
float x_hpf1[3] = {0}, y_hpf1[3] = {0}; // Modul 1
float x_hpf2[3] = {0}, y_hpf2[3] = {0}; // Modul 2
// Fungsi HPF untuk Modul 1
float applyHPF1(float x_in) {
x_hpf1[2] = x_hpf1[1]; x_hpf1[1] = x_hpf1[0]; x_hpf1[0] = x_in;
y_hpf1[2] = y_hpf1[1]; y_hpf1[1] = y_hpf1[0];
y_hpf1[0] = b_hpf[0] * x_hpf1[0] + b_hpf[1] * x_hpf1[1] + b_hpf[2] * x_hpf1[2]
- a_hpf[1] * y_hpf1[1] - a_hpf[2] * y_hpf1[2];
return y_hpf1[0];
}
// Fungsi HPF untuk Modul 2
float applyHPF2(float x_in) {
x_hpf2[2] = x_hpf2[1]; x_hpf2[1] = x_hpf2[0]; x_hpf2[0] = x_in;
y_hpf2[2] = y_hpf2[1]; y_hpf2[1] = y_hpf2[0];
y_hpf2[0] = b_hpf[0] * x_hpf2[0] + b_hpf[1] * x_hpf2[1] + b_hpf[2] * x_hpf2[2]
- a_hpf[1] * y_hpf2[1] - a_hpf[2] * y_hpf2[2];
return y_hpf2[0];
}
#define MA_WINDOW 10 // Jumlah sampel untuk moving average
float ma_buffer1[MA_WINDOW] = {0}; // Buffer untuk Modul 1
float ma_buffer2[MA_WINDOW] = {0}; // Buffer untuk Modul 2
int ma_index1 = 0;
int ma_index2 = 0;
// Fungsi Moving Average
float movingAverage(float input, int modul) {
float sum = 0.0;
if (modul == 1) {
ma_buffer1[ma_index1] = input; // Simpan input terbaru
ma_index1 = (ma_index1 + 1) % MA_WINDOW; // Geser index
for (int i = 0; i < MA_WINDOW; i++) {
sum += ma_buffer1[i];
}
return sum / MA_WINDOW;
} else {
ma_buffer2[ma_index2] = input;
ma_index2 = (ma_index2 + 1) % MA_WINDOW;
for (int i = 0; i < MA_WINDOW; i++) {
sum += ma_buffer2[i];
}
return sum / MA_WINDOW;
}
}
float filterSignal(float input, int modul) {
float hpfOutput, notchOutput, lpfOutput, mafOutput;
if (modul == 1) {
hpfOutput = applyHPF1(input); // Hilangkan frekuensi di bawah 2 Hz
notchOutput = applyNotch1(hpfOutput); // Hilangkan noise 50 Hz
lpfOutput = applyLPF1(notchOutput); // Haluskan sinyal di bawah 15 Hz
mafOutput = movingAverage(lpfOutput, 1); // Stabilkan sinyal
} else {
hpfOutput = applyHPF2(input);
notchOutput = applyNotch2(hpfOutput);
lpfOutput = applyLPF2(notchOutput);
mafOutput = movingAverage(lpfOutput, 2);
}
return mafOutput;
}
void setup() {
Serial.begin(115200);
SPI.begin();
data_modul1.RED_data = 0;
data_modul2.RED_data = 0;
pinMode(AFE44XX_CS_PIN_1, OUTPUT);
pinMode(AFE44XX_CS_PIN_2, OUTPUT);
pinMode(BUFFER_ENABLE_1, OUTPUT);
pinMode(BUFFER_ENABLE_2, OUTPUT);
// Nonaktifkan semua CS dan buffer di awal
digitalWrite(AFE44XX_CS_PIN_1, HIGH);
digitalWrite(AFE44XX_CS_PIN_2, HIGH);
digitalWrite(BUFFER_ENABLE_1, HIGH); // Disable buffer (OE aktif rendah)
digitalWrite(BUFFER_ENABLE_2, HIGH); // Disable buffer
afe44xx_modul1.afe44xx_init(&data_modul1);
afe44xx_modul2.afe44xx_init(&data_modul2);
pinMode(pwmout, OUTPUT);
analogWrite(pwmout, 0);
sensor.begin();
sensor.setResolution(0, 12);
Timer1.initialize(1000000);
//Timer1.attachInterrupt(readPPG);
}
float calculateDerivativeError(float currentError) {
unsigned long currentTime = millis(); // Waktu saat ini
// Menghitung perbedaan waktu
timeDifference = currentTime - previousTime;
// Menghitung perbedaan error
float errorDifference = currentError - previousError;
// Menghitung nilai error turunan
derivativeError = errorDifference / (float)timeDifference;
// Update waktu dan nilai error sebelumnya
previousTime = currentTime;
previousError = currentError;
return derivativeError;
}
// Membership function parameters (example values)
float errorMFs[5][3] = { { -1, 0, 2 }, { 1, 3, 5 }, { 4, 6, 8 }, { 7, 9, 11 }, { 10, 11, 12 } };
float errorChangeMFs[5][3] = { { -0.5, -0.25, 0 }, { -0.25, -0.1, 0.1 }, { -0.1, 0, 0.1 }, { 0.1, 0.25, 0.5 }, { 0.25, 0.5, 0.75 } };
// Rules output PWM values
float ruleOutput[25] = { 0, 20, 40, 60, 80, 100, 120, 140, 160, 180, 200, 220, 240, 255, 255, 255, 240, 220, 200, 180, 160, 140, 120, 100, 80 };
// Function to calculate triangular membership
float calculateMF(float x, float a, float b, float c) {
if (x <= a || x >= c) return 0;
if (x == b) return 1;
if (x < b) return (x - a) / (b - a);
return (c - x) / (c - b);
}
// Calculate ANFIS output
float calculateANFISOutput(float error, float errorChange) {
float weights[25] = { 0 };
float outputSum = 0;
float weightSum = 0;
// Calculate firing strength for each rule
for (int i = 0; i < 5; i++) {
float errorWeight = calculateMF(error, errorMFs[i][0], errorMFs[i][1], errorMFs[i][2]);
for (int j = 0; j < 5; j++) {
float errorChangeWeight = calculateMF(errorChange, errorChangeMFs[j][0], errorChangeMFs[j][1], errorChangeMFs[j][2]);
weights[i * 5 + j] = errorWeight * errorChangeWeight;
outputSum += weights[i * 5 + j] * ruleOutput[i * 5 + j];
weightSum += weights[i * 5 + j];
}
}
return (weightSum > 0) ? (outputSum / weightSum) : 0;
}
float generateRandomPPG(float min, float max) {
return random(min * 100, max * 100) / 100.0;
}
void loop() {
if (Serial.available() > 0) {
String command = Serial.readStringUntil('\n');
processCommand(command);
}
// Akses Modul 1
digitalWrite(BUFFER_ENABLE_1, LOW); // Aktifkan buffer Modul 1
digitalWrite(BUFFER_ENABLE_2, HIGH); // Nonaktifkan buffer Modul 2
digitalWrite(AFE44XX_CS_PIN_1, LOW); // Aktifkan CS Modul 1
afe44xx_modul1.get_AFE44XX_Data(&data_modul1);
heart_rate_prev1 = data_modul1.heart_rate;
spo2_prev1 = data_modul1.spo2;
float raw_signal1 = (float)data_modul1.RED_data;
float notch_signal1 = applyNotch1(raw_signal1);
// float filtered_signal1 = applyLPF1(notch_signal1);
float filtered_signal1 = filterSignal(raw_signal1, 1);
// *Deteksi noise & tampilkan hanya jika ada sinyal valid*
if (abs(raw_signal1 - NOISE_BASELINE) < (NOISE_BASELINE * NOISE_THRESHOLD)) {
filtered_signal1 = 0; // Jangan tampilkan noise di grafik
}
digitalWrite(AFE44XX_CS_PIN_1, HIGH); // Nonaktifkan CS Modul 1
digitalWrite(BUFFER_ENABLE_1, HIGH); // Nonaktifkan buffer Modul 1
// Akses Modul 2
digitalWrite(BUFFER_ENABLE_2, LOW); // Aktifkan buffer Modul 2
digitalWrite(BUFFER_ENABLE_1, HIGH); // Nonaktifkan buffer Modul 1
digitalWrite(AFE44XX_CS_PIN_2, LOW); // Aktifkan CS Modul 2
afe44xx_modul2.get_AFE44XX_Data(&data_modul2);
heart_rate_prev2 = data_modul2.heart_rate;
spo2_prev2 = data_modul2.spo2;
float raw_signal2 = (float)data_modul2.RED_data;
float notch_signal2 = applyNotch2(raw_signal2);
// float filtered_signal2 = applyLPF2(notch_signal2);
float filtered_signal2 = filterSignal(raw_signal2, 2);
if (abs(raw_signal2 - NOISE_BASELINE) < (NOISE_BASELINE * NOISE_THRESHOLD)) {
filtered_signal2 = 0;
}
digitalWrite(AFE44XX_CS_PIN_2, HIGH); // Nonaktifkan CS Modul 2
digitalWrite(BUFFER_ENABLE_2, HIGH); // Nonaktifkan buffer Modul 2
// if (readyToRead) {
// sensor.requestTemperatures();
// suhu = sensor.getTempCByIndex(0) * 1.1; // Ambil hasil konversi
//readyToRead = false; // Reset flag
//}
skinTemp = (abs(bacaSKIN()));
if (isnan(skinTemp)) {
if (sensorSkinTerhubung) {
// Jika sensor baru saja terputus
//Serial.println("Sensor skin tidak terdeteksi, cek koneksi!");
sensorSkinTerhubung = false;
// Reset buffer untuk menghindari nilai lama
// for (int i = 0; i < storedskin; i++) {
// skins[i] = 0;
// }
// totalskin = 0;
// skinIndex = 0;
}
} else {
if (!sensorSkinTerhubung) {
// Jika sensor baru saja terhubung kembali
//Serial.println("Sensor skin terdeteksi kembali, memulai pembacaan!");
sensorSkinTerhubung = true;
}
skin = skinTemp; // Update nilai suhu skin
}
// if ((millis() - waktu) > 1000) {
// error = skinTemp - targetTemperature;
// currentError = error; // Current error reading
// derivativeError = calculateDerivativeError(currentError) * 10000; // Scaling factor for better resolution
// waktu = millis();
// }
// g_fisInput[0] = error;
// g_fisInput[1] = derivativeError;
// g_fisOutput[0] = 0;
// fis_evaluate();
// if (heaterState) {
// if (mode == "Auto" || mode == "Manual") {
//
// // Pastikan output FIS dalam rentang 0-255
//
// //int pwmValue = constrain(g_fisOutput[0], 0, 255);
//
// analogWrite(pwmout, g_fisOutput[0]);
// }
//
// else {
//
// analogWrite(pwmout, 0);
//
// }
// }
currentTemperature = (sensorType == "D") ? suhu : skinTemp;
controlHeater(currentTemperature);
pwmPercentage = map(g_fisOutput[0], 0, 255, 0, 100);
// float data[12] = { suhu, skinTemp, error, ec, i, spopre, hrpre, spopost, hrpost, ppg1, ppg2, pwmPercentage };
// for (int i = 0; i < 12; i++) {
// Serial.print(data[i]);
// if (i < 11) {
// Serial.print("/");
// }
// }
Serial.print(suhu2);
Serial.print("/");
Serial.print(skinTemp);
Serial.print("/");
Serial.print(error);
Serial.print("/");
Serial.print(derivativeError); +
Serial.print("/");
Serial.print(weight);
Serial.print("/");
Serial.print(data_modul1.spo2);
Serial.print("/");
Serial.print(data_modul1.heart_rate);
Serial.print("/");
Serial.print(data_modul2.spo2);
Serial.print("/");
Serial.print(data_modul2.heart_rate);
Serial.print("/");
Serial.print(filtered_signal1);
Serial.print("/");
Serial.print(filtered_signal2);
Serial.print("/");
Serial.println(pwmPercentage);
delay(8);
}
void processCommand(String command) {
command.trim();
if (command == "H") {
heaterState = true; // Hidupkan heater
analogWrite(pwmout, 255);
} else if (command == "L") {
heaterState = false; // Matikan heater
analogWrite(pwmout, 0);
targetTemperature = 0;
} else if (command == "D") {
sensorType = "D";
} else if (command == "Y") {
sensorType = "Y";
} else if (command == "M") {
mode = "Manual";
} else if (command == "A") {
mode = "Auto";
}
else {
float value = command.toInt();
if (value >= 32 && value <= 38) {
targetTemperature = value; // Atur suhu target
}
}
}
void controlHeater(float currentTemp) {
if ((millis() - waktu) > 1000) {
error = targetTemperature - currentTemp;
currentError = error; // Current error reading
derivativeError = calculateDerivativeError(currentError) * 10000; // Scaling factor for better resolution
waktu = millis();
}
if (heaterState) {
g_fisInput[0] = error;
g_fisInput[1] = derivativeError;
//g_fisOutput[0] = 0;
fis_evaluate();
analogWrite(pwmout, g_fisOutput[0]);
//digitalWrite(pwmout, 255);
return; // Exit the function if the heater is off
} else {
//pwmOutput = 0;
analogWrite(pwmout, 0);
//digitalWrite(pwmout, 0);
return; // Exit the function if the heater is off
}
}
why do you describe the sample rate as a time, instead of frequency and why as 12-bit?
seems like there is a lot of processing within loop(). I would have expected there only to be processing after each sample is collected.
i don't see any timer code using millis(). how to do determine when to collect a sample?
because the resolution of the DS18B20 sensor is set to 12-bit which is equivalent to 750ms.
sensor.requestTemperatures();
suhu = sensor.getTempCByIndex(0) * 1.1;
We want the readings for the AFE4490 module to be fast. When we disappear the DS18B20 reading program, the other sensor readings can be read properly.
don't understand. doesn't the 12-it refer to the resolution of the temperature value? how does that affect how often it is sampled?
doesn't sampling every 750 msec mean once every 1.33 sec?
this terminology is confusing
this is the time to display sensor results
Timer1.initialize(1000000);
yes, but in practice I use a delay of 10ms looks very slow. does not the DS18B20 affect the sampling rate used?
looks like bacaSKIN() is sampling some analog device. Is this the temperature sensor?
looks like bacaSKIN() is called within loop() and will be invoked every 8+ msec (hadn't seen the delay() before)
this doesn't seem to correspond to a sampling "period" of 750msec. so i'm confused
what I mean is, DS18B20 sensor with suhu float variable. bacaSKIN() is an analog sensor for skin temperature reading, not this bacaSKIN() sensor that I'm concerned about. It is my DS18B20 sensor that causes the reading delay to not match 10 ms, thus affecting the PPG Spo2 signal to be not realtime.
where is the DS18B20 sample being collected?
i don't see how the Timer is being used. I see it initialized, but i don't see what it does when it expires?
i'm not sure you code to controlling the sample and processing. even sampling every 10 msec isn't very fast, i don't see a need for a hardware timer
why structure the code as follows?
i'm guessing you may not be sampling every 750 msec
const unsigned long SamplePeriodMsec = 750;
unsigned long msec0;
void
loop ()
{
unsigned long msec = millis ();
// sample periodically
if (msec - msec0 >= SamplePeriod) {
collectAndProcessSample ();
}
// monitor serial interface
if (Serial.available () > 0) {
String command = Serial.readStringUntil ('\n');
processCommand (command);
}
}
I stored the DS18B20 sensor in the temperature float variable. then I have tried to use a timer as directed by the gpt chat claimed to interrupt the program to prioritize. However, the sample of 750ms I got from an article about the DS18B20 sensor. here is the link: DS18B20 Temperature Sensor Pinout, Specifications, Equivalents & Datasheet
chatGPT ?
please try to explain what you are trying to do?
trying to reverse engineer what you're trying to do from code wirtten by chatrgpt, not YOU, is going to be confusing and time consuming
this the code i get from chatgpt
#include <OneWire.h>
#include <DallasTemperature.h>
#include <TimerOne.h>
#define ONE_WIRE_BUS 2 // Pin data DS18B20
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
volatile float suhu = 0.0;
volatile bool readyToRead = false; // Flag untuk pengecekan data
void setup() {
Serial.begin(115200);
sensors.begin();
sensors.setResolution(12); // Resolusi 12-bit (750ms)
// Konfigurasi Timer Interrupt setiap 1 detik (1000000 microseconds)
Timer1.initialize(1000000);
Timer1.attachInterrupt(requestTemperature);
}
void loop() {
if (readyToRead) {
suhu = sensors.getTempCByIndex(0) * 1.1; // Ambil hasil konversi
readyToRead = false; // Reset flag
Serial.print("Suhu: ");
Serial.println(suhu);
}
}
// ISR: Meminta pembacaan suhu tanpa menunggu
void requestTemperature() {
if (!readyToRead) {
sensors.requestTemperatures(); // Mulai konversi suhu
readyToRead = true; // Tandai data sudah siap untuk dibaca di loop utama
}
}
i don't want to look at coe from chatgpt
please explain what you think that code is doing?
ChatGPT has very little idea what happens in the real world.
IIRC, the last time I used a DS18B20 (about 15 years ago), Istarted the conversion, and went off to do other stuff for a while, and read the (conversion complete status bit), temperature a bit later and only performed whatever was needed to be done then.
I didn’t sit twiddling my thumbs waiting for the temperature conversion to be completed..
From my program above, which I have tested the DS18B20 sensor with a resolution setting of 9 bits, the temperature output is -139 degrees. When I set it to 12 bits the results that come out on the serial monitor are slow even though the delay I set is 10ms. So, I just want the output of the DS18B20 sensor not to interfere with the speed of sending the AFE4490 sensor value issued on the serial monitor, because this causes the output of the AFE4490 sensor in the form of a PPG signal graph not real-time.
for these types of converters i thought it was common to start the conversion immediately after reading the sample.
if you wanted to periodically sample, would you delay reading/processing the sample until the sample period expired?
where does your code start the DS18B20 conversion?