Объединение двух кодов двух датчиков в одной программе
Я использую два датчика: датчик кожно-гальванической реакции и датчик сердечного ритма. Проблема в том, что когда я объединил оба кода, единственный вывод, который отображается, — это только частота пульса, которая находится на уровне A0. Если я запускаю их отдельно, оба кода работают отлично. У меня базовый опыт программирования, оба кода взяты из Интернета.
Вот коды:
#define BLYNK_PRINT Serial
#include <ESP8266_Lib.h>
#include <BlynkSimpleShieldEsp8266.h>
#include <SoftwareSerial.h>
SoftwareSerial EspSerial(2, 3); // RX, TX
#define samp_siz 4
#define rise_threshold 4
// Your ESP8266 baud rate:
#define ESP8266_BAUD 9600
char auth[] = "ba4e5bd1bd9549669a02ac378db9faf6";
char ssid[] = "vivo";
char pass[] = "takoyaki";
/*char auth[] = "b3f01a592b78471f9f720b09d2ff8047";
char ssid[] = "vivo";
char pass[] = "takoyaki";
*/
ESP8266 wifi(&EspSerial);
BLYNK_CONNECTED()
{
Blynk.syncAll();
}
BlynkTimer timer;
// Pulse Monitor Test Script
void setup() {
Serial.begin(9600);
// Set ESP8266 baud rate
EspSerial.begin(ESP8266_BAUD);
delay(10);
Blynk.begin(auth, wifi, ssid, pass);
pinMode(A0, INPUT);
pinMode(A1, INPUT);
//timer.setInterval(1000L, myTimerEvent); //send the arduino's uptime
timer.setInterval(350L, sensor); //send gsr data every 0.35s
}
/*void myTimerEvent()
{
// You can send any value at any time.
// Please don't send more that 10 values per second.
Blynk.virtualWrite(V4, millis() / 1000);
}
*/
void sensor(){
const int GSR=A1;
int inputvalue=0;
int gsr_average=0;
long total=0;
for(int j=0;j<10;j++) //Average the 10 measurements to remove the glitch
{
inputvalue=analogRead(GSR);
total += inputvalue;
delay(5);
}
gsr_average = total/10;
Serial.println(gsr_average);
Blynk.virtualWrite(V6, gsr_average);
}
void heartrate ()
{
int sensorPin =A0;
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 heartrate;
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);
heartrate = print_value;
//Serial.print(print_value);
Serial.print(heartrate);
Serial.print('\n');
Blynk.virtualWrite(V7, heartrate);
third = second;
second = first;
}
}
else
{
// Ok, the curve is falling
rising = false;
rise_count = 0;
}
before = last;
ptr++;
ptr %= samp_siz;
}
}
void loop()
{
Blynk.run();
//timer.run();
sensor();
heartrate();
}
@tako, 👍0
Обсуждение1 ответ
Лучший ответ:
Я не тестировал следующий код, поэтому вам придется сделать это и обработать небольшие ошибки. Речь идет скорее о грубом способе изменения программы . И вам придется понимать, что на самом деле делает код, чтобы иметь возможность изменить его так, как вам нужно.
Сначала вам придется преобразовать некоторые переменные в функции heartrate()
в глобальные переменные (записав их в верхней части скетча вне любой функции), чтобы они сохраняли свое значение. значения между различными выполнениями функции. Я также изменил некоторые типы переменных, которые соответствуют типам присвоенных значений.
float reads[samp_siz], sum;
unsigned long now, start, ptr;
float last, before, reader;
unsigned long first, second, third;
bool rising;
int rise_count;
float print_value, heartrate;
unsigned long last_beat;
Вывод датчика должен быть #define
d в верхней части программы (по соглашению). Тогда вам следует поместить этот код:
for (int i = 0; i < samp_siz; i++)
reads[i] = 0;
sum = 0;
ptr = 0;
в функцию setup()
.
Теперь мы можем взглянуть на цикл while(1)
. В Arduino значение 0
рассматривается как логическое значение false
, а все остальные значения — как true
. Это то же самое, что писать while(true)
. Структура while()
выполняется до тех пор, пока выражение внутри скобок принимает значение true
. Поскольку здесь это всегда так, это будет повторяться вечно. На этом этапе вы можете просто стереть эту строку (и соответствующую закрывающую скобку ).
После этих изменений функция выполнит только одно чтение (в среднем более 20 мс), затем проверит, было ли обнаружено тактовое сообщение, и, наконец, выполнит выход из функции loop()
. Поскольку не каждое чтение является тактовым сигналом, вы получите больше выходных данных от функции sensor()
(которая выводит данные при каждом выполнении), чем от функции heartbeat()
. И теперь, поскольку ваши функции неблокируются, вы получите очень быстрый результат. Возможно, вы захотите замедлить этот процесс, используя функцию delay()
или (лучше) функцию millis()
(как в примере с BlinkWithoutDelay
). из Arduino IDE).
Обратите внимание, что этот код демонстрирует некоторые плохие стили написания. В сети можно найти как много хорошего кода, так и много плохого кода. Я вижу неправильные типы переменных, использование совершенно ненужных переменных и использование функции millis()
, которая не обрабатывает ролловер. Это не значит, что код не работает. Но с их помощью можно получить странные и трудные для отладки ошибки.
- (Код ультразвукового датчика: такого файла или каталога нет)
- Несколько неблокирующих таймеров обратного отсчета?
- Датчик HC-SR505 PIR выдает только HIGH уровень
- Отправка данных из ESP8266 в PHP
- Определение уровня заряда с помощью датчика тока (ACS758) с arduino uno
- Использование YS-IRTM с Arduino Uno
- Как объединить два разных скетча датчика в один полный скетч?
- Как использовать фотодиод для arduino?
Если вам нужны коды без команды blynk, просто сообщите мне в разделе комментариев., @tako
функция
heartrate()
имеет бесконечный цикл, поэтому Uno застревает там, @chrislпоэтому я не могу использовать код как функцию? как мне нужно его отредактировать?, @tako
Проблема заключается в цикле while(1). Перепишите функцию так, чтобы она считывала данные, что-то с ними делала, а затем выходила в основной цикл, чтобы сделать что-то еще., @chrisl
Поскольку код записывает последние измерения, вам придется сделать эти переменные статическими или глобальными, чтобы они сохраняли свое значение между различными выполнениями функции. И кстати: переменная
start
должна бытьunsigned long
, поскольку именно этот тип возвращает функцияmillis()
. То же самое касается переменной «сейчас»., @chrislБольшое вам спасибо за вашу помощь. Я действительно ценю это, сэр. Я скоро внесу правки, и если у меня возникнут вопросы, я буду здесь снова., @tako
Можете ли вы объяснить немного больше об этом цикле while(1)? я так потерян, @tako
while(1){ ... }
— это бесконечный цикл, он никогда не завершается, поэтомуheartrate()
никогда не может завершиться и вернуться в цикл. Он просто сидит там и снимает показания — навсегда. Попробуйте вызвать только один из датчиков(), пока он не заработает. Затем попробуйте вызвать только другой, пока _он_ тоже не заработает. Как только каждый из них заработает правильно, только тогда попробуйте позвонить им обоим. Это классический метод отладки по принципу «разделяй и властвуй»., @JRobertЯ выполнил советы, подобные тем, что вы предлагали, и вызывал эти датчики один за другим, и все работает отлично. Какая структура управления мне больше всего подходит для замены while(1)?, @tako