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

Запись "заводских" настроек в EEPROM AtMega8


-=FISHER=-

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

1 hour ago, ARV said:

И мои советы могут быть, мягко говоря, не в струю.

Я просто пока вижу только один вариант, это отследив нажатие кнопки (кстати в автомате состояний, как вы меня когда-то научили), затем через if проверив включены ли габариты и исходя (как Вы мне показали только что) из значения direction отнять или прибавить яркость, и опять такие проверив перед этим через if, не уперся ли я в потолок или дно.

UPD: сейчас только понял что в автомате состояний не получится, так как отслеживать одно и то же нажатие нужно много раз подряд, не переходя в другое состояние.

Мы все учились по-немногу, чему-нибудь и как-нибудь...

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

Хотел сейчас записать функцию опроса кнопок вот так:

uint8_t get_button(void) //опрос сразе двух кнопок
{
	static unsigned char but_code;
	but_code=PIND & BUTTON_PINS;
	_delay_ms(10);
	if(but_code==(PIND & BUTTON_PINS))
	{
		return but_code;
	}
	else
	{
		return 0xff;
	}
}

void check_buttons(void)
{
	static unsigned char command;
	command=get_button();
	if(command==Command_CH0_BTN_CLICK) //нажали кнопку №1
	{
		if(input_state==GAB_ON)
		{
			
		}
		if(input_state==GAB_OFF)
		{
			
		}
	}
	
	if(command==Command_CH1_BTN_CLICK) //нажали кнопку №2
	{
		if(input_state==GAB_ON)
		{
			
		}
		if(input_state==GAB_OFF)
		{
			
		}
	}

	if(command==Command_ALL_BTN_OFF) //ни одна кнопка не нажата
	{
		if(direction){direction=-1;}
		else{direction=1;}
	}
}

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

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

Изменено пользователем -=FISHER=-

Мы все учились по-немногу, чему-нибудь и как-нибудь...

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

Как по мне, так функция опроса должна возвращать число, биты которого соответствуют состоянию кнопок. То есть в одном байте можно вернуть состояние до 8 кнопок, причем в различных комбинациях нажатий. Если все биты равны нулю, то кнопки не нажаты. Я именно так и делаю всегда в своих проектах.

А вот пример моего кода из одного проекта, который реализует автоповтор кодов нажатых кнопок при длительном удержании их в нажатом состоянии:

MAKE_TIMER(TR, 0, 0);

char key_repeater(char kk){
	static char old_kk;
	char result = 0;

	if(kk == 0){
		timer_stop(&TR);
	} else {
		if(old_kk != kk){
			timer_start(&TR, 1000, 0);
			result = kk;
		} else {
			if(timeout(&TR)){
				result = kk;
				timer_start(&TR, 300, 0);
			}
		}
	}
	old_kk = kk;
	return result;
}

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

- при первом изменении состояния кнопок сразу вернет код нажатий;
- при удержании более 1 секунды - начнет снова возвращать код каждые 0,3 с;
- во все прочие моменты будет возвращать 0.

То есть функция реализует алгоритм работы обычной клавиатуры компа: автоповтор начинается не сразу, а спустя секунду, но скорость автоповтора меньше 3 символа в секунду. Как часто эта функция будет вызываться - не имеет значения, т.к. работает в ней "фоновый" таймер TR.

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

Если забанить всех, кто набрался смелости думать независимо, здорово будет на форуме - как на кладбище: тишина, птички поют...

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

Сравнительное тестирование аккумуляторов EVE Energy и Samsung типоразмера 18650

Инженеры КОМПЭЛ провели сравнительное тестирование аккумуляторов EVE и Samsung популярного для бытовых и индустриальных применений типоразмера 18650. 

Для теста были выбраны аккумуляторы литий-никельмарганцевой системы: по два образца одного наименования каждого производителя – и протестированы на двух значениях тока разряда: 0,5 А и 2,5 А. Испытания проводились в нормальных условиях на электронной нагрузке EBD-USB от ZKEtech, а зарядка осуществлялась от лабораторного источника питания в режиме CC+CV в соответствии с рекомендациями в даташите на определенную модель. Подробнее>>

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

1 hour ago, ARV said:

Как по мне, так функция опроса должна возвращать число, биты которого соответствуют состоянию кнопок. То есть в одном байте можно вернуть состояние до 8 кнопок, причем в различных комбинациях нажатий. Если все биты равны нулю, то кнопки не нажаты. Я именно так и делаю всегда в своих проектах.

В коде, что я выше привел функция get_button тоже возвращает комбинацию битов, перед этим обрабатывая дребезг. А в вашем случае, Вы как раз результат работы аналогичной функции и передаете в key_repeater? И через определённое время транслируете дальше? А как потом анализируете? Вернула она вам например 0b00000001, какие дальше варианты?

Мы все учились по-немногу, чему-нибудь и как-нибудь...

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

Новый аккумулятор EVE серии PLM для GSM-трекеров, работающих в жёстких условиях (до -40°С)

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

Эти аккумуляторы поддерживают заряд при температуре от -40/-20°С (сниженным значением тока), безопасны (не воспламеняются и не взрываются) при механическом повреждении (протыкание и сдавливание), устойчивы к вибрации. Они могут применяться как для автотранспорта (трекеры, маячки, сигнализация), так и для промышленных устройств мониторинга, IoT-устройств. Подробнее параметры и результаты тестов новой серии PLM по ссылке.

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

Ну, у меня в главном цикле как-то так делается:

char key;

while(1){
	// это главный цикл
	
	key = key_repeater(get_button_presed());
	switch(key){
	case K_LEFT: 
		break;
	case K_RIGHT:
		break;
	case K_UP:
		break;
	case K_DN:
		break;
	}
}

Если кнопки не нажаты - ничего не делаю, а если нажаты - что-то делаю по коду нажатой комбинации.

Если забанить всех, кто набрался смелости думать независимо, здорово будет на форуме - как на кладбище: тишина, птички поют...

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

Литиевые батарейки и аккумуляторы от мирового лидера  EVE в Компэл

Компания Компэл, официальный дистрибьютор EVE Energy, бренда №1 по производству химических источников тока (ХИТ) в мире, предлагает продукцию EVE как со склада, так и под заказ. Компания EVE широко известна в странах Европы, Америки и Юго-Восточной Азии уже более 20 лет. Недавно EVE была объявлена поставщиком новых аккумуляторных элементов круглого формата для электрических моделей «нового класса» компании BMW.

Продукция EVE предназначена для самого широкого спектра применений – от бытового до промышленного. Подробнее>>

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

13 hours ago, ARV said:

Я именно так и делаю всегда в своих проектах.

Сейчас разбираю Ваш пример, появились вопросы.

1. Чтобы таймер запустился без выполнения процедуры, Вы запускаете его с параметром NULL вместо указания ссылки на функцию?

void StartTimer(SoftTimer *CurSoftTimer, enum StateTimer state, unsigned int time, void (*pFunc)());

StartTimer(&Timer_KK, ACTIVE, 1*sec, NULL);

2. Я правильно понимаю, что эта функция вернет TRUE если значения поля time для указанного таймера будет равно 0?

bool TimeoutTimer(SoftTimer *CurSoftTimer) //проверяем не вышло ли время
{
    return CurSoftTimer->time == 0;
}

if(TimeoutTimer(&Timer_KK)) //если время таймера вышло
{
	//что-то делаем
}

 

Изменено пользователем -=FISHER=-

Мы все учились по-немногу, чему-нибудь и как-нибудь...

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

Макрос MAKE_TIMER создаёт таймер, указанный в первом параметре. Второй параметр - период таймера, третий - вызываемая после истечения периода функция. Функция timer_start имеет точно такие же параметры. Если функция не указана, то надо опрашивать состояние таймера функцией timeout, которая вернет true, если таймерный период истек. Если функция указана при создании или старте таймера, то она будет вызвана по истечению периода. Если функция вернет true, таймер автоматически перезапустится с тем же периодом, если false, то таймер остановится. Функция таймера получает в параметре указатель на свой таймер и через него может изменить его период, если надо.

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

Если забанить всех, кто набрался смелости думать независимо, здорово будет на форуме - как на кладбище: тишина, птички поют...

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

@ARV У меня получилось адаптировать тот программный таймер который я использую под Ваши примеры (дописав пару функций и исправив существующие). Всё заработало как часы! Спасибо!

Осталось разобраться с "переворотом направления" изменения яркости, и морганием при упоре в потолок или пол. Разбираюсь.

Мы все учились по-немногу, чему-нибудь и как-нибудь...

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

14 часов назад, ARV сказал:

if(kk == 0){ timer_stop(&TR); }

Только вот в Вашем примере, если ни одна кнопка не нажата, то таймер останавливает,а мне ведь нужно чтобы в этом случае менялось направление...

И если я просто допишу в этот if, переворот значение direction, то оно будет меняться при каждом опросе кнопок.

Мы все учились по-немногу, чему-нибудь и как-нибудь...

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

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

Если забанить всех, кто набрался смелости думать независимо, здорово будет на форуме - как на кладбище: тишина, птички поют...

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

1 час назад, ARV сказал:

Внутрь функции повтора кода кнопок лезть не стоит.

Но ведь иначе "отжатие" кнопок не отследить?...

Мы все учились по-немногу, чему-нибудь и как-нибудь...

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

Тогда надо лезть так, чтобы заставить её выдавать разные коды для отсутствия кода при автоповторе и при отпускании кнопки. Сейчас втобоих случаях вернётся ноль, а надо эти случаи разделять.

Если забанить всех, кто набрался смелости думать независимо, здорово будет на форуме - как на кладбище: тишина, птички поют...

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

5 hours ago, -=FISHER=- said:

"отжатие" кнопок не отследить

Добавьте новую переменную в функцию check_buttons() для хранения предыдущего состояния кнопок. Если в предыдущем что-то было нажато, а текущее состояние == Command_ALL_BTN_OFF,  значит кнопка отпущена, и надо переворачивать направление.

Вот такое сравнение сработает только один раз при отпускании кнопки.

static unsigned char old_command;

if(old_command != Command_ALL_BTN_OFF && command == Command_ALL_BTN_OFF) //ни одна кнопка не нажата 
{
	if(direction == 1)
		direction = -1; 
	else
		direction = 1; 
}

old_command = command;

После проверки новое состояние записывается в old_command.

 

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

  • 3 недели спустя...
28.07.2019 в 01:17, Yurkin2015 сказал:

Вот такое сравнение сработает только один раз при отпускании кнопки.

Очень крутой вариант похоже!

Мы все учились по-немногу, чему-нибудь и как-нибудь...

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

27.07.2019 в 23:17, Yurkin2015 сказал:

if(direction == 1) 
	direction = -1; 
else 
	direction = 1;

 

Я бы заменил на

direction *= -1;

 

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

Если забанить всех, кто набрался смелости думать независимо, здорово будет на форуме - как на кладбище: тишина, птички поют...

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

Что за ерунду вы написали?! 

Знак у числа меняется умножением его на -1. Вы как-то забыли, разве, что число может быть по модулю больше 1?

Не надо заниматься битовой оптимизацией, доверьтесь компилятору, он все сделает в лучшем виде.

Если забанить всех, кто набрался смелости думать независимо, здорово будет на форуме - как на кладбище: тишина, птички поют...

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

19 часов назад, ARV сказал:

Я бы заменил на

Выглядит лаконичнее, надо бы запомнить.

Мы все учились по-немногу, чему-нибудь и как-нибудь...

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

Дело не в лаконичности, а в правильности. Математически знак у числа меняется умножением на -1, так и следует поступать, так и будет правильно.

А правильно - практически всегда красиво :) 

Если забанить всех, кто набрался смелости думать независимо, здорово будет на форуме - как на кладбище: тишина, птички поют...

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

  • 4 недели спустя...
14.08.2019 в 17:09, ARV сказал:

Я бы заменил на


direction *= -1;

Приветствую!

Я сделал именно так, но почему-то результат этого сокращенного выражения у меня получается 255, а не -1 как хотелось бы... переменная типа char. В чем я ошибаюсь?...

Или просто функция itoa не умеет переводить отрицательные числа в строку?

if(old_kk!=Command_NO_BTN_CLICK){dir*=-1; itoa(dir, tmp, 10); USART_SendStr(tmp);}

 

Изменено пользователем -=FISHER=-

Мы все учились по-немногу, чему-нибудь и как-нибудь...

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

itoa хочет иметь int на входе, а не char

Если забанить всех, кто набрался смелости думать независимо, здорово будет на форуме - как на кладбище: тишина, птички поют...

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

@ARV Но почему-то условие:

if(dir==-1){}

у меня вообще не выполняется после выражения:

dir*=-1;

 

Мы все учились по-немногу, чему-нибудь и как-нибудь...

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

А вы уверены, что dir у вас именно -1? Направление, как мне кажется, определяется не значением, а знаком. Например, -2 тоже будет "в другую сторону", но не равно -1.

Если забанить всех, кто набрался смелости думать независимо, здорово будет на форуме - как на кладбище: тишина, птички поют...

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

12 минут назад, ARV сказал:

А вы уверены, что dir у вас именно -1

Я объявляю и инициализирую переменную сразу так:

char dir = 1;

Затем при отжатии кнопки происходит действие:

dir*=-1;

Я предполагаю что значение переменной dir в таком случае может быть либо 1 либо -1.

Мы все учились по-немногу, чему-нибудь и как-нибудь...

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

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

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

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

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

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

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

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

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

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

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

  • Сообщения

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