355 500 произведений, 25 200 авторов.

Электронная библиотека книг » Автор Неизвестен » Знакомство с Arduino (перевод книги "Getting Started with Arduino") » Текст книги (страница 4)
Знакомство с Arduino (перевод книги "Getting Started with Arduino")
  • Текст добавлен: 4 октября 2016, 02:54

Текст книги "Знакомство с Arduino (перевод книги "Getting Started with Arduino")"


Автор книги: Автор Неизвестен



сообщить о нарушении

Текущая страница: 4 (всего у книги 5 страниц)

5.3 Использование фотодатчика вместо кнопки

Сейчас мы произведём интересный эксперимент. Возьмём фотодатчик, как на рис. 5-5.

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

Соберите схему для примера 4-2 (см. "Использование кнопки для управления светодиодом" в главе 4), затем загрузите код из примера 4-2 в вашу Arduino.

Теперь подключите фотодатчик в плату вместо кнопки. Вы увидите, что если закрыть датчик рукой, светодиод выключится. Откройте датчик, и светодиод зажжётся. Вы только что собрали схему со светодиодом, управляемым датчиком. Это важно, так как первый раз в книге мы используем электронный компонет, не являющийся просто механическим устройством: это полнофункциональный датчик.

5.4 Аналоговый ввод

Как вы узнали из предыдущего раздела, Arduino может определять, было-ли приложено напряжение к одному из её выводов и сообщать это функции digitalRead(). Тип ответа «да/нет» хорош для многих приложений, но датчик света, который мы недавно использовали, может сообщить нам не только что свет есть, но также и сколько его. В этом и состоит разница между датчиками вкл/выкл (который сообщает что что-то мы что-то имеем) и аналоговым датчиком, данные которого постоянно изменяются. Для чтения таких датчиков нам требуется другой тип выводов.

В правой нижней части платы Arduino вы видите шесть выводов, обозначенных "Analog In"; это специальные выводы, которые могут сообщить нам не только что к ним приложено напряжение, но и его величину. Используя функцию analogRead(), мы можем считывать величину этого напряжения. Данная функция возвращает числа от 0 до 1023, которые соответствуют напряжению в пределах от 0 до 5 вольт. Например, для напряжения величиной 2,5 В, приложенного к выводу 0, функция analogRead(0) вернёт 512.

Теперь, если вы соберёте схему по рис. 5-6, используя резистор 10 кОм и запустите код из примера 5-3, вы увидите что светодиод на плате (также вы можете вставить светодиод в выводы 13 и GND как показано в разделе "Мигающий светодиод" из главы 4) мигает с частотой, зависящей от освещённости фотодатчика.

Рис. 5-6. Схема с аналоговым датчиком


Пример 5-6. Мигание светодиодом со скоростью, зависящей от величины на аналоговом входе

#define LED 13 // the pin for the LED

int val = 0; // variable used to store the value

               // coming from the sensor

void setup() {

  pinMode(LED, OUTPUT); // LED is as an OUTPUT

  // Note: Analogue pins are

  // automatically set as inputs

}

void loop() {

  val = analogRead(0); // read the value from

                       // the sensor

  digitalWrite(13, HIGH); // turn the LED on

  delay(val); // stop the program for

              // some time

  digitalWrite(13, LOW); // turn the LED off

  delay(val); // stop the program for

              // some time

}

Теперь попробуйте пример 5-4, но перед этим вам придётся изменить свою схему. Посмотрите на рис. 5-4 ещё раз и соедините светодиод с выводом 9. Так как у вас уже есть собранная схема, вам надо найти точку платы где светодиод, провод и резистор не будет соединён с фотодатчиком.

Пример 5-4. Установка яркости светодиода, определяемая данными на аналоговом входе.

#define LED 9 // the pin for the LED

int val = 0; // variable used to store the value

              // coming from the sensor

void setup() {

  pinMode(LED, OUTPUT); // LED is as an OUTPUT

  // Note: Analogue pins are

  // automatically set as inputs

}

void loop() {

  val = analogRead(0); // read the value from

                       // the sensor

  analogWrite(LED, val/4); // turn the LED on at

                           // the brightness set

                           // by the sensor

  delay(10); // stop the program for

             // some time

}

Примечание: мы указываем яркость, деля val на 4 из-за того, что analogRead() возвращает число до 1023, а analogWrite() принимает 255 максимум.

5.5 Попробуйте другие аналоговые датчики

Используя ту же схему что вы видели в предыдущем разделе, вы можете подсоединить множество других резистивных датчиков, которые работают более менее подобным образом. Например, вы можете подключить термистор (простое устройство, изменяющее своё сопротивление в зависимости от температуры). В схеме показано как изменение сопротивления изменяет напряжение в ней. Это напряжение может быть измерено Arduino.

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

До сих пор мы использовали в качестве устройства вывода светодиод, но сейчас как нам прочесть действительные данные значений, полученный Arduino с датчика? Мы не можем сделать плату, мигающую кодом Морзе (ну, вообще-то можем, но для людей есть более простые способы чтения данных). Для этого мы может заставить Arduino общаться с компьютером по последовательному порту, который и будет описан в следующем разделе.

5.6 Последовательная связь

Как вы прочли в начале книги, у Arduino есть USB-подключение, используемое средой разработки для загрузки кода в процессор. Хорошая новость в том, что это подключение также может использоваться скетчами для отправки назад на компьютер данных или получения команд от него. Для этой цели мы изучим обьект serial (обьект – это набор свойств, которые обьединены вместе для удобства пишущих скетчи людей).

Этот объект содержит весь код, необходимый для отправки и получения данных. Сейчас мы используем предыдущую схему с фоторезистором и будем отправлять значения, которые прочли, на компьютер. Вставьте следующий код в новый скетч (его также можно скачать с www.makezine.com/getstartedarduino):

Пример 5-5. Отправка на компьютер данных, прочитанных с аналогового входа 0. После выгрузки скетча на плату нажмите кнопку "Serial Monitor" в IDE.

#define SENSOR 0 // select the input pin for the

                 // sensor resistor

int val = 0; // variable to store the value coming

             // from the sensor

void setup() {

 Serial.begin(9600); // open the serial port to send

                     // data back to the computer at

                     // 9600 bits per second

}

void loop() {

  val = analogRead(SENSOR); // read the value from

                            // the sensor

  Serial.println(val); // print the value to

                       // the serial port

  delay(100); // wait 100ms between

              // each send

}

После того, как вы выгрузите скетч в Arduino, нажмите кнопку «Serial Monitor» в Arduino IDE; в открывшемся вы увидите постоянно увеличивающийся список цифр. Теперь любая программа, способная работать с последовательным портом, может вести диалог с Arduino. Существует много языков программирования, которые позволяют писать программы, общающиеся с последовательным портом. Processing (www.processing.org) является отличным дополнением к Arduino из-за того что он, и Arduino IDE очень похожи.

5.7 Управление большими нагрузками (электродвигатели, лампы и тому подобное)

Каждый из выводов Arduino может быть использован для запитки устройств с током до 20 миллиампер – это очень маленькая величина тока, достаточная только для питания светодиода. Если вы попробуете управлять чем-нибудь другим, например, моторчиком, вывод немедленно перестанет работать, и, вероятно, сожжёт весь процессор. Для управления большими нагрузками, такими как электродвигатели или лампы накаливания нам требуется внешний компонент, который может включать и выключать другие компоненты и который управляется выводом Arduino. Одним из таких приборов является MOSFET-транзистор (МОП-транзистор) – не обращайте внимания на смешное название – это электронный выключатель, который может управляться подачей напряжения на один из его трёх выводов, каждый из которых называется затвором. Он подобен выключателю света в доме, когда движение руки для включения или выключения света заменено выводом Arduino, подающим напряжение на затвор такого транзистора.

Примечание: MOSFET означает «metal–oxide–semiconductor field-effect transistor» (металл-оксид-полупроводник (МОП) полевой транзистор). Это специальный вид транзистора, который может работать на принципе полевого эффекта. Это означает, что электричество будет протекать через частицу полупроводника (между выводами стока и истока) при прикладывании напряжения к выводу затвора. Так как затвор изолирован от остальных выводов плёнкой оксида металла, из Arduino в MOSFET ток не протекает, что позволяет создать простой интерфейс. Они идеальны для включения и выключения больших нагрузок с высокой частостой.

На рис. 5-7 видно как мы применили MOSFET IRF520 для включения и выключения маленького моторчика, присоединённого к вентилятору. Вы также должны заметить, что моторчик получает питание от разъёма 9 В на плате Arduino. Это ещё одно преимущество MOSFET: он позволяет управляет приборами, у которых питание осуществляется от других источников. Так как MOSFET подключён к выводу 9, мы может использовать команду analogWrite() для управления скоростью моторчика при помощи ШИМ.

5.8 Сложные сенсоры

Мы определим сложные сенсоры как такие, которые могут выдавать информацию, что требует больше чем просто функции digitalRead() или analogRead(). Обычно они представляют собой маленькую схему с небольшим микроконтроллером внутри, который предварительно обрабатывает информацию.

Некоторые из таких сложных сенсоров являются ульразвуковыми или инфракрасными датчиками расстояния, акселерометрами. Вы можете увидеть примеры на нашем сайте в разделе "Tutorials" (www.arduino.cc/en/Tutorial/HomePage).

Книга "Making Things Talk" (автор – Tom Igoe, издательство O'Reilly) подробно разъясняет принципы работы этих сенсоров, а также множества других.

Рис. 5-7. Схема двигателя вентилятора с Arduino



Глава 6. Разговоры с облаками

В предыдущих главах вы познакомились с основами Arduino и основами строительных блоков. Позвольте мне напомнить вам, из чего состоит «алфавит Arduino»:

6.1 Цифровой вывод

6.1.1 Цифровой вывод

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

6.1.2 Аналоговый вывод

Даёт возможность управлять яркостью светодиода, а не просто включать или выключаеть его. Мы даже можем контролировать с его помощью скорость электродвигателя.

6.1.3 Цифровой ввод

Позволяет нам читать состояние простых сенсоров, таких как кнопки или датчики наклона.

6.1.4 Аналоговый ввод

Мы можем читать сигналы с датчиков, которые постоянно посылают данные, а не просто "вкл/выкл", таких как потенциометр или датчик света.

6.1.5 Последовательная связь

Позволяет связываться с компьютером и обмениваться данными, или просто следить за тем, что происходит в скетче, выполняющемся Arduino.

В этой главе мы посмотрим как обьединить работающие приложения используя всё что мы выучили в предыдущих. Эта глава покажет вам как каждый отдельный пример может быть использован как кирпичик при построении сложного проекта.

Вот где во мне проявляется желание быть дизайнером. Мы создадим версию двадцать первого века классической лампы моего любимого итальянского дизайнера, Джо Коломбо. Объект, который мы будем создавать, называется "Атон" с 1964 года.

Рис. 6-1. Закончення лампа


Лампа, которую вы можете видеть на рис. 6-1 – это простой шар, установленный на подставке с большим отверстием для того чтобы шар не скатился с вашего стола. Такая конструкция позволяет направлять лампу куда угодно.

В терминах функциональности, мы хотим создать устройство, которое должно подключаться к интернету, получать текущий список статей в блоге Make blog (blog.makezine.com) и подсчитывать использованное количество слов «peace», «love» и «Arduino». С этими значениями мы будет создавать цвет и показывать его при помощи лампы. Лампа имеет кнопку для включения и выключения, а также датчик света для автоматического включения.

6.2 Планирование

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

Arduino – это простой компьютер с небольшой памятью, она не может легко обрабатывать большие файлы, и мы подключимся к RSS-ленте для получения понятного XML-файла, который требует больше оперативной памяти. Мы создадим промежуточный элемент (прокси) для упрощения XML с применением языка Processing.

Processing

Processing – это то, откуда появился Arduino. Мы любим этот язык и используем его как для обучения программирования начинающих, так и для создания прекрасного кода. Другое преимущество Processing – это то, что у него открытый код и он работает на всех основных платформах (Mac, Linux и Windows). Он также может создавать отдельные приложения, которые будут выполняться на этих платформах. Более того, сообщество Processing довольно оживлено и полезно, к тому-же вы можете найти тысячи уже написанных примеров программ.

Прокси сделает для нас следующая работу: скачает ленту RSS с сайта makezine.com и извлечёт все слова из полученного XML-файла. Затем, пройдя по файлу, он подсчитает количество слов «peace», «love» и «Arduino» в тексте. Исходя из полученных трёх чисел мы можем вычислить значение цвета, которое пошлём Arduino. Плата отправит обратно величину света, измеренную датчиком и покажет её на экране компьютера.

Со стороны аппаратного обеспечения, мы объединим пример с кнопкой, управлением светодиодом при помощи ШИМ (умноженное на три) и последовательную связь.

Поскольку Arduino – простое устройство, нам требуется закодировать цвет простым способом. Мы будем использовать стандартный способ, представленный в языке HTML: знак решётки # с шестью шестнадцатеричными цифрами после него.

Шестнадцатеричные цифры удобны потому, что каждое 8-ми битовое число сохраняется в двух битах; для десятичных чисел количество знаков меняется от одного до трёх. Предсказуемость делает код проще: ждём, пока не увидим решётку "#", затем считываем шесть знаков после неё в буфер (переменную для временного хранения данных). И, наконец, превращаем каждую группу из двух цифр в один байт, который будет соответствовать яркости одного из трёх светодиодов.

6.3 Программирование

Вы будете запускать два скетча: один скетч на языке Processing и один а языке Arduino. Вот код для Processing. Вы можете скачать его с www.makezine.com/getstartedarduino.

Пример 6-1. Часть кода для лампы с подключением к сети, вдохновлённые записью блоге Tod E. Kurt (todbot.com)

import processing.serial.*;

String feed = «http://blog.makezine.com/index.xml»;

int interval = 10; // retrieve feed every 60 seconds;

int lastTime; // the last time we fetched the content

int love = 0;

int peace = 0;

int arduino = 0;

int light = 0; // light level measured by the lamp

Serial port;

color c;

String cs;

String buffer = ""; // Accumulates characters coming from Arduino

PFont font;

void setup() {

  size(640,480);

  frameRate(10);   // we don't need fast updates

  font = loadFont(«HelveticaNeue-Bold-32.vlw»);

  fill(255);

  textFont(font, 32);

  // IMPORTANT NOTE:

  // The first serial port retrieved by Serial.list()

  // should be your Arduino. If not, uncomment the next

  // line by deleting the // before it, and re-run the

  // sketch to see a list of serial ports. Then, change

  // the 0 in between [ and ] to the number of the port

  // that your Arduino is connected to.

  //println(Serial.list());

  String arduinoPort = Serial.list()[0];

  port = new Serial(this, arduinoPort, 9600); // connect to Arduino

  lastTime = 0;

  fetchData();

}

void draw() {

  background( c );

  int n = (interval – ((millis()-lastTime)/1000));

  // Build a colour based on the 3 values

  c = color(peace, love, arduino);

  cs = "#" + hex(c,6); // Prepare a string to be sent to Arduino

  text(«Arduino Networked Lamp», 10,40);

  text("Reading feed:", 10, 100);

  text(feed, 10, 140);

  text("Next update in "+ n + « seconds»,10,450);

  text("peace" ,10,200);

  text(" " + peace, 130, 200);

  rect(200,172, peace, 28);

  text("love ",10,240);

  text(" " + love, 130, 240);

  rect(200,212, love, 28);

  text("arduino ",10,280);

  text(" " + arduino, 130, 280);

  rect(200,252, arduino, 28);

  // write the colour string to the screen

  text("sending", 10, 340);

  text(cs, 200,340);

  text("light level", 10, 380);

  rect(200, 352,light/10.23,28); // this turns 1023 into 100

  if (n <= 0) {

    fetchData();

    lastTime = millis();

  }

  port.write(cs); // send data to Arduino

  if (port.available() > 0) { // check if there is data waiting

    int inByte = port.read(); // read one byte

    if (inByte != 10) { // if byte is not newline

      buffer = buffer + char(inByte); // just add it to the buffer

    }

    else {

      // newline reached, let's process the data

      if (buffer.length() > 1) { // make sure there is enough data

        // chop off the last character, it's a carriage return

        // (a carriage return is the character at the end of a

        // line of text)

        buffer = buffer.substring(0,buffer.length() -1);

       // turn the buffer from string into an integer number

       light = int(buffer);

       // clean the buffer for the next read cycle

       buffer = "";

       // We're likely falling behind in taking readings

       // from Arduino. So let's clear the backlog of

       // incoming sensor readings so the next reading is

       // up-to-date.

       port.clear();

     }

   }

 }

}

void fetchData() {

  // we use these strings to parse the feed

  String data;

  String chunk;

  // zero the counters

  love = 0;

  peace = 0;

  arduino = 0;

  try {

    URL url = new URL(feed); // An object to represent the URL

    // prepare a connection

    URLConnection conn = url.openConnection();

    conn.connect(); // now connect to the Website

    // this is a bit of virtual plumbing as we connect

    // the data coming from the connection to a buffered

    // reader that reads the data one line at a time.

    BufferedReader in = new

      BufferedReader(new InputStreamReader(conn.getInputStream()));

    // read each line from the feed

    while ((data = in.readLine()) != null) {

      StringTokenizer st =

        new StringTokenizer(data,""<>,.()[] ");// break it down

      while (st.hasMoreTokens()) {

        // each chunk of data is made lowercase

        chunk= st.nextToken().toLowerCase() ;

        if (chunk.indexOf(«love») >= 0 ) // found «love»?

          love++; // increment love by 1

        if (chunk.indexOf("peace") >= 0) // found "peace"?

          peace++; // increment peace by 1

        if (chunk.indexOf("arduino") >= 0) // found "arduino"?

          arduino++; // increment arduino by 1

     }

    }

    // Set 64 to be the maximum number of references we care about.

    if (peace > 64) peace = 64;

    if (love > 64) love = 64;

    if (arduino > 64) arduino = 64;

    peace = peace * 4;     // multiply by 4 so that the max is 255,

    love = love * 4;       // which comes in handy when building a

    arduino = arduino * 4; // colour that is made of 4 bytes (ARGB)

  }

  catch (Exception ex) { // If there was an error, stop the sketch

    ex.printStackTrace();

    System.out.println("ERROR: "+ex.getMessage());

  }

}

Есть две вещи, которые вам потребуются для правильного запуска скетча Processing. Во-первых, вы должны указать Processing создать шрифт, который мы будем использовать для скетча. Чтобы сделать это, создайте и сохраните этот скетч. Затем, при открытом скетче, щёлкните меню «Tools» и выберите «Create Font». Выберите шрифт с именем «HelveticaNeue-Bold», выберите 32 для размера шрифта, а затем щёлкните «ОК».

Во-вторых, вам требуется удостовериться в том, что скетч использует правильный последовательный порт для связи с Arduino. Вам надо подождать, пока мы не соберём схему с Arduino и загрузим в неё скетч. На большинстве систем скетч Processing будет работать нормально. Однако если вы видите что на плате Arduino ничего не происходит и на экран не выводится никаких данных от датчика света, найдите комментарий "IMPORTANT NOTE (ВАЖНОЕ ЗАМЕЧАНИЕ)" в скетче Processing и следуйте следующим инструкциям.

  // IMPORTANT NOTE:

  // The first serial port retrieved by Serial.list()

  // should be your Arduino. If not, uncomment the next

  // line by deleting the // before it, and re-run the

  // sketch to see a list of serial ports. Then, change

  // the 0 in between [ and ] to the number of the port

  // that your Arduino is connected to.

  // ВАЖНОЕ ЗАМЕЧАНИЕ

  // Первый последовательный порт, полученный функцией Serial.list(),

  // должен быть подключён к Arduino. Если это не так, раскомментируйте следующую

  // строку удалением // перед ней, и перезапустите

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

  // 0 в между скобками [ и ] на номер порта, к которому

  // подключена ваша Arduino.

  //println(Serial.list());

Вот скетч для Arduino (также доступен на www.makezine.com/getstartedarduino):

Пример 6-2. Сетевая лампа с Arduino

#define SENSOR 0

#define R_LED 9

#define G_LED 10

#define B_LED 11

#define BUTTON 12

int val = 0; // variable to store the value coming from the sensor

int btn = LOW;

int old_btn = LOW;

int state = 0;

char buffer[7] ;

int pointer = 0;

byte inByte = 0;

byte r = 0;

byte g = 0;

byte b = 0;

void setup() {

  Serial.begin(9600); // open the serial port

  pinMode(BUTTON, INPUT);

}

void loop() {

  val = analogRead(SENSOR); // read the value from the sensor

  Serial.println(val); // print the value to

                            // the serial port

if (Serial.available() >0) {

  // read the incoming byte:

  inByte = Serial.read();

  // If the marker's found, next 6 characters are the colour

  if (inByte == '#') {

    while (pointer < 6) { // accumulate 6 chars

      buffer[pointer] = Serial.read(); // store in the buffer

      pointer++; // move the pointer forward by 1

    }

      // now we have the 3 numbers stored as hex numbers

      // we need to decode them into 3 bytes r, g and b

      r = hex2dec(buffer[1]) + hex2dec(buffer[0]) * 16;

      g = hex2dec(buffer[3]) + hex2dec(buffer[2]) * 16;

      b = hex2dec(buffer[5]) + hex2dec(buffer[4]) * 16;

      pointer = 0; // reset the pointer so we can reuse the buffer

    }

  }

  btn = digitalRead(BUTTON); // read input value and store it

  // Check if there was a transition

  if ((btn == HIGH) && (old_btn == LOW)){

    state = 1 – state;

  }

  old_btn = btn; // val is now old, let's store it

  if (state == 1) { // if the lamp is on

    analogWrite(R_LED, r); // turn the leds on

    analogWrite(G_LED, g); // at the colour

    analogWrite(B_LED, b); // sent by the computer

  } else {

    analogWrite(R_LED, 0); // otherwise turn off

    analogWrite(G_LED, 0);

    analogWrite(B_LED, 0);

   }

  delay(100); // wait 100ms between each send

}

int hex2dec(byte c) { // converts one HEX character into a number

    if (c >= '0' && c <= '9') {

      return c – '0';

    } else if (c >= 'A' && c <= 'F') {

      return c – 'A' + 10;

    }

}



    Ваша оценка произведения:

Популярные книги за неделю