Нет соответствующей функции для вызова SoftwareSerial::SoftwareSerial(int&,int&)? Как исправить эту проблему
#include <LiquidCrystal.h>
#include <SoftwareSerial.h>
float pulse = 0;
float temp = 0;
SoftwareSerial ser(9,10);
String apiKey = "U5AGYVQT5JRJPSDR";
// Переменные
int pulsePin = A0; // Фиолетовый провод датчика пульса, подключенный к аналоговому контакту 0
int blinkPin = 7 ; // вывод для мигания светодиода при каждом ударе
int fadePin = 8; // вывод для причудливого классического затухания, мигающего на каждом такте
int fadeRate = 0; // используется для постепенного включения светодиода с помощью ШИМ на fadePin
LiquidCrystal lcd(13, 12, 6, 5, 4, 3);
// Изменчивые переменные, используемые в подпрограмме обслуживания прерывания!
volatile int BPM; // целое число, которое содержит необработанный аналог в 0. обновляется каждые 2 мс
volatile int Signal; // содержит входящие необработанные данные
volatile int IBI = 600; // int, который содержит временной интервал между ударами! Сеять надо!
volatile boolean Pulse = false; // «Истинно», когда обнаружено живое сердцебиение пользователя. «Ложь», когда нет
a "live beat".
volatile boolean QS = false; // становится истинным, когда Arduoino находит бит.
// С уважением, Serial OutPut -- Настройте это в соответствии с вашими потребностями
static boolean serialVisual = true; // По умолчанию установлено значение «false». Снова установите «true», чтобы увидеть Arduino
Serial Monitor ASCII Visual Pulse
volatile int rate[10]; // массив для хранения последних десяти значений IBI
volatile unsigned long sampleCounter = 0; // используется для определения времени импульса
volatile unsigned long lastBeatTime = 0; // используется для поиска IBI
volatile int P = 512; // используется для нахождения пика в пульсовой волне, с затравкой
volatile int T = 512; // используется для поиска впадины в пульсовой волне, засеянной
volatile int thresh = 525; // используется для нахождения мгновенного момента сердцебиения, засеяно
volatile int amp = 100; // используется для хранения амплитуды импульсного сигнала, заполненного
volatile boolean firstBeat = true; // используется для заполнения массива скорости, поэтому мы запускаем с разумным BPM
volatile boolean secondBeat = false; // используется для заполнения массива скорости, поэтому мы запускаем с разумным BPM
void setup()
{
lcd.begin(16, 2);
pinMode(blinkPin,OUTPUT); // вывод, который будет мигать в такт вашему сердцу!
pinMode(fadePin,OUTPUT); // вывод, который будет исчезать в такт вашему сердцу!
Serial.begin(115200); // мы согласны говорить быстро!
interruptSetup(); // настраивает чтение сигнала датчика пульса каждые 2 мс
// ЕСЛИ ВЫ ПОДАЕТЕ ПИТАНИЕ НА ДАТЧИК ИМПУЛЬСОВ ПРИ НАПРЯЖЕНИИ МЕНЬШЕ, ЧЕМ НАПРЯЖЕНИЕ НА ПЛАТЕ,
// ОТКОММЕНТИРУЕМ СЛЕДУЮЩУЮ СТРОКУ И ПОДАЕМ ЭТО НАПРЯЖЕНИЕ НА ВЫВОД A-REF
// аналоговая ссылка (ВНЕШНЯЯ);
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Engineers Garage");
ser.begin(9600);
ser.println("AT");
delay(1000);
ser.println("AT+GMR");
delay(1000);
ser.println("AT+CWMODE=3");
delay(1000);
ser.println("AT+RST");
delay(5000);
ser.println("AT+CIPMUX=1");
delay(1000);
String cmd="AT+CWJAP="EngineersGarage","egP@$$w0rd?"";
ser.println(cmd);
delay(1000);
ser.println("AT+CIFSR");
delay(1000);
}
// Где происходят чудеса
void loop()
{
serialOutput();
if (QS == true) // Было найдено сердцебиение
{
// BPM и IBI определены
// Quantified Self "QS" true, когда arduino находит сердцебиение
fadeRate = 255; // Создает эффект затухания светодиода, установите для переменной 'fadeRate' значение 255, чтобы светодиод исчез
with pulse
serialOutputWhenBeatHappens(); // Случился бит, выведите его в последовательный порт.
QS = false; // сброс флага Quantified Self для следующего раза
}
ledFadeToBeat(); // Создает эффект затухания светодиода
delay(20); // сделать перерыв
read_temp();
esp_8266();
}
void ledFadeToBeat()
{
fadeRate -= 15; // устанавливаем значение затухания светодиода
fadeRate = constrain(fadeRate,0,255); // чтобы значение затухания светодиода не стало отрицательным!
analogWrite(fadePin,fadeRate); // гаснет светодиод
}
void interruptSetup()
{
// Инициализирует Timer2 для создания прерывания каждые 2 мс.
TCCR2A = 0x02; // ОТКЛЮЧИТЬ ШИМ НА ЦИФРОВЫХ ВЫВОДАХ 3 И 11 И ПЕРЕХОДИТЬ В РЕЖИМ CTC
TCCR2B = 0x06; // НЕ ПРИНИМАТЬ СРАВНЕНИЕ, 256 PRESCALER
OCR2A = 0X7C; // УСТАНОВИМ НАЧАЛЬНУЮ ЧАСТЬ СЧЁТЧИКА НА 124 ДЛЯ ЧАСТОТЫ ВЫБОРКИ 500 Гц
TIMSK2 = 0x02; // ВКЛЮЧАЕМ ПРЕРЫВАНИЕ ПРИ СОВПАДЕНИИ МЕЖДУ TIMER2 И OCR2A
sei(); // УБЕДИТЕСЬ, ЧТО ГЛОБАЛЬНЫЕ ПРЕРЫВАНИЯ РАЗРЕШЕНЫ
}
void serialOutput()
{ // Решаем, как выводить серийный номер.
if (serialVisual == true)
{
arduinoSerialMonitorVisual('-', Signal); // переходит к функции, которая делает Serial Monitor Visualizer
}
else
{
sendDataToSerial('S', Signal); // переходит к функции sendDataToSerial
}
}
void serialOutputWhenBeatHappens()
{
if (serialVisual == true) // Код для работы визуализатора последовательного монитора
{
Serial.print("*** Heart-Beat Happened *** "); // Безумие искусства ASCII
Serial.print("BPM: ");
Serial.println(BPM);
lcd.clear();
lcd.print("BPM: ");
lcd.print(BPM);
}
else
{
sendDataToSerial('B',BPM); // отправляем частоту сердечных сокращений с префиксом «B»
sendDataToSerial('Q',IBI); // отправляем время между ударами с префиксом 'Q'
}
}
void arduinoSerialMonitorVisual(char symbol, int data )
{
const int sensorMin = 0; // минимум сенсора, обнаруженный экспериментально
const int sensorMax = 1024; // максимум сенсора, обнаруженный экспериментально
int sensorReading = data; // сопоставляем диапазон датчика с диапазоном из 12 вариантов:
int range = map(sensorReading, sensorMin, sensorMax, 0, 11);
// делаем что-то другое в зависимости от
// значение диапазона:
switch (range)
{
case 0:
Serial.println(""); /////Безумие искусства ASCII
break;
case 1:
Serial.println("---");
break;
case 2:
Serial.println("------");
break;
case 3:
Serial.println("---------");
break;
case 4:
Serial.println("------------");
break;
case 5:
Serial.println("--------------|-");
break;
case 6:
Serial.println("--------------|---");
break;
case 7:
Serial.println("--------------|-------");
break;
case 8:
Serial.println("--------------|----------");
break;
case 9:
Serial.println("--------------|----------------");
break;
case 10:
Serial.println("--------------|-------------------");
break;
case 11:
Serial.println("--------------|-----------------------");
break;
}
}
void sendDataToSerial(char symbol, int data )
{
Serial.print(symbol);
Serial.println(data);
}
ISR(TIMER2_COMPA_vect) // срабатывает, когда Timer2 считает до 124
{
cli(); // отключаем прерывания, пока делаем это
Signal = analogRead(pulsePin); // чтение датчика пульса
sampleCounter += 2; // отслеживать время в миллисекундах с помощью этой переменной
int N = sampleCounter - lastBeatTime; // отслеживаем время с момента последнего удара, чтобы избежать шума
// найти пик и впадину пульсовой волны
if(Signal < thresh && N > (IBI/5)*3) // избегаем дихротического шума, ожидая 3/5 последнего IBI
{
if (Signal < T) // T - впадина
{
T = Signal; // отслеживаем самую низкую точку пульсовой волны
}
}
if(Signal > thresh && Signal > P)
{ // условие thresh помогает избежать шума
P = Signal; // P — пик
} // отслеживаем наивысшую точку пульсовой волны
// ТЕПЕРЬ ПРИШЛО ВРЕМЯ УЗНАТЬ БИЕНИЕ СЕРДЦА
// значение сигнала возрастает каждый раз, когда есть импульс
if (N > 250)
{ // избегаем высокочастотного шума
if ( (Signal > thresh) && (Pulse == false) && (N > (IBI/5)*3) )
{
Pulse = true; // устанавливаем флаг Pulse, когда мы думаем, что есть пульс
digitalWrite(blinkPin,HIGH); // включить светодиод на контакте 13
IBI = sampleCounter - lastBeatTime; // измеряем время между ударами в мс
lastBeatTime = sampleCounter; // отслеживать время следующего импульса
if(secondBeat)
{ // если это вторая доля, if secondBeat == TRUE
secondBeat = false; // очистить флаг secondBeat
for(int i=0; i<=9; i++) // начальное значение промежуточной суммы для получения реалистичного BPM при запуске
{
rate[i] = IBI;
}
}
if(firstBeat) // если бит найден впервые, if firstBeat == TRUE
{
firstBeat = false; // очистить флаг firstBeat
secondBeat = true; // устанавливаем второй флаг долей
sei(); // снова разрешаем прерывания
return; // Значение IBI ненадежно, поэтому отбрасываем его
}
// сохраняем промежуточный итог последних 10 значений IBI
word runningTotal = 0; // очищаем переменную runningTotal
for(int i=0; i<=8; i++)
{ // сдвигаем данные в массиве ставок
rate[i] = rate[i+1]; // и удалить самое старое значение IBI
runningTotal += rate[i]; // суммируем 9 самых старых значений IBI
}
rate[9] = IBI; // добавляем последний IBI в массив ставок
runningTotal += rate[9]; // добавить последний IBI в runningTotal
runningTotal /= 10; // среднее значение последних 10 значений IBI
BPM = 60000/runningTotal; // сколько ударов может уместиться в минуту? это БПМ!
QS = true; // установить флаг Quantified Self
// ФЛАГ QS НЕ СНЯТ ВНУТРИ ЭТОЙ ISR
pulse = BPM;
}
}
if (Signal < thresh && Pulse == true)
{ // когда значения уменьшаются, бит закончен
digitalWrite(blinkPin,LOW); // выключаем светодиод на контакте 13
Pulse = false; // сбрасываем флаг Pulse, чтобы мы могли сделать это снова
amp = P - T; // получаем амплитуду пульсовой волны
thresh = amp/2 + T; // устанавливаем порог на 50% от амплитуды
P = thresh; // сбросить их для следующего раза
T = thresh;
}
if (N > 2500)
{ // если 2,5 секунды проходят без такта
thresh = 512; // устанавливаем порог по умолчанию
P = 512; // установить P по умолчанию
T = 512; // устанавливаем Т по умолчанию
lastBeatTime = sampleCounter; // обновить lastBeatTime
firstBeat = true; // установите их, чтобы избежать шума
secondBeat = false; // когда мы получим сердцебиение
}
sei(); // разрешить прерывания, когда закончите!
}// конец isr
void esp_8266()
{
// TCP-соединение AT+CIPSTART=4,"TCP","184.106.153.149",80
String cmd = "AT+CIPSTART=4,"TCP","";
cmd += "184.106.153.149"; // api.thingspeak.com
cmd += "",80";
ser.println(cmd);
Serial.println(cmd);
if(ser.find("Error"))
{
Serial.println("AT+CIPSTART error");
return;
}
// подготовить строку GET GET https://api.thingspeak.com/update?api_key=LHAG4NSIYJ5UWS6U&field1=0rnrn
String getStr = "GET /update?api_key=";
getStr += apiKey;
getStr +="&field1=";
getStr +=String(temp);
getStr +="&field2=";
getStr +=String(pulse);
getStr += "rnrn";
// отправляем длину данных
cmd = "AT+CIPSEND=4,";
cmd += String(getStr.length());
ser.println(cmd);
Serial.println(cmd);
delay(1000);
ser.print(getStr);
Serial.println(getStr);
//thingspeak требует 15-секундной задержки между обновлениями
delay(3000);
}
void read_temp()
{
int temp_val = analogRead(A1);
float mv = (temp_val/1024.0)*5000;
float cel = mv/10;
temp = (cel*9)/5 + 32;
}
@user60819, 👍0
Обсуждение1 ответ
▲ 2
Скетч в вопросе не для NodeMCU. Это для Arduino с esp8266, подключенным к контактам 9 и 10. Но ошибка в заголовке является текущей ошибкой для пакета плат esp8266 Arduino 2.6.0. EspSoftwareSerial, входящий в состав пакета плат Arduino esp8266 версии 2.6.0, содержит изменение, нарушающее совместимость.
О проблеме было немедленно сообщено, и сопровождающий EspSoftwareSerial добавил устаревший API обратно в EspSoftwareSerial. Исправленная версия будет доступна с пакетом плат esp8266 2.6.1, который будет доступен в ближайшее время из-за многочисленных проблем с 2.6.0.
,
@Juraj
2.6.1 выпущен, @Juraj
Смотрите также:
- AT-команда не отвечает на последовательный монитор
- Получить данные с сайта с помощью ESP8266 с помощью AT-команд
- Программное обеспечениеSerial с ESP8266
- Как связаться с ESP8266 ESP01, отправив данные через программный сериал на Arduino Uno?
- Отправить строку данных из Arduino UNO в ESP8266-01
- Последовательная связь arduino mega и D1 Wemos Mini
- Последовательная связь от Arduino до ESP8266 NodeMCU работает, но от NodeMCU до Arduino не работает
- Программный последовательный конфликт с Wi-Fi на ESP8266
Выровняйте свой код (выделите и нажмите ctrl-k), а также сделайте минимальный скетч, который показывает программу., @Michel Keijzers
Извините, не могли бы вы кратко изложить это ясно?, @user60819
Теперь я вижу, что код уже выровнен (если вы этого не сделали, это сделал кто-то другой), @Michel Keijzers
Я не вижу ничего неправильного в объявлении SoftwareSerial… можете ли вы перепроверить, используете ли вы правильную библиотеку? Проверьте конструктор класса SoftwareSerial, который вы используете., @Michel Keijzers
ты на esp8266. они изменили конструктор и переместили параметры в метод begin(), @Juraj
Я просто скопировал код из Интернета. Должен ли я добавить какую-либо другую функцию или заголовочный файл к этому коду?, @user60819
да, я использую esp8266, можете ли вы объяснить, что я должен изменить в этом коде?, @user60819
мы можем использовать этот код для модуля wifi nodemcu?, @user60819
скетч не для NodeMCU. это для Uno с esp8266, подключенным к контактам 9 и 10, @Juraj