avergearray not declared in scope, who can solve my Big Problem

Hey Guys,
sorry my english is not really better since last time. :slight_smile: But give my Best !

I have a PH Elektrode with "Driver Board" and want to send the Value via MQTT to Home-Assistant.

Thats the plan but i m saddly not a Programmer and make this Hobby only recently for a couple of months.

I have a sketch from the PH seller and one from home assistant and make them once.

also ive edited this from esp2866wifi to arduino ethernet.

Now my problem is the "avergearray" ( i dont know what this is) where i cant solve i try it since Wednesday.

When i compile the Sketch the following issue will display:

/Users/nedsin/Documents/Arduino/mqtt_PH/mqtt_PH.ino: In function 'void loop()':
mqtt_PH:103: error: 'avergearray' was not declared in this scope
       voltage = avergearray(pHArray, ArrayLenth) * 5.0 / 1024;
                                                ^

No plan how to edit this to make it work.
There are a few more issues shown but i dont know if there go away when the array is solved.

Hope Someone have the Time to look at the sketches.

PH Sensor Sketch ---------- MQTT HASS Sketch
My Version till now :

#include <SPI.h>
#include <Ethernet.h>
// #include <Wire.h>
#include <PubSubClient.h>
#define SensorPin A5            //pH meter Analog output to Arduino Analog Input 0
#define Offset 0.00            //deviation compensate
#define LED 13
#define samplingInterval 20
#define printInterval 800
#define ArrayLenth  40    //times of collection
int pHArray[ArrayLenth];   //Store the average value of the sensor feedback
int pHArrayIndex = 0;


byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };

// use the numeric IP instead of the name for the server:
IPAddress server(192, 168, 0, 1); // numeric IP for Google (no DNS)


// Set the static IP address to use if the DHCP fails to assign
IPAddress ip(192, 168, 0, 985);

// Initialize the Ethernet client library
// with the IP address and port of the server
// that you want to connect to (port 80 is default for HTTP):
EthernetClient client;

#define mqtt_server "192.168.0.987"
#define mqtt_user "us"
#define mqtt_password "pw"

#define ph_topic "spfo/sensor/ph"


// PubSubClient client(server, 1883, callback, ethClient);
EthernetClient ethClient;
PubSubClient mqttClient;

void setup() {
  {
    pinMode(LED, OUTPUT);
    Serial.begin(9600);
    Serial.println("PH Sensor Started ...");    //Test the serial monitor


    while (!Serial) {
      ; // wait for serial port to connect. Needed for native USB port only
    }

    // start the Ethernet connection:
    if (Ethernet.begin(mac) == 0) {
      Serial.println("Scheiße kein Netzwerk !!!");
      Ethernet.begin(mac, ip);
    }

    delay(3000);
    Serial.println("Verbinde ... Juhu ...");

    // if you get a connection, report back via serial:
    if (client.connect(server, 80)) {
      Serial.println("Verbunden, JUHUUUU ...");
      client.println("Connection: close");
      client.println();
      Serial.println("Na dann Heiter Weiter ...");
    } else {
      // if you didn't get a connection to the server:
      Serial.println("Mist, konnte nicht zum Broker Telefonieren ...");
    }
  }
  mqttClient.setClient(ethClient);
  mqttClient.setServer(mqtt_server, 1883);
  Serial.println(F("MQTT Client getartet ... Es geht aufwärts !!!"));
}

// Kunst oder kann das weg ?
bool checkBound(float newValue, float prevValue, float maxDiff) {
  return !isnan(newValue) &&
         (newValue < prevValue - maxDiff || newValue > prevValue + maxDiff);
}
//// Kunst Ende ///
long lastMsg = 0;
float PH = 0.0;



void loop(void)
{
  if (!client.connected()) {
    //    reconnect();
  }
  mqttClient.loop();
  {
    static unsigned long samplingTime = millis();
    static unsigned long printTime = millis();
    static float pHValue, voltage;
    if (millis() - samplingTime > samplingInterval)
    {
      pHArray[pHArrayIndex++] = analogRead(SensorPin);
      if (pHArrayIndex == ArrayLenth)pHArrayIndex = 0;
      voltage = avergearray(pHArray, ArrayLenth) * 5.0 / 1024;
      pHValue = 3.5 * voltage + Offset;
      samplingTime = millis();
    }
    if (millis() - printTime > printInterval)  //Every 800 milliseconds, print a numerical, convert the state of the LED indicator
    {
      double avergearray(int* arr, int number) {
        int i;
        int max, min;
        double avg;
        long amount = 0;
        if (number <= 0) {
          Serial.println("Error number for the array to avraging!/n");
          Serial.print("Voltage:");
          Serial.print(voltage, 2);
          Serial.print("    pH value: ");
          Serial.println(pHValue, 2);
          digitalWrite(LED, digitalRead(LED) ^ 1);
          printTime = millis();


          return 0;

          long now = millis();
          if (now - lastMsg > 1000) {
            lastMsg = now;
            newph digitalRead(pHValue, 2);

            if (checkBound(newph)) {
              newph = (newph);
              Serial.print("PH-Wert Aktuell:");
              Serial.println(String(newph));
              mqttClient.publish("spfo/sensor/ph", String(newph), (true));
              {
                mqttClient.publish("spfo/sensor/ip", (localip));
              }
            } else {
              Serial.println("Unknown value");
              mqttClient.publish("spfo/sensor/nb", "Syntax Error");
            }
          }
          if (number < 5) { //less than 5, calculated directly statistics
            for (i = 0; i < number; i++) {
              amount += arr[i];
            }
            avg = amount / number;
            return avg;
          } else {
            if (arr[0] < arr[1]) {
              min = arr[0]; max = arr[1];
            }
            else {
              min = arr[1]; max = arr[0];
            }
            for (i = 2; i < number; i++) {
              if (arr[i] < min) {
                amount += min;      //arr<min
                min = arr[i];
              } else {
                if (arr[i] > max) {
                  amount += max;  //arr>max
                  max = arr[i];
                } else {
                  amount += arr[i]; //min<=arr<=max
                }
              }//if

            }//for
            avg = (double)amount / (number - 2);
          }//if
          return avg;

        }
      }
    }
  }
}

The Issues Part ( i think ) is a little bit under the void(loop) section:

  mqttClient.loop();
  {
    static unsigned long samplingTime = millis();
    static unsigned long printTime = millis();
    static float pHValue, voltage;
    if (millis() - samplingTime > samplingInterval)
    {
      pHArray[pHArrayIndex++] = analogRead(SensorPin);
      if (pHArrayIndex == ArrayLenth)pHArrayIndex = 0;
      voltage = avergearray(pHArray, ArrayLenth) * 5.0 / 1024;
      pHValue = 3.5 * voltage + Offset;
      samplingTime = millis();
    }

I really really grateful for every second who someone look at my Problem.

I take every littlest Note that could give me a way to go ...

Who could Solve This ???

Thank you ...

Best Wishes
Ned

This is a function:

double avergearray(int* arr, int number) {
  ...
}

Just like "setup()" and "loop()" and "checkBound()" are functions.

You have taken the function "avergearray()" and have put it inside the "loop()" function in the code.

You can remind yourself that it is a function with comment:

// -------------------------------
// function avergearray
// -------------------------------
// It uses the first parameter, pointing to an array with data,
// to calculate the average.
// -------------------------------
double avergearray(int* arr, int number) {
  ...
}

Hey Koepel,
thank you for your answer.

I have edited the sketch like this:

  }
  mqttClient.loop();
    static unsigned long samplingTime = millis();
    static unsigned long printTime = millis();
    static float pHValue, voltage;
    if (millis() - samplingTime > samplingInterval) 
      pHArray[pHArrayIndex++] = analogRead(SensorPin);
      if (pHArrayIndex == ArrayLenth)pHArrayIndex = 0;
double avergearray(int* arr, int number) ;
      voltage = avergearray(pHArray, ArrayLenth) * 5.0 / 1024;
      pHValue = 3.5 * voltage + Offset;
      samplingTime = millis();
    }
          }

Now i become the issue:

exit status 1
expected declaration before '}' token

Then i try:

  }
  mqttClient.loop();
    static unsigned long samplingTime = millis();
    static unsigned long printTime = millis();
    static float pHValue, voltage;
    if (millis() - samplingTime > samplingInterval) 
      pHArray[pHArrayIndex++] = analogRead(SensorPin);
      if (pHArrayIndex == ArrayLenth)pHArrayIndex = 0;
double avergearray(int* arr, int number) ;
      voltage = avergearray(pHArray, ArrayLenth) * 5.0 / 1024;
      pHValue = 3.5 * voltage + Offset;
      samplingTime = millis();
    }:
          }

But it even dont work :frowning: ...

I dont know which declaration could missing ... have you any idea ???

Thank you again.

Best wishes

Look at the functions "setup()" and "loop()" and "checkBound()".
Do they have a ';' after the first line ?

This is the first line of a function, the rest of the function should follow after it:

double avergearray(int* arr, int number)

I think you made it worse. Can you read about functions in the 'c' language and how they should be used ?

You can make the text layout better. Make ik look nicer and have every space, every indent, every '{' and '}' at the right place. That will help to write code.

Hey,
Youre right i have to learn a lot and i will do.

I want to make this Sketch For My Aquarium and Its Really important thats this go fast.

After thats i want learn it in queue ... time to time

Really thank you for help Hope that made it...

I try it After Work ...

Greetings

Edited: Have wrote from Tablet at work ... must correkt something ...

Hello again Koepel,

// EDIT: I have SOLVED this Thread ...

Thanks for your Help Koepel.

Now i have the float convert into a string and it works great ...

// EDIT: down here is done ...

because of youre note, i have a new sketch edited and make its more "look nicer".

Now the compiling runs thru and the sketch is on my Arduino.

Unfortunately the MQTT Value comes not in the right code ...

the Mosquitto Output in Shell on RasPi and MQTT.fx look like: "????.?"

and by the wayHome Assistant shows nothing, but i think its the same issue.
If i send a message via terminal to the Topic everything goes right.

Can someone help a NOOB again ? :wink:

Heres the Sketch:

// CONFIG -------------------------------------------------------------------------------------
#include <SPI.h>
#include <Ethernet.h>
#include <PubSubClient.h>

// Update these with values suitable for your network.
byte mac[]    = {  0xDE, 0xED, 0xBA, 0xFE, 0xFE, 0xED };
IPAddress ip(192, 168, 0, 117);
IPAddress server(192, 168, 0, 110);


#define SensorPin A0            //pH meter Analog output to Arduino Analog Input 0
#define Offset 0.00            //deviation compensate
#define LED 13
#define samplingInterval 20
#define printInterval 5000
#define ArrayLenth  40    //times of collection
int pHArray[ArrayLenth];   //Store the average value of the sensor feedback
int pHArrayIndex=0;    

// SETUP -------------------------------------------------------------------------------------

void setup(void)
{
  pinMode(LED,OUTPUT);  
  Serial.begin(9600);  

  Serial.println("PH Senssor started");//Test the serial monitor

  EthernetClient ethClient;
  PubSubClient client(ethClient);
  Ethernet.begin(mac, ip);
  client.setServer(server, 1883);

  while (!client.connected()) {
    Serial.print("Attempting MQTT connection...");
    // Attempt to connect
    if (client.connect("PH.Sensor")) {
      Serial.println("connected"); 
      // Allow the hardware to sort itself out
    delay(1500);
}
}
}

// LOOP -------------------------------------------------------------------------------------

void loop()
{

  static unsigned long samplingTime = millis();
  static unsigned long printTime = millis();
  static float pHValue,voltage;

  if(millis()-samplingTime > samplingInterval)
  {
      pHArray[pHArrayIndex++]=analogRead(SensorPin);
      if(pHArrayIndex==ArrayLenth)pHArrayIndex=0;
      voltage = avergearray(pHArray, ArrayLenth)*5.0/1024;
      pHValue = 3.5*voltage+Offset;
      samplingTime=millis();
  }
  if(millis() - printTime > printInterval)   //Every 800 milliseconds, print a numerical, convert the state of the LED indicator
  {
  Serial.print("Voltage:");
        Serial.print(voltage,2);
        Serial.print("    pH value: ");
  Serial.println(pHValue,2);
        digitalWrite(LED,digitalRead(LED)^1);
        printTime=millis();
          EthernetClient ethClient;
  PubSubClient client(ethClient);
  client.setServer(server, 1883);
        client.connect("PH.Sensor");
      Serial.println("Send PH via MQTT");
      client.publish("spfo/sensor/ph", (pHValue,2) );
  }
}

// AVERAGEARRAY -------------------------------------------------------------------------------------

double avergearray(int* arr, int number){
  int i;
  int max,min;
  double avg;
  long amount=0;
  
  EthernetClient ethClient;
  PubSubClient client(ethClient);
  
  if(number<=0){
    Serial.println("Error number for the array to avraging!/n");
    return 0;
  }
  if(number<5){   //less than 5, calculated directly statistics
    for(i=0;i<number;i++){
      amount+=arr[i];
    }
    avg = amount/number;
    return avg;
  }else{
    if(arr[0]<arr[1]){
      min = arr[0];max=arr[1];
    }
    else{
      min=arr[1];max=arr[0];
    }
    for(i=2;i<number;i++){
      if(arr[i]<min){
        amount+=min;        //arr<min
        min=arr[i];
      }else {
        if(arr[i]>max){
          amount+=max;    //arr>max
          max=arr[i];
        }else{
          amount+=arr[i]; //min<=arr<=max
        }
      }//if
    }//for
    avg = (double)amount/(number-2);
  }//if
  return avg;
  client.loop();
}

Best wishes

Ned

The text layout is still not "nice", it is "less ugly" :o
You could try to press Ctrl+T. The Arduino IDE has an automatic text layout.

To keep the MQTT going, the "client.loop()" should be executed as much as possible. That function should be in the Arduino loop() function. If you don't use a callback, then you don't need to check with client.loop().

I have only used MQTT once with the Adafruit server.
I have "EthernetClient ethClient;" and "PubSubClient client(ethClient);" as global variables and I start the MQTT once in setup. That is also according the examples that come with the PubSubClient library.
You create the PubSubClient everytime in every function. I'm not sure if that is okay. Have a look at the examples.

You have to find how to use it for the Mosquitto server. Some servers need a specific way for the path and the key and the user name.

Are you going to use a node-red dashboard ? What is Home Assistant ?

My MQTT knowledge does not go further. You have to start a new topic. Be sure to mention "MQTT" and "Mosquitto" in the subject.

Hello,
im already in process to optimize the code, its not sooo easy for noobs and i read a lot ... first i just want to work this thing than comes the details ...

The most of here starts as noob and can not wait until the first bigger project is done, i think :wink:

Thank you for the tipps they will help me much ...

Home-Assistant(.io) is an Home Automatic System like OpenHAB but much better i find ...

The Mosquitto Server runs without problems ...

Best wishes ....

ned