Timer for I2C

Which TIMER is influencing the Clock(SCL) of the I2C interface? Can it be changed to another timer?
I use millis() for a blinker which seems to be controlled via TIMER 0. I want to decouple the blinking interval from the I2C reading of sensors because everytime a sensor sends an update the blinker period

Non, I2C timing is derived from the system clock. :slight_smile:

Is that time difference notable for a human or is it in ms range? Because I2C will cause interrupts.

Can you show us compilable (demo) code?

If ATmega then the Timers and I2C are independent despite they have common I/O clock unit. The millis() and all other stuff around is controlled by Timer/Counter0. The SCL is independent. Read the datasheet "Clock Systems and their Distribution". In case of your issue, I think, it is probably insufficiency of your program.

I want to decouple the blinking interval from the I2C reading of sensors because everytime a sensor sends an update the blinker period

Please post a program that demonstrates this happening.

Ok. I have attached the code which is a bit longer. I use several I2C shields for reading temperature, pressure and DAC. I hope the comments are explaining the purposes.

RMC_APMRev4.ino (37.1 KB)

AMS_5600.cpp (10.7 KB)

AMS_5600.h (1.77 KB)

Maybe I should explain my project. I have developed an articulated frame steering E-trike with front wheel hubmotor up to 45 kph. Now, I want to change it to rear wheel drive with electronic differential and two rear hub motors instead of one in front.I want to read a hallsensor switch for velocity measurement of the front wheel and use the throttle grip to setpoint the velocity. A turning angle sensor is measuring the steering angle which sets the velocities of rear left and right wheel. I use two BLDC controllers which should each get a throttle signal(0-5V) from the MEGA2560. A PID controller library is included which will be needed for the velocity adjustment. Then I have several consumers which can be switched by GPIOs at a Nextion display. One of them is the blinker unit. I would like to attach a picture in PNG of the trike but it is forbidden somehow. I also would like to realize anti slip control and ESP.

I would guess that the issue is that the arduino can't turn the LED on or off while it's busy doing something else; those routines that read sensors are not instant, but worse still they have a bunch of delay(10)'s in them.

while you've really done a great job muscling through this code, you'd benefit a lot from learning about some C++ basics like Arrays and structs.

getting all that blocking code out of your functions is key, as already pointed out.


//Definition of parameters as characters
char buffer[100]            = {0},
                              buffer_temp[10]        = {0},
                                  buffer_speed[10]       = {0},
                                      buffer_dailytrip[10]   = {0},
                                          buffer_totaltrip[10]   = {0},
                                              buffer_voltage[10]     = {0},
                                                  buffer_current[10]     = {0},
                                                      buffer_charge[10]      = {0},
                                                          buffer_temp_bat[10]    = {0},
                                                              buffer_temp_lctr[10]   = {0},
                                                                  buffer_temp_rctr[10]   = {0},
                                                                      buffer_pres[10]        = {0};

uint8_t number              = 0;
int   addr;

//Time sampling
uint16_t delta_t            = 0,
         t_0                = 0,
         t_1                = 0;
boolean timemarker          = LOW;

// current and charge calculation
float charge                = 0,
      ms_to_h_factor        = 3.6E-6;
int      vileft             = 0.0,
         viright             = 0.0;
const int   vileftPin       = A0, // analogue input for current left controller
            virightPin      = A1; // analogue input for current right controller
double i_left               = 0.0,   //current left controller from -50 to 50 A
       i_right              = 0.0, //current right controller from -50 to 50 A
       i_tot                = 0.0, // total current
       i_sample             = 0.0;

// distance measurement
float dailytripkm           = 0,
      totaltrip             = 0;
boolean wheelsensorState        = LOW,
        lastwheelsensorState    = LOW,
        resetdailytrip          = LOW;

// actual rpm measurement rear wheels
volatile int rpmcount[2]    = {0, 0};
int rpm[2]                  = {0, 0};
unsigned long lastmillis[2] = {0, 0};
int index;
  • did you know C++ will initialize global variables to zero by default?
  • booleans are true or false (Arduino defines LOW as zero and HIGH as 1)
  • you've got some rather un-conventional formatting, you can auto-format your code in the arduino IDE (using TOOLS -> AUTOFORMAT)


String burnAngle()
  int burnResult = ams5600.burnAngle();
  String returnStr = "Burn angle error: ";

  switch (burnResult)
    case 1:
      returnStr = "Burn angle success";
    case -1:
      returnStr += "no magnet detected";
    case -2:
      returnStr += "no more burns left";
    case -3:
      returnStr += "no positions set";
      returnStr += "unknown";
  return returnStr;

do you really need to take all the risk of using String class?

though, it is a huge undertaking to get this all sorted...

Hello BulldogLowell and DrAzzy,

thanks for your advices. So I can spare out to set any global variable to 0. I have done Autoformat.
As a mechanical engineer it is a bit tough to get through C++ but I am willing to learn. The main aim
is to first get the velocities of all three wheels. This is mandatory for controlling the rear wheels to achieve the set velocity for the front wheel. The rear hub motor wheels with three hall sensors each are 24" and the front with external hallsensor switch(turns from 1 to 0 if magnet passes) is 20". I will only need one hall sensor for each wheel. The maximum RPM is 420 or around 7 Hz of sampling rate which is very low. So it should be no issue for the MEGA 2560. Maybe someone could me help out with that. Regarding the blinker I could simply use a LED blinker if it cannot be realized with the MEGA2560.

Why do you need to get the velocity of the front wheel ?

The LED blinker can easily be done using the BlinkWithoutDelay principal

Hello UKHEliBob,
I need the velocity of the passive driven front wheel for transmission-slip control, i.e. if both or one rear wheel is in the mud they will loose traction. In the worst case this can be indicated by front velocity is equal or close to 0.The code blinkwithoutDelay is already implemented in the actual function.