Go Down

Topic: Multiple by-turn ColorPal reads on SoftwareSerial library (Read 164 times) previous topic - next topic

Eriol

Hello,

Lately I've been trying to hook up 3 color sensors to a single Arduino Uno board so that I can read different colors in different places, but it's not going as expected. I'm trying to use a pin for both Rx/Tx as specified in the product page, namely pins 2, 4 and 6.

I can get a single sensor running fine with the sample code from Parallax (http://www.parallax.com/product/28380), but I've tried making a very unoptimized version that I thought could allot 3 sensors, sending me data taking turns:

Code: [Select]
/* 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 = 2; // ColorPAL connected to pin 2
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() {
  // Unoptimized data reads taking turns
  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);
}


I guess I'm overlooking something blatant in the SoftwareSerial library and my code is not doing what I am expecting? Does the Uno even have enough firepower for this (I have a Mega lying around too)?

Eriol

Bumping this to see if anyone has any idea. I resorted to working with one but the algorithm I'm trying to implement with the data received gets much more difficult with only one source.

Go Up