Colour Sensor and Midi Out Question

Hello to all :slight_smile: I have a colour sensor (tcs3200) detecting colours on a spinning wheel and sending midi according to each colour. My problem is that I need to send a NoteOn only once and not multiple times while the sensor remains on it's passing colour. I have taken a piece of code that worked well for a capacitive sensor doing something similar and tried to work it here for the colour sensor but without luck.

This is the part giving me trouble

 int RED = val;

  bool sensorHit1 = val;
  static boolean lastSensorHit1 = false;

  if (tmpr<210 & tmpr>160 & tmpg < 40 & tmpb < 10) {//RED
    val = RED;

    if (sensorHit1 != lastSensorHit1)
      if (sensorHit1 && !lastSensorHit1)
      {
        MIDI.sendNoteOn(79, 127, 1);    // Send a Note (pitch 79, velo 127 on channel 1)
        MIDI.sendControlChange(64, 127, 1);
      }

      else {

        MIDI.sendNoteOff(79, 0, 1);     // Stop the note
        MIDI.sendControlChange(64, 0, 1);


      }
    lastSensorHit1 = sensorHit1;


  }
}

Any pointers in the right direction very much appreciated :slight_smile:
Entire code here

/*
  // TCS230 color recognition sensor
  // Sensor connection pins to Arduino are shown in comments

  Color Sensor      Arduino
  -----------      --------
  VCC               5V
  GND               GND
  s0                8
  s1                9
  s2                12
  s3                11
  OUT               10
  OE                GND
*/
#include <MIDI.h>
int val;
const int s0 = 8;
const int s1 = 9;
const int s2 = 12;
const int s3 = 11;
const int out = 10;

// LED pins connected to Arduino
int redLed = 5;
int greenLed = 6;
int blueLed = 7;
// Variables
int red = 0;
int green = 0;
int blue = 0;
const int rgbr = 7;
const int rgbg = 6;
const int rgbb = 5;

MIDI_CREATE_DEFAULT_INSTANCE();

void setup()
{
  MIDI.begin();                      // Launch MIDI and listen to channel 4

  Serial.begin(9600);
  pinMode(s0, OUTPUT);
  pinMode(rgbr, OUTPUT);
  pinMode(rgbg, OUTPUT);
  pinMode(rgbb, OUTPUT);
  pinMode(s1, OUTPUT);
  pinMode(s2, OUTPUT);
  pinMode(s3, OUTPUT);
  pinMode(out, INPUT);
  pinMode(redLed, OUTPUT);
  pinMode(greenLed, OUTPUT);
  pinMode(blueLed, OUTPUT);
  digitalWrite(s0, HIGH);
  digitalWrite(s1, HIGH);
}

void loop()
{
  color();

  int tmpr = (((20 - red) - 10) * 30); //int tmpr=(((20-red)-10)*30);
  int tmpg = (((20 - green) - 10) * 30); //int tmpg=(((20-green)-10)*30);
  int tmpb = (((20 - blue) - 10) * 30); //  int tmpb=(((20-blue)-10)*30);

  if (tmpr < 0)
    tmpr = 0;

  if (tmpg < 0)
    tmpg = 0;

  if (tmpb < 0)
    tmpb = 0;

  if (tmpg > tmpb && tmpg > tmpr)
  { tmpb = 0;
    tmpr = 0;
  }
  analogWrite(rgbr, tmpr);
  analogWrite(rgbg, tmpg );
  analogWrite(rgbb, tmpb );


  int RED = val;

  bool sensorHit1 = val;
  static boolean lastSensorHit1 = false;

  if (tmpr<210 & tmpr>160 & tmpg < 40 & tmpb < 10) {//RED
    val = RED;

    if (sensorHit1 != lastSensorHit1)
      if (sensorHit1 && !lastSensorHit1)
      {
        MIDI.sendNoteOn(79, 127, 1);    // Send a Note (pitch 79, velo 127 on channel 1)
        MIDI.sendControlChange(64, 127, 1);
      }

      else {

        MIDI.sendNoteOff(79, 0, 1);     // Stop the note
        MIDI.sendControlChange(64, 0, 1);


      }
    lastSensorHit1 = sensorHit1;


  }
}
void color()
{
  digitalWrite(s2, LOW);
  digitalWrite(s3, LOW);
  //count OUT, pRed, RED


  red = pulseIn(out, digitalRead(out) == HIGH ? LOW : HIGH);

  digitalWrite(s3, HIGH);
  //count OUT, pBLUE, BLUE
  blue = pulseIn(out, digitalRead(out) == HIGH ? LOW : HIGH);
  digitalWrite(s2, HIGH);
  //count OUT, pGreen, GREEN
  green = pulseIn(out, digitalRead(out) == HIGH ? LOW : HIGH);

  //}
  delay(50);
}
 if (tmpr<210 & tmpr>160 & tmpg < 40 & tmpb < 10) {//RED

& and && are completely different operators.

    if (sensorHit1 != lastSensorHit1)
      if (sensorHit1 && !lastSensorHit1)

If they are not the same, is there any chance that one will be true and the other not false? Is there any point in testing something you KNOW will be true?

What does sensorHit mean for a color sensor?

The code does something. You expect it to do something. What those two things are is a complete mystery.

  pinMode(out, INPUT);

Naming an input out makes not a lick of sense.

  int tmpr = (((20 - red) - 10) * 30); //int tmpr=(((20-red)-10)*30);
  int tmpg = (((20 - green) - 10) * 30); //int tmpg=(((20-green)-10)*30);
  int tmpb = (((20 - blue) - 10) * 30); //  int tmpb=(((20-blue)-10)*30);

Useless comments.

I'm afraid the useless comments were a reminder of optimal settings whilst I altered values..

This is the previous code I have with midi working but with the use of delays. With my last addition being a jumbled mess, how would you suggest I begin to solve my problem Paul?

/*
  // TCS230 color recognition sensor
  // Sensor connection pins to Arduino are shown in comments

  Color Sensor      Arduino
  -----------      --------
  VCC               5V
  GND               GND
  s0                8
  s1                9
  s2                12
  s3                11
  OUT               10
  OE                GND
*/
#include <MIDI.h>
int val;
const int s0 = 8;
const int s1 = 9;
const int s2 = 12;
const int s3 = 11;
const int out = 10;

// LED pins connected to Arduino
int redLed = 5;
int greenLed = 6;
int blueLed = 7;
// Variables
int red = 0;
int green = 0;
int blue = 0;
int indeks = 0;
const int rgbr = 7;
const int rgbg = 6;
const int rgbb = 5;

MIDI_CREATE_DEFAULT_INSTANCE();

void setup()
{
  MIDI.begin();                      // Launch MIDI and listen to channel 4

  Serial.begin(9600);
  pinMode(s0, OUTPUT);
  pinMode(rgbr, OUTPUT);
  pinMode(rgbg, OUTPUT);
  pinMode(rgbb, OUTPUT);
  pinMode(s1, OUTPUT);
  pinMode(s2, OUTPUT);
  pinMode(s3, OUTPUT);
  pinMode(out, INPUT);
  pinMode(redLed, OUTPUT);
  pinMode(greenLed, OUTPUT);
  pinMode(blueLed, OUTPUT);
  digitalWrite(s0, HIGH);
  digitalWrite(s1, HIGH);
}

void loop()
{
  color();

  int tmpr = (((20 - red) - 10) * 30); //int tmpr=(((20-red)-10)*30);
  int tmpg = (((20 - green) - 10) * 30); //int tmpg=(((20-green)-10)*30);
  int tmpb = (((20 - blue) - 10) * 30); //  int tmpb=(((20-blue)-10)*30);

  if (tmpr < 0)
    tmpr = 0;

  if (tmpg < 0)
    tmpg = 0;

  if (tmpb < 0)
    tmpb = 0;

  if (tmpg > tmpb && tmpg > tmpr)
  { tmpb = 0;
    tmpr = 0;
  }
  analogWrite(rgbr, tmpr);
  analogWrite(rgbg, tmpg );
  analogWrite(rgbb, tmpb );

  
  int firstNote = val;
  int lastNote = 0;
  int newNote = firstNote;

  if (tmpr<210 & tmpr>160 & tmpg < 40 & tmpb < 10) {//RED
    MIDI.sendNoteOn(79, 127, 1);    // Send a Note (pitch 79, velo 127 on channel 1)
    MIDI.sendControlChange(64, 127, 1);
    delay(50);
  }
  else {
    MIDI.sendNoteOff(79, 0, 1);     // Stop the note

  }
  if (tmpr<10  & tmpg > 140 & tmpb < 90) { //LIME GREEN

    MIDI.sendNoteOn(82, 127, 1);    // Send a Note (pitch 79, velo 127 on channel 1)
    MIDI.sendControlChange(64, 127, 1);
    delay(150);
  }
  else {
    MIDI.sendNoteOff(82, 0, 1);     // Stop the note
  }
  if (tmpr<10 &  & tmpg > 25 & tmpg < 50 & tmpb < 70 & tmpb > 45) { //LIGHT BLUE

    MIDI.sendNoteOn(85, 127, 1);    // Send a Note (pitch 79, velo 127 on channel 1)
    MIDI.sendControlChange(64, 127, 1);
    delay(150);
  }
  else {
    MIDI.sendNoteOff(85, 0, 1);     // Stop the note

  }
  

  }


void color()
{
  digitalWrite(s2, LOW);
  digitalWrite(s3, LOW);
  //count OUT, pRed, RED


  red = pulseIn(out, digitalRead(out) == HIGH ? LOW : HIGH);

  digitalWrite(s3, HIGH);
  //count OUT, pBLUE, BLUE
  blue = pulseIn(out, digitalRead(out) == HIGH ? LOW : HIGH);
  digitalWrite(s2, HIGH);
  //count OUT, pGreen, GREEN
  green = pulseIn(out, digitalRead(out) == HIGH ? LOW : HIGH);

}

Is State Change Detection the best way to do this?
And if so, how do I use a value such as "val = RED" instead of using a HIGH or LOW read from a digital pin?

Is State Change Detection the best way to do this?

In my opinion? No.

What state do you think is changing? The color read by the sensor is a value, not a state.

You might be concerned about the red component of the color changing from "really red" to "not really red" or from "not really red" to "really red", in which case the state change is detectable.

But, a change of the color sensed, from [240, 128, 125] to [127, 35, 209] isn't a state change.

Thanks Paul. I had borrowed a sketch for a colour sorting machine which used a switch statement to sort between the colours but while i could use that to trigger midi notes, I couldn't figure out how to stop sending notes whilst on the same colour. Is it better to use a switch statement for this solution?

The original code using servos in the switch statement

    /*     Arduino Project - Color Sorting Machine
     *
     *  by Dejan Nedelkovski, www.HowToMechatronics.com
     *
     */
    #include <Servo.h>
    #define S0 8
    #define S1 9
    #define S2 12
    #define S3 11
    #define sensorOut 10
    Servo topServo;
    Servo bottomServo;
    int frequency = 0;
    int color=0;
    void setup() {
      pinMode(S0, OUTPUT);
      pinMode(S1, OUTPUT);
      pinMode(S2, OUTPUT);
      pinMode(S3, OUTPUT);
      pinMode(sensorOut, INPUT);
      // Setting frequency-scaling to 20%
      digitalWrite(S0, HIGH);
      digitalWrite(S1, LOW); // digitalWrite(S1, LOW);
      topServo.attach(7);
      bottomServo.attach(8);
      Serial.begin(9600);
    }
    void loop() {
      topServo.write(115);
      //delay(500);
      
      for(int i = 115; i > 65; i--) {
        topServo.write(i);
        //delay(2);
      }
      //delay(500);
      
      color = readColor();
      delay(10);  
      switch (color) {
        case 1:
        bottomServo.write(50);
        break;
        case 2:
        bottomServo.write(75);
        break;
        case 3:
        bottomServo.write(100);
        break;
        case 4:
        bottomServo.write(125);
        break;
        case 5:
        bottomServo.write(150);
        break;
        case 6:
        bottomServo.write(175);
        break;
        
        case 0:
        break;
      }
      delay(300);
      
      for(int i = 65; i > 29; i--) {
        topServo.write(i);
        delay(2);
      } 
      delay(200);
      
      for(int i = 29; i < 115; i++) {
        topServo.write(i);
        delay(2);
      }
      color=0;
    }
    // Custom Function - readColor()
    int readColor() {
      // Setting red filtered photodiodes to be read
      digitalWrite(S2, LOW);
      digitalWrite(S3, LOW);
      // Reading the output frequency
      frequency = pulseIn(sensorOut, LOW);
      int R = frequency;
      // Printing the value on the serial monitor
      Serial.print("R= ");//printing name
      Serial.print(frequency);//printing RED color frequency
      Serial.print("  ");
      delay(50);
      // Setting Green filtered photodiodes to be read
      digitalWrite(S2, HIGH);
      digitalWrite(S3, HIGH);
      // Reading the output frequency
      frequency = pulseIn(sensorOut, LOW);
      int G = frequency;
      // Printing the value on the serial monitor
      Serial.print("G= ");//printing name
      Serial.print(frequency);//printing RED color frequency
      Serial.print("  ");
      delay(50);
      // Setting Blue filtered photodiodes to be read
      digitalWrite(S2, LOW);
      digitalWrite(S3, HIGH);
      // Reading the output frequency
      frequency = pulseIn(sensorOut, LOW);
      int B = frequency;
      // Printing the value on the serial monitor
      Serial.print("B= ");//printing name
      Serial.print(frequency);//printing RED color frequency
      Serial.println("  ");
      delay(50);
      if(R<45 & R>32 & G<65 & G>55){
        color = 1; // Red
      }
      if(G<55 & G>43 & B<47 &B>35){
        color = 2; // Orange
      }
      if(R<53 & R>40 & G<53 & G>40){
        color = 3; // Green
      }
      if(R<38 & R>24 & G<44 & G>30){
        color = 4; // Yellow
      }
      if(R<56 & R>46 & G<65 & G>55){
        color = 5; // Brown
      }
      if (G<58 & G>45 & B<40 &B>26){
        color = 6; // Blue
      }
      return color;  
    }

the code below uses the switch statement to send a midi note but used a delay which is not practical.

    /*     Arduino Project - Color Sorting Machine
     *
     *  by Dejan Nedelkovski, www.HowToMechatronics.com
     *
     */
    #include <MIDI.h>
    #include <Servo.h>
    #define S0 8
    #define S1 9
    #define S2 12
    #define S3 11
    #define sensorOut 10
    Servo topServo;
    Servo bottomServo;
    int frequency = 0;
    int color=0;
    
    MIDI_CREATE_DEFAULT_INSTANCE();

    void setup() {
          MIDI.begin();                      // Launch MIDI and listen to channel 4
      pinMode(S0, OUTPUT);
      pinMode(S1, OUTPUT);
      pinMode(S2, OUTPUT);
      pinMode(S3, OUTPUT);
      pinMode(sensorOut, INPUT);
      // Setting frequency-scaling to 20%
      digitalWrite(S0, HIGH);
      digitalWrite(S1, LOW); // digitalWrite(S1, LOW);
      topServo.attach(7);
      bottomServo.attach(8);
      Serial.begin(9600);
    }
    void loop() {
      //topServo.write(115);
      //delay(500);
      
      //for(int i = 115; i > 65; i--) {
        //topServo.write(i);
        //delay(2);
      //}
      //delay(500);
      
      color = readColor();
      delay(10);  
      switch (color) {
        case 1:
        bottomServo.write(50);
        MIDI.sendNoteOn(42, 127, 1);    // Send a Note (pitch 42, velo 127 on channel 1)
        delay(300);                // Wait for a second
        MIDI.sendNoteOff(42, 0, 1);     // Stop the note
        
        break;
        case 2:
        bottomServo.write(75);
        break;
        case 3:
        bottomServo.write(100);
        break;
        case 4:
        bottomServo.write(125);
        break;
        case 5:
        bottomServo.write(150);
        break;
        case 6:
        bottomServo.write(175);
        break;
        
        case 0:
        break;
      }
      //delay(300);
      
      //for(int i = 65; i > 29; i--) {
      //  topServo.write(i);
      //  delay(2);
      //} 
      //delay(200);
      
      //for(int i = 29; i < 115; i++) {
        //topServo.write(i);
        //delay(2);
      //}
      color=0;
    }
    // Custom Function - readColor()
    int readColor() {
      // Setting red filtered photodiodes to be read
      digitalWrite(S2, LOW);
      digitalWrite(S3, LOW);
      // Reading the output frequency
      frequency = pulseIn(sensorOut, LOW);
      int R = frequency;
      // Printing the value on the serial monitor
      //Serial.print("R= ");//printing name
      //Serial.print(frequency);//printing RED color frequency
      //Serial.print("  ");
      //delay(50);
      // Setting Green filtered photodiodes to be read
      digitalWrite(S2, HIGH);
      digitalWrite(S3, HIGH);
      // Reading the output frequency
      frequency = pulseIn(sensorOut, LOW);
      int G = frequency;
      // Printing the value on the serial monitor
      //Serial.print("G= ");//printing name
      //Serial.print(frequency);//printing RED color frequency
      //Serial.print("  ");
      //delay(50);
      // Setting Blue filtered photodiodes to be read
      digitalWrite(S2, LOW);
      digitalWrite(S3, HIGH);
      // Reading the output frequency
      frequency = pulseIn(sensorOut, LOW);
      int B = frequency;
      // Printing the value on the serial monitor
      //Serial.print("B= ");//printing name
      //Serial.print(frequency);//printing RED color frequency
      //Serial.println("  ");
      //delay(50);
      if(R<25 & R>14 & G<90 & G>78){
        color = 1; // Red
      }
      if(G<55 & G>43 & B<47 &B>35){
        color = 2; // Orange
      }
      if(R<53 & R>40 & G<53 & G>40){
        color = 3; // Green
      }
      if(R<38 & R>24 & G<44 & G>30){
        color = 4; // Yellow
      }
      if(R<56 & R>46 & G<65 & G>55){
        color = 5; // Brown
      }
      if (G<58 & G>45 & B<40 &B>26){
        color = 6; // Blue
      }
      return color;  
    }

Is it better to use a switch statement for this solution?

Better than honey-roasted peanuts?

I find your code VERY hard to follow. Please, use at least one blank line between functions. Use Tools + Auto Format, so the code is properly indented. DELETE code that you are not using, rather than commenting it out. Limit the scope of variables to the smallest possible scope. There is NO reason for frequency to be global. There is really no reason for that variable at all. Directly store the output of pulseIn() into R, G, and B.

The readColor() function incorrectly uses & in place of &&. In the end, though, it returns (uselessly) a global variable that contains one of 7 values - 0 to 6.

The value that it returns on one call might be the same as the value that it returned last time, in which case you should ignore it, or it might be different, in which case you should use it.

To know, of course, you need to keep track of the current value and the previous value, and act only when the current value is not the same as the previous value.

Thanks Paul, honey roasted are hard to beat!

Now to try and roast the rest of this code!

:slight_smile: Slowly but surely I managed to get this working the way I need it to work for now. However, if PaulS or anyone else for that matter could tell me why the LED only stays lit on green and not the other colours, I'd be grateful. Midi notes act as they should for all colours. That is, they sustain without repeating whilst dwelling on each colour...

*/
#include <MIDI.h>

#define S0 8
#define S1 9
#define S2 12
#define S3 11
#define sensorOut 10
int frequency;
int color = 0;

// Variables:

int sensorState1      = 0;     // current state of sensor
int sensorState2      = 0;     // current state of sensor
int sensorState3      = 0;     // current state of sensor

int lastSensorState1  = 0;     // previous state of the sensor
int lastSensorState2  = 0;     // previous state of the sensor
int lastSensorState3  = 0;     // previous state of the sensor

static const unsigned ledPin1 = 3;      // LED pin on Arduino Mega
MIDI_CREATE_DEFAULT_INSTANCE();


void setup() {
  pinMode(S0, OUTPUT);
  pinMode(S1, OUTPUT);
  pinMode(S2, OUTPUT);
  pinMode(S3, OUTPUT);
  pinMode(sensorOut, INPUT);
  pinMode(ledPin1, OUTPUT);

  // Setting frequency-scaling to 20%
  digitalWrite(S0, LOW);
  digitalWrite(S1, HIGH); 
  Serial.begin(9600);
}

void loop() {

  color = readColor();
  sensorState1 = readColor();
  if (sensorState1 != lastSensorState1) {
    if (sensorState1 == 1)

    {
      digitalWrite(ledPin1, HIGH);
      MIDI.sendNoteOn(80, 127, 1);    // Send a Note (pitch 80, velo 127 on channel 1)
      MIDI.sendControlChange(64, 127, 1);
    }

    else {
      digitalWrite(ledPin1, LOW);
      MIDI.sendNoteOff(80, 0, 1);     // Stop the note
      MIDI.sendControlChange(64, 0, 1);
    }


    sensorState2 = readColor();
    if (sensorState2 != lastSensorState2) {
      if (sensorState2 == 2)

      {
        digitalWrite(ledPin1, HIGH);
        MIDI.sendNoteOn(72, 127, 1);    // Send a Note (pitch 72, velo 127 on channel 1)
        MIDI.sendControlChange(64, 127, 1);
      }

      else {
        digitalWrite(ledPin1, LOW);
        MIDI.sendNoteOff(72, 0, 1);     // Stop the note
        MIDI.sendControlChange(64, 0, 1);
      }


      sensorState3 = readColor();
      if (sensorState3 != lastSensorState3) {
        if (sensorState3 == 3)

        {
          digitalWrite(ledPin1, HIGH);
          MIDI.sendNoteOn(64, 127, 1);    // Send a Note (pitch 64, velo 127 on channel 1)
          MIDI.sendControlChange(64, 127, 1);
        }

        else {
          digitalWrite(ledPin1, LOW);
          MIDI.sendNoteOff(64, 0, 1);     // Stop the note
          MIDI.sendControlChange(64, 0, 1);
        }
      }
    }
    
    lastSensorState1 = sensorState1;
    lastSensorState2 = sensorState2;
    lastSensorState3 = sensorState3;

  }
  color = 0;
  delay(50);
}



// Custom Function - readColor()
int readColor() {
  // Setting red filtered photodiodes to be read
  digitalWrite(S2, LOW);
  digitalWrite(S3, LOW);
  // Reading the output frequency
  frequency = pulseIn(sensorOut, LOW);
  int R = frequency;

  // Setting Green filtered photodiodes to be read
  digitalWrite(S2, HIGH);
  digitalWrite(S3, HIGH);
  // Reading the output frequency
  frequency = pulseIn(sensorOut, LOW);
  int G = frequency;

  // Setting Blue filtered photodiodes to be read
  digitalWrite(S2, LOW);
  digitalWrite(S3, HIGH);
  // Reading the output frequency
  frequency = pulseIn(sensorOut, LOW);
  int B = frequency;

  if (R < 31 && R > 23 && G < 110 && G > 98 && B < 85 && B > 73) {
    color = 1;
  }
  if (G < 50 && G > 39 && B < 60 && B > 50 && R < 21 && R > 13) {
    color = 2; // Orange
  }
  if (R < 41 && R > 30 && G < 35 && G > 24 && B < 51 && B > 40) {
    color = 3; // Green
  }
  return color;
}

Why does your posted code start with an end comment marker?

  color = readColor();
  sensorState1 = readColor();

The first line makes sense. Storing a color (for ANY definition of color) in a variable called sensorState1 makes NO sense.

The readColor() function modifies a global variable, and then returns the global variable. Why? There is NO reason for the function to f**k with a global variable.

frequency is a global variable but it is used only in readColor(), and then used only uselessly. The value returned by pulseIn() should be stored directly in R, G, or B, depending on when it is called.

The value returned by pulseIn() is a time, NOT a frequency. "That discrete event took n microseconds" says NOTHING about frequency.

could tell me why the LED only stays lit on green and not the other colours

I have NO clue what you are asking. You are returning values of 0, 1, 2, or 3, telling us only what "color" values 2 and 3 represent. You are doing with that value that is extremely hard to follow, since you assign the color (number) to stupidly named variables, and you do that 3 times. Some of what you do affects a pin called ledPin1 (why the hell was it necessary to suffix a number to the variable when you only have one LED pin?) and you are sending MIDI notes. Only YOU have any clue what the relationship is between sending the MIDI note and turning the pin on or off means with respect to the LED and green.

Code starts with an end maker due to some shoddy copy and pasting!

The reason behind using sensorState1 was because I needed to store the value read by the readColor function and use it for some sort of state change detection. Looking at many examples (mostly to do with buttons) I found it difficult to apply to the code I'd pilfered but then I managed something that has worked even if it's badly named! I don't know the correct way to do it but it tracks the colours well and I'm able to use different shades.

The LED was only introduced when I had one colour working just to indicate when the sensor was dwelling on a colour or not. From another piece of code I had worked with, an RGB LED changed according to the colour it sensed which I'll try to incorporate. The important thing is she's firing notes in a way that I can use.

The reason behind using sensorState1 was because I needed to store the value read by the readColor function and use it for some sort of state change detection. Looking at many examples (mostly to do with buttons) I found it difficult to apply to the code I'd pilfered but then I managed something that has worked even if it's badly named! I don't know the correct way to do it but it tracks the colours well and I'm able to use different shades.

So, sensorColorN seems like a more useful name than sensorStateN.

It is a color change you are looking for, not a state change. You CAN adapt the names the reflect what you are actually doing.