[ Новые сообщения · Участники · Правила форума · Поиск · RSS ]
Страница 1 из 11
Модератор форума: RD3AVJ 
Форум » форумы » В разработке » 6-ти канальный модуль радиоуправления на NRF24L01 (Нужна помощь в разработке.)
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


Прикрепления: Dist_module.rar(84Kb) · 0534917.jpg(462Kb)




Сообщение отредактировал Ramzses - Пятница, 24.01.2014, 19:12
 
Valera18Дата: Суббота, 25.01.2014, 15:14 | Сообщение # 2
Группа: Проверенные
Сообщений: 22

Статус: Offline
То-есть Attiny2313 постоянно подключена к питанию через блок питания 12V?
Если ДА, то можно и так:
Прикрепления: __Attiny2313-6_.rar(332Kb)




Сообщение отредактировал 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 В архиве попытка подключения приемника к передатчику в протеусе.
Прикрепления: 6__.zip(17Kb)




Сообщение отредактировал Ramzses - Понедельник, 27.01.2014, 18:36
 
Форум » форумы » В разработке » 6-ти канальный модуль радиоуправления на NRF24L01 (Нужна помощь в разработке.)
Страница 1 из 11
Поиск: