:Some Experimental Results on Wire.requestFrom() Command and I2C Clock Stretching:
1. In Master UNO-1, I have executed the following instruction.
Wire.requestFrom(0x51, 3); //Slave address (UNO-2) is 0x51; 3-byte data to read from Slave
My understanding: This is a looping instruction. The Master has sent the deviceAddress (0x51); but it has not yet received ACK pulse (SDA line will be puled down by the Slave's TWI Logic) from the Slave. We will see later -- when and how the Slave creates the ACK signal.
After receiving the ACK signal, the Master generates required amount of SCL pulses to collect 3-byte data from the data buffer of the Slave.
2. After receiving the deviceaddress (0x51), the Slave is interrupted; it goes to ISR, and from the ISR it goes to Wire.onRequest() subroutine. (The Slave has not yet genertaed the ACK signal by pulling down the SDA line.) In the SUR, the Slave executes the following instruction to fill up data buffer (Ref: Post#19).
void sendEvent()
{
Wire.write(0x12);
Wire.write(0x34);
Wire.write(0x56);
}
After executing the above SUR, the Slave returns to ISR and then creates the ACK signal by pulling down the SDA line. After that the Slave returns to MLP (Main Line Progrom) -- the loop() function.
3. The Master has now received the ACK signal while it is still within the Wire.requestFrom() loop instruction. Now, the Master generates SCL pulses as required to collects 3-byte data from the Slave. The data are automatically stored in the 32-byte wide FIFO buffer.
4. I have added the following codes after the Wire.requestFrom() command of the UNO-1 (Master Side).
byte x1 = Wire.read();
Serial.prinrln(x1, HEX); //Serial Monitor shows: 12
byte x2 = Wire.read();
Serial.prinrln(x2, HEX); //Serial Monitor shows: 34
byte x3 = Wire.read();
Serial.prinrln(x13, HEX); //Serial Monitor shows: 56
5. The Serial Monitor shows:
12
34
56
6. The Master has correctly read 3-byte data from the active Slave (UNO_2).
Is there any requirement of clock stretching in the present case?
Any comments will be highly appreciated.
Master Codes:
#include <Wire.h>
volatile bool flag3 = false;
void setup()
{
Serial.begin(9600);
Wire.begin(0x50);
Wire.onReceive(receiveEvent);
Wire.beginTransmission(0x051);
Wire.write(0x01); //Command for Motor1
Wire.endTransmission();
while(flag3 == false)
;
Wire.requestFrom(0x51, 3); //slider position
// while (Wire.available() ==0)
// ;
byte x1 = Wire.read();
// Serial.print("Slider value received: ");
Serial.println(x1, HEX);
byte x2 = Wire.read();
Serial.println(x2, HEX);
byte x3 = Wire.read();
Serial.println(x3, HEX);
}
void loop()
{
}
void receiveEvent()
{
sei();
if(Wire.read() == 0x06)
{
Serial.println("Motor-1 Moved Command ACK Received from Slave!");
flag3 = true;
}
}
Slave Codes:
#include<Wire.h>
void setup()
{
Wire.begin(0x51); //address as a slave
Serial.begin(9600);
pinMode(13, OUTPUT);
analogReference(DEFAULT);
Wire.onReceive(receiveEvent);
Wire.onRequest(sendEvent);
}
void loop()
{
}
void receiveEvent(int howmany)
{
sei();
if(Wire.read() == 0x01) //Command to Move motor-1
{
Serial.println("Motor-1 Move Command Received");
//--SEND ack (0X06)--
Wire.beginTransmission(0x50);
Wire.write(0x06); //ACK Send
// Wire.endTransmission();
//---Motor-q move command
digitalWrite(13, HIGH);
delay(5000); //5-sec delay to move slider
digitalWrite(13, LOW);
Serial.println("Slider Moved!");
Wire.endTransmission();
}
}
void sendEvent(int howmany)
{
Serial.println("Request Received to send Slider Position");
Wire.write(0x12);//analogRead(A0)); // slider position is sent from Ch-0 of ADC (3.3V = 0XA6)
Wire.write(0x34);
Wire.write(0x56);
Serial.println("Slider-1 position is sent to Master");
}