... сенсор самое главное и интересное и сложное и есть
Имхо главное это то, какая преследуется цель и что для решения задачи есть на данный момент в тумбочке. Пардон - похоже уже флудим в теме. Если есть вопросы, плиз в личку.
Может быть я туплю, конечно, но дела таковы: переключил я таймер 1 в режим захвата. Написал такой код Спойлер
Код:
voidtim1_ini(void) { // Частота кварца 20000000Гц TCCR1A=0x00; // Normal mode TCCR1B &= ~((1<<WGM12)|(1<<WGM13)|(1<<CS11)); // Делитель 1024. Частота тактирования после делителя 19530 Гц. TCCR1B |= ((1<<CS12)|(1<CS10)); // Захват по спаду TCNT1=0; TIMSK1 |=(1<<ICIE1); // Разрешение прерывания по захвату }
volatileuint16_t cnt=0; uint16_t frec=0;
ISR(TIMER1_CAPT_vect) { TCNT1=0; cnt=ICR1;
}
intmain(void) { tim1_ini(); sei();
While(1) { frec=19530/cnt; // Здесь понятно, что на ноль делить нельзя, просто для понимания. sprintf(val_1,"%.0d",frec); } }
Подал с генератора 113 Гц. Получил на экране число 682. И это не дребезг. Период меандра 113 Гц = 8.8 мС. Период частоты тактирования таймера 19530Гц=51.2 мкС. Исходя из этого за 1 период частоты 113 Гц должно посчитаться примерно 170 тиков. Но не 682. По ходу с математикой может я протупливаю?
Датчик представляет из себя обычный геркон, который замыкает подтянутый к 5 вольтам вход приборки на землю. ... Поставил на вход кондер 0.1 мкф и на землю.
Конденсатор в параллель геркону может сократить ресурс контактов геркона. Я бы примерно так сделал:
Добавлено after 19 minutes 50 seconds: У SMAJ5.0A ток утечки великоват, нужно что-то другое, выбор есть.
Попробую для начала без кондера включить noice canceler, хотя наверно не поможет. Там провода от датчика проходят рядом с трамблером. Он то скорее всего и наводит шороху. Если не поможет, тогда по железу буду дальше кумекать. Но там вроде идет сигнал на UAF 2115. Думаю, нет там таких токов огромных. Я просто не знал, что кондер в параллель геркону приводит к снижению ресурса.
В догонку... За счет некоторой протяженности проводов и с учетом их какой-то индуктивности возможно ли нивелирование этих эффектов? Понятно, что провода также привносят свою емкостную составляющую.
Это Ваше уродование слов не уместно. Наверняка, когда к доктору или полицейскому приходите, внезапно грамотность просыпается, но тут-то кто? Тут гопники и быдло, недостойное уважения. И я спрашивал без сарказма.
Ну и вообще любителям (болтателям) за " жили-были" и за " кашу манную-жизнь туманную" просьба не флудить, если нечем ответить по конкретике. Все очень знатоки поговорить, подкольнуть, упрекнуть. Как только есть конкретика, так сразу " ну в чужих исходниках грех копать, кот заболел и т.д.". Так пройдите мимо, зачем встревать, если вы бесполезны?
У Вас низкая самооценка. К тому же под свою самооценку вы подвели всех участников форума, обобщив их. Не нужно так делать. Вы не можете решать за всех. Обратитесь к психологу, он вам поможет. Наверно...
Да нет, конечно. Не стоит. Просто плата сделана, распаяна. Буду переделывать. Но есть некоторые вопросы. Озвучу позже. Возможнр завтра. Времени не хватает...
Всем доброго здравия! Разобрался я с выводом пробега. Все сделал через целочисленные значения. Не то, что хотелось, но float рассчитывается очень неважно. У меня возник еще один вопрос по поводу алгоритма обработки нажатия кнопки. Суть такова, что есть "теневое" меню, где можно корректировать данные в зависимости от пробега авто, производительности форсунки, от емкости топливного бака, от количества импульсов датчика скорости на 1000 метров (комплектации разные) и запоминать их в EEPROM для последующих расчетов. Я набросал некоторые функции по коррекции этих данных, но вопрос уперся в обработку нажатия кнопки. Хочу отметить то, что кнопка всего ОДНА. И нужно как-то выкрутиться. Функцию обработки нажатия кнопки я честно признаюсь украл. Проблема сейчас в том, что при двойном нажатии ловится сначала одиночное нажатие, потом двойное. Код нажатия одиночного 03, двойного 05. Код под спойлером. Спойлер
uint8_t button1S; // храним состояния кнопок (S - State) uint8_t button1F; // флажки кнопок (F - Flag) uint8_t button1R; // флажки кнопок на отпускание (R - Release) uint8_t button1P; // флажки кнопок на нажатие (P - Press) uint8_t button1H; // флажки кнопок на удержание (многократный вызов) (H - Hold) uint8_t button1HO; // флажки кнопок на удержание (один вызов при нажатии) (HO - Hold Once) uint8_t button1D; // флажки кнопок на двойное нажатие (D - Double) uint8_t button1DP; // флажки кнопок на двойное нажатие и отпускание (D - Double Pressed)
#define DOUBLE_TIMER 500 // время (мс), отведённое на второе нажатие #define HOLD 2000 // время (мс), после которого кнопка считается зажатой #define DEBOUNCE 50 // (мс), антидребезг uint32_t button1_timer; // таймер последнего нажатия кнопки uint32_t button1_double; // таймер двойного нажатия кнопки
uint8_tbuttons(void) { uint8_t bt1=0; // Будем возвращать результат в этой переменной
if (BitIsClear(BUT1_PIN,BUT1)) button1S=1; else button1S=0; // Состояние кнопки
// нажали (с антидребезгом) if (button1S && !button1F && millis - button1_timer > DEBOUNCE) { button1F = 1; // Установим флаг кнопки button1HO = 1; // флаг на удержание button1_timer = millis; // таймер последнего нажатия кнопки bt1=1; } // если отпустили до hold, считать отпущенной if (!button1S && button1F && !button1R && !button1DP && millis - button1_timer < HOLD) { button1R = 1; // флаг на отпускание button1F = 0; //флаг кнопки bt1=2; button1_double = millis; // Таймер двойного нажатия кнопки }
// если отпустили и прошло больше double_timer, считать 1 нажатием if (button1R && !button1DP && millis - button1_double > DOUBLE_TIMER) { button1R = 0; button1P = 1; bt1=3; }
// если отпустили и прошло меньше double_timer и нажата снова, считать что нажата 2 разa if (button1F && !button1DP && button1R && millis - button1_double < DOUBLE_TIMER) { button1F = 0; button1R = 0; button1DP = 1; bt1=4; }
// если была нажата 2 разa и отпущена, считать что была нажата 2 раза if (button1DP && millis - button1_timer < HOLD) { button1DP = 0; button1D = 1; button1_timer = millis; bt1=5; }
// Если удерживается более hold, то считать удержанием if (button1F && !button1D && !button1H && millis - button1_timer > HOLD) { button1H = 1; bt1=6; }
// Если отпущена после hold, то считать, что была удержана if (!button1S && button1F && millis - button1_timer > HOLD) { button1F = 0; button1H = 0; button1_timer = millis; bt1=7; }
// отработка режимов (опускание флага обязательно!) if (button1P) button1P = 0; if (button1D) button1D = 0; if (button1H && button1HO) button1HO = 0; if (button1H) button1H = 0;
uint8_t main_dark_mode=0; // Переменная для хранения режима теневого меню. uint8_t sub_mode=0; // флаг входа в подменю uint8_t edit_mode=0; // пока не используется uint8_t b=0; // счетчик нажатия кнопки uint8_t pr_var=0; // Переменная, которая в подменю будет инкрементироваться по нажатию кнопки от 0 до 9 uint8_t pr[6]={0,1,2,3,4,5}; // Массив для разбивки пробега(или еще чего-то) поразрядно для возможности коррекции(тест)
voidmain_text(void)// Основной текст меню // Построчный вывод пунктов меню { print_string_5x8(11,0,"MILEAGE(km)"); // Вывод типа " -> MILLEAGE(km)" print_string_5x8(11,1,"SPEED SENSOR(imp)"); print_string_5x8(11,2,"INJECTOR (cc/min)"); print_string_5x8(11,3,"FUEL TANK MIN NOW"); print_string_5x8(11,4,"FUEL TANK MAX NOW"); }
voidmain_dark_menu(void) { screen_clear(); if (cod==3) // Если нажали и отпустили кнопку { main_dark_mode++; // Бегаем по основному меню if(main_dark_mode>4) main_dark_mode=0; // Бегаем по кругу } switch (main_dark_mode) { case0: // коррекция пробега pointer_clear(); // Очистка стрелочки print_string_5x8(0,main_dark_mode,"->"); // Cтрелка на нулевой строке, т.к. mode_1 сейчас равен нулю. main_text(); // Выводим все пункты основного меню
if (cod==5) // Если двойное нажатие, заходим в подменю { cod=0; // Сразу обнулим код нажатия кнопки screen_clear(); // Очистим экран sub_mode=1; // Зайдем в режим подменю
while(sub_mode) { cod=buttons(); print_string_5x8(16,2,"SET MILEAGE(km)"); // Тут печать пояснительного текста print_string_5x8(16,3,"x100000----x1"); print_string_5x8(16,4,"ALL 6 DIGIT"); screen_update(); correction(6,16,pr); // Заходим в функцию коррекции величин
if (cod==6) // Нужно как-то выйти из цикла.. { sub_mode=0; }
} } break;
case1: // Speed sensor pointer_clear(); print_string_5x8(0,main_dark_mode,"->"); main_text(); if (cod==5) { cod=0; // Сразу обнулим код нажатия кнопки screen_clear(); // Очистим экран sub_mode=1;
uint8_t a=51; // Параметр начала строки. Магическое число. С этой позиции курсора начинаем вывод
for (uint8_t i; i<size; i++) {
print_MediumNumbers(a,6,par[i]%10 + '0'); // Выводим все разряды корректируемой величины a+=12;
}
if (cod==5) // при двойном нажатии прыгаем на следующую циферку, которую нам необходимо изменить и подсвечиваем // ее инверсией { b++; // при каждом двойном нажатии кнопки инкрементируем переменную cod=0; //Обнуляем код нажатия для следующего скана if(b==size) b=0; // В зависимости от переданного в функцию количества разрядов корректируемой величины // инкрементируем разряды
pr_var=par[b]; // Читаем в переменную содержание элемента массива }
Попробовал я buttons() в симуляторе IMHO она нормально не будет работать с двойным кликом. Только если аппаратный антидребезг сделать. Кроме того, "флажки" не инициализируются, поэтому первый клик часто глючный.
Вот эта библиотека https://github.com/TanPitch/ButtonKing В симуляторе работает значительно лучше. Хотя на физической кнопке (типа Jog Dial) могут быть нюансы.
И ещё. button1_timer = millis; Эта операция не атомарная. Если прерывание с инкрементом millis сработает внутри, то может оказаться, что часть байтов этой переменной будет от старого состояния millis, часть - от нового. Это касается всех операций с millis.
Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 5
Вы не можете начинать темы Вы не можете отвечать на сообщения Вы не можете редактировать свои сообщения Вы не можете удалять свои сообщения Вы не можете добавлять вложения