Модули радио-удлинители - ФОРУМ ДВ Робот dvrobot.ru
Четверг, 18.10.2018, 15:03
Главная Мой профиль Регистрация Выход
  • НАШ МАГАЗИН
  • Вы вошли как Гость | Группа "Гости"Приветствую Вас, Гость
    [ Новые сообщения · Участники · Правила форума · Поиск · RSS ]
    • Страница 1 из 1
    • 1
    Модератор форума: GRACH, Serg  
    ФОРУМ ДВ Робот dvrobot.ru » DV ROBOT » Библиотека Проектов » Модули радио-удлинители (Пример связи двух микроконтроллеров через радиоканал)
    Модули радио-удлинители
    SergДата: Воскресенье, 24.03.2013, 21:18 | Сообщение # 1
    Ампер
    Группа: Модераторы
    Сообщений: 510
    Репутация: 28
    Статус: Offline
    [c]Радио- удлинитель
    [/c]

    Модуль радио-удлинителя можно приенить для беспроводной связи двух Аrduino между собой. Подключаются они очень просто- питание +5 Вольт. Вывод ТХ к радиопередающему модулю (маленькая квадратная платка) и вывод RX к приемному модулю (прямоугольная платка).
    К передающей Arduino подключен дисплей для контроля передаваемых команд.



    Схема проекта:



    Проект довольно простой. Нажатием одной кнопки включаем светодиод, нажатием другой- выключаем.
    Проект легко изменить :
    1. Приемников может быть сколько угодно.
    2. Вместо светодиодов поставить любые исполнительные механизмы.
    В моем случае поднимаются- опускаются жалюзи в квартире.
    Программа написана на языке Си , она  очень маленькая по размеру, занимает 8% памяти. Поэтому остается большой простор для творчества.
    Что бы не тратить зря дорогую  плату Arduino, применяем вот такой дешевый аналог :

    Для работы с ней нам понадобится вот такой программатор:



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



    или же датчик вибрации:


    либо датчик наклона:



    либо датчик звуковых колебаний:



    а также множество других датчиков...

    Приемное устройство может управлять мощной нагрузкой, например лампой на 220 Вольт, с помощью такого реле:

    Прикрепления: 5554412.png(30.8 Kb)
     
    SergДата: Воскресенье, 24.03.2013, 22:07 | Сообщение # 2
    Ампер
    Группа: Модераторы
    Сообщений: 510
    Репутация: 28
    Статус: Offline
    Код передающей части.
    Код
    #include <avr/io.h>

    #include <avr/interrupt.h>

    //работа от внутреннего генератора на  1 МГц
    #define F_CPU 1000000UL

    //Скорость обмена с радиомодулем
    #define BAUDRATE 1200
    //calculate UBRR value
    #define UBRRVAL ((F_CPU/(BAUDRATE*16UL))-1)
    //define receive parameters
    #define SYNC 0x55// синхро-байт
    #define RADDR_0 0x31// адреса трех приемников (сколько угодно приемников можно применить)
    #define RADDR_1 0x32
    #define RADDR_2 0x33
    #define LEDON 0x11//команда включения светодиода
    #define LEDOFF 0x22//команда выключения светодиода
    unsigned char i = 0;

    // Функция задержки в мкс
    void _delay_us(unsigned char time_us)
    { register unsigned char i;

    for(i = 0; i < time_us; i++)
    {
    asm volatile(" PUSH  R0 ");
    asm volatile(" POP   R0 ");
    }
    }

    // Функция задержки в мс
    void _delay_ms(unsigned int time_ms)
    { register unsigned int i;

    for(i = 0; i < time_ms; i++)
    {      
    _delay_us(250);
    _delay_us(250);
    _delay_us(250);
    _delay_us(250);
    }
    }
    #define RS PD2      
    #define EN PD3

    // Функция передачи команды
    void lcd_com(unsigned char p)
    {
    PORTD &= ~(1 << RS); // RS = 0 (запись команд)
    PORTD |= (1 << EN); // EN = 1 (начало записи команды в LCD)
    PORTD &= 0x0F; PORTD |= (p & 0xF0); // старший нибл
    _delay_us(100);
    PORTD &= ~(1 << EN); // EN = 0 (конец записи команды в LCD)
    _delay_us(100);
    PORTD |= (1 << EN); // EN = 1 (начало записи команды в LCD)
    PORTD &= 0x0F; PORTD |= (p << 4); // младший нибл
    _delay_us(100);
    PORTD &= ~(1 << EN); // EN = 0 (конец записи команды в LCD)
    _delay_us(100);
    }

    // Функция передачи данных
    void lcd_data(unsigned char p)
    {
    PORTD |= (1 << RS)|(1 << EN); // RS = 1 (запись данных), EN - 1 (начало записи команды в LCD)
    PORTD &= 0x0F; PORTD |= (p & 0xF0); // старший нибл
    _delay_us(100);
    PORTD &= ~(1 << EN); // EN = 0 (конец записи команды в LCD)
    _delay_us(100);
    PORTD |= (1 << EN); // EN = 1 (начало записи команды в LCD)
    PORTD &= 0x0F; PORTD |= (p << 4); // младший нибл
    _delay_us(100);
    PORTD &= ~(1 << EN); // EN = 0 (конец записи команды в LCD)
    _delay_us(100);
    }

    // Функция инициализации LCD
    void lcd_init(void)
    {
    _delay_ms(50); // Ожидание готовности ЖК-модуля

    // Конфигурирование четырехразрядного режима
    PORTD |= (1 << PD5);
    PORTD &= ~(1 << PD4);

    // Активизация четырехразрядного режима
    PORTD |= (1 << EN);
    PORTD &= ~(1 << EN);
    _delay_ms(5);      

    lcd_com(0x28); // шина 4 бит, LCD - 2 строки
    lcd_com(0x08); // полное выключение дисплея
    lcd_com(0x01); // очистка дисплея
    _delay_us(100);
    lcd_com(0x06); // сдвиг курсора вправо
    lcd_com(0x0C); // включение дисплея, курсор не видим
    }

          //Функция вывода строки на LCD
    void lcd_string(unsigned char command, char *string)
    {
    lcd_com(0x0C);
    lcd_com(command);
    while(*string != '\0')
    {
    lcd_data(*string);
    string++;
    }
    }

    void USART_Init(void)
    {
            //Set baud rate
            UBRRL=(uint8_t)UBRRVAL;      //low byte
            UBRRH=(UBRRVAL>>8);   //high byte
            //Set data frame format: asynchronous mode,no parity, 1 stop bit, 8 bit size
            UCSRC=(1<<URSEL)|(0<<UMSEL)|(0<<UPM1)|(0<<UPM0)|
               (0<<USBS)|(0<<UCSZ2)|(1<<UCSZ1)|(1<<UCSZ0);        
            //Enable Transmitter and Receiver and Interrupt on receive complete
            UCSRB=(1<<TXEN);
    }
    void USART_vSendByte(uint8_t u8Data)
    {
             //  Ждем пока идет передача байта
             while((UCSRA&(1<<UDRE)) == 0);
             // Transmit data
             UDR = u8Data;      
    }
    void Send_Packet(uint8_t addr, uint8_t cmd)
    {
            USART_vSendByte(SYNC);//send synchro byte        
            USART_vSendByte(addr);//send receiver address
            USART_vSendByte(cmd);//send increment command
            USART_vSendByte((addr+cmd));//send checksum
    }

    int main(void)
    {

    DDRB = 0x00;// порт В на вход
    PORTB = 0xFF;// подтягивающте резисторы
    DDRD  = 0b11111110;
    PORTD = 0x00;
                 
    lcd_init(); // Инициализация LCD
    USART_Init();
    while(1)
            {

                  if ((PINB&(1 << PB0)) == 0) {//если PB0 равен нулю нажата кнопка
                  //endless transmission

                  while ((PINB&(1<<PB0)) ==0){} // ждем отпускания кнопки
                  //send command to switch led ON
                  Send_Packet(RADDR_0, LEDON);
                  //   Send_Packet(RADDR_0, LEDON);
                        //Send_Packet(RADDR_0, LEDON);
                  //_delay_us(50);
                  //Send_Packet(RADDR_0, LEDOFF);
                  lcd_string(0x80, "SEND COMAND"); // Выводим строку на LCD
                  //lcd_data(0x80);// отправляем символы из кодовой таблицы
                  //lcd_data("o");
                  //lcd_data("n");
                  /*lcd_data(0xb5);*/
                  _delay_ms(100);
                  lcd_com(0x01); // Очищаем LCD
                  }      
                  if ((PINB&(1 << PB1)) == 0) {//если PB1 равен нулю
                  while ((PINB&(1<<PB1)) ==0){} // ждем отпускания кнопки
                  //endless transmission
                  //send command to switch led OFF      
                  lcd_string(0x80, "SEND COMAND 2"); // Выводим строку на LCD
                   _delay_ms(100);
                  lcd_com(0x01); // Очищаем LCD
                  Send_Packet(RADDR_0, LEDOFF);
                  }      

                  if ((PINB&(1 << PB2)) == 0) {//если PB2 равен нулю
                  //endless transmission
                  while ((PINB&(1<<PB2)) ==0){} // ждем отпускания кнопки
                  //send command to switch led ON
                  Send_Packet(RADDR_1, LEDON);
                  }      
                  if ((PINB&(1 << PB3)) == 0) {//если PB3 равен нулю
                  //endless transmission
                  while ((PINB&(1<<PB3)) ==0){} // ждем отпускания кнопки
                  //send command to switch led ON
                  Send_Packet(RADDR_1, LEDOFF);
                  }      
                  if ((PINB&(1 << PB4)) == 0) {//если PB4 равен нулю
                  //endless transmission
                  while ((PINB&(1<<PB4)) ==0){} // ждем отпускания кнопки
                  //send command to switch led ON
                  Send_Packet(RADDR_2, LEDON);
                  }      
                  if ((PINB&(1 << PB5)) == 0) {//если PB5 равен нулю
                  //endless transmission
                  while ((PINB&(1<<PB5)) ==0){} // ждем отпускания кнопки
                  //send command to switch led ON
                  Send_Packet(RADDR_2, LEDOFF);
                  }      
            }
            return 0;
    }
     пример работы  с дисплеем и UART подсмотрен на Микроконтроллеры и Технологии
     
    SergДата: Воскресенье, 24.03.2013, 22:27 | Сообщение # 3
    Ампер
    Группа: Модераторы
    Сообщений: 510
    Репутация: 28
    Статус: Offline
    Код приемной части
    Микроконтроллер шлет в UART  информацию о статусе выполнения команды. Ее можно использовать как для отладки, так и для  двухсторонней связи с командным модулем.

    Код
    #include <avr/io.h>
    #include <avr/interrupt.h>

    #ifndef F_CPU
    //Определяем Частоту процессора     
    #define F_CPU 1000000
    #endif
    //Установить желаемую скорость UART
    #define BAUDRATE 1200
    //Вычисляем значение UBRR value
    #define UBRRVAL ((F_CPU/(BAUDRATE*16UL))-1)
    //Определяем параметры приема      
    #define SYNC 0x55// synchro signal
    #define RADDR_0 0x31//адрес приемника. Для каждого приемника индивидуальный адрес
    #define LEDON 0x11//LED on включить
    #define LEDOFF 0x22//LED off выключить
    #define RADDR_BASE 0x88// адрес базы

    char SEND=0x00;//0x12; //ответ о выполнении команды
    //  0x13; //ответ о невыполнении команды
    unsigned char i = 0;

    // Функция задержки в мкс
    void _delay_us(unsigned char time_us)
    { register unsigned char i;

    for(i = 0; i < time_us; i++)
    {
    asm volatile(" PUSH  R0 ");
    asm volatile(" POP   R0 ");
    }
    }

    // Функция задержки в мс
    void _delay_ms(unsigned int time_ms)
    { register unsigned int i;

    for(i = 0; i < time_ms; i++)
    {      
    _delay_us(250);
    _delay_us(250);
    _delay_us(250);
    _delay_us(250);
    }
    }

    void USART_Init(void)
    {
            //Установить скорость передачи      
            UBRRL=(uint8_t)UBRRVAL;      //младший байт
            UBRRH=(UBRRVAL>>8);   //старший байт
            //Установить данные Формат кадра: асинхронном режиме, без контроля четности, 1 стоповый бит, 8 бит размера      
            UCSRC=(1<<URSEL)|(0<<UMSEL)|(0<<UPM1)|(0<<UPM0)|
               (0<<USBS)|(0<<UCSZ2)|(1<<UCSZ1)|(1<<UCSZ0);        
            //Включить передатчик и приемник и прерываний on receive complete
            UCSRB=(1<<RXEN)|(1<<RXCIE)|(1<<TXEN);
            //Разрешить глобальные прерывания      

    }

    void USART_vSendByte(uint8_t u8Data)
    {
             // Wait if a byte is being transmitted Ждем пока идет передача байта
             while((UCSRA&(1<<UDRE)) == 0);
             // Transmit data
             UDR = u8Data;      
    }
    void Send_Packet(uint8_t addr, uint8_t cmd)
    {
            USART_vSendByte(SYNC);//send synchro byte        
            USART_vSendByte(addr);//send base address
            USART_vSendByte(cmd);//send OK ERROR command
            USART_vSendByte((addr+cmd));//send checksum
    }
    uint8_t USART_vReceiveByte(void)
    {
             // ждем получения байта
             while((UCSRA&(1<<RXC)) == 0);
             // Возврат полученных данных
             return UDR;
    }
    ISR(USART_RXC_vect)
    {
            //Определяем переменные      
            uint8_t sync, raddress, data, chk;//адрес передатчика
            //Получить адрес назначения
            sync=USART_vReceiveByte();
            raddress=USART_vReceiveByte();
            //Получение данных
            data=USART_vReceiveByte();
            //Получить контрольную сумму      
            chk=USART_vReceiveByte();
            //Сравнить контрольную сумму полученных с расчетными      
            if(chk==(raddress+data))//если соответствие выполнения операций
            {
               //если адрес датчика матч
               if(raddress==RADDR_0)
                  {
                     if(data==LEDON)
                        {
                           PORTC&=~(1<<PC0);//LED ON
                           SEND=0x12;//статус выполнения команды ОК

                        }

                     else if(data==LEDOFF)
                        {
                           PORTC|=(1<<PC0);//LED OFF
                           SEND=0x13;// статус ошибки выполнения
                        }

                     else
                     {
                        //blink led as error
                        PORTC|=(1<<0);//LED OFF
                        _delay_ms(10);
                        PORTC&=~(1<<0);//LED ON        
                     }
                  }
            }
                    
               Send_Packet(RADDR_BASE, SEND );        
    }
    void Main_Init(void)
    {
            PORTC|=(1<<PC0);//LED OFF
            DDRC=0xFF;//определить порт C pin-0, как выход;
            //enable global interrupts

            sei();
    }
    int main(void)
    {

            Main_Init();
            USART_Init();
            while(1)
            {
                 
            }
            //ничего здесь прерывания работы
            return 0;
    }

    Пример работы с UART подсмотрен на Микроконтроллеры и Технологии
     
    ФОРУМ ДВ Робот dvrobot.ru » DV ROBOT » Библиотека Проектов » Модули радио-удлинители (Пример связи двух микроконтроллеров через радиоканал)
    • Страница 1 из 1
    • 1
    Поиск:

    ДВ Робот - Чат