Softwarefehler?

Hallo zusammen,
zunächstmal sollte ich erwähnen, dass ich absoluter Anfänger mit Arduino bin und mich nur über meine MakerAG bei Arduino gelandet bin. Ich habe versucht für den Chemieunterricht ein Kolorimeter zu bauen. Das Projekt findet man im Thingiverse unter Minimalist Colorimeter. Dort habei ch auch den Code her. Das Kolorimeter ist soweit gebaut und misst wieviel farbiges Licht durch eine Probe absorbiert wird. Den Code habe ich größtenteils übernommen, nur einige Kleinigekeiten ausgetauscht. Zum Beispiel habe ich einen Fehler in der Berechnung der Absorbtion gefunden und diesen ausgebessert. Das Problem ist, dass ich bei einer Messung viel zu hohe Werte für die Transmission bekommen. Ich habe versuch mich in den Code reinzulesen, verstehe aber zu wenig von C++ um den Fehler zu finden. Vielleicht kann mir hier jemand helfen und einen guten Rat geben??? Ich bin echt verzweifelt.

Hier mein Code:

#include <math.h>
#include <SPI.h>
#include <Wire.h>
#include <Adafruit_SSD1306.h>
#define OLED_RESET 4

Adafruit_SSD1306 display(OLED_RESET);

const int numReadings = 101;    //how many readings to take for each color
const int sensorDelay = 10;     //time between each reacing in milliseconds

const int sensorPin = A0;
const int ledRedPin = 9;
const int ledGreenPin = 8;
const int ledBluePin = 7;
const int buttonBlankPin = 5;
const int buttonReadPin = 6;
const int lcdPowerPin = 3;
const int sensorPowerPin = 4;

double transRed = 0.0;
double transGreen = 0.0;
double transBlue = 0.0;

double absRed = 0.00;
double absGreen = 0.00;
double absBlue = 0.00;

int readingsRed[numReadings];
int readRedIndex = 0;
long totalRed = 0;
double averageRed = 0;

int readingsGreen[numReadings];
int readGreenIndex = 0;
long totalGreen = 0;
double averageGreen = 0;

int readingsBlue[numReadings];
int readBlueIndex = 0;
long totalBlue = 0;
double averageBlue = 0;

int buttonBlankState = 0;
int buttonSampleState = 0;

double blankRed = 0;
double blankGreen = 0;
double blankBlue = 0;

int sampleRed = 0;
int sampleGreen = 0;
int sampleBlue = 0;

int readingRed = 0;
int readingGreen = 0;
int readingBlue = 0;

String incommingSerial;

bool blankRequest = false;
bool readRequest = false;



void setup()
{

  Serial.begin(9600);

  //setting up what pins belongs to which device
  pinMode(ledRedPin, OUTPUT);
  pinMode(ledGreenPin, OUTPUT);
  pinMode(ledBluePin, OUTPUT);
  pinMode(sensorPin, INPUT);
  pinMode(buttonBlankPin, INPUT_PULLUP);
  pinMode(buttonReadPin, INPUT_PULLUP);
  //pinMode(lcdPowerPin, OUTPUT);
  pinMode(sensorPowerPin, OUTPUT);

  digitalWrite(sensorPowerPin, HIGH);

  //initial display stuff and splash screen
  display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
  display.clearDisplay();
  display.setTextSize(1);
  display.setTextColor(WHITE); //DO NOT DELETE THIS LINE ELSE SCREEN NO WORKS
  display.setCursor(0, 0);
  display.println(" Makers");
  display.print("   Masterclass GHG");
  display.display();
  delay(2500);
  display.clearDisplay();
  display.setTextSize(1);
  display.setCursor(0, 0);
  display.println();
  display.println("  Regionalteam   ");
  display.print("       Chemie");
  display.display();
  delay(2500);
  display.clearDisplay();
  display.setTextSize(1);
  display.setCursor(0, 0);
  display.println();
  display.println("   RGB Colorimeter");
  display.setTextSize(1);
  display.print("        v1.0");
  display.display();
  delay(2500);

  //fill the reading arrays for each color with 0 to ensure things work okay
  for (int thisReading = 0; thisReading < numReadings; thisReading++)
    readingsRed[thisReading] = 0;
  for (int thisReading = 0; thisReading < numReadings; thisReading++)
    readingsGreen[thisReading] = 0;
  for (int thisReading = 0; thisReading < numReadings; thisReading++)
    readingsBlue[thisReading] = 0;
}



void loop()
{
  if (blankRequest == true)
  {
    readBlank();
    blankRequest = false;
  }

  if (readRequest == true)
  {
    readSample();
    readRequest = false;
  }

  buttonBlankState = digitalRead(buttonBlankPin);
  buttonSampleState = digitalRead(buttonReadPin);

  if (buttonBlankState == LOW)
  {
    readBlank();
  }

  if (buttonSampleState == LOW)
  {
    readSample();
  }

  display.clearDisplay();
  display.setCursor(0, 0);
  display.setTextSize(1);

  display.print("R");
  display.print(readingRed);
  display.print(" T ");
  display.print(transRed);
  display.print(" A ");
  display.println(absRed);

  display.print("G");
  display.print(readingGreen);
  display.print(" T ");
  display.print(transGreen);
  display.print(" A ");
  display.println(absGreen);

  display.print("B");
  display.print(readingBlue);
  display.print(" T ");
  display.print(transBlue);
  display.print(" A ");
  display.print(absBlue);
  display.display();
}

void serialEvent()
{
  while (Serial.available())
  {
    incommingSerial = Serial.readString(); // read the incoming data as string

    if (incommingSerial == "b\r")
    {
      readBlank();
    }

    if (incommingSerial == "s\r")
    {
      readSample();
    }
  }
}

void readBlank()
{
  readingRed = 0;
  readingGreen = 0;
  readingBlue = 0;

  display.setTextSize(1);
  display.clearDisplay();
  display.setCursor(0, 0);
  display.println(" Nehme Referenz!");
  display.setCursor(0, 24);
  display.setTextSize(1);
  display.print(" Moment");
  display.display();
  // scan and average RED LED readings
  digitalWrite(ledRedPin, HIGH);

  for (int thisReading = 0; thisReading < numReadings; thisReading++)
  {
    totalRed = totalRed - readingsRed[thisReading];
    // read from the sensor:
    readingsRed[thisReading] = analogRead(sensorPin);
    // add the reading to the total:
    totalRed = totalRed + readingsRed[thisReading];
    delay(sensorDelay);
  }

  averageRed = totalRed / numReadings;
  blankRed = averageRed;
  digitalWrite(ledRedPin, LOW);

  //scan and average GREEN LED readings
  digitalWrite(ledGreenPin, HIGH);
  for (int thisReading = 0; thisReading < numReadings; thisReading++)
  {
    totalGreen = totalGreen - readingsGreen[thisReading];
    // read from the sensor:
    readingsGreen[thisReading] = analogRead(sensorPin);
    // add the reading to the total:
    totalGreen = totalGreen + readingsGreen[thisReading];
    delay(sensorDelay);
  }

  averageGreen = totalGreen / numReadings;
  blankGreen = averageGreen;
  digitalWrite(ledGreenPin, LOW);

  //scan and average BLUE LED readings
  digitalWrite(ledBluePin, HIGH);
  for (int thisReading = 0; thisReading < numReadings; thisReading++)
  {
    totalBlue = totalBlue - readingsBlue[thisReading];
    // read from the sensor:
    readingsBlue[thisReading] = analogRead(sensorPin);
    // add the reading to the total:
    totalBlue = totalBlue + readingsBlue[thisReading];
    delay(sensorDelay);
  }

  averageBlue = totalBlue / numReadings;
  blankBlue = averageBlue;
  digitalWrite(ledBluePin, LOW);

  readingRed = blankRed;
  readingGreen = blankGreen;
  readingBlue = blankBlue;

  transRed = (averageRed / blankRed) * 100;
  transGreen = (averageGreen / blankGreen) * 100;
  transBlue = (averageBlue / blankBlue) * 100;

  absRed = 2 - log10(transRed);
  absGreen = 2 - log10(transGreen);
  absBlue = 2 - log10(transBlue);

  Serial.print("B,");
  Serial.print(blankRed);
  Serial.print(",");
  Serial.print(blankGreen);
  Serial.print(",");
  Serial.println(blankBlue);



  //tell the arduino the button is now in the unpressed state so it can listen for another press when needed
  buttonBlankState = 1;
}



void readSample()
{
  readingRed = 0;
  readingGreen = 0;
  readingBlue = 0;

  display.setTextSize(2);
  display.clearDisplay();
  display.setCursor(0, 0);
  display.println("  Messe!");
  display.setCursor(0, 24);
  display.setTextSize(1);
  display.print("    Mmmmmm, Daten...");
  display.display();

  // scan and average RED LED readings
  digitalWrite(ledRedPin, HIGH);

  for (int thisReading = 0; thisReading < numReadings; thisReading++)
  {
    totalRed = totalRed - readingsRed[thisReading];
    // read from the sensor:
    readingsRed[thisReading] = analogRead(sensorPin);
    // add the reading to the total:
    totalRed = totalRed + readingsRed[thisReading];
    delay(sensorDelay);
  }

  averageRed = totalRed / numReadings;
  sampleRed = averageRed;
  digitalWrite(ledRedPin, LOW);


  //scan and average GREEN LED readings
  digitalWrite(ledGreenPin, HIGH);
  for (int thisReading = 0; thisReading < numReadings; thisReading++)
  {
    totalGreen = totalGreen - readingsGreen[thisReading];
    // read from the sensor:
    readingsGreen[thisReading] = analogRead(sensorPin);
    // add the reading to the total:
    totalGreen = totalGreen + readingsGreen[thisReading];
    delay(sensorDelay);
  }

  averageGreen = totalGreen / numReadings;
  sampleGreen = averageGreen;
  digitalWrite(ledGreenPin, LOW);


  //scan and average BLUE LED readings
  digitalWrite(ledBluePin, HIGH);
  for (int thisReading = 0; thisReading < numReadings; thisReading++)
  {
    totalBlue = totalBlue - readingsBlue[thisReading];
    // read from the sensor:
    readingsBlue[thisReading] = analogRead(sensorPin);
    // add the reading to the total:
    totalBlue = totalBlue + readingsBlue[thisReading];
    delay(sensorDelay);
  }

  averageBlue = totalBlue / numReadings;
  // send it to the computer as ASCII digits
  sampleBlue = averageBlue;
  digitalWrite(ledBluePin, LOW);


  //make sure the RGB values do not exceed 255 or are less than 0
  readingRed = map(averageRed, 0, blankRed, 0, 255);

  if (readingRed > 255)
  {
    readingRed = 255;
  }

  if (readingRed < 0)
  {
    readingRed = 0;
  }

  readingGreen = map(averageGreen, 0, blankGreen, 0, 255);

  if (readingGreen > 255)
  {
    readingGreen = 255;
  }

  if (readingGreen < 0)
  {
    readingGreen = 0;
  }

  readingBlue = map(averageBlue, 0, blankBlue, 0, 255);

  if (readingBlue > 255)
  {
    readingBlue = 255;
  }

  if (readingBlue < 0)
  {
    readingBlue = 0;
  }

  transRed = (averageRed / blankRed ) * 100;
  transGreen = (averageGreen / blankGreen) * 100;
  transBlue = (averageBlue / blankBlue) * 100;

  absRed = abs(2 - log10(transRed));
  absGreen = abs(2 - log10(transGreen));
  absBlue = abs(2 - log10(transBlue));

  Serial.print("S,");
  Serial.print(readingRed);
  Serial.print(",");
  Serial.print(readingGreen);
  Serial.print(",");
  Serial.println(readingBlue);


  //tell the arduino the button is now in the unpressed state so it can listen for another press when needed
  buttonSampleState = 1;
}

Wo gibt es die falschen Werte?

Beim Blanking ist noch alles okay, dort wird die Transmission auf 100 % und die Absorbtion auf 0 gesetzt. Wenn dann eine Messung durchgeführt wird, übersteigt die Transmission plötzlich 100%. Der Fehler liegt also wahrscheinlich in readSample ().

Hört sich nach einem Überlauf an.
Beim durchscrollen ist mir das zu lang um sofort was zu sehen...

Hallo,
da kommmst Du nur mit zusätzlichen Serial.print() an ausgewählten Stellen weiter um das vernünftig zu debuggen und zu sehen was da wo passiert.

Was ist das für ein Arduino ?

Danke erstmal für eure schnellen Antworten. Das ist ein Arduino Pro mini. Wo setze ich denn am besten noch Serial.Prints um herauszubekommen was hier schief läuft?

Ich habe jetzt Versuch immer die selbe Probe zu messen und dann erst kalibirert und dann gemessen. In meiner Logik müssten dann für die Werte T 100 und A0 angezeigt werden, da die Kalbrierung und Messung identisch sind. Wenn ich mir jetzt sowohl bei readBlank() und bei readSample () die folgenden Werte averageRed, blankRed und sampleRed ausgeben lasse, sehe ich diese Werte:

readBlank: 112.00,112.00,0
readSample: 112.00,115.00,115

Damit ist dann auch klar, warum der Transmissionswert immer höher als 100% ist. Die Frage ist nun, woher der höhere Werte bei der zweiten Messung kommt.

Ich habe in dem Code den du gepostest hast keine einzige Zeile gefunden die

readBlank

ausgeben würde.

Wie soll man dir helfen wenn der Code den du gepostest hast sich von dem unterscheidet den du in deinen Postings dann zum erklären benutzt?

const int numReadings = 101;    //how many readings to take for each color

Überall da wo etwas eingelesen wird und wo etwas gerechnet wird.

Die Betonung auf überall ist ernst gemeint.
Man kann das so auf den Punkt bringen:
entweder du investierst Zeit um ganz allgemein Programmieren zu lernen
und schreibst das Programm selbst. Dann weißt du was du bei jeder Progammzeile machst und du brauchst wenig Zeit zum debuggen.
oder
du investierst Zeit in das Hinzufügen von wenn es sein muss 500 Zeilen Serial.print()
um dir von jedem Teilschritt anzeigen zu lassen was da für Einzel-Werte in einer Berechnung verwendet werden und was da für Zwischenergebnisse herauskommen.

Man kann auch die Halbierungsmethode anwenden:
Halbierungsmethode meinst du gehst als erstes in die Mite (= die Hälfte) des Codes in dem der entsprechende Wert berechnet wird un lässt dir das Zwischenergebnis

auf den seriellen Monitor

printen. Nicht auf das Display !

Wenn in der Hälfte alles I.O. ist dann setzt man das nächste serielle Print in die Mitte der unteren Hälfte.

Wenn in der Mitte schon ein Fehler auftritt dann setzt man das nächste serielle Print in die Mitte der oberen Hälfte. usw. usw.
Damit ist man dann nach 10 bis 15 Durchläufen auch an der Stelle wo der Fehler auftritt.

Wenn du die IDE 2.X verwendest: empfehle ich dir gaaaanz dringend zum debuggen eine portable-Version der IDE Version 1.8.19 zu installieren.
Die IDE 2.X hat eine total verkrüppelte serielle Ausgabe.
mit der man nur bruchstückhaft debuggen kann.

Hier ist die Anleitung wie man das macht

Wird auch nicht, soll auch nicht und zeigt, dass du den TO nicht verstehst.

Wie hast Du den Fototransistor angeschlossen?
Wie hast Du den 200 Ohm Poti angeschlossen / abgeglichen?
Hast Du Vorwiderstände an die RGB LED angeschlossen?
Hast Du die RGB LED und den Fototransistor gut von Umgebungslicht abgeschirmt/verdunkelt?

Du weißt schon daß Du nur in 3 ziemlich schmalbandigen Farben (Wellenlängen) mißt. Farbstoffe, die nicht in diesen Wellenlängen liegen haben keinen Einfluß auf die Messung.

Auch ist dasTutorial schlecht gemacht, Es fehlt ein Schaltplan/ Anschlußplan und die verlinkten Teile passen nicht wirklich zusammen ( 5V Mini mit 3,3V Display) Ich sehe keine Vorwiderstände an den LEDs.
Grüße Uwe

Grüße Uwe