Compile error Arduino: include expects "FILENAME OR <FILENAME>

I am trying to use this code but the notation is giving me issues. I keep getting the compile error that this title is named after. I think it might be the use of && &lt, &gt. Can these be substituted for something?

#include &lt;MAX3010x.h&gt;
#include "filters.h"
#include &lt;LiquidCrystal.h&gt;
 
 
// Sensor (adjust to your sensor type)
MAX30105 sensor;
// set a sampling rate
const auto kSamplingRate = sensor.SAMPLING_RATE_400SPS;
// set a sampling frequency
const float kSamplingFrequency = 400.0;
 
// set a Finger Detection Threshold and Cooldown
const unsigned long kFingerThreshold = 10000;
const unsigned int kFingerCooldownMs = 500;
 
// set an Edge Detection Threshold
const float kEdgeThreshold = -2000.0;
 
// Filters
const float kLowPassCutoff = 5.0;
const float kHighPassCutoff = 0.5;
 
// Averaging
const bool kEnableAveraging = true;
const int kAveragingSamples = 50;
const int kSampleThreshold = 5;
 
// for LCD, set the pins connected to display
// here its will be pins 7,8,9,10,11,12
LiquidCrystal lcd(7, 8, 9, 10, 11, 12);
 
 
 
void setup() {
  Serial.begin(9600);
  lcd.begin(16, 2);
 
// set if else condition to display on serial monitor whether sensor is working or not
  if(sensor.begin() &amp;&amp; sensor.setSamplingRate(kSamplingRate)) { 
    // if the sensor detects pulse, print the following message on LCD display
    lcd.print("Hello from CityBeat");
  }
  // if the sensor is not initialized, print the following on LCD
  else {
    Serial.println("Sensor not found");  
    while(1);
  }
 
 
}
 
// Filter Instances
HighPassFilter high_pass_filter(kHighPassCutoff, kSamplingFrequency);
LowPassFilter low_pass_filter(kLowPassCutoff, kSamplingFrequency);
Differentiator differentiator(kSamplingFrequency);
MovingAverageFilter&lt;kAveragingSamples&gt; averager;
 
// Timestamp of the last heartbeat
long last_heartbeat = 0;
 
// Timestamp for finger detection
long finger_timestamp = 0;
bool finger_detected = false;
 
// Last diff to detect zero crossing
float last_diff = NAN;
bool crossed = false;
long crossed_time = 0;
 
 
 
void loop() {
  // read sample on sensor every 1000 milliseconds
  auto sample = sensor.readSample(1000);
  float current_value = sample.red;
  
  // Detect Finger using raw sensor value
  if(sample.red &gt; kFingerThreshold) {
    if(millis() - finger_timestamp &gt; kFingerCooldownMs) {
      finger_detected = true;
    }
  }
  else {
    // Reset values if the finger is removed
    differentiator.reset();
    averager.reset();
    low_pass_filter.reset();
    high_pass_filter.reset();
    
    finger_detected = false;
    finger_timestamp = millis();
  }
 
  if(finger_detected) {
    current_value = low_pass_filter.process(current_value);
    current_value = high_pass_filter.process(current_value);
    float current_diff = differentiator.process(current_value);
 
    // Valid values?
    if(!isnan(current_diff) &amp;&amp; !isnan(last_diff)) {
      
      // Detect Heartbeat - Zero-Crossing
      if(last_diff &gt; 0 &amp;&amp; current_diff &lt; 0) {
        crossed = true;
        crossed_time = millis();
      }
      
      if(current_diff &gt; 0) {
        crossed = false;
      }
  
      // Detect Heartbeat - Falling Edge Threshold
      if(crossed &amp;&amp; current_diff &lt; kEdgeThreshold) {
        if(last_heartbeat != 0 &amp;&amp; crossed_time - last_heartbeat &gt; 300) {
          // Show Results
          int bpm = 60000/(crossed_time - last_heartbeat);
          if(bpm &gt; 50 &amp;&amp; bpm &lt; 250) {
            // Average?
            if(kEnableAveraging) {
              int average_bpm = averager.process(bpm);
  
              // Show if enough samples have been collected
              if(averager.count() &gt; kSampleThreshold) {
                // first print output of average heartrate on serial monitor
                Serial.print("Heart Rate (avg, bpm): ");
                Serial.println(average_bpm);
                // then print output of average heartrate on LCD display
                lcd.clear();
                lcd.print("avg Rate: ");
                lcd.print(average_bpm);
                lcd.print("bpm");                
              }
            }
            else {
              // otherwise print output of heartrate on serial monitor
              Serial.print("Heart Rate (current, bpm): ");
              Serial.println(bpm); 
              // otherwise print output of heartrate on LCD Display
              lcd.clear(); 
              lcd.print(" rate: ");
             lcd.println(bpm);
            }
          }
        }
  
        crossed = false;
        last_heartbeat = crossed_time;
      }
    }
 
    last_diff = current_diff;
  }
 
  
}

looks like you copied the code from a word processor
try

#include <MAX3010x.h>
#include "filters.h"
#include <LiquidCrystal.h>
1 Like

You got the characters encoded as HTML entities. You need to decode them.

  • &lt; -> <
  • &gt; -> >
  • &amp; -> &

I have not checked if there are more. For a list take a look here: Entity - MDN Web Docs Glossary: Definitions of Web-related terms | MDN

1 Like

Ok thank you guys that helped a lot. The formatting of this file is affecting other lines of code. These line (and similar ones) gives me the error "'HighPassFilter' does not name a type; did you mean 'kHighPassCutoff'?" Do these also need to be decoded?

HighPassFilter high_pass_filter(kHighPassCutoff, kSamplingFrequency);

Please post your file 'filters.h' (and other possibly related files).

Which board are you compiling for?

Arduino UNO. I am not sure what you are asking me to post.

You include a file "filters.h". In this file HighPassFilter should be defined. This file should be located in the folder of your sketch.

Ok I decoded it and found filters.h from an example.

#ifndef FILTERS_H
#define FILTERS_H

/**
 * @brief Statistic block for min/nax/avg
 */
class MinMaxAvgStatistic {
  float min_;
  float max_;
  float sum_;
  int count_;
public:
  /**
   * @brief Initialize the Statistic block
   */
  MinMaxAvgStatistic() :
    min_(NAN),
    max_(NAN),
    sum_(0),
    count_(0){}

  /**
   * @brief Add value to the statistic
   */
  void process(float value) {  
    min_ = isnan(min_) ? value : min(min_, value);
    max_ = isnan(max_) ? value : max(max_, value);
    sum_ += value;
    count_++;
  }

  /**
   * @brief Resets the stored values
   */
  void reset() {
    min_ = NAN;
    max_ = NAN;
    sum_ = 0;
    count_ = 0;
  }

  /**
   * @brief Get Minimum
   * @return Minimum Value
   */
  float minimum() const {
    return min_;
  }

  /**
   * @brief Get Maximum
   * @return Maximum Value
   */
  float maximum() const {
    return max_;
  }

  /**
   * @brief Get Average
   * @return Average Value
   */
  float average() const {
    return sum_/count_;
  }
};

/**
 * @brief High Pass Filter 
 */
class HighPassFilter {
  const float kX;
  const float kA0;
  const float kA1;
  const float kB1;
  float last_filter_value_;
  float last_raw_value_;
public:
  /**
   * @brief Initialize the High Pass Filter
   * @param samples Number of samples until decay to 36.8 %
   * @remark Sample number is an RC time-constant equivalent
   */
  HighPassFilter(float samples) :
    kX(exp(-1/samples)),
    kA0((1+kX)/2),
    kA1(-kA0),
    kB1(kX),
    last_filter_value_(NAN),
    last_raw_value_(NAN){}

  /**
   * @brief Initialize the High Pass Filter
   * @param cutoff Cutoff frequency
   * @pram sampling_frequency Sampling frequency
   */
  HighPassFilter(float cutoff, float sampling_frequency) :
    HighPassFilter(sampling_frequency/(cutoff*2*PI)){}

  /**
   * @brief Applies the high pass filter
   */
  float process(float value) { 
    if(isnan(last_filter_value_) || isnan(last_raw_value_)) {
      last_filter_value_ = 0.0;
    }
    else {
      last_filter_value_ = 
        kA0 * value 
        + kA1 * last_raw_value_ 
        + kB1 * last_filter_value_;
    }
    
    last_raw_value_ = value;
    return last_filter_value_;
  }

  /**
   * @brief Resets the stored values
   */
  void reset() {
    last_raw_value_ = NAN;
    last_filter_value_ = NAN;
  }
};

/**
 * @brief Low Pass Filter 
 */
class LowPassFilter {
  const float kX;
  const float kA0;
  const float kB1;
  float last_value_;
public:
  /**
   * @brief Initialize the Low Pass Filter
   * @param samples Number of samples until decay to 36.8 %
   * @remark Sample number is an RC time-constant equivalent
   */
  LowPassFilter(float samples) :
    kX(exp(-1/samples)),
    kA0(1-kX),
    kB1(kX),
    last_value_(NAN){}

  /**
   * @brief Initialize the Low Pass Filter
   * @param cutoff Cutoff frequency
   * @pram sampling_frequency Sampling frequency
   */
  LowPassFilter(float cutoff, float sampling_frequency) :
    LowPassFilter(sampling_frequency/(cutoff*2*PI)){}

  /**
   * @brief Applies the low pass filter
   */
  float process(float value) {  
    if(isnan(last_value_)) {
      last_value_ = value;
    }
    else {  
      last_value_ = kA0 * value + kB1 * last_value_;
    }
    return last_value_;
  }

  /**
   * @brief Resets the stored values
   */
  void reset() {
    last_value_ = NAN;
  }
};

/**
 * @brief Differentiator
 */
class Differentiator {
  const float kSamplingFrequency;
  float last_value_;
public:
  /**
   * @brief Initializes the differentiator
   */
  Differentiator(float sampling_frequency) :
    kSamplingFrequency(sampling_frequency),
    last_value_(NAN){}

  /**
   * @brief Applies the differentiator
   */
  float process(float value) {  
      float diff = (value-last_value_)*kSamplingFrequency;
      last_value_ = value;
      return diff;
  }

  /**
   * @brief Resets the stored values
   */
  void reset() {
    last_value_ = NAN;
  }
};

/**
 * @brief MovingAverageFilter
 * @tparam buffer_size Number of samples to average over
 */
template<int kBufferSize> class MovingAverageFilter {
  int index_;
  int count_;
  float values_[kBufferSize];
public:
  /**
   * @brief Initalize moving average filter
   */
  MovingAverageFilter() :
    index_(0),
    count_(0){}

  /**
   * @brief Applies the moving average filter
   */
  float process(float value) {  
      // Add value
      values_[index_] = value;

      // Increase index and count
      index_ = (index_ + 1) % kBufferSize;
      if(count_ < kBufferSize) {
        count_++;  
      }

      // Calculate sum
      float sum = 0.0;
      for(int i = 0; i < count_; i++) {
          sum += values_[i];
      }

      // Calculate average
      return sum/count_;
  }

  /**
   * @brief Resets the stored values
   */
  void reset() {
    index_ = 0;
    count_ = 0;
  }

  /**
   * @brief Get number of samples
   * @return Number of stored samples
   */
  int count() const {
    return count_;
  }
};

#endif // FILTERS_H

There is the HighPassFilter.

Does it compile when the filters.h is in the same directory as the .ino?

yes, this does compile now. thank you for all of the help

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.