Manipular objeto pasando una variable a una funcion

Hola a todos

Estoy armando los circuitos del tiempo del DeLorean de volver al futuro

Tengo el display rojo y el verde (los leds amarillos aun no los consegui)

Mi problema es que creo el objeto verde y el objeto rojo y tengo funciones para dibujar cada letra y numero, pero si bien el codigo se repite, tengo que declarar el objeto verde o el rojo segun cual quiero escribir

Mi idea es pasar una variable a una funcion que tenga todos las funciones de los numeros y con pasarle 0 o 1 sepa si tiene que escribir la matriz roja o verde. Espero haber transmitido la idea

Sigue el codigo

#include <Wire.h>
#include <Adafruit_GFX.h>
#include "Adafruit_LEDBackpack.h"
Adafruit_8x16matrix rojo = Adafruit_8x16matrix();
Adafruit_8x16matrix verde = Adafruit_8x16matrix();


void setup() 
{

  rojo.begin(0x70);  // pass in the address
  verde.begin(0x71);  // pass in the address
  rojo.clear();
  verde.clear();
}


void loop()
{
  verde.drawPixel(7, 15, LED_ON);//G
  verde.drawPixel(6, 15, LED_ON);//G
  rojo.drawPixel(7, 15, LED_ON);//G
  rojo.drawPixel(6, 15, LED_ON);//G
  verde.writeDisplay();
  rojo.writeDisplay();

  delay(500);

  verde.drawPixel(7, 15, LED_OFF);//G
  verde.drawPixel(6, 15, LED_OFF);//G
  rojo.drawPixel(7, 15, LED_OFF);//G
  rojo.drawPixel(6, 15, LED_OFF);//G
  rojo.writeDisplay();
  verde.writeDisplay();
  delay(500);
}

Como ven repito el mismo código para el display rojo y el verde
Mi idea es crear una función asi

void blink(string VARIABLE) //String como ejemplo, la idea es pasarle "amarillo" por ejemplo y que la función substituya en la linea
{
VARIABLE.drawPixel(7, 15, LED_ON);//G
VARIABLE.drawPixel(6, 15, LED_ON);//G
VARIABLE.writeDisplay();
}
Ejemplo llamo a la función blink (amarillo) y que me devuelva
{
amarillo.drawPixel(7, 15, LED_ON);//G
amarillo.drawPixel(6, 15, LED_ON);//G
amarillo.writeDisplay();
}
Y si llamo a blink(rojo)
{
rojo.drawPixel(7, 15, LED_ON);//G
rojo.drawPixel(6, 15, LED_ON);//G
rojo.writeDisplay();
}

Sino tengo que repetir las mismas 5 lineas creando funciones para cada modulo HT16K33 iniciado (rojo, amarillo, verde)

Existe posibilidad de manipular los objetos de esta manera o tengo que apegarme a llamar a cada modulo por separado repitiendo gran parte del código para cada color en el proceso?

Desde ya muchas gracias

Prueba crear un solo objeto con indice, por ejemplo; Adafruit_8x16matrix led[3] = Adafruit_8x16matrix();
e iniciando cada uno con el indice led[0].begin(0x70); Luego crea una función donde le pases el indice. En teoría debería funcionar(no lo probé ).

saludos

Pasa a la función el puntero del objeto:

void blink(Adafruit_8x16matrix* VARIABLE) 
{
VARIABLE->drawPixel(7, 15, LED_ON);//G
VARIABLE->drawPixel(6, 15, LED_ON);//G
VARIABLE->writeDisplay();
}


//Hay que pasar la dirección, usando &
// Para llamar a la función con verde

blink(&verde);

// Para usar la función con rojo

blink(&rojo);

Saludos

Hay otra opción. Pasar a la función una referencia en lugar de un puntero.

void blink(Adafruit_8x16matrix &variable)
{
  variable.drawPixel(7, 15, LED_ON);
  variable.drawPixel(6, 15, LED_ON);
  variable.writeDisplay();
}

// Para llamar a la función con verde
blink(verde);

// Para usar la función con rojo
blink(rojo);

Uso variable en lugar de VARIABLE porque todo en mayúsculas se suele usar para las constantes (ej. LED_ON).

Diferencias entre pasar una referencia respecto a pasar un puntero: al declarar la función en el parámetro se pone un & en lugar de un * indicando así que la función recibe una referencia en lugar de un puntero. Dentro de la función se utiliza el operador . (punto) en lugar del operador -> para acceder a las funciones o variables miembro del objeto (la referencia es, en principio, la misma cosa que lo referenciado, así que se utilizan y se comportan igual. Sin embargo un puntero es "otra cosa"). En las llamadas a la función no hay que poner el & al parámetro para "obtener" el puntero.

Nota: espero que el poner un delay() es porque se trata de un ejemplo. Porque mi consejo es que no uses delay(), en su lugar usa millis() y "máquinas de estado". Aunque inicialmente es más complicado, a la larga te resuelve muchos problemas que tiene el uso del delay(). En la parte del documentación del foro puedes encontrar información de cómo usar millis() y "máquinas de estado".

P. D. Yo no lo haría con "funciones sueltas" sino que, haciendo uso de la "programación orientada a objetos", haría una clase que se encargaría de "gestionar" los datos y el comportamiento de un display y crearía tres objetos de esa clase, uno por cada display. Luego a cada objeto le dices qué quieres que muestre y cómo quieres que lo muestre.

PeterKantTropus:
Prueba crear un solo objeto con indice, por ejemplo; Adafruit_8x16matrix led[3] = Adafruit_8x16matrix();
e iniciando cada uno con el indice led[0].begin(0x70); Luego crea una función donde le pases el indice. En teoría debería funcionar(no lo probé ).

saludos

Luego de leer los 2 métodos propuestos utilice el de PeterKantTropus y funciono a la perfección!

Un comentario interesante, pensé que doblando el codigo a la mitad (un tercio si tuviera encaminado el display amarillo) el tamaño del sketch y variables se reduciría notablemente

El sketch esta pesando alrededor de 300Kb y lo estoy corriendo desde un ESP8266 (también me beneficio de poder obtener la hora por servidor NTP y no depender de un RTC)

Sin embargo apenas logre una disminución de unos 8Kb de codigo. De todas formas no me molesta el esp tiene 1mb de flash (aunque se supone que debia ser de 4, china.com...)

De todas formas va mucho mas encaminado. Me falta hacer la función blink para los led de segundos y un comparador de horas para los led de AM/PM y luego falta el sonido y el keypad!

Hasta logre mandarle un string por puerto serial y que muestre el tiempo de destino!

Nuevamente muchas gracias!

SI alguien desea armar su propio circuito del tiempo o quiere alguna foto de lo que voy armando puede enviarme un PM

Este hilo se puede cerrar (si lo tiene que hacer el autor avísenme, que no se como hacerlo)

Los veré en el futuro!... mmm en el pasado! Exacto!

IgnoranteAbsoluto:
Nota: espero que el poner un delay() es porque se trata de un ejemplo. Porque mi consejo es que no uses delay(), en su lugar usa millis() y "máquinas de estado". Aunque inicialmente es más complicado, a la larga te resuelve muchos problemas que tiene el uso del delay(). En la parte del documentación del foro puedes encontrar información de cómo usar millis() y "máquinas de estado".

P. D. Yo no lo haría con "funciones sueltas" sino que, haciendo uso de la "programación orientada a objetos", haría una clase que se encargaría de "gestionar" los datos y el comportamiento de un display y crearía tres objetos de esa clase, uno por cada display. Luego a cada objeto le dices qué quieres que muestre y cómo quieres que lo muestre.

Si, lo del delay fue en principio para probar, estoy familiarizado con el blink without delay e intente implementarlo esta mañana cuando estaba armando la funcion de blink de los led de segundos.

Pero en algún punto tengo que usar si o si aunque sea 1 delay en el loop, de entre 100 a 200ms, debido al tiempo que le lleva a los módulos HT16K33 "refrescar" los display y a la función para obtener la fecha y hora por NTP. He intentado dejar el loop corriendo lo mas libre posible pero muchas veces la hora al iniciar el skecth no se actualiza desde internet y los displays presentan comportamiento errático.

Hablando de la libreria tengo ganas de implementar algo como lo sugerido, pero una vez que arme el display amarillo y tenga todo estructurado veré de seguir reduciendo el código.

De todas maneras como el sketch solo necesita actualizar la hora cada 60 segundos, y alternar los led cada 500ms por ahora no tengo mucha limitacion de "procesamiento"

Ademas el ES8266 esta corriendo a 160Mhz