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

Компьютеризированное Колесо


G1KuL1N

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

Решил взять и освоить AVR (захотелось не только чужие конструкции на МК повторять).

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

Составил ТЗ.

Устройство должно измерять:

- расстояние которое грызун пробегает в метрах

- скорость в метрах в секунду.

- количество подходов к "снаряду"

Данные выводятся на дисплей 16х2

Так же должны быть кнопки RESET - сброс счетчиков в ноль, и включения\выключения подсветки дисплея (котрая подключается к порту PC0 через транзисторный ключ).

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

Написал программу для меги8 (частота 4МГц) - кнопки, расчет скорости и пройденного расстояния сделал. Но ни как не могу додуматься как реализовать счетчик "подходов к снаряду". Принцип такой - если датчик не срабатывает 5сек, то при последующем срабатывании датчика в переменную плюсуется 1, которая через спринтф выводится на дисплей. Понятно что надо замутить таймер на 5сек который стартует при каждом срабатывании датчика - а вот как дальше, ставить условие?? Подскажите как реализовать этот счетчик?

Еще думал записывать периодически переменные в EEPROM на случай отключения питания, но думаю это нафиг не надо :)

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

И еще один вопросик - правильно ли я вписал в обработчик прерывания INT0 задержку на дребезг контактов геркона?

Код (просьба сильно не пинать если где по дурацки составлен :D )

#include <mega8.h>
#include <stdlib.h>
#include <stdio.h>
#include <lcd.h>
#include <delay.h>

#asm
  .equ __lcd_port=0x18 ;PORTB
#endasm


float s=0, v=0 , x=0.435, t=0;
bit flag = 0;

void tmr_start() { 
TCNT1=0; 
TCCR1B=0x04; 
} 

void tmr_stop(void) { 
TCCR1B=0x00;
}


interrupt [EXT_INT0] void ext_int0_isr(void)
{
char buf[10];
delay_ms(50); //Правильно ли вписана задержка для устранения дребезга контактов геркона??
s=s+x;          
sprintf (buf,"%3.2f",s);   
lcd_gotoxy(0,0);               
lcd_puts(buf);
tmr_stop();  
t=TCNT1/31.25;  
tmr_start();
t=t/475;
v=x/t;
sprintf (buf,"%3.2f",v);   
lcd_gotoxy(0,1);           
lcd_puts(buf);
}

void set(){ 
flag = !flag; 
PORTC.0 = flag; 
} 

void main(void)
{

PORTC=0x00;
DDRC=0x03;

PORTD=0x1C;
DDRD=0x00;

GICR|=0xC0;
MCUCR=0x02;
GIFR=0xC0;

lcd_init(16);
lcd_gotoxy(7,0);
lcd_putsf("  METERS");
lcd_gotoxy(4,1);
lcd_putsf("M/S");
#asm("sei")

{ 
while (1) 
  {   
  if (PIND.4==0) { 
  delay_ms(50);  
  if (PIND.4==0) set();    
  else continue; 
  } 
  else continue; 

  while(PIND.4==0) {}; 
  delay_ms(50);   
  }; 

while (1) { };
}
}

f45fa8c0ad27e077f441cb5540e7483a.jpg

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

Кто-то куёт Metal, а я паяю Industrial © G1KuL1N (А то уже по всему интернету растащили :)

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

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

Оказывается ларчик открывался просто :D зато изучил таймеры вдоль и поперек.

.........
unsigned int num,p;

interrupt [TIM1_COMPA] void timer1_compa_isr(void)
{
 TCNT1H=0;
 TCNT1L=0;
 num++; 
}

char buf[10];
interrupt [EXT_INT0] void ext_int0_isr(void)
{
.......
if (num>=5)
p++;
num=0;
sprintf (buf,"%i",p);   
lcd_gotoxy(10,0);               
lcd_puts(buf);

}
............

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

Кто-то куёт Metal, а я паяю Industrial © G1KuL1N (А то уже по всему интернету растащили :)

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

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

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

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

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

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

Вот что получилось, ИМХО неплохо для первого проекта.

#include <mega8.h>
#include <stdio.h>
#include <lcd.h>
#include <delay.h>

#asm
  .equ __lcd_port=0x18 ;PORTB //Дисплей подключается к порту B
#endasm

float v,s=0, x=0.44 ;
bit flag = 0;
unsigned int num=0,p=1,t;
char buf[10];


interrupt [TIM2_OVF] void timer2_ovf_isr(void) {   // прерывание по переполнению таймера TCCR2 раз в 3.3333ms
t++;    // инкрементирруем
}

interrupt [TIM1_COMPA] void timer1_compa_isr(void) {   // прерывание по сравнению таймера TCCR1 раз в 1s
TCNT1H=0;
TCNT1L=0;
num++;   // инкрементирруем
}


interrupt [EXT_INT0] void ext_int0_isr(void) {  // прерывание INT0 по срабатыванию датчика
delay_ms(50); //антидребезг
s=s+x;        // увеличение пройденного расстояния с каждым срабатыванием датчика  
sprintf (buf,"%3.2f",s);  //вывод на дисплей пройденного расстояния 
lcd_gotoxy(0,1);   // координаты вывода на дисплей знак,строка            
lcd_puts(buf);    
if (num>=5)   // если таймер TCCR1 отсчитал 5сек то
p++;          // увеличиваем количество подходов на 1 при следующем внешнем прерывании INT0
num=0;        // сброс таймера TCCR1
sprintf (buf,"%i",p);  // вывод на LCD кол-ва подходов 
lcd_gotoxy(10,0); // координаты вывода на дисплей знак,строка              
lcd_puts(buf);
v=x/t;       //рассчет скорости между срабатываниями датчика
t=0;         //сброс таймера TCCR2
v=v*30;      //приведение скорости к метрам в секунду
sprintf (buf,"%3.2f",v);  // вывод на LCD скорости 
lcd_gotoxy(8,1);           
lcd_puts(buf);
}

void set(){ // функция смены значения на выходе 
flag = !flag; 
PORTC.0 = flag; 
} 

void main(void) {
PORTC=0x00;  
DDRC=0x03;   
PORTD=0x1C;  
DDRD=0x00;
GICR|=0xC0;
MCUCR=0x02;
GIFR=0xC0;
TCCR1B=0x05;
OCR1AH=0x1E;
OCR1AL=0x85;
TIMSK=0x50; // разрешение прерываний от таймеров
ASSR=0x00;
TCCR2=0x07;
TCNT2=0x00;
OCR2=0x00;

lcd_init(16);
lcd_gotoxy(0,0);
lcd_putsf("METERS");
lcd_gotoxy(12,1);
lcd_putsf("M/S");
lcd_gotoxy(0,1);
lcd_putsf("0.00");
lcd_gotoxy(8,0);
lcd_putsf("P=0");
lcd_gotoxy(8,1);
lcd_putsf("0.00");

#asm("sei") // разрешение глобальных прерываний

{ 
while (1) 
  {   
  if (PIND.4==0) { // ждем нажатия 
  delay_ms(50); // антидребезг 
  if (PIND.4==0) set(); // если все норм, переключаем   
  else continue; 
  } 
  else continue; 

  while(PIND.4==0) {}; // ждем отпускания кнопки 
  delay_ms(50); // антидребезг   
  }; 

while (1){};
}
}

97093dbb8de91b66dc77be85b48fd055.jpg

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

Кто-то куёт Metal, а я паяю Industrial © G1KuL1N (А то уже по всему интернету растащили :)

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

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

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

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

Оговорюсь сразу, код полностью не читал. Реализация подсчёта "подходов" я бы сделал так.

#define STOP   0
#define WORK  1

// глобальные переменные
unsigned char work_stop = STOP; // текущее состояние простой или подход 
unsigned char counter_work=0; 	// общее количество подходов
unsigned char timeout_5sek=0; // переменная помогающая вычислить простой 5 секунд между подходами

............
// допишем немного кода в обработчик прерывания от датчика 
interrupt [EXT_INT0] void ext_int0_isr(void) {  // прерывание INT0 по срабатыванию датчика
...............
if (work_stop == STOP) { // условие выполняется если простой
  work_stop= WORK; // подход начат
  counter_work +=1; // увеличиваем количество подходов
  timeout_5sek = 5; // "взводим" программный таймер на 5 секунд
}else{ // предыдущее срабатывание датчика было менее 5-и секунд назад
  timeout_5sek = 5; // обновляем "завод" таймера
} 
...............
}

// допишем немного кода в обработчик прерывания от таймера
interrupt [TIM1_COMPA] void timer1_compa_isr(void) {   // прерывание по сравнению таймера TCCR1 раз в 1s
...................
  if ( timeout_5sek ) { // если 5 секунд после сработки датчика ещё не прошли,
     timeout_5sek--; // то уменьшаем софт-таймер
     if ( timeout_5sek == 0 ) {// если после уменьшения он стал нулём, то
        work_stop = STOP; // подход полностью завершён
     }
  }
...................
}

Пока ты жив, надежда есть.

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

@mazzi, спасибо за ответ.

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

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

Кто-то куёт Metal, а я паяю Industrial © G1KuL1N (А то уже по всему интернету растащили :)

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

Рациональный подход к написанию программ такой:

1) быстро пишем на Си

2) быстро отлаживаем алгоритм

Если всё уместилось в память и всё работает, то больше ничего делать не нужно.

Иначе начинаем профилировать и оптимизировать вплоть до написания критичных кусков кода на ассемблере.

Нужно всегда помнить, что:

---- лучшее враг хорошего!

---- совершенству нет пределов!

И ещё, если программа пишется "ради искусства", то тогда конечно, можно кайфовать и "выжимать" всё что можно и хочется.:rolleyes:

Пока ты жив, надежда есть.

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

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

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

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

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

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

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

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

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

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

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