ATmega 128 select ADC on each timer interrupt

Go To Last Post
9 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hey guys,

 

I have a ATmega 128 with some inputs like and LCD, Poti, etc. provided by my university.

 

I want to read the present data from my ADC (the ADC value can be adjusted with a poti from 0-5 volts) each time my timer interrupt accours.

 

So my code needs to do the following:

If Timer Interrupt cnt++

read present value of ADC

store in an array

show value of ADC on LCD

if TimerInterrupt cnt++

read present value of adc

store in next line of array

show new value on LCD

...... the array should store 100 values.

 

I can get no function that provides this. I can show the whole range of the adc on the screen but not one single value that is frozen since my timer hasn't counted up.

 

I would be very happy, if you could show me a way to manage this :D

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Can you provide an example of you code

We don't complete homework assignments but are more than happy to provide guidance & help you resolve your problem.

 

 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The hint here is two tasks - one to do the adc acquisition and store in an array and another to display.
How do you get 100 values? Do you have 100 inputs?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

This is some code:

actually, this is just showing the present value of the adc on my 7seg and the lcd but dow not sample them on each of the sampling "events".

THIS IS JUST PART OF THE CODE MOST VARIABLES ARE NOT SHOWN, SOME PARTS ARE ALSO NOT SHOWN!

 

void volt_disp(int array_num) //read value of adc and store in the array                           
    {
        volt_array[array_num]=getadc(0)/10;

        write_lcd_one_step(0x8D, precom);
        write_lcd_one_step(0x8F, sufcom);
        dis_7seg_num(1,volt_array[array_num]);
        dis_7seg_num(5, array_num);
    }

int main(void)

{

while(1)  //main while loop
    {
    key_value = readkey(); //wait for valid key
    if (key_value == 1)    //adjust the sample rate from 1(max)-9(min)
        i=100;
    else if (key_value ==0x02)
        i=150;
    else if (key_value ==0x03)
        i=200;
    else if (key_value ==0x04)
        i=250;
    else if (key_value ==0x05)
        i=300;
    else if (key_value ==0x06)
        i=350;
    else if (key_value ==7)
        i=400;
    else if (key_value ==0x08)
        i=450;
    else if (key_value ==9)
        i=512;
    
    newcnt = cnt/i;

    if (newcnt >= 100)
    {
    cnt=0;
    }
    if (key_value == 0x0A) //by pressing 'A' in the keypad, start sampling the ADC-value
    {
    fall = 1;
    }
    while (fall == 1)
    {
    key_value = readkey(); //wait for valid key    
    if (newcnt == 1)
    {
        volt_disp(1); //see first line
        }else if (newcnt == 2){
        volt_disp(2);
        }else if (newcnt == 3){
        volt_disp(3);
        }else if (newcnt == 4){
        volt_disp(4);
        }else if (newcnt == 5){
        volt_disp(5);
        }else if (newcnt == 6){
        volt_disp(6);
        }else if (newcnt == 7){
        volt_disp(7);
        }else if (newcnt == 8){
        volt_disp(8);
        }else if (newcnt == 9){
        volt_disp(9);
        }else if (newcnt == 10){
        volt_disp(10);
        }else if (newcnt == 11){
        volt_disp(11);
        }else if (newcnt == 12){
        volt_disp(12);
        }else if (newcnt == 13){
        volt_disp(13);
        }else if (newcnt == 14){
        volt_disp(14);
        }else if (newcnt == 15){
        volt_disp(15);
        }else if (newcnt == 16){
        volt_disp(16);
        }else if (newcnt == 17){
        volt_disp(17);
        }else if (newcnt == 18){
        volt_disp(18);
        }else if (newcnt == 19){
        volt_disp(19);
        }else if (newcnt == 20){
        {
        volt_disp(20);
        }
    }
    }
    if(key_value == 0x0B) //press B to stop sampling
    {
    fall == 0;
    dis_7seg(4,0x04);
    }
    //dis_7seg_num(5, newcnt);

        /*for(int newcnt=0; newcnt<100;)
            {
            volt_array[newcnt] = getadc(0)/10;
            dis_7seg_num(5, volt_array[newcnt]); //display value of channel 5
            }*/    
    }
}
ISR(TIMER2_COMP_vect) 
{
    cnt++;  //timer interrupt counts up
}

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I have 1023 inputs for voltage of 0-5volts. I devide it by 10 to get the 102 values.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

When you see repeated code like this:

    if (key_value == 1)    //adjust the sample rate from 1(max)-9(min)
        i=100;
    else if (key_value ==0x02)
        i=150;
    else if (key_value ==0x03)
        i=200;
    else if (key_value ==0x04)
        i=250;
    else if (key_value ==0x05)
        i=300;
    else if (key_value ==0x06)
        i=350;
    else if (key_value ==7)
        i=400;
    else if (key_value ==0x08)
        i=450;
    else if (key_value ==9)
        i=512;

it's often the case it can be simplified:

    const __flash uint16_t ivals[] = { 100, 150, 200, 250, 300, 350, 400, 450, 512 };
    i = ivals[key_value - 1];

That's especially true here:

    if (newcnt == 1)
    {
        volt_disp(1); //see first line
        }else if (newcnt == 2){
        volt_disp(2);
        }else if (newcnt == 3){
        volt_disp(3);
        }else if (newcnt == 4){
        volt_disp(4);
        }else if (newcnt == 5){
        volt_disp(5);
        }else if (newcnt == 6){
        volt_disp(6);
        }else if (newcnt == 7){
        volt_disp(7);
        }else if (newcnt == 8){
        volt_disp(8);
        }else if (newcnt == 9){
        volt_disp(9);
        }else if (newcnt == 10){
        volt_disp(10);
        }else if (newcnt == 11){
        volt_disp(11);
        }else if (newcnt == 12){
        volt_disp(12);
        }else if (newcnt == 13){
        volt_disp(13);
        }else if (newcnt == 14){
        volt_disp(14);
        }else if (newcnt == 15){
        volt_disp(15);
        }else if (newcnt == 16){
        volt_disp(16);
        }else if (newcnt == 17){
        volt_disp(17);
        }else if (newcnt == 18){
        volt_disp(18);
        }else if (newcnt == 19){
        volt_disp(19);
        }else if (newcnt == 20){
        {
        volt_disp(20);
        }
    }

which becomes:

volt_disp(newcnt);

As I said in our email exchange you should DESIGN your solution first before writing C code. Just jot down the general steps you think you need then later convert each in to a few lines of C. Don't just sit in front of your C editor and type in bits as they occur to you. It will lead to a very confused design.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

@ clawson

 

Yes, I wrote down my steps (at least how I think it should work), but like a kid trying to walk, you need to know how you step up, move the foot right and balance before u have an idea of the way to go. Same goes to me, I need to find the ways to convert what i wrote down. 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

@ clawson:

 

thanks for these helping hands, but why did u use const __flash? I can find that eather const or flash is used if one want to access the FLASH memory.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

As that table of numbers is unlikely to change while the program is actually running there is no point in wasting precious RAM to hold them. That is why I used "__flash". A requirement of __flash (which kind of makes sense when you think about it) is that the data is also marked as "const" meaning it is "constant and cannot be written to". const serves two purposes.

 

1) If I later inadvertently had code such as:

ivals[2] = 123;

The compiler would say "hey, you can't do that, you already told me that ivals[] was const so you aren't allowed to write to it"

 

2) It is useful for the compiler to know that these are "read only" values. It can help it in the way it organizes and sequences the code if it knows there is no possibility that it will ever need to write back to the data (or contemplate the fact that code elsewhere might have done so).

 

Putting stuff in flash used to be quite cumbersome in GCC (PROGMEM then pgm_read_something() to access it). But now GCC has the very easy to use __flash you should always consider whether some data you are about to create in your program is a candidate to be held in flash alone (so no wastage of RAM). Apply __flash when you can and, as I say, a requirement of using __flash is that the data must also be defined with the "const" modifier too.