I2C data sending

Hey, I've got a quick question, does Wire.onRequest(event); work like an interrupt? I mean, is the function "event" executing immidiately after getting a request from I2C master?

Also, here is my code:

/****************************** STS-5 Geiger-Muller Counter/Dosimeter ******************************/
/*                                             by emce                                             */

#include <Wire.h>
#define GEIGER (2)                        // Geiger tube signal pin (must be an interrupt pin)
#define GEIGER_ADDRESS (8)                // I2C address
volatile word decay = 0;

void setup() {
  pinMode(GEIGER, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(GEIGER), decayCount, FALLING);
  Wire.begin(GEIGER_ADDRESS);
  Wire.onRequest(request);
  Serial.begin(9600);
 }

void loop() {
  
 }

void decayCount() {
  decay++;
  Serial.println(); 
  Serial.print("Dose: ");
  Serial.print(decay);
  Serial.println(" counts).");
  Serial.println();
 }

void request() {
  Wire.write(decay);
  decay = 0;
 }

Can I leave loop function empty or just delete it?

Looking quickly over the source files, I see an object and some constructs. I see nothing that operates like an interrupt.

In this example, from the wire library, the void loop is left empty.

Have you compiled the code?

Does it work?

Yeah, I compiled the code, looks fine and i had no errors. Ufortunately I dont have a hardware to test it.

Why there is a delay in loop in this example?

void loop() {
  delay(100);
}

Ufortunately I dont have a hardware to test it.

If you would have the opportunity to program the ATmega328P/ATmega32A Microcontroller using assembly (low level language), you would certainly become impressed and astonished to observe how hard and beautiful work the Arduino Developers have done to bring the I2C Bus (aka TWI Bus) Protocol into the High Level Programming paradigm.

It is my understanding that the Forum Members who do talk on the I2C Bus have learnt the protocol having done a lot of experiments using two UNOs and many kinds of I2C based devices. They have also spent a good amount of time in the Forum particularly on the I2C Bus related topics.

Therefore, I would like to request you to kindly arrange the hardware (2 UNOs) and learn yourself (also by taking help from the Forum) (performing experiments) the meanins of TWI bus Interrupt, Wire.requestFrom();, Wire.onRequest();, Wire.onReceive();, Wire.available();, Wire.read();, Wire.write();, and etc.

Thank you,

void request() {
  Wire.write(decay);
  decay = 0;
 }

decay was typed as a "word" or unsigned int which is two bytes.

The wire library transmits bytes. You need to break decay into two bytes for transmission. There are several methods to do this.

The master receiver will also have request and reassemble two bytes.

The onRequest handler is a real interrupt function and it is called immediately.

The code of Wire.cpp and utility/twi.c work together.
https://github.com/arduino/Arduino/tree/master/hardware/arduino/avr/libraries/Wire/src.
In twi.c is a single large interrupt routine that works almost like a state machine. It calls the onReceive and onRequest functions (via a pointer and via an other function) from that interrupt routine.

You don't need a delay in the Arduino loop(). You can use an empty loop().
However, in your sketch you probably need code in the loop().
Using the Serial functions (or delay or display functions or sensors via I2C) in a interrupt is not good. The Serial functions use interrupts themself, and things can get stuck with blocked interrupts.

Use volatile counters in interrupts, but do calculations and Serial things in the loop().
If you use an Arduino Uno, that is a 8-bit microcontroller. That means that when decay is read in the loop(), an interrupt could occur right in between reading the MSB and LSB of the delay variable.

The Wire.write() writes a byte, as @cattledog mentioned.