Wie vermeide ich: "error: control reaches end of non-void function"

Hallo,

ich möchte in einer Funktion einen Stromsensor auslesen und dann einen Status zurückmelden.
Von der Logik müsste das so funktionieren, allerdings bekomme ich die Fehlermeldung: "error: control reaches end of non-void function"

byte leseINA226() {
  shuntVoltage_mV = 0.0;
  loadVoltage_V = 0.0;
  busVoltage_V = 0.0;
  current_mA = 0.0;
  power_mW = 0.0;
  ina226.readAndClearFlags();
  shuntVoltage_mV = ina226.getShuntVoltage_mV();
  busVoltage_V = ina226.getBusVoltage_V();
  current_mA = ina226.getCurrent_mA();
  power_mW = ina226.getBusPower();
  loadVoltage_V  = busVoltage_V + (shuntVoltage_mV / 1000);
  if (!ina226.overflow) {
    //Serial.println("Werte OK - kein Überlauf");
  }
  else {
    Serial.println("Überlauf! Höheren Strombereich wählen!");
  }

  if (current_mA <= 0.1) {   // Error low
    Serial.println("Fehler, Strom zu niedrig, eventuell Leitung unterbrochen");
    return 0;
  };
  if (current_mA > 0.1 && current_mA < 1.2) {   // Sensor hat Reflexion
    Serial.println("Reflexion");
    return 1;
  };
  if (current_mA >= 1.2 && current_mA < 2.1) {   // Sensor meldet Rückwärtslauf
    Serial.println("Rückwärtslauf");
    return 2;
  };
  if (current_mA >= 2.1 && current_mA < 10) {   // Sensor hat keine Reflexion
    Serial.println("keine Reflexion");
    return 3;
  };
  if (current_mA >= 10 ) {   // Error High
    Serial.println("Fehler, Strom zu hoch, eventuell Kurzschluss");
    return 4;
  };
}

Wie macht man das richtig?

Danke und beste Grüße,
Chris

Der Fehler ist hier:

  };
}

Wenn der Ablauf da hin kommt, gibt es keinen Rückgabewert.

Und dann mal als Hinweis: Du kommst mit -1, 0, 1 und willst bits sparen und machst Vergleiche mit floatWerten.
Das ist sowas von unlogisch.
Warum rechnest Du die Werte um und vergleichst nicht den ADC-Wert? Das ist ein unsigned int und ermöglicht Dir u.A. ein switch / case.

1 Like

aha, und was muss man dann ändern?

Hmm, ich nutze eine Library und die gibt floatWerte aus?! Funktionieren tut das.
Das sparen von Bits war auch nur so ein Gedanke, ich bin nicht dazu gezwungen Speicher zu sparen.

Beste Grüße,
Chris

Versuchs mal:

byte leseINA226()
{
  uint8_t returnWert = 255;
  shuntVoltage_mV = 0.0;
  loadVoltage_V = 0.0;
  busVoltage_V = 0.0;
  current_mA = 0.0;
  power_mW = 0.0;
  ina226.readAndClearFlags();
  shuntVoltage_mV = ina226.getShuntVoltage_mV();
  busVoltage_V = ina226.getBusVoltage_V();
  current_mA = ina226.getCurrent_mA();
  power_mW = ina226.getBusPower();
  loadVoltage_V  = busVoltage_V + (shuntVoltage_mV / 1000);
  if (!ina226.overflow)
  {
    //Serial.println("Werte OK - kein Überlauf");
  }
  else
  {
    Serial.println("Überlauf! Höheren Strombereich wählen!");
  }
  if (current_mA <= 0.1)     // Error low
  {
    Serial.println("Fehler, Strom zu niedrig, eventuell Leitung unterbrochen");
    returnWert = 0;
  }
  else if (current_mA > 0.1 && current_mA < 1.2)    // Sensor hat Reflexion
  {
    Serial.println("Reflexion");
    returnWert = 1;
  }
  else if (current_mA >= 1.2 && current_mA < 2.1)    // Sensor meldet Rückwärtslauf
  {
    Serial.println("Rückwärtslauf");
    returnWert = 2;
  }
  else if (current_mA >= 2.1 && current_mA < 10)     // Sensor hat keine Reflexion
  {
    Serial.println("keine Reflexion");
    returnWert = 3;
  }
  else if (current_mA >= 10 )     // Error High
  {
    Serial.println("Fehler, Strom zu hoch, eventuell Kurzschluss");
    returnWert = 4;
  };
  return returnWert;
}

Nur geschrieben ohne irgendwelche Ambitionen.

Vielleicht da ein return hinschreiben?

Mein Rat:

  1. Meldung aufmerksam lesen!
  2. Mehrmals drüber nachdenken
  3. Lösung erarbeiten
  4. Lösung durchsetzen

ahhhh, verstehe! Dankeschön!

Neue Version:

byte leseINA226()
{
  uint8_t returnWert = 255;
  shuntVoltage_mV = 0.0;
  loadVoltage_V = 0.0;
  busVoltage_V = 0.0;
  current_mA = 0.0;
  power_mW = 0.0;
  ina226.readAndClearFlags();
  shuntVoltage_mV = ina226.getShuntVoltage_mV();
  busVoltage_V = ina226.getBusVoltage_V();
  current_mA = ina226.getCurrent_mA();
  power_mW = ina226.getBusPower();
  loadVoltage_V  = busVoltage_V + (shuntVoltage_mV / 1000);
  if (!ina226.overflow)
  {
    //Serial.println("Werte OK - kein Überlauf");
  }
  else
  {
    Serial.println(F("Überlauf! Höheren Strombereich wählen!"));
  }
  if (current_mA <= 0.1)     // Error low
  {
    Serial.println(F("Fehler, Strom zu niedrig, eventuell Leitung unterbrochen"));
    returnWert = 0;
  }
  else if (current_mA < 1.2)    // Sensor hat Reflexion
  {
    Serial.println(F("Reflexion"));
    returnWert = 1;
  }
  else if (current_mA < 2.1)    // Sensor meldet Rückwärtslauf
  {
    Serial.println(F("Rückwärtslauf"));
    returnWert = 2;
  }
  else if (current_mA < 10)     // Sensor hat keine Reflexion
  {
    Serial.println(F("keine Reflexion"));
    returnWert = 3;
  }
  else  // Error High
  {
    Serial.println(F("Fehler, Strom zu hoch, eventuell Kurzschluss"));
    returnWert = 4;
  }
  return returnWert;
}

Bitte beachte alle Änderungen!
Nur so hingeschrieben - ohne Anspruch auf irgendwas!

Die Lösung wurde ja schon gegeben. Um es noch kurz zu erklären. Sämtliche Return Anweisungen sind in Deiner Funktion in IF Anweisungen verpackt. Der Compiler zieht die Möglichkeit in Betracht, dass keine der Bedingungen zutrifft.

In diesem Fall gäbe es keinen Return Wert. Und das entspricht nicht der Funktionsdefinition. Deshalb musst Du deine Anweisungen so umschreiben, dass auch ein Return Wert außerhalb der IF-Anweisungen zurückgegeben wird..

Nachdem die Lösung geschrieben war, habe ich das sofort verstanden. Vor der Erklärung bin ich nicht darauf gekommen.

Das werde ich später auch noch umsetzen.
Nun bin ich aber woanders drüber gestolpert.
Ich möchte eine "-1" aus der Funktion zurückgeben.
Dazu habe ich anstatt "byte" und "uint8_t" auf "int" umgebaut, aber es kommt keine "-1" zurück, sondern eine "255"?!

int leseINA226() {
  int returnWert = 127;
  shuntVoltage_mV = 0.0;
  loadVoltage_V = 0.0;
  busVoltage_V = 0.0;
  current_mA = 0.0;
  power_mW = 0.0;
  ina226.readAndClearFlags();
  shuntVoltage_mV = ina226.getShuntVoltage_mV();
  busVoltage_V = ina226.getBusVoltage_V();
  current_mA = ina226.getCurrent_mA();
  power_mW = ina226.getBusPower();
  loadVoltage_V  = busVoltage_V + (shuntVoltage_mV / 1000);
  if (!ina226.overflow) {
    //Serial.println("Werte OK - kein Überlauf");
  }
  else {
    //Serial.println("Überlauf! Höheren Strombereich wählen!");
  }

  if (current_mA <= 0.1) {   // Error low
    //Serial.println("Fehler, Strom zu niedrig, eventuell Leitung unterbrochen");
    returnWert = 3;
  };
  if (current_mA > 0.1 && current_mA < 1.2) {   // Sensor hat Reflexion
    //Serial.println("Reflexion");
    returnWert = 1;
  };
  if (current_mA >= 1.2 && current_mA < 2.1) {   // Sensor meldet Rückwärtslauf
    //Serial.println("Rückwärtslauf");
    returnWert = -1;
  };
  if (current_mA >= 2.1 && current_mA < 10) {   // Sensor hat keine Reflexion
    //Serial.println("keine Reflexion");
    returnWert = 0;
  };
  if (current_mA >= 10 ) {   // Error High
    //Serial.println("Fehler, Strom zu hoch, eventuell Kurzschluss");
    returnWert = 4;
  }
  return returnWert;
}

Warum kommt keine "-1"?

Weil Du keine definiert hast.

Hinweis: Ein int braucht auf einem Arduino gerne 2 bytes.
Wenn Du nur eines brauchst, benutze es auch.

Mach aus jedem int ein int8_t
Mach aus der 127 eine -1

Schwuppdiwupp

Hab ich doch?!

Aber es wird 255 zurück geliefert

Auch dann kommt eine 255 dabei raus und keine -1 ?!

Schreibe ich -2 kommt 254
Schreibe ich -3 kommt 253

void setup()
{
  Serial.begin(115200);
  Serial.println(F("Start..."));
  Serial.print(tik());
}


int8_t tik()
{
  int8_t xWert = 127;
  xWert = -1;
  return xWert;
}

void loop()
{
}

Wenn da -1 zurück kommt ist das nichts anderes wie der Codeschnipsel oben.

Schreibst du das beim Auswerten ein byte? Dann passiert das

void setup()
{
  Serial.begin(9600);

  byte value = func();
  Serial.println(value);
}

void loop() 
{
}

int func()
{
  return -3;
}

Weil einfach die Bit-Darstellung als Zahl ohne Vorzeichen interpretiert wird

Tipp:
C++ Buch, das Kapitel über integrale Datentypen
Und den impliziten Konvertierungen zwischen diesen.
(das ist Pflicht Wissen)

Man kann den Fehler vermuten aber nicht direkt sehen, weil der Code fehlt, mit dem Du dir den Rückgabewert anzeigen lässt. Es ist anzunehmen, dass Du den Rückgabewert einer unsigned Variable zuweist.

Ja, da kommt -1 bei raus

Ich habe es dann versucht auf meinen Code zu adaptieren:
....da kommt wieder 255 bei raus?! Ich check's nicht!?

#include <Wire.h>
#include <INA226_WE.h>
#define I2C_ADDRESS 0x40
INA226_WE ina226 = INA226_WE(I2C_ADDRESS);
float shuntVoltage_mV = 0.0;
float loadVoltage_V = 0.0;
float busVoltage_V = 0.0;
float current_mA = 0.0;
float power_mW = 0.0;
byte lastvalue;
byte actualvalue;
unsigned long Schleifen = 0;                  // wie viele Schleifen wurden durchlaufen?
unsigned long Startzeit = 0;                  // Merker für die Zeit in Millisekunden seit letzten Aufruf der Funktion. Millis zählt immer weiter hoch seit dem Einschalten des Controllers

int8_t leseINA226() {
  int8_t returnWert = 127;
  shuntVoltage_mV = 0.0;
  loadVoltage_V = 0.0;
  busVoltage_V = 0.0;
  current_mA = 0.0;
  power_mW = 0.0;
  ina226.readAndClearFlags();
  shuntVoltage_mV = ina226.getShuntVoltage_mV();
  busVoltage_V = ina226.getBusVoltage_V();
  current_mA = ina226.getCurrent_mA();
  power_mW = ina226.getBusPower();
  loadVoltage_V  = busVoltage_V + (shuntVoltage_mV / 1000);
  if (!ina226.overflow) {
    //Serial.println("Werte OK - kein Überlauf");
  }
  else {
    //Serial.println("Überlauf! Höheren Strombereich wählen!");
  }

  if (current_mA <= 0.1) {   // Error low
    //Serial.println("Fehler, Strom zu niedrig, eventuell Leitung unterbrochen");
    returnWert = 2;
  };
  if (current_mA > 0.1 && current_mA < 1.2) {   // Sensor hat Reflexion
    //Serial.println("Reflexion");
    returnWert = 1;
  };
  if (current_mA >= 1.2 && current_mA < 2.1) {   // Sensor meldet Rückwärtslauf
    //Serial.println("Rückwärtslauf");
    returnWert = -1;
  };
  if (current_mA >= 2.1 && current_mA < 10) {   // Sensor hat keine Reflexion
    //Serial.println("keine Reflexion");
    returnWert = 0;
  };
  if (current_mA >= 10 ) {   // Error High
    //Serial.println("Fehler, Strom zu hoch, eventuell Kurzschluss");
    returnWert = 3;
  }
  return returnWert;
}

void setup() {
  Serial.begin(9600);
  delay(200);
  Wire.begin();
  ina226.init();
  ina226.setAverage(AVERAGE_1); // 1(default),4,16,64,128,256,512,1024 choose mode and uncomment for change of default
  ina226.setConversionTime(CONV_TIME_1100); //140,204,332,588,1100(default),2116,4156,8244 choose conversion time and uncomment for change of default
  ina226.setMeasureMode(CONTINUOUS); // "POWER_DOWN" INA226 switched off, "TRIGGERED" measurement on demand, "CONTINUOUS" continuous measurements (default) choose mode and uncomment for change of default
  ina226.setCurrentRange(MA_400); // 400,800(default) choose gain and uncomment for change of default
  ina226.waitUntilConversionCompleted(); //if you comment this line the first data might be zero
  lastvalue = leseINA226();
  Startzeit = millis();
}

void loop() {
  //Serial.print(lastvalue);
  //Serial.print(" ");
  //Serial.println(leseINA226());
  actualvalue = leseINA226();
  if (actualvalue != lastvalue) { // Sensor hat keine Reflexion
    Serial.print(actualvalue);
    Serial.print("  Current[mA]: ");    Serial.print(current_mA);
    lastvalue = actualvalue;
    Serial.print("  Schleifen durchlaufen: ");
    Serial.print(Schleifen);
    Serial.print("  Wechselzeit[ms]: ");
    Serial.println(millis() - Startzeit);
    Schleifen = 0;
    Startzeit = millis();
  }
  Schleifen++;
  /* Serial.print("Shunt Voltage[mV]: "); Serial.print(shuntVoltage_mV);
    Serial.print("  Bus Voltage[V]: "); Serial.print(busVoltage_V);
    Serial.print("  Load Voltage [V]: "); Serial.print(loadVoltage_V);
    Serial.print("  Current[mA]: ");
    Serial.print(current_mA);
    Serial.print("  Bus Power [mW]: "); Serial.print(power_mW);
  */
}

:wink:

Da ist ein uint8_t versteckt.
wenn das ein int8_t wird, könnte es klappen.

Weil int8_t(-1) und byte(255) bei dir das selbe Binärmuster haben.

Tipp A:
Ein gutes C++ Buch gibt gerne Auskunft über Datentypen und ihre Verwendung.

Tipp B:
Die Ausführlichen Ausgaben scharf schalten, und die Warnungen beachten.