1

I'm writing a code where analogRead() reads ADC value from load. After reading ADC value, if it is not in range, I need to manipulate Timer1 value. Which is also getting changed. But, after changing the Timer value, if the load value again gets restored, ADC doesn't show the same value again, but shows some other value.

Please refer below code:

#include <TimerOne.h>

int LED = 13;
int IN0 = 12;
int IN1 = 11;
int OUT1 = 10;
int OUT2 = 9;
int OUT3 = 8;
int OUT4 = 7;
//float A0;
//int OUT5 = 6;
const float refvolt = 5.0;
int volts = 0;
byte tempL_flag = 0;
float samples, loadval, avgacs, acsvaluef =0;
float refval = 2.0;
bool lflag=0;
unsigned long count = 0;

void setup()
{
    pinMode(IN0, INPUT);
    pinMode(IN1, INPUT);
    pinMode(OUT1, OUTPUT);
    pinMode(OUT2, OUTPUT);
    pinMode(OUT3, OUTPUT); 
    pinMode(OUT4, OUTPUT);
    pinMode(LED, OUTPUT);
    pinMode(A0, INPUT);
    //digitalWrite(OUT3, LOW);
    Timer1.initialize(370000);
    Serial.begin(9600);
}

word ADC_READ(byte sample, byte tim, byte CH)
{
    word adcdata;
    word avrdata;
    word abcdata;
    byte i;

    for(i=0; i<sample; i++)
    {
        adcdata = 0;
        adcdata = analogRead(CH);
        avrdata = avrdata + adcdata;
        delay(tim);
    }
    return(avrdata/sample);
}

void flash_L()
{
    digitalWrite(LED, !digitalRead(LED));
    digitalWrite(OUT4, !digitalRead(OUT4));

    if (digitalRead(OUT4)==1)
    {
        loadval = ADC_READ(10, 10, A5);
        Serial.println(loadval);

        if(loadval < refval)
        {
            Timer1.initialize(185000);
        }
        else
        {
            tempL_flag = 1;
        }
        return;
    }
}

void loop() {

    delay(2000);

    if(digitalRead(IN0)==1)
    {
        Timer1.attachInterrupt(flash_L);
    }
    else if(digitalRead(IN0)==0)
    {
        digitalWrite(LED, LOW);
        digitalWrite(OUT4, LOW);
    }
}
16
  • 1
    "If high gets to IN0, Timer will be at 370000." how? "Timer Interrupt will occur" and will do what? the function is not attached to interrupt yet.
    – Juraj
    Apr 29, 2020 at 12:39
  • 1
    IN0 is HIGH, the interrupt gets attached. at next 370000 micros multiple it fires and from then it fires always again at next 370000 or 185000 microseconds
    – Juraj
    Apr 29, 2020 at 13:49
  • 1
    do you understand that the set timer value of TimerOne is a period at which the attached function will be called repeatedly? so you want to attach the interrupt in setup() or detach it in interrupt. do you want it run repeatedly or as one shot?
    – Juraj
    Apr 29, 2020 at 15:53
  • 1
    it will run always after next period, once attached. and it will not run 300000 after you attached it. it will run 300000 micros after you initialized the period. so the logic of your sketch doesn't make sense, because you don't understand how TimerOne library works
    – Juraj
    Apr 29, 2020 at 17:13
  • 1
    pjrc.com/teensy/td_libs_TimerOne.html
    – Juraj
    Apr 29, 2020 at 17:19

1 Answer 1

1

ADC doesn't show the same value again

You are not reading the ADC correctly, so ADC_READ() can return anything. See the comments in the code:

word ADC_READ(byte sample, byte tim, byte CH)
{
    word adcdata;  // not needed
    word avrdata;  // not initialized
    word abcdata;  // not used
    byte i;
    for (i = 0; i < sample; i++)
    {
        adcdata = 0;  // useless
        adcdata = analogRead(CH);
        avrdata = avrdata + adcdata;
        delay(tim);
    }
    return (avrdata/sample);
}

The big issue is avrdata not being initialized. Its initial value is whatever was left there (in the stack or some CPU registers) by the code that ran before. The value returned by the function is then hard to predict and depends on what the rest of the program is doing.

The other remarks I left in the comments are not that problematic, although they are revealing of some lack of attention to detail. Same for some badly named variables. Here is how I would implement this function:

word ADC_READ(byte samples, byte time, byte channel)
{
    word sum = 0;
    for (int i = 0; i < samples; i++)
    {
        sum += analogRead(channel);
        delay(time);
    }
    return sum/samples;
}
4
  • Sir, I will try you suggestion. thank you Apr 29, 2020 at 14:47
  • its not working sir, I tried your code. I think its having problem with timer and ADC function jumping back to 370000 from 185000 Apr 29, 2020 at 15:06
  • 1
    @HrishikeshDixit: I am not addressing the timer issue. I am just showing you how to correctly average ADC readings, which the program you posted doesn't do. Apr 29, 2020 at 15:18
  • 1
    Sir, thanks for the suggestion, it did save variable and some lines of code. Thank you! Apr 30, 2020 at 6:50

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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