Arduino Nano Every I2C @ 400kHz?

Hi everyone

just a quick question, can the Nano Every run i2c speeds of 400kHz or am I stuck with 100kHz?

Couldn't find anything on the matter except for this post that I can't really make sense of: i2c clock speed - #2 by westfw


1. The NANO Every runs at 20 MHz.
2. According to data sheets of ATmega4809 (the MCU of NANO Every), frequency of SCL signal of TWI Bus is given by the following formula:

==> 400x1000 = 20x1000000/(1+2xBAUD + 20x1000000*10 nsec)
==> BAUD = 50-10.2 = 40

3. To set SCL at 400 kHz, the above value of BAUD has to be loaded into MBAUD Register keepng Master/TWI Bus at disabled condition.

Use the Wire.setClock() function:

Wire.setClock( 400000L);

Here is the source code to set the clock speed for the megaavr branch:

There are reports that the Wire.setClock() does not work properly.

Below 100kHz is not possible, and from 800kHz and up there is a bug. The 400kHz is possible, but it will actually be 300kHz.

The answer is:

  • Yes, you can use Wire.setClock (400000L);
  • No, 400kHz is not possible, it will be 300kHz.


#include <Wire.h>

void setup()
  Wire.setClock( 400000L);

void loop()
  Wire.beginTransmission( 0x2B);

  delay( 100);

Hardware signals (sample rate 24MHz with LHT00SU1 and PulseView/sigrok):


The SCL is 300kHz instead of 400kHz.

Issue made:

[ADDED] the resulting clock speed seems to depend on the pullup resistors as almytom clearly shows below.

Working through the calculations in the library code, the frequency is set at 392kHz. However the data sheet simply says that the rate actually sets the maximum value and the clock is slowed down by the rise time of TCL. Since this is open drain, that time is determined by the pullup and capacitance on the line. It would appear the the quoted frequency will only be obtained with nothing connected to the SCL pin!

1 Like

hey everyone, thanks for all the replies.

admittedly, I'm a little confused by the details, so I guess the short answer is the Nano Every supports I2C speeds of 400kHz, yes?

I'm a little concerned about the possibility of the wire.Setclock() function not working properly - is there a simple way to check if (300/392/)400kHz actually works once it's set?

The Nano Every, using the boards package from Arduino, runs at 16MHz - the box and webpage in the store are wrong when they state 20MHz. Using MCUdude's MegaCoreX, or modifying the boards.txt file, will enable running at 20MHz.

1 Like

It is working properly. Things are clearer when viewed with an oscilloscope rather than a logic analyzer (using Koepel's sketch):

You can see that SCL (the blue trace) is being limited by the rise time of the signal. The I2C state machine cannot proceed until SCL is high. In my case I'm measuring 322kHz.

If I add an additional 1K pullup resistor to SCK the rise time improves immensely at it actually shows 417kHz (because a nominal rise time is factored into the clock calculation, and we are now faster than the nominal rise time.)

So if you want to run faster, you just need to add an external pullup resistor. The built-in one is just too large. (Note that it doesn't seem to be working correctly at this speed for some reason! The pullup probably needs to be larger because this seems to be introducing some timing issue.)

1 Like

I don't own a physical NANO Every Board; so, I can't verify the actual operating frequency of the board.

Ouch, we have been cheated on.
#define F_CPU 16000000U

@gabechan You can try Wire.setClock(400000L) after the Wire.begin(). That should make it faster, but there is also overhead by the Wire library.
Don't mind us talking about the bug and wrong cpu clock speed. Those problems came to the surface because we looked into it. Thank you for your contribution to the open source community :smiley:

haha ok, thanks to everyone who replied!