I2c with multiple command structure

Hello Everyone,

Since last week i am the owner of an Arduino Nano v3.
Luckily i have some previous work done with microcontrollers.
When i searched for examples for i2c i found only very basic ones.
So i thought i share what i have so far.

the setup is;
an lcd-screen to an AY0348 to the Arduino Nano.
the Arduino is connected via i2c to a Raspberry pi.
the C program runs on the pi and tells de Arduino the time.

Left to do; Error handling

The setup works, the lcd display is telling the correct time and the colon is blinking.

lcd.ino (2.49 KB)

TWItoTime.c (1.63 KB)

Well done.

The Arduino receiveEvent() is an interrupt handler, and it is called at the end of the I2C transmission. The received data is in the buffer, and the parameter 'howMany' is the number of bytes in the buffer. When nothing is taken from the buffer with Wire.read(), the Wire.available() is also the same as 'howMany'.

Could you fill the data in a buffer, and transmit that buffer in a single I2C transmission ?
Suppose 7 bytes are transmitted at once.

volatile buffer[40];

void receiveEvent(int howMany)
{
  if( howMany == 7) // check if this is the number of bytes we are expecting.
  {
    Wire.readBytes( buffer, howMany);
  }
}

If "setTime()" is a short function, you could call it from receiveEvent(). But no delay() and no use of the Serial library may be used in receiveEvent().

The update of the display is very fast. You could add a delay(50) ; at the end of the loop().

Hello Peter,

Thank you.

Quote; Could you fill the data in a buffer, and transmit that buffer in a single I2C transmission ?
Suppose 7 bytes are transmitted at once.

I suppose I could, and I will keep it in mind for further versions. I will have to remember that the maximum i2c buffer on an Arduino is 32 Bytes.
Also; I want it to be a sort of skeleton code, so that I will be able to put other commands to use as well.
That is the same reason I don't use setTime() in the receiveEvent.
If I add a command something else is going to happen, time needs only to be set once and will be updated by the Arduino on its own.

Quote;
The update of the display is very fast. You could add a delay(50) ; at the end of the loop().

Well not really, the display function is called all the time, but only updates the screen output once a minute.
And of course happily blinks the colon every second. Again this is because its a start.
I want to add code to the loop to do other things with other commands. And still update the display.

Okay :slight_smile:
Sending a single packet of data is how I2C is used (always).
To do more things in the loop(), remove all delay() and use millis(). The BlinkWithoutDelay is a start how to use millis() : https://www.arduino.cc/en/Tutorial/BlinkWithoutDelay
That example is wrong, since a long is used for previousMillis. Every variable that is used with millis() should be unsigned long to prevent the rollover problem.

Actually, the little ElapsedMillis library is very easy to use and takes care of these things inducing the rollover very nicely.

Time for a small update, i have rewritten the sketch and attached a different display.

The display is now 16x2, and the goal was to have the time on the first line.
After that i wanted to be able to display text on the second line.
It took a bit of tinkering, but that is part of the fun.

Headroom:
Actually, the little ElapsedMillis library is very easy to use and takes care of these things inducing the rollover very nicely.

Thank you, Headroom. i have used it now and it works like a charm.

Still the loop doesn't do much but there is no need at this moment.

Display.ino (3.26 KB)

twrite.c (1.87 KB)