Thank you for your responses.
I managed to finish it already. The issue is that all the documents available online only use the macro example where it automatically detects red, green, and blue. The example works wonderfully, but only for color detection, and even so, we are uncertain if the measurements are accurate. It's surprising that there are even theses that directly cite this example and develop complex applications assuming that color detection is correct.
The key point for developing a good sensor application is to verify the documentation. I'll try to explain it briefly:
- The documentation explains that color acquisition can be done by turning on a LED on the Parallax ColorPal sensor. However, this is done through direct mode, and it's not possible to extract data through buffer transmission.
- Verify that to enter direct mode, an 80 ms pulse is required to change the sensor's function.
- Do not program a sensor sequence. This is because it can be stored in EEPROM memory from 00 to 3F. This will only turn on the sensor's LED according to your needs, regardless of whether you try to extract the sensed data.
- On the other hand, as I mentioned initially, the documentation indicates that by using the command "00=m!" a macro is executed, which most of the examples online use, and they lack flexibility for modification.
- Consider that the command "=COLOR s!" will turn on the internal LED, and then you can acquire the data sensed by ColorPal.
Here, I'm adding remedial programming to turn on the ColorPAL LED for subsequent data acquisition.
As an additional comment, I used Arduino temporarily due to its ease of programming. However, it's important to consider that the sensor uses the same pin for both input and output. Therefore, when using the SoftwareSerial function, you need to set it up for both input and output. Also, don't forget that when you want to send a command to the sensor to turn on any color, you should follow these steps:
- Set the baud rate of the transmission port.
- Set the pin as an output.
- Send the color command.
- End the serial communication of the transmission port.
- Enable the baud rate of the receiving port.
- Set the pin as an input.
- Commands for receiving the color (consider that it works with a buffer, and data is received in hexadecimal; I recommend conducting separate tests to become familiar with the sensor).
- Print the sensed data.
- Close the receiving port.
Thoroughly verify each part of the sensor.
I hope this code is helpful to you, and you can enhance it according to your needs. Later, I will program it on a ZEDBOARD Zynq 7 card. This will help revive the use of the sensor, which is quite old but has significant potential.
Do not forget that the "$" symbol is used to indicate when the sensor is receiving an instruction.
The reason I placed it in the "void setup" is that I only need the data processing code to run once.
#include <SoftwareSerial.h>
const int sio = 10; // ColorPAL connected to pin 2
const int unused = 255; // Non-existant pin # for SoftwareSerial
const int sioBaud = 4800;
const int waitDelay = 200;
int red;
SoftwareSerial serin(sio, unused);
SoftwareSerial serout(unused, sio);
void setup() {
Serial.begin(9600);
rojo();
delay(1000);
verde();
delay(1000);
azul();
delay(1000);
blanco();
delay(1000);
sincolor();
delay(1000);
}
void loop()
{
}
void rojo()
{
serout.begin(sioBaud);
pinMode(sio, OUTPUT);
serout.println("=$Rs!");
serout.end(); // Discontinue serial port for transmitting
serin.begin(sioBaud); // Set up serial port for receiving
pinMode(sio, INPUT);
reset();
////// Comienza la lectura del sensor
char buffer[32];
char datojunto[10];
if (serin.available()>0)
{
buffer[0]=serin.read();
if (buffer[0] == '$')
{
for(int i = 0; i <=3; i++) {
while (serin.available() == 0); // Wait for next input character
buffer[i] = serin.read();
if (buffer[i] == '$') // Return early if $ character encountered
return;
}
}
Serial.print ("Rojo: ");
parseAndPrint(buffer);
delay(10);
}
serin.end();
}
void verde()
{
serout.begin(sioBaud);
pinMode(sio, OUTPUT);
serout.println("=$Gs!");
serout.end(); // Discontinue serial port for transmitting
serin.begin(sioBaud); // Set up serial port for receiving
pinMode(sio, INPUT);
reset();
////// Comienza la lectura del sensor
char buffer[32];
char datojunto[10];
if (serin.available()>0)
{
buffer[0]=serin.read();
if (buffer[0] == '$')
{
for(int i = 0; i <=3; i++) {
while (serin.available() == 0); // Wait for next input character
buffer[i] = serin.read();
if (buffer[i] == '$') // Return early if $ character encountered
return;
}
}
Serial.print ("Verde :");
parseAndPrint(buffer);
delay(10);
}
serin.end();
}
void azul()
{
serout.begin(sioBaud);
pinMode(sio, OUTPUT);
serout.println("=$Bs!");
serout.end(); // Discontinue serial port for transmitting
serin.begin(sioBaud); // Set up serial port for receiving
pinMode(sio, INPUT);
reset();
////// Comienza la lectura del sensor
char buffer[32];
char datojunto[10];
if (serin.available()>0)
{
buffer[0]=serin.read();
if (buffer[0] == '$')
{
for(int i = 0; i <=3; i++) {
while (serin.available() == 0); // Wait for next input character
buffer[i] = serin.read();
if (buffer[i] == '$') // Return early if $ character encountered
return;
}
}
Serial.print ("Azul:");
parseAndPrint(buffer);
delay(10);
}
serin.end();
}
void blanco()
{
serout.begin(sioBaud);
pinMode(sio, OUTPUT);
serout.println("=$Ws!");
serout.end(); // Discontinue serial port for transmitting
serin.begin(sioBaud); // Set up serial port for receiving
pinMode(sio, INPUT);
reset();
////// Comienza la lectura del sensor
char buffer[32];
char datojunto[10];
if (serin.available()>0)
{
buffer[0]=serin.read();
if (buffer[0] == '$')
{
for(int i = 0; i <=3; i++) {
while (serin.available() == 0); // Wait for next input character
buffer[i] = serin.read();
if (buffer[i] == '$') // Return early if $ character encountered
return;
}
}
Serial.print ("Blanco:");
parseAndPrint(buffer);
delay(10);
}
serin.end();
}
void sincolor()
{
serout.begin(sioBaud);
pinMode(sio, OUTPUT);
serout.println("=$Xs!");
serout.end(); // Discontinue serial port for transmitting
serin.begin(sioBaud); // Set up serial port for receiving
pinMode(sio, INPUT);
reset();
////// Comienza la lectura del sensor
char buffer[32];
char datojunto[10];
if (serin.available()>0)
{
buffer[0]=serin.read();
if (buffer[0] == '$')
{
for(int i = 0; i <=3; i++) {
while (serin.available() == 0); // Wait for next input character
buffer[i] = serin.read();
if (buffer[i] == '$') // Return early if $ character encountered
return;
}
}
Serial.print ("Apagado:");
parseAndPrint(buffer);
delay(10);
}
serin.end();
}
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 parseAndPrint(char * data) {
sscanf (data, "%3x%3x%3x", &red);
char buffer[32];
sprintf(buffer, "valor= %4.4d", red);
Serial.println(buffer);
}