|
|
  |
Измеритель уровня топлива, Первый проект на AVR |
|
|
|
Mar 20 2007, 17:55
|
Профессионал
   
Группа: Свой
Сообщений: 553
Регистрация: 17-02-05
Из: Свердловская обл.
Пользователь №: 2 712

|
Цитата(alex2103 @ Mar 20 2007, 19:36)  Если верхнее плечо делителя питать от VCC и вход AREF АЦП соединить с VCC, то как я понимаю возможные скачки напряжения не будут влиять на результат АЦП? Не стоит AREF цеплять на VCC, лучше использовать внутренний ИОН. На делитель можно подать VCC через дополнительный R, равный сопротивлению делителя. К этой же точке можно прилепить еще одну емкость - получившаяся RC цепочка не будет лишней в цепи питания делителя. Кроме того, я бы несколько увеличил номинал R1 в Вашей схеме стабилизации питания (ом до 50-100).
--------------------
Закономерность: Чем больше узнаю, тем меньше знаю... Любые мнения, даже ошибочные, имеют право на существование. Чем лучше узнаю людей, тем больше нравятся собаки...
|
|
|
|
|
Mar 22 2007, 23:03
|
Частый гость
 
Группа: Свой
Сообщений: 135
Регистрация: 7-03-07
Из: г. Запорожье
Пользователь №: 25 945

|
спаял я платку... подключил вместо датчика в баке переменный резистор и покрутил его руками... Вроде АЦП работает-значения на индикаторе меняются (могу наблюдать значения от 0 до 99, потом старшие разряды не влазят). Не понравилось что даже при 8бит АЦП значение мл. разряда скачут +/- 2 единицы. Так и должно быть? (делитель питается от ACC? а опора используется внутренняя). Валентиныч, резистор поставил 47Е. Как произвести калибровку? Индикатор же у меня на 2 разряда... Пока только приходит мысль отсылать результат АЦП через УАРТ на компьютер...но как-то неохочется компьютер в гараж тащить  Может подскажите другую реализацию? Например при нажатии кнопки записать округленное значение АЦП в епром, а потом считать все эти значение программатором? Можно такое реализовать?
|
|
|
|
|
Mar 23 2007, 16:35
|
Профессионал
   
Группа: Свой
Сообщений: 553
Регистрация: 17-02-05
Из: Свердловская обл.
Пользователь №: 2 712

|
Цитата(alex2103 @ Mar 23 2007, 17:32)  Конструктивно датчик уроня топлива есть переменный резистор на оси которого заркеплен рычаг с поплавком. Ход у оськи резистора 0-90 градусов. Бак на 38 литров. Получается что одному литру примерно соответствует 2,4 градуса поворота оси резистора. Вообще реально ли достоверно определить кол-во литров при такой характеристике датчика? Не факт, что характеристика этого потенциометра типа "А". Может быть, и скорее всего, она не линейная. Это связано с нелинейностью электромеханики штатного прибора, отображающего уровень топлива в баке.
--------------------
Закономерность: Чем больше узнаю, тем меньше знаю... Любые мнения, даже ошибочные, имеют право на существование. Чем лучше узнаю людей, тем больше нравятся собаки...
|
|
|
|
|
Mar 23 2007, 17:33
|
Частый гость
 
Группа: Свой
Сообщений: 135
Регистрация: 7-03-07
Из: г. Запорожье
Пользователь №: 25 945

|
Валентиныч, изначально в баке был проволочный резистор наверное с логарифмической характеристикой, но я туда приспособлю обычный переменник, т.к. заводского резистора хватает максимум на пару месяцев...потом он рассыпается, витки сползают и т.п. Вот в 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); }
|
|
|
|
|
Mar 24 2007, 00:24
|

Участник

Группа: Свой
Сообщений: 72
Регистрация: 27-06-06
Из: Msk
Пользователь №: 18 401

|
приведу ваш код, немного лучьше форматированный и с моими комментами Код 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() }
|
|
|
|
|
Mar 24 2007, 12:04
|

Гуру
     
Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095

|
Цитата(Massi @ Mar 24 2007, 09:21)  ставьте фильтр активный на вход...вытянете все разряды... вначале сигнал получите чистый...ибо будете писать писать...воевать с мельницами... Вот получение чистого сигнала с потенциометра с помощью активных фильтров и хитрых операционников как раз и является войной с мельницами, а также пальбой из пушки по воробъям. Чтобы получить нормальные отсчеты с потенциометра необходимо и достаточно обеспечить хорошее питание и грамотную разводку: Цитата спаял я платку... подключил вместо датчика в баке переменный резистор и покрутил его руками...
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Mar 25 2007, 17:26
|
Частый гость
 
Группа: Свой
Сообщений: 135
Регистрация: 7-03-07
Из: г. Запорожье
Пользователь №: 25 945

|
vooon, за подправленный код спасибо. Как я понял в моем коде ошибок нет? Я вот думаю может действительно нужно делать задержки между чтением АЦП? Пойду курить даташит... Massi, операционник нежелателен - места для него не хватает...да и на радиорынок ехать не хочется  Сергей Борщ, Цитата Чтобы получить нормальные отсчеты с потенциометра необходимо и достаточно обеспечить хорошее питание и грамотную разводку Питание пытался сделать по совету Massi. Схемка есть на предыдущей странице. Такого питания будет достаточно? Что вы имеете ввиду под грамотной разводкой?
|
|
|
|
|
Mar 26 2007, 04:22
|
Участник

Группа: Новичок
Сообщений: 29
Регистрация: 16-03-07
Из: МО, г.Балашиха
Пользователь №: 26 210

|
> Не понравилось что даже при 8бит АЦП значение мл. разряда скачут +/- > 2 единицы. Так и должно быть? Ещё одна возможная причина (помимо упомянутого питания): при перемещении движка механического потенциометра из-за дребезга механики вы можете получать случайные, в том числе и краевые, значения АЦП. Наличие программного интегратора в какой-то степени спасает ситуацию, но результат интегрирования и последующего деления однозначно будет искажён этими случайными измерениями, что отразится в гулянии младших разрядов. Рекомендую циклически пропускать полученные значения через фильтр "минимум/максимум", а уж только затем складывать среднее значение этого фильтра в интегратор. Для начала достаточно буфера на 3 значения и обычной пузырьковой сортировки. Если потенциометр совсем хреновый, то длину буфера можно увеличить. Данный метод обработки потенциометров был использован в системе "Астролябия", изготовленного под руководством С.Борщ
|
|
|
|
|
Mar 26 2007, 08:39
|
Частый гость
 
Группа: Свой
Сообщений: 135
Регистрация: 7-03-07
Из: г. Запорожье
Пользователь №: 25 945

|
Обвешал по питанию всё КМками и мл. разряд вроде устаканился  Код 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 получается дробное число  как из него получить только целую часть?
|
|
|
|
|
Mar 26 2007, 08:59
|

Знающий
   
Группа: Свой
Сообщений: 648
Регистрация: 11-02-06
Из: Санкт-Петербург
Пользователь №: 14 237

|
Код out=(unsigned char)sum/10; Так делать категорически нельзя - именно в этом ошибка. Здесь к типу unsigned char приводится только переменная sum, а не sum/10, как может показаться, то есть от накопленной суммы программа оставит младшие 8 байт, и уже их поделит на 10. Обойдитесь корректно без деления и дробных чисел. Возьмите фильтр по 16 значениям, и вместо деления на 16 примените сдвиг вправо на 4 разряда. Код sum = sum>>4; out=(unsigned char)sum; Ну и таймаут между чтениями АЦП сделать обязательно, и анализ считанного значения на диапазон, как советовали выше, просто необходимо.
--------------------
Сделано в Китае. Упаковано в России.
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|