-2

I have two problems in the code below. This ACS712 sensor is too noisy so I am not getting the count value properly, since I need approximate reading I consider curve is linear, and calculate the slope.

My problems are:

  1. When I take a 10 sample average, the first value it reads properly, i.e. 512 is count value, other value taking as 0. I don't why.

  2. Once current exceeds 1A, my relay output should go low. Once it goes low it waits for 30s & again it must high the relay high. Since I am checking output in loop, it making high & low without waiting for 30s. Can someone help me how can I do this?

If you used without MStimer, the newaverage values print 512 which is my reference, but for other 9 values print newaverage as zero.

#include <MsTimer2.h>

#define RELAY1  3
#define RELAY2  4

int num_readings=10;
//int total;
int readings[10];
int index;
float CS_Value;
static float Output_Current;
float mad;
float madstd;
float lowlimit ;
float highlimit;
int count;
int total;  
int reading;  
static int newaverage;
unsigned long Wait_Time=30000;
unsigned long Current_Time;
static int Tripped_Flag=0;


float standard_deviation(int avg1) {
  total = 0;
  for( int i=0; i<num_readings; i++)
    total = total + pow((avg1 -readings[i]), 2);
  return sqrt(total/num_readings);
}

int  average() 
{
  total = 0;
  for( int i=0; i<num_readings; i++)
  {
    total = total + readings[i];
  }
  return total/num_readings;
}

void TakeReading()
{

  reading = analogRead(A0);
  readings[index] = reading;
  index = index + 1; 

  if (index >= num_readings)
  {
    index=0;
    int avg = average();
    float std = standard_deviation(avg);
    madstd = mad * std;
    lowlimit = avg - madstd;
    highlimit = avg + madstd;


    total=0;
    count=0;
    for(int i=0; i<num_readings; i++) {
      // Check if the values of the readings are within the limits.
      if(readings[i] >= lowlimit && readings[i] <= highlimit) {
        total = total + readings[i];
        count = count + 1;
      }

    }

    // compute the new average
    newaverage = total/count;
    // send it to the serial port (as ASCII digits)

    Serial.print("Newaverage:");
    Serial.println(newaverage, DEC);
    Output_Current = 0.0336666666667*newaverage - 17.17; 
    //return(Output_Current);
  }

}

void setup() {
  // sets the serial port to 9600
  Serial.begin(9600);
  pinMode(RELAY1, OUTPUT);
  pinMode(RELAY2, OUTPUT);
  Relay_Intialize();


}

void loop()
{
  MsTimer2::set(50, TakeReading); // 500ms period
  MsTimer2::start();
  //  CS_Value=  TakeReading();
  Serial.print("current is :");
  Serial.println(Output_Current);
  //if (CS_Value>0.95 && Tripped_Flag==0)
  if (Output_Current>0.95 && Tripped_Flag==0)
  {
    Serial.println("Main Activate");
    Serial.print("Tripped_Flag_status:");
    Serial.println(Tripped_Flag);
    Relay_Activate();


  }
  else
  {

    Serial.println("Main Deactivate");
    Serial.print("Tripped_Flag_status:");
    Serial.println(Tripped_Flag);
    Relay_Deactivate();
  }
  Serial.println(",,,,,,,,,,,,,,,,,,,,,,,,,,,,,");
  delay(1000);

}


void Relay_Activate()
{
  for (unsigned long start = millis(); millis() - start < 10000;)
  {
    digitalWrite(RELAY1,LOW);
    digitalWrite(RELAY2,LOW);
    Serial.println("RELAY GOT TRIPPED");
    Tripped_Flag=1;
  }

}

void  Relay_Deactivate()
{
  digitalWrite(RELAY1,HIGH);
  digitalWrite(RELAY2,HIGH);
  Serial.println("RELAY NOT TRIPPED");
  Tripped_Flag=0;

}

void Relay_Intialize()
{
  Serial.println("RELAY GOT INTIALISE....");
  digitalWrite(RELAY1,HIGH);
  digitalWrite(RELAY2,HIGH);
}

Data output when load connected with MS library

4
  • 1
    Please can you write 1) clearer? I can't understand.
    – Lesto
    Sep 9, 2014 at 6:53
  • @lesto which point you are not clear about.
    – AMPS
    Sep 9, 2014 at 7:04
  • 1
    " first value it reads properlyi.e 512 is count value other value taking as 0.I don't why." I cant understand what you expect andvwhatvyoubget
    – Lesto
    Sep 9, 2014 at 7:10
  • 2
    Instead of posting output screenshot, could you copy it here as a text? Screenshot is hard to read and impossible to copy.
    – Suma
    Sep 9, 2014 at 14:50

1 Answer 1

2

I didn't have a look at your item 2, but regarding item 1:

Please consider that in function TakeReading(), if the condition is never true, count is 0 when you come to newaverage = total/count;!

I don't know what the Arduino does in case 0/0, but -1 may be a proper return value.

1
  • 2
    The result of dividing by zero is undefined. It doesn't throw an exception, but will return invalid data. you need to check for and avoid dividing by zero to avoid bad data.
    – Duncan C
    Sep 9, 2014 at 14:09

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.