Работа с микроконтроллером Arduino

Автор работы: Пользователь скрыл имя, 03 Декабря 2012 в 16:37, доклад

Краткое описание

Принцип действия.
Для управления машинкой используется обычный пульт дистанционного управления. Он посылает сигнал в виде чередующихся импульсов инфракрасного излучения. Эти импульсы передаются ИК-приемнику, который в свою очередь преобразует их в электрические импульсы, а затем в код клавиши. Далее, в зависимости от кода клавиши, Arduino отдает управляющие команды электромоторам, приводящим машинку в движение.

Содержимое работы - 1 файл

Машинка на пульте ДУ на базе Arduino.docx

— 679.30 Кб (Скачать файл)

 

 

 

Машинка на пульте ДУ на базе Arduino.

 

 

 

 

 

Принцип действия.

Для управления машинкой используется обычный пульт  дистанционного управления. Он посылает сигнал в виде чередующихся импульсов  инфракрасного излучения. Эти импульсы передаются ИК-приемнику, который в свою очередь преобразует их в электрические импульсы, а затем в код клавиши. Далее, в зависимости от кода клавиши, Arduino отдает управляющие команды электромоторам, приводящим машинку в движение.

Необходимые запчасти:

  • Плата Arduino;
  • Датчик расстояния;
  • LCD дисплей (WH1602B-YYK-CTK);
  • 2 электромотора;
  • Драйвер двигателей (L239D);
  • ИК-приемник (TSOP2238);
  • Блок батареек или аккумуляторов;
  • Настроечный потенциометр;
  • Соединительные провода.

Аппаратная часть.

  1. Подсоединение электромоторов и датчика расстояния описано здесь: http://ets.ifmo.ru/Bluetooth.text
  2. Подключение ИК-приемника.

ИК-приемник имеет 3 вывода:

    • VCC – питание (подключаем к выводу 5V Arduino);
    • GND – нулевой провод (подключаем к выводу  Gnd Arduino)
    • SIG – сигнальный провод (подключаем к цифровому входу 12 Arduino).
  1. Подключение LCD дисплея.

У дисплея типа WH1602B-YYK-CTK 16 выводов, 12 из которых нам понадобятся:

  1. Vss (подключаем к Gnd);
  2. Vdd  - питание (подключаем к 5V);
  3. Управление контрастностью (подключаем к выходу потенциометра);
  4. Выбор регистра (подключаем к 13 цифровому выводу);
  5. Выбор режима запись/чтение (подключаем к Gnd – режим записи);
  6. Enable (подключаем к 11 цифровому выводу);
  7. Выводы 7-10 дисплея – младшие биты восьмибитного интерфейса (не подключены);
  8. Выводы 11-14 дисплея – старшие биты восьмибитного интерфейса (подключены к цифровым выводам с 5 по 2 соответственно);
  9. 15 вывод дисплея – питание для подсветки (подключаем к 5V);
  10. 16 вывод дисплея – нулевой провод для подсветки (подключаем к Gnd).

Если после загрузки скетча на плату  на дисплее ничего не видно, нужно  подкрутить настроечный потенциометр до появления текста на дисплее.

Программная часть.

  1. Запись кода опорной клавиши пульта.

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

Код скетча для Arduino:

#include <EEPROM.h> //для работы с энергонезависимой памятью

 

enum { Intervals = 25 }; //Здесь мы указываем, сколько битов бы будем считывать

//разные  пульты выдают разное количество  битов

 

 

int startt, endt, time,n,  code;

char data[Intervals]; // Массив времени импульсов

byte  otl;

int pin=12; //выход. к которому подключен ИК-приемник

void setup() {

  pinMode(pin, INPUT);

}

 

void loop()

{ if (digitalRead(pin)==0) //Если сигнал есть

    {

    startt=micros();  //время начала импульса

     while (digitalRead(pin)==0); //ждем пока он не прекратися.

     endt=micros(); //время окончания импульса

     time=endt-startt; // длительность импульса

     if (time>1000) //если это стартовый импульс, начинаем считывать остальные биты

       {while (n<Intervals) //в цикле считываем бит за битом

           { if (digitalRead(pin)==0) //если импульс положительный

              { startt=micros(); //высчитываем время импульса, как и в прошлый раз

                while (digitalRead(pin)==0);

                endt=micros();

                time=endt-startt;

                data[n]=time/100;     //записываем в массив текущий код

                //делим на 100 чтобы сэкономить место под переменные

                n++; //прибавляем колличество считанных битов

              }

            if (digitalRead(pin)==1) //если импульс отрицательный

              {startt=micros(); //время начала импульса

              while (digitalRead(pin)==1) //проверка на остановку передачи

                {endt=micros();

                 time=endt-startt;

                 if (time>10000) //условие конца передачи

                   {while (n<Intervals) //заполняем остальные длительности нулями

                       {data[n]=0 ;

                         n++;

                       }

                     goto out; //выходим из цикла считывания битов

                   }

                 }  

                endt=micros(); //если передача продолжается

                time=endt-startt;

                data[n]=-time/100;//запишем длительность отр-ого импулшьа с минусом    

                n++;

              }

        }

 out: //после того как все биты считаны

    n=0;

    for (byte x=0; x<Intervals; x++) //в этом цикле запишем получившийся код в EEPROM

     {EEPROM.write(x,data[x]);

    }

}

}

}

 

В результате в памяти Arduino будет код опорной клавиши, т.е. мы будем в состоянии определить код каждой клавиши пульта. Коды остальных клавиш можно выяснить с помощью их распечатывания на дисплее или отправки их значений в последовательный порт. Для вычисления кода клавиши удобнее использовать функцию getCode(), рассмотренную далее.

  1. Основное приложение.

На этом этапе приложение научится распознавать команды с пульта и реагировать  на них. В итоге мы получим машинку, управляемую с обычного пульта ДУ.

Замечание: пульт, который использовал я, посылает с одной и той же клавиши 2 разных кода поочередно, поэтому при выяснении, какая клавиша была нажата используются составные условия.

Код скетча:

#include <EEPROM.h> //для работы с энергонезависимой памятью

#include <LiquidCrystal.h> //для работы с дисплеем

 

LiquidCrystal lcd(13,11,5,4,3,2); //задаем как подключен дисплей

const int Intervals=25,tz=300; //онстанты количества битов и длительности одной команды

char data[Intervals],array[Intervals]; //массивы длиельности ипульсов

long rast,vrem,vr1,rast1;

int i,dv=1,kol,kolvp;

const int rastpin=8, p1=6,p2=7,p3=9,p4=10,pin=12; //выходы, к которым подключены

//двигатели,  датчик рассояния, ИК-приемник

void setup()

{lcd.begin(16,2); //дисплей размером 2 строки по 16 символов

  pinMode(p1,OUTPUT);

  pinMode(pin,INPUT);

pinMode(p2,OUTPUT);

pinMode(p3,OUTPUT);

pinMode(p4,OUTPUT);

for (byte x=0; x<Intervals; x++) //читаем из EEPROM опорный масив

   {data[x]=EEPROM.read(x); }

  

}

void loop(){

if(digitalRead(pin)==0){//если пришел сигнал с пульта

    i=getCode();//определяем. что за клавиша нажата

    if(i==174 || i==295) napravo(); //коды клвиши направо

    if(i==192 || i==261)nalevo(); //коды клавиши налево

    if(i==43 || i==111) {vpered(); dv=1;} //коды клавиши вперед

    if(i==206) {nazad(); dv=-1;} //код клавиши назад 

    }

}

 

void vpered() //функция движения вперед

{lcd.clear(); //очищаем дисплей

lcd.print("forward"); //пишем куда едет машинка

lcd.setCursor(0,1); //переходим на 2 строку

long r=rasstoyanie(); //определяем расстояние до препятствия

if(r<15)while(rasstoyanie()<15)nalevo(); //если оно близко, объезжаем его

  else{ //если нет. двигаемся вперед

lcd.print(r); //пишем на дисплее расстояние до препятствия

  digitalWrite(p1,HIGH);  //вращаем оба мотора вперед

  digitalWrite(p2,LOW);  //в течение времени команды

    digitalWrite(p3,HIGH); 

  digitalWrite(p4,LOW);

 

  delay(tz);

  digitalWrite(p1,LOW);

 digitalWrite(p3,LOW); }

}

 

void nazad(){ //функция движения назад

  lcd.clear(); //очистка дисплея

lcd.print("backward"); //пишем. куда едет машинка

digitalWrite(p1,LOW);  //вращаем оба мотора  назад

  digitalWrite(p2,HIGH); //в течение времени команды

  digitalWrite(p3,LOW); 

  digitalWrite(p4,HIGH);

  digitalWrite(13,LOW);

  delay(tz);

  digitalWrite(p2,LOW);

  digitalWrite(p4,LOW);

}

void napravo(){ //функция движения направо

  lcd.clear(); //очистка дисплея

  lcd.print("right"); //пишем. куда едет машинка

  if(dv>0) {digitalWrite(p1,HIGH); //если до этого она ехала вперед

    digitalWrite(p2,LOW);// вращаем левый мотор вперед

    digitalWrite(13,HIGH);

    delay(tz);

    digitalWrite(p1,LOW);

  digitalWrite(13,LOW);}

  else //если до этого машинка ехала назад

    {digitalWrite(p2,HIGH); //вращаем левый мотор назад

    digitalWrite(p1,LOW);

    delay(tz);

    digitalWrite(p2,LOW);}

}

 

void nalevo(){//функция движения влево

  lcd.clear();//все аналогично движению направо

  lcd.print("left");

  if(dv>0){digitalWrite(p3,HIGH);

    digitalWrite(p4,LOW);

    delay(tz);

    digitalWrite(p3,LOW);}

  else

    {digitalWrite(p4,HIGH);

    digitalWrite(p3,LOW);

    delay(tz);

    digitalWrite(p4,LOW);}

}

 

long rasstoyanie(){ //определение рассояния до препятствия

  pinMode(rastpin,OUTPUT); //посылаем импульс

  digitalWrite(rastpin,LOW);

  delayMicroseconds(2);

  digitalWrite(rastpin,HIGH);

  delayMicroseconds(5);

  digitalWrite(rastpin,LOW);

  pinMode(rastpin,INPUT);//принимаем импульс

  vrem=-1;

  vrem=pulseIn(rastpin,HIGH); //считаем. сколько времени он шел

  if(vrem>=0)rast=vrem/29/2;//вычисляем расстояние

  return rast;

}

 

int getCode(){//функция получения кода клавиши пульта

  int startt, endt, time,n,  code;

  byte  otl;

  otl=0;

  code=0;

  if (digitalRead(pin)==0) //цикл считывания битов кода

    {                     //аналогичен предыдущему скетчу

    startt=micros(); 

     while (digitalRead(pin)==0);

     endt=micros();

     time=endt-startt;

     if (time>1000)

       {while (n<Intervals)

           { if (digitalRead(pin)==0)

              { startt=micros();

                while (digitalRead(pin)==0);

                endt=micros();

                time=endt-startt;

                array[n]=time/100;   

                n++;

              }

            if (digitalRead(pin)==1)

              {startt=micros();

              while (digitalRead(pin)==1)

                {endt=micros();

                 time=endt-startt;

                 if (time>10000)

                   {while (n<Intervals)

                       {array[n]=0 ;

                         n++;

                       }

                     goto out;

                   }

                 }  

                endt=micros();

                time=endt-startt;

                array[n]=-time/100;   

                n++;

              }

        }

 out:

    n=0;

    for (byte x=0; x<Intervals; x++) // сравнение полученного кода с опорным

     {if (abs(array[x]-data[x])>5 && array[x]!=0 && data[x]!=0) // проверка на отличия

       {otl++;

        code=code+(x+1)*otl; //генерируем код клавиши

       }

    }

    return code;

}

}

}

 


Информация о работе Работа с микроконтроллером Arduino