Перейти к содержанию
    

mega168 - скачет напряжение с АЦП

Попробуйте 32. Сдвиг удобный >>5.

попробовал

результат стал стоять мертво, но если опять же Uadc ставить перед выводом на дисплей - опять перескакивает 12,9-13,2 ...

 

спасибо

 

результат стал стоять мертво (поторопился, извините - не лучше чем 11)

вот

Изменено пользователем kd_Rash

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Выключайте индикатор на время оцифровки, чтобы не текли токи индикатора по аналоговой земле. А то происходит как бы самовозбуждение от индикатора на АЦП. Ну или опорное напряжение АЦП должно прыгать в такт с измеряемым. В общем говно вопрос - надо аналоговую землю отделять от цифровой.

Изменено пользователем Maik-vs

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

ну да ладно

всем спасибо

зато вопрос знаю теперь чуть лучше, любой опыт не лишний

 

Удачи, Дмитрий.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Рекомедую, просмотреть этот топик сначала и проанализировать все с позиций знаний, полученных в процессе. Это поможет в дальнейшем, чтобы не было сказки про белого бычка. :biggrin:

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Всё таки добил - работает теперь луше чем было раньше!

 

 

for (;;)

{

//----------------

if (timer_count_a > 11)

{

if (ADCSRA & Bit(ADIF) != 0)

{

x1=x2;

x2=x3;

x3=x4;

x4=x5;

x5=x6;

x6=x7;

x7=x8;

x8=x9;

x9=x10;

x10=x11;

x11=x12;

x12=x13;

x13=x14;

x14=x15;

x15=x16;

x16=ADCrez;

ADCSRA |= Bit(ADSC);

}

timer_count_a=0;

}

...

...

...

 

if (timer_count > 180) // 0.5 сек.

{

 

switch (g_Uset)

{

case 1: ADCSRA |= Bit(ADSC); // вывод напряжения

ADCcp = (x1+x2+x3+x4+x5+x6+x7+x8+x9+x10+x11+x12+x13+x14+x15+x16) >> 4;

Uadc = (0.1929 * (float)ADCcp) + 13;

SetDataDisp (1,(unsigned short)Uadc);

break;

 

 

...

...

...

 

 

}

timer_count=0;

}

timer_count++; timer_count_a++;

...

 

 

Удачи, Дмитрий.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Почему бы вам не сделать цикличский буффер?

 

WORD awAdcBuff[16];

WORD wAdcResult;

 

WORD* pAdcBuff = awAdcBuff;

 

И в прерывании:

 

*pAdcBuff = ADC;

pAdcBuff++;

if(pAdcBuff == (awAdcBuff+16)) pAdcBuff = awAdcBuff;

 

wAdcResult = 0;

for(BYTE i=0; i<16; i++){

wAdcResult += awAdcBuff;

}

wAdcResult = wAdcResult/16; //

 

Как то поприятнее выглядит.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Почему бы вам не сделать цикличский буффер?

 

:)

потому что знал, что так можно,

но как - не знал ... до этого момента

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

потому что знал, что так можно,

но как - не знал ... до этого момента

Тогда вот вам еще в копилку - чтобы не высчитывать каждый раз сумму по всему буферу, ее можно считать при занесении значения в буфер:
WORD wAdcSum;
    wAdcSum -= *pAdcBuff
    wAdcSum += (*pAdcBuff = ADC);
    pAdcBuff++;
    if(pAdcBuff == (awAdcBuff + 16))
        pAdcBuff = awAdcBuff;

// там, где нужен результат:
wAdcResult = wAdcSum / 16;

А еще можно заменить константу 16 на (sizeof(awAdcBuff) / sizeof(awAdcBuff[0])) - это позволит задавать размер буфера только в одном месте - при объявлении. А еще - можно этот sizeof() обернуть в удобный макрос:

#define  ELEMENTS(Array)   (sizeof(Array) / sizeof(Array[0]))
WORD awAdcBuff[16];
WORD wAdcResult;
WORD wAdcSum;
WORD* pAdcBuff = awAdcBuff;

    wAdcSum -= *pAdcBuff
    wAdcSum += (*pAdcBuff = ADC);
    pAdcBuff++;
    if(pAdcBuff == (awAdcBuff + ELEMENTS(awAdcBuff) ))
        pAdcBuff = awAdcBuff;

// там, где нужен результат:
wAdcResult = wAdcSum / ELEMENTS(awAdcBuff);

так будет совсем красиво.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А еще можно не заносить значение в буфер, а только считать сумму.

А на 16 раз среднее,

обнулять сумму.

А еще можно не проверять счетчик, а делать так

Счетчик &=0xf;

PS. Всегда найдется дело для умелых рук. :)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

ну, спасибо, всем!

Интересная тема. Расскажу про свой опыт измерений. Я работал только с мега8 и мега16. При измерении сигнала от тензодатчика (0-18мВ) стоял инструментальный усилитель AD620 (дорогой собака - 10$) с коеф.ус.275 и с него на АЦП. В итоге на выходе (рисовал график на компе) получил все наводки - и помехи от силовой аппаратуры (модуляция 8кгц) и синфазные (50гц) на уровне до 10% от максимума (может, конечно, можно было увеличить RC фильтр, но я не стал). Частота контроллера 8мгц, предделитель ацп 128 (максимальный), ацп считает за 13 тактов (по даташиту), в итоге получается около 4800 результатов в секунду (мне необходимо было не меньше 2). В итоге я усреднял каждые 2500 результатов и получил почти идеально гладкий график.

 

С наводками мне очень сложно бороться, какой бы фильтр не ставил, как бы подальше от силовых проводов не отводил, всеравно прыгает результат довольно значительно.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

В итоге я усреднял каждые 2500 результатов и получил почти идеально гладкий график.

sqrt(2500)=50

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...