color sensor within a menu

hi! i'm working on a project to determine the concentration of iron using a TC3200 color sensor. I've managed to get that working after calibrating but I am having difficulty integrating that code into a code with a menu. i am able to upload the final code without any error but it doesn't seem to display the concentration values on my LCD. everything else works fine and is printed on the lcd.

*the codes for the menu and color sensor work fine on their own but not together

materials used:
tc3200 color sensor
16x2 LCD i2c
rotary encoder
arduino mega (a clone but I've downloaded the drivers)

functions:

  1. menu: (single-level) consists of 6 items (one of which will trigger the LCD to start printing the concentration values).
  2. color sensor used to detect iron concentrations
  3. basic settings (volume, power mode)

I'm a newbie and I'm not sure where i went wrong
so any advice or help would be appreciated, thanks!
here's my code:

#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x3F, 16, 2);


// rotary encoder inputs
#define Clock 9   //clock pin connected to D9
#define Data 8    //data pin connected to D8
#define Push 10   //push button pin connected to D10

#define S0 4 // S0 to pin 4
#define S1 5 // S1 to pin 5
#define S2 6 // S2 to pin 6
#define S3 7 // S3 to pin 7
#define sensorOut 11 // OUT to pin 11

int counter = 1;                    //use this variable to store "steps"
int currentStateClock;            //store the status of the clock pin (HIGH or LOW)
int lastStateClock;                //store the PREVIOUS status of the clock pin (HIGH or LOW)
String currentDir = "";             //use this to print text
unsigned long lastButtonPress = 0;  //use this to store if the push button was pressed or not

int pushed = 0; // create variable pushed to count when the button has been pushed
int menu = 0; // create variable to count menu


// variables for color sensor
float inv_green;
int frequency = 0;
float concentration = 0.0000;

void updateMenu() {
  switch (menu) {
    case 0:
      menu = 1;
      break;
    case 1:
      lcd.clear();
      lcd.print("> Start");
      lcd.setCursor(0, 1);
      lcd.print("  Patient Details");
      break;
    case 2:
      lcd.clear();
      lcd.print("  Start");
      lcd.setCursor(0, 1);
      lcd.print("> Patient Details");
      break;
    case 3:
      lcd.clear();
      lcd.print("> Power Mode");
      lcd.setCursor(0, 1);
      lcd.print("  Volume");
      break;
    case 4:
      lcd.clear();
      lcd.print("  Power Mode");
      lcd.setCursor(0, 1);
      lcd.print("> Volume");
      break;
    case 5:
      menu = 4;
      break;
  }//switch menu
}//void updatemenu

void Enterdetails() {
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("Please Enter");
  lcd.setCursor(0, 1);
  lcd.print("Patient ID: ");


}// void enterdetails

void concentrationDetector() {

  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("Please wait...");
  delay(1000);
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("Detecting...");
  delay(1000);

   // printing concentration of iron on I2C LCD
  lcd.clear();
  lcd.setCursor(0, 0);         // move cursor to   (0, 0)
  lcd.print("Concentration"); // print message at (0, 0)
  lcd.setCursor(0, 1);         // move cursor to   (0, 1)
  lcd.print(concentration); // print message at (0, 1)


}// void concentration detector

void powerMode() {
  lcd.clear();
  lcd.print("Executing...");
  delay(1500);

  //code for power mode

} // void power

void adjustVolume() {
  lcd.clear();
  lcd.print("Executing...");
  delay(1500);

  //code for volume

} // void adjust volume



void executeAction1() {
  switch (menu) {
    case 1:
      concentrationDetector();
      break;
    case 2:
      Enterdetails();
      break;
    case 3:
      powerMode();
      break;
    case 4:
      adjustVolume();
      break;
  }// switch menu
}//void action 1

void setup() {
  lcd.init();
  lcd.backlight();
  pinMode(Clock, INPUT_PULLUP);// clock, input pullup
  pinMode(Data, INPUT_PULLUP); // data, input pullup
  pinMode(Push, INPUT_PULLUP); // push, input pullup
  updateMenu();

  pinMode(S0, OUTPUT);
  pinMode(S1, OUTPUT);
  pinMode(S2, OUTPUT);
  pinMode(S3, OUTPUT);


  // Setting the sensorOut as an input
  pinMode(sensorOut, INPUT);

  // Setting frequency-scaling to 20%
  digitalWrite(S0, HIGH);
  digitalWrite(S1, LOW);

  lcd.clear();
  lcd.setCursor(0, 0);         // move cursor to   (0, 0)
  lcd.print("Setup "); // print message at (0, 0)
  lcd.setCursor(0, 1);         // move cursor to   (0, 1)
  lcd.print("Initiating"); // print message at (0, 1)
  delay(2000);
  
  lcd.clear();
  lcd.setCursor(0, 0);         // move cursor to   (0, 0)
  lcd.print("Setup ");// print message at (0, 0)
  lcd.setCursor(0, 1);         // move cursor to   (0, 1)
  lcd.print("Initiated"); // print message at (0, 1)
  delay(2000);

  Serial.begin(9600);
}


void loop()
{
  counter = constrain(counter, -1, 4);

  // Read the current state of CLK
  currentStateClock = digitalRead(Clock);


  if (currentStateClock != lastStateClock  && currentStateClock == 1) {


    if (digitalRead(Data) != currentStateClock) {
      updateMenu();
      menu++;
      counter ++;
      currentDir = "Counterclockwise";
    } else {
      // Encoder is rotating CW so increment

      updateMenu();
      menu--;
      counter --;
      currentDir = "Clockwise";
    }

    Serial.print("Direction: ");
    Serial.print(currentDir);
    Serial.print(" | Counter: ");
    Serial.println(counter);
  }

  // We save last Clock state for next loop
  lastStateClock = currentStateClock;

  // Read the button state
  int btnState = digitalRead(Push);

  //If we detect LOW signal, button is pressed
  if (btnState == LOW) {
    //if 50ms have passed since last LOW pulse, it means that the
    //button has been pressed, released and pressed again
    if (millis() - lastButtonPress > 50) {
      Serial.println("Button pressed!");
      executeAction1();

    }

    // Remember last button press event
    lastButtonPress = millis();
  }

  // Put in a slight delay to help debounce the reading
  delay(1);
  
// Setting Red filtered photodiodes to be read
  digitalWrite(S2, LOW);
  digitalWrite(S3, LOW);
  // Reading the output frequency
  frequency = pulseIn(sensorOut, LOW);
  //Remaping the value of the frequency to the RGB Model of 0 to 255
  frequency = map(frequency, 1985,1985, 255, 0);
  // Printing the value on the serial monitor
  Serial.print("R= ");//printing name
  Serial.print(frequency);//printing RED color frequency
  Serial.print("  ");
  delay(100);

  // Setting Green filtered photodiodes to be read
  digitalWrite(S2, HIGH);
  digitalWrite(S3, HIGH);
  // Reading the output frequency
  frequency = pulseIn(sensorOut, LOW);
  //Remaping the value of the frequency to the RGB Model of 0 to 255
  frequency = map(frequency, 2187,2236, 255, 0);
  // Printing the value on the serial monitor
  Serial.print("G= ");//printing name
  Serial.print(frequency);//printing GREEN color frequency
  Serial.print("  ");
  delay(100);

  // putting our inverse green values to our equation
  inv_green = 1.0000 / frequency  ;

  Serial.print("inverse green= ");//printing name
  Serial.print(inv_green,7);//printing RED color frequency
  Serial.print("  ");
  delay(100);

  concentration = (inv_green - 0.0039) / (5 * pow(10, -5)); // here frequency is Red filtered photodiodes Value
 
  //printing concentration
  Serial.print("Concentration= ");
  Serial.print(concentration,5);
  Serial.print("  ");
  delay(100);
 
  // Setting Blue filtered photodiodes to be read
  digitalWrite(S2, LOW);
  digitalWrite(S3, HIGH);
  // Reading the output frequency
  frequency = pulseIn(sensorOut, LOW);
  //Remaping the value of the frequency to the RGB Model of 0 to 255
  frequency = map(frequency, -900, -885, 255, 0);
 // Printing the value on the serial monitor
  Serial.print("B= ");//printing name
  Serial.print(frequency);//printing BLUE color frequency
  Serial.println("  ");
  delay(100);
}

This code should show the value on the Serial Monitor; I guess that works?

soniak:

  //printing concentration

Serial.print("Concentration= ");
  Serial.print(concentration,5);
  Serial.print("  ");}

Now if you add some code to print it on the lcd as well, it might just show up... :wink:

  lcd.setCursor(0,0);
  lcd.print("Concentration= ");
  lcd.print(concentration);
  lcd.print("  ");

thanks for your reply @Erik_Baas, appreciate it. :slight_smile: unfortunately, there isn't anything showing up on my serial monitor except for the things I wanted to be printed for the rotary encoder.

about the lcd printing, I had some codes for that in the concentrationDetector() function. would that code be able to pull values like the concentration from the void loop() function to the concentrationDetector() function? or is that not possible? again, I'm new and I apologise if this is a stupid question haha! thanks again, mate.

void concentrationDetector() {
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("Please wait...");
  delay(1000);
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("Detecting...");
  delay(1000);

   // printing concentration of iron on I2C LCD
  lcd.clear();
  lcd.setCursor(0, 0);         // move cursor to   (0, 0)
  lcd.print("Concentration"); // print message at (0, 0)
  lcd.setCursor(0, 1);         // move cursor to   (0, 1)
  lcd.print(concentration); // print message at (0, 1)

}// void concentration detector

Oh. But you wrote:

soniak:
doesn't seem to display the concentration values on my LCD

That's why I assumed there was no problem on the serial monitor...

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