6-ти канальный модуль радиоуправления на NRF24L01
|
|
Ramzses | Дата: Пятница, 24.01.2014, 19:11 | Сообщение # 1 |
Группа: Пользователи
Сообщений: 9
Статус: Offline
| За основу был взят проект с 4-ех канальным модулем http://avrproject.ru/publ....1-0-147 Т.к. для пульта у меня используется стационарное питание. То мне пришлось отказаться от гениального решения комрада exersizze. Подтягивающие резисторы тоже убрал,надеюсь получиться обойтись без них. В приемнике на тригере Шмидта как раз осталось два канала. По этому плату пришлось немного переразвести. Т.к. у меня все будет запитываться от 12В, а модули работают на 3.3В. Думал понизить сначала 7805 до 5В потом до 3.3В. Посмотрев даташит на 3.3V стабилизатор, я понял что скорее всего его должно быть достаточно для стабилизации моего напряжения. Помимо простого увеличения числа выводов мне необходимо еще различать длинные нажатия от коротких. В связи с тем что я не силен в программировании и создаю эту тему. Пока просто попытался адаптировать код под свои нужды без реализации задержки нажатия. Симулирую в протеусе т.к. модули еще идут. Контроллер пока только включается но почему то нажатия не передает. Ниже архив с разведенными платами в DipTrace Исходники кода и файл протеуса. Привожу полученный мною код:
Код $regfile = "attiny2313.dat" $crystal = 1000000
Dim W As Byte 'переменная с номером нажатой кнопки Const Pult = 1 'номер пульта, можно разграничить права для разных пультов
'кнопки Config Portb.0 = Input Config Portb.1 = Input Config Portd.6 = Input Config Portd.5 = Input Config Portd.4 = Input Config Portd.3 = Input
Pinb.0 = 1 Pinb.1 = 1 'включаем подтягивающие резисторы Pind.6 = 1 Pind.5 = 1 Pind.4 = 1 Pind.3 = 1
Config Portd.2 = Output 'сюда подключается светодиод индикации Portd.2 = 0 Led Alias Portd.2
Config Int0 = Falling 'прерывание по нисходящему фронту On Int0 Button Enable Interrupts 'разрешаем прерывания Enable Int0
'конфигурирование передатчика Declare Sub W_register(byval C_bytes As Byte) 'SPI (nRF24L01) команды Const Write_reg = &H20 'Определить Команду Записи В Реестр Const Wr_tx_pload = &HA0 'Определить Tx Полезной Нагрузки Адрес Регистра Const Flush_tx = &HE1 'Определить Флеш Tx Зарегистрировать Команду 'SPI (nRF24L01) регистры (адреса) Const Config_nrf = &H00 'Config адрес регистра Const En_aa = &H01 'Включить Автоматическое Подтверждение регистрации адреса Const En_rxaddr = &H02 'Включено Rx адреса " адрес регистра" Const Rf_ch = &H05 'RF channel' адрес регистра Const Rf_setup = &H06 'РФ Setup " (Настройка) адрес регистра" Const Status = &H07 'Статус " адрес регистра" Const Rx_addr_p0 = &H0A 'rx адрес Pipe0 " зарегистрировать адрес" Const Tx_addr = &H10 'TX address (адрес) Dim D_bytes(6) As Byte 'назначение ножек Config Spi = Soft , Din = Portb.6 , Dout = Portb.5 , Ss = Portb.3 , Clock = Portb.7 'конфигурация аппаратного SPI интерфейса Config Portb.4 = Output : Ce Alias Portb.4 'CE pin is output Config Portb.3 = Output : Ss Alias Portb.3 'SS pin is output Config Pinb.2 = Input : Irq Alias Pinb.2 'IRQ pin is input
Spiinit
Portd.2 = 1 Waitms 10 Portd.2 = 0
'Основной цикл программы Do
Waitms 10 Gosub Peredacha 'передаем данные
W = 0
Idle 'и отключаемся
Loop
End
'обработчик прерывания Button: 'здесь мы в цикле сканируем все подключенные кнопки Do Waitms 100 Dim B As Byte
If Pinb.0 = 0 Then W = 1 End If
If Pinb.1 = 0 Then W = 2 End If
If Pind.6 = 0 Then W = 3 End If
If Pind.5 = 0 Then W = 4 End If
If Pinb.4 = 0 Then W = 5 End If
If Pinb.3 = 0 Then W = 6 End If
If W <> 0 Then Portd.2 = 1 Waitms 100 Portd.2 = 0 End If
Incr B
Loop Until W <> 0 Or B > 10 'если дребезг помешал вычислению нажатой кнопки, повторяем
Waitms 10 Gifr = 64 'сброс флага прерывания
Return
'подпрограма передачи данных Peredacha: Set Ce Waitms 10 Reset Ce Reset Ss
D_bytes(1) = Flush_tx 'Flush the TX_fifo буфера Call W_register(1) D_bytes(1) = Write_reg + Status 'Reset IRQ бит D_bytes(2) = &B00110000 Call W_register(2)
Gosub Setup_tx 'Настройка nrf240l01 для TX D_bytes(1) = Wr_tx_pload 'Положи 5 байт в TX pload буфера D_bytes(2) = W 'Байт 1 отправляем номер нажатой кнопки D_bytes(3) = &H00 'Байт 2 D_bytes(4) = &H00 'Байт 3 D_bytes(5) = &H00 'Байт 4 D_bytes(6) = Pult 'Байт 5 идентификационный номер пульта Call W_register(6) 'Запись 6 байт для регистрации
Waitms 2 Set Ce 'Set CE, чтобы передать буфер fifo Waitms 1 Reset Ce
Return
'подпрограммы для настройки и работы с передатчиком Sub W_register(byval C_bytes As Byte) 'Пишите зарегистрировать с SPI Reset Ss 'Руководство управления СС контакт, установить СС низких до смещение, байт Spiout D_bytes(1) , C_bytes 'Shiftout байты данных SPI корыта, C_bytes это количество байт, которые будут написаны Set Ss 'Set СС высокого End Sub
Setup_tx: 'Подготовка к TX D_bytes(1) = Write_reg + Tx_addr 'TX адрес D_bytes(2) = &H34 D_bytes(3) = &H43 D_bytes(4) = &H10 D_bytes(5) = &H10 D_bytes(6) = &H01 Call W_register(6) D_bytes(1) = Write_reg + Rx_addr_p0 'RX адрес для pipe0 D_bytes(2) = &H34 D_bytes(3) = &H43 D_bytes(4) = &H10 D_bytes(5) = &H10 D_bytes(6) = &H01 Call W_register(6) D_bytes(1) = Write_reg + En_aa 'Enable auto ACK на pipe0 D_bytes(2) = &H01 Call W_register(2) D_bytes(1) = Write_reg + En_rxaddr 'Включить RX адрес для pipe0 D_bytes(2) = &H01 Call W_register(2) D_bytes(1) = Write_reg + Rf_ch 'Настройка каналов D_bytes(2) = 40 'Частота 2440 MГц Call W_register(2) D_bytes(1) = Write_reg + Rf_setup 'Настройка РФ -> Выходной мощности 0 дБм, datarate 2 Мбит / с МШУ D_bytes(2) = &H0F Call W_register(2) D_bytes(1) = Write_reg + Config_nrf 'Настройка CONFIG -> I=0 (TX_device), PWR_UP=1, CRC 2bytes, Включить CRC D_bytes(2) = &H0E Call W_register(2) Return
Сообщение отредактировал Ramzses - Пятница, 24.01.2014, 19:12 |
|
| |
Valera18 | Дата: Суббота, 25.01.2014, 15:14 | Сообщение # 2 |
Группа: Проверенные
Сообщений: 22
Статус: Offline
| То-есть Attiny2313 постоянно подключена к питанию через блок питания 12V? Если ДА, то можно и так:
Сообщение отредактировал Valera18 - Суббота, 25.01.2014, 15:59 |
|
| |
Ramzses | Дата: Понедельник, 27.01.2014, 15:16 | Сообщение # 3 |
Группа: Пользователи
Сообщений: 9
Статус: Offline
| Спасибо огромное, но мне бы хотелось использовать внутренние подтягивающие резисторы. Я не знаю как с внешними грамотно развести плату что бы она занимала не много места. Или ничего страшного что я буду использовать внутренние?
В идеале мне нужно теперь что бы одна кнопка различала длинное нажатие от короткого ( для включения, выключения) И еще две кнопки работали как например увеличение громкости, получится ли так? или из за задержки не получится это нормально реализовать?
Теперь мне нужен счетчик что бы я мог определять длинное нажатие или короткое верно? Длинное нажатие у меня будет где-то 1с. Смысл получается такой:
Код If Pinb.0=0 Then 'кнопка нажата, тогда Waitms 900 'ждем 900мс if Pinb.0=0 = 1 Then 'кнопка нажата, тогда K11 'переходим на К11 Else ' в противном случае K1 'переходим на К1 End If
Как это правильно вставить в функцию Debounce?
Сообщение отредактировал Ramzses - Понедельник, 27.01.2014, 16:00 |
|
| |
Valera18 | Дата: Понедельник, 27.01.2014, 16:17 | Сообщение # 4 |
Группа: Проверенные
Сообщений: 22
Статус: Offline
| Во первых нужно понимать что микроконтроллер работает последовательно (т.е. последовательно выполняет прошитый код). Пример: сначала обработка длинного нажатия, а уже после увеличение или уменьшении громкости - всё это выполняется МК последовательно, поэтому одновременно не получится.
Я давно работал над пультом с функцией длинного нажатия на кнопку использовал такой "Последовательный" способ: 1 кнопка на порте Pind.2 2 кнопка на порте Pind.3
Config Pind.2 = Input : Pind.2 = 1 'Разблокировка Config Pind.3 = Input : Pind.3 = 1 'Блокировка
Do 'Цикл
If Pind.2 = 0 And Pind.3 = 1 Then 'Разблокировка Wait 4 'Задержка 4 секунды If Pind.2 = 0 And Pind.3 = 1 Then Prom = 1 'Номер передачи Gosub Tx 'Передача данных End If Else If Pind.3 = 0 And Pind.2 = 1 Then 'Блокировка Wait 4 'Задержка 4 секунды If Pind.3 = 0 And Pind.2 = 1 Then Prom = 2 'Номер передачи Gosub Tx 'Передача данных End If End If End If
Bitwait Pind.2 , Set 'Ждём пока кнопка будет отпущена Bitwait Pind.3 , Set 'Ждём пока кнопка будет отпущена
NOP 'Микросекундная задержка, чтобы не запороть МК цикличностью Loop 'Конец цикла End
Объясняю что происходит: Нажимаю 1 кнопку (порт Pind.2 был =1 переходит 0) активируется задержка на 4 секунды по истечению 4 секунд если порт остался Pind.2=0 (это долгое нажатие), то выполняется передача, если по истечению 4 секунд порт Pind.2=1, следовательно, кнопка была отпущена (это кратковременное нажатие) поэтому передача не выполняется. Также и со 2 кнопкой. Практика показывала, что лучше использовать внешнюю подтяжку для каждой кнопки на 10 кОм к плюсу питания, то есть повышается помехоустойчивость кнопок к ложным срабатываниям.
Сообщение отредактировал Valera18 - Понедельник, 27.01.2014, 16:27 |
|
| |
Valera18 | Дата: Понедельник, 27.01.2014, 16:34 | Сообщение # 5 |
Группа: Проверенные
Сообщений: 22
Статус: Offline
| Функция Debounce лучше использовать на тех кнопках на которых нет задержек, то есть мгновенное выполнение действий. Debounce защищён от цикличности, то есть выполняет один раз. Условие If Pind.2 = 0 Then можно использовать с задержками. Условие If Pind.2 = 0 Then не защищено от цикличности, то есть может выполнять до бесконечности, для остановки цикличности используют Bitwait Pind.2 , Set
|
|
| |
Ramzses | Дата: Понедельник, 27.01.2014, 17:16 | Сообщение # 6 |
Группа: Пользователи
Сообщений: 9
Статус: Offline
| Спасибо огромное. У меня будет управление плеером.Из чего мне получается необходимо: 1. Вкл/Выкл (Длинное нажатие) + Пауза (короткое) 2. Трек Вперед. (Debounce нажатие) 3. Трек Назад. (Debounce нажатие) 4. Режимы (Debounce нажатие) 5. Громкость + 6. Громкость -
В принципе у меня 50 делений громкости. Может будет проще сделать например что бы при нажатии либо увеличения либо уменьшения громкости приемник просто дрыгал 5 раз пином порта ( регулировка громкости +- 5 получится. Либо какая получается задержка между нажатиями ( что бы просто увеличивать и уменьшать громкость с шагом +-1 ) ?
Таким образом основной цикл моей программы будет выглядеть так?
Do
'Кнопка включение+пауза If Pinb.0 = 0 Then 'кнопка нажата, тогда Waitms 900 'ждем 900мс If Pinb.0 = 0 = 1 Then 'кнопка нажата, тогда W = 11 Gosub Tx 'отправляем код длинного нажатия Else 'в противном случае W = 1 Gosub Tx 'отправляем код короткого нажатия End If End If
Debounce Pinb.1 , 0 , K2 , Sub 'Кнопка №2 Debounce Pind.6 , 0 , K3 , Sub 'Кнопка №3 Debounce Pind.5 , 0 , K4 , Sub 'Кнопка №4
'Кнопки громкости If Pind.3 = 0 And Pind.4 = 1 Then 'Разблокировка Waitms 500 'Задержка 4 секунды If Pind.3 = 0 And Pind.4 = 1 Then W = 5 'Номер передачи Gosub Tx 'Передача данных End If Else If Pind.4 = 0 And Pind.3 = 1 Then 'Блокировка Waitms 500 'Задержка 4 секунды If Pind.4 = 0 And Pind.3 = 1 Then W = 6 'Номер передачи Gosub Tx 'Передача данных End If End If End If
Bitwait Pind.3 , Set 'Ждём пока кнопка будет отпущена Bitwait Pind.4 , Set 'Ждём пока кнопка будет отпущена
Nop 'Микрозадержка для цикла Loop
А получится ли у меня подключить мои выходы для регулировки громкости к поворотному энкодеру? Может мне вообще от управления громкостью отказаться?
PS В архиве попытка подключения приемника к передатчику в протеусе.
Сообщение отредактировал Ramzses - Понедельник, 27.01.2014, 18:36 |
|
| |