четверг, 9 ноября 2017 г.

Радиоуправление

Я уже рассказывал про радиоуправляемую машинку (статья). Но там использовался готовый передатчик и приемник для самолетов. В этой статье описывается радиоуправление на основе модулей для ардуино.


Радиоуправляемой стала моя новая платформа. Про саму платформу лучше почитать в ранее опубликованных статьях (железо, электроника).

Для этого проекта были куплены радиомодули


Transceiver Module

Нужно две штуки. А лучше три.

Для пульта нужна arduino nano


Arduino Nano

Удобно использовать arduino nano вместе с шильдиком предназначенным для подключения различных сенсоров


Sensor Shield

Ещё для пульта нужен модуль с кнопочками


Keyboard Module

Подойдет и такая клавиатурка


Membrane Keypad

И проводочки


Female to Female Cable

Соединяется всё в соответствии с изложенными ниже инструкциями.

Arduino Nano --- Keyboard module
GND --- GND
D8 --- K1
D9 --- K2
D10 --- K3
D11 --- K4

Arduino Nano --- Transceiver module
VCC --- VDD
GND --- GND
RX --- TXD
TX --- RXD

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

Код для пульта

////////////////////////
//
// Arduino Nano
//
////////////////////////
//
// Sketch: Transmitter
//

#include <util/delay.h>

void PORTB_Init( void )
{
    // Port B
    DDRB = 0b00000000;
    PORTB = 0b00001111;
}

void PORTC_Init( void )
{
    // Port C
    DDRC = 0b00000000;
    PORTC = 0b00000000;
}

void PORTD_Init( void )
{
    // Port D
    DDRD = 0b00000000;
    PORTD = 0b00000000;
}

void USART_Init( void )
{
    // Set baud rate (9600 bps)
    UBRR0H = 0x00;
    UBRR0L = 0x67;

    // Enable receiver and transmitter
    UCSR0B = (1<<RXEN0)|(1<<TXEN0);

    // Set frame format: 8 data, 1 stop bit
    UCSR0C = (1<<UCSZ01)|(1<<UCSZ00);
}

unsigned char USART_Receive( void )
{
    // Wait for data to be received
    while ( !(UCSR0A & (1<<RXC0)) ) ;

    // Get and return received data from buffer
    return UDR0;
}

void USART_Transmit( unsigned char data )
{
    // Wait for empty transmit buffer
    while ( !( UCSR0A & (1<<UDRE0)) ) ;

    // Put data into buffer, sends the data
    UDR0 = data;
}

void setup()
{
    cli();

    PORTB_Init();
    PORTC_Init();
    PORTD_Init();

    USART_Init();

    sei();
}

void loop()
{
    while (1)
    {
        if ( !(PINB & (1<<0)) )
        {
            _delay_ms(80);
            USART_Transmit('f');
            while ( !(PINB & (1<<0)) ) ;
        }

        else if ( !(PINB & (1<<1)) )
        {
            _delay_ms(80);
            USART_Transmit('b');
            while ( !(PINB & (1<<1)) ) ;
        }

        else if ( !(PINB & (1<<2)) )
        {
            _delay_ms(80);
            USART_Transmit('l');
            while ( !(PINB & (1<<2)) ) ;
        }

        else if ( !(PINB & (1<<3)) )
        {
            _delay_ms(80);
            USART_Transmit('r');
            while ( !(PINB & (1<<3)) ) ;
        }

        USART_Transmit('s');
        _delay_ms(80);
    }
}

//
// End
//
////////////////////////

Код для платформы

////////////////////////
//
// Arduino Uno
//
////////////////////////
//
// Sketch: Receiver
//

const unsigned char IN1 = 12;
const unsigned char IN2 = 11;
const unsigned char IN3 = 10;
const unsigned char IN4 = 9;

void driver_init(void)
{
    pinMode(IN1, OUTPUT);
    pinMode(IN2, OUTPUT);
    pinMode(IN3, OUTPUT);
    pinMode(IN4, OUTPUT);
}

void stop(void)
{
    digitalWrite(IN1, LOW);
    digitalWrite(IN2, LOW);
    digitalWrite(IN3, LOW);
    digitalWrite(IN4, LOW);
}

void forward(void)
{
    digitalWrite(IN1, LOW);
    digitalWrite(IN2, HIGH);
    digitalWrite(IN3, LOW);
    digitalWrite(IN4, HIGH);
}

void backward(void)
{
    digitalWrite(IN1, HIGH);
    digitalWrite(IN2, LOW);
    digitalWrite(IN3, HIGH);
    digitalWrite(IN4, LOW);
}

void left(void)
{
    digitalWrite(IN1, LOW);
    digitalWrite(IN2, HIGH);
    digitalWrite(IN3, HIGH);
    digitalWrite(IN4, LOW);
}

void right(void)
{
    digitalWrite(IN1, HIGH);
    digitalWrite(IN2, LOW);
    digitalWrite(IN3, LOW);
    digitalWrite(IN4, HIGH);
}

void setup()
{
    Serial.begin(9600);

    driver_init();
    stop();
}

void loop()
{
    unsigned char data;

    if (Serial.available() > 0)
    {
        data = Serial.read();

        if ( data == 's' )
            stop();
        if ( data == 'f' )
            forward();
        if ( data == 'b' )
            backward();
        if ( data == 'l' )
            left();
        if ( data == 'r' )
            right();
    }
}

//
// End
//
////////////////////////

Назначение кнопок пульта:

K1 --- движение вперед,
K2 --- движение назад,
K3 --- поворот налево,
K4 --- поворот направо.

Если не нажата ни одна кнопка, то платформа не двигается.

Модули обеспечивают связь в пределах метров пяти точно. На большем расстоянии не было возможности проверить.