user1692: I've been trying to get an Arduino (I have a Mega and Uno lying around) to read values from a small array of 3 ColorPal 20380, which individually, work as intended with some reflective material. The demo gives no problem, but I am confused as to how to approach activating all the 3 sensors and reading the 3 different sets of values so that I can analyze them in a program on the Arduino.
How can I get all three sensors to output data to my program in parallel? I want to use the values at the same point in time on all three sensors to do some calculations in my program. Should I approach something like a state machine? Or at least near-parallel (a few ms delay is fine too)? How would an example look like?
The most confusing thing for me is the non-inverted, open-drain protocol it uses. From the documentation:

Because of the open-drain protocol, the pin used to communicate with the ColorPAL should always be configured as an input, except when being driven low. Also, when starting up, you should wait for this pin to be pulled high by the ColorPAL before trying to send it any commands.

I tried modifying the demo to something silly in sequence like this just to see how it would work in the Arduino but I got nothing (pins 2, 4 and 6 are the data pins):
/* ColorPal Sensor Example for Arduino
  Author: Martin Heermance, with some assistance from Gordon McComb
  This program drives the Parallax ColorPAL color sensor and provides
  serial RGB data in a format compatible with the PC-hosted 
  TCS230_ColorPAL_match.exe color matching program.
*/

#include <SoftwareSerial.h>

int sio = 0;            
const int unused = 255;         // Non-existant pin # for SoftwareSerial
const int sioBaud = 4800;
const int waitDelay = 10;

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

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

void setup() {

  // Unoptimized setup

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

      serin.begin(sioBaud);           // Set up serial port for receiving
      pinMode(2, INPUT);

      sio = 4;
      serin = SoftwareSerial(4, unused);
      serout = SoftwareSerial(unused, 4);
      Serial.begin(9600);
      reset();                
      serout.begin(sioBaud);
      pinMode(4, OUTPUT);
      serout.print("= (00 $ m) !"); 
      serout.end();          

      serin.begin(sioBaud);    
      pinMode(4, INPUT);

      sio = 6;
      serin = SoftwareSerial(6, unused);
      serout = SoftwareSerial(unused, 6);
      Serial.begin(9600);
      reset();               
      serout.begin(sioBaud);
      pinMode(6, OUTPUT);
      serout.print("= (00 $ m) !"); 
      serout.end();         

      serin.begin(sioBaud);     
      pinMode(6, INPUT);
}

void loop() {

  sio = 2;
  serin = SoftwareSerial(sio, unused);
  serout = SoftwareSerial(unused, sio);
  readData();

  sio = sio + 2;
  serin = SoftwareSerial(sio, unused);
  serout = SoftwareSerial(unused, sio);
  readData();

  sio = sio + 2;
  serin = SoftwareSerial(sio, unused);
  serout = SoftwareSerial(unused, sio);
  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(waitDelay);
}

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();
        if (buffer[i] == '$')               // Return early if $ character encountered
          return;
      }
      parseAndPrint(buffer);
      delay(10);
    }
  }
}

// Parse the hex data into integers
void parseAndPrint(char * data) {
  sscanf (data, "%3x%3x%3x", &red, &grn, &blu);
  char buffer[32];
  sprintf(buffer, "R%4.4d G%4.4d B%4.4d", red, grn, blu);
  Serial.println(buffer);
}


user4808: I'm doing something similar with you right now. I'm troubleshooting this right now so we can collaborate.
First of all, even though you have setup 3 pins, you're only telling the Arduino to read only 1 sensor because they're using the same variable (pin6 since it's the last one you set up). You have to declare each pin with a different variable then create 2 more readData() functions to read each pin as a start. But even after I set it up with that, it only read one colorpal. Reading up a little more on the Uno board, it seems that only pin 2 and 3 can do serial interrupt which we need to use to communicate with the ColorPal. I'm not 100% sure as I'm a novice still, but from what my analysis and research shows, that's the problem right now. I'll update if I find anything.

user15217: Try using serin.listen() for each SoftwareSerial before using serin.read(). 
Only one pin can be read at a time and by default it's reading from the last pin initialized. 

1692: <p>I've been trying to get an Arduino (I have a Mega and Uno lying around) to read values from a small array of 3 <a href="http://www.parallax.com/product/28380" rel="nofollow">ColorPal 20380</a>, which individually, work as intended with some reflective material. The <a href="http://learn.parallax.com/colorpal-arduino-demo" rel="nofollow">demo</a> gives no problem, but I am confused as to how to approach activating all the 3 sensors and reading the 3 different sets of values so that I can analyze them in a program on the Arduino.</p>

<p><strong>How can I get all three sensors to output data to my program in parallel?</strong> I want to use the values at the same point in time on all three sensors to do some calculations in my program. Should I approach something like a state machine? Or at least near-parallel (a few ms delay is fine too)? How would an example look like?</p>

<p>The most confusing thing for me is the non-inverted, open-drain protocol it uses. From the documentation:</p>

<blockquote>
  <p>Because of the open-drain protocol, the pin used to communicate with the ColorPAL should always be configured as an input, except when being driven low. Also, when starting up, you should wait for this pin to be pulled high by the ColorPAL before trying to send it any commands.</p>
</blockquote>

<p>I tried modifying the demo to something silly in sequence like this just to see how it would work in the Arduino but I got nothing (pins 2, 4 and 6 are the data pins):</p>

<pre><code>/* ColorPal Sensor Example for Arduino
  Author: Martin Heermance, with some assistance from Gordon McComb
  This program drives the Parallax ColorPAL color sensor and provides
  serial RGB data in a format compatible with the PC-hosted 
  TCS230_ColorPAL_match.exe color matching program.
*/

#include &lt;SoftwareSerial.h&gt;

int sio = 0;            
const int unused = 255;         // Non-existant pin # for SoftwareSerial
const int sioBaud = 4800;
const int waitDelay = 10;

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

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

void setup() {

  // Unoptimized setup

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

      serin.begin(sioBaud);           // Set up serial port for receiving
      pinMode(2, INPUT);

      sio = 4;
      serin = SoftwareSerial(4, unused);
      serout = SoftwareSerial(unused, 4);
      Serial.begin(9600);
      reset();                
      serout.begin(sioBaud);
      pinMode(4, OUTPUT);
      serout.print("= (00 $ m) !"); 
      serout.end();          

      serin.begin(sioBaud);    
      pinMode(4, INPUT);

      sio = 6;
      serin = SoftwareSerial(6, unused);
      serout = SoftwareSerial(unused, 6);
      Serial.begin(9600);
      reset();               
      serout.begin(sioBaud);
      pinMode(6, OUTPUT);
      serout.print("= (00 $ m) !"); 
      serout.end();         

      serin.begin(sioBaud);     
      pinMode(6, INPUT);
}

void loop() {

  sio = 2;
  serin = SoftwareSerial(sio, unused);
  serout = SoftwareSerial(unused, sio);
  readData();

  sio = sio + 2;
  serin = SoftwareSerial(sio, unused);
  serout = SoftwareSerial(unused, sio);
  readData();

  sio = sio + 2;
  serin = SoftwareSerial(sio, unused);
  serout = SoftwareSerial(unused, sio);
  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(waitDelay);
}

void readData() {
  char buffer[32];

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

// Parse the hex data into integers
void parseAndPrint(char * data) {
  sscanf (data, "%3x%3x%3x", &amp;red, &amp;grn, &amp;blu);
  char buffer[32];
  sprintf(buffer, "R%4.4d G%4.4d B%4.4d", red, grn, blu);
  Serial.println(buffer);
}
</code></pre>
 4808: <p>I'm doing something similar with you right now. I'm troubleshooting this right now so we can collaborate.</p>

<p>First of all, even though you have setup 3 pins, you're only telling the Arduino to read only 1 sensor because they're using the same variable (pin6 since it's the last one you set up). You have to declare each pin with a different variable then create 2 more readData() functions to read each pin as a start. But even after I set it up with that, it only read one colorpal. Reading up a little more on the Uno board, it seems that only pin 2 and 3 can do serial interrupt which we need to use to communicate with the ColorPal. I'm not 100% sure as I'm a novice still, but from what my analysis and research shows, that's the problem right now. I'll update if I find anything.</p>
 15217: <p>Try using <code>serin.listen()</code> for each SoftwareSerial before using <code>serin.read()</code>. </p>

<p>Only one pin can be read at a time and by default it's reading from the last pin initialized. </p>
