I2C Won't communicate in setup()

Hi folks,

Background:
I have an I2C master Uno sending a long type to an I2C slave Uno which controls a stepper motor with virtually uninterrupted pulses, leaving the master to do other more complex processing. I’m using the I2C_Anything library for this Gammon Forum : Electronics : Microprocessors : I2C - Two-Wire Peripheral Interface - for Arduino. It’s handy, but not entirely necessary.

The Problem:
I’d like to send an initial value to the slave after the master reboots the slave, as shown in my code in setup(). The slave does not register the initial communication and stays at it’s initialized value of “1000.” As soon as a command is send to the slave from loop() the slave reads it. Why the heck won’t it read when sent from setup()? I’ve messed with delays to allow the slave time to recover after reboot, but no size of value effects the above stated problem.

I2C MASTER:

//This is a program for the I2C Master which does all the processing and sends it to the 
//I2C Slave which controls a stepper motor without much processing time.
//The Master program will be expanded after communication issues are straighened out.

//It is assumed that all timing values in this program are in microseconds unless otherwise noted

#include <I2C_Anything.h>
#include <Wire.h>

int SLAVE_ADDRESS = 1;
int slave_reset_pin = 12;


long max_delay = 9830;       //this is the biggest amount of time delay sent to the slave arduino
long min_delay = 12;         //this is the smallest amount of time delay sent to the slave arduino

long received_delay = 10000; //converted value received from serial terminal
char received_char[16];      //characters received from serial terminal



void setup(){
  pinMode(slave_reset_pin, OUTPUT);
  pinMode(13, OUTPUT);
  digitalWrite(13, LOW);
  
  Wire.begin();
  Serial.begin(115200);
  delay(100);
  
  //reset the slave arduino!!!!!!!!!!!!!!!
  digitalWrite(slave_reset_pin, LOW);
  delay(100);
  digitalWrite(slave_reset_pin, HIGH);
  delay(200);

//THIS WON'T DO ANYTHING!!!!!!!!!!!!!! WHY????????????????????  
  Wire.beginTransmission(SLAVE_ADDRESS);
  I2C_writeAnything(0);                  //if slave receives a 0 is stops the stepper motor
  Wire.endTransmission();

}






void loop(){

//Serial com with computer can receive up to 16 characters (more than enough)
//I like this kind of serial communication. It's exciting because I figured it
//out on my own for the first time, without referencing THE INTERNET :)
  if(Serial.available() > 0){
    for(int i = 0; i < 16; i++){
      received_char[i] = Serial.read();
      if(received_char[i] <= 0)    //fill the remainder of the array with ascii "NULL" value
        received_char[i] = 0;
    }
    


//Convert char array to number
     received_delay = atof(received_char);
    

//Make sure delay is within limits of the I2C slave system
     if(received_delay > max_delay){
        received_delay = 0;      //send 0 to slave so it stops the stepper
      }else{
        if(received_delay < min_delay)
          received_delay = min_delay;
      }
      
      
//Send data to slave system  
      Wire.beginTransmission(SLAVE_ADDRESS);
      I2C_writeAnything(received_delay);
      Wire.endTransmission();
  }    
    
    
     


//print feedback for user on computer - for debugging
  Serial.print(received_delay); Serial.print("\t\t");
  for(int i = 0; i < 16; i++)
    Serial.print(received_char[i]);
  Serial.println("");
    
    
  
  
  delay(500);  
}

I2C SLAVE:

#include <I2C_Anything.h>
#include <Wire.h>

int MY_ADDRESS = 1;                //I2C Slave address

int Direction_Pin = 2;
int Step_Pin = 3;
int MS1_Pin = 4;
int MS2_Pin = 5;
int ms1 = 0;
int ms2 = 0;

long received_delay = 1000; //initialize with some foo foo values
double step_delay = 300;





void setup(){
  Wire.begin(MY_ADDRESS);
  Wire.onReceive(receiveEvent);

  pinMode(Direction_Pin, OUTPUT);
  pinMode(Step_Pin, OUTPUT);
  pinMode(MS1_Pin, OUTPUT);
  pinMode(MS2_Pin, OUTPUT);

  digitalWrite(Direction_Pin, LOW);
  digitalWrite(MS1_Pin, LOW);
  digitalWrite(MS2_Pin, LOW);
  delay(100);
}






void loop()
{
  step_delay = step_calc(received_delay);
  micro_Stepping();

  if(step_delay != 0){
    digitalWrite(Step_Pin, LOW);                // This LOW to HIGH change is what creates the
    digitalWrite(Step_Pin, HIGH);               // "Rising Edge" so the easydriver knows to when to step.
    delayMicroseconds(step_delay);
  }
}





//get the new delay time if data is send from the I2C master
void receiveEvent(int howMany)
{  
  if (howMany >= (sizeof received_delay)){
  I2C_readAnything(received_delay);
  }
}





//step_calc() and mircro_Stepping() calculate and assign
//the values of the micro-Stepping pins on the stepper driver
double step_calc(long delay_input){
  if(delay_input < 0){
    ms1 = 0;
    ms2 = 0;
    return 0;
  }  
  if(delay_input >= 0 && delay_input < 170){
    ms1 = 0;
    ms2 = 0;
    return delay_input * 10;
  }
  if(delay_input >= 170 && delay_input < 400){
    ms1 = 1;
    ms2 = 0;
    return delay_input * 5;
  }
  if(delay_input >= 400 && delay_input < 1000){
    ms1 = 0;
    ms2 = 1;
    return delay_input * 10;
  }
  if(delay_input >= 1000){
    ms1 = 1;
    ms2 = 1;
    return delay_input * 5;
  }
}






void micro_Stepping(){
  if(ms1 == 1){
    digitalWrite(MS1_Pin, HIGH);
  }else{
    digitalWrite(MS1_Pin, LOW);
  }

  if(ms2 == 1){
    digitalWrite(MS2_Pin, HIGH);
  }else{
    digitalWrite(MS2_Pin, LOW);
  }  
}

I’m sure there are better ways to write this code. I’ll clean it up later, but for now I want the functionality to work.

Any thoughts?

  //reset the slave arduino!!!!!!!!!!!!!!!
  digitalWrite(slave_reset_pin, LOW);
  delay(100);
  digitalWrite(slave_reset_pin, HIGH);
  delay(200);

//THIS WON'T DO ANYTHING!!!!!!!!!!!!!! WHY????????????????????  
  Wire.beginTransmission(SLAVE_ADDRESS);
  I2C_writeAnything(0);                  //if slave receives a 0 is stops the stepper motor
  Wire.endTransmission();

You're resetting the slave Arduino and try to send it anything just 200ms after the reset? It's not ready then to do anything because it's still waiting for a sketch to arrive over the serial connection. Increase that delay to 2500ms and try again.

Thanks. I'll give 2500ms a try. I'm not sure what you mean by "waiting for a sketch to arrive over serial".

What does the Arduino do when you upload a sketch?

The DTR line of the serial (or USB2Serial adapter) resets the Arduino. It waits for a short time for a sketch to arrive on the serial interface (pin 0 and 1). If that doesn't happen for some time it continues and starts the stored sketch. You cannot send anything to your arduino before that happened.

Anyway, if you have to reset your slave Arduino your general concept fails. My Arduinos run 24/7 without interruption, no need to reset them. If you have to do that, fix your code.

IN BELOW CODE.

I2C_writeAnything(0);

what is this meant for.Whether to check rtc is sending or receiving data.I wanna check whether RTC is sending data or not .

AMPS-N don't capture threads that have nothing to do with your case. We told you in your own thread what you have to do and you haven't done yet.
If you'd have read the whole thread you found a link to the used library together with a description of how it's used.

I've tried many different delays, but they have no effect from 5 ms to 5000 ms. For some reason the serial code in setup won't run...

I know how code is uploaded to the arduino and how the DTR pin works. This is not applicable because these arduinos are running and exhibiting this problem without being hooked up to a computer, just to a 5v power source.

  Wire.beginTransmission(SLAVE_ADDRESS);
  I2C_writeAnything(0);                  //if slave receives a 0 is stops the stepper motor
  Wire.endTransmission();

...

long received_delay = 1000; //initialize with some foo foo values
...

//get the new delay time if data is send from the I2C master
void receiveEvent(int howMany)
{  
  if (howMany >= (sizeof received_delay)){
  I2C_readAnything(received_delay);
  }
}

Looks to me you are hoping to receive a long but are sending a byte. Thus the size won't match and the receiver will discard the result.

Ah, nice catch. I will test it and come back with results.