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

Измеритель уровня топлива

Валентиныч, ОК! Значит сегодня травлю платку :)

 

Еще вопрос по ИОН. Если верхнее плечо делителя питать от VCC и вход AREF АЦП соединить с VCC, то как я понимаю возможные скачки напряжения не будут влиять на результат АЦП?

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


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

Если верхнее плечо делителя питать от VCC и вход AREF АЦП соединить с VCC, то как я понимаю возможные скачки напряжения не будут влиять на результат АЦП?

Не стоит AREF цеплять на VCC, лучше использовать внутренний ИОН. На делитель можно подать VCC через дополнительный R, равный сопротивлению делителя. К этой же точке можно прилепить еще одну емкость - получившаяся RC цепочка не будет лишней в цепи питания делителя.

Кроме того, я бы несколько увеличил номинал R1 в Вашей схеме стабилизации питания (ом до 50-100).

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


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

спаял я платку... подключил вместо датчика в баке переменный резистор и покрутил его руками... Вроде АЦП работает-значения на индикаторе меняются (могу наблюдать значения от 0 до 99, потом старшие разряды не влазят). Не понравилось что даже при 8бит АЦП значение мл. разряда скачут +/- 2 единицы. Так и должно быть? (делитель питается от ACC? а опора используется внутренняя).

 

Валентиныч, резистор поставил 47Е.

 

Как произвести калибровку? Индикатор же у меня на 2 разряда... Пока только приходит мысль отсылать результат АЦП через УАРТ на компьютер...но как-то неохочется компьютер в гараж тащить :) Может подскажите другую реализацию? Например при нажатии кнопки записать округленное значение АЦП в епром, а потом считать все эти значение программатором? Можно такое реализовать?

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


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

Не понравилось что даже при 8бит АЦП значение мл. разряда скачут +/- 2 единицы. Так и должно быть? (делитель питается от ACC? а опора используется внутренняя).

 

При аккуратно спроектированной схеме и правильно написанной программе, у ATMega8 на столе шум 10-битного АЦП получается заметно меньше единицы младшего разряда.

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


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

меня вот такая мысль посетила... Конструктивно датчик уроня топлива есть переменный резистор на оси которого заркеплен рычаг с поплавком. Ход у оськи резистора 0-90 градусов. Бак на 38 литров. Получается что одному литру примерно соответствует 2,4 градуса поворота оси резистора. Вообще реально ли достоверно определить кол-во литров при такой характеристике датчика? Или это пустая трата времени?

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


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

Конструктивно датчик уроня топлива есть переменный резистор на оси которого заркеплен рычаг с поплавком. Ход у оськи резистора 0-90 градусов. Бак на 38 литров. Получается что одному литру примерно соответствует 2,4 градуса поворота оси резистора. Вообще реально ли достоверно определить кол-во литров при такой характеристике датчика?

Не факт, что характеристика этого потенциометра типа "А". Может быть, и скорее всего, она не линейная. Это связано с нелинейностью электромеханики штатного прибора, отображающего уровень топлива в баке.

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


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

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

 

Вот в CV хотел сделать округление рез-та АЦП...не получилось :)

Без округления вроде все адекватно, но скачет мл. разряд. С округлением вообще непонятно что показывает :( Помогите найти ошибку.

unsigned char t[10];
while (1)
      {
unsigned char out=0;
unsigned char n=0;
unsigned int sum=0;
n=0;
sum=0;
while(n<10)        
        {
        t[n]=read_adc(0); // читаем АЦП
         n++;
         }   
n=0;
while(n<10)
{
    sum+=(unsigned int)t[n];
    n++;
}
out=(unsigned char)sum/10;

        leds(out); //выводим на индикатор
        
        delay_ms(1000);   
           }

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


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

приведу ваш код, немного лучьше форматированный и с моими комментами

unsigned char t[10];
while (1)
{
    unsigned char out=0;
    unsigned char n=0;
    unsigned int sum=0;

    n=0;        // ненужно, и так 0
    sum=0;

    while(n<10) // для этих целей for боьше подходит
    {
        t[n] = read_adc(0); // читаем АЦП
        n++;
    }
    n=0;
    while(n<10) // for(n = 0; n < 10; n++)
    {
        sum+=(unsigned int)t[n]; // приведение типа ненужно, автоматически это сделают
        n++;
    }
    out=(unsigned char)sum/10; // тоже самое

    leds(out);                 //выводим на индикатор

    delay_ms(1000);            // вместо задержки моглибы еще что нибудь сделать, ну да ладно :)
                               // да и лучьше сделать задержку между read_adc()
}

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


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

ставьте фильтр активный на вход...вытянете все разряды...

вначале сигнал получите чистый...ибо будете писать писать...воевать с мельницами...если все проблемы можно решить одним операционником....возьмите даташит на AD629...там есть фильт на 10 50 100 Гц...пощитанный...вместо этого опера ставить AD820...на вход защитный стабилитрон и RC 100 R 50 pF...от ВЧ помех...вытянешь все 10 разрядов...

 

и от калибровки не уйти...однозначно...

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


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

ставьте фильтр активный на вход...вытянете все разряды...

вначале сигнал получите чистый...ибо будете писать писать...воевать с мельницами...

Вот получение чистого сигнала с потенциометра с помощью активных фильтров и хитрых операционников как раз и является войной с мельницами, а также пальбой из пушки по воробъям. Чтобы получить нормальные отсчеты с потенциометра необходимо и достаточно обеспечить хорошее питание и грамотную разводку:

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

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


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

vooon, за подправленный код спасибо. Как я понял в моем коде ошибок нет? Я вот думаю может действительно нужно делать задержки между чтением АЦП? Пойду курить даташит...

 

Massi, операционник нежелателен - места для него не хватает...да и на радиорынок ехать не хочется :)

 

Сергей Борщ,

Чтобы получить нормальные отсчеты с потенциометра необходимо и достаточно обеспечить хорошее питание и грамотную разводку

Питание пытался сделать по совету Massi. Схемка есть на предыдущей странице. Такого питания будет достаточно? Что вы имеете ввиду под грамотной разводкой?

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


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

> Не понравилось что даже при 8бит АЦП значение мл. разряда скачут +/-

> 2 единицы. Так и должно быть?

 

Ещё одна возможная причина (помимо упомянутого питания): при перемещении движка механического потенциометра из-за дребезга механики вы можете получать случайные, в том числе и краевые, значения АЦП. Наличие программного интегратора в какой-то степени спасает ситуацию, но результат интегрирования и последующего деления однозначно будет искажён этими случайными измерениями, что отразится в гулянии младших разрядов.

 

Рекомендую циклически пропускать полученные значения через фильтр "минимум/максимум", а уж только затем складывать среднее значение этого фильтра в интегратор. Для начала достаточно буфера на 3 значения и обычной пузырьковой сортировки. Если потенциометр совсем хреновый, то длину буфера можно увеличить.

 

Данный метод обработки потенциометров был использован в системе "Астролябия", изготовленного под руководством С.Борщ :)

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


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

Обвешал по питанию всё КМками и мл. разряд вроде устаканился :)

 

for(n=0;n<10;n++)
        {
        t[n]=read_adc(0); // Измерить напряжение на нулевом входе АЦП (линия РАО порта А)
        }   
for(n=0;n<10;n++)
        {
        sum+=t[n];
        }
out=sum/10; //среднее <--
leds(out);
delay_ms(1000);

 

по-моему понял почему у меня округление не работает... В out получается дробное число :) как из него получить только целую часть? :help:

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


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

out=(unsigned char)sum/10;

Так делать категорически нельзя - именно в этом ошибка. Здесь к типу unsigned char приводится только переменная sum, а не sum/10, как может показаться, то есть от накопленной суммы программа оставит младшие 8 байт, и уже их поделит на 10.

Обойдитесь корректно без деления и дробных чисел. Возьмите фильтр по 16 значениям, и вместо деления на 16 примените сдвиг вправо на 4 разряда.

sum = sum>>4;
out=(unsigned char)sum;

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

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


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

Demeny, спасибо! сделал как вы посоветовали. Теперь среднее правильно считает. Сейчас разбираюсь как выкинуть из буфера минимальные и максимальные значения...

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


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

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

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

Гость
К сожалению, ваш контент содержит запрещённые слова. Пожалуйста, отредактируйте контент, чтобы удалить выделенные ниже слова.
Ответить в этой теме...

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

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

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

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

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

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