Карма: 4
Рейтинг сообщений: 15
Зарегистрирован: Ср янв 26, 2011 13:43:30 Сообщений: 414 Откуда: С того берега моря
Рейтинг сообщения:0
Всем привет. Собираю проект для контроля света в гараже. Суть такая, прикошатил ПИР датчик с дискретным выходом, фотодатчик с оу с выходом 0-5В и клавишу включения 220В, так же есть регулировка чувствительности фотосенсора потенциометром. Алгоритм придумал такой: Если темно и человек заходит в зону ПИР датчика, включаю через задержку лампу, ухожу - из поле ПИРА, через задержку выключаю (ПИР сам формирует задержку от ложных срабатываний). Если светло, лампу не включаю, если нажимаю клавишу включения света - то включаю лампу в любом случае (главный приоритет), если забыли выключить клавишу, через несколько часов отключаем свет (в коде я пока много не ставил, что бы в проверить можно было). В программирование не особо силен (особенно в настройке периферии). Нужна помощь. Начал кодить, и что-то проект мой что в железе, что в протеусе сходит с ума. Проект делал в CVAVR. Исходник с файлом протеуса в пристежке. Ткните, что я не так сделал. ЗЫ: Использую настройки тактирования камня по дефалту. т.е 9,6МГц/CKDIV = 1,2МГц... Таймер тикает на 1,200000/8 = 150 000.
_________________ - Бежит этот подлец-электрон, а вокруг его масса (аж 10 в 23й) штук ионов кремния и 10 в 15й ионов примеси и он, подлец, взаимодействует!
А как 8 битным таймером считать несколько часов???
Еще, лень распаковывать проект, тем более, у меня нет КодеВижена, зато есть АВРСтудия, в которую по любому ваш код не смогу портировать... Поэтому, если не сложно, то выложите свой код в теги под спойлер.
Заголовок сообщения: Re: Контроллер света на Attiny13
Добавлено: Вт май 03, 2016 20:54:07
Мучитель микросхем
Карма: 4
Рейтинг сообщений: 15
Зарегистрирован: Ср янв 26, 2011 13:43:30 Сообщений: 414 Откуда: С того берега моря
Рейтинг сообщения:0
СКАЗОЧНИК писал(а):
А как 8 битным таймером считать несколько часов???
Еще, лень распаковывать проект, тем более, у меня нет КодеВижена, зато есть АВРСтудия, в которую по любому ваш код не смогу портировать... Поэтому, если не сложно, то выложите свой код в теги под спойлер.
Вроде все настроил, в протеусе пашет... Только проверил. Настроил таймер по переполнению CTC Mode, в OCRA записал 95 - это дало мне 1 мс. По поводу пари часов, разве не получится инкрементируя переменную накопить нужное число и выполнить действие? Вот инит:
// ADC interrupt service routine // with auto input scanning interrupt [ADC_INT] void adc_isr(void) { static unsigned char input_index=0; // Read the AD conversion result adc_data[input_index]=ADCW; // Select next ADC input if (++input_index > (LAST_ADC_INPUT-FIRST_ADC_INPUT)) input_index=0; ADMUX=(FIRST_ADC_INPUT | ADC_VREF_TYPE)+input_index; // Delay needed for the stabilization of the ADC input voltage delay_us(10); // Start the AD conversion ADCSRA|=(1<<ADSC); }
volatile unsigned int on=0, tic_tac=0, tic_down=0; // Счетчик; volatile unsigned int outdoor_sensor; // Датчик света; volatile unsigned int sensivity; // Регулировка чувствительности; volatile unsigned char key_on_flag = 0; // состояние выключателя 0 - выключен;
// Timer 0 output compare A interrupt service routine interrupt [TIM0_COMPA] void timer0_compa_isr(void) { static unsigned char counter = 15; // Счетчик для сетевого віключателя;
TCNT0=0x00; if(key) { // считали 1 - похоже, выключен; // проверяем сколько времени прошло; if(counter) { // время не вышло; counter --; } else { // прошло 15 миллисекунд выключатель выключен key_on_flag = 0; counter = 15; // устанавливаем счётчик заново } } else { // считали 0 - включён key_on_flag = 1; counter = 20; // устанавливаем счётчик заново } if (key_on_flag) // Запуск таймера включения кнопки (антидребезг); tic_tac++; else tic_tac=0;
if (!pir && key_on_flag==0){ // Задержка на включение, антидребезг ПИР дачика; on++; } else { on=0; //TCNT0=0; }
}
void adc_read (void) // Функция считывания значения из АЦП. АЦП 8бит; { outdoor_sensor=adc_data[1]; // Значение 1 канала, PORTB2 ; sensivity=adc_data[0]; // Значение 2 канала читаем из массива сканированных каналов АЦП, PORTB4; }
if (key_on==1 && tic_tac>=debounce) // Приоритет включения по клавише; { out=1; while (key_on==1 && tic_tac>=lamp_off_time) { out=0; }
} else { adc_read (); //Функция чтения значения из АЦП (0-255);
if (!pir&&on>=pir_delay&&outdoor_sensor>=sensivity) // Пир сработал, выключатель отключен, фотодатчик сработал;
out = 1; // Порт включен; // else if (pir||((outdoor_sensor<=sensivity)||outdoor_sensor==0)&& tic_down>=off_time) // out = 0; else out = 0; // Порт выключен; }
} }
Я потом это перенесу в Атмел студио. Кодвижн использую только для настройки... Пока не совсем могу хорошо настроить периферию...
_________________ - Бежит этот подлец-электрон, а вокруг его масса (аж 10 в 23й) штук ионов кремния и 10 в 15й ионов примеси и он, подлец, взаимодействует!
В проекте, который Вы выложили в начале этой темы, инициализация периферии сделана правильно, кроме одного. Выкиньте этот кусок кода нафиг. Совсем. Тогда тактовая частота будет определяться только фьюзами CKSEL0, CKSEL1 и CKDIV8. А если он Вам очень дорог, то сделайте предделитель на 8:
Заголовок сообщения: Re: Контроллер света на Attiny13
Добавлено: Ср май 04, 2016 08:54:44
Мучитель микросхем
Карма: 4
Рейтинг сообщений: 15
Зарегистрирован: Ср янв 26, 2011 13:43:30 Сообщений: 414 Откуда: С того берега моря
Рейтинг сообщения:0
Я читал давно где-то на форуме, что free running не очень хорошая идея. А вот почему, можете объяснить? PS: осциллограф не поверите, вчера пришел ко мне...
_________________ - Бежит этот подлец-электрон, а вокруг его масса (аж 10 в 23й) штук ионов кремния и 10 в 15й ионов примеси и он, подлец, взаимодействует!
Почему? Очень даже нормальный режим, когда надо делать очень много отсчётов за короткое время. АЦП перезапускает сам себя. Остаётся только считывать результат по прерыванию. Короче цикла не придумаешь. А для Вашей задачи, одного отсчёта каждую миллисекунду более чем достаточно, поэтому режим Free Running нафиг не нужен.
В начале обработчика прерывания от таймера выведите в порт единичку, а в конце обработчика - нолик. И посмотрите осциллографом, как оно работает. А то протеус конечно хорошо, но в живую лучше.
Кстати, чуть не забыл. При работе таймера в режиме CTC, в регистр сравнения OCR0A надо записывать число на единицу меньше, чем получилось по расчёту. Т.е. чтобы получилась ровно миллисекунда, надо прописать 149, а не 150.
Заголовок сообщения: Re: Контроллер света на Attiny13
Добавлено: Ср май 04, 2016 13:44:08
Мучитель микросхем
Карма: 4
Рейтинг сообщений: 15
Зарегистрирован: Ср янв 26, 2011 13:43:30 Сообщений: 414 Откуда: С того берега моря
Рейтинг сообщения:0
Так, все заработало. Я тут немного подправил. Осталось логику додумать, ибо фотодатчик получился слишком не инерционен..
_________________ - Бежит этот подлец-электрон, а вокруг его масса (аж 10 в 23й) штук ионов кремния и 10 в 15й ионов примеси и он, подлец, взаимодействует!
if (key_on==1 && tic_tac>=debounce) // Приоритет включения по клавише; { out=1;
while (key_on==1 && i>=overflow_time)//lamp_off_time) { out=0; }
if (key_on==0) { out=0; } }
Блин не работает... Если пишу например
Код:
volatile unsigned long int overflow_time = 60000;
Все работает хорошо... В чем затык?
_________________ - Бежит этот подлец-электрон, а вокруг его масса (аж 10 в 23й) штук ионов кремния и 10 в 15й ионов примеси и он, подлец, взаимодействует!
О.... Пока писал, отработало!!! =) Оптимальнее будет работать с большим числом? Или наделать циклов?
_________________ - Бежит этот подлец-электрон, а вокруг его масса (аж 10 в 23й) штук ионов кремния и 10 в 15й ионов примеси и он, подлец, взаимодействует!
Заголовок сообщения: Re: Контроллер света на Attiny13
Добавлено: Чт авг 18, 2016 15:46:46
Мучитель микросхем
Карма: 4
Рейтинг сообщений: 15
Зарегистрирован: Ср янв 26, 2011 13:43:30 Сообщений: 414 Откуда: С того берега моря
Рейтинг сообщения:0
Всем привет. Девайс собрал, но пока не устанавливал. На столе работает отлично. Тут такое дело. Я захотел переписать код в Atmel studio, компиллируется без ошибок, но не работает нормально. Может где-то напутал с битами входов выходов (в Atmel Studii как-то по другому все =)) Помогите пожалуйста найти ошибку.
ISR(ADC_vect) { static unsigned char input_index=0; // Read the AD conversion result adcScanningData[input_index]=ADCW; // Select next ADC input if (++input_index > (LAST_ADC_INPUT-FIRST_ADC_INPUT)) input_index=0; ADMUX=(FIRST_ADC_INPUT | ADC_VREF_TYPE)+input_index; // Delay needed for the stabilization of the ADC input voltage _delay_us(10); // Start the AD conversion ADCSRA|=(1<<ADSC); }
// Timer0 compare interrupt;
ISR (TIM0_COMPA_vect) { // Counter for light switch; static unsigned char acNetCounter = 15; // TCNT0=0x00; if((PINB &_BV(PINB1))==1) { // Read 1 state - switch is active; // Time checking; if(acNetCounter) { // time is not run; acNetCounter --; } else { // 15 mseconds switch is on; keyFlag = 0; // set the counter again; acNetCounter = 15; } } else { // Read 0 - Switch is on; keyFlag = 1; // set the counter again; acNetCounter = 15; } // Start with switch / debounnce; if (keyFlag==1) { timeCounter++; if (timeCounter>=DEBOUNCE) { timeCounter = DEBOUNCE; timeCounter++;
if (milliSeconds==999) { milliSeconds=0; seconds++;
_________________ - Бежит этот подлец-электрон, а вокруг его масса (аж 10 в 23й) штук ионов кремния и 10 в 15й ионов примеси и он, подлец, взаимодействует!
#define BULB 3 #define FIRST_ADC_INPUT 1 #define LAST_ADC_INPUT 2 // Bandgap Voltage Reference: Off #define ADC_VREF_TYPE ((0<<REFS0) | (0<<ADLAR))
volatile unsigned int adcScanningData[LAST_ADC_INPUT-FIRST_ADC_INPUT+1]; volatile char photoSeensor; volatile char sensivity;
ISR(ADC_vect) { static unsigned char input_index=0; // Read the AD conversion result adcScanningData[input_index]=ADCW; // Select next ADC input if (++input_index > (LAST_ADC_INPUT-FIRST_ADC_INPUT)) input_index=0; ADMUX=(FIRST_ADC_INPUT | ADC_VREF_TYPE)+input_index; // Delay needed for the stabilization of the ADC input voltage _delay_us(10); // Start the AD conversion ADCSRA|=(1<<ADSC); }
Вот функция опроса двух каналов
Код:
void adcInputsread (void) { // first channel value, PORTB2 ; photoSeensor=adcScanningData[1]; // second channel value, PORTB4; sensivity=adcScanningData[0]; }
Вот основной код для проверки. Если напряжение на входе больше напряжения порога (на втором входе) Включаем Пин. Если нет, то выключаем.
Код:
if (photoSeensor>=sensivity) { // Out is log 1; PORTB |=(1<<BULB); } else if(photoSeensor<sensivity) PORTB &=~(1<<BULB);
Моделирую в протеусе, и там происходит следующее. Устанавливаю опорное напряжение (sensivity) потенциометром и фиксирую. И начинаю от нижнего края потенциометра, который посажен на вход (photoSeensor) двигать ползунок к большему значению. Выход у меня начинает загораться хаотично при движении ползунка в любую сторону, хотя должен строго выше опорного напряжения срабатывать, а ниже опорного отключаться. Что это происходит?
_________________ - Бежит этот подлец-электрон, а вокруг его масса (аж 10 в 23й) штук ионов кремния и 10 в 15й ионов примеси и он, подлец, взаимодействует!
Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 27
Вы не можете начинать темы Вы не можете отвечать на сообщения Вы не можете редактировать свои сообщения Вы не можете удалять свои сообщения Вы не можете добавлять вложения