Calculate Elapse time

In below code i am trying to run motor for Every 1 min . Here i am attaching algorithm, calculation parts and code for understanding.

Question : how to run actuator exact 1 min.It should move 0.9091 mm per minute as mentioned. Let me know what mistake i done.

static float proecss_error;
static float Desired_Angle;
static float Actual_Angle;
static int Length_Min=0;
static int Length_Max=600;
signed int Degree_Min=-45;
signed int Degree_Max=45;
static float Desired_pos=0;
static float Actual_pos=0;
static float SLOPE;
static float INTERCEPT;
static int TS;
static int h;
static int m;
static float band_length=6.667;
static int hdec;
static int IN1=7;
static int DG1=6;
static int DG2=5;
static int IN2=4;
static int PWM =2;


static enum mode{
  INIT,
  TRACK,
  STOW
}MODE;


static enum dir{
  FWD,
  REV,
  STOP
}DIR;

void setupActuator(){
  pinMode(IN1,OUTPUT);
  pinMode(IN2,OUTPUT);
  pinMode(PWM,OUTPUT);
  pinMode(DG1,INPUT); 
  pinMode(DG2,INPUT);
 // moveSTOP();
}


void Move_Forward()
{
  Serial.println("Actuator DIR:FWD");
  //Serial.println(FWD);
 digitalWrite(PWM,1);
  digitalWrite(IN1,1);
  digitalWrite(IN2,0);

}


void Move_Reverse()
{
  Serial.println("Actuator DIR:REV");
 // Serial.println(REV);
  digitalWrite(PWM,1);
  digitalWrite(IN1,0);//spdt
  digitalWrite(IN2,1);//dpdt


}

void Move_Stop()

{
  Serial.println("Actuator DIR:STOP");
 // Serial.println(STOP);
  digitalWrite(PWM,0);
  digitalWrite(IN1,0);
  digitalWrite(IN2,0);

}





void setup()
{
 Serial.begin(9600); 
h=7;
m=0;
 MODE=INIT;
}

void loop()
{
  
   calc_min();
   calc_pos();
   calc_processError();
   if(h<23)
   {
  Serial.print("HH-MM: ");
 Serial.print(h);Serial.print(":");Serial.println(m);
 /*SLOPE=(Degree_Max+Degree_Min)/(Length_Max-Length_Min);
 Serial.print("slope:");
 Serial.println(SLOPE);
 INTERCEPT=(Degree_Min-(Length_Min*SLOPE));
 Serial.print("Intercept:");
 Serial.println(INTERCEPT);*/
 TS=(3600*h)+(60*m);
 if(TS>25200 && TS<64800)
 {
   callMode();MODE=TRACK;
 }else
 {
   callMode();MODE=STOW;
 }
 
 
}
 
 Serial.println("...............");
 delay(1000); 
}


void calc_pos()
{
   hdec=h+float(m/60);
   Desired_pos=hdec*0.909;
  Serial.print("Desired Pos:");
  Serial.println(Desired_pos);
  
}
void calc_processError()
{
  proecss_error=Desired_pos-Actual_pos;
  if (proecss_error>band_legth)
  {
  Actual_pos=Actual_pos+6.4;Move_Forward();
  Serial.print("Actual_pos:");
  Serial.println(Actual_pos);
  }else
  {
    Actual_pos=Actual_pos-6.4; Move_Reverse();
    Serial.print("Actual_pos:");
  Serial.println(Actual_pos);
  }
}



void calc_min()
{

if(m<60)
{
   m=m+5;
}else if(m==60)
{
  m=0;h=h+1;
}
}

void callMode(){

  switch(MODE){


  case STOW:
    Serial.println("MODE:STOW ");
    callStow();
    break;

  case TRACK:
    Serial.println("MODE:TRACK");
    callTrack();
    break;

  case INIT:
      Serial.println("MODE:INIT");
    callInit();
    break;
  }
}

void callStow()
{
 Serial.println("Stow function has called"); 
 Desired_pos=300;
 if((Desired_pos-Actual_pos)==0.0)
 {
   Move_Stop();
 }else
 {
   Move_Reverse();
 }
 //TS=(3600*h)+(60*m);
 
}

void callTrack()
{
  Serial.println("Track function has called");
  TS=(3600*h)+(60*m);
}

void callInit()
{
   Serial.println("INIT function has called");
   TS=(3600*h)+(60*m);
}

AMPS-N: In below code i am trying to run motor for Every 1 min . Here i am attaching algorithm, calculation parts and code for understanding.

Question : how to run actuator exact 1 min.It should move 0.9091 mm per minute as mentioned. Let me know what mistake i done.

Well, you have to time it. You have a variable called h, and one called m. hours and minutes? Possibly, but hard to tell. Meaningful variable names are best. Anyway, you have another variable, TS, that looks like it is calculated from h and m, but nowhere do I see anything that sets any sort of time into h and m.

What makes m increase, and how often do you think it increases? You need to use something like a real-time clock, or millis() to get any sort of meaningful increments for time variables. You call calc_min() evey time through loop(). That is going to happen VERY quickly, considering that at 16MHz an Arduino has a cycle time of 62.5 nanoseconds.

Read the Blink Without Delay sketch in the examples directory of the IDE. You can use those techniques to time any events.

lar3ry:

AMPS-N: In below code i am trying to run motor for Every 1 min . Here i am attaching algorithm, calculation parts and code for understanding.

Question : how to run actuator exact 1 min.It should move 0.9091 mm per minute as mentioned. Let me know what mistake i done.

Well, you have to time it. You have a variable called h, and one called m. hours and minutes? Possibly, but hard to tell. Meaningful variable names are best. Anyway, you have another variable, TS, that looks like it is calculated from h and m, but nowhere do I see anything that sets any sort of time into h and m.

What makes m increase, and how often do you think it increases? You need to use something like a real-time clock, or millis() to get any sort of meaningful increments for time variables. You call calc_min() evey time through loop(). That is going to happen VERY quickly, considering that at 16MHz an Arduino has a cycle time of 62.5 nanoseconds.

Read the Blink Without Delay sketch in the examples directory of the IDE. You can use those techniques to time any events.

Practically i am using Ds1307 RTC . For testing I created fake time Here So that time get incremented for Every 5 min.Yes H means hour and m means minute.TS variable used to calculate time in Seconds.

Here i am attaching The error of change in actual position and direction .

changes made here
RTC functions has been included in main

void rtcSetup(){

  Wire.begin();
}
void getRTCDateTime(){

  Wire.beginTransmission(DS1307_ADDRESS);
  Wire.write(zero);
  Wire.endTransmission();
  Wire.requestFrom(DS1307_ADDRESS, 7);

if(RTC_ERROR_FLAG==0)
{
  //Serial.println("RTC IS ACTIVE :\n");
  s = bcdToDec(Wire.read());
  m = bcdToDec(Wire.read());
  h = bcdToDec(Wire.read() & 0b111111); //24 hour time
  wkDay = bcdToDec(Wire.read()); //0-6 -> sunday - Saturday
  dd = bcdToDec(Wire.read());
  mm = bcdToDec(Wire.read());
  yy =bcdToDec(Wire.read());
  
}
}



byte decToBcd(byte val){
  // Convert normal decimal numbers to binary coded decimal
  return ( (val/10*16) + (val%10) );
}

byte bcdToDec(byte val)  {
  // Convert binary coded decimal to normal decimal numbers
  return ( (val/16*10) + (val%16) );
}

int getLastTwoDigOfYear(int y){
 return(y%1000); 
}

calculate_pos function has being changed

void calc_pos()
{
   //hdec=h+float(m/60);
   unsigned long currentMillis = millis();
   if(currentMillis - previousMillis > interval) 
   {
     previousMillis = currentMillis; 
   }else 
   hdec=(previousMillis/1000);
   Desired_pos=hdec*0.909;
  Serial.print("Desired Pos:");
  Serial.println(Desired_pos);
  
}

after 1 min.bmp (562 KB)

init _mode.bmp (523 KB)

I find your code almost impenetrable but I would be very suspicious of this  if((Desired_pos-Actual_pos)==0.0)Both the variables are floats, so the likelihood of the subtraction equalling exactly 0.0 is small, particularly when you have statements like this    Actual_pos=Actual_pos+6.4;and this    Actual_pos=Actual_pos-6.4;in the code.

UKHeliBob: I find your code almost impenetrable but I would be very suspicious of this if((Desired_pos-Actual_pos)==0.0)Both the variables are floats, so the likelihood of the subtraction equalling exactly 0.0 is small, particularly when you have statements like this   Actual_pos=Actual_pos+6.4;and this   Actual_pos=Actual_pos-6.4;in the code.

ya we can make it has +/- 1 degree. so that it goto stow position and stops.And have you found any error in actuator position image attached why it is varying?? And in program i am saying move forward and reverse. But i wanted to actuate for only 2 second

I also mistake I am doing here.

1) calculation of HDEC value calculation.Since motor runs for 1 min it has to calculate no of minutes elapsed and that has to get multiplied by 0.909 2)turn on/off of actuator.

I have lost track of what you want to do. Can you please restate it ? Something needs to happen for a minute, but what is it that you want to happen ?

AMPS-N: Question : how to run actuator exact 1 min.It should move 0.9091 mm per minute as mentioned. Let me know what mistake i done.

Note the current value of millis(). Start running the actuator.

Read the return value of millis() repeatedly. After each reading, subtract the start value to get the elapsed time. When the elapsed time exceeds 60,000 ms, stop running the actuator. The blink without delay example sketch demonstrates doing this.