Program Getting stuck during the running

Hi Team
I am using Color checking program using Two TCS3475 Color sensors
Both sensors are connected I2C multiplexer
Both Sensors are working and detecting and reading are coming with my another program
But when following program lines activated gest stuck

int color_index_1 = detectColorIndex(red_adjusted_1, green_adjusted_1, blue_adjusted_1);
  if (color_index_1 != -1) {
    sensor1_counts[color_index_1]++;
  }

above code is inside the ReadColor() function

Full Code

#include <Wire.h>
#include <Adafruit_TCS34725.h>

// Define the multiplexer address
#define TCAADDR 0x70

// Define pin for the calibration switch
#define CALIBRATION_SWITCH_PIN 2

// Initialize the sensors
Adafruit_TCS34725 tcs1 = Adafruit_TCS34725(TCS34725_INTEGRATIONTIME_154MS, TCS34725_GAIN_1X);
Adafruit_TCS34725 tcs2 = Adafruit_TCS34725(TCS34725_INTEGRATIONTIME_154MS, TCS34725_GAIN_1X);

// Color thresholds for detection (adjust according to your requirements)
#define COLOR_THRESHOLD 20
// Number of different colors
#define NUM_COLORS 3

// Define variables to store calibrated values
uint16_t red_calibrated_1 = 0;
uint16_t green_calibrated_1 = 0;
uint16_t blue_calibrated_1 = 0;
uint16_t clear_calibrated_1 = 0;

uint16_t red_calibrated_2 = 0;
uint16_t green_calibrated_2 = 0;
uint16_t blue_calibrated_2 = 0;
uint16_t clear_calibrated_2 = 0;

// Counter arrays for detected colors by each sensor
int sensor1_counts[NUM_COLORS] = {0};
int sensor2_counts[NUM_COLORS] = {0};

// Define colors for calibration
#define CALIBRATION_COLORS 3
enum CalibrationColor { RED, RED2 , GREEN, GREEN2, BLUE, BLUE2, STOP };

// Color detection function
bool detectColor(uint16_t red, uint16_t green, uint16_t blue);
// Current color being calibrated

CalibrationColor current_color = RED;
uint16_t STEP = 1;
void setup() {

  Serial.begin(9600);

  // Initialize the multiplexer
  Wire.begin();
  selectChannel(0);
  // Initialize the sensors
  if (!tcs1.begin() || !tcs2.begin()) {
    Serial.println("Error initializing TCS34725 sensors!");
    while (1);
  }

  // Initialize the calibration switch pin
  pinMode(CALIBRATION_SWITCH_PIN, INPUT_PULLUP);

  Serial.println("TCS34725 sensors found. Press the switch to calibrate each color.");
  Serial.println("TCS34725 sensors found. Press the switch to calibrate each color.");
}

void loop() {

  Serial.println("TCS34725 sensors found. Press the switch to calibrate each color.");
  // Calibration();
  Serial.println("Calibration completed.");
  while (1) {
    Serial.println("Coloer Reading");
    ReadColor();
  }
}

void ReadColor() {
  Serial.println("red_1");
  //  // Select and read data from sensor 1
  //  selectChannel(0);
  uint16_t red_1, green_1, blue_1, clear_1;
  tcs1.getRawData(&red_1, &green_1, &blue_1, &clear_1);
  Serial.println("red_1");
  //  // Adjust raw values using calibrated values for sensor 1
  uint16_t red_adjusted_1 = red_1 * 255 / red_calibrated_1;
  uint16_t green_adjusted_1 = green_1 * 255 / green_calibrated_1;
  uint16_t blue_adjusted_1 = blue_1 * 255 / blue_calibrated_1;
  uint16_t clear_adjusted_1 = clear_1 * 255 / clear_calibrated_1;
  Serial.println(red_1);
  //  // Select and read data from sensor 2
  selectChannel(1);
  uint16_t red_2, green_2, blue_2, clear_2;
  Serial.println("red_2");
  delay(200);
  //  tcs2.getRawData(&red_2, &green_2, &blue_2, &clear_2);

  // Adjust raw values using calibrated values for sensor 2
  uint16_t red_adjusted_2 = red_2 * 255 / red_calibrated_2;
  uint16_t green_adjusted_2 = green_2 * 255 / green_calibrated_2;
  uint16_t blue_adjusted_2 = blue_2 * 255 / blue_calibrated_2;
  uint16_t clear_adjusted_2 = clear_2 * 255 / clear_calibrated_2;

  Serial.println("Test_3");
  delay(400);
  //
  //  // Check for color detection in sensor 1
  int color_index_1 = detectColorIndex(red_adjusted_1, green_adjusted_1, blue_adjusted_1);
  if (color_index_1 != -1) {
    sensor1_counts[color_index_1]++;
  }
  Serial.println("Test_3");
  delay(400);
  //
  //  // Check for color detection in sensor 2
  //  int color_index_2 = detectColorIndex(red_adjusted_2, green_adjusted_2, blue_adjusted_2);
  //  if (color_index_2 != -1) {
  //    sensor2_counts[color_index_2]++;
  //  }
  
    // Print the count of detected color boxes for each sensor
    Serial.println("Sensor 1 Counts:");
    for (int i = 0; i < NUM_COLORS; i++) {
      Serial.print("Color ");
      Serial.print(i);
      Serial.print(": ");
      Serial.println(sensor1_counts[i]);
    }
  
    Serial.println("Sensor 2 Counts:");
    for (int i = 0; i < NUM_COLORS; i++) {
      Serial.print("Color ");
      Serial.print(i);
      Serial.print(": ");
      Serial.println(sensor2_counts[i]);
    }
  
    delay(1000); // Adjust delay according to your application

}
void Calibration() {
  while (STEP < 7) {

    // Check if the calibration switch is pressed
    if (digitalRead(CALIBRATION_SWITCH_PIN) == LOW) {
      // Calibrate the current color
      calibrateCurrentColor();

      // Move to the next color for calibration
      switch (current_color) {
        case RED:
          current_color = RED2;
          break;
        case RED2:
          current_color = GREEN;
          break;
        case GREEN:
          current_color = GREEN2;
          break;
        case GREEN2:
          current_color = BLUE;
          break;
        case BLUE:
          current_color = BLUE2;
          break;
        case BLUE2:
          current_color = STOP;
          break;
      }
      STEP++;
      //Serial.println("Calibration completed.");
      delay(1000); // Delay to avoid multiple calibration triggers
    }

    // Add your color detection and counting logic here

    delay(2000); // Adjust delay according to your application
  }
}

void calibrateCurrentColor() {
  // Read raw data from the sensor for the current color
  uint16_t red, green, blue, clear;
  readRawDataForColor(red, green, blue, clear);

  // Store raw data as calibrated values based on the current color
  switch (current_color) {
    case RED:
      red_calibrated_1 = red;
      Serial.println("RED Left Calibration values:");
      break;
    case RED2:
      red_calibrated_2 = red;
      Serial.println("RED Right Calibration values:");
      break;
    case GREEN:
      green_calibrated_1 = green;
      Serial.println("GREEN Left Calibration values:");
      break;
    case GREEN2:
      green_calibrated_2 = green;
      Serial.println("GREEN2 Right Calibration values:");
      break;
    case BLUE:
      green_calibrated_1 = blue;
      Serial.println("BLUE Left Calibration values:");
      break;
    case BLUE2:
      green_calibrated_2 = blue;
      Serial.println("BLUE2 Right Calibration values:");
      break;
  }

  Serial.print("Red: "); Serial.println(red);
  Serial.print("Green: "); Serial.println(green);
  Serial.print("Blue: "); Serial.println(blue);
  Serial.print("Clear: "); Serial.println(clear);
}

void readRawDataForColor(uint16_t &red, uint16_t &green, uint16_t &blue, uint16_t &clear) {
  // Select the appropriate sensor and channel based on the current color
  switch (current_color) {
    case RED:
      selectChannel(0);
      tcs1.getRawData(&red, &green, &blue, &clear);
      break;
    case RED2:
      selectChannel(1);
      tcs2.getRawData(&red, &green, &blue, &clear);
      break;
    case GREEN:
      selectChannel(0);
      tcs1.getRawData(&red, &green, &blue, &clear);
      break;
    case GREEN2:
      selectChannel(1);
      tcs1.getRawData(&red, &green, &blue, &clear);
      break;
    case BLUE:
      selectChannel(0);
      tcs1.getRawData(&red, &green, &blue, &clear);
      break;
  }
}
void selectChannel(uint8_t bus) {
  Wire.beginTransmission(0x70);
  Wire.write(1 << (bus + 2) ); // will be using 2-7 instead of 0-5 because of convience (placed better on the breadboard)
  Wire.endTransmission();
}


int detectColorIndex(uint16_t red, uint16_t green, uint16_t blue) {
  // Add color detection logic here based on RGB values and thresholds
  if (red > 255 - COLOR_THRESHOLD && green < COLOR_THRESHOLD && blue < COLOR_THRESHOLD) {
    return 0; // Detected red color
  }
  // Add more color detection conditions as needed
  return -1; // No color detected
}
bool detectColor(uint16_t red, uint16_t green, uint16_t blue) {
  // Add color detection logic here based on RGB values and thresholds
  if (red > 255 - COLOR_THRESHOLD && green < COLOR_THRESHOLD && blue < COLOR_THRESHOLD) {
    return true; // Detected red color
  }
  // Add more color detection conditions as needed
  return false;
}

The program is getting stuck at the forth line of the ReadColor() function

Please advise
Thanks in advanced

What happens when color_index_1 is "undefined" due to division by zero?

can you please more elaborate it

Shouldn’t you actually run the calibration routine?

which type of arduino are you using?

how do you know?

Even comment the Calibration(); function problem remaining same

I am checking with serial Monitor

Serial printing is asynchronous meaning your code will continue to run after you issued a Serial.print() and so you can't really judge by what you see or don't see where the program was when it crashed.

if you add a Serial.flush(); after your print, it will make the code wait there until really all the printing has been done. Then it's not asynchronous anymore and you can really know where you are in the program.

1 Like

What is the value of red_calibrated_1 the very first time this instruction is executed?

1 Like

The problem was solved when following variables define globally, Previously them are in locally

uint16_t red_1, green_1, blue_1, clear_1;
uint16_t red_2, green_2, blue_2, clear_2;

I am confused

A global variable keeps the assigned value through every function.
A local variable keeps its value only inside its "local" scope (function).

This is the worst program I could every write not using delay()... I added some comment for you to follow.... the result should be "9600, 7, 8, 2, 9600"

int a = 9600; // global "a"
void setup() {
  Serial.begin(a);
  Serial.println(a);
  int a = 2; // locally defined in "setup()"

  for (int a = 7; a < 9; a++) { // local-local definition inside "for"
    Serial.println(a);
  }
  Serial.println(a); // the "local a" in "setup"
}
void loop() {
  Serial.println(a); // this is the global "a"
  while(1);
}
1 Like

Grate thanks for perfect answer

Even it local variable or globe variable if program is compiled successfully how it getting stuck in the IC

? is that a question? could you rephrase?

Sorry please check

sorry, I don't get what you mean with

If a variable is declared as either a global or a local variable, the program compiles successfully without errors. How the program might encounter stuck inside the IC

yes. it's legit in C++ to reuse a variable's identifier inside a inner statement

âžś read about scope

1 Like

You must remember; all programs do exactly as you program them, so if a program is stuck because it was programmed to be stuck. We search for the reason. In my example in Post #12 I use "Serial.println();" often to see how "a" is changed. This is called "using debug statements" to find where variables are "good" and where they become "bad."

Some people have asked the value of "red_calibrated_1" (and other colors) because the first use of it is in a division. If "red_calibrated_1" starts at "0", a using it in a division becomes "undefined" ( x / 0 = undefined). Do you see this concern about "0"? Can you "Serial.println()" the value of all "color_calibrated_#" to verify you are not dividing by zero?

If you are dividing by zero, then why? As another person indicated, you commented-out "calibrate()"... which probably gives values to variables.

Try to find these data... start with the "calibrated()" missing issue...

If your program is “stuck”, “hung”, “lost” or “misbehaving” or resetting the Arduino look for

  • Too many strings
  • Divisions (make sure denominator is not zero)
  • Out of bound array references (often times off-by-one)
  • Other stuff, such as recursive calls, int overflow, while loops, stray semicolons, …

Serial.print() can help you track how a variable changes its value and pinpoint some errors

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