Olá a todos,
Estou enfrentando dificuldades ao tentar ler cores (verde, branco, cinza, preto) usando sensores ópticos reflexivos TCRT5000 em um Arduino Mega 2560. Estou usando três sensores conectados aos pinos analógicos A8, A9 e A10.
Apesar de ajustar os thresholds com base em leituras experimentais, estou tendo problemas porque os valores lidos das cores se sobrepõem, dificultando a distinção precisa entre elas. Aqui estão algumas médias, mínimos e máximos das leituras que obtive:
- Verde: Média: 823, Mín: 808, Máx: 843
- Branco: Média: 817, Mín: 803, Máx: 834
- Cinza: Média: 816, Mín: 802, Máx: 833
- Preto: Média: 818, Mín: 803, Máx: 835
Como podem ver, os valores estão muito próximos, causando sobreposição nas faixas de leitura. Já tentei calcular os thresholds como a média das médias das cores adjacentes, mas isso não resolveu o problema. Alterar a sensibilidade o sensor também apenas deixa as faixas menos iguais porém, ainda sobrepostas.
Aqui está um trecho do meu código atual para leitura e calibração:
#include <AFMotor.h>
#include <Ultrasonic.h>
// Definição dos pinos dos sensores
#define SENSOR_1 A8
#define SENSOR_2 A9
#define SENSOR_3 A10
// Estrutura para armazenar média, mínimo e máximo
struct SensorReadings {
int average;
int minimum;
int maximum;
};
// Definição dos thresholds (ajuste conforme necessário)
int thresholdGreenWhite;
int thresholdWhiteGray;
int thresholdGrayBlack;
// Função para ler e calcular a média de valores de um sensor com 1000 leituras
SensorReadings readAverage(int sensorPin) {
long sum = 0;
int minVal = 1023;
int maxVal = 0;
int numReadings = 1000;
// Coletar leituras
for (int i = 0; i < numReadings; i++) {
int reading = analogRead(sensorPin);
sum += reading;
if (reading < minVal) minVal = reading;
if (reading > maxVal) maxVal = reading;
delay(1); // Pequeno atraso para estabilizar a leitura
}
SensorReadings result;
result.average = sum / numReadings;
result.minimum = minVal;
result.maximum = maxVal;
return result;
}
// Função de depuração para imprimir leituras brutas do sensor
void debugReadings(int sensorPin) {
Serial.print("Leituras do sensor no pino ");
Serial.println(sensorPin);
for (int i = 0; i < 100; i++) {
int reading = analogRead(sensorPin);
Serial.print(reading);
Serial.print(" ");
delay(10);
}
Serial.println();
}
void setup() {
Serial.begin(9600);
// Calibração inicial para definir os thresholds
Serial.println("Calibrando...");
Serial.println("Coloque o sensor no Verde e pressione uma tecla...");
while (!Serial.available());
Serial.read();
debugReadings(SENSOR_1);
SensorReadings greenReadings = readAverage(SENSOR_1);
Serial.print("Verde: ");
Serial.print(" Média: ");
Serial.print(greenReadings.average);
Serial.print(" Min: ");
Serial.print(greenReadings.minimum);
Serial.print(" Max: ");
Serial.println(greenReadings.maximum);
Serial.println("Coloque o sensor no Branco e pressione uma tecla...");
while (!Serial.available());
Serial.read();
debugReadings(SENSOR_1);
SensorReadings whiteReadings = readAverage(SENSOR_1);
Serial.print("Branco: ");
Serial.print(" Média: ");
Serial.print(whiteReadings.average);
Serial.print(" Min: ");
Serial.print(whiteReadings.minimum);
Serial.print(" Max: ");
Serial.println(whiteReadings.maximum);
Serial.println("Coloque o sensor no Cinza e pressione uma tecla...");
while (!Serial.available());
Serial.read();
debugReadings(SENSOR_1);
SensorReadings grayReadings = readAverage(SENSOR_1);
Serial.print("Cinza: ");
Serial.print(" Média: ");
Serial.print(grayReadings.average);
Serial.print(" Min: ");
Serial.print(grayReadings.minimum);
Serial.print(" Max: ");
Serial.println(grayReadings.maximum);
Serial.println("Coloque o sensor no Preto e pressione uma tecla...");
while (!Serial.available());
Serial.read();
debugReadings(SENSOR_1);
SensorReadings blackReadings = readAverage(SENSOR_1);
Serial.print("Preto: ");
Serial.print(" Média: ");
Serial.print(blackReadings.average);
Serial.print(" Min: ");
Serial.print(blackReadings.minimum);
Serial.print(" Max: ");
Serial.println(blackReadings.maximum);
// Definir thresholds dinamicamente
thresholdGreenWhite = (greenReadings.average + whiteReadings.average) / 2;
thresholdWhiteGray = (whiteReadings.average + grayReadings.average) / 2;
thresholdGrayBlack = (grayReadings.average + blackReadings.average) / 2;
Serial.print("Threshold Verde-Branco: ");
Serial.println(thresholdGreenWhite);
Serial.print("Threshold Branco-Cinza: ");
Serial.println(thresholdWhiteGray);
Serial.print("Threshold Cinza-Preto: ");
Serial.println(thresholdGrayBlack);
}
void loop() {
// Leitura dos sensores
SensorReadings sensorReadings[3];
sensorReadings[0] = readAverage(SENSOR_1);
sensorReadings[1] = readAverage(SENSOR_2);
sensorReadings[2] = readAverage(SENSOR_3);
// Calcular a média dos três sensores
int combinedAverage = (sensorReadings[0].average + sensorReadings[1].average + sensorReadings[2].average) / 3;
// Mapeamento dos valores para as cores
String color = mapColor(combinedAverage);
Serial.print("Média dos sensores: ");
Serial.print(combinedAverage);
Serial.print(" -> ");
Serial.println(color);
delay(500);
}
// Função para mapear o valor lido em uma cor
String mapColor(int value) {
if (value < thresholdGreenWhite) {
return "Verde";
} else if (value < thresholdWhiteGray) {
return "Branco";
} else if (value < thresholdGrayBlack) {
return "Cinza";
} else {
return "Preto";
}
}
Minhas Dúvidas
Há uma melhor maneira de calcular os thresholds para distinguir claramente entre as cores?
Devo considerar uma abordagem diferente, como filtragem ou ponderação das leituras?
Existe uma forma de melhorar a precisão dos sensores TCRT5000 para este tipo de aplicação?
Agradeço qualquer orientação ou sugestões que possam ajudar a resolver este problema.
Obrigado!