Clock Stretching

Hi

How do I implement clock stretching in arduino Mega 2560?

Do I write the code as

while (   )
 {digitalWrite(21,LOW);    // SCL pin
}
digitalWrite(21,HIGH) ;

"while" what exactly?

What are you trying to do?

Hi

I have a master which gives a command to the slave to make the stepper motor run .
The master requests the slave if the stepper motor has finished running .
I want the slave to respond back to the master only after the stepper motor has finished running .

Here is my program . Please tell me what to change or add .. since I am unaware of clock stretching .
My stepper motor gets stuck when a request to the slave is made

MASTER

// I2C 1 master  1 slaves

// given adressess as 4 for slave 1 
//                    

#include <Wire.h>


#include <AccelStepper.h>

int incomingByte = 0;
long millisec = 0;



void setup()
{
   Wire.begin();
   //Start Serial for debuging purposes	
  Serial.begin(115200); // USB comm with PC
  
  delay(100);
  
  spam();
}



void spam() {
  Serial.println("--------------------");
  
  Serial.println("1: Stepper1 FORWARD");

  
  
}


void loop()
{
  
   
    if (Serial.available() > 0) {
        incomingByte = Serial.read()-48;
        Serial.print("  Selection:");Serial.println(incomingByte);
         
        switch(incomingByte) {
          case 1:  Serial.println("Stepper1: forward"); 
                   Wire.beginTransmission(4);
                   Wire.send(1);
                   Wire.endTransmission(); 
                    
                   Serial.println("Waiting for Stepper motor1 to complete");
                   delay(100);                                         
                   Wire.requestFrom(4,15);
                   while(Wire.available())
                   {  
                      char c = Wire.receive();
                      Serial.print(c);
                    }
                  
                   break;
        
          default: spam(); 
                   break;
                  
        } // switch case loop
    }   //serial available loop
     
}       // void loop

SLAVE

// I2C communication  1 Master- 1 Slave 

// program for slave 4



#include <Wire.h>

#include <AccelStepper.h>

int incomingByte = 0;


// timer variables
long millisec = 0;
long microsec = 0;



// stepper motor pins: STEP, DIRECTION, STEPPER ON/OFF
AccelStepper Stepper1(1,2,3);



void setup() {
  
  Wire.begin(4);
  Wire.onReceive(receiveEvent);
  Wire.onRequest(requestEvent);

  
    
 //Start Serial for debuging purposes	
  Serial.begin(115200); // USB comm with PC

for(int i = 0;i <54;i++) {
    pinMode(i,OUTPUT);
    digitalWrite(i,LOW);
  }

// switch stepper chips off 
  digitalWrite(4,HIGH);

Stepper1.setMaxSpeed(1000);

}


void receiveEvent(int howMany)
{
     if (Wire.available() > 0) {
     incomingByte = Wire.receive();
     }

}  
      
//
void requestEvent()
{ 
   while(Stepper1.currentPosition() != Stepper1.targetPosition())     
   { digitalWrite(20,HIGH);                        // SDA line 
     digitalWrite(21,LOW);                          //SCL line
     
   }
   
   
   if(Stepper1.currentPosition() >= Stepper1.targetPosition())
    {digitalWrite(21,HIGH);
    Wire.send("Action complete");
    }
    else
    Wire.send("Didnotcomplete");
   
   
   digitalWrite(4,HIGH);

}


  


void loop()
{ 
   
   Stepper1.run();
  
//   while(Stepper1.run())                                                  // to check the current position of the motor
//   {Serial.println(Stepper1.currentPosition());
//   }

   
  

    //Serial.print("  Selection:");Serial.println(incomingByte);
    switch(incomingByte) {
      case 1: digitalWrite(4,LOW); digitalWrite(3,HIGH); digitalWrite(2,HIGH); //Serial.println("Stepper1: forward"); 
              
              Serial.println("forward");
              Stepper1.setCurrentPosition(0);
              Stepper1.setAcceleration(500.0);
              Stepper1.moveTo(4000); 
              
              break;
         }
     // switch loop
     incomingByte = 0;   
} // main loop

"incomingByte" (of the slave) has to be declared "volatile" because it's modified in an interrupt routine. If you don't declare it that way the compiler might optimise it away.

What the meaning of this code part?

   while(Stepper1.currentPosition() != Stepper1.targetPosition())     
   { digitalWrite(20,HIGH);                        // SDA line 
     digitalWrite(21,LOW);                          //SCL line
     
   }

You're using the Wire library but setting some I2C pins directly? The slave is not allowed to change the SCL wire itself. The master is clocking.

I guess you have to explain what you wanna do, what clock stretching means.

Hi

You're using the Wire library but setting some I2C pins directly? The slave is not allowed to change the SCL wire itself. The master is clocking.

I guess you have to explain what you wanna do, what clock stretching means.

While my stepper motor is running , I give a request from the master to ask the slave to respond when the task is over .
So , while the request is send , the motor is still running . I would like the slave to hold/slow the clock line as the motor has not completed running . (So I gave pin 21 as LOW )
And then when it has finished running , the slave makes it HIGH , to transfer the data.

Is the way have implemented wrong ?

I think you are going to have to rethink your design. Your master is going to have to ask the slave "Are you done yet?" not "Tell me when you are done". The master may have to ask the slave a million times, before it gets a "Yes, I'm done" answer.

Hi

Paul : Thanks ... I understand what you are trying to say . I will redesign it accordingly.

@Pylon & AWOL : Many thanks for the input .