Der sprechende Farbdetektor mit DFPlayer und TCS3200 - [Teil 2]

Introducción

En la primera parte de esta serie de blogs, queremos poner en funcionamiento el reproductor de MP3 para la salida de voz. También añadimos la entrada del usuario con un pulsador y un potenciómetro. En la segunda parte queremos ahora conectar y probar el sensor de color. Le mostraremos qué librerías están disponibles y en qué se debe fijar para hacer funcionar el sensor.

Herramientas que necesitamos

Numero Componente
1 Módulo TCS3200 Sensor Color
1 Módulo DFPlayer Mini MP3 Player
1 Mikro-SD Card
1 Arduino Nano V3.0
1 Altavoz (Max 3 W)
Cable de puente
Resistencia 1 kOhm
Resistencia Variable (Potenciómetro)
1 Botón Ordenador
Ordenador con Arduino IDE y conexión a Internet
Fuente de Voltaje externo (recomendado), 7 – 12 V
Tarjetas de referencia de color

Preparación

Asumo que ya ha construido el circuito de la Parte 1 y que ha insertado la tarjeta SD con los archivos de voz en la ranura SD del reproductor MP3. No necesitaremos estos componentes todavía, pero es una ventaja si el circuito ya está configurado ya que lo necesitamos al final. Dado que lo complementaremos con el sensor de color.



DFPlayer Mini Pines Arduino Nano Pines
VCC 5V
GND GND
RX KOhm en D11 (TX)
TX D10 (RX)
Altavoz
SPK_1 Rojo (Plus)
SPK_2 Negro (Minus)
Potenciómetro Arduino Nano Pines
1 GND
2 (Mitte) A0
3 +5V
Pulsador Arduino Nano Pines
1 D12
2 GND

Para una prueba de funcionamiento, invitamos el programa de la parte 1 al Arduino:

completo: 1.2DFPlayerStartsoundPotiTaster.ino

Sensor de color

El sensor de color TCS3200 consiste en un fotodiodo dispuesto en la cuadrícula. Siempre hay cuatro de ellos dispuestos en la plaza. Tres de ellos están equipados con un filtro de color en rojo, verde o azul. Un fotodiodo no contiene un filtro de color. De estos cuartetos hay 16 distribuidos uniformemente en la superficie del sensor, lo que representa, un total de 64 fotodiodos.

Los diodos con los mismos filtros de color están conectados entre sí. Esta cuadrícula de diodos es el sensor de color actual que está soldado en la placa de ruptura. Hay cuatro LEDs blancos que iluminan el objeto. La luz se refleja y se devuelve a los fotodiodos, que generan una tensión a partir de la luz. Los filtros de color garantizan que cada grupo de colores recoja sólo un color. Con las conexiones S2 y S3 se pueden activar y desactivar los grupos de fotodiodos. Hay cuatro combinaciones, por lo que siempre se enciende un grupo con el mismo color.

S2 S3 Color
LOW LOW Rojo
LOW HIGH Azul
HIGH LOW Claro (sin filtro)
HIGH HIGH Verde



El voltaje generado por cada grupo de fotodiodos se convierte en una oscilación rectangular con un convertidor de frecuencia de voltaje. Según el color del objeto su frecuencia cambia. Recibirá un valor de frecuencia de cada uno de los grupos de color. A continuación, esto se debe convertir en valores RGB significativos.

Otras conexiones son S0 y S1. Sirven para un divisor de frecuencia con el que escala la frecuencia de salida y también puede desactivar el sensor.

S0 S1 Output Frequency Scaling
LOW LOW Desactiva
LOW HIGH 2%
HIGH LOW 20%
HIGH HIGH 100%


Los pines VCC y GND se utilizan para la fuente de alimentación que puede estar entre 2.7 y 5.5 V. En el pin de salida, la frecuencia medida que podemos medir en el Arduino. El pin OE (Salida Habilitada) activa o desactiva la salida del sensor. “He” es Bajo Activo. Si no hay nada disponible en esta entrada, el sensor está activo de forma predeterminada. Así que puede convertir el programa fuera de la salida para conectar varios sensores que no deben interferir entre sí. De lo contrario, puede dejarlo libre o conectarlo con GND.

Los detalles técnicos del sensor se pueden encontrar en la hoja de datos.

Cableado

Insertamos el sensor de color en nuestro circuito de la siguiente manera:



TCS3200 Pines Arduino Nano Pines
VCC 5V
GND GND
OE D3
S0 D4
S1 D8
S2 D6
S3 D7
OUT D5


Así como puede reconocer, los pines no están completamente dispuestos cronológicamente. Esto se debe a una razón. Una de las librerías que le mostraré más adelante requiere que la salida se conecte al pin D5. Para que todo sea uniforme y que no tengamos que cambiar cada vez, por eso dejo así para los otros ejemplos que le voy a mostrar.

Cosas que se deben considerar

El sensor también absorbe la luz del ambiente. Esto, por supuesto, cambia los valores medidos. Además, la distancia del sensor al objeto medido (recomendado entre 1 y 3 cm) es decisiva. Se recomienda construir una caja cerrada para que los factores de interferencia permanezcan lo más constantes posible. Entonces, es posible calibrar el sensor y ajustarlo a su ambiente. Espontáneamente hice una pequeña pieza de papel negro.


Todavía se puede ver una estrecha tira de papel que puse alrededor del sensor. En mi opinión, demasiada luz de los LED irradia directamente al sensor. En Thingiverse encontré algunos modelos para impresión 3D, que también están destinados a esto (aquíhier y aquí,).

Por supuesto, también puede diseñar una carcasa como modelo 3D, en la que el resto de la electrónica tenga cabida. Es importante que tan poca luz desde el exterior pueda golpear el sensor y la distancia a la superficie medida siga siendo la misma. Sería una buena opción usar una linterna desgastada. Allí, la misma batería para la fuente de alimentación móvil tiene espacio.

Sin bibliotecas

Encontré diferentes variantes durante mi investigación sobre el TSC3200 (y también el TCS230, el modelo predecesor) para programar este componente con el Arduino. Antes de presentarle las dos librerías que he encontrado, me gustaría volver a cómo funciona la comunicación entre el microcontrolador y el sensor.

Como ya se mencionó anteriormente, los pines S2 y S3 son responsables del cambio de los fotodiodos. Hay cuatro grupos de colores cuyos diodos (rojo, verde, azul y transparente sin filtros) son activados por una de las combinaciones de S2 y S3. A continuación, el sensor genera una señal rectangular uniforme en la salida. Su ancho de pulso (es decir, el tiempo de una "vibración") se debe medir con el Arduino. Básicamente, no es necesaria ninguna librería adicional para esto. Probemos primero sin.

Definimos nuestros pines Arduino como constantes:

#define S0 4
#define S1 8
S2 6
S3 7
ENABLED
#define TCS_IN 5

Después añadimos algunas variables para los colores. También quiero formatear la emisión en el monitor serie. Lo soluciono con un búfer de cadena:

int red = 0;
int gruen = 0;
= int 0;
int = 0;
char serialBuffer[55];

En setup() inicializamos el monitor serie (de nuevo nos aseguramos de que la misma velocidad en baudios esté establecida allí):

void setup()
{
  Serial.begin(115200);
  pinMode(S0, OUTPUT); //S0
  pinMode(S1, OUTPUT); //S1
  pinMode(S2, OUTPUT); //S2
  pinMode(S3, OUTPUT); //S3
  pinMode(OE, OUTPUT); //S3
  pinMode(TCS_IN, INPUT); //OUT

  // Sensor Output aktivieren
  digitalWrite(OE, LOW);
 
  // Frequenzteiler auf 20%
  digitalWrite(S0, HIGH);
  digitalWrite(S1, LOW);
}

Las entradas del sensor de color S0 a S3, así como OE son entradas allí. Por lo tanto, las puede establecer en el Arduino como salidas. La salida del sensor es una entrada en el Arduino. Para volver a establecer el pin para OE en LOW, solo tiene que hacerlo si está conectado. Puesto que “He” está activo bajo, también se puede dejar sin conectar y luego no tiene que inicializarlo. Como he dicho, también es posible conectarlo al pin GND, aunque no es absolutamente necesario.

Establecemos el divisor de frecuencia (como se muestra en la tabla anterior) a 20%.

En la función loop(),ahora activaremos los grupos de colores individuales uno tras otro y mediremos los valores en la entrada. Para facilitar la comparación de estos datos, agregue una interrupción:

// Auf Eingabe warten
  while (Serial.available() == 0) {
    if (Serial.available() != 0) {
      break;
    }
  }
  // Serial Puffer loeschen
  while (Serial.read() != -1) {}

Cuando abre el monitor serie, simplemente puede presionar la tecla Intro en el campo de entrada. A continuación, se realiza una serie de mediciones. Para los siguientes valores, debe pulsar el botón de nuevo. Lo siguiente es la conexión de los fotodiodos y la medición en la entrada de los Arduinos:

   // LOW / LOW = rote Photodiode
  digitalWrite(S2, LOW);
  digitalWrite(S3, LOW);
  // Frequenz messen
  rot = pulseIn(TCS_IN, digitalRead(TCS_IN) == HIGH ? LOW : HIGH);
  
  // LOW / HIGH = blaue Photodiode
  digitalWrite(S3, HIGH);
  blau = pulseIn(TCS_IN, digitalRead(TCS_IN) == HIGH ? LOW : HIGH);
  
  // HIGH / HIGH = Gruene Photodiode
  digitalWrite(S2, HIGH);
  gruen = pulseIn(TCS_IN, digitalRead(TCS_IN) == HIGH ? LOW : HIGH);
  
  // HIGH / LOW = Photodiode ohne Filter
  digitalWrite(S3, LOW);
  klar = pulseIn(TCS_IN, digitalRead(TCS_IN) == HIGH ? LOW : HIGH);    
  
  // Ausgabe
  sprintf(serialBuffer, "Rot: %4d Gruen: %4d Blau: %4d Klar: %4d", rot, gruen, blau, klar);
  Serial.println(serialBuffer);

S2 y S3 se establecen primero en Low / Low, luego S3 en High. S2 permanece Low, lo que resulta en LOW/HIGH. A continuación, S2 se establece en High, lo que representa High / High, porque S3 no se cambia. Por último, S3 se establece en LOW sin cambiar S2, lo que resulta en HIGH / LOW. Compare las combinaciones con la tabla anterior para cada color. Aquí sólo he intercambiado el verde, para que sólo haya que cambiar un pin digital en la orden, lo que significa menos tiempo de comandos para el procesador.

Por último, los valores se emiten en el monitor serie. Para esto uso la edición formateada, pero no funciona en el Arduino Nano Serial.printf(). Un pequeño desvío va aquí a través de la salida con formato en una matriz de caracteres que luego se enviará al monitor serie.

Código fuente completo: 2.0TCS3200Test.ino

Descargue el programa al Arduino, mantenga pulsado el sensor en un área de color de su elección y pulse Intro en el campo de entrada del monitor serie. A continuación, verá los valores de color. Cambie el área de color y pulse de nuevo la tecla Intro. A continuación, los valores de color cambian.

He escaneado rojo, verde, azul, negro y blanco y obtuve los siguientes resultados:


Ahora tenemos que interpretar los valores primero. Cada línea es de un color escaneado. Veamos la primera línea. Estos valores representan el color rojo de mi tarjeta de referencia. Un rojo completo compuesto, a partir de los tres valores de color en forma aditiva en 8 bits sería 255, 0, 0 (R, G, B). Sólo conseguiremos esos colores ideales. Esto es que estos valores de salida no son 8 bits. Además, podemos ver que la parte giratoria es inferior a las acciones para el verde y el azul. La siguiente línea es la tarjeta de referencia verde. Aquí vemos que las acciones son verdes y azules. Eso normalmente sería una turquesa más bien. En la tarjeta de referencia azul, vemos que los valores de la parte azul son más bajos. Si medimos el área negra, los valores son mucho más altos. El blanco da como resultado valores muy bajos. Esto sugiere que las fracciones de color más claras por canal de color significan valores bajos.

La función  pulseIn() mide el tiempo entre los cambios de estado en un pin. Así que los valores de salida no son valores de voltaje, esto se puede utilizar, por ejemplo, con analogRead(). Estas son frecuencias. Cuanto menor sea la frecuencia, más brillante será el valor de color. Para el color rojo, esto significa que la proporción de luz roja reflejada es la más brillante y por lo tanto tiene el valor más bajo.

A partir de esto se podría escribir un programa que reconoce colores para nosotros. Dado que esto es más de 8 bits, las diferencias de color se pueden mostrar mucho más finas. Si cambia la escala de frecuencia, puede influir en esta resolución. Para este proyecto, sin embargo, los colores simples y el programa son suficientes para escribir, también dejo fuera.

Con Librerías

Ahora queremos hacer que nuestro detector de color parlante pronuncie los colores. ¿Cómo sabe que es el color rojo y qué pasa si los valores de color difieren un poco? Después de todo, el rojo no es lo mismo que el rojo. Para esto, tendríamos que implementar una calibración en el programa. También necesitaríamos un peso si los colores difieren ligeramente.

Ya no tenemos que programar estas cosas nosotros mismos. Ahora utilizamos las librerías. Alguien ya ha hecho el trabajo y ahora queremos probar sus ejemplos. Instalamos las librerías MD_TCS230 de majicDesigns y tcs3200 de Panjkrc desde la gestión de la librería:


Si introduce "TCS" en el cuadro de búsqueda, aparecerán los resultados adecuados. Ahora tenemos estas librerías y sus ejemplos incluidos a nuestra disposición. Al hacer clic en "Info" en la gestión de librerías en la entrada respectiva, se le llevará a las descripciones y el código fuente en Github. Sin embargo, un error se ha deslizado en el link de majicsDesigns. Puede llegar a la página de Github a través de este enlace.

Comencemos con la librería MDTCS230. Esta librería trabaja con el modelo sucesor TCS3200, que ahora está disponible. Hay cuatro ejemplos incluidos. Con los proyectos "SimpleBTCS230" y "SimpleNB_TCS230" se muestra una comparación entre bloqueo y no bloqueo en conexión con este sensor. No quiero ir más lejos. Sin embargo, pruébelo por usted mismo. Preste atención a los pines utilizados.

Abramos el ejemplo "Calibrate_TSC230". Aquí notará que se utiliza una librería llamada "FreqCount.h". Esto se debe instalar:


Cambiamos los números de pin en el ejemplo en "Definiciones de Pines" como en nuestro proyecto de prueba. Estos son para S2 pin 6 y para S3 pin 7. OE es pin 3.

Nota: Esta es la librería que requiere (como se mencionó anteriormente) la salida del sensor en la entrada del pin Arduino D5. Esto se establece en la librería “FreqCount.h”. Puede encontrar más información en el sitio web de StoffregenTambién hay una lista de los pines que se deben utilizar para las placas Arduino respectivas.

Cambiamos la velocidad en baudios para el monitor serie, ya sea en el código fuente o en el monitor serie. Puede decidir por usted mismo, ya que ambos son posibles. Lo importante es que ambos tengan el mismo valor. Después de estos cambios, invitamos el programa al Arduino y lo ejecutamos.

Observará que no se especifican los pines S0 y S1. Estos se utilizan (como se describió anteriormente) para la escala de frecuencia, que no se necesita establecer en este programa. Sin mirar el código fuente de la librería, asumo que la configuración se programó allí.

Cuando se inicia el programa y se abre el monitor serie, aparece un mensaje que indica que se debe escanear el negro. Hacemos esto y confirmamos con “Enter”. A continuación, el conjunto de nuevo con el blanco. Después puede escanear los colores deseados. Pruebo esto con rojo, azul y verde y obtuve los siguientes valores:


Mi tarjeta de referencia roja tiene las fracciones de color 127, 16, 18 (R, G, B). El azul tiene 19, 51, 99 (R, G, B) y el verde tiene 53, 78, 39 (R, G, B). En este caso, estos son valores de color de 8 bits, es decir, cada canal de color puede tomar los valores 0 a 255. Cuanto mayor sea el valor, mayor será el contenido del color. Por lo tanto, la parte giratoria es más alta en el color rojo registrado. Esta es la diferencia con nuestra primera prueba con este sensor. Los valores ya han sido convertidos aquí. Nos falta una ponderación para nuestro detector de color parlante.

Abrimos el proyecto de ejemplo "colormatch_tcs230" desde la misma librería. Aquí también cambiamos los números pin para S2, S3 y OE (6, 7 y 3). Además, ajustamos la velocidad en baudios para el monitor en serie y cargamos el programa en el Arduino. En la salida de pantalla se nos pide que elijamos entre el modo “Learn” o “Match”. En el modo Learn, volveremos a tomar valores de referencia. Necesitamos ponerlos en el archivo ColorMatch.h. Con una mirada hacia este archivo (se puede llegar a ella en la pestaña debajo del menú en el Arduino IDE), vemos una matriz para diferentes colores. Allí, los valores del modo Learn se introducen más adelante.

Pasamos por el proceso del modo Learn, en el que introducimos una gran "L" en la entrada del monitor serie. Ahora tenemos que grabar negro y blanco de nuevo. Estos son los valores máximos de referencia. El blanco idealmente tiene valores de 255, 255, 255 (RGB) y el negro tiene 0, 0, 0 (RGB). Dado que no siempre alcanzamos estos valores ideales, necesitamos la calibración.

En el siguiente paso, podemos registrar nuestras referencias para los colores de la matriz de colores. También podemos introducir nuestros propios nombres para los colores. Si no escribimos ningún nombre en la entrada, los textos se toman de la plantilla. Después de escanear todos los colores, aparece la siguiente información en la salida:


Copiamos el texto de "=Calibration Data" y lo pegamos en el archivo ColorMatch.h allí.

 


Nota: En el monitor serie, seleccione el texto y presione CTRL+C en el teclado. El botón derecho del ratón y copiar no funciona aquí.


Ahora recargamos el programa en el Arduino. Nuestros valores de referencia están almacenados. Ahora seleccionamos el modo de coincidencia con "M". Si escaneamos uno de los colores de referencia almacenados anteriormente, se nos emitirá de nuevo. Esta vez tiene lugar una ponderación. Aunque los valores no son exactamente los mismos, sigue siendo del mismo color:


35, 14, 8 (RGB) y 27, 9, 5 (RGB) se reconocen como marrones.

Ya podemos estar satisfechos con el resultado, ya que necesitamos exactamente eso para nuestro detector de color parlante. Sin embargo, esto significaría que tendríamos que grabar los colores de referencia cada vez y luego reprogramar el Arduino. Tenemos esto en mente y ahora queremos probar la segunda librería que hemos instalado.

Abrimos el proyecto de muestra "TCS3200_Calibration" de la librería "TCS3200". El pin D5 no necesariamente tiene que ser utilizado para la salida. Aquí podríamos cambiar el orden del pin de nuevo para que sea cronológico. Sin embargo, los dejaré de esta manera, si quiero comparar algo de nuevo. Entonces no necesito cambiar para poder usar la otra librería de nuevo. Así que cambiamos los números pin en esta línea:

TCS3200 TCS (4, 8, 6, 7, 5); // (S0, S1, S2, S3, Pin de Salida)

El pin OE no se necesita aquí. Pero como lo hemos puesto, también lo inicializamos para asegurarnos de que se establece en un nivel Low. Además, estamos ajustando la velocidad en baudios para el monitor serie de nuevo:

void setup() -
Serial.begin(115200);
pinMode(3, SALIDA);
digitalWrite(3, LOW);
}

Si ahora desea cargar el programa en el Arduino, recibirá un mensaje de error. Al menos en el caso de que se incluya la siguiente línea en su código fuente en la parte superior:

String distinctColors[num_of_colors] ="blanco", "negro" "rojo", "rojo", "amarillo", "verde", "naranja", "azul"};

así. Puede página Github de la biblioteca, pero la línea allí tiene este aspecto:

int distinctColors[num_of_colors] = en0, 1, 2, 3, 4, 5, 6};

Esta librería espera que la función ClosestColor() sea una matriz int y no una matriz de cadenas. No puedo decir por qué el ejemplo es diferente en la administración de librerías. Es posible que no tenga error. Después de la corrección, el programa se puede compilar y cargar. Todavía guardo la línea antigua y sólo cambio el nombre de la matriz:

String colorNames[num_of_colors] ="blanco", "negro" "rojo", "rojo", "amarillo" "verde", "naranja", "naranja", "azul"};

En este momento, ya pensé que los nombres de los colores, en lugar de los números deben ser emitidos. Podemos implementar esto más tarde.

Si ejecutamos el programa, vemos la salida cíclica de los valores de color.

En el código fuente encontraremos la siguiente línea en el área superior:

int distinctRGB[num_of_colors][3] = {{250, 250, 250}, {0, 0, 0}, {142, 34, 41}, {166, 125, 71}, {35, 55, 38}, {150, 50, 43}, {22, 25, 45}};

Estos son los valores de referencia para los colores. Ahora mantenga todas las tarjetas de referencia delante del sensor una vez más y transfiera los valores de color del monitor serie a la matriz. Tomo el orden de la línea de color. Así que blanco, negro, rojo, amarillo, verde, naranja y azul. A continuación, descargue el programa en el Arduino y escanee uno de los colores. Se le debe mostrar el número adecuado para usted

Sin embargo, dado que queremos ver textos en lugar de números, cambiamos en la función loop() la salida. La función ClosestColor() devuelve un valor int. Esto todavía se está gastando allí. Podemos usarlo como índice para la matriz con nuestros nombres de color. Así que vamos a cambiar la línea:

Serial.println(tcs.closestColor(distinctRGB, distinctColors, num_of_colors));

in:

Serial.println(colorNames[tcs.closestColor(distinctRGB, distinctColors, num_of_colors)]);

El requisito previo es que usted, como yo, mantenga la línea con los nombres y sólo cambió el nombre de la matriz a colorNames[].

Si ahora cargamos el programa en el Arduino y escaneamos uno de los colores de referencia, veremos los nombres asociados. De nuevo, también, se lleva a cabo una ponderación, es decir, los valores pueden variar y los colores siguen siendo reconocidos. Para añadir más colores, necesitamos el cambio constante Numofcolors y llevar más campos en las matrices distinctColors, distinctColors ,y COLORNAMES. Continuaré en la tercera parte.

Código fuente completo: 2.1tcs3200calibration_changed.ino

Con esta librería el ejemplo TCS3200_example estará incluido. Sin embargo, solo los valores de color medidos se emiten allí. Los valores de referencia de la calibración no se pueden introducir allí. Además, falta la ponderación y la salida del color registrado. Por lo tanto, no voy en el ejemplo en este punto.

Perspectivas

En la próxima entrada de blog integraremos el sensor de color en nuestro programa. Tenemos dos maneras de escanear los colores y pasar el nombre del color registrado con ponderación. Nuestro dispositivo debe emitir el color como un idioma. Buscaremos una manera de simplificar la calibración y evitar el paso de cargar del programa dos veces en el Arduino. Esto significa que tenemos que cambiar entre el modo Learn y el modo Match en la operación en vivo y almacenar los datos directamente en el Arduino. También me gustaría más idiomas que también podemos cambiar en la operación en vivo. Como también queremos utilizar el dispositivo móvil, lo prepararé para que funcione con batería.

Hasta entonces,

Andreas Wolter

AZ-Delivery Blog

Para arduinoProyectos para principiantesSensores

Deja un comentario

Todos los comentarios son moderados antes de ser publicados

Artículos de blog

  1. Ahora instalamos el esp32 a través de la administración.
  2. Lüftersteuerung Raspberry Pi
  3. Arduino IDE - Programmieren für Einsteiger - Teil 1
  4. ESP32 - das Multitalent
  5. Transporte Aéreo - programación de ESP mediante redes locales inalámbricas