|
Измеритель уровня топлива, Первый проект на AVR |
|
|
|
Mar 16 2007, 22:33
|
Частый гость
 
Группа: Свой
Сообщений: 135
Регистрация: 7-03-07
Из: г. Запорожье
Пользователь №: 25 945

|
Очень хочется разобраться в МК... Для этого был куплен ATmega8 и поставлена перед собой задача собрать устройство контроля уровня бензина в баке.  В баке стоит переменный резистор с поплавком, диапазон примерно 0-60 Ом. Зависимость сопротивление/литры неизвестна К МК подключен сдвоенный семисегментный индикатор от старого системного блока (показывал раньше крутые мегагерцы). У этого индикатора выводы общих анодов запараллелены...из-за этого динамической индикации не получилось и индикатор занимает 14 ног Устройство должно мереть падение напряжения на резисторе в баке и выводить результат в литрах на индикатор. Сам пока написал функцию для вывода числа 0-99 на индикатор. Подскажите пожалуйста: 1) как организовать подключение резистора к АЦП (с учетом того, что резистор в баке и токи там должны быть маленькие) 2) как интерпретировать значение АЦП с учетом нелинейности сопротивление/литры? Спасибо. З.Ы.:не пинайте сильно...это мой первый опыт работы с МК.
|
|
|
|
|
 |
Ответов
(1 - 69)
|
Mar 18 2007, 18:23
|
Частый гость
 
Группа: Свой
Сообщений: 135
Регистрация: 7-03-07
Из: г. Запорожье
Пользователь №: 25 945

|
Massi, калибровку так себе и представлял. Бак всего 38 литров и заливать буду по литру и снимать значения. В итоге получу некую таблицу соответствия результата АЦП и литров. Как потом в проге реализовать эту таблицу? неужели через IF...  Хотелось бы чтоб на индикатор выводилась челая часть литров, а дробная с округлением до 0,5 литра обозначалась запятой. Можно где-нибудь посмотреть на примеры? Насчет токов в баке: В заводской системе они там нехилые. В цепи резистора там бывает до 0,1А и еще есть контакт, который моммутирует лампу на 2Вт (замыкается если меньше 5 литров). Ничего не взрывается (да и взрываться там ИМХО нечему-это отдельный разговор). Насчет опорного. Нужна ли в такой задаче высокая точность? Что получится если использовать Uпит.? Прочитав про фильтрацию питания стало страшно  Вот сейчас на столе лежит автомобильный тахометр/вольтметр и т.д. и питание там на 7805 в стандартной обвязке. Расчитывал сделать также. Это возможно? Где можно подсмотреть примеры готовых решений с питанием для авто? З.Ы.: извиняюсь что много написАл. Просто тема очень интересна для меня и многое еще непонятно. Надеюсь на помощь!
|
|
|
|
|
Mar 19 2007, 12:03
|
Частый гость
 
Группа: Свой
Сообщений: 135
Регистрация: 7-03-07
Из: г. Запорожье
Пользователь №: 25 945

|
Прогу за меня писать не надо, мне самому интересно  Просто хочется посмотреть чей-то исходник... Под тахометром я имел ввиду МК устройство (часы, будильник, тахометр и т.д.). Совет по питанию постараюсь реализовать. Но что-то мне кажется что он уж очень навороченый...у будущего устройства в принципе функция не особо ответсвенная - просто показывать сколько у меня еще в баке бензина. Что такое супресор?
Сообщение отредактировал alex2103 - Mar 19 2007, 12:25
|
|
|
|
|
Mar 19 2007, 16:55
|
Профессионал
   
Группа: Свой
Сообщений: 553
Регистрация: 17-02-05
Из: Свердловская обл.
Пользователь №: 2 712

|
Цитата(alex2103 @ Mar 19 2007, 14:03)  ...у будущего устройства в принципе функция не особо ответсвенная - просто показывать сколько у меня еще в баке бензина. Если с точностью до 0,5 литра - то, скорее всего, не получится (да и зачем?). При движении авто уровень бензина в баке непостоянен, также будут меняться и показания уровнемера. Выход - многократные измерения в течение нескольких секунд (мо-быть - десятков секунд) с последующим усреднением значений. Что касается требований по питанию, то они не так сташны, как описано выше, но проблемы, все таки, могут быть. Занимаюсь разработкой автоэлектроники много лет (на уровне "для души"), опыт использования AVR показывает, что желательно развязывать бортовую сеть и питание контроллера LC-фильтром с последующей стабилизацией параметрикой. И кренки 78хх - не лучший вариант. Предпочтительнее что-нить более интересное.
--------------------
Закономерность: Чем больше узнаю, тем меньше знаю... Любые мнения, даже ошибочные, имеют право на существование. Чем лучше узнаю людей, тем больше нравятся собаки...
|
|
|
|
|
Mar 20 2007, 09:32
|
Частый гость
 
Группа: Свой
Сообщений: 135
Регистрация: 7-03-07
Из: г. Запорожье
Пользователь №: 25 945

|
muravei, спасибо! Жаль что в сети в свободном доступе только оглавление этого журнала  Статью так и не получилось найти. У вас случаем нет ее?
|
|
|
|
|
Mar 20 2007, 13:27
|
Частый гость
 
Группа: Свой
Сообщений: 135
Регистрация: 7-03-07
Из: г. Запорожье
Пользователь №: 25 945

|
Old1, спасибо огромное, читаю... Вот так собираюсь сделать питание... Какие будут замечания?
Сообщение отредактировал alex2103 - Mar 20 2007, 13:32
Прикрепленные файлы
power.GIF ( 4.08 килобайт )
Кол-во скачиваний: 204
|
|
|
|
|
Mar 20 2007, 17:12
|
Профессионал
   
Группа: Свой
Сообщений: 553
Регистрация: 17-02-05
Из: Свердловская обл.
Пользователь №: 2 712

|
Цитата(alex2103 @ Mar 20 2007, 15:27)  Вот так собираюсь сделать питание... Какие будут замечания? Пожалуй, схема близка к оптимальной.
--------------------
Закономерность: Чем больше узнаю, тем меньше знаю... Любые мнения, даже ошибочные, имеют право на существование. Чем лучше узнаю людей, тем больше нравятся собаки...
|
|
|
|
|
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; Ну и таймаут между чтениями АЦП сделать обязательно, и анализ считанного значения на диапазон, как советовали выше, просто необходимо.
--------------------
Сделано в Китае. Упаковано в России.
|
|
|
|
|
Mar 26 2007, 09:54
|
Участник

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

|
Из буфера интегратора ничего выкидывать не надо. Фильтр мин/макс организуется дополнительно. Пример. Конечно коряво, но смысл видно: Код uint8_t i, k, temp; uint8_t filt_res[3]; uint16_t integrator;
for (i=0; i < 16; i++) { for (k=0; k < 3; k++) { filt_res[k] = read_adc(0); // читаем АЦП delay (xxx); }
// Пузырьковая сортировка if (filt_res[0] > filt_res[1]) { temp = filt_res[1]; filt_res[1] = filt_res[0]; filt_res[0] = temp; }
if (filt_res[1] > filt_res[2]) { temp = filt_res[2]; filt_res[2] = filt_res[1]; filt_res[1] = temp; }
if (filt_res[0] > filt_res[1]) { temp = filt_res[1]; filt_res[1] = filt_res[0]; filt_res[0] = temp; }
// В filt_res[1] - среднее (не путать с усреднённым) по величене значение integrator += filt_res[1]; }
temp = (uint8_t)(integrator >> 4); // В temp искомое
Сообщение отредактировал Vladimir Chekin - Mar 26 2007, 09:56
|
|
|
|
|
Mar 26 2007, 12:31
|
Частый гость
 
Группа: Свой
Сообщений: 135
Регистрация: 7-03-07
Из: г. Запорожье
Пользователь №: 25 945

|
Если резистор не трогать, то показания АЦП теперь стоят как вкопаные, но стоит его тронуть и значения начинают скакать  думаю из-за дребезга... Может просто поставить RC цепочку секунды на две? И еще остается открытым вопрос с калибровкой. Как её организовать?
|
|
|
|
|
Mar 26 2007, 13:13
|

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

|
Цитата(alex2103 @ Mar 26 2007, 13:31)  Если резистор не трогать, то показания АЦП теперь стоят как вкопаные, но стоит его тронуть и значения начинают скакать  думаю из-за дребезга... Может просто поставить RC цепочку секунды на две? Это можно сделать и программно. Программным аналогом RC-цепочки можно считать усреднение, он же фильтр низкой частоты, он же апериодическое звено первого порядка. Если постоянную времени RC-цепи принять за Т, то для аналогичного программного эффекта вам нужно усреднять все значения измерения на временном интервале примерно 3*T, то есть в вашем случае около 6 с. Чем больше показаний АЦП за этот интервал вы успеете накопить - тем точнее будет измерение. Чтобы не хранить огромный массив значений, каждый раз не считать сумму всех значений (если, допустим, вы усредняете по 1024 точкам) , ведь разрядности переменной может не хватить, есть простой программный приём. При усреднении по N точкам достаточно хранить только само СРЕДНЕЕ значение, и на каждом цикле съёма данных с АЦП к этому среднему прибавлять разницу нового и среднего, делённую на N. Код .......... Uaverage = Uaverage + (Ucurrent - Uaverage)/N .......... Если N точек у вас равномерно распределены по временному интервалу 6 секунд, вы получаете классический фильтр с постоянной времени 2 секунды. Цитата(alex2103 @ Mar 26 2007, 13:31)  И еще остается открытым вопрос с калибровкой. Как её организовать? Тоже просто. Составляем две таблицы равной длины. В одной храним показания АЦП, в другой "литры". Заполняем таблицу опытным путём - от пустого бака к полному. Дальше всё решает линейная интерполяция. Чем больше точек вы можете себе позволить хранить в программе - тем точнее будет измерение. Если же вы примените квадратичную интерполяцию - ну тогда вааще...
--------------------
Сделано в Китае. Упаковано в России.
|
|
|
|
|
Mar 27 2007, 14:30
|
Частый гость
 
Группа: Свой
Сообщений: 135
Регистрация: 7-03-07
Из: г. Запорожье
Пользователь №: 25 945

|
Цитата Составляем две таблицы равной длины. В одной храним показания АЦП, в другой "литры". Заполняем таблицу опытным путём - от пустого бака к полному. Прикрутил я к своему "девайсу" кнопочку и теперь если при включении питания удерживать кнопку, то попадаем в режим калибровки  в этом режиме заполняется массив в eeprom из N значений, которые соответствуют литрам (от 0 до N-1). Вроде все корректно заполняется. Только как теперь этот массив использовать? На индикаторе хочу получить целое кол-во литров. Еще нужно предусмотреть какое-то округление до целой части, т.е. если значение АЦП соответсвует 13,6 литрам, то на индикатор выводилось бы 14, а если 13,4 то 13. Поможете?
|
|
|
|
|
Mar 29 2007, 21:11
|
Частый гость
 
Группа: Свой
Сообщений: 135
Регистрация: 7-03-07
Из: г. Запорожье
Пользователь №: 25 945

|
Собрал я свой измеритель и окончательно убедился, что датчик в виде поплавка с резистором абсолютно не подходит  Наверное нужно сооружать в баке конденсатор и мерять его емкость. Подскажите наиболее простой вариант реализации.
|
|
|
|
|
Mar 30 2007, 01:18
|
Участник

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

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

|
Вот так провожу измерение Код unsigned char read_adc(unsigned char adc_input) { unsigned char out=0; unsigned char n=0; unsigned char i=0; unsigned int sum=0;
for(i=0;i<16;i++) { for(n=0;n<16;n++) { ADMUX=adc_input | (ADC_VREF_TYPE & 0xff); // Start the AD conversion ADCSRA|=0x40; // Wait for the AD conversion to complete while ((ADCSRA & 0x10)==0); ADCSRA|=0x10; t[n]=ADCH; delay_us(30); } for(n=0;n<16;n++) { sum+=t[n]; } sum = sum>>4; t1[i]=(unsigned char)sum; } for(n=0;n<16;n++) { sum+=t1[n]; } sum = sum>>4; out=(unsigned char)sum;
return out;} Вот так вывожу: Код while (1) { unsigned char out=0; unsigned char n=0; out=read_adc(0);
for (n=9;n>0;n--) { if (out>=kalibr[n]-((kalibr[n]-kalibr[n-1])>>2)) if (out<=kalibr[n]+((kalibr[n+1]-kalibr[n-1])>>2)) leds(n); } } kalibr хранит значения полученные при калибровке. Не нравится мне конструкция из if, но в силу своей неопытности ничего лучшего не придумал. Проблема в том, что 1 литр = 2 градуса поворота резистора. Испытание в баке еще не проводил, но что-то кажется что точность будет никакая... С пузырьковой сортировкой пробывал, но что-то не заработало.
|
|
|
|
|
Mar 30 2007, 09:31
|
Участник

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

|
Я задавал вопросы про времена, ты привёл код. Как по этому коду мне получить ответы? Не зная тактовой частоты твоего камня, да и АВР я не знаю, поэтому участок кода работы с АЦП проверить не могу, может знатоки АВР проверят. Так что, мои вопросы остались без ответа. По проге. На первый взгляд вроде всё правильно. На данном этапе это главное, а красота придёт с опытом. Навскидку, в твоей проге delay_us(30); Сделай побольше порядка на 3, не микросекунды, а мили. Тогда и появится нужная плавность в показаниях. Зачем ты заводишь массивы? В данной проге они не нужны совсем. Достаточно накапливать сумму в одном unsigned int sum с последующим делением, как было в моём примере выше. Показалось мало 16 раз, ты сделал 256. Пусть так. 16 * 16 = 256. Не нужно 2 цикла. Т.к. ты нигде кроме этой процедуры не используешь промежуточный результат после 16 первых "оборотов", то достаточно одного цикла 256 раз с последующим делением на 256 (сдвиг вправо на 8 разрядов). Смысл не изменится. А это куда вывод? Код for (n=9;n>0;n--) { if (out>=kalibr[n]-((kalibr[n]-kalibr[n-1])>>2)) if (out<=kalibr[n]+((kalibr[n+1]-kalibr[n-1])>>2)) leds(n); } >> С пузырьковой сортировкой пробывал, но что-то не заработало. Не заработало что? Я привёл полностью рабочий код. Надо было просто скопировать его в свою прогу и всё.
|
|
|
|
|
Mar 30 2007, 10:29
|
Частый гость
 
Группа: Свой
Сообщений: 135
Регистрация: 7-03-07
Из: г. Запорожье
Пользователь №: 25 945

|
Vladimir Chekin , спасибо за внимание к теме Clock frequency : 1,000000 MHz ADC Clock frequency: 125,000 kHz Зачем заводил массив не объясню...сам незнаю зачем  Обязательно исправлю. Цитата А это куда вывод? Это вывод на индикатор целого кол-ва литров. Если значение АЦП лежит в пределах n-0.25литра<n<n+0.25литра , то на индикатор выводится n. С пузірьковой сортировкой попробую еще. muravei, наступание на грабли хороший метод обучения  muravei, наступание на грабли хороший метод обучения
|
|
|
|
|
Mar 30 2007, 12:02
|
Частый гость
 
Группа: Свой
Сообщений: 135
Регистрация: 7-03-07
Из: г. Запорожье
Пользователь №: 25 945

|
Получилась у меня пузырьковая сортировка!  Код unsigned char i, k, temp; unsigned char filt_res[3]; unsigned int integrator=0;
for (i=0; i < 16; i++) { for (k=0; k < 3; k++) { filt_res[k] = read_adc(0); // ÷èòàåì ÀÖÏ delay_ms (10); }
// Ïóçûðüêîâàÿ ñîðòèðîâêà if (filt_res[0] > filt_res[1]) { temp = filt_res[1]; filt_res[1] = filt_res[0]; filt_res[0] = temp; }
if (filt_res[1] > filt_res[2]) { temp = filt_res[2]; filt_res[2] = filt_res[1]; filt_res[1] = temp; }
if (filt_res[0] > filt_res[1]) { temp = filt_res[1]; filt_res[1] = filt_res[0]; filt_res[0] = temp; }
//  filt_res[1] - ñðåäíåå (íå ïóòàòü ñ óñðåäí¸ííûì) ïî âåëè÷åíå çíà÷åíèå integrator += filt_res[1]; }
temp = integrator >> 4; // Â temp èñêîìîå сразу неработало из-за того, что перед началом нового отсчета нужно было обнулить integtator.
Сообщение отредактировал alex2103 - Mar 30 2007, 12:02
|
|
|
|
|
Mar 30 2007, 12:31
|
Частый гость
 
Группа: Свой
Сообщений: 135
Регистрация: 7-03-07
Из: г. Запорожье
Пользователь №: 25 945

|
muravei, ну так и раздел форума для "детей"  ОФФ: многим обитателям форума мои вопросы могут показаться очень простыми, на которые даже отвечать не хочется  Для меня любой ваш ответ - неоценимая помощь в освоении МК! Когда-то прогуливал лекции по МК, было неинтересно... А теперь сам пытаюсь обучиться, причем не потому, что "надо", а просто для себя...
|
|
|
|
|
Mar 30 2007, 12:40
|
Участник

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

|
>> Clock frequency, АDC Clock frequency... Я оценил юмор  Мож заодно пришлёшь мне компилятор и симулятор или макет с эмулятором/дебагером, чтоб я смог откомпилить и прогнать твою прогу, чтоб узнать сколько времени между измерениями и выводом на экран на самом деле? >> Это вывод на индикатор целого кол-ва литров Хм, у тебя только 9 градаций? Странно, вроде изначально речь шла о 40-литровом. Чего-то я не пойму тогда изначальной затеи. Пока нет опыта сделать нормальную процедуру калибровки, можно пойти более долгим, менее универсальным, но более простым путём: сперва сделать вывод на индикатор значения отфильрованного АЦП, т.е. out. Наливать в бак по литру и записывать показания индикатора на бумажку. Затем в программе объявить массив, инициализированный данными с бумажки: uchar table [40] = {x0, x1,... x39}; В цикле путём сравнения значений таблицы с out находишь номер члена таблицы меньше или больше out, как удобнее, и уже его выводишь на экран. Кстати, а что за экран? Судя по "плаванию" в элементарном есть подозрение в корректном написании процедуры преобразования целого в ASCI и собственно вывод. Может поэтому показания "скачат"?
|
|
|
|
|
Mar 30 2007, 13:24
|
Частый гость
 
Группа: Свой
Сообщений: 135
Регистрация: 7-03-07
Из: г. Запорожье
Пользователь №: 25 945

|
Цитата Хм, у тебя только 9 градаций? Странно, вроде изначально речь шла о 40-литровом. Чего-то я не пойму тогда изначальной затеи. 9 градаций сделано на время отладки. Потом будет 40. Цитата Наливать в бак по литру и записывать показания индикатора на бумажку. Алгоритм у меня такой же. Только индикатор у меня на 2 символа и out для калибровки я записываю в епром. Налил литр - нажал кнопку, налил еще - нажал.  Цитата В цикле путём сравнения значений таблицы с out находишь номер члена таблицы меньше или больше out, как удобнее, и уже его выводишь на экран. Вот как это красиво организовать? Цитата Кстати, а что за экран? Судя по "плаванию" в элементарном есть подозрение в корректном написании процедуры преобразования целого в ASCI и собственно вывод. "Экран" от старого системника...на 2 с половиной разряда  Вот так с ним работаю: Код void leds(char a) { unsigned char digits[2]; if(a>=99) // если больше 99, то на индикаторе "Er"-типа ошибка. { PORTD=0x86; PORTB=0x5F; return; } digits[0] =a % 10; digits[1] =a / 10 % 10; switch(digits[1]) // в led[] и led1[] храняться коды индикаторов. { case 0: PORTD=led[0]; break; case 1: PORTD=led[1]; break; case 2: PORTD=led[2]; break; case 3: PORTD=led[3]; break; case 4: PORTD=led[4]; break; case 5: PORTD=led[5]; break; case 6: PORTD=led[6]; break; case 7: PORTD=led[7]; break; case 8: PORTD=led[8]; break; case 9: PORTD=led[9]; break; default: PORTD=0xBF;break; } switch(digits[0]) { case 0: PORTB=led1[0]; break; case 1: PORTB=led1[1]; break; case 2: PORTB=led1[2]; break; case 3: PORTB=led1[3]; break; case 4: PORTB=led1[4]; break; case 5: PORTB=led1[5]; break; case 6: PORTB=led1[6]; break; case 7: PORTB=led1[7]; break; case 8: PORTB=led1[8]; break; case 9: PORTB=led1[9]; break; default: PORTB=0xBF;break; } } Еще раз спасибо за содействие!
|
|
|
|
|
Mar 30 2007, 14:44
|

Участник

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

|
Цитата(alex2103 @ Mar 30 2007, 14:24)  Код ... ... switch(digits[1]) // в led[] и led1[] храняться коды индикаторов. { case 0: PORTD=led[0]; break; case 1: PORTD=led[1]; break; case 2: PORTD=led[2]; break; case 3: PORTD=led[3]; break; case 4: PORTD=led[4]; break; case 5: PORTD=led[5]; break; case 6: PORTD=led[6]; break; case 7: PORTD=led[7]; break; case 8: PORTD=led[8]; break; case 9: PORTD=led[9]; break; default: PORTD=0xBF;break; } switch(digits[0]) { case 0: PORTB=led1[0]; break; case 1: PORTB=led1[1]; break; case 2: PORTB=led1[2]; break; case 3: PORTB=led1[3]; break; case 4: PORTB=led1[4]; break; case 5: PORTB=led1[5]; break; case 6: PORTB=led1[6]; break; case 7: PORTB=led1[7]; break; case 8: PORTB=led1[8]; break; case 9: PORTB=led1[9]; break; default: PORTB=0xBF;break; } не лучьше ли сдалать так: Код // старшее знакоместо if (digits[1] < 10) PORTD = led[digits[1]]; else PORTD = 0xBF;
// младшее знакоместо if (digits[0] < 10) PORTB = led1[digits[0]]; else PORTB = 0xBF; кстати зачем заводить два массива-знакогенератора? лучше сделать подключение сегментов одинаково на обоих портах.
|
|
|
|
|
Mar 30 2007, 19:17
|
Участник

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

|
>> Вот как это красиво организовать? Дык написано ж было... "В цикле путём сравнения значений таблицы с out находишь номер члена таблицы меньше или больше out, как удобнее, и уже его выводишь на экран." Или надо код написать? Может стоит хотя б какую-нить книжку по Си почитать, там обычно примеров разных циклов предостаточно. В книгах однозначно основы разжеваны куда более чётко и методично, чем наши несвязные советы.
По процедуре вывода, сорри, был неправ, вроде бы работать должно. Про оптимизацию кода уже подсказали выше.
После увеличения паузы между измерениями и фильтра "мин/макс" изменилось ли что-то? Или всё равно показания скачат?
|
|
|
|
|
Mar 30 2007, 22:28
|
Частый гость
 
Группа: Свой
Сообщений: 135
Регистрация: 7-03-07
Из: г. Запорожье
Пользователь №: 25 945

|
Цитата После увеличения паузы между измерениями и фильтра "мин/макс" изменилось ли что-то? Или всё равно показания скачат? С показаниями все отлично! Спасибо. Цитата Может стоит хотя б какую-нить книжку по Си почитать, там обычно примеров разных циклов предостаточно. Читаю Шпак Ю.А. Программирование на языке С для AVR и PIC микроконтроллеров. Наверное ненадолго я перестану вас мучать глупыми вопросами...на выходных доделаю датчик и проведу эксперимент, сниму зависимость литры/ацп... Кстати никто не подскажет как поведет себя пепроволочный переменный резистор в баке? Бензин резистивный слой не погубит?
|
|
|
|
|
Jul 6 2007, 05:36
|
Профессионал
    
Группа: Свой
Сообщений: 1 266
Регистрация: 22-04-05
Из: Киев
Пользователь №: 4 387

|
Недавно видел схему простого емкостного уровнемера - идея датчика следующая - (генератор на 555) задающий конденсатор представлят собой цепочку последовательнго включенных конденсаторов, располагаемых на планке, ну а с другой стороны отводы типа иголочек. И мне кажется, что опорный генератор (конденсатор) нужен, если его пластина также есть часть сенсора, но в неосушаемой области. Посмотрите по линкам - может что покажется интересным http://www.merl.com/projects/iGlassware/http://www.discovercircuits.com/PDF-FILES/capgage.pdf
--------------------
aka Vit
|
|
|
|
|
Jul 6 2007, 20:29
|
Частый гость
 
Группа: Свой
Сообщений: 135
Регистрация: 7-03-07
Из: г. Запорожье
Пользователь №: 25 945

|
sensor_ua, спасибо за ссылки. Жаль с английским туго  Как я понял датчик в баке является частью генератора. Изменение емкости датчика влияет на частоту генерации... Буду смотреть проекты частотомеров на МК чтоб эту частоту измерить и оценить уровень жидкости. В МК я все еще ламер
|
|
|
|
|
Nov 19 2007, 13:54
|
Группа: Новичок
Сообщений: 3
Регистрация: 19-11-07
Пользователь №: 32 453

|
Скажите а где взять прошивку для решения датчика из журнала Схемотехника 1,2007 . Их сайт dian.ru не отвечает.
|
|
|
|
|
Nov 20 2007, 08:27
|

Гуру
     
Группа: Свой
Сообщений: 2 002
Регистрация: 17-01-06
Из: Томск, Россия
Пользователь №: 13 271

|
Я вот тоже не понял, почему автору не понравился штатный датчик уровня топлива? Допустим, по Вашему мнению, показания прыгают - Вам это не нравится... А почему тогда показания не прыгают у стрелки на табло? Потому что у неё время интегрирования чуть ли не 10 секунд. И даже если топливо плещется на кочках, то всё успевает сгладиться. Я уверен, что увеличение времени интегрирования до десятков секунд решит любую проблему непостоянности показаний. Добавлю ещё, что существует множество ботовых компьютеров, в которых вход измерителя топлива цепляется к штатному датчику. И всё нормально показывает. Имеется в них и калибровка. Доливаешь в бак литр - нажимаешь кнопку. И так пока весь не откалибруешь.
--------------------
Зная себе цену, нужно ещё и пользоваться спросом...
|
|
|
|
|
Nov 22 2007, 06:46
|
Группа: Новичок
Сообщений: 3
Регистрация: 19-11-07
Пользователь №: 32 453

|
Устройство очень полезное тем что нет движ. частей . У меня на двух машинах это вызывает разные неполадки. И не всегда понятно когда в пути надо дозапрвить бак а когда можно подождать и доехать до заправки с хорошим качественным бензином. Скачки показаний действительно на многих машинах убираются за счет инерционочсти показометра.
|
|
|
|
|
Nov 22 2007, 09:45
|
Группа: Новичок
Сообщений: 3
Регистрация: 19-11-07
Пользователь №: 32 453

|
А прошивка есть или нет? того чудо девайса что в Схемотехнике 1.2007
|
|
|
|
|
Nov 26 2007, 09:17
|

Гуру
     
Группа: Свой
Сообщений: 2 002
Регистрация: 17-01-06
Из: Томск, Россия
Пользователь №: 13 271

|
Цитата(rv3dll(lex) @ Nov 22 2007, 19:13)  опять вернулись к тому что стрелка ничего не порказывает Извиняюсь перед модераторами за демагогию, но почему это стрелка ничего не показывает? Она показывает уровень топлива в баке. Цитата(rv3dll(lex) @ Nov 22 2007, 19:13)  получается, что при уклоне машины в разные стороны при ускорениях поворотах и торможении бензин плещется переливается и нет возможности что либо мерить. Есть возможность. Нужно интегрировать показания, в среднем они будут правильные, близкие к реальному остатку топлива. Другое дело, что когда бензин плещется, то ни один датчик, ни одной системы, не измерит вам точно остаток топлива, поэтому интегрирование придётся делать с любого датчика. Цитата(rv3dll(lex) @ Nov 22 2007, 19:13)  ЗАЧЕМ ДЕЛАТЬ ТО ЧТО НЕ ДОЛЖНО РАБОТАТЬ В ПРИНЦИПЕ!!!!!!!!!!!!!!!!!!!!????????????????? И должно, и работает. Не верите - посмотрите у меня на машине. У большинства автовладельцев всё работает и показывает, притом показывает правильно (в пределах погрешности).
--------------------
Зная себе цену, нужно ещё и пользоваться спросом...
|
|
|
|
|
Nov 26 2007, 11:30
|

Полное ничтожество
    
Группа: Banned
Сообщений: 1 991
Регистрация: 20-03-07
Из: Коломна
Пользователь №: 26 354

|
Цитата(Krys @ Nov 26 2007, 12:17)  Извиняюсь перед модераторами за демагогию, но почему это стрелка ничего не показывает? Она показывает уровень топлива в баке. Есть возможность. Нужно интегрировать показания, в среднем они будут правильные, близкие к реальному остатку топлива. Другое дело, что когда бензин плещется, то ни один датчик, ни одной системы, не измерит вам точно остаток топлива, поэтому интегрирование придётся делать с любого датчика.
И должно, и работает. Не верите - посмотрите у меня на машине. У большинства автовладельцев всё работает и показывает, притом показывает правильно (в пределах погрешности). пример) движение по обычному шоссе 5 км туда - 5 обратно загрузка машины разная так вот туда лампочка заправься горела устойчиво а обратно только мигала. это о чем нибудь говорит ???? Автомобиль нива 21213 - спроси любого владельца нивы и он тебе пользуясь определённой лексикой расскажет что показывает стрелка
|
|
|
|
|
Nov 26 2007, 19:08
|

Полное ничтожество
    
Группа: Banned
Сообщений: 1 991
Регистрация: 20-03-07
Из: Коломна
Пользователь №: 26 354

|
Цитата(Марк_Я @ Nov 26 2007, 17:57)  Проблемы с плеском бензина нет никакой. Даже если не интегрировать, то есть такая идея мерять только при стабильном положении машины, а в дороге вычитать расходомером. Остановка - и сразу сверка и коррекция. Кстати и поплавок можно заменить сильфоном с дифманометром, как в стиральных и посудомоечных машинах. тут согласен - расходомер основной инструмент остальное индикатор тем кто плохо разбирается в машине самой - после работы в сервисе для меня капиталка вазовского двигателя не вызывает трудностей сам езжу на моторе 1875см3 переделывал сам. объём топливной магистрали около 200 - 500 грамм разная для каждой машины туда входят трубки - если карбюр солекс - то их 2 там есть обратка, фильтр - в инжекторе большой, поплавковая камера - в инжекторе рампа, бензонасос после того как двигатель остановили инжектор сливает рампу в бак , в карбюраторе испаряется бензин из поплавковой камеры - поплавок падает соединяяя топливопровод с атмосферой бензин сливается в бак. как вам ошибка в 200 грамм минимум?. дальше хуже в зависимости от нагрузки машины и кренов эти 200-500 могут не использоваться двигателем - у инжектора хватанув воздух насос несколько секунд вообще не качает - у карбюраторных - обратка выльется в пустоту и новая порция не всасётся заборником точность ваших измерителей поллитра? - я и так знаю когда кончится бензин!!!!!!
|
|
|
|
|
Nov 28 2007, 08:46
|

Гуру
     
Группа: Свой
Сообщений: 2 002
Регистрация: 17-01-06
Из: Томск, Россия
Пользователь №: 13 271

|
Цитата(rv3dll(lex) @ Nov 27 2007, 01:08)  точность ваших измерителей поллитра? - я и так знаю когда кончится бензин!!!!!! Во-первых, не нервничайте. Во-вторых, меня лично устроит точность измерителя плюс-минус поллитра, это всего лишь плюс-минус один процент по отношению к 43 литрам в моей 8ке. А когда бензин кончится - лучше не знать, а заправляться несколько раньше, лучше даже существенно раньше, чем он кончится. А для этого даже показания с погрешностью подойдут. В-третьих, считаю это уже офтопом и предлагаю прекратить данную дискуссию.
--------------------
Зная себе цену, нужно ещё и пользоваться спросом...
|
|
|
|
|
Nov 28 2007, 11:10
|

Полное ничтожество
    
Группа: Banned
Сообщений: 1 991
Регистрация: 20-03-07
Из: Коломна
Пользователь №: 26 354

|
Цитата(Krys @ Nov 28 2007, 11:46)  Во-первых, не нервничайте. Во-вторых, меня лично устроит точность измерителя плюс-минус поллитра, это всего лишь плюс-минус один процент по отношению к 43 литрам в моей 8ке. А когда бензин кончится - лучше не знать, а заправляться несколько раньше, лучше даже существенно раньше, чем он кончится. А для этого даже показания с погрешностью подойдут. В-третьих, считаю это уже офтопом и предлагаю прекратить данную дискуссию. а вот это уже не офф топ 1 - в горизонтальном баке - даже +-литр не получишь!!! 2 - ты на 3 литра если не больше ошибёшься , когда зальёшь бак по горловину - так как поплавок к тому времени уже упрётся в крышу бака - ))) 3 - точность в 1 процент она относительная для литра ошибки. 1/43 = 0,023 полный бак 1/20 = 0,05 полбака 1/10 = 0,1 четверть 1/(5)= 0,2-резерв 20% - 10км которых как раз до заправки может не хватить)))) я всё к тому, что чем меньше осталось - тем хуже точность - но тем не менее тут как раз точность наиболее важна 10 км по сравнению с 400 и 10 по сравнению с 50. с удовольствием присоединюсь к обсуждению измерений с использованием датчика объёмного расхода топлива и импульсного датчика скорости, что я собственно и предлогаю!!!!
|
|
|
|
|
Jun 9 2011, 10:53
|

Местный
  
Группа: Свой
Сообщений: 206
Регистрация: 14-06-06
Из: Могилев
Пользователь №: 18 059

|
А как быть с термокомпенсацией. Замечал у себя: выезжаешь в -20, показывает пол-бака, проезжаешь 200 км, в это время бензин по обратке греется, смотришь на показания - опять пол-бака  . Или мне показалось? Посчитал, на 20гр погрешность примерно 1,5%. Значит показалось... Но 1,5%/20гр - это существенно, надо ставить термодатчик.
Сообщение отредактировал John Silver - Jun 9 2011, 11:07
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|