I2C Wire communication - Send 3 Arrays of 32 Bytes

Hi there!

I want to read data from a SD Card and I want to send this data via i2c bus on request.

The arduino with the SD Card reader is a i2c salve device and the other arduino is the master.

I need a good speed because I want to control 256 RGB leds with various sequences (25fps) (Okay with 19600 bps/s)

I do that, here is the code:

Master :

#include <Wire.h>
 
byte askcode[6] = {128,10,20,30,40,50}; 
byte command_nr;
int a, b, c, d, e; // Ask Data
byte SlaveDeviceId = 1;

byte i2cdata[32];
byte fsqcluster[80];
byte countcluster = 0;
 
void setup()
{
  Wire.begin();        // join i2c bus (address optional for master)
  Serial.begin(9600);  // start serial for output
  
}
 
void loop()
{
 
  Serial.println("Init Comm");
 
  sendDataPacket(128);
  Serial.println("Send 128");
  receiveResponse();
  for (int i=0; i <= 31; i++) {
  fsqcluster[countcluster] = i2cdata[i];  
  countcluster++;
  }
 
  sendDataPacket(129);
  Serial.println("Send 129");
  receiveResponse();
  for (int i=0; i <= 31; i++) {
  fsqcluster[countcluster] = i2cdata[i];  
  countcluster++;
  }

  sendDataPacket(130);
  Serial.println("Send 130");
  receiveResponse();  
  for (int i=0; i <= 31; i++) {
  fsqcluster[countcluster] = i2cdata[i];  
  countcluster++;
  }

  Serial.print("Received MATRIX : ");
  for (int i=0; i <= 78; i++) {
  Serial.print(fsqcluster[i]);  
  Serial.print(" - ");  
  }
  Serial.println(fsqcluster[79]);    
  Serial.println("--------------------------------------------------------------------------------------------------");
  countcluster = 0;
  delay(5000);
  
}

void sendDataPacket(byte seq){
  Wire.beginTransmission(SlaveDeviceId);
  askcode[0] = seq;
  Wire.write(askcode, 6);
  delay(10);
}
 
int receiveResponse(){
  Serial.println("Receive reponse :");
  int available = Wire.requestFrom(SlaveDeviceId, (byte)32);
  if(available == 32)
  {
    Serial.println("32 Bits i2c Alvaible");
    byte count = 0;
    while (count < 32) {
    i2cdata[count] = Wire.read(); 
    count++;
    }
  }
  else
  {
    Serial.print("ERROR: Unexpected number of bytes received - ");
    Serial.println(available);
  }
 Wire.endTransmission(true);
}

Here is the code of the slave:

#include <Wire.h>
 
const byte SlaveDeviceId = 1;
byte LastMasterCommand = 0;
int a, b, c, d, e;

byte i2cdata[32] =     {11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42};
byte i2credgreen[32] = {61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92};
byte i2cblue[32] =     {41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00};
 
void setup(){
  Serial.begin(9600);
  Wire.begin(SlaveDeviceId);      // join i2c bus with Slave ID
  Wire.onReceive(receiveDataPacket); // register talk event
  Wire.onRequest(slavesRespond);  // register callback event
}
  
void loop(){}
 
void receiveDataPacket(int howMany){
  //  if (howMany != 11) return; // Error
  Serial.print("Matrix Received : ");
  LastMasterCommand = Wire.read();          
  a = Wire.read();
  b = Wire.read();
  c = Wire.read();
  d = Wire.read();
  e = Wire.read();
  Serial.print(LastMasterCommand);
  Serial.print(" - ");
  Serial.print(a);
  Serial.print(" - ");
  Serial.print(b);
  Serial.print(" - ");
  Serial.print(c);
  Serial.print(" - ");
  Serial.print(d);
  Serial.print(" - ");
  Serial.println(e);  
}
 
void slavesRespond(){
 
  int returnValue = 0;
 
  switch(LastMasterCommand){
    case 0:   
       Serial.println("Error i2c BUS :(");
    break;
 
    case 128: 
      Serial.println("Sending i2cdata[32] array");
      Wire.write(i2cdata, 32);
    break;
    
    case 129: 
      Serial.println("Sending i2credgreen[32] array");
      Wire.write(i2credgreen, 32);
    break;
    
    case 130: 
      Serial.println("Sending i2cblue[32] array");
      Wire.write(i2cblue, 32);
    break;
 
  }
 
  LastMasterCommand = 0;       // null last Master's command
}

I send a packet to the slave, if the first byte of this packet is 128, the slave is asking with the data of i2cdata array, 129 with i2credgreen, 130 with i2cblue.

This code doesn’t work, finally what I want to do is to fill the array fsqcluster.

Please help!

Regards.

I can get your code to run with some slight modifications to the master code.

void sendDataPacket(byte seq){
  Wire.beginTransmission(SlaveDeviceId);
  askcode[0] = seq;
  Wire.write(askcode, 6);
  Wire.endTransmission();//ADDED
  delay(50);//RAISED FROM 10
}

Your code appears to be written to truncate the data from i2cblue and is filling fsqcluster with 80 bytes of data instead of 96 = 3x32 so I left it that way.

EDIT: 5/16 With the Wire.endTransmission() statement moved into the sendDataPacket function, the last line of the master program Wire.endTransmission(true); can be removed.

To transmit data : Wire.beginTransmission - Wire.write - Wire.endTransmission. To received data : Wire.requestFrom - Wire.read

The Wire.requestFrom() does not need a Wire.endtransmission.

In the Slave, the onReceive() and onRequest() handlers should not use a call to Serial. Please remove every use of Serial from those functions.

From Peter_n

In the Slave, the onReceive() and onRequest() handlers should not use a call to Serial. Please remove every use of Serial from those functions.

Absolutely correct. When I removed all the Serial.print calls from the slave's two handlers, there was no delay required at the end of the master sendDataPacket function.

void sendDataPacket(byte seq){
  Wire.beginTransmission(SlaveDeviceId);
  askcode[0] = seq;
  Wire.write(askcode, 6);
  Wire.endTransmission();//ADDED
  //delay(50);//RAISED FROM 10
}

Hi there ;D (6 monthes later :-[ :-[ :-[ - I had Problems to solve)

Thanks for your answers!

It seems to work!!!

Here is the code of the working sample I made :

Master code:

#include <Wire.h>
 
byte askcode[6] = {128,10,20,30,40,50}; 
int a, b, c, d, e; // Ask Data
byte SlaveDeviceId = 1;

byte i2cdata[32];
byte fsqcluster[80];
byte countcluster = 0;
 
void setup()
{
  Wire.begin();        // join i2c bus (address optional for master)
  Serial.begin(9600);  // start serial for output
  
}
 
void loop()
{
  
  sendDataPacket(128);
  receiveResponse();
  for (int i=0; i <= 31; i++) {
  fsqcluster[countcluster] = i2cdata[i];  
  countcluster++;
  }
     
  sendDataPacket(129);
  receiveResponse();
  for (int i=0; i <= 31; i++) {
  fsqcluster[countcluster] = i2cdata[i];  
  countcluster++;
  }

  sendDataPacket(130);
  receiveResponse();  
  for (int i=0; i <= 31; i++) {
  fsqcluster[countcluster] = i2cdata[i];  
  countcluster++;
  }

  for (int i=0; i <= 78; i++) {
  Serial.print(fsqcluster[i]);  
  Serial.print(" - ");  
  }
  Serial.println(fsqcluster[79]);    
  countcluster = 0;
  delay(100);
  
}

void sendDataPacket(byte seq){
  Wire.beginTransmission(SlaveDeviceId);
  askcode[0] = seq;
  Wire.write(askcode, 6);
  Wire.endTransmission(true);
}
 
int receiveResponse(){
  int available = Wire.requestFrom(SlaveDeviceId, (byte)32);
  if(available == 32)
  {
    byte count = 0;
    while (count < 32) {
    i2cdata[count] = Wire.read(); 
    count++;
    }
  }
  else
  {
  }
 
}

Slave code:

#include <Wire.h>
 
const byte SlaveDeviceId = 1;
byte LastMasterCommand = 0;
int a, b, c, d, e;

byte i2cdata[32] =     {11,12,13,14,0,16,17,18,19,0,21,22,23,24,0,26,27,28,29,0,31,32,33,34,0,36,37,38,39,40,41,42};
byte i2credgreen[32] = {61,62,63,64,65,66,67,68,69,0,71,72,73,74,75,76,77,78,79,0,81,82,83,84,85,86,87,88,89,0,91,92};
byte i2cblue[32] =     {41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00};
 
void setup(){
  Wire.begin(SlaveDeviceId);      // join i2c bus with Slave ID
  Wire.onReceive(receiveDataPacket); // register talk event
  Wire.onRequest(slavesRespond);  // register callback event
}
  
void loop(){}
 
void receiveDataPacket(int howMany){
  //  if (howMany != 11) return; // Error
  LastMasterCommand = Wire.read();          
  a = Wire.read();
  b = Wire.read();
  c = Wire.read();
  d = Wire.read();
  e = Wire.read();
}
 
void slavesRespond(){
 
  int returnValue = 0;
 
  switch(LastMasterCommand){
    case 0:   

    break;
 
    case 128: 
      Wire.write(i2cdata, 32);
    break;
    
    case 129: 
      Wire.write(i2credgreen, 32);
    break;
    
    case 130: 
      Wire.write(i2cblue, 32);
    break;
 
  }
 
  LastMasterCommand = 0;       // null last Master's command
}

Now I found 2 new problems:

1st problem

Compliling this exactly with Arduino 1.0.5 there isn’t any data error or data corruption.

Compliling this exactly with Arduino 1.6.5 there is sometimes data corruption!

So I decided to compile with Arduino 1.0.5 for the moment to solve the problem.

2nd problem

I added to the i2c bus a PCF8574 as an input to get 8 microswitches. The PCF8574 have the adress 0x21.

Here is the code :

#include <Wire.h>
 
byte askcode[6] = {128,10,20,30,40,50}; 
int a, b, c, d, e; // Ask Data
byte SlaveDeviceId = 1;

byte i2cdata[32];
byte fsqcluster[80];
byte countcluster = 0;
byte  i2cswitches = 0;
byte  timepressed = 0;
 
void setup()
{
  Wire.begin();        // join i2c bus (address optional for master)
  Serial.begin(9600);  // start serial for output
}
 
void loop()
{
  
  sendDataPacket(128);
  receiveResponse();
  for (int i=0; i <= 31; i++) {
  fsqcluster[countcluster] = i2cdata[i];  
  countcluster++;
  }
     
  sendDataPacket(129);
  receiveResponse();
  for (int i=0; i <= 31; i++) {
  fsqcluster[countcluster] = i2cdata[i];  
  countcluster++;
  }

  sendDataPacket(130);
  receiveResponse();  
  for (int i=0; i <= 31; i++) {
  fsqcluster[countcluster] = i2cdata[i];  
  countcluster++;
  }
  
  // Serial Print to see if the i2c values entered are correct.
  
  /*
  for (int i=0; i <= 78; i++) {
  Serial.print(fsqcluster[i]);  
  Serial.print(" - ");  
  }
  
  Serial.println(fsqcluster[79]);    
  countcluster = 0;
  
  delay(10);
  */
  
  
  
  Wire.requestFrom(0x21,1);// Begin transmission to PCF8574 with the buttons
  if(Wire.available())   // If bytes are available to be recieved
  {
    i2cswitches = Wire.read();// Read a byte
  }  
  


        
            // No switch pressed
            if (i2cswitches==255)
            { 
            timepressed = 0;  
            }            
            
            
            if (i2cswitches==254)
            { 
              
            timepressed++;    
            
            Serial.println(timepressed,DEC);    
            
            if (timepressed == 1) {
            Serial.println("Pressed Short button 1");   
            delay(100); 
            }
            
            if (timepressed > 5) {
            Serial.println("Pressed long");    
            delay(100); 
            }
                         
            }
           
            if (i2cswitches==253) 
            { 
              
            timepressed++;
        
            Serial.println(timepressed,DEC);           
            
            if (timepressed == 1) {
            Serial.println("Pressed Short button 2");   
            delay(100);   
            }
            
            if (timepressed > 5) {
            Serial.println("Pressed long");    
            delay(100); 
            } 
            
            }

  
}
  


void sendDataPacket(byte seq){
  Wire.beginTransmission(SlaveDeviceId);
  askcode[0] = seq;
  Wire.write(askcode, 6);
  Wire.endTransmission(true);
}
 
int receiveResponse(){
  int available = Wire.requestFrom(SlaveDeviceId, (byte)32);
  if(available == 32)
  {
    byte count = 0;
    while (count < 32) {
    i2cdata[count] = Wire.read(); 
    count++;
    }
  }
  else
  {
  }
 
}

The problem is the variable timepressed always have the same value :frowning: The increment dosn’t work…

When I comment the lines, timepressed icrements correctly.

 sendDataPacket(128);
  receiveResponse();
  for (int i=0; i <= 31; i++) {
  fsqcluster[countcluster] = i2cdata[i];  
  countcluster++;
  }
     
  sendDataPacket(129);
  receiveResponse();
  for (int i=0; i <= 31; i++) {
  fsqcluster[countcluster] = i2cdata[i];  
  countcluster++;
  }

  sendDataPacket(130);
  receiveResponse();  
  for (int i=0; i <= 31; i++) {
  fsqcluster[countcluster] = i2cdata[i];  
  countcluster++;
  }

I think there is a problem while I receive the i2c data form another adress, a conflict or something like that…

I tried to put the PCF8574 code read section into int receiveResponse() but without positive result…

I believe that fsqcluster[countcluster] is overrunning its memory space and corrupting the readings from the PCF8574.

byte fsqcluster[80];

But, fsqcluster is written 96 times as countcluster is incremented in the for loop and countcluster is a global variable.

Try

sendDataPacket(128);
  receiveResponse();
  countcluster = 0;
  for (int i=0; i <= 31; i++) {
  fsqcluster[countcluster] = i2cdata[i];  
  countcluster++;
  }
     
  sendDataPacket(129);
  receiveResponse();
  countcluster = 0;
  for (int i=0; i <= 31; i++) {
  fsqcluster[countcluster] = i2cdata[i];  
  countcluster++;
  }

  sendDataPacket(130);
  receiveResponse();
  countcluster = 0;  
  for (int i=0; i <= 31; i++) {
  fsqcluster[countcluster] = i2cdata[i];  
  countcluster++;
  }

I do not have your setup, but I tested this while reading a byte set to 254 from a register on an i2c nvram (on an RTC) while running the rest of your program. With the countcluster changes I could increment timepressed. Otherwise it was unchanging like you experienced.

Edit–I’m not sure that resetting countcluster is the correct solution if you need to use that data, but it demonstrates where the problem lies.

Hi!

Thank for your answer :slight_smile:

I use Arduino 1.0.5 in this case.

I made a check of the free RAM of the arduino in the master in this program, and I get 1.5K free.

The variable countcluster is correct, it should be resetted at each beginning of the loop to reach the final of the fsqcluster at 80. (I use in reality 32, 32 and 16 bytes, not 96).

But the problem still exists… :frowning:

Here is the new master code I made with ypur suggestion :

#include <Wire.h>
#include <MemoryFree.h>
 
byte askcode[6] = {128,10,20,30,40,50}; 
int a, b, c, d, e; // Ask Data
byte SlaveDeviceId = 1;

byte i2cdata[32];
byte fsqcluster[80];
byte countcluster = 0;
byte  i2cswitches = 0;
byte  timepressed = 0;
 
void setup()
{
  Wire.begin();        // join i2c bus (address optional for master)
  Serial.begin(9600);  // start serial for output
}
 
void loop()
{
  
  countcluster = 0;
  
  sendDataPacket(128);
  receiveResponse();
  for (int i=0; i <= 31; i++) {
  fsqcluster[countcluster] = i2cdata[i];  
  countcluster++;
  }
     
  sendDataPacket(129);
  receiveResponse();
  for (int i=0; i <= 31; i++) {
  fsqcluster[countcluster] = i2cdata[i];  
  countcluster++;
  }

  sendDataPacket(130);
  receiveResponse();  
  for (int i=0; i <= 31; i++) {
  fsqcluster[countcluster] = i2cdata[i];  
  countcluster++;
  }
  
  // Serial Print to see if the i2c values entered are correct.
  
  
  for (int i=0; i <= 78; i++) {
  Serial.print(fsqcluster[i]);  
  Serial.print(" - ");  
  }
  
  Serial.println(fsqcluster[79]);    
  countcluster = 0;
  
  Serial.print("FREE MEMORY ");    
  Serial.println(freeMemory());
  
  delay(100);
  
  
  
  
  Wire.requestFrom(0x21,1);// Begin transmission to PCF8574 with the buttons
  if(Wire.available())   // If bytes are available to be recieved
  {
    i2cswitches = Wire.read();// Read a byte
  }  
  


        
            // No switch pressed
            if (i2cswitches==255)
            { 
            timepressed = 0;  
            }            
            
            
            if (i2cswitches==254)
            { 
              
            timepressed++;    
            Serial.print("timepressed variable : ");   
            Serial.println(timepressed,DEC);    
            
            if (timepressed == 1) {
            Serial.println("Pressed Short button 1");   
            delay(100); 
            }
            
            if (timepressed > 5) {
            Serial.println("Pressed long");    
            delay(100); 
            }
                         
            }
           
            if (i2cswitches==253) 
            { 
              
            timepressed++;
            
            Serial.print("timepressed variable : ");   
            Serial.println(timepressed,DEC);         
            
            if (timepressed == 1) {
            Serial.println("Pressed Short button 2");   
            delay(100);   
            }
            
            if (timepressed > 5) {
            Serial.println("Pressed long");    
            delay(100); 
            } 
            
            }

  
}
  


void sendDataPacket(byte seq){
  Wire.beginTransmission(SlaveDeviceId);
  askcode[0] = seq;
  Wire.write(askcode, 6);
  Wire.endTransmission(true);
}
 
int receiveResponse(){
  int available = Wire.requestFrom(SlaveDeviceId, (byte)32);
  if(available == 32)
  {
    byte count = 0;
    while (count < 32) {
    i2cdata[count] = Wire.read(); 
    count++;
    }
  }
  else
  {
  }
 
}

And here is the sorial monitor debug output:

11 - 12 - 13 - 14 - 0 - 16 - 17 - 18 - 19 - 0 - 21 - 22 - 23 - 24 - 0 - 26 - 27 - 28 - 29 - 0 - 31 - 32 - 33 - 34 - 0 - 36 - 37 - 38 - 39 - 40 - 41 - 42 - 61 - 62 - 63 - 64 - 65 - 66 - 67 - 68 - 69 - 0 - 71 - 72 - 73 - 74 - 75 - 76 - 77 - 78 - 79 - 0 - 81 - 82 - 83 - 84 - 85 - 86 - 87 - 88 - 89 - 0 - 91 - 92 - 41 - 42 - 43 - 44 - 45 - 46 - 47 - 48 - 49 - 50 - 51 - 52 - 53 - 54 - 55 - 56
FREE MEMORY 1402
timepressed variable : 1
Pressed Short button 2
11 - 12 - 13 - 14 - 0 - 16 - 17 - 18 - 19 - 0 - 21 - 22 - 23 - 24 - 0 - 26 - 27 - 28 - 29 - 0 - 31 - 32 - 33 - 34 - 0 - 36 - 37 - 38 - 39 - 40 - 41 - 42 - 61 - 62 - 63 - 64 - 65 - 66 - 67 - 68 - 69 - 0 - 71 - 72 - 73 - 74 - 75 - 76 - 77 - 78 - 79 - 0 - 81 - 82 - 83 - 84 - 85 - 86 - 87 - 88 - 89 - 0 - 91 - 92 - 41 - 42 - 43 - 44 - 45 - 46 - 47 - 48 - 49 - 50 - 51 - 52 - 53 - 54 - 55 - 56
FREE MEMORY 1402
timepressed variable : 1
Pressed Short button 2
11 - 12 - 13 - 14 - 0 - 16 - 17 - 18 - 19 - 0 - 21 - 22 - 23 - 24 - 0 - 26 - 27 - 28 - 29 - 0 - 31 - 32 - 33 - 34 - 0 - 36 - 37 - 38 - 39 - 40 - 41 - 42 - 61 - 62 - 63 - 64 - 65 - 66 - 67 - 68 - 69 - 0 - 71 - 72 - 73 - 74 - 75 - 76 - 77 - 78 - 79 - 0 - 81 - 82 - 83 - 84 - 85 - 86 - 87 - 88 - 89 - 0 - 91 - 92 - 41 - 42 - 43 - 44 - 45 - 46 - 47 - 48 - 49 - 50 - 51 - 52 - 53 - 54 - 55 - 56
FREE MEMORY 1402
timepressed variable : 1
Pressed Short button 2
11 - 12 - 13 - 14 - 0 - 16 - 17 - 18 - 19 - 0 - 21 - 22 - 23 - 24 - 0 - 26 - 27 - 28 - 29 - 0 - 31 - 32 - 33 - 34 - 0 - 36 - 37 - 38 - 39 - 40 - 41 - 42 - 61 - 62 - 63 - 64 - 65 - 66 - 67 - 68 - 69 - 0 - 71 - 72 - 73 - 74 - 75 - 76 - 77 - 78 - 79 - 0 - 81 - 82 - 83 - 84 - 85 - 86 - 87 - 88 - 89 - 0 - 91 - 92 - 41 - 42 - 43 - 44 - 45 - 46 - 47 - 48 - 49 - 50 - 51 - 52 - 53 - 54 - 55 - 56
FREE MEMORY 1402
timepressed variable : 1
Pressed Short button 2
11 - 12 - 13 - 14 - 0 - 16 - 17 - 18 - 19 - 0 - 21 - 22 - 23 - 24 - 0 - 26 - 27 - 28 - 29 - 0 - 31 - 32 - 33 - 34 - 0 - 36 - 37 - 38 - 39 - 40 - 41 - 42 - 61 - 62 - 63 - 64 - 65 - 66 - 67 - 68 - 69 - 0 - 71 - 72 - 73 - 74 - 75 - 76 - 77 - 78 - 79 - 0 - 81 - 82 - 83 - 84 - 85 - 86 - 87 - 88 - 89 - 0 - 91 - 92 - 41 - 42 - 43 - 44 - 45 - 46 - 47 - 48 - 49 - 50 - 51 - 52 - 53 - 54 - 55 - 56
FREE MEMORY 1402
timepressed variable : 1
Pressed Short button 2
11 - 12 - 13 - 14 - 0 - 16 - 17 - 18 - 19 - 0 - 21 - 22 - 23 - 24 - 0 - 26 - 27 - 28 - 29 - 0 - 31 - 32 - 33 - 34 - 0 - 36 - 37 - 38 - 39 - 40 - 41 - 42 - 61 - 62 - 63 - 64 - 65 - 66 - 67 - 68 - 69 - 0 - 71 - 72 - 73 - 74 - 75 - 76 - 77 - 78 - 79 - 0 - 81 - 82 - 83 - 84 - 85 - 86 - 87 - 88 - 89 - 0 - 91 - 92 - 41 - 42 - 43 - 44 - 45 - 46 - 47 - 48 - 49 - 50 - 51 - 52 - 53 - 54 - 55 - 56
FREE MEMORY 1402
timepressed variable : 1
Pressed Short button 2
11 - 12 - 13 - 14 - 0 - 16 - 17 - 18 - 19 - 0 - 21 - 22 - 23 - 24 - 0 - 26 - 27 - 28 - 29 - 0 - 31 - 32 - 33 - 34 - 0 - 36 - 37 - 38 - 39 - 40 - 41 - 42 - 61 - 62 - 63 - 64 - 65 - 66 - 67 - 68 - 69 - 0 - 71 - 72 - 73 - 74 - 75 - 76 - 77 - 78 - 79 - 0 - 81 - 82 - 83 - 84 - 85 - 86 - 87 - 88 - 89 - 0 - 91 - 92 - 41 - 42 - 43 - 44 - 45 - 46 - 47 - 48 - 49 - 50 - 51 - 52 - 53 - 54 - 55 - 56
FREE MEMORY 1402
timepressed variable : 1
Pressed Short button 2
11 - 12 - 13 - 14 - 0 - 16 - 17 - 18 - 19 - 0 - 21 - 22 - 23 - 24 - 0 - 26 - 27 - 28 - 29 - 0 - 31 - 32 - 33 - 34 - 0 - 36 - 37 - 38 - 39 - 40 - 41 - 42 - 61 - 62 - 63 - 64 - 65 - 66 - 67 - 68 - 69 - 0 - 71 - 72 - 73 - 74 - 75 - 76 - 77 - 78 - 79 - 0 - 81 - 82 - 83 - 84 - 85 - 86 - 87 - 88 - 89 - 0 - 91 - 92 - 41 - 42 - 43 - 44 - 45 - 46 - 47 - 48 - 49 - 50 - 51 - 52 - 53 - 54 - 55 - 56
FREE MEMORY 1402
timepressed variable : 1
Pressed Short button 2
11 - 12 - 13 - 14 - 0 - 16 - 17 - 18 - 19 - 0 - 21 - 22 - 23 - 24 - 0 - 26 - 27 - 28 - 29 - 0 - 31 - 32 - 33 - 34 - 0 - 36 - 37 - 38 - 39 - 40 - 41 - 42 - 61 - 62 - 63 - 64 - 65 - 66 - 67 - 68 - 69 - 0 - 71 - 72 - 73 - 74 - 75 - 76 - 77 - 78 - 79 - 0 - 81 - 82 - 83 - 84 - 85 - 86 - 87 - 88 - 89 - 0 - 91 - 92 - 41 - 42 - 43 - 44 - 45 - 46 - 47 - 48 - 49 - 50 - 51 - 52 - 53 - 54 - 55 - 56
FREE MEMORY 1402
timepressed variable : 1
Pressed Short button 2
11 - 12 - 13 - 14 - 0 - 16 - 17 - 18 - 19 - 0 - 21 - 22 - 23 - 24 - 0 - 26 - 27 - 28 - 29 - 0 - 31 - 32 - 33 - 34 - 0 - 36 - 37 - 38 - 39 - 40 - 41 - 42 - 61 - 62 - 63 - 64 - 65 - 66 - 67 - 68 - 69 - 0 - 71 - 72 - 73 - 74 - 75 - 76 - 77 - 78 - 79 - 0 - 81 - 82 - 83 - 84 - 85 - 86 - 87 - 88 - 89 - 0 - 91 - 92 - 41 - 42 - 43 - 44 - 45 - 46 - 47 - 48 - 49 - 50 - 51 - 52 - 53 - 54 - 55 - 56
FREE MEMORY 1402
timepressed variable : 1
Pressed Short button 2
11 - 12 - 13 - 14 - 0 - 16 - 17 - 18 - 19 - 0 - 21 - 22 - 23 - 24 - 0 - 26 - 27 - 28 - 29 - 0 - 31 - 32 - 33 - 34 - 0 - 36 - 37 - 38 - 39 - 40 - 41 - 42 - 61 - 62 - 63 - 64 - 65 - 66 - 67 - 68 - 69 - 0 - 71 - 72 - 73 - 74 - 75 - 76 - 77 - 78 - 79 - 0 - 81 - 82 - 83 - 84 - 85 - 86 - 87 - 88 - 89 - 0 - 91 - 92 - 41 - 42 - 43 - 44 - 45 - 46 - 47 - 48 - 49 - 50 - 51 - 52 - 53 - 54 - 55 - 56

timepressed variable : 1

This variable stays to 1 value and no increment…

Regards :wink:

I do not have the hardware to test your code, but the management of countcluster looks much better.

As I said, with control over countcluster I can send/receive from SlaveDeviceId = 1 and another i2c device at address 0x68, so there is no fundamental conflict.

Since you release the buss with Wire.endTransmission(true) you could try to add a new Wire.beginTransmission() when you address the PCF8574.

// Begin transmission to PCF8574 with the buttons
 Wire.beginTransmission(0x21);
 Wire.write(0x00); //set to resister with data
 Wire.endTransmission();

 Wire.requestFrom(0x21,1);
  if(Wire.available())   // If bytes are available to be recieved
  {
    i2cswitches = Wire.read();// Read a byte
    Serial.println(i2cswitches);
  }

Good info! Very good info! Probably the problem comes from where you are pointing…

I made some tests.

I added:

Wire.beginTransmission(0x21);
Wire.write(0x00); //set to resister with data
Wire.endTransmission();

When I put this code, the PCF8574 radically get stucked, as I reload the firmware without these 3 lines, the PCF8574 follows stucked, i need to unpower the hard and trun on again to get it working.

I investigated about this first byte “REGISTER” of i2c and I found some examples:

http://blog.alvarolopez.net/2012/10/comunicacion-i2c-con-arduino/

Here is what I’m looking for:

// Reads num bytes starting from address register on device in to _buff array
void readFrom(byte address, int num, byte _buff[]) {
  Wire.beginTransmission(DEVICE); // start transmission to device
  Wire.write(address); // sends address to read from
  Wire.endTransmission(); // end transmission
 
  Wire.beginTransmission(DEVICE); // start transmission to device
  Wire.requestFrom(DEVICE, num); // request 6 bytes from device
 
  int i = 0;
  while(Wire.available()) // device may send less than requested (abnormal)
  {
    _buff[i] = Wire.read(); // receive a byte
    i++;
  }
  Wire.endTransmission(); // end transmission
}

So you are in the right way, before requestFrom, they are sending a REGISTER (that contains the adress of the device), I made some tests:

Instead of

Wire.beginTransmission(0x21);
Wire.write(0x00); //set to resister with data
Wire.endTransmission();

I put

Wire.beginTransmission(0x21);
Wire.write(0x21); //set to resister with data
Wire.endTransmission();

Without sucess…

Then I tried with an “All done library”, exactly : GitHub - skywodd/pcf8574_arduino_library: PCF8574 / PCF8575 Arduino library (version 2.0)

Here is the test code with this library:

#include <Wire.h>    // Required for I2C communication
#include "PCF8574.h" // Required for PCF8574

/** PCF8574 instance */
PCF8574 expander;

/** setup() */
void setup() {

  /* Setup serial for debug */
  Serial.begin(9600);
  
  /* Start I2C bus and PCF8574 instance */
  expander.begin(0x21);
  
  /* Setup some PCF8574 pins for demo */
  expander.pinMode(0, INPUT);
  expander.pinMode(1, INPUT);
  expander.pinMode(2, INPUT);
  expander.pinMode(3, INPUT);
  expander.pinMode(4, INPUT);
  expander.pinMode(5, INPUT);
  expander.pinMode(6, INPUT);
  expander.pinMode(7, INPUT);

  
}


void loop() {
  Serial.println(expander.read(), DEC); // Read the whole pins input register
}

It works perfectly, but when I put it with the reading of the other i2c 3 arrays slave, i get EXACLTY THE SAME PROBLEM, the variable timepressed dosen’t increment!

Now looking in this excellent page, I think I have to use only a Wire.onReceive (receiveEvent); for the PCF on the master code…

http://www.gammon.com.au/i2c

So I will try it now and I will give you feedback!

Here is the wiring diagram I use:

Regards :slight_smile:

3 hours later :

New observation :

In the master code, if I use only one of the three sendDataPacket

  sendDataPacket(128);
  receiveResponse();
  for (int i=0; i <= 31; i++) {
  fsqcluster[countcluster] = i2cdata[i];  
  countcluster++;
  }

it works perfectly:

Here is the code:

#include <Wire.h>
#include <MemoryFree.h>
 
byte askcode[6] = {128,10,20,30,40,50}; 
int a, b, c, d, e; // Ask Data
byte SlaveDeviceId = 1;

byte i2cdata[32];
byte fsqcluster[80];
byte countcluster = 0;
byte  i2cswitches = 0;
byte  timepressed = 0;
 
void setup()
{
  Wire.begin();        // join i2c bus (address optional for master)
  Serial.begin(9600);  // start serial for output
}
 
void loop()
{
  
  countcluster = 0;
  
  sendDataPacket(128);
  receiveResponse();
  for (int i=0; i <= 31; i++) {
  fsqcluster[countcluster] = i2cdata[i];  
  countcluster++;
  }
  /*  
  sendDataPacket(129);
  receiveResponse();
  for (int i=0; i <= 31; i++) {
  fsqcluster[countcluster] = i2cdata[i];  
  countcluster++;
  }

  sendDataPacket(130);
  receiveResponse();  
  for (int i=0; i <= 31; i++) {
  fsqcluster[countcluster] = i2cdata[i];  
  countcluster++;
  }
  */
  
  // Serial Print to see if the i2c values entered are correct.
  
  
  for (int i=0; i <= 78; i++) {
  Serial.print(fsqcluster[i]);  
  Serial.print(" - ");  
  }
  
  Serial.println(fsqcluster[79]);    
  countcluster = 0;
  
  Serial.print("FREE MEMORY ");    
  Serial.println(freeMemory());
  
  delay(100);
  
  
  
  
  Wire.requestFrom(0x21,1);// Begin transmission to PCF8574 with the buttons
  if(Wire.available())   // If bytes are available to be recieved
  {
    i2cswitches = Wire.read();// Read a byte
  }  
  


        
            // No switch pressed
            if (i2cswitches==255)
            { 
            timepressed = 0;  
            }            
            
            
            if (i2cswitches==254)
            { 
              
            timepressed++;    
            Serial.print("timepressed variable : ");   
            Serial.println(timepressed,DEC);    
            
            if (timepressed == 1) {
            Serial.println("Pressed Short button 1");   
            delay(100); 
            }
            
            if (timepressed > 5) {
            Serial.println("Pressed long");    
            delay(100); 
            }
                         
            }
           
            if (i2cswitches==253) 
            { 
              
            timepressed++;
            
            Serial.print("timepressed variable : ");   
            Serial.println(timepressed,DEC);         
            
            if (timepressed == 1) {
            Serial.println("Pressed Short button 2");   
            delay(100);   
            }
            
            if (timepressed > 5) {
            Serial.println("Pressed long");    
            delay(100); 
            } 
            
            }

  
}
  


void sendDataPacket(byte seq){
  Wire.beginTransmission(SlaveDeviceId);
  askcode[0] = seq;
  Wire.write(askcode, 6);
  Wire.endTransmission(true);
}
 
int receiveResponse(){
  int available = Wire.requestFrom(SlaveDeviceId, (byte)32);
  if(available == 32)
  {
    byte count = 0;
    while (count < 32) {
    i2cdata[count] = Wire.read(); 
    count++;
    }
  }
  else
  {
  }
 
}

Here is the serial monitor result:

FREE MEMORY 1404
timepressed variable : 1
Pressed Short button 2
11 - 12 - 13 - 14 - 0 - 16 - 17 - .......
FREE MEMORY 1404
timepressed variable : 2
11 - 12 - 13 - 14 - 0 - 16 - 17 - .......
FREE MEMORY 1404
timepressed variable : 3
11 - 12 - 13 - 14 - 0 - 16 - 17 - .......
FREE MEMORY 1404
timepressed variable : 4
11 - 12 - 13 - 14 - 0 - 16 - 17 - .......
FREE MEMORY 1404
timepressed variable : 5
11 - 12 - 13 - 14 - 0 - 16 - 17 - .......
FREE MEMORY 1404
timepressed variable : 6
Pressed long
11 - 12 - 13 - 14 - 0 - 16 - 17 - .......
FREE MEMORY 1404
timepressed variable : 7

So the problem is coming clearly from these part of code:

  sendDataPacket(128);
  receiveResponse();
  for (int i=0; i <= 31; i++) {
  fsqcluster[countcluster] = i2cdata[i];  
  countcluster++;
  }

Using a

Wire.beginTransmission(SlaveDeviceId);

Wire.endTransmission(true);

then

Wire.requestFrom(SlaveDeviceId, (byte)32);

Could create an internal conflict? And this could be the explaination of why this code is running well on Arduino 1.0.5 and give incoherent reading sometimes with Arduino 1.6.5!!

What do you think?

I think I have resolved the problem!

Apparently, the variable increment timepressed problem is provocated by Arduino 1.0.5 bug, this IDE is old, so better forget it, because wire has been actualized since Arduino 1.5, so much better to work with the last stable release of Arduino.

With Arduino 1.6.5 (The last) it works only I had to add some beginTransmission endTransmission when using wire.read!

int receiveResponse(){
  Wire.beginTransmission(SlaveDeviceId); // ADDED
  int available0x01 = Wire.requestFrom(SlaveDeviceId, (byte)32);
  if(available0x01 == 32)
  {
    byte count = 0;
    while (count < 32) {
    i2cdata[count] = Wire.read(); 
    count++;
    }
  }
 Wire.endTransmission(true);  // ADDED
}

Now I made a master code to compare the fsqculster received 80 byte array, I works like a charm! If there is a reading error, it will print ERROR on the serial monitor. And tihs example combine perfectly with other I2C devices such as

Here is the complete master sketch:

/!\ Works with Arduino 1.6.5 R5 - If use arduino 1.0.5, will not work /!\

/* TESTED AND WORKS WITH ARDUINO 1.6.5 R5 */
#include <Wire.h>
 
byte askcode[6] = {128,10,20,30,40,50}; 
int a, b, c, d, e; // Ask Data
byte SlaveDeviceId = 1;

byte i2cdata[32];
byte fsqcluster[80];
byte refcluster[80] = {11,12,13,14,0,16,17,18,19,0,21,22,23,24,0,26,27,28,29,0,31,32,33,34,0,36,37,38,39,40,41,42,61,62,63,64,65,66,67,68,69,0,71,72,73,74,75,76,77,78,79,0,81,82,83,84,85,86,87,88,89,0,91,92,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56};
byte countcluster = 0;
byte  i2cswitches = 0;
byte  timepressed1 = 0;
byte  timepressed2 = 0;

bool dataerror = false;
 
void setup()
{
  Wire.begin();
  Serial.begin(9600);
}
 
void loop()
{
  
  countcluster = 0;
  dataerror = false;
  
  sendDataPacket(128);
  receiveResponse();
  for (int i=0; i <= 31; i++) {
  fsqcluster[countcluster] = i2cdata[i];  
  countcluster++;
  }
     
  sendDataPacket(129);
  receiveResponse();
  for (int i=0; i <= 31; i++) {
  fsqcluster[countcluster] = i2cdata[i];  
  countcluster++;
  }

  sendDataPacket(130);
  receiveResponse();  
  for (int i=0; i <= 31; i++) {
  fsqcluster[countcluster] = i2cdata[i];  
  countcluster++;
  }



  

// Here we comnpare the received DATA if match with the original pattern, if error then display it.
// Normally, the error message should NEVER APPAER :)

  for (int i=0; i <= 79; i++) {
    if (fsqcluster[i] != refcluster[i]) {
      dataerror = true;
    } else {
      dataerror = false;
    }
  }


  if (dataerror == true) {
    Serial.println("ERROR");
  } else {
   // Serial.println("FRAME OK");
  }
  
  Wire.beginTransmission(0x21);
  Wire.requestFrom(0x21,1);// Begin transmission to PCF8574 with the buttons
  if(Wire.available())   // If bytes are available to be recieved
  {
    i2cswitches = Wire.read();// Read a byte
  }  
  Wire.endTransmission(true);

            // No switch pressed
            if (i2cswitches==255)
            { 
            timepressed1 = 0;  
            timepressed2 = 0;  
            }            
            
            
            if (i2cswitches==254)
            { 
              
            timepressed1++;    
            
            if (timepressed1 == 1) {
            Serial.println("Pressed Short button 1");   
            }
            
            if (timepressed1 > 50) {
            Serial.println("Pressed long");    
            }
                         
            }
           
            if (i2cswitches==253) 
            { 
              
            timepressed2++;
                 
            
            if (timepressed2 == 1) {
            Serial.println("Pressed Short button 2");   
            }
            
            if (timepressed2 > 50) {
            Serial.println("Pressed long");    
            } 
            
            }

  
}
  


void sendDataPacket(byte seq){
  Wire.beginTransmission(SlaveDeviceId);
  askcode[0] = seq;
  Wire.write(askcode, 6);
  Wire.endTransmission(true);
}
 
int receiveResponse(){
  Wire.beginTransmission(SlaveDeviceId);
  int available0x01 = Wire.requestFrom(SlaveDeviceId, (byte)32);
  if(available0x01 == 32)
  {
    byte count = 0;
    while (count < 32) {
    i2cdata[count] = Wire.read(); 
    count++;
    }
  }
 Wire.endTransmission(true);
}

Here is the complete slave sketch:

#include <Wire.h>
 
const byte SlaveDeviceId = 1;
byte LastMasterCommand = 0;
int a, b, c, d, e;

byte i2cdata[32] =     {11,12,13,14,0,16,17,18,19,0,21,22,23,24,0,26,27,28,29,0,31,32,33,34,0,36,37,38,39,40,41,42};
byte i2credgreen[32] = {61,62,63,64,65,66,67,68,69,0,71,72,73,74,75,76,77,78,79,0,81,82,83,84,85,86,87,88,89,0,91,92};
byte i2cblue[32] =     {41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00};
 
void setup(){
  Wire.begin(SlaveDeviceId);      // join i2c bus with Slave ID
  Wire.onReceive(receiveDataPacket); // register talk event
  Wire.onRequest(slavesRespond);  // register callback event
}
  
void loop(){}
 
void receiveDataPacket(int howMany){
  //  if (howMany != 11) return; // Error
  LastMasterCommand = Wire.read();          
  a = Wire.read();
  b = Wire.read();
  c = Wire.read();
  d = Wire.read();
  e = Wire.read();
}
 
void slavesRespond(){
 
  int returnValue = 0;
 
  switch(LastMasterCommand){
    case 0:   

    break;
 
    case 128: 
      Wire.write(i2cdata, 32);
    break;
    
    case 129: 
      Wire.write(i2credgreen, 32);
    break;
    
    case 130: 
      Wire.write(i2cblue, 32);
    break;
 
  }
 
  LastMasterCommand = 0;       // null last Master's command
}

Thanks a lot cattledog to give me the main help vectors to get at this result :smiling_imp: :wink: