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 (ColorPAL Color Sensor - Parallax), but I've tried making a very unoptimized version that I thought could allot 3 sensors, sending me data taking turns:
/* 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] == '
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)?) {
for(int i = 0; i < 9; i++) {
while (serin.available() == 0); // Wait for next input character
buffer[i] = serin.read();
if (buffer[i] == '
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)?) // 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)?