I²C Read data

Hi,

For my project I need to read and send data from and to a PIC16F… configured as a I²C slave, so far I have the code for the PIC.
But I’m using an Pro Micro (programmed in the Arduino IDE) as a master.
For this µC I have the send data script ready but I can’t figue out how to read the data.
For the communication I use the default layout that you can find back at the bottom.
I got the write part, but how do I go about reading?

Thank you in advanced
~TJHUNTER

If you could duplicate your problem in a pure Arduino environment, you'd have no problem getting responses here.
For I2C, I have found this site very helpful and have a built a couple of projects based on examples here:
http://www.gammon.com.au/i2c

This might help
master reader / slave writer
master writer / slave reader

6v6gt:
If you could duplicate your problem in a pure Arduino environment, you’d have no problem getting responses here.

My problem is pure for an Arduino environment (unless this means no I²C sensors).
The communication methode I use is used in a lot of sensors and all I’m asking is the Arduino side (as the PIC µC is in this case a sensor) the rest shouldn’t matter.

sterretje:
This might help
master reader / slave writer
master writer / slave reader

This is exactly my problem, in the code available at those links you either write the data (wich I already had) or you request an x number of bytes (registers) so you would have to read all register before the one you want, if I’m not mistaking those sites.
What I want is to ONLY request one byte for any register.

A: This is an example in which the Arduino-UNO1 (Atmega328P-1) reads 1-byte data (content of PINB) from Arduino-UNO2 (ATmega328P-2). It may help you to figure out the way of reading 1-byte data from your PIC MCU by the Arduino-UNO1 using I2C Bus.
i2c-1.png

B: Master-UNO1 Codes:

#include<Wire.h>

void setup()
{
  Serial.begin(9600);
  Wire.begin();

  //--requesting Slave to send content of PBR-Register--
  Wire.beginTransmission(0x23); //I2C Address  of Slve (UNO2)
  Wire.write(0x01); //command code for PBR Register
  Wire.endTransmission();

  //---reading data (from FIFO Buffer) that is to come from Slave--
  Wire.requestFrom(0x23, 1);  //1-byte data being reqiested
  byte x = Wire.read();    //x contains the value of PINB sent by UNO2
  Serial.println(x, BIN);   //Serial Monitor shows PINB values of Slave
}

void loop()
{

}

C: Slave-UNO2 Codes:

#include<Wire.h>
bool flag1 = LOW;

void setup()
{
  Serial.begin(9600);
  Wire.begin(0x23);    //Slave's I2C Address
  DDRB = 0x00;   //Port-B direction as input
  
  Wire.onReceive(receiveEvent);
  Wire.onRequest(sendEvent);
}

void loop()
{

}

void receiveEvent(int howMany)
{
  byte x= Wire.read();
  if(x == 0x01)
  {
    flag1 = HIGH;  //command received to send Port-B (input = PINB) content 
  }
}

void sendEvent(int howMany)
{
  if(flag1 == HIGH)
  {
    Wire.write(PINB); //sending PINB value of Port-B Register
    flag1 = LOW;
  }
}

D: Operating Procedures:
(1) Build the circuit as per diagram of Step-A.
(2) Upload Master codes of Step-B.
(3) Upload Slave Codes of Step-C.
(4) Using jumpers engage Logic level at DPin-8 to 13 (PB0 - PB5) of Slave.
(5) Press and hold reset buttons of both Arduinos.
(6) Bring in Serial Monitor of Master at 9600 Bd.
(7) Release reset button of Slave.
(8) Release reset button of Master.
(9) Check that the content of PINB Register of Slave has correctly appeared on Serial Monitor of Master.

i2c-1.png

What I want is to ONLY request one byte for any register.

Why is that a problem? There are many, many on line examples for how to do exactly that operation. Google “arduino i2c read register”.

Hint: if the site shows you how to read “x” bytes, substitute 1 for x.

jremington:
Why is that a problem? There are many, many on line examples for how to do exactly that operation. Google "arduino i2c read register".

Hint: if the site shows you how to read "x" bytes, substitute 1 for x.

All examples are in this form:

  1. Request a write to the address
  2. Send the register
  3. Request a read from the address

The form I need is:

  1. Request a read from the address
  2. Send the register

So I don't want the write part, only a read part.

The communication you are describing either does not conform to I2C conventions, or your understanding of it is in error.

Each I2C transaction either sends a byte (or bytes) from the Master to a Slave (I2C Write operation) or listens for the Slave to send a byte (or bytes) to the Master (I2C Read operation).

If you want to read a specific register in the Slave, the Master needs to tell it the desired register address. That is done with an I2C Write operation.

gfvalvo:
If you want to read a specific register in the Slave, the Master needs to tell it the desired register address. That is done with an I2C Write operation.

This is correct for a passive slave but (probably) not for an active slave like another Microcontroller (ATmega328P of PIC). When the Slave is an 'active slave', we need to have an agreed rule that sending a command value of 0x01 (or any other value) from the Master to the Slave would mean that the Master is requesting for the content of PINB Register (or any other register) of the Slave. The strategy has been explained in Post#4.

GolamMostafa:
When the Slave is an 'active slave', we need to have an agreed rule that sending a command value of 0x01 (or any other value) from the Master to the Slave would mean that the Master is requesting for the content of PINB Register (or any other register) of the Slave.

"Sending a command value of 0x01" is, in fact, done with an I2C Write operation where the '0x01' is the payload. Whether you call it a "command" or a "register address" is immaterial. You need to do an I2C Write in order to tell the Slave what you want.

gfvalvo:
"Sending a command value of 0x01" is, in fact, done with an I2C Write operation where the '0x01' is the payload. Whether you call it a "command" or a "register address" is immaterial. You need to do an I2C Write in order to tell the Slave what you want.

Yes!

GolamMostafa:
Yes!

Glad we're in agreement and you understand. Apparently @TJHUNTER still does not.

I've edited the slave and it is now compatible with this Arduino methode you all showed, I added a register were you can choose what methode you use.