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

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

сделал так - уже лучше (да... креатифчик был :))

#pragma vector = ADC_vect

__interrupt void MY_ADC (void)

{

static char t=0;

static unsigned short x1=0,x2=0,x3=0;

 

ADCrez = ADCL; ADCrez = ADCrez + (ADCH << 8);

 

if (t <= 2)

{

x1=x2;

x2=x3;

x3=ADCrez;

t++;

}

else

{

t=0;

}

ADCrez = (x1+x2+x3)/3;

k=1;

}

 

 

ADMUX = Bit(REFS0) | Bit(REFS1);

ADCSRA = Bit(ADEN) | Bit(ADIE) | Bit(ADPS2) | Bit(ADPS1) | Bit(ADPS0);

ADCSRA |= Bit(ADSC);DIDR0 |= Bit(ADC0D);

 

case 1:

ADCSRA |= Bit(ADSC);

while (k==0) {;}

Uadc = (0.1947 * (float)ADCrez) + 9.5684;

SetDataDisp (1,(unsigned short)Uadc);

k=0;

break;

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


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

Совет. Берите выборку кратную 1, 2, 4, 8 и т.д (2 в степени 0, 1,2,3...). Не будете терять точность при вычислении среднего (обойдетесь простым сдвигом на соответствующее количество разрядов).

Извините, чужие листинги читать лень (свои тоже временами). :biggrin:

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


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

ADCrez = ADCL; ADCrez = ADCrez + (ADCH << 8);

лучше записать:

ADCrez = ADCL | (ADCH << 8);

или

ADCrez = ADCL; ADCrez |= (ADCH << 8);

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


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

сделал так - уже лучше (да... креатифчик был :))

 

. . .

 

Да уж, впердолить в прерывание три лишних пересылки в статическом массиве и до кучи деление на три - это сильный креатифчик. :(

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


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

Что может быть, подскажите

на вход АЦП (через делитель) подаю напряжение, которое потом вывожу на индикаторы. использую ИОН - 1.1 V

но при выводе на индикаторы напряжение скачет (перескакивает) 11,9-12,3-11,9-12,1...

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

 

что посоветуете

С Уважением, Дмитрий.

 

 

1. Хорошим и быстрым вольтметром проверьте питание в процессе измерения. Из-за проводов питания/разводки напряжение может меняться от количества горящих сегментов индикатора. Вообще мерять питание через делитель можно, если питание ооочень стабильное.

2. Как управляются индикаторы? Портами Меги? Тогда - совсем плохо, по 5-10 мА в каждый сегмент, количество сегментов скачет, Мега дает ошибку. Если надо точно мерять - порты должны работать только на высокоомную нагрузку. Я использую для светодиодной индикации очередь сдвиговых регистров.

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


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

сделал все таки - и не скачет, и почти мгновенно

...

#pragma vector = ADC_vect __interrupt void MY_ADC (void)

{

ADCrez = ADCL; ADCrez = ADCrez + (ADCH << 8);

}

...

ADMUX = Bit(REFS0) | Bit(REFS1);

ADCSRA = Bit(ADEN) | Bit(ADIE) | Bit(ADPS2) | Bit(ADPS1) | Bit(ADPS0);

ADCSRA |= Bit(ADSC);

DIDR0 |= Bit(ADC0D);

...

(main)

...

for (;;)

{

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

{

x1=x2;

x2=x3;

x3=x4;

x4=x5;

x5=x6;

x6=x7;

x7=x8;

x8=x9;

x9=x10;

x10=ADCrez;

ADCrez = (x1+x2+x3+x4+x5+x6+x7+x8+x9+x10)/10;

Uadc = (0.1947 * (float)ADCrez) + 9.5684;

ADCSRA |= Bit(ADSC);

j++;

}

...

 

case 1: // вывод напряжения

ADCSRA |= Bit(ADSC);

j=0;

SetDataDisp (1,(unsigned short)Uadc);

break;

...

 

правда, чтобы не загружать сильно процессор надо правильней наверно так:

 

...

if (j<10)

{

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

{

x1=x2;

x2=x3;

x3=x4;

x4=x5;

x5=x6;

x6=x7;

x7=x8;

x8=x9;

x9=x10;

x10=ADCrez;

ADCrez = (x1+x2+x3+x4+x5+x6+x7+x8+x9+x10)/10;

Uadc = (0.1947 * (float)ADCrez) + 9.5684;

ADCSRA |= Bit(ADSC);

j++;

}

}

...

 

но тогда показания меняются совсем медленно, и не могу понять почему :(

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


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

 

Несколько соображений.

1. Сделайте 16 выборок и сосчитайте среднее и только потом вывод на дисплей.

2. Считать Uadc незачем каждый раз (арифметика с плавающей точкой выполняется очень медленно). Только перед выводом на дисплей.

3. Альтернативный вариант. Можно сделать циклический буфер. Причем при подсчете среднего вычитать самое последнее (заменяемое) и прибавлять последнее (которое заменяет).

4. При 16 выборках и считайте так.

ADCres=Sum>>4;

 

Это видно невооруженным глазом. :biggrin:

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


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

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

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


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

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

 

естественно так и надо

но переделывать лень для первого варианта, а подумать и программно исправить - интерес

 

Несколько соображений.

1. Сделайте 16 выборок и сосчитайте среднее и только потом вывод на дисплей.

2. Считать Uadc незачем каждый раз (арифметика с плавающей точкой выполняется очень медленно). Только перед выводом на дисплей.

3. Альтернативный вариант. Можно сделать циклический буфер. Причем при подсчете среднего вычитать самое последнее (заменяемое) и прибавлять последнее (которое заменяет).

4. При 16 выборках и считайте так.

ADCres=Sum>>4;

 

Это видно невооруженным глазом. :biggrin:

 

 

спасибо

исправлюсь :)

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


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

А лучше запитать индикаторы через один защитный диод и 7805, а контроллер через отдельный стабилизатор с делителем через отдельный диод. И землю с питанием разделить на аналоговую и цифровую.

Бесполезно - у него полный ток индикатора течет через землю МК (все аноды индикатора коммутируются портом).

Возможно поможет только повышение опорного напряжения т.к. станет больше ступенька АЦП....

 

Хотя... Вот сейчас пришла мысля - ток индикатора протекает всегда в одну сторону создавая паразитное напряжение которое не зависимо от величины ОТНИМАЕТСЯ от истинного измеряемого значения. Можно попробовать измерить несколько раз и ВЫБРАТЬ наибольшее из группы...

 

Или еще вариант - измерять при выключенных всех разрядах (при индикации сделать паузу на несколько измерений)...

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


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

Бесполезно - у него полный ток индикатора течет через землю МК (все аноды индикатора коммутируются портом).

Возможно поможет только повышение опорного напряжения т.к. станет больше ступенька АЦП....

Наврятли это реальная причина...

то есть влиять может конечно, в сумме....

просто похоже что у Автора пока еще "каша в голове" по поводу того что он хочет сделать, и как

это нужно делать...

 

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

вопросы здесь ?

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

ну а мы если что отредактируем...

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


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

Уже предложена куча полезных советов, автору нужно только их осознать и все будет ХОРОШО. :biggrin:

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


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

Наврятли это реальная причина...

то есть влиять может конечно, в сумме....

просто похоже что у Автора пока еще "каша в голове" по поводу того что он хочет сделать, и как

это нужно делать...

 

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

вопросы здесь ?

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

ну а мы если что отредактируем...

 

мне кажется, что сформулировал более, чем достаточно

 

если бы все здесь были такие как вы, то естественно, что я даже не стал регистрироваться на этом форуме

 

а вопрос был в самом начале - стояла мега8. напряжение показывалось великолепно. выпаял и поставил мегу168 (кстати поменял их 2 греша на брак) - и начались перескакивания в напряжении

укажите плз хотя бы одну причину

 

Несколько соображений.

1. Сделайте 16 выборок и сосчитайте среднее и только потом вывод на дисплей.

2. Считать Uadc незачем каждый раз (арифметика с плавающей точкой выполняется очень медленно). Только перед выводом на дисплей.

3. Альтернативный вариант. Можно сделать циклический буфер. Причем при подсчете среднего вычитать самое последнее (заменяемое) и прибавлять последнее (которое заменяет).

4. При 16 выборках и считайте так.

ADCres=Sum>>4;

 

Это видно невооруженным глазом. :biggrin:

 

Uadc у меня стояло сначала только перед выводом на дисплей. но когда я это поставил там где стоит - перескакивания исчезли полностью в купе с подсчетом среднего из 10-ти.

 

пробовал брать 16, как Вы посоветовали - чуть стало похуже.

беря последовательно среднее из от 2 до 20, лучшими стали из 10 и 11

 

спасибо

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


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

Бесполезно - у него полный ток индикатора течет через землю МК (все аноды индикатора коммутируются портом).

Возможно поможет только повышение опорного напряжения т.к. станет больше ступенька АЦП....

 

Хотя... Вот сейчас пришла мысля - ток индикатора протекает всегда в одну сторону создавая паразитное напряжение которое не зависимо от величины ОТНИМАЕТСЯ от истинного измеряемого значения. Можно попробовать измерить несколько раз и ВЫБРАТЬ наибольшее из группы...

 

Или еще вариант - измерять при выключенных всех разрядах (при индикации сделать паузу на несколько измерений)...

 

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

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


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

пробовал брать 16, как Вы посоветовали - чуть стало похуже.

беря последовательно среднее из от 2 до 20, лучшими стали из 10 и 11

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

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


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

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

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

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

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

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

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

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

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

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