HELP! PROJECT COLOR SORTER! NEED HELP!

Hello Everyone, I’d Like to Seek an Advice or Code for me to Develop Our Color Sorter Project

Now I Already Have My Code with Me but The Big Problem is That the color sensor detects and detects

and doesn’t wait for another object to be read, it just continue to read and read which the servo in my

program always rotating which is difficult for me. it detects

colors and always tells the servo to move continuously i need help in order for me to point out a

certain location a specific location for the servo for example if detects red it goes to that location

should i use a distance sensor , here in Philippines we lack of distance sensors IR to be specific so

it would be a big help if i can do this project without any IR distance sensors just an instance of timing

for the servo and color sensor.

Here is The Code

#include <Wire.h>
#include <Math.h>
#include <Servo.h>
#include <Arduino.h>

byte i2cWriteBuffer[10];
byte i2cReadBuffer[10];
Servo myServo1; Servo myServo2;

#define SensorAddressWrite 0x29 //
#define SensorAddressRead 0x29 // 
#define EnableAddress 0xa0 // register address + command bits
#define ATimeAddress 0xa1 // register address + command bits
#define WTimeAddress 0xa3 // register address + command bits
#define ConfigAddress 0xad // register address + command bits
#define ControlAddress 0xaf // register address + command bits
#define IDAddress 0xb2 // register address + command bits
#define ColorAddress 0xb4 // register address + command bits


/*  
Send register address and the byte value you want to write the magnetometer and 
loads the destination register with the value you send
*/
void Writei2cRegisters(byte numberbytes, byte command)
{
    byte i = 0;

    Wire.beginTransmission(SensorAddressWrite);   // Send address with Write bit set
    Wire.write(command);                          // Send command, normally the register address 
    for (i=0;i<numberbytes;i++)                       // Send data 
      Wire.write(i2cWriteBuffer[i]);
    Wire.endTransmission();

    delayMicroseconds(150);      // allow some time for bus to settle      
}

/*  
Send register address to this function and it returns byte value
for the magnetometer register's contents 
*/
byte Readi2cRegisters(int numberbytes, byte command)
{
   byte i = 0;

    Wire.beginTransmission(SensorAddressWrite);   // Write address of read to sensor
    Wire.write(command);
    Wire.endTransmission();

    delayMicroseconds(150);      // allow some time for bus to settle      

    Wire.requestFrom(SensorAddressRead,numberbytes);   // read data
    for(i=0;i<numberbytes;i++)
      i2cReadBuffer[i] = Wire.read();
    Wire.endTransmission();   

    delayMicroseconds(100);      // allow some time for bus to settle      
}  

void init_TCS34725(void)
{
  i2cWriteBuffer[0] = 0x10;
  Writei2cRegisters(1,ATimeAddress);    // RGBC timing is 256 - contents x 2.4mS =  
  i2cWriteBuffer[0] = 0x00;
  Writei2cRegisters(1,ConfigAddress);   // Can be used to change the wait time
  i2cWriteBuffer[0] = 0x00;
  Writei2cRegisters(1,ControlAddress);  // RGBC gain control
  i2cWriteBuffer[0] = 0x03;
  Writei2cRegisters(1,EnableAddress);    // enable ADs and oscillator for sensor  
}

void get_TCS34725ID(void)
{
  Readi2cRegisters(1,IDAddress);
  if (i2cReadBuffer[0] = 0x44)
    Serial.println("TCS34725 is present");    
  else
    Serial.println("TCS34725 not responding");    
}

/*
Reads the register values for clear, red, green, and blue.
*/
int ledpin=11;

void get_Colors(void)
{
  unsigned int clear_color = 0;
  unsigned int red_color = 0;
  unsigned int green_color = 0;
  unsigned int blue_color = 0;

  Readi2cRegisters(8,ColorAddress);
  clear_color = (unsigned int)(i2cReadBuffer[1]<<8) + (unsigned int)i2cReadBuffer[0];
  red_color = (unsigned int)(i2cReadBuffer[3]<<8) + (unsigned int)i2cReadBuffer[2];
  green_color = (unsigned int)(i2cReadBuffer[5]<<8) + (unsigned int)i2cReadBuffer[4];
  blue_color = (unsigned int)(i2cReadBuffer[7]<<8) + (unsigned int)i2cReadBuffer[6];

  // send register values to the serial monitor 
/*
  Serial.print("clear color=");
  Serial.print(clear_color, DEC);    
  Serial.print(" red color=");
  Serial.print(red_color, DEC);    
  Serial.print(" green color=");
  Serial.print(green_color, DEC);    
  Serial.print(" blue color=");
  Serial.println(blue_color, DEC);
*/

 // Basic RGB color differentiation can be accomplished by comparing the values and the largest reading will be 
 // the prominent color

  if((red_color>blue_color) && (red_color>green_color))
  {
    Serial.println("detecting red");
    myServo1.write(90);
  } 
  else if((green_color>blue_color) && (green_color>red_color))
  {
    Serial.println("detecting green");
    myServo1.write(180);
  } 
  else if((blue_color>red_color) && (blue_color>green_color))
  {
    Serial.println("detecting blue");
    myServo1.write(270);
  }
  else
  {
    Serial.println("color not detectable");
    myServo1.write(360);
  }  
}

void setup() 
{
  Wire.begin();
  Serial.begin(9600);  // start serial for output
  pinMode(ledpin,OUTPUT);
  init_TCS34725();
  get_TCS34725ID();     // get the device ID, this is just a test to see if we're connected
  myServo1.attach(9);
  myServo2.attach(8);
}

void loop()
{
    digitalWrite(ledpin,HIGH);
    get_Colors();
    delay(1000);
}

A Response and Advice is greatly Appreciated Thanks a Lot!

What kind of servos are these? 360 degrees of travel is a little unusual.

Are they regular servos or continuous rotation models?

What do your serial print statements tell you the colour sensor is detecting?

Hello! and First of All Thank You!

Yes The Servo which is in myServo1 is 360 degrees and continous rotation.

in Serial Monitor it detects the color and shows the color it detects respectively. any idea how am i going to make a little delay in detecting a color and also to the servo that it spins to the exact location then wait for the nxt color to be determine for the servo to move again.

Thanks a Lot Brother!

If the servo is continuous rotation, you can't stop it at a particular place without additional hardware. A regular servo might serve you better.

forelectronics02:
A Response and Advice is greatly Appreciated Thanks a Lot!

First thing I’d do is giving the program a clear structure and programming logic using the IPO programming model:

  • Input
  • Processing
  • Output

I did some changes to your code and cancelled the processing code for now:

#include <Wire.h>
#include <Math.h>
#include <Servo.h>
#include <Arduino.h>

byte i2cWriteBuffer[10];
byte i2cReadBuffer[10];
Servo myServo1; Servo myServo2;

#define SensorAddressWrite 0x29 //
#define SensorAddressRead 0x29 // 
#define EnableAddress 0xa0 // register address + command bits
#define ATimeAddress 0xa1 // register address + command bits
#define WTimeAddress 0xa3 // register address + command bits
#define ConfigAddress 0xad // register address + command bits
#define ControlAddress 0xaf // register address + command bits
#define IDAddress 0xb2 // register address + command bits
#define ColorAddress 0xb4 // register address + command bits


/*  
Send register address and the byte value you want to write the magnetometer and 
loads the destination register with the value you send
*/
void Writei2cRegisters(byte numberbytes, byte command)
{
    byte i = 0;

    Wire.beginTransmission(SensorAddressWrite);   // Send address with Write bit set
    Wire.write(command);                          // Send command, normally the register address 
    for (i=0;i<numberbytes;i++)                       // Send data 
      Wire.write(i2cWriteBuffer[i]);
    Wire.endTransmission();

    delayMicroseconds(150);      // allow some time for bus to settle      
}

/*  
Send register address to this function and it returns byte value
for the magnetometer register's contents 
*/
byte Readi2cRegisters(int numberbytes, byte command)
{
   byte i = 0;

    Wire.beginTransmission(SensorAddressWrite);   // Write address of read to sensor
    Wire.write(command);
    Wire.endTransmission();

    delayMicroseconds(150);      // allow some time for bus to settle      

    Wire.requestFrom(SensorAddressRead,numberbytes);   // read data
    for(i=0;i<numberbytes;i++)
      i2cReadBuffer[i] = Wire.read();
    Wire.endTransmission();   

    delayMicroseconds(100);      // allow some time for bus to settle      
}  

void init_TCS34725(void)
{
  i2cWriteBuffer[0] = 0x10;
  Writei2cRegisters(1,ATimeAddress);    // RGBC timing is 256 - contents x 2.4mS =  
  i2cWriteBuffer[0] = 0x00;
  Writei2cRegisters(1,ConfigAddress);   // Can be used to change the wait time
  i2cWriteBuffer[0] = 0x00;
  Writei2cRegisters(1,ControlAddress);  // RGBC gain control
  i2cWriteBuffer[0] = 0x03;
  Writei2cRegisters(1,EnableAddress);    // enable ADs and oscillator for sensor  
}

void get_TCS34725ID(void)
{
  Readi2cRegisters(1,IDAddress);
  if (i2cReadBuffer[0] = 0x44)
    Serial.println("TCS34725 is present");    
  else
    Serial.println("TCS34725 not responding");    
}

int ledpin=11;


void setup() 
{
  Wire.begin();
  Serial.begin(9600);  // start serial for output
  Serial.println();
  pinMode(ledpin,OUTPUT);
  init_TCS34725();
  get_TCS34725ID();     // get the device ID, this is just a test to see if we're connected
  myServo1.attach(9);
  myServo2.attach(8);
  Serial.println();
  Serial.println("clear\tred\tgreen\tblue\tservo1\tservo2");
}

unsigned int clear_color = 0;
unsigned int red_color = 0;
unsigned int green_color = 0;
unsigned int blue_color = 0;

void input()
{ // Read the color sensor
  Readi2cRegisters(8,ColorAddress);
  clear_color = (unsigned int)(i2cReadBuffer[1]<<8) + (unsigned int)i2cReadBuffer[0];
  red_color = (unsigned int)(i2cReadBuffer[3]<<8) + (unsigned int)i2cReadBuffer[2];
  green_color = (unsigned int)(i2cReadBuffer[5]<<8) + (unsigned int)i2cReadBuffer[4];
  blue_color = (unsigned int)(i2cReadBuffer[7]<<8) + (unsigned int)i2cReadBuffer[6];
}

int servo1pos=180;
int servo2pos=180;

void processing()
{ // here you do the calculations and logical processing
  // just some silly time based servopos movement
  servo1pos=(millis()/1000)%180;
  servo2pos=180-servo1pos;
}

void output()
{
  // output to Serial
  Serial.print(clear_color);
  Serial.print('\t');
  Serial.print(red_color);
  Serial.print('\t');
  Serial.print(green_color);
  Serial.print('\t');
  Serial.print(blue_color);
  Serial.print('\t');
  Serial.print(servo1pos);
  Serial.print('\t');
  Serial.print(servo2pos);
  Serial.print('\t');
  Serial.println();

  // send output to servos
   myServo1.write(servo1pos);
   myServo2.write(servo2pos);
}


void loop()
{
  input();
  processing();
  output();
  delay(1000); // if you like "blocking" your program while it is running
}

So now you get an output after each step on Serial:

  • which color is detected
  • which position is sent to the servos

Next would be: Create the processing logic as you need it and rewrite the processing() function so that it does what you want!

P.S.: And please fix the sensor detection, wich sends the wrong message:

 if (i2cReadBuffer[0] = 0x44)  // '=' means assign value 0x44 to i2cReadBuffer[0]

But you want COMPARE with ‘==’

 if (i2cReadBuffer[0] == 0x44)  // '==' means comparison of 0x44 and i2cReadBuffer[0]

Cheers To The Both Of You! I'll Go Try To Code Now and Try To Buy a New Servo

Really Helpful! I Commend The Both Of You! Goodluck On Your Projects! :D CHEERS! :D