Skip to content

Allow customization of transmit and receive buffer sizes for I2C 'Wire' and 'Wire1' objects. #148

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 18 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 6 additions & 8 deletions libraries/Wire/examples/master_reader/master_reader.ino
Original file line number Diff line number Diff line change
Expand Up @@ -12,21 +12,19 @@

#include <Wire.h>

void setup()
{
Wire.begin(); // join i2c bus (address optional for master)
void setup() {
Wire.begin(); // join I2C bus (address optional for master)
Serial.begin(9600); // start serial for output
}

void loop()
{
Wire.requestFrom(2, 6); // request 6 bytes from slave device #2
void loop() {
Wire.requestFrom(8, 6); // request 6 bytes from slave device #8

while(Wire.available()) // slave may send less than requested
{
while (Wire.available()) { // slave may send less than requested
char c = Wire.read(); // receive a byte as character
Serial.print(c); // print the character
}
Serial.println();

delay(500);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
// Wire Master Reader Custom Buffer

// Demonstrates use of the Wire library with customized buffers
// Reads data from an I2C/TWI slave device
// Refer to the "Wire Slave Sender Custom Buffer" example for use with this

// Created 31 Dec 2024

// This example code is in the public domain.


#include <Wire.h>
#include <TwoWireBuffers.h>
#include "Arduino.h"

#define USE_WIRE1 false // Set to true for using Wire1

// request 6 bytes from slave device #8
constexpr size_t REQUESTED_BYTE_COUNT = 6;

constexpr size_t RECEIVE_BUFFER_SIZE = REQUESTED_BYTE_COUNT;
constexpr size_t TRANSMIT_BUFFER_SIZE = 0; // There is no transmit in this sketch.

#if not USE_WIRE1

SET_Wire_BUFFERS(RECEIVE_BUFFER_SIZE, TRANSMIT_BUFFER_SIZE,
true /* master buffers needed */, false /* no slave buffers needed */ );

void setup() {
Wire.begin(); // join I2C bus (address optional for master)
Serial.begin(9600); // start serial for output

// This is just for curiosity and could be removed
printWireBuffersCapacity(Serial);
}

void loop() {
Wire.requestFrom(8, REQUESTED_BYTE_COUNT);

while (Wire.available()) { // slave may send less than requested
const char c = Wire.read(); // receive a byte as character
Serial.print(c); // print the character
}
Serial.println();

delay(500);
}

void printWireBuffersCapacity(Stream& stream) {
const auto& buffers = GET_Wire_BUFFERS();

stream.print("Wire transmit buffer size is ");
stream.println(buffers.txWireBufferCapacity());

stream.print("Wire receive buffer size is ");
stream.println(buffers.rxWireBufferCapacity());

stream.print("Wire service buffer size is ");
stream.println(buffers.srvWireBufferCapacity());
}

#else

SET_Wire1_BUFFERS(RECEIVE_BUFFER_SIZE, TRANSMIT_BUFFER_SIZE,
true /* master buffers needed */, false /* no slave buffers needed */ );

void setup() {
Wire1.begin(); // join I2C bus (address optional for master)
Serial.begin(9600); // start serial for output

// This is just for curiosity and could be removed
printWire1BuffersCapacity(Serial);
}

void loop() {
Wire1.requestFrom(8, REQUESTED_BYTE_COUNT);

while (Wire1.available()) { // slave may send less than requested
const char c = Wire1.read(); // receive a byte as character
Serial.print(c); // print the character
}
Serial.println();

delay(500);
}

void printWire1BuffersCapacity(Stream& stream) {
const auto& buffers = GET_Wire1_BUFFERS();

stream.print("Wire1 transmit buffer size is ");
stream.println(buffers.txWireBufferCapacity());

stream.print("Wire1 receive buffer size is ");
stream.println(buffers.rxWireBufferCapacity());

stream.print("Wire1 service buffer size is ");
stream.println(buffers.srvWireBufferCapacity());
}

#endif
2 changes: 1 addition & 1 deletion libraries/Wire/examples/master_writer/master_writer.ino
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ void setup()
Wire.begin(); // join i2c bus (address optional for master)
}

byte x = 0;
static byte x = 0;

void loop()
{
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
// Wire Master Writer Custom Buffer

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

// Created 31 Dec 2024

// This example code is in the public domain.


#include <Wire.h>
#include <TwoWireBuffers.h>
#include "Arduino.h"

#define USE_WIRE1 false // Set to true for using Wire1

// The following text will not fit into the default buffer of 32 bytes.
static const char text[] = "You really won't believe it, but x is ";

constexpr size_t RECEIVE_BUFFER_SIZE = 0; // There is no receive in this sketch.
constexpr size_t TRANSMIT_BUFFER_SIZE = 42; // Enhance the buffer to 42 characters.

#if not USE_WIRE1

SET_Wire_BUFFERS(RECEIVE_BUFFER_SIZE, TRANSMIT_BUFFER_SIZE,
true /* master buffers needed */, false /* no slave buffers needed */ );

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

// This is just for curiosity and could be removed
Serial.begin(9600); // start serial for output
printWireBuffersCapacity(Serial);
}

static byte x = 0;

void loop() {
Wire.beginTransmission(8); // transmit to device #8
Wire.write(text); // sends multiple bytes
Wire.write(x); // sends one byte
Wire.endTransmission(); // stop transmitting

x++;
delay(500);
}

void printWireBuffersCapacity(Stream& stream) {
const auto& buffers = GET_Wire_BUFFERS();

stream.print("Wire transmit buffer size is ");
stream.println(buffers.txWireBufferCapacity());

stream.print("Wire receive buffer size is ");
stream.println(buffers.rxWireBufferCapacity());

stream.print("Wire service buffer size is ");
stream.println(buffers.srvWireBufferCapacity());
}

#else

SET_Wire1_BUFFERS(RECEIVE_BUFFER_SIZE, TRANSMIT_BUFFER_SIZE,
true /* master buffers needed */, false /* no slave buffers needed */ );

void setup() {
Wire1.begin(); // join I2C bus (address optional for master)

// This is just for curiosity and could be removed
Serial.begin(9600); // start serial for output
printWire1BuffersCapacity(Serial);
}

static byte x = 0;

void loop() {
Wire1.beginTransmission(8); // transmit to device #8
Wire1.write(text); // sends multiple bytes
Wire1.write(x); // sends one byte
Wire1.endTransmission(); // stop transmitting

x++;
delay(500);
}

void printWire1BuffersCapacity(Stream& stream) {
const auto& buffers = GET_Wire1_BUFFERS();

stream.print("Wire1 transmit buffer size is ");
stream.println(buffers.txWireBufferCapacity());

stream.print("Wire1 receive buffer size is ");
stream.println(buffers.rxWireBufferCapacity());

stream.print("Wire1 service buffer size is ");
stream.println(buffers.srvWireBufferCapacity());
}

#endif
5 changes: 5 additions & 0 deletions libraries/Wire/examples/slave_receiver/slave_receiver.ino
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,11 @@ void loop()

// function that executes whenever data is received from master
// this function is registered as an event, see setup()
//
// Hint: This function is called within an interrupt context.
// That means, that there must be enough space in the Serial output
// buffer for the characters to be printed. Otherwise the
// Serial.print() call will lock up.
void receiveEvent(int howMany)
{
while(1 < Wire.available()) // loop through all but the last
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
// Wire1 connnected to Wire. (scl <-> scl1, sda <-> sda1)

// Demonstrates use of the Wire library on a single Arduino board
// with 2 Wire interfaces (like Arduino Due).
// Uses the option of customizing the buffers.
//
// Wire data to an I2C/TWI slave device
// Wire1 receives data as an I2C/TWI slave device

// Created 02 Jan 2025

// This example code is in the public domain.


#include <Wire.h>
#include <TwoWireBuffers.h>
#include "Arduino.h"

static_assert(WIRE_INTERFACES_COUNT > 1, "You need two I2C interfaces on the Arduino board to run this sketch");

static const char text[] = "You really won't believe it, but x is ";

// Wire is the master writer
constexpr size_t M_RECEIVE_BUFFER_SIZE = 0; // There is no receive in this sketch.
constexpr size_t M_TRANSMIT_BUFFER_SIZE = 42; // Enhance the buffer to 42 characters.
SET_Wire_BUFFERS(M_RECEIVE_BUFFER_SIZE, M_TRANSMIT_BUFFER_SIZE,
true /* master buffers needed */, false /* no slave buffers needed */ );

// Wire1 is the slave receiver
constexpr size_t S_RECEIVE_BUFFER_SIZE = 42; // Be able receive up to 42 characters in one message.
constexpr size_t S_TRANSMIT_BUFFER_SIZE = 0; // There is no transmit in this sketch.
SET_Wire1_BUFFERS(S_RECEIVE_BUFFER_SIZE, S_TRANSMIT_BUFFER_SIZE,
false /* no master buffers needed */, true /* slave buffers needed */ );

void setup() {
Serial.begin(9600); // start serial for output
Wire.begin(); // master joins I2C bus (address optional for master)
Wire1.begin(8); // slave joins I2C bus with address #8
Wire1.onReceive(receiveEvent); // register event

// This is just for curiosity and could be removed
printWireBuffersCapacity(Serial);
printWire1BuffersCapacity(Serial);
}

static byte x = 0;

void loop() {
Wire.beginTransmission(8); // transmit to device #8
Wire.write(text); // sends multiple bytes
Wire.write(x); // sends one byte
Wire.endTransmission(); // stop transmitting

x++;
delay(500);
}

// function that executes whenever data is received from master
// this function is registered as an event, see setup()
//
// Hint: This function is called within an interrupt context.
// That means, that there must be enough space in the Serial output
// buffer for the characters to be printed. Otherwise the
// Serial.print() call will lock up.
void receiveEvent(int howMany) {
while (1 < Wire1.available()) { // loop through all but the last
const char c = Wire1.read(); // receive byte as a character
Serial.print(c); // print the character
}
const int x = Wire1.read(); // receive byte as an integer
Serial.println(x); // print the integer
}

void printWireBuffersCapacity(Stream& stream) {
const auto& buffers = GET_Wire_BUFFERS();

stream.print("Wire transmit buffer size is ");
stream.println(buffers.txWireBufferCapacity());

stream.print("Wire receive buffer size is ");
stream.println(buffers.rxWireBufferCapacity());

stream.print("Wire service buffer size is ");
stream.println(buffers.srvWireBufferCapacity());
delay(250); // Give time to finalize the print out
}

void printWire1BuffersCapacity(Stream& stream) {
const auto& buffers = GET_Wire1_BUFFERS();

stream.print("Wire1 transmit buffer size is ");
stream.println(buffers.txWireBufferCapacity());

stream.print("Wire1 receive buffer size is ");
stream.println(buffers.rxWireBufferCapacity());

stream.print("Wire1 service buffer size is ");
stream.println(buffers.srvWireBufferCapacity());
delay(250); // Give time to free up Serial output buffer.
}
Loading