Нет соответствующей функции для вызова 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;

}

, 👍0

Обсуждение

Выровняйте свой код (выделите и нажмите 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


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.

,

2.6.1 выпущен, @Juraj