Fallo recepcion i2c

Buenos dias, como digo en el titulo esoty intentando hacer una red i2c con dos arduinos, Master-mega Salve1-Uno
El tema es que cada uno de ellos por medio de la libreria Pxmatrix tiene un panel RGB 32*16 y quiero decirle al esclavo que tiene que pintar dependiendo de un numero que mande el Master.

Pero en el esclavo algo hago mas que no lo logro.

Pongo los codigo por si alguien me puede indicar.

Basicamente es, con un flanco se de subida el master pinta una cosa y manda un 1, con un flanco descente pinto otra cosa y mando un 5

El esclavo tiene que ver el 1 y el cinco y pintar cosas deacuerdo con el que le llege.

Master

#define PxMATRIX_COLOR_DEPTH 1
#define PxMATRIX_MAX_HEIGHT 16
#define PxMATRIX_MAX_WIDTH 32

#include <Wire.h>
#include <PxMatrix.h>
#include <avr/pgmspace.h>
// Pins for LED MATRIX
#define P_A 2
#define P_B 3
#define P_C 0
#define P_D 0
#define P_E 0
#define P_LAT 7
#define P_OE 8

//PxMATRIX display(32,16,P_LAT, P_OE,P_A,P_B,P_C);
//PxMATRIX display(64,32,P_LAT, P_OE,P_A,P_B,P_C,P_D);
PxMATRIX display(32,16,P_LAT, P_OE,P_A,P_B);

// Some standard colors
uint16_t myRED = display.color565(255, 0, 0);
uint16_t myGREEN = display.color565(0, 255, 0);
uint16_t myBLUE = display.color565(0, 0, 255);
uint16_t myWHITE = display.color565(255, 255, 255);
uint16_t myYELLOW = display.color565(255, 255, 0);
uint16_t myCYAN = display.color565(0, 255, 255);
uint16_t myMAGENTA = display.color565(255, 0, 255);
uint16_t myBLACK = display.color565(0, 0, 0);

unsigned long start_time=0;
uint8_t icon_index=0;
#define PIN_BOTON_A 6
byte x = 0;
String cadena_1 = "Hola";


void setup()
{
  Wire.begin(); // join i2c bus (address optional for master)
  Serial.begin(9600);
  display.begin(2);
  display.setMuxPattern(BINARY);
  display.setScanPattern(ZAGGIZ);
  display.setPanelsWidth(1);


  display.clearDisplay();
  display.setTextColor(myMAGENTA);
  display.setCursor(1,8);
  display.print("test");
  start_time = millis();
  while((millis()-start_time)<3000)
    display.display(20);
delay(2000);

}


void loop()
{
int flanco_A = detectaFlanco(PIN_BOTON_A);
  if (flanco_A == 1)
  {cadena_1 = "Hola_1";
  display.clearDisplay();
  scroll_text(cadena_1);
  x=1;
  Wire.beginTransmission(1); // transmit to device #4
  Wire.write(x);              // sends one byte  
  Wire.endTransmission();    // stop transmitting
  
  }
     
  if (flanco_A == -1){
    cadena_1 = "Hola_2";
    display.clearDisplay();
    scroll_text(cadena_1);
  x=5;
  Wire.beginTransmission(1); // transmit to device #4
  Wire.write(x);              // sends one byte  
  Wire.endTransmission();    // stop transmitting
  }
    
}


void scroll_text(String cadena_1)
{
    display.setTextWrap(false);  // we don't wrap text so it scrolls nicely
    display.setTextSize(1);
    display.setRotation(0);

    for (int xpos=64; xpos>-140; xpos--)
    {
      display.setTextColor(myWHITE);
      display.clearDisplay();
      display.setCursor(xpos,0);
      display.println(cadena_1);
      start_time = millis();
      while((millis()-start_time)<15)
           display.display(5);
    }
}


int detectaFlanco(int pin) {
  //Devuelve 1 flanco ascendente, -1 flanco descendente y 0 si no hay nada
  static boolean anterior_estado = digitalRead(pin);
  boolean estado = digitalRead(pin);

  if (anterior_estado != estado) {
    if (estado == HIGH) {
      anterior_estado = estado;
      return 1;
    }
    else {
      anterior_estado = estado;
      return -1;
    }
  }
  else {
    return 0;
  }
}

Esclavo

#define PxMATRIX_COLOR_DEPTH 1
#define PxMATRIX_MAX_HEIGHT 16
#define PxMATRIX_MAX_WIDTH 32

#include <PxMatrix.h>
#include <avr/pgmspace.h>
#include <Wire.h>

// Pins for LED MATRIX
#define P_A 2
#define P_B 3
#define P_LAT 7
#define P_OE 8

PxMATRIX display(32, 16, P_LAT, P_OE, P_A, P_B);

// Some standard colors
uint16_t myRED = display.color565(255, 0, 0);
uint16_t myGREEN = display.color565(0, 255, 0);
uint16_t myBLUE = display.color565(0, 0, 255);
uint16_t myWHITE = display.color565(255, 255, 255);
uint16_t myYELLOW = display.color565(255, 255, 0);
uint16_t myCYAN = display.color565(0, 255, 255);
uint16_t myMAGENTA = display.color565(255, 0, 255);
uint16_t myBLACK = display.color565(0, 0, 0);

unsigned long start_time=0;
uint8_t icon_index=0;

String cadena_1="Hola";

void setup() {
     Serial.begin(9600);
     display.begin(2);
     display.setMuxPattern(BINARY);
     display.setScanPattern(ZAGGIZ);
     display.setPanelsWidth(1);

  Wire.begin(1);                // join i2c bus with address #4
  Wire.onReceive(receiveEvent); // register event

  display.clearDisplay();
  display.setTextColor(myMAGENTA);
  display.setCursor(0,8);
  display.print("INICIO");
  start_time = millis();
  while((millis()-start_time)<3000)
    display.display(20);
 delay(3000);
}

void loop()
{
  delay(100);
 }

// function that executes whenever data is received from master
// this function is registered as an event, see setup()
void receiveEvent(int howMany)
{
  int x;
  while(1 < Wire.available()) // loop through all but the last
//  {
//    char c = Wire.read(); // receive byte as a character
//   Serial.print(c);         // print the character
//  }
  int x = Wire.read();    // receive byte as an integer
//  Serial.println(x); // print the integer


if (x==1){cadena_1="tengo un 1";
     display.clearDisplay();
  scroll_text(cadena_1);}
  if (x==5){cadena_1="tengo un 5";
      display.clearDisplay();
  scroll_text(cadena_1); }
     
}

void scroll_text(String cadena_1)
{
    display.setTextWrap(false);  // we don't wrap text so it scrolls nicely
    display.setTextSize(1);
    display.setRotation(0);

    for (int xpos=64; xpos>-140; xpos--)
    {
      display.setTextColor(myWHITE);
      display.clearDisplay();
      display.setCursor(xpos,0);
      display.println(cadena_1);
      start_time = millis();
      while((millis()-start_time)<15)
           display.display(5);
    }
}

Hay varios hilos similares con respuestas a tus preguntas en esta sección, porqué no los buscas y tendrás buenas ideas?

Pregunta: lo que envias con el master es recibido por el esclavo? Hablo de los msgs.

Buenas tardes, he leido todos los que he encontrado pero no la solucion a mi problema.

Lo que envio si es recibido pero cuando le digo que pinte en el panel rgb se queda como colgado, y no funciona bien, vamos nunca llega a pintar nada y luego ya no puedo continuar enviando nada.

He pensado incluso tratar de sacar el valor que recibo al void loop() y usarlo en el pero tampoco he logrado hacerlo.

¿Alguna indicacion? Gracias.

Entonces tu problema no es comunicación. Sino la tarea que sigue.

Para que tienes esto empecemos a encontrar responsables

void loop() {
  delay(100);
}

quita ese delay() deja solo

void loop() {} y listo

son 100 mseg menos por cada acción.

Prueba esto y dinos como va

#include <PxMatrix.h>
#include <avr/pgmspace.h>
#include <Wire.h>

// Pins for LED MATRIX
#define P_A 2
#define P_B 3
#define P_LAT 7
#define P_OE 8

PxMATRIX display(32, 16, P_LAT, P_OE, P_A, P_B);

// Some standard colors
uint16_t myRED = display.color565(255, 0, 0);
uint16_t myGREEN = display.color565(0, 255, 0);
uint16_t myBLUE = display.color565(0, 0, 255);
uint16_t myWHITE = display.color565(255, 255, 255);
uint16_t myYELLOW = display.color565(255, 255, 0);
uint16_t myCYAN = display.color565(0, 255, 255);
uint16_t myMAGENTA = display.color565(255, 0, 255);
uint16_t myBLACK = display.color565(0, 0, 0);

unsigned long start_time=0;
uint8_t icon_index=0;
String cadena_1="Hola";
volatile bool flag = false;

void setup() {
  Serial.begin(9600);
  display.begin(2);
  display.setMuxPattern(BINARY);
  display.setScanPattern(ZAGGIZ);
  display.setPanelsWidth(1);

  Wire.begin(1);                // join i2c bus with address #4
  Wire.onReceive(receiveEvent); // register event

  display.clearDisplay();
  display.setTextColor(myMAGENTA);
  display.setCursor(0,8);
  display.print("INICIO");
  start_time = millis();
  while ((millis()-start_time)<3000)
         display.display(20);
  delay(3000);
}

void loop()
{
  if (flag) {
    if (x==1)
        cadena_1="tengo un 1";
    if (x==5) 
        cadena_1="tengo un 5";
    display.clearDisplay();
    scroll_text(cadena_1);
    flag = false;
  }
}

// function that executes whenever data is received from master
// this function is registered as an event, see setup()
void receiveEvent(int howMany) {
  int x;
  while (1 < Wire.available()) // loop through all but the last
        int x = Wire.read();    // receive byte as an integer
        if (x == 1 || x== 5)
           flag = true;
  }    
}

void scroll_text(String cadena_1) {
    display.setTextWrap(false);  // we don't wrap text so it scrolls nicely
    display.setTextSize(1);
    display.setRotation(0);

    for (int xpos = 64; xpos>-140; xpos--)  {
      display.setTextColor(myWHITE);
      display.clearDisplay();
      display.setCursor(xpos,0);
      display.println(cadena_1);
      start_time = millis();
      while ((millis()-start_time)<15)
            display.display(5);
    }
}

Buenos dias, he probado el codigo tal y como lo tienes pero la x del void loop dice:
exit status 1
'x' was not declared in this scope

la he declarado como int arriba pero continua sin funcionar. no pinta nada.

He dado un paso para atras y he puesto el siguiente ejemplo que es con el que empece para ver si la comunicacion estaba bien y descargar fallos de cableado

y todo funciona bien, en el puerto serie del escalvo puedo ver: x is 10 x is 11 ,.....

Buenas tardes, he probado a escribir en el panel solamente dependiendo de lo que se entra en esclavo y nada de nada.

Este es el codigo del master

// Wire Master Writer
// by Nicholas Zambetti <http://www.zambetti.com>

// Demonstrates use of the Wire library
// Writes data to an I2C/TWI slave device
// Refer to the "Wire Slave Receiver" example for use with this

// Created 29 March 2006

// This example code is in the public domain.


#include <Wire.h>

void setup()
{
  Wire.begin(); // join i2c bus (address optional for master)
}

byte x = 0;

void loop()
{
  Wire.beginTransmission(4); // transmit to device #4
  Wire.write("x is ");        // sends five bytes
  Wire.write(x);              // sends one byte  
  Wire.endTransmission();    // stop transmitting

  x++;
  delay(500);
  if(x>30){x=0;}
}

y este es el codigo del esclavo.

#include <PxMatrix.h>
#include <avr/pgmspace.h>
#include <Wire.h>

// Pins for LED MATRIX
#define P_A 2
#define P_B 3
#define P_LAT 7
#define P_OE 8

PxMATRIX display(32, 16, P_LAT, P_OE, P_A, P_B);

// Some standard colors
uint16_t myRED = display.color565(255, 0, 0);
uint16_t myGREEN = display.color565(0, 255, 0);
uint16_t myBLUE = display.color565(0, 0, 255);
uint16_t myWHITE = display.color565(255, 255, 255);
uint16_t myYELLOW = display.color565(255, 255, 0);
uint16_t myCYAN = display.color565(0, 255, 255);
uint16_t myMAGENTA = display.color565(255, 0, 255);
uint16_t myBLACK = display.color565(0, 0, 0);

unsigned long start_time=0;
uint8_t icon_index=0;
String cadena_1="Hola";
volatile bool flag = false;
int x=1;

void setup() {
   Wire.begin(1);                // join i2c bus with address #4
  Wire.onReceive(receiveEvent); // register event
  
  Serial.begin(9600);
  display.begin(2);
  display.setMuxPattern(BINARY);
  display.setScanPattern(ZAGGIZ);
  display.setPanelsWidth(1);

 
  display.clearDisplay();
  display.setTextColor(myMAGENTA);
  display.setCursor(0,8);
  display.print("INICIO");
  start_time = millis();
  while ((millis()-start_time)<3000)
         display.display(20);
  delay(3000);
}

void loop()
{
//  if (flag) {
//    if (x==1)
//        cadena_1="tengo un 1";
//        Serial.print(cadena_1);
//    if (x==5)
//        cadena_1="tengo un 5";
//         Serial.print(cadena_1);
////    display.clearDisplay();
////    scroll_text(cadena_1);
//    flag = false;
//  }
}

// function that executes whenever data is received from master
// this function is registered as an event, see setup()
void receiveEvent(int howMany) {
//  int x=10;
  while (1 < Wire.available()) // loop through all but the last
        {
    char c = Wire.read(); // receive byte as a character
    Serial.print(c);         // print the character
  }
        int x = Wire.read();    // receive byte as an integer
        
        if (x == 1 || x== 5){
               display.clearDisplay();
               scroll_text(cadena_1);
           
           flag = true;
           Serial.print("x es igual a: ");
           Serial.print(x);}
  }   


void scroll_text(String cadena_1) {
    display.setTextWrap(false);  // we don't wrap text so it scrolls nicely
    display.setTextSize(1);
    display.setRotation(0);

    for (int xpos = 64; xpos>-140; xpos--)  {
      display.setTextColor(myWHITE);
      display.clearDisplay();
      display.setCursor(xpos,0);
      display.println(cadena_1);
      start_time = millis();
      while ((millis()-start_time)<15)
            display.display(5);
    }
}

Me sorprende que con semejante proyecto de Array de LEDs y comunicación I2C no puedas resolver eso.

En la rutina se define x no lo hagas. Eliminalo.

void receiveEvent(int howMany) {
  int x;

Defínelo como global.
Si no funciona defínelo como volatile int x;

Buenas noches, parece que ser que es un problema de mezca ya que la libreria y la comunicacion usan Serial.

todo va bien hasta que recibo algo que le hace trabajar al panel:

Haciendo caso he definido la variable como has dicho pero continuo el problema. una vez que recibo algo que hace trabajar al panel se acabo.

void receiveEvent(int howMany) {

  while (1 < Wire.available()) // loop through all but the last
        {
    char c = Wire.read(); // receive byte as a character
    Serial.print(c);         // print the character
  }
        int x = Wire.read();    // receive byte as an integer
        Serial.println(x);
//        if (x == 10){
        if (x == 10 || x== 20){
           Serial.println("soy un 10 o un 20");
               display.clearDisplay();
               cadena_1="tengo un 1";
              scroll_text(cadena_1); 
              Serial.println(x);

        }
        if (x== 20){
           Serial.println("soy un 10 o un 20");
               display.clearDisplay();
               cadena_1="tengo un 2";
              scroll_text(cadena_1); 

        }
                      
//           flag = true;
  }

El com va recibiendo esto:
x is 27
x is 28
x is 29
x is 30
x is 0
x is 1
x is 2
x is 3
x is 4
x is 5
x is 6
x is 7
x is 8
x is 9
x
hasque que se cumple la codicion, entonces bloque.

He pensado usar dos megas y conectarlos por otro serial diferente pero el problema es que el proyecto tiene 4 megas por eso es mas facil usar i2c pero parece ser que no va a ser muy posible.

Buenas tardes y perdon por la tardanza, finalmente el problema ha sido resuelto las cosas tal y como se indican en el post de arriba (como indicaba surbyte )

Master
Esto seria un resumen del codigo:

void envia(int esclavo, int valor){
  Wire.beginTransmission(esclavo); // transmit to device #4
  Wire.write("x is ");        // sends five bytes
  Wire.write(valor);              // sends one byte  
  Wire.endTransmission();    // stop transmitting

y dentro del void principal: Se puede condicionar tantas veces como sera necesario....

envia(2,0)  // envio al exclavo 2 un cero.

para el esclavo dos por ejemplo:

void setup() {
  Wire.begin(2);                // join i2c bus with address #2
  Wire.onReceive(receiveEvent); // register event
  Serial.begin(9600);
}


void receiveEvent(int howMany) {
  while (1 < Wire.available()) // loop through all but the last
        {
    char c = Wire.read(); // receive byte as a character
    Serial.print(c);         // print the character
  }
        int x = Wire.read();    // receive byte as an integer
        Serial.println(x);

        if (x == 0 ){ flag0 = true;}
        if (x == 5 ){ flag1 = true;}
}

void loop() {
 
if (flag0) {Serial.println("Hola, tengo un 0");
flag0 = false; 
if (flag1) {Serial.println("Hola, tengo un 5");
flag1 = false; 
}

Con esto doy por cerrada la pregunta, Gracias