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

Atmega8, Codevisionavr, Застрял


Юрец

Рекомендуемые сообщения

Здравствуйте!

цифровую панель приборов на 21063 запустил. есть небольшая проблемка в программировании:

нужно, чтобы при уменьшении или увеличении переменной result_f считывалось несколько значений, и выбиралось максимальное.

в машине сам стрелочный индикатор уровня топлива имеет плавный ход (т.е. если подать на него питание, то стрелка ПЛАВНО отклонится, а не рывком. (как будто стрелка "плавает" в густом масле) также и при отключении питания - стрелка возвращается на ноль за 2-3сек.).

как это сделать програмно?, а то цифры прыгают быстро.

я додумался до такого:

char i_fuel=0; // вспомогательная переменная (0-10)

unsigned int real_f; // значение fuel для выдачи на индикатор

unsigned int sr_f; // среднее значение fuel

result_f=read_adc(1); // считать значение fuel с ацп

delay_ms(10); // пауза 10мс

#asm("cli") // выключить прерывания]

switch (i_fuel) {

case 0:{real_f=result_f;i_fuel=1;break;};// показать real_f первый раз

case 1:{sr_f=((result_f+real_f)/2);if (result_f<real_f){real_f=result_f;i_fuel=1;} else{i_fuel=2;};break;};// найти среднее значение десяти считываний АЦП. если значение увеличилось (при увеличении уровня топлива значение result_f (уменьшается) и будет меньше real_f) , то real_f меняем быстро, а при уменьшении - через 10 опросов.)

case 2:{sr_f=((result_f+sr_f)/2);if (result_f<real_f){real_f=result_f;i_fuel=1;} else{i_fuel=3;};break;};

case 3:{sr_f=((result_f+sr_f)/2);if (result_f<real_f){real_f=result_f;i_fuel=1;} else{i_fuel=4;};break;};

case 4:{sr_f=((result_f+sr_f)/2);if (result_f<real_f){real_f=result_f;i_fuel=1;} else{i_fuel=5;};break;};

case 5:{sr_f=((result_f+sr_f)/2);if (result_f<real_f){real_f=result_f;i_fuel=1;} else{i_fuel=6;};break;};

case 6:{sr_f=((result_f+sr_f)/2);if (result_f<real_f){real_f=result_f;i_fuel=1;} else{i_fuel=7;};break;};

case 7:{sr_f=((result_f+sr_f)/2);if (result_f<real_f){real_f=result_f;i_fuel=1;} else{i_fuel=8;};break;};

case 8:{sr_f=((result_f+sr_f)/2);if (result_f<real_f){real_f=result_f;i_fuel=1;} else{i_fuel=9;};break;};

case 9:{sr_f=((result_f+sr_f)/2);if (result_f<real_f){real_f=result_f;i_fuel=1;} else{i_fuel=10;};break;};// показать real_f

case 10:{sr_f=((result_f+sr_f)/2);i_fuel=1;real_f=sr_f;break;};

break;

};

лучше, но не то...

дома, при наладке (подключив переменный резистор вместо датчика топлива) всё ок.(с окончанием изменения сопротивления резистора показ литража стоит как вкопанный), а в машине показания прыгают на 1-2 литра. проверяю сопротивление датчика уровня топлива прямо на машине - плавает на 5-8ом (машина не заведена). такое впечатление, что машину качают, хотя стоит ровно.

как програмно можно эмулировать плавный ход? понимаю, что нужно реализовывать через min, max значения изменении переменной result_f, но как?

P.S. индикация вольтажа, давления масла,температуры нормальная. проблема только с показом топлива.

есть программисты?

Изменено пользователем Юрец

не всё золото, что на контактах...

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

Реклама: ООО ТД Промэлектроника, ИНН: 6659197470, Тел: 8 (800) 1000-321

Первое что приходит в голову:

1.Преобразование №1 - получаем некое L1

2.Выводим L1 на индикатор, устанавливаем флаг, чтобы не возвращаться больше к пунктам 1.и 2.

3.Преобразование №N - получаем некое L2 //сюда должны попасть только при n=0

4.Если счетчик итераций n<5 то пункт5.Если n>=5 то n=0, L1=L2, Выводим L1, переходим к пункту 3.

5.Вычисляем:dL=(L1-L2)*2/10, L = L1-dL*(n+1)

6.Выводим L

7.Прибавляем к счетчику итераций n единицу, переходим к пункту 4.

Переменные dL,L должны быть signed

Это примерный алгоритм, демонстрирующий идею, его можно оптимизировать (скажем, не вычислять каждый раз dL, а работать по флагу), если подойдет, конечно...

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

Любой, заслуживающий внимания, опыт приобретается себе в убыток...

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

20% скидка на весь каталог электронных компонентов в ТМ Электроникс!

Акция "Лето ближе - цены ниже", успей сделать выгодные покупки!

Плюс весь апрель действует скидка 10% по промокоду APREL24 + 15% кэшбэк и бесплатная доставка!

Перейти на страницу акции

Реклама: ООО ТМ ЭЛЕКТРОНИКС, ИНН: 7806548420, info@tmelectronics.ru, +7(812)4094849

Это примерный алгоритм, демонстрирующий идею, его можно оптимизировать (скажем, не вычислять каждый раз dL, а работать по флагу), если подойдет, конечно...

не понял :unsure:

пробовал ещё так: делаю 3 измерения на входе АЦП, считаю среднее значение, далее в цикле-

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

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

таким образом уменьшаю гистерезис показа. программа нормально работает только дома (с подключенным переменным резистором вместо датчика), а в машине показания прыгают. (такое впечатление, что поплавок на датчике уровня топлива поднимают и опускают). может моя ошибка в схемном решении? (в машине так: +12в -> стрелочный индикатор -> датчик -> минус). а я сделал так:post-14455-1196859544_thumb.jpg

повторюсь- дома питаю компьютерным блоком питания (беру только +12в) через две кренки (стоят в девайсе)- на8 а потом на 5в.(для отсутствия нагрева кренок).

мне кажется, что дело или в питании, или в наводках электропроводки авто, потому-что как только я включаю габариты (вентилятор печки или еще что-нибудь), показания температуры, уровня топлива и давления масла меняются на 2-3% (все вместе в сторону увеличения).

Есть предложения?

p.s. вот текст программы: 21063.rar

Изменено пользователем Юрец

не всё золото, что на контактах...

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

Особенности хранения литиевых аккумуляторов и батареек

Потеря емкости аккумулятора напрямую зависит от условий хранения и эксплуатации. При неправильном хранении даже самый лучший литиевый источник тока с превосходными характеристиками может не оправдать ожиданий. Технология, основанная на рекомендациях таких известных производителей литиевых источников тока, как компании FANSO и EVE Energy, поможет организовать правильный процесс хранения батареек и аккумуляторов. Подробнее>>

Реклама: АО КОМПЭЛ, ИНН: 7713005406, ОГРН: 1027700032161

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

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

Любой, заслуживающий внимания, опыт приобретается себе в убыток...

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

Выбираем схему BMS для корректной работы литий-железофосфатных (LiFePO4) аккумуляторов

 Обязательным условием долгой и стабильной работы Li-FePO4-аккумуляторов, в том числе и производства EVE Energy, является применение специализированных BMS-микросхем. Литий-железофосфатные АКБ отличаются такими характеристиками, как высокая многократность циклов заряда-разряда, безопасность, возможность быстрой зарядки, устойчивость к буферному режиму работы и приемлемая стоимость. Но для этих АКБ, также как и для других, очень важен контроль процесса заряда и разряда, а специализированных микросхем для этого вида аккумуляторов не так много. Инженеры КОМПЭЛ подготовили список имеющихся микросхем и возможных решений от разных производителей. Подробнее>>

Реклама: АО КОМПЭЛ, ИНН: 7713005406, ОГРН: 1027700032161

понял Вашу идею используя лист бумаги и ручку (задавал L1 и L2)! Оригинально! Спасибо!

на мой взгляд вычисление dL=(L1-L2)*2/10 нужно вставить между пунктами 3 и 4. тогда dL не будет болтаться в цикле n(0...5).

а что насчет разницы индикации при питании от стационарного БП и бортовой сети авто? может быть какая нибудь зависимость?

не всё золото, что на контактах...

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

а что насчет разницы индикации при питании от стационарного БП и бортовой сети авто? может быть какая нибудь зависимость?

Как я понял это обусловлено изменением сопротивления датчика:

дома, при наладке (подключив переменный резистор вместо датчика топлива) всё ок.(с окончанием изменения сопротивления резистора показ литража стоит как вкопанный), а в машине показания прыгают на 1-2 литра. проверяю сопротивление датчика уровня топлива прямо на машине - плавает на 5-8ом (машина не заведена). такое впечатление, что машину качают, хотя стоит ровно.

Думаю, лучший способ это победить - вычислять L1 и L2 как среднее из десятка выборок. Колебания показаний должны практически исчезнуть. Потом останется только грамотно "завернуть" цикл демпфирования...

Чтобы избавится от колебаний показаний при изменении бортового напряжения, нужно запитывать измерительный реостат (и используемые датчики вообще) от стабилизатора, например той-же ЕНКИ...

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

Любой, заслуживающий внимания, опыт приобретается себе в убыток...

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

Думаю, лучший способ это победить - вычислять L1 и L2 как среднее из десятка выборок. Колебания показаний должны практически исчезнуть. Потом останется только грамотно "завернуть" цикл демпфирования...

Чтобы избавится от колебаний показаний при изменении бортового напряжения, нужно запитывать измерительный реостат (и используемые датчики вообще) от стабилизатора, например той-же ЕНКИ...

датчики запитываю (видно из схемы преобразования входного сигнала) +5в от крЕНки.

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

причину нашел (для проверки прямо на машине подключил вместо датчика уровня топлива переменный резистор- показания литража НЕ ПРЫГАЮТ!).питал от бортовой сети. видимо сам датчик корявый или влияет смачиваемость его бензином.

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

а насчет "грамотно завернуть цикл демпфирования..." - чуть позже сообщу, что у меня получилось. сейчас оптимизирую программу (изначально программа занимала 86% памяти Меги, сейчас уже 29%). потом буду думать над циклом демпфирования. можно надеятся на Вашу помощь?

не всё золото, что на контактах...

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

  • 2 недели спустя...

на видео 16-12-07_1000.3gp видна нестабильность входного напряжения (хотя цифровой мультиметр, подключенный паралельно показывает отклонение около 0,08 - 0,1в). что-то с преобразованием АЦП.

файл 21063.с - вытянул из codevisionavr. (если нужно, могу слить весь проект, схему).

картинка panel.jpg - фото с пояснением FD,FE,и т.д.

21063.rar

post-14455-1197786220_thumb.jpg

16_12_07_1000.rar

Изменено пользователем Юрец

не всё золото, что на контактах...

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

Основательно разбираться в проге пока нет времени. Общие замечания:

1.ADMUX = 0x40? - зарезервированный для меги8 источник опорного напряжения - т.е непонятно какой. Я бы подключил внутренний ИОН 2,56В - ADMUX=0xC0;

2.На ногу AREF нужно посадить конденсатор для лучшей помехозащищенности (номинал должен быть в даташите);

3.В проге используется мультиплексор для выбора каналов АЦП. Канал определяется каждый раз при вызове функции преобразования. Причем : "ADMUX=adc_input|ADC_VREF_TYPE;", а надо: "ADMUX=adc_input | (ADC_VREF_TYPE & 0xff);" - CVAVR, может имеет значение..

4.Рекомендуется после выбора канала мультиплексора выключить и включить модуль АЦП. Или дважды произвести преобразования - первое преобразование будет холостым, т.е кусок

"ADCSRA|=0x40;

while ((ADCSRA & 0x10)==0);

ADCSRA|=0x10;"

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

5.В начале функции int read_adc глобально запретить прерывания (чтобы во время АЦП МК не дергал ногами в обработчике прерываний по таймеру), а в конце разрешить.

6. Уменьшить число кол-ва выборок АЦП до 20-50 (400 и 2000 слишком, по-моему...) - и индикаторы моргать не будут, если прерывания запретим...

Пока попробуйте так. Про демпфирование подумаю чуть позже...

P.S. Результат АЦП можно попробовать возвратить как:

n1=ADCL;

n2=((unsigned int) ADCH)<<8;

return n1|n2;

где n1 и n2 некие локальные переменные (unsigned int). Либо если получится так:

return ADCL|(((unsigned long int) ADCH)<<8); - смысл в том, что 10-и битный результат АЦП нужно считывать и з восьмибитных регистров в определенном порядке. Что считается первым во втором случае не уверен... Но

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

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

Любой, заслуживающий внимания, опыт приобретается себе в убыток...

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

Основательно разбираться в проге пока нет времени. Общие замечания:

1.ADMUX = 0x40? - зарезервированный для меги8 источник опорного напряжения - т.е непонятно какой. Я бы подключил внутренний ИОН 2,56В - ADMUX=0xC0;

2.На ногу AREF нужно посадить конденсатор для лучшей помехозащищенности (номинал должен быть в даташите);

3.В проге используется мультиплексор для выбора каналов АЦП. Канал определяется каждый раз при вызове функции преобразования. Причем : "ADMUX=adc_input|ADC_VREF_TYPE;", а надо: "ADMUX=adc_input | (ADC_VREF_TYPE & 0xff);" - CVAVR, может имеет значение..

4.Рекомендуется после выбора канала мультиплексора выключить и включить модуль АЦП. Или дважды произвести преобразования - первое преобразование будет холостым, т.е кусок

"ADCSRA|=0x40;

while ((ADCSRA & 0x10)==0);

ADCSRA|=0x10;"

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

5.В начале функции int read_adc глобально запретить прерывания (чтобы во время АЦП МК не дергал ногами в обработчике прерываний по таймеру), а в конце разрешить.

6. Уменьшить число кол-ва выборок АЦП до 20-50 (400 и 2000 слишком, по-моему...) - и индикаторы моргать не будут, если прерывания запретим...

Пока попробуйте так. Про демпфирование подумаю чуть позже...

1. при AREF=AVCC --> ADMUX = 0x40 (как я понял из даташита). схемно вывод AVCC соединенён с VCC (+5в).

2. действительно, в даташите указано, что для лучшей помехозащищенности (как я понял с английского) рекомендуется поставить конденсатор между AREF и GND. вот только какой емкости? я так и не нашел.

3. пробовал как ADMUX=adc_input|ADC_VREF_TYPE; , так и ADMUX=adc_input | (ADC_VREF_TYPE & 0xff); --> визуальных отличий в работе не заметил.

4. делаю преобразование дважды. экспериментально сделал задержку в 10микросекунд.

unsigned int read_adc(unsigned char adc_input)

{

ADMUX=adc_input|ADC_VREF_TYPE;

// Start the AD conversion

ADCSRA|=0x40;

// Wait for the AD conversion to complete

while ((ADCSRA & 0x10)==0);

ADCSRA|=0x10;

delay_us(10); //пауза 10mks

// Start the AD conversion

ADCSRA|=0x40;

// Wait for the AD conversion to complete

while ((ADCSRA & 0x10)==0);

ADCSRA|=0x10;

return ADCW;

}

5.

#asm("cli") // выключить все прерывания глобально

result_v=read_adc(0); // считать значение volt с АЦП

#asm("sei") // включить все прерывания глобально

6.переделал алгоритм выборок.

while (i_volt<50){result_v=result_v+read_adc(0);i_volt+=1;} // считать 50 значений и вычислить сумму.

result_v=result_v/51; // выбрать среднее

********************************************************

результат: работает (показывает) как надо! (эффект появился с выполнением пункта 4.

для демпфирования необходимо учитывать не результат преобразования, а значение переменной volt_visible (из текста программы). к примеру: переменная volt_visible была равна 120 (12.0в), а стала 122 (12.2в). нужно, чтобы показ вольт был таким: 12.0--> 12.1-->12.2 .

Изменено пользователем Юрец

не всё золото, что на контактах...

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

  • 4 недели спустя...

А такой алгоритм:

1.L:=0.

2.L:=(L+Lтек)/2

3.вывод раз в 5 минут. (по дельта не стоит)

4.цикл на 2 (но гораздо чаще чем раз в 5 мин)

Изменено пользователем kentawrik
Ссылка на комментарий
Поделиться на другие сайты

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

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

Гость
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Ответить в этой теме...

×   Вставлено с форматированием.   Восстановить форматирование

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

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

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

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

Загрузка...
  • Последние посетители   0 пользователей онлайн

    • Ни одного зарегистрированного пользователя не просматривает данную страницу
  • Сообщения

    • Спрошу здесь, извиняюсь заранее если не совсем верно в тему.  Вопрос в следующем - хочу сделать экранчик для своего цапа (преобразователя) чтобы выводил частоту дискретизации (допустим это). Я узнал что можно реализовать эту задачу на контроллере Ардуино, можно Нано или другой и дисплей SSD1306 I2C OLED. Сигнал с цапа снимается по LRCLK с I2S и преобразовывается в I2C для вывода на экран. Купить экран и контроллер не проблема, а как подключить контроллер к цапу если на самом нано нет нужного пина или я что то не понимаю и все возможно? Прошивка есть! Хочу разобраться с подключением и купить плату с экраном. Можете обьяснить как соединять?  Вот у человека все подключено и работает. Частично он мне обьяснил...    
    • Ну надо сказать, заработало. Причём режимы даже совпали с расчётными. По усилению только не совсем понятно, толи погрешность осциллографа, толи действительно есть небольшой разбег...
    • "Так а если этот ваш телефон или монитор перенести на другую улицу - там все эти глюки пропадают?"  Телефон так работает везде по городу и области. Монитор не везде, но степень разная, где-то лучше, где-то хуже, но это не 1 монитор, это любой монитор. То есть в каких-то местах где одно устройство хорошо работает - там будет работать хорошо и другие.
    • Вот такие "мелкие" казалось бы детали, которые многие могут не заметить. Но я сразу подозревал, что на этой плате все-таки стоит внутренняя видеокарта (несмотря на заявления ТС что ее там нет). И выложеные (большое спасибо за это) выше таблицы раз за разом это подверждают тоже - чипсет 945GZ таки имеет встроенную видеокарту. В данном случае, ТС также использует внешнюю видеокарту (NVidia GeForce 210), а для внутренней не установлен драйвер, почему он и показан как "Microsoft Basic Adapter" (используется "драйвер Windows по-умолчанию"). Для того чтобы "добавить" памяти в систему (максимум что может добавиться это 512мб, писал об этом выше), надо вначале выключить внутреннюю видеокарту в BIOS (ну и включить Memory Re-Map, как уже предлагали). 
    • Так а если этот ваш телефон или монитор перенести на другую улицу - там все эти глюки пропадают?
    • Всех радиолюбителей поздравляю С ДНЁМ РАДИО.
    • Это мимо кассы - пк древний, в биос он похоже не влазил.  Тонкое наблюдение. Прямо из названия темы  
×
×
  • Создать...