Wire library

Wire.RequestFrom specifies a number of characters. Can the slave get access to this number, and if so how? Thanks Max

Can the slave get access to this number, and if so how?

Yes. When the registered onReceive() event handler is called, the argument to the function is how many bytes to return.

Ah. Thank you. Sorry, that should have been obvious. Max

I hope that this is not a hijack, as it the thread is recent and I believe the question is identical. I have two Arduinos. The master requests data packets from the slave with requestFrom(). But it appears to me that the slave must run a function registered with onRequest(). That function has no size parameter.

In the Wire library example for Master reader/ Slave sender, the slave transmits a fixed length packet, the length of which is known by the master and hard coded as a constant 6.

So I felt I had to design a system where the size is transmitted first. The slave sends a signal on an I/O pin to signal the master that it has data to read. Am I missing something? Is there a better way?

master:

#include <Wire.h>

const uint8_t dataReceivedPin = 4;
uint8_t bufsize;
bool  dataWasRead;

void setup() {
  Wire.begin();        // join i2c bus (address optional for master)
  Serial.begin(9600);  // start serial for output
  delay(50);
  pinMode(dataReceivedPin, INPUT);
  pinMode(A4, INPUT_PULLUP);
  pinMode(A5, INPUT_PULLUP);
  Serial.println("starting...");
}

void loop()
{
  if (digitalRead(dataReceivedPin) == HIGH)
  {
    if (dataWasRead == false)
    {
      Wire.requestFrom(0x55, 1);    // request size byte from slave device
      if (Wire.available())
      {
        bufsize = Wire.read();
      }

      Wire.requestFrom(0x55, bufsize);    // request n=size bytes from slave device
      while (Wire.available())
      {
        uint8_t c = Wire.read();
        Serial.print(c, HEX);         // print the character
        Serial.print(' ');         // print the character
      }
      Serial.println();
      dataWasRead = true;
    }
  }
  else
  {
    dataWasRead = false;
  }
}

slave:

// airTime receive 2.02
//
// receives an encrypted OOK packet and relays it on the serial port and I2C, decrypted.
#define DEBUG_ATR

#include <Wire.h>

// Radiohead Amplitude Shift Keying (OOK) library
#include <RH_ASK.h>

// cypher decoder
// library modified to support uint8_t data type

#include <Cape.h>

Cape codec("chenghuasmokes", 2, true);

// radio receiver
//   RH_ASK::RH_ASK(bps=2000, rxpin=11, txpin=12, ptt=10, ptt_invert=false)
RH_ASK radio(2000, 8, 9, 13);

const uint8_t dataFlagPin = 4;

enum wState {RESPOND_SIZE, RESPOND_DATA};
wState wireState = RESPOND_SIZE;

void setup()
{
  Serial.begin(9600);	// Debugging only
  if (!radio.init())
    Serial.println(F("radio failure"));
  else
    Serial.print(F("airTime receive 2.02 - compiled "));
  Serial.println(__DATE__);
  Serial.println(F("radio is on"));

  // become an I2C slave on address 0x55
  Wire.begin(0x55);
  Wire.onRequest(packetReadEvent);
  pinMode(dataFlagPin, OUTPUT);
  pinMode(A4, INPUT_PULLUP);
  pinMode(A5, INPUT_PULLUP);
  pinMode(LED_BUILTIN, OUTPUT);
}

uint8_t buf[RH_ASK_MAX_MESSAGE_LEN];
uint8_t buflen = sizeof(buf);

void loop()
{

  if (radio.recv(buf, &buflen)) // Non-blocking
  {
    // decrypt packet
    //
    // A strange quirk of the Cape library:
    // decrypt() receives a buffer length that doesn't include the initialization vector
    // which it needs in order to decode.
    buflen--;
    codec.decrypt(buf, buflen);
    // decrypted packet is the same size as the encrypted one

    // validation
    // read checksum
    unsigned int packetChecksum = (uint16_t)codec.result[buflen - 2] << 8
                                  | codec.result[buflen - 1];

    // compute checksum
    unsigned int verifyChecksum = 0;
    for (int i = 0; i < buflen - sizeof(packetChecksum); i++)
    {
      verifyChecksum += codec.result[i];
    }

    if (verifyChecksum == packetChecksum)  //checksum is valid
    {
#ifdef DEBUG_ATR
      for (int i = 0; i < buflen; i++)
      {
        Serial.print(codec.result[i] / 16, HEX);
        Serial.print(codec.result[i] % 16, HEX);
      }
      Serial.println();
#endif

      // Initialize the I2C slave process
      //
      // expect a size request first
      wireState = RESPOND_SIZE;
      // set the data received flag for the master
      digitalWrite(LED_BUILTIN, HIGH);
      digitalWrite(dataFlagPin, HIGH);
    }
  }
}

// ***************************
// slave respond with a packet
//


void packetReadEvent()
{
  if (wireState == RESPOND_SIZE)
  {
    Wire.write(buflen);
    wireState = RESPOND_DATA;
  }
  else if (wireState == RESPOND_DATA)
  {

    Wire.write(codec.result, buflen);
    wireState == RESPOND_SIZE;
    digitalWrite(LED_BUILTIN, LOW);
    digitalWrite(dataFlagPin, LOW);
  }
}