Average.h library malfunction

Hey there,

Moderator edit: diatribe removed

(just saying i´m a complete beginnner so forgive me any mistakes i will try as hard as i can to fulfill forum regulation, etc.)

so my problem:
i donwloaded the "Average.h" library from Github and tried a GPS example for navigating a boat to specific waypoints (The Arduino IDE shows the library as installed so that´s not the problem).

When compiling the sketch to the Arduino Uno it shows the error: 'mean' was not declared in this scope

i have no idea what the problem is and i hope you can help me

thanks a lot,

Gus

Hello there!

Can you post the code you are using, as well as a picture of the error message(s) you are getting?

When compiling the sketch to the Arduino Uno it shows the error: 'mean' was not declared in this scope

The sketch you didn't post?

The error message includes a lot more information than that.

bos1714:
Hello there!

Can you post the code you are using, as well as a picture of the error message(s) you are getting?

DO NOT POST PICTURES OF TEXT.

If you want a simple moving average (i.e. Finite Impulse Respones), take a look at the RunningAverage example on the playground.

If you want an exponential moving average (which is better in many cases), you can use this:

[color=#95a5a6]/*[/color]
[color=#95a5a6]   Exponential Moving Average filter (single-pole IIR filter)[/color]

[color=#95a5a6]   Difference equation:[/color]
[color=#95a5a6]       y[n] = k*x[n] + (1-k)*y[n-1][/color]

[color=#95a5a6]     where y[n] is the filtered output at time n,[/color]
[color=#95a5a6]     and x[n] the raw input at time n[/color]
[color=#95a5a6]     y[n-1] is the previous filtered output.[/color]

[color=#95a5a6]   k == 0.5^shiftFac[/color]

[color=#95a5a6]   Fixed point arithmetic is used for speed.[/color]
[color=#95a5a6]     1 == 1 << (2*shiftFac)[/color]
[color=#95a5a6]   Two times shiftFac because otherwise, precision[/color]
[color=#95a5a6]   would be lost when shifting (value - filtered).[/color]

[color=#95a5a6]   Rounding is performed by adding 0.5 to the[/color]
[color=#95a5a6]   fixed point representation before converting[/color]
[color=#95a5a6]   to an integer.[/color]
[color=#95a5a6]     0.5 == 1 << (2*shiftFac - 1)[/color]
[color=#95a5a6]*/[/color]
[color=#00979c]class[/color] [color=#000000]EMA[/color] [color=#000000]{[/color]
  [color=#00979c]public[/color][color=#434f54]:[/color]
    [color=#95a5a6]/* Constructor: Initialize constants */[/color]
    [color=#000000]EMA[/color][color=#000000]([/color][color=#00979c]uint8_t[/color] [color=#000000]shiftFac[/color][color=#000000])[/color]
      [color=#434f54]:[/color] [color=#000000]shiftFac[/color][color=#000000]([/color][color=#000000]shiftFac[/color][color=#000000])[/color][color=#434f54],[/color] [color=#000000]fixedPointAHalf[/color][color=#000000]([/color][color=#000000]1[/color] [color=#434f54]<<[/color] [color=#000000]([/color][color=#000000]([/color][color=#000000]shiftFac[/color] [color=#434f54]*[/color] [color=#000000]2[/color][color=#000000])[/color] [color=#434f54]-[/color] [color=#000000]1[/color][color=#000000])[/color][color=#000000])[/color] [color=#000000]{[/color][color=#000000]}[/color]

    [color=#95a5a6]/* Filter a new raw input value x[n] and return the filtered output y[n].[/color]
[color=#95a5a6]       Should be called at regular intervals for best results. */[/color]
    [color=#00979c]int32_t[/color] [color=#d35400]filter[/color][color=#000000]([/color][color=#00979c]int32_t[/color] [color=#000000]value[/color][color=#000000])[/color] [color=#000000]{[/color]
      [color=#000000]value[/color] [color=#434f54]=[/color] [color=#000000]value[/color] [color=#434f54]<<[/color] [color=#000000]([/color][color=#000000]shiftFac[/color] [color=#434f54]*[/color] [color=#000000]2[/color][color=#000000])[/color][color=#000000];[/color]
      [color=#000000]filtered[/color] [color=#434f54]=[/color] [color=#000000]filtered[/color] [color=#434f54]+[/color] [color=#000000]([/color][color=#000000]([/color][color=#000000]value[/color] [color=#434f54]-[/color] [color=#000000]filtered[/color][color=#000000])[/color] [color=#434f54]>>[/color] [color=#000000]shiftFac[/color][color=#000000])[/color][color=#000000];[/color]
      [color=#5e6d03]return[/color] [color=#000000]([/color][color=#000000]filtered[/color] [color=#434f54]+[/color] [color=#000000]fixedPointAHalf[/color][color=#000000])[/color] [color=#434f54]>>[/color] [color=#000000]([/color][color=#000000]shiftFac[/color] [color=#434f54]*[/color] [color=#000000]2[/color][color=#000000])[/color][color=#000000];[/color]
    [color=#000000]}[/color]

  [color=#00979c]private[/color][color=#434f54]:[/color]
    [color=#95a5a6]/* Member variables */[/color]
    [color=#00979c]const[/color] [color=#00979c]uint8_t[/color] [color=#000000]shiftFac[/color][color=#000000];[/color]
    [color=#00979c]const[/color] [color=#00979c]int32_t[/color] [color=#000000]fixedPointAHalf[/color][color=#000000];[/color]
    [color=#00979c]int32_t[/color] [color=#000000]filtered[/color] [color=#434f54]=[/color] [color=#000000]0[/color][color=#000000];[/color]
[color=#000000]}[/color][color=#000000];[/color]

[color=#000000]EMA[/color] [color=#000000]ema[/color][color=#000000]([/color][color=#000000]4[/color][color=#000000])[/color][color=#000000];[/color] [color=#434f54]// k = 0.5^4 = 0.0625[/color]

[color=#00979c]const[/color] [color=#00979c]unsigned[/color] [color=#00979c]long[/color] [color=#d35400]interval[/color] [color=#434f54]=[/color] [color=#000000]10000[/color][color=#000000];[/color] [color=#434f54]// sample every 10 milliseconds[/color]

[color=#00979c]void[/color] [color=#000000]measureAndFilter[/color][color=#000000]([/color][color=#000000])[/color] [color=#000000]{[/color]
  [color=#00979c]int[/color] [color=#000000]x[/color] [color=#434f54]=[/color] [color=#d35400]analogRead[/color][color=#000000]([/color][color=#000000]A0[/color][color=#000000])[/color][color=#000000];[/color]
  [color=#00979c]int[/color] [color=#000000]y[/color] [color=#434f54]=[/color] [color=#000000]ema[/color][color=#434f54].[/color][color=#d35400]filter[/color][color=#000000]([/color][color=#000000]x[/color][color=#000000])[/color][color=#000000];[/color]
  [b][color=#d35400]Serial[/color][/b][color=#434f54].[/color][color=#d35400]println[/color][color=#000000]([/color][color=#000000]y[/color][color=#000000])[/color][color=#000000];[/color]  
[color=#000000]}[/color]

[color=#00979c]void[/color] [color=#5e6d03]setup[/color][color=#000000]([/color][color=#000000])[/color] [color=#000000]{[/color]
  [b][color=#d35400]Serial[/color][/b][color=#434f54].[/color][color=#d35400]begin[/color][color=#000000]([/color][color=#000000]115200[/color][color=#000000])[/color][color=#000000];[/color]
[color=#000000]}[/color]

[color=#00979c]void[/color] [color=#5e6d03]loop[/color][color=#000000]([/color][color=#000000])[/color] [color=#000000]{[/color]
  [color=#00979c]static[/color] [color=#00979c]unsigned[/color] [color=#00979c]long[/color] [color=#000000]previousMicros[/color] [color=#434f54]=[/color] [color=#d35400]micros[/color][color=#000000]([/color][color=#000000])[/color][color=#000000];[/color]
  [color=#5e6d03]if[/color] [color=#000000]([/color][color=#d35400]micros[/color][color=#000000]([/color][color=#000000])[/color] [color=#434f54]-[/color] [color=#000000]previousMicros[/color] [color=#434f54]>[/color] [color=#d35400]interval[/color][color=#000000])[/color] [color=#000000]{[/color] [color=#434f54]// sample at precise interval[/color]
    [color=#000000]measureAndFilter[/color][color=#000000]([/color][color=#000000])[/color][color=#000000];[/color]
    [color=#000000]previousMicros[/color] [color=#434f54]+=[/color] [color=#d35400]interval[/color][color=#000000];[/color]
  [color=#000000]}[/color]
[color=#000000]}[/color]

If you want help with the library you’re currently using, you’ll have to post all of your code and error messages, as well as a link to the library in question.

Pieter

oh wow thanks a lot!
i didnt expect that much response so fast.

so the library i used was this one: GitHub - MajenkoLibraries/Average: Templated class for calculating averages and statistics of data sets.

my code:

#include <Average.h>
#include <SoftwareSerial.h>
#include <PWMServo.h>
#include <Wire.h>
#include <HMC5883L.h>
#include "TinyGPS++.h"

int compassavg = 50;
PWMServo rudder;

int maxspeed = 40;
int waypointdist = 8;

int prevangle = 90;
int accuracy = 4;

int rudderspeed = 10;

int lock = 12;
int distance = 7;
int data = 5;

int gpsavg = 10;

int ruddertrim = -2;
int compasstrim = 180;

int ang = 0;

static int r = 6371;
const float Pi = 3.14159;

HMC5883L compass;
int error = 0;

TinyGPSPlus gps;

unsigned long startTime;
unsigned long otherTime;

SoftwareSerial ss(5, 4);

void setup() {
  Serial.begin(4800);
  rudder.attach(9);
  Wire.begin();
  compass = HMC5883L();
  error = compass.SetScale(0.88);
  error = compass.SetMeasurementMode(Measurement_Continuous);
  ss.begin(9600);      
}

void loop() {

  startTime = millis();
  float bearing = RealBearing(49,-123,GetBearing());
  int heading = 0;
  RudderTurn(RudderAngle(bearing,heading));
  Serial.println(millis() - startTime);
  delay(200);
}

static void KeepHeading(int heading) {
  float bearing = RealBearing(49,-123,GetBearing());
  RudderTurn(RudderAngle(bearing,heading));
  delay(200);
}

static void GoByPath(float lat2, float long2){
  gps.encode(ss.read());
  while (1 > 0){
    if (millis() > 5000 && gps.charsProcessed() < 10)
    {
      digitalWrite(data, HIGH);
    }
    else {
      digitalWrite(data, LOW);
    }
    while (ss.available() > 0){
      gps.encode(ss.read());
      if (gps.location.isUpdated())
      {
pathagain:
        if (gps.speed.mps() > maxspeed){ 
          delay(100);
          goto pathagain;
        }

        int latslice = gpsavg;
        int lati;
        float lataverage[latslice];
        for (lati = 0; lati < latslice; lati = lati + 1) {
          lataverage[lati] = gps.location.lat();
        }
        float lat1 = mean(lataverage, latslice);

        int longslice = gpsavg;
        int longi;
        float longaverage[longslice];
        for (longi = 0; longi < longslice; longi = longi + 1) {
          longaverage[longi] = gps.location.lng();
        }
        float long1 = mean(longaverage, longslice);
        float heading = GetHeading(lat1, long1, lat2, long2);
        while (1 > 0){
          if (GetDistanceInM(lat1, long1, lat2, long2) > accuracy){
            float heading = GetHeading(lat1, long1, lat2, long2);
            long1=GetPosition(lat1, long1, waypointdist, heading, 2);
            lat1=GetPosition(lat1, long1, waypointdist, heading, 1);
            GoToWaypoint(lat1, long1);
          }
          else {
            return; 
          }
        }
      }
    }
  }
}

static void GoToWaypoint(float lat2, float long2){
  gps.encode(ss.read());
  while (1 > 0){
    while (ss.available() > 0){
      gps.encode(ss.read());
      if (gps.location.isUpdated())
      {
        digitalWrite(lock, HIGH);
        float lat1, long1;
        lat1 = gps.location.lat();
        long1 = gps.location.lng();
        if (GetDistanceInM(lat1, long1, lat2, long2) < (accuracy/1.9)){
          ////Serial.println("Path Point Reached");
          digitalWrite(distance, HIGH);
          delay(500);
          digitalWrite(distance, LOW);
          return;
        }
        else {

gpsagain:

          int latslice = gpsavg;
          int lati;
          float lataverage[latslice];
          for (lati = 0; lati < latslice; lati = lati + 1) {
            lataverage[lati] = gps.location.lat();
          }
          float lat1 = mean(lataverage, latslice);

          int longslice = gpsavg;
          int longi;
          float longaverage[longslice];
          for (longi = 0; longi < longslice; longi = longi + 1) {
            longaverage[longi] = gps.location.lng();
          }
          float long1 = mean(longaverage, longslice);

          if (gps.speed.knots() > maxspeed){ 
            delay(100);
            goto gpsagain;
          }
          delay(20); 

          int slice = 20;
          int i;
          int average[slice];
          for (i = 0; i < slice; i = i + 1) {
            average[i] = (int)GetBearing();
          }
          float bearing = mode(average, slice);
          float heading = GetHeading(lat1, long1, lat2, long2);
          bearing = RealBearing(lat1, long1, bearing);
          RudderTurn(RudderAngle(bearing, heading));
        }
      }
      digitalWrite(lock, LOW);
    }
  }
  return;
}


static void RudderTurn(int angle){
  otherTime = millis();
  while (angle > prevangle) {
    prevangle++;
    rudder.write(prevangle); 
    delay(rudderspeed);  
  }
  while (angle < prevangle) {
    prevangle--;
    rudder.write(prevangle); 
    delay(rudderspeed);  
  }
  otherTime = millis() - otherTime;
  if (otherTime < 800) {
    delay(800 - otherTime);
  }
  prevangle = angle;
}
static float GetPosition(float lat1, float long1, float distance, float heading, int option)
{
  distance = distance / 1000;
  lat1 = ConvertToRadians(lat1);
  long1 = ConvertToRadians(long1);
  heading = ConvertToRadians(heading);
  float lat2 = asin(sin(lat1) * cos(distance / r) +
    cos(lat1) * sin(distance / r) * cos(heading));
  float long2 = long1 + atan2(sin(heading) * sin(distance / r) * cos(lat1),
  cos(distance / r) - sin(lat1) * sin(lat2));
  if (option == 1)
  {
    return ConvertToDegrees(lat2);
  }
  else
  {
    return ConvertToDegrees(long2);
  }
}

static int RudderAngle(float bearing, float heading){
  heading = (int)heading % 360;
  bearing = (int)bearing % 360;
  if (heading == bearing)
  {
    return 90;
  }
  int o1 = (int)heading - (int)bearing;
  int o2 = (int)bearing - (int)heading;
  int dir = ((360-((int)heading - (int)bearing)) % 360);
  if (dir < 180) {
    if (dir > 30)
    {
      return 60;
    }
    else
    {
      return 90 - dir / 2;
    }
  }
  else if (dir >= 180)
  {
    if ((360 - dir) > 30)
    {
      return 120;
    }
    else
    {
      return 90 + (360 - dir) / 2;
    }
  }
  return 90;
}

static float GetBearing(){
  int i;
  int average[compassavg];
  for (i = 0; i < compassavg; i = i + 1) {
    MagnetometerRaw raw = compass.ReadRawAxis();
    MagnetometerScaled scaled = compass.ReadScaledAxis();
    int MilliGauss_OnThe_XAxis = scaled.XAxis;// (or YAxis, or ZAxis)
    float heading = atan2(scaled.YAxis, scaled.XAxis);
    if(heading < 0)
      heading += 2*Pi;
    if(heading > 2*Pi)
      heading -= 2*Pi;
    float headingDegrees = (heading * 180/M_PI); 
    headingDegrees = fmod((headingDegrees + compasstrim),360);
    average[i] = (int)headingDegrees;
  }
  return mode(average, compassavg);
}


static float RealBearing(float lat1, float long1, float bearing)
{
  float magdif = GetHeading(lat1, long1, 75.7667, -99.7833);
  return (fmod((bearing + magdif),360));
}
static float GetHeading(float lat1, float long1, float lat2, float long2)
{
  lat1 = ConvertToRadians(lat1);
  lat2 = ConvertToRadians(lat2);
  long1 = ConvertToRadians(long1);
  long2 = ConvertToRadians(long2);
  float dLon = long2 - long1;
  float y = sin(dLon) * cos(lat2);
  float x = cos(lat1) * sin(lat2) - sin(lat1) * cos(lat2) * cos(dLon);
  return ConvertToStaticDegrees(atan2(y, x));
}
static float GetDistanceInM(float lat1, float long1, float lat2, float long2)
{
  lat1 = ConvertToRadians(lat1);
  lat2 = ConvertToRadians(lat2);
  long1 = ConvertToRadians(long1);
  long2 = ConvertToRadians(long2);
  float dLat = lat2 - lat1;
  float dLon = long2 - long1;
  float a = haversin(dLat) + cos(lat1) * cos(lat2) * haversin(dLon);
  float c = 2 * atan2(sqrt(a), sqrt(1 - a));
  return r * c * 1000; // Distance in M
}
static float ConvertToDegrees(float rad)
{
  float degrees = rad / (Pi / 180);
  if (degrees <= -180) {
    return degrees + 360;
  }
  else {
    return degrees;
  }
}
static float ConvertToStaticDegrees(float rad)
{
  float degrees = rad / (Pi / 180);
  if (degrees <= 0) {
    return degrees + 360;
  }
  else {
    return degrees;
  }
}
static float ConvertToRadians(float angle)
{
  return (Pi / 180) * angle;
}
static float haversin(float input)
{
  return (sin(input / 2)) * (sin(input / 2));
}

static void RoutineDone(){
  RudderTurn(0);
  delay(100);
  RudderTurn(180);
  delay(100);
}

and finally the error message (too many characters for one post):

C:\Users\augus\AppData\Local\Temp\Rar$DIa4312.33111\V02\V02.ino: In function 'void GoByPath(float, float)':

V02:95: error: 'mean' was not declared in this scope

float lat1 = mean(lataverage, latslice);

^

C:\Users\augus\AppData\Local\Temp\Rar$DIa4312.33111\V02\V02.ino: In function 'void GoToWaypoint(float, float)':

V02:149: error: 'mean' was not declared in this scope

float lat1 = mean(lataverage, latslice);

^

V02:171: error: 'mode' was not declared in this scope

float bearing = mode(average, slice);

^

C:\Users\augus\AppData\Local\Temp\Rar$DIa4312.33111\V02\V02.ino: In function 'float GetBearing()':

V02:272: error: 'mode' was not declared in this scope

return mode(average, compassavg);

^

A lot of librarys were found for "HMC5883L.h"
Used: C:\Users\augus\Documents\Arduino\libraries\HMC5883L
Not used: C:\Users\augus\Documents\Arduino\libraries\Grove_3-Axis_Digital_Compass_HMC5883L
exit status 1
'mean' was not declared in this scope

First of all, refactor your code to get rid of the goto's.

Secondly, the compiler is right: 'mean' is not a free function, it's an instance function/method of the Average class, so it can only be invoked against an instance of that class.
Try studying the examples that come with the library.

ok i will do that

but somehow this one guy on instructables used exactly this code and this library and for him it worked

could this be a problem with my computer and its compatibility with the library?

but somehow this one guy on instructables used exactly this code and this library and for him it worked

Instructables are crap. No serious programmer, or hobbyist, would ever use code from an instructables.

GusWT:
but somehow this one guy on instructables used exactly this code and this library and for him it worked

Then he either defined that function somewhere else, or he used a different Average.h library.

@GusWT, any personal attack is unacceptable. Even ones directed at anonymous groups. Do not do it again.

@PaulS, stop picking on the cuss redacted ... uh ... newbies.

short explaining needed! i have literally no idea what you are talking about

GusWT:
short explaining needed!

Asshole. You post that word again you are banned.