[SOLUCIONADO] Crear un color con 4 LEDS?

Hola a todos,

Queria saber si con el siguiente codigo puedo enviar un color en HEX via bluetooth al arduino y que este los encienda de forma que los cuatro leds lo representen de la forma mas aproximada. Hay algun error en el?

 /*
 
 */

#define RED OCR1A
#define GREEN OCR1B
#define BLUE OCR1C
#define WHITE OCR4A

int whitevalue;


void setup() {
   // initialize serial:
  Serial.begin(9600);
  Serial.print("Arduino control RGB LEDs Connected OK ( Sent From Arduinno Board )");
  Serial.print('\n');
}

void loop() {
  // if there's any serial available, read it:
  while (Serial.available() > 0) {
     
    // look for the next valid integer in the incoming serial stream:
    int red = Serial.parseInt(); 
    // do it again:
    int green = Serial.parseInt(); 
    // do it again:
    int blue = Serial.parseInt(); 
    // do it again:
    int white = Serial.parseInt();
    
    // look for the newline. That's the end of your
    // sentence:
    if (Serial.read() == '\n') {

      // print the three numbers in one string as hexadecimal:
      Serial.print("Data Response : ");
      Serial.print(red, HEX);
      Serial.print(green, HEX);
      Serial.println(blue, HEX);
      Serial.println(white, HEX);
    }
  }
  
}

El código si funcionara, solo leerá 4 enteros desde el puerto serie y los asigna a las variables, red, blue, green, white y luego los vuelve a presentar por el puerto serie.

Si quieres visualizar el LED deberias cablear a 4 salidas del arduino, por ejemplo 2,3,4,5 definirlas como salida. Y luego con los 4 valores recibidos que supongo estan entre 0 y 255, usas analogWrite(pin, value) y lograrás el efecto buscado.

Solo por curiosidad, ¿por qué el led blanco? con la mezcla de los tres colores rojo, verde y azul, se puede crear el blanco.

carmeloco: Solo por curiosidad, ¿por qué el led blanco? con la mezcla de los tres colores rojo, verde y azul, se puede crear el blanco.

En resumen es por la pureza del blanco y por la facilidad de crear colores. Te dejo una explicacion que he encontrado en internet en ingles.

"If you’ve ever attempted to produce white light using a RGB LED array, you will inevitably find that the perceptual quality of that light is… off. To be more specific, the color balance is never quite right, there are always shadows that have variations in hue, and the precise color of white is poorly defined.

In order to fix this, there is a constraint that we can apply which changes our conversion from degenerate to fully defined. This constraint is as follows: Non-saturated hues will be generated by mixing of a fully saturated hue with white.

That’s all! Why is this a great constraint? First, the white from the white LED is carefully manufactured to be a very good approximation to “real” white. Second, it means that we will never be attempting to balance red, green, and blue off against each other.

The end result, is that the colors produced have the same apparent hue when fully saturated as they do when only slightly saturated.

According to the definition of saturation, it is the ratio of whiteness to “colorfulness” to be somewhat vague. In practice, we will assume that this means a linear relationship where a 50% saturated color is 50% “color” and 50% white. This fits in with traditional definitions, but is far more intuitive than definitions based on trigonometric functions in the context of an actual light that has actual white to add in. So, what we do in order to produce a fully optimized conversion from non-degenerate HSI colorspace to degenerate RGB+white colorspace is to first convert to a fully saturated, non-degenerate RGB colorspace, and then simply mix linearly with white."

surbyte: El código si funcionara, solo leerá 4 enteros desde el puerto serie y los asigna a las variables, red, blue, green, white y luego los vuelve a presentar por el puerto serie.

Quieres decir que recibira el dato, pero no lo enviara al LED?

Lo unico que te falta hacer es completar el codigo con 4 definiciones en el setup

void setup() {
// otras definiciones
  pinMode(RED, OUTPUT);
  pinMode(BLUE, OUTPUT); 
  pinMode(GREEN, OUTPUT);
  pinMode(WHITE, OUTPUT);

}

void loop() {

......................
 // luego de leer los datos del puerto serie agregas
 analogWrite(RED, red);
 analogWrite(BLUE, blue);
 analogWrite(GREEN, green);
 analogWrite(WHITE, white);

}

Y listo!!

Gracias por la respuesta Surbyte, lo probaré. Por cierto, el codigo cambia si escribo red o RED, o no es sensible a mayusculas y minusculas?

El analogwrite funciona a 8 bits, no? Hay alguna forma para mandar valores de 16 bits?

Ojo con eso!!! Definiste con MAYUSCULAS tus pines. Yo uso este criterio en lugar del tuyo pero cada cual tiene su convención. Mi criterio (adoptado de un buen programador americano) es agregar Pin a la etiqueta que identifica la salida por ejemplo

En tu caso quedaría asi PWM pins (3, 5, 6, 9, 10, or 11)

 */

const byte redPin =  3;
const byte bluePin =  5;
const byte greenPin = 6;
const byte whitePin = 9;

int red, blue, green, white;


void setup() {
   // initialize serial:
  pinMode(redPin, OUTPUT);
  pinMode(bluePin, OUTPUT);
  pinMode(greenPin, OUTPUT);
  pinMode(whitePin, OUTPUT);

  Serial.begin(9600);
  Serial.print("Arduino control RGB LEDs Connected OK ( Sent From Arduinno Board )\n");
}

void loop() {

  // if there's any serial available, read it:
  while (Serial.available() > 0) {
     
    // look for the next valid integer in the incoming serial stream:
    red = Serial.parseInt(); 
    // do it again:
    green = Serial.parseInt(); 
    // do it again:
    blue = Serial.parseInt(); 
    // do it again:
    white = Serial.parseInt();
    
    // look for the newline. That's the end of your
    // sentence:
    if (Serial.read() == '\n') {

      // print the three numbers in one string as hexadecimal:
      Serial.print("Data Response : ");
      Serial.print(red, HEX);
      Serial.print(green, HEX);
      Serial.println(blue, HEX);
      Serial.println(white, HEX);
      analogWrite(red, redPin);
      analogWrite(green, greenPin);
      analogWrite(blue, bluePin);
      analogWrite(white, whitePin);

    }
  }
  
}

Muchisimas gracias Surbyte, lo provare. Sirve tambien para manda valores de 0 a 65535, o solo funciona con valores de 0 a 255?

Las salidas pwm, solo permiten un maximo de 255. En el DUE, el maximo llega a 4095.

No te deprimas :grin: Aun así, tienes potencialmente 16 millones de combinaciones de colores para probar, sin contar con el led blanco.

noter: No te deprimas :grin: Aun así, tienes potencialmente 16 millones de combinaciones de colores para probar, sin contar con el led blanco.

Sí, eso es lo que en su día tenía el Commodore Amiga, y era una pasada. De todas formas, no creo que consigas tantos matices de color con leds, de forma que los 255 (256 contando el cero) creo que pueden ser más que suficientes.

Bueno, yo tengo un Leonardo y me habian dicho que si se podia, lo que no se como.

Tienes un leonardo pero parece que sabes poco de él. Que tal si usas las palabras mágicas: Arduino Leonardo y ves que puede hacer y que no?

Luego con mas fundamento seguimos hablando pero no podemos hacer todo tu trabajo... algo tienes que hacer tu, no te parece?

Como dije, solo buscas Arduino Etiqueta (etique es lo que te importa buscar) y salen toneladas de información de lo que sea. Asi que ejemplo. google : Arduino Leonardo y mira que surge..

Yo solo queria saber si es posible enviar tales valores a traves de un pin del leonardo, y si es asi que instruccion se usa, no pido que me den el codigo escrito ya. Sabiendo el nombre de lo que busco es mas facil encontrar informacion por mi cuenta en google.

El secreto de las busquedas en internet es que empiezas de una manera y terminas con otra.
En tu caso… buscas ARDUINO 4 LED por ejemplo y verás cosas con 4 leds, entonces ahhh no es asi.
de golpe lees multicolor led y pruebas
Arduino Multicolor Led y empieza a aparecer lo que buscas, y entre las opciones a leer, verás algo como RGB LED link1, link2.
La buena info esta en inglés generalmente.

Pero en tu caso buscas RGBW que incluye el blanco.

Buscar ya he buscado, no te creas. El problema es que lo que busco ahora es como enviar a los pines valores de hasta 65535, y por lo que estoy leyendo el Leonardo si que permite trabajar hasta 16bits en pwm, pero el analogwrite solo es capaz de hacerlo hasta 255 http://arduino.cc/en/pmwiki.php?n=Tutorial/SecretsOfArduinoPWM
El problema está en el “equivalente en 16 bits a analogwrite” por decirlo de alguna manera.

Bien, por lo visto diste con la tecla en algo que yo no habia reparado.. y es que parece ser que analogWrite esta limitado a 8 bits pero los microcontroladores si tienes timers de 16 bits y por ende puedes alcanzar esos 0 a 65535 pasos deseados.

ATMEGA328 tiene Timer0 y Timer2 a 8 bits pero Timer1 es 16 bits. mmmm no se porque analogWrite no deja usarlo será por compatibilidad con los que no son 16 bits.

ATmega1280 o el ATmega2560. Estos tienen 6 timers. Timer 0, timer1 and timer2 son iguales al ATmega168/328. El timer3, timer4 and timer5 son todos de 16bit idénticos al timer1.

Entonces. Con UNO/NANO solo tienes dos salidas 16 bits Con Mega tienes lo necesario.

Y evidentemente para usarlo debes recurrir a otra librería y no usar analogWrite

Empezamos a entendernos. Lo que pasa aparte de los timers como https://www.pjrc.com/teensy/td_libs_TimerOne.html es que si bien usandolas correctamente te permiten el calculo de esos valores....Como "escribes" esos valores en pin pwm si no puedes usar Analogwrite? Ese es el gran problema y que no consigo resolver. En principio los pins que uso en el codigo, en un Leonardo, corresponden a los usados por los Timers que son capaces de calcular con esos 16 bits.

Yo no es por aguar la fiesta, pero, usando el standard RGB, si usamos 256 valores distintos para cada uno de los tres colores, obtenemos 16.777.216 colores diferentes.

Hasta el famosísimo photoshop, usa 256 valores para cada uno de los componentes RGB.

El ojo humano, es capaz de distinguir alrededor de los 8.000.000.

En definitiva, no veo la necesidad de usar más...