0

First off let me preface this my explaining my background. I am a mechanical engineering student and have some programming knowledge but it's limited. I'm trying to make a skittle sorter and I right now I'm working on the color identification part. I bought a ColorPal sensor for the project but I'm having trouble using it. I modified the demo a bit and it sort of works but not as well as I would like. Can someone please help me with my code or perhaps suggest an easier color sensor to use. Also I hope I paste my code correctly.

#include <SoftwareSerial.h>

#define sio      6           // ColorPAL connected to pin 6
#define unused   255         // Non-existant pin # for SoftwareSerial
#define sioBaud  4800

// Received RGB values from ColorPAL
int red;
int grn;
int blu;

// Set up two software serials on the same pin.
SoftwareSerial serin(sio, unused);
SoftwareSerial serout(unused, sio);

void setup() {

  delay(2000);

  Serial.begin(9600);
  reset();                    // Send reset to ColorPal
  serout.begin(sioBaud);
  pinMode(sio, OUTPUT);
  serout.print("=(00 $ m)!"); // Loop print values, see ColorPAL documentation
  serout.end();               // Discontinue serial port for transmitting
  pinMode(sio, INPUT);
  serin.begin(sioBaud);       // Set up serial port for receiving
}

void loop() {
  readData();
}

// Reset ColorPAL; see ColorPAL documentation for sequence
void reset() {
  delay(200);
  pinMode(sio, OUTPUT);
  digitalWrite(sio, LOW);
  pinMode(sio, INPUT);
  while (digitalRead(sio) != HIGH);
  pinMode(sio, OUTPUT);
  digitalWrite(sio, LOW);
  delay(80);
  pinMode(sio, INPUT);
  delay(200);
}

void readData() {
  char buffer[32];

  if (serin.available() > 0) {
    // Wait for a $ character, then read three 3 digit hex numbers
    buffer[0] = serin.read();
    if (buffer[0] == '$') {
      for (int i = 0; i < 9; i++) {
        while (serin.available() == 0);     // Wait for next input character
        buffer[i] = serin.read();
        //Serial.print(buffer[i]);
        if (buffer[i] == '$')               // Return early if $ character encountered
          return;
      }
      //Serial.println("");
      parseAndPrint(buffer);
      delay(10);
    }
  }
}

// Parse the hex data into integers
void parseAndPrint(char * data) {
  sscanf (data, "%3x%3x%3x", &red, &grn, &blu);  // Pull the R, G, and B values from the data string

  char buffer[48];                               // create a buffer
  //sprintf(buffer, "r = %4.4d    g = %4.4d    b = %4.4d", red, grn, blu);   //print the values into a buffer as formatted integers
  int sum = red + grn + blu;
  //Serial.println(sum);
  if (sum >= 120 && sum < 126) {
    Serial.println("Purple");
  }
  if (sum >=  238 && sum < 248) {
    Serial.println("Green");
  }
  if (sum >= 230 && sum < 235) {
    Serial.println("Red");
  }
  if (sum >=  330 && sum < 340) {
    Serial.println("Orange");
  }
  if (sum >=  420 && sum < 430) {
    Serial.println("Yellow");
  }
}
Dave X
  • 2,350
  • 15
  • 29

1 Answers1

1

In parseAndPrint

You need to check the return value of sscanf to see if the function read the data.

The problem you are having is the difference between + and &. The sensor is providing 3, 3 digit hex values (which should be sprintfed with %03x not %4.4d). Adding these together isn't going to give you the write answer. For instance $001001001 should give you a colour of r=1, g=1 and b=1. If you add those together you get 3, but you really want 0x001 0x001 0x001.

You need to recalibrate you system and keep the three values separate and represent each colour by a minimum and max of those three colours and then check the value 3 values you receive are within the 3 ranges you have.

// Define a structure (could be a class) to hold the data
struct ColourData
{
    int redMin;
    int redMax;
    int grnMin;
    int grnMax;
    int bluMin;
    int bluMax;
    char Name[30];
    ColourData (int rm, int rx, int gm, int gx, int bm, int bx, char* name)
      : redMin(rm), redMax(rx)
      , grnMin(rm), grnMax(rx)
      , bluMin(bm), bluMax(bx)
    {
        sprint(Name, "%s", name);
    }
};

// Define an array containing the data
ColourData colours[MaxColours] = {ColourData(150, 200, 0, 20, 150, 200, "Purple")
                         , // Add some more

// The code to check the colours
for (int index = 0; index < MaxColours; ++index)
{ 
    if (  red >= colours[index].redMin && red <= colours[index].redMax
       && grn >= colours[index].grnMin && grn <= colours[index].grnMax
       && blu >= colours[index].bluMin && blu <= colours[index].bluMax)
    {
       Serial.println(colours[index].Name)
    }
}
Code Gorilla
  • 5,652
  • 1
  • 17
  • 31