I am new to arduino and I am developing a project so need help.

so this is basically how the project works. i need to calculate the time between the square wave pulses, which i supply to two different pins. i am going to use a interrupt based approach. where i have used millis(), now i know millis() wont count when in ISR, but that is not gonna make much difference as my ISR is very small. Also the code is little complex as first it must start the time when interrupt is from volt. so i have used a variable selc. so my problem is that i right now dont have an arduino board so cant test it out. i have tried online arduino simulation site 123d.circuits.io where i have tried a lot but interrupt based programs don't work. so is there any problem in the code please help out. thank you.. (i have searched a lot of forums and this type of approach has not been discussed. so will this work? any better option.?)

  • fellow learner.
#include <Math.h>
#include <LiquidCrystal.h>
const int Button1 = 6;
const int Button2 =7;
const int Output = 8;
const int Output2 = 9;
int volt = 0;
int current = 0;
int selc = 0;
int looper = 0;
double degree;
double display;
double radi;
long time;
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

void start()
{
   volt=1;
   current=1;
}
void stop()
{
   current=1;
}

void setup()
{
   pinMode(Button1,INPUT);
   pinMode(Button2,INPUT);
   attachInterrupt(Button1,start, RISING);
   attachInterrupt(Button2,stop, RISING);
   lcd.begin(16, 2);
   lcd.clear();
   lcd.setCursor(0,0);
   lcd.print("Power Factor");
}

void loop()
{
   interrupts();              //enable interrupt
if(volt == 1)
  {
    time == millis();
    volt = 0; 
    selc = 1;
  }

if( ( current == 1 ) && ( selc == 1 ) )
  {
    time=millis()-time;
    current = 0;
    selc = 0;
    looper = 1;
  }
if(looper == 1)
  {
    noInterrupts();
    degree = time*18.0;
    radi = degree*0.017445;
    display = cos(radi);
    lcd.setCursor(0,1);
    lcd.print("        ");
    lcd.setCursor(0,1);
    lcd.print(time);
    delay(2000);
    looper = 0;
  }
if( display<0.80 )
  {
    digitalWrite(Output,HIGH);
  }
if(display<0.60)
  {
    digitalWrite(Output2,HIGH);
   }
}

pfactor.ino (1.2 KB)

Did you forget some "volatile"s?

BTW, your shift key appears to be broken.

Weedpharma

AnkushSharma:
so this is basically how the project works. i need to calculate the time between the square wave pulses, which i supply to two different pins. i am going to use a interrupt based approach.

That is NOT a description of "how the project works". It tells us nothing about your project. All it tells us is that, for some reason, you believe calculating the time between square wave pulses is necessary.

In addition it does not even tell us anything about the square waves - what produces them, what is their frequency, are there regular intervals between them?

...R

made minor changes.. i know it might have some syntax bugs, but will the logic with interrupt work?

Robin2- thanks, here is the explaination
okay.. the freq of the square waves is 50 Hz.. that is the time between the two interrupts can be as low as 1 ms (if power factor is good). the square waves will be generated by a zero-crossing detector(made with op amp.) and the amplitude of the square wave can be controlled( i have chosen 5 v). both the waves are voltage waves (current wave is transformed into volt wave).

now if i have time between the two pulses, i can calculate the phase angle..(50 hz is 20 ms, and hence, 20 ms is 360 degree.) so phase is (time*360)/20. i take the cos of the phase after converting it into radians. and then display. if the value of the final answer is less then it has to send the output.

#include <Math.h>
#include <LiquidCrystal.h>
const int Button1 = 6;
const int Button2 =7;
const int Op = 8;
const int Op2 = 9;
volatile int volt = 0;          //incremented when interrupt occurs from voltage wave
volatile int current = 0;     //incremented when interrupt occurs from current wave
volatile int selc = 0;          //incremented only when interrupt occurs from voltage wave
int looper = 0;
double degree;
double display;
double radi;
long time;
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

void start()
{
   volt=1;
   current=0;
}
void stop()
{
   current=1;
}

void setup()
{
   pinMode(Button1,INPUT);
   pinMode(Button2,INPUT);
   pinMode(Op,OUTPUT);
   pinMode(Op2,OUTPUT);
   attachInterrupt(Button1,start, RISING);
   attachInterrupt(Button2,stop, RISING);
   lcd.begin(16, 2);
   lcd.clear();
   lcd.setCursor(0,0);
   lcd.print("Power Factor");
}

void loop()
{
   interrupts();              //enable interrupt
if(volt == 1)
  {
    time == millis();
    volt = 0; 
    selc = 1;
  }

if( ( current == 1 ) && ( selc == 1 ) )
  {
    time=millis()-time;
    current = 0;
    selc = 0;
    looper = 1;
  }
if(looper == 1)           //looper is used so as the program enter to display only after calculating time
  {
    noInterrupts();
    degree = time*18.0;
    radi = degree*0.017445;
    display = cos(radi);
    lcd.setCursor(0,1);
    lcd.print("        ");
    lcd.setCursor(0,1);
    lcd.print(display);
    delay(2000);
    looper = 0;
  }
if( display<0.80 )
  {
    digitalWrite(Op,HIGH);
  }
if(display<0.60)
  {
    digitalWrite(Op2,HIGH);
   }
}

AnkushSharma:
okay.. the freq of the square waves is 50 Hz.. that is the time between the two interrupts can be as low as 1 ms (if power factor is good). the square waves will be generated by a zero-crossing detector

That sounds as if your project is trying to meaure the phase angle of 50Hz ac power supply (or something like that). Why not just say what it is - and why? It's hardly a big secret is it?

I can't relate 50Hz with 1 millisec between interrupts.

It also sounds as if you are trying to measure small variations in the frequency. What is the range of variation? What is causing the variation? How does the frequency vary - is is a slow cyclical variation or is it completely random from cycle to cycle?

If you provide a simple explanation / overview of the project all this might be obvious.

...R