Escribir en matriz 8x8 desde monitor serial[SOLUCIONADO]

Hola a todos:

Hace tiempo, he copiado este código desde el github de MD_MAX72xx.

En teoría, al escribir en el monitor, se debe trasladar lo escrito a la matriz 8x8 y en desplazamiento scroll.

He conseguido, únicamente, representar en la matriz el mensaje de /…uint8_t curMessage[BUF_SIZE] = { "Hola.12" }; …/ y regular su velocidad de desplazamiento con potenciómetro.

No consigo trasladar el mensaje desde el monitor a la matriz 8x8.

Adjunto código.

Gracias por la ayuda !!.... :cocktail_glass:... :cocktail_glass:


/*
   MATRIZ 8x8 + MONITOR + POTENCIOMETRO

   IDE: Archivo/Ejemplos/MD_MAX72xx/MD_MAX72xx_Message_Serial

   https://github.com/MajicDesigns/MD_MAX72XX/blob/main/examples/MD_MAX72xx_Message_Serial/MD_MAX72xx_Message_Serial.ino

   GITHUB: examples/MD_MAX72xx_Message_Serial/MD_MAX72xx_Message_Serial.ino


*/
// Desplazar texto en la pantalla; Biblioteca  MD_MAX72XX
//
// Demuestra el uso de la función de devolución de llamada para controlar qué se desplaza en el texto de la pantalla.
//
// El usuario puede introducir texto en el monitor serie y este se mostrará como un mensaje desplazable en la pantalla.
// La velocidad de la pantalla se controla mediante un potenciómetro en la entrada analógica SPEED_IN: (A5).
//
#include <MD_MAX72xx.h>
#include <SPI.h>

#define IMMEDIATE_NEW   1   // Si "1": mostrará inmediatamente un nuevo mensaje
#define USE_POT_CONTROL 1   // Si "1": Habilita uso potenciometro.
#define PRINT_CALLBACK  1   // Si "1": Imprime en monitor valores: potenciometro(velocidad)

#define PRINT(s, v) { Serial.print(F(s)); Serial.print(v); }

// Define la cantidad de dispositivos que tenemos en la cadena y la interfaz de hardware.
// NOTA: Es probable que estos números de pin no funcionen con tu hardware y deban adaptarse.

// VARIAS SOLUCIONES de HARDWARE_TYPE: //>>PAROLA_HW--DR1CR1RR1_HW--DR0CR0RR1_HW--DR0CR1RR0_HW

#define HARDWARE_TYPE MD_MAX72XX::ICSTATION_HW
#define MAX_DEVICES 1

#define CLK_PIN   13  // or SCK
#define DATA_PIN  11  // or MOSI
#define CS_PIN    10  // or SS

// SPI hardware interface
//MD_MAX72XX mx = MD_MAX72XX(HARDWARE_TYPE, CS_PIN, MAX_DEVICES);

// pines arbitrarios
MD_MAX72XX mx = MD_MAX72XX(HARDWARE_TYPE, DATA_PIN, CLK_PIN, CS_PIN, MAX_DEVICES);

// Scrolling parameters
#if USE_POT_CONTROL
#define SPEED_IN  A5     // Entrada potenciometro: Analogica 5
#else
#define SCROLL_DELAY  75  // 75 in milliseconds
#endif                    // USE_POT_CONTROL

#define CHAR_SPACING  1   // píxeles entre caracteres 

#define BUF_SIZE  75       // Buffers de mensajes globales compartidos por las funciones seriales y de desplazamiento
uint8_t curMessage[BUF_SIZE] = { "Hola.12" };
uint8_t newMessage[BUF_SIZE];
bool newMessageAvailable = false;

uint16_t  scrollDelay;  // en milliseconds

void readSerial(void)
{
  static uint8_t  putIndex = 0;

  while (Serial.available())
  {
    newMessage[putIndex] = (char)Serial.read();
    if ((newMessage[putIndex] == '\n') || (putIndex >= BUF_SIZE - 3)) // end of message character or full buffer
    {
      // Coloque un separador de mensajes y finalice la cadena
      newMessage[putIndex++] = ' ';
      newMessage[putIndex] = '\0';
      // Reiniciar el índice para la próxima ola de llenado y marcar que tenemos un mensaje en espera.
      putIndex = 0;
      newMessageAvailable = true;
    }
    else if (newMessage[putIndex] != '\r')// guarde el siguiente carácter en la siguiente ubicación

      putIndex++;
  }
}

//Función de devolución de llamada para datos que se desplazan fuera de la pantalla
void scrollDataSink(uint8_t dev, MD_MAX72XX::transformType_t t, uint8_t col)
{
#if PRINT_CALLBACK
  Serial.print("\n cb ");
  Serial.print(dev);
  Serial.print(' ');
  Serial.print(t);   // tabulador
  Serial.print(' ');
  Serial.println(col);
#endif
}
// Función de devolución de llamada para los datos que se requieren para desplazarse por la pantalla
uint8_t scrollDataSource(uint8_t dev, MD_MAX72XX::transformType_t t)
{
  static uint8_t* p = curMessage;
  static enum { NEW_MESSAGE, LOAD_CHAR, SHOW_CHAR, BETWEEN_CHAR } state = LOAD_CHAR;
  static uint8_t  curLen, showLen;
  static uint8_t  cBuf[15];
  uint8_t colData = 0;      // La columna en blanco es la predeterminada

#if IMMEDIATE_NEW
  if (newMessageAvailable)  // Hay un nuevo mensaje esperando
  {
    state = NEW_MESSAGE;
    mx.clear();              // borrar la pantalla
  }
#endif

  // máquina de estados finitos para controlar lo que hacemos en la devolución de llamada
  switch (state)
  {
    case NEW_MESSAGE:               // Cargar el nuevo mensaje
      memcpy(curMessage, newMessage, BUF_SIZE);	// copiarlo en
      newMessageAvailable = false;    // ¡Lo usé!
      p = curMessage;
      state = LOAD_CHAR;
      break;

    case LOAD_CHAR:                    // Cargar el siguiente carácter de la tabla de fuentes
      showLen = mx.getChar(*p++, sizeof(cBuf) / sizeof(cBuf[0]), cBuf);
      curLen = 0;
      state = SHOW_CHAR;

      // Si llegamos al final del mensaje, oportunidad de cargar el siguiente.
      if (*p == '\0')
      {
        p = curMessage;     // restablecer el puntero al inicio del mensaje
#if !IMMEDIATE_NEW
        if (newMessageAvailable)  // SI Hay un nuevo mensaje esperando
        {
          state = NEW_MESSAGE;    // Lo cargaremos aqui
          break;
        }
#endif
      }
    // !! pasar deliberadamente al siguiente estado para comenzar a mostrar

    case SHOW_CHAR:             //mostrar la siguiente parte del mensaje
      colData = cBuf[curLen++];
      if (curLen == showLen)
      {
        showLen = CHAR_SPACING;
        curLen = 0;
        state = BETWEEN_CHAR;
      }
      break;

    case BETWEEN_CHAR:          // mostrar el espaciado entre caracteres (columnas en blanco)
      colData = 0;
      curLen++;
      if (curLen == showLen)
        state = LOAD_CHAR;
      break;

    default:
      state = LOAD_CHAR;
  }

  return (colData);
}

void scrollText(void)
{
  static uint32_t	prevTime = 0;

  //¿Es hora de desplazarse por el texto?
  if (millis() - prevTime >= scrollDelay)
  {
    mx.transform(MD_MAX72XX::TSL);  // desplazarse a lo largo del camino - la devolución de llamada cargará todos los datos
    prevTime = millis();            // punto de partida para la próxima vez
  }
}

uint16_t getScrollDelay(void)
{
#if USE_POT_CONTROL
  uint16_t  t;

  t = analogRead(SPEED_IN);     // Entrada potenciometro: analogica 5
  t = map(t, 0, 1023, 25, 250);

  return (t);
#else
  return (SCROLL_DELAY);        // 75 milliseconds
#endif
}

void setup()
{
  Serial.begin(57600);
  mx.begin();
  mx.setShiftDataInCallback(scrollDataSource);
  mx.setShiftDataOutCallback(scrollDataSink);

#if USE_POT_CONTROL
  pinMode(SPEED_IN, INPUT);     // Entrada potenciometro: analogica 5
#else
  scrollDelay = SCROLL_DELAY;   // 75 milliseconds
#endif
  newMessage[0] = '\0';

  Serial.print("\n[MD_MAX72XX Visualización de mensajes]\nEscriba un mensaje para la pantalla desplazable\nFin de la línea del mensaje con una nueva línea");
}

void loop()
{
  scrollDelay = getScrollDelay();
  readSerial();
  scrollText();
}

//**************************  FIN  ******************************

[/code]

Lo simulé en wokwi y funciona (solo que el texto sale patas para arriba).
Seteaste la terminal a 57600?

1 Like

Hola @MaximoEsfuerzo !!!

Si, en el monitor a 57600. (Serial.begin(57600);)

Yo cambio la orientación de las letras según: // VARIAS SOLUCIONES de HARDWARE_TYPE: //ICSTATION_HWPAROLA_HWDR1CR1RR1_HWDR0CR0RR1_HWDR0CR1RR0_HW.

Utilizando una u otra , las letras salen invertidas, cabeza abajo o derecha/izquierda o al revés;

esto no es un problema para mi. Yo escojo según mi conveniencia.

Como comentaba, lo único que reproduce la Matriz es: "Hola.12" de curMessage[BUF_SIZE]

Lo que no funciona es: Al escribir en monitor, no se reproduce en la Matriz 8x8 ???.

Un saludo !!!…:cocktail_glass::cocktail_glass:

1 Like

Gracias a la simulación de @MaximoEsfuerzo hice una sola correccion y funciona bien.

Corrección realizada.

#define HARDWARE_TYPE MD_MAX72XX::DR1CR1RR0_HW 

Escribes en serial y se visualiza en la matriz.

3 Likes

Hola @MaximoEsfuerzo Gracias por tu rápida respuesta.!!!

En tu simulación wokwi :

  • Representa en Matriz : Hola. 12 (igual al mío)
  • En monitor: escribe datos siguiendo la Instrucción: #define PRINT_CALLBACK 1 // Si "1": Imprime en monitor valores: potenciómetro(velocidad) (igual)
  • No he podido (en el wokwi), entrar mensaje en monitor serial, por tanto no ha variado el mensaje en la Matriz. ???

Me lo puedes aclarar ???

Gracias !!!

Hola @Surbyte :

Gracias por tu rápida respuesta.!!!

Te respondo “casi” igual que a @MaximoEsfuerzo :

En tu simulación rectificada de wokwi :

  • Representa en Matriz : Hola. 12 (igual al mío)

  • En monitor: ya no escribe datos siguiendo la Instrucción: #define PRINT_CALLBACK 1 // Si "1": Imprime en monitor valores: potenciómetro(velocidad) , ya que has variado a un ”(0)”

  • La corrección : #define HARDWARE_TYPE MD_MAX72XX::DR1CR1RR0_HW, no me afecta, (solo en la posición de las letras), ya que las vario a mi gusto.

  • No he podido (en el wokwi), entrar mensaje en monitor serial, por tanto no ha variado el mensaje en la Matriz. ???. Es el mismo problema que en mi circuito real .

Gracias de nuevo !!!

Lo tenés que ingresar en el campo de entrada de la terminal del simulador.

Aprovecho la versión corregida de @Surbyte para que se vea mejor :wink:

1 Like

Hola @MaximoEsfuerzo Gracias por la documentada respuesta !! :

He conseguido, que funcione el wowki.

En wowki, puedo cambiar el mensaje y cambio su velocidad. Hasta he cambiado la orientación de las letras varias veces.

En el circuito real, puedo: cambiar velocidad, orientación y representación en monitor de datos tabulados.

No consigo, escribiendo en monitor, que cambie la matriz.

Lógicamente, el código que utilizamos en el wowki, es el mismo que utilizo en el real.

Uso una UNO versión 1.8.3 .

No llego a comprender que ocurre ???.

Un saludo !!! …:cocktail_glass::cocktail_glass:

Y como tienes el Monitor serie configurado?
Mira esto y coméntanos

PD: Creo que tu problema esta por lo que acabo de señalar pero si no, busca en esto último.
Hay que probar todo y documentar que se hace para no hacerlo a lo loco y no saber que probé antes.
Siempre que tengas un problema hay dos caminos:

  1. Entender. para lo cual se debe leer y hacerlo comprensivamente. Leer no significa que se entiende, a veces requiere de algún ensayo/error para que la ficha cerebral caiga.
  2. Si lo anterior no va.... prueba error con documentación como digo yo. Anotas, prueba 1. hice tal y cual cosa.. no anduvo.
    Prueba 2... modifiqué esto y lo otro.
    TIP o Truco: no hagas mas de 1 cambio por vez.
1 Like

Hola GRAN MAESTRO @Surbyte :

La veteranía es un grado !!!. :roll_eyes:

He probado (como bien insinuaste) en los parámetros del monitor, he seleccionado: Nueva linea ….y… bingo !!!.
A funcionado !!
(con: Ambos NL&CR también funciona)
Nunca me había visto en la necesidad de cambiar ese parámetro.
Antes de consultar al Foro, estuve cambiando datos en todo el código.

El resto de tus sabias recomendaciones, es el que normalmente utilizo:

Pero.....A veces (o siempre) nos faltan conocimientos !!!!

Muchísimas gracias !!! :bottle_with_popping_cork:... :cocktail_glass:... :cocktail_glass:

Por eso, 1. lleva tiempo hasta pasar a 2.
jajaja

1 Like