Опубликовано

Инструменты для работы через последовательный порт

Рассмотренные нами ранее (см. разд. «Доступ к интерфейсу командной строки») программы эмуляции терминала позволяют получать доступ к удаленным компьютерам через Интернет, но их возможности этим не исчерпываются. Посредством таких программ можно подключаться и к последовательному порту компьютера. Сравнительно недавно в большинстве случаев подключение к Интернету осуществлялось не через какое-либо широкополосное соединение, а через обычные телефонные линии с помощью модема, подключаемого к последовательному порту компьютера. А на заре развития компьютерных коммуникаций многие пользователи таким образом подключались к доскам объявлений (bulletin boards, BBS) и с помощью систем меню программ эмуляции терминала оставляли сообщения, загружали файлы и обменивались сообщениями с другими пользователями этой же доски объявлений. В настоящее время последовательные порты в большинстве случаев эмулируются программными драйверами и служат для связи с различными устройствами USB и прочими периферийными устройствами. Через такие же последовательные порты осуществляется и программирование микроконтроллеров, и обмен данными между ними и компьютером.

В проектах этой книги для подключения микроконтроллера к последовательному порту компьютера также используются программы терминала. Существует большое число терминальных программ — как платных, так и бесплатных. Одной из них является замечательная бесплатная программа CoolTerm, разработанная Роджером Майером (Roger Meier), которую можно загрузить с веб-сайта http://freeware.the-meiers.org. Программа работает как на компьютерах под macOS, так и под Windows, — и это сейчас моя самая любимая программа. Если вы решите пользоваться ею, поступите правильно и сделайте пожертвование, так как автор разрабатывал ее в свое свободное время. Для пользователей Windows хорошей альтернативой может стать уже упомянутая ранее программа PuTTY (рис. 1.6), поскольку, кроме подключения по ssh, она также может открывать последовательные порты. Вы можете избрать и совсем простой путь — воспользоваться классической программой Screen (под лицензией GNU), исполняющейся в окне терминала. Эту программу можно также использовать и на компьютерах под масOS, но она обладает меньшей функциональностью, чем программа CoolTerm.

Рис. 1.6. Установка типа подключения и последовательного порта в PuTTY

Кто получит порт?

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

Программа CoolTerm

Запустите программу CoolTerm (рис. 1.7) и щелкните мышью на значке Options. В открывшемся диалоговом окне Connection Options выберите из раскрывающегося списка Port последовательный порт, к которому подключен микроконтроллер Arduino. Имена портов в macOS представлены в формате вида:

/dev/ tty.usbmodem1441

В Windows порты именуются COM1, COM2, COM3 и т. д. Чтобы узнать наверняка, к какому порту подсоединен ваш микроконтроллер Arduino, проверьте список портов при отсоединенном устройстве, а затем — при подсоединенном. Порт, появившийся в списке после подсоединения микроконтроллера, и будет его портом. Чтобы открыть порт и подключить к нему микроконтроллер, нажмите кнопку Connect на панели инструментов главного окна программы. Чтобы отключить микроконтроллер и закрыть порт, нажмите кнопку Disconnect.

Рис. 1.7. Окно программы терминала CoolTerm

Программа GNU Screen

Пользователи Linux и macOS для работы с последовательным портом также могут использовать программу CoolTerm (см. рис. 1.7) или же альтернативную ей программу GNU Screen.

На Ubuntu версии 15 программу GNU Screen можно установить, выполнив команду:

$ sudo apt-get install screen

Чтобы начать работу с GNU Screen в macOS или Linux, откройте окно терминала и выполните соответствующую команду:

$ ls /dev/tty —* # macOS

$ ls /dev/tty* # Linux

В результате исполнения этой команды в терминале будет выведен список последовательных портов, доступных в системе. Формат имен последовательных портов в macOS и Linux более сложный, чем формат COM1, COM2 и т. д., используемый в Windows, так как каждый порт в этих ОС имеет уникальное имя. Выберите необходимый последовательный порт и выполните команду:

$ screen номер_порта скорость_обмена

Например, чтобы открыть последовательный порт в macOS для подключения к микроконтроллеру Arduino со скоростью 9600 битов в секунду, выполняется команда:

screen /dev/tty.usbmodem1441 9600

Соответствующая ей команда в Linux будет иметь вид:

screen /dev/ttyUSB0 9600

В результате выполнения такой команды окно терминала очищается, устанавливается подключение микроконтроллера к последовательному порту и все, что вводится в терминал, отправляется на открытый последовательный порт. При этом вводимый текст на экране не отображается, но информация, получаемая на последовательный порт от микроконтроллера, отображается на экране в виде символов ASCII. Чтобы закрыть последовательный порт, нажмите комбинацию клавиш <Ctrl>+<A>, а затем — <Ctrl>+<\>.

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

Опубликовано

Платформа node.js

Большинство программ для веб-сервера в этой книге написаны на основе платформы (фреймворка) node.js, позволяющей программировать в операционной системе на языке JavaScript. Первоначально язык JavaScript предназначался для использования в веб-браузерах, чтобы предоставить пользователям возможности взаимодействия с веб-страницами, которые не обеспечивались средствами HTML[1]. Вскоре он стал стандартным языком программирования приложений для веб-браузеров. В 2009 году Райан Даль (Ryan Dahl) с группой программистов из компании Joyent решили использовать язык JavaScript при создании серверных программ, для чего они и разработали платформу node.js. Впоследствии эта платформа приобрела большую популярность для программирования серверных приложений, а также нашла много других применений.

Весьма примечательно, что созданные созданные с использованием платформы node.js программы могут исполняться на локальном или встроенном компьютере, не требуя для этого установки веб-сервера[2]. Это дает возможность протестировать на локальном компьютере свеженаписанные программы, прежде чем загружать их на веб-сайт. Платформа node.js также позволяет создавать клиент-серверные приложения для использования в домашней сети без необходимости подключения к Интернету. Чтобы упростить выполнение примеров этой книги, в большинстве случаев в качестве сервера в ней задействуется локальный компьютер.

В отличие от среды Processing, для платформы node.js не существует стандартного графического интерфейса пользователя. Работа с ней выполняется с помощью командной строки. Загрузите программу установщика node.js с сайта https://nodejs.org/en/ и установите ее на свой компьютер. Затем откройте окно программы терминала, как описано в предыдущем разделе, и выполните команду:

$ node –v

В ответ на экран должно быть выведено сообщение наподобие следующего:

v6.9.5

Это сообщение содержит информацию о версии node.js, установленной на компьютере. Код для проектов этой книги писался под версию node.js 6.9.5, поэтому для их исполнения на вашем компьютере должна быть установлена эта или более поздняя версия node.js.

Установка набора средств разработки

Для создания программ в node.js требуется также ряд других программных средств разработки, которые могут отсутствовать у начинающих программистов. Такой набор состоит из компиляторов, текстовых редакторов и отладчиков и иногда называется цепочкой инструментов[3] (что подразумевает последовательное их использование). Для компьютеров под Windows большинство этих инструментов доступны в пакете интегрированной среды разработки Microsoft Visual Studio, а под macOS — в интегрированной среде разработки XCode.

Пакет Visual Studio платный, но также существует его бесплатная версия Community Edition. Загрузить любую версию пакета, включая бесплатную, можно по адресу: www.visualstudio.com/downloads/.

Пакет XCode можно загрузить из магазина приложений Mac App Store. После установки этого пакета нужно будет также установить средства XCode для работы в командной строке. Это можно сделать, выполнив следующую команду:

$ xcode-select --install

После установки необходимых программных средств можно устанавливать и node.js.

Пишем код

Итак, создадим в node.js первую программу. Запустите свой текстовый редактор, введите в него следующий код:

console.log("Hello world!");

и сохраните файл под именем hello.js на своем компьютере.

Затем запустите программу терминала и перейдите в каталог, в котором вы сохранили программу. Запустите программу на исполнение, выполнив команду:

$ node hello.js

В результате исполнения этой команды на экран будет выведен следующий текст:

Hello world!

Примерно так же захватывающе, как ваш первый скетч на Processing[4], не так ли?

Веб-сервер на node.js

Платформа node.js первоначально предназначалась для написания веб-серверов, и именно с ее помощью большинство пользователей создают такие программы.

Сервер — это программа, которая предоставляет в сети сервисы другим программам, которые называются клиентами. Клиенты посылают веб-серверу запросы по протоколу HTTP[5]. В ответ на эти запросы сервер отсылает клиенту файлы HTML, изображений, аудио и других элементов веб-сайта. Например, ваш веб-браузер, выполняющий роль клиента, устанавливает подключение к серверу и запрашивает веб-страницу. Серверная программа принимает подключение и доставляет клиентской программе (т. е. браузеру) файлы, представляющие эту веб-страницу.

Протокол HTTP, серверы и клиенты рассматриваются более подробно в главе 3, однако мы и сейчас можем написать простой сервер на node.js.

Пишем код

Создайте в своем домашнем каталоге каталог под названием simpleServer. Затем откройте текстовый редактор, введите в него представленную далее программу и сохраните ее в файле server.js в каталоге simpleServer.

Рассмотрим ее код подробнее, чтобы выяснить, как выглядит общая структура программ node.js:

  1. Подключаются библиотеки:
// подключаем библиотеки и объявляем глобальные переменные:
 
var express = require('express'); // Подключаем библиотеку express
  1. Определяются глобальные переменные:
var server = express(); // создаем объект server,
 
// используя библиотеку express
  1. Определяются функции обратного вызова:
// определяем функцию, которая вызывается
 
// при поступления запроса от клиента:
 
function respondToClient(request, response) {
 
console.log("got a request"); // выводим сообщение
 
//в консоли командной строки
 
//отправляем сообщение клиенту:
 
response.writeHead(200, {"Content-Type": "text/html"});
 
response.write("Hello, client!");
 
response.end();
 
}
  1. Исполняется основной код:
// Запускаем сервер:
 
server.listen (8080);
 
// определяем, что делать при получении запроса клиента:
 
server.get('/*', respondToClient);
 
console.log("Server is listening on port 8080");

Убедитесь в наличии подключения к Интернету, затем перейдите в командной строке в каталог simpleServer и выполните команду:

$ npm install express

Эта команда дает указание npm — диспетчеру пакетов node (node package manager) установить библиотеку express.js, которая необходима для работы сервера. В процессе исполнения команды отображается индикатор выполнения, выводятся несколько предупреждений, и по завершении исполнения снова возвращается командная строка. Теперь выполните следующую команду:

$ node server.js

В результате исполнения этой команды на экран выведется следующий текст:

Server is listening on port 8080 (Сервер прослушивает порт 8080)

После этого предложение командной строки вы увидеть не сможете, поскольку, в отличие от программы из файла hello.js, исполнение которой завершилось после выполнения одной ее строки, эта программа продолжает исполняться. Откройте какой-либо браузер и введите в строку адреса:

$ node server.js
http://localhost:8080

В результате должна открыться страница, наподобие показанной на рис. 1.5.

Рис. 1.5. Результат исполнения программы сервера node.js браузере

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

Got a request! (Получен запрос!)

И так на каждый запрос веб-браузера сервер выводит ответ в консоль командной строки. Иногда после ввода адреса в адресную строку веб-браузер посылает серверу два запроса, одним из которых является запрос favicon — небольшого значка слева от адреса страницы в строке адреса веб-браузера.

Чтобы завершить работу программы веб-сервера, нажмите на клавиатуре комбинацию клавиш <Ctrl>+<C>.

Структура программ node.js

Структура программ node.js (которые иногда называются скриптами или сценариями) иная, чем у скетчей Processing. Рассмотрим некоторые из этих различий.

Прежде всего, JavaScript (и, соответственно, node.js) является языком со слабым контролем типов данных. Это означает, что при объявлении переменных объявлять тип их данных не нужно — достаточно объявить их с помощью ключевого слова var. А JavaScript сам попытается определить тип данных переменной в зависимости от способа ее применения.

Второе, JavaScript является функциональным языком программирования. То есть переменные в нем могут содержать не только значения, но и функции. Все станет вам более понятным, когда вы увидите реализацию этого принципа на практике. Посмотрите на программу веб-сервера из предыдущего раздела. В первой строке программы создается копия (которая называется экземпляром) библиотеки node.js express, которая сохраняется в переменной express. Функции этой библиотеки будут затем вызываться из переменной http. Во второй строке кода функция express() создает экземпляр всей библиотеки express, который сохраняется в переменной server. Далее, в конце программы, вызывается функция listen() объекта server, которая прослушивает порт 8080 на наличие новых запросов от клиентов.

Третье, программы JavaScript исполняются асинхронно. Это означает, что каждая команда начинает исполняться сразу же после запуска предыдущей, не дожидаясь завершения ее исполнения. При вызове функции ей часто передается функция обратного вызова, которая исполняется, когда она готова выдать какие-либо результаты. Пример использования такой функции можно увидеть во второй строке основного кода программы server.js — функция server.get() содержит функцию обратного вызова respondToClient(), которая исполняется при каждом поступлении запроса от нового клиента. Благодаря свойству асинхронности программ JavaScript, сервер может одновременно отвечать на несколько запросов, без необходимости завершить ответ на один, чтобы начать отвечать на другой.

В языке JavaScript используется синтаксис в стиле языков С и Java. В частности, операторы (инструкции) заканчиваются точкой с запятой, а блоки кода заключаются в фигурные скобки. Синтаксис в стиле языка С используется и для условных операторов if-then и операторов цикла for.

Сценарии серверов на node.js обычно имеют такую структуру:

  1. С помощью функции require() подключаются все необходимые библиотеки.
  2. Объявляются переменные, область действия которых охватывает всю программу (глобальные переменные).
  3. Объявляются функции обратного вызова, которые будут использоваться в основном коде.
  4. Исполняется основной код.

В соответствии с этой структурой и создана программа server.js.

Дополнительную информацию по синтаксису node.js вы найдете в руководстве, которое можно загрузить с веб-сайта www.nodejs.org. Более подробно программирование с использованием node.js описано в книге Шелли Пауэрс (Shelley Powers) «Learning Node: Moving to the Server-Side» (издательство O’Reilly). А книга Этана Брауна (Ethan Brown) «Learning JavaScript» (издательство O’Reily) поможет вам в изучении языка JavaScript.

  1. HTML, HyperText Markup Language — язык разметки гипертекстовых документов.
  2. Значимость этого обстоятельства становится понятной в свете того факта, что для исполнения на локальном или удаленном компьютере программ, написанных на другом популярном языке для серверных программ — PHP, требуется наличие веб-сервера — например, Apache.
  3. От англ. toolchain.
  4. К сожалению, русские буквы с консольном режиме в среде node.js не отображаются, поэтому получить здесь «Здравствуй, мир!» у нас не получится.
  5. HTTP, Hypertext Transfer [Transport] Protocol — протокол передачи гипертекста.
Опубликовано

Интерфейсы командной строки и удаленные серверы

Интерфейсы командной строки и удаленные серверы

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

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

Наиболее распространенная версия интерфейса командной строки используется в операционных системах на основе UNIX, включая такие операционные системы, как BSD, Linux, macOS и прочие. Операционные системы, интерфейс командной строки в которых организован таким образом, называются операционными системами в стиле POSIX[1]. Все встречающиеся в этой книге инструкции командной строки предполагают использование интерфейса командной строки именно в этом стиле.

Доступ к интерфейсу командной строки

Доступ к  интерфейсу командной строки на компьютере реализуется через программу эмуляции терминала.

В macOS и Linux

В macOS эта программа называется Terminal и находится в подкаталоге Utilities каталога Applications. В Linux эмулятор командной строки может называться xterm, rxvt, Terminal или Konsole.

 В Windows

Интерфейс командной строки Windows основан на DOS и отличается от интерфейсов командной строки, используемых в операционных системах в стиле POSIX. Найти программу командной строки в Windows можно, набрав cmd в поле поиска меню Пуск. Пока готовилась эта книга, компания Microsoft выпустила интерфейс командной строки в стиле POSIX для Windows 10 (выполните поиск по фразе: bash для Windows 10) — в настоящее время он доступен только в режиме разработчика, но уже выглядит многообещающе. Получить полноценный интерпретатор команд (именно так еще называется интерфейс командной строки) в стиле POSIX на Windows можно, установив программу Cygwin (www.cygwin.com). По мере возможности, примеры этой книги с использованием командной строки для Windows были протестированы под Cygwin и доказали свою работоспособность. В процессе установки Cygwin в обязательном порядке выберите опцию установки пакета Net (входит в список экрана Packages установщика)  тогда будут установлены многие полезные сетевые инструменты, использующие стиль POSIX.

Виртуальные частные серверы

Многие рассматриваемые в этой книге программы представляют собой веб-серверы, для работы с которыми требуется веб-хост. Современные веб-серверы очень просто устанавливать и обслуживать. И если у вас нет своего веб-хоста, можно обратиться к поставщикам услуг веб-хостинга, предоставляющим услуги виртуального частного сервера (ВЧС). У них можно будет создать виртуальный веб-сервер, доступ к которому будет только у вас. Виртуальный веб-сервер позволит вам разобраться с конфигурированием веб-сервера и управлением им, а если вы что-либо наконфигурируете до невозможности восстановления нормальной работы веб-сервера, его можно будет просто удалить нажатием кнопки на веб-панели и создать другой веб-сервер с исходной конфигурацией. Существует ряд поставщиков услуг веб-хостинга, предоставляющих услуги виртуального частного сервера по низкой цене или вообще бесплатно — при условии ограниченного веб-трафика на ваш сервер. Например, такие поставщики услуг веб-хостинга как Digital Ocean (www.digitalocean.com), Amazon Web Services (aws.amazon.com), BlueHost (www.bluehost.com) и DreamHost (www.dreamhost.com) предоставляют услуги ВЧС по вполне доступным расценкам. Некоторые поставщики услуг веб-хостинга также предоставляют скидки для преподавателей и/или студентов, так что уточните у них и эту возможность.

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

Подключение к удаленному веб-хосту

Хотя интерфейс командной строки можно использовать для работы на локальном компьютере, в этой книге он также часто задействуется для доступа к удаленным компьютерам: или к веб-хосту или ко встроенному микропроцессору. Большинство поставщиков веб-хостинга используют Linux, BSD, Solaris или другую UNIX-подобную операционную систему.

Для компьютеров Windows существует несколько программ удаленного доступа, но мы будем пользоваться программой PuTTY, которую можно загрузить по адресу www.puttyssh.org. Процедура установки несложная — с веб-сайта программы загрузите установщик Windows для нее и запустите его на исполнение. На компьютерах под macOS и Linux для удаленного доступа можно использовать программу OpenSSH, которая входит в состав обеих этих операционных систем. Запустить ее на исполнение можно в программе Terminal с помощью команды ssh.

В macOS и Linux

Откройте программу терминала. Обычно терминал предоставляет простое текстовое окно с приветствием наподобие следующего:

Last login: Wed Feb 22 07:20:34 on ttyp1

ComputerName:~ username$

В системах POSIX символ $ называется приглашением командной строки. Когда за этим символом следует мигающий курсор, это означает, что система ожидает ввода команды. Во всех случаях, рассмотренных в этой книге, в командную строку следует ввести все, что следует за этим символом.

Чтобы подключиться к требуемому веб-серверу, выполните в командной строке команду:

ssh имя_пользователя@имя_хоста.com

Разумеется, вместо параметров имя_пользователя и имя_хоста.com введите свои имя пользователя (имя_пользователя) и адрес веб-сервера (имя_хоста.com) соответственно. Введите пароль, который затем потребует удаленный веб-сервер, и вы должны к нему подключиться.

В Windows

Запустите программу PuTTY (рис. 1.3).

Рис. 1.3. Главное окно программы PuTTY

Введите адрес своего веб-сервера (имя_хоста.com) в поле Host Name, установите в разделе Connection type переключатель SSH и нажмите кнопку Open. Затем выполните вход на сервер, введя в соответствующие поля открывшейся панели свои имя пользователя и пароль.

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

Работа с командной строкой

Установив соединение с удаленным веб-сервером, вы увидите примерно такое сообщение:

Last login: Wed Feb 22 08:50:04 2016 from 216.157.45.215

[userid@myhost ~]$

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

$ pwd

Эта команда состоит из первых букв фразы print working directory, которая означает «распечатать рабочий каталог». Она указывает компьютеру отобразить имя и путь текущего каталога. (Многие команды POSIX весьма кратки — чтобы их было легче вводить. С другой стороны, аббревиатурные команды труднее запомнить.) В ответ сервер выведет путь и имя текущего каталога — в моем случае:

/home/igoe

Это рабочий (домашний) каталог учетной записи на сервере. Для вывода списка файлов каталога используется команда ls (list):

$ ls -l .

Точки в конце команды

Точка в конце команды означает «текущий каталог», а две точки — «родительский каталог текущего каталога».

Параметр –l при команде ls означает list long — требование выводить подробный список. В результате исполнения этой команды выводится примерно такой ответ:

total 44

drwxr-xr-x 13 igoe users 4096 Apr 14 11:42 public_html

drwxr-xr-x 3 igoe users 4096 Nov 25 2005 share

Это список всех файлов и вложенных каталогов, содержащихся в текущем каталоге, с указанием их атрибутов:

  • в первом элементе строки (например: drwxr-xr-x) указываются разрешения для действий с этим объектом: чтение, изменение или исполнение;
  • во втором элементе (13) указывается количество ссылок на этот файл из других областей системы;
  • в третьем элементе (igoe) указывается владелец объекта, а в четвертом (users) — группа владельцев;
  • в пятом элементе (4096) указывается размер объекта, а в шестом (Apr 14 11:42) — дата и время последнего изменения;
  • наконец, в последнем элементе (public_html) указывается имя объекта.

В среде POSIX все файлы, имена которых начинаются с точки, в общем случае не отображаются. Это требуется для некоторых особых файлов — таких, например, как файлы паролей или конфигурационные файлы. Чтобы просмотреть содержимое каталога, включая его скрытые файлы, с командой ls нужно использовать параметр: ‑la:

$ ls -la

Для создания нового каталога служит команда: mkdir (make directory):

$ mkdir directoryname

Эта команда создает новый каталог в текущем каталоге. Команда ls –l, выполненная после создания нового каталога, отобразит этот каталог на новой строке в списке объектов текущего каталога. При просмотре содержимого пустого каталога (каким будет вновь созданный каталог) с помощью команды ls -la выводится только две строчки:

drwxr-xr-x 2 tqi6023 users 4096 Feb 17 10:19 .

drwxr-xr-x 4 tqi6023 users 4096 Feb 17 10:19 ..

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

Чтобы удалить каталог, служит команда rm (remove directory) с указанием каталога, подлежащего удалению:

$ rmdir directoryname

Удалить можно только пустой каталог, поэтому перед удалением каталога нужно удалить все его содержимое — как файлы, так и вложенные каталоги. Команда rmdir выполняется немедленно, без запроса на подтверждение удаления, поэтому нужно быть осторожным в ее использовании. Не следует также удалять какие бы то ни было каталоги или файлы, которые создавали не вы.

В большинстве веб-хостингов для веб-сайтов пользователей автоматически создается домашний каталог, которая называется html или public_html, — для размещения в нем файлов HTML для общего доступа. Если на вашем веб-сервере такого каталога нет, создайте его с помощью команды mkdir:

$ mkdir html

Для перемещения из одного каталога в другой служит команда cd (change directory) — изменить каталог. Например, перейти из корневого каталога в каталог html можно, выполнив следующую команду:

$ cd html

Чтобы переместиться на один уровень выше в иерархии каталогов, выполняется команда:

$ cd ..

Для возврата в домашний (корневой) каталог к команде cd добавляется параметр ~ (тильда):

$ cd ~

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

Для перехода во вложенный каталог этот каталог указывается после родительского каталога через косую черту / (слэш). Например, чтобы перейти в каталог html в домашнем каталоге, выполняется команда cd~/html. Чтобы указать абсолютный путь из главного каталога сервера (который называется root — корневой), в начале пути файла ставится такая же косая черта — /. Пути без косой черты в их начале называются относительными.

Управление доступом к файлам

Выполните команду ls –l, чтобы вывести список файлов текущего каталога, и рассмотрите поближе разрешения для файлов.

Например, обозначение:

drwx ——

означает, что объект является каталогом (d — directory), и создавший его пользователь (который также называется владельцем) может просматривать или читать его (r — read), записывать в него (w — write), а также исполнять его (x — execute). Рассмотрим другой пример разрешения:

-rw-rw-rw

Дефис в начале означает, что объект является файлом (а не каталогом), и что владелец файла, группа владельцев (обычно владелец является членом этой группы), а также любой другой, кто имеет доступ к файлу, может просматривать его и выполнять запись в него. При этом первая группа rw- задает разрешения владельца, вторая — группы, а третья — всех остальных. Владелец объекта может изменить его разрешения с помощью команды chmod:

$ chmod go-w имя_файла

Параметры этой команды указывают пользователей, которых она затрагивает, и изменяемые разрешения. В приведенном примере мы удаляем разрешения на запись (-w) для группы (g — group) владельцев файла и всех других (o — others), кроме владельца файла. А в следующем примере мы присваиваем права записи и исполнения для группы и других пользователей:

$ chmod go+wx имя_файла

Как вы уже поняли, в параметрах команды chmod буква u означает пользователя (user), g — группу (group), а o — прочих (others). Мы также знаем, что буква r означает разрешения чтения (read), w — записи (write), а x — исполнения (execute). Знак + (плюс) означает присвоение разрешений, а знак – (минус) — лишение их. Будьте осторожны, чтобы случайно не лишить разрешений самого себя (пользователя). Кроме того, выработайте привычку не предоставлять доступа к файлам для групп и прочих, если только в этом нет необходимости, — на крупных поставщиках услуг веб-хостинга иметь соседями по серверу сотни других пользователей — обычное дело.

Создание, просмотр и удаление файлов

Для работы с файлами вам пригодятся еще две программы командной строки: nano и less. Программа nano — это текстовый редактор, и очень простой редактор, поэтому для объемных работ лучше редактировать текст на своем компьютере с помощью какого-либо другого, более удобного, редактора, а затем загружать готовый текст на сервер. Но для небольших правок прямо на сервере программа nano незаменима. Чтобы создать с помощью nano новый файл, выполните следующую команду:

$ nano имя_файла.txt

Откроется окно редактора (рис. 1.4).

Рис. 1.4. Окно текстового редактора nano. В нижней части окна имеется список доступных команд, которые исполняются по нажатию клавиши <Ctrl> совместно с клавишей буквы английского алфавита, указанной слева от соответствующей команды. Например, нажатие комбинации клавиш <Ctrl>+<K> выполняет операцию вырезания (kut) выделенного фрагмента текста

Все команды для работы в nano вводятся с клавиатуры совместно с клавишей <Ctrl>. Например, для выхода из программы нужно нажать комбинацию клавиш <Ctrl>+<X>. Наиболее часто употребляемые команды указаны в нижней части окна редактора.

Удалить любой файл можно с помощью команды rm (remove):

$ rm filename

Подобно команде rmdir, команда rm не выводит запроса на подтверждение удаления файла, поэтому нужно быть осторожным в ее использовании.

Насколько редактор nano удобен для быстрого создания и редактирования небольших текстовых файлов, настолько для чтения таких файлов хорошо подходит редактор less. Этот редактор отображает текстовый файл по одному экрану за раз. Для просмотра текстового файла в less нужно просто ввести имя этого редактора, а за ним требуемый файл:

$ less имя_файла.txt

В результате содержимое файла выводится поэкранно, с приглашением в виде двоеточия (:) в конце экрана. Нажатие клавиши пробела выводит следующий экран текста. Чтобы завершить работу программы, нажмите клавишу <q>. Определенно, похвастаться никакими крутыми наворотами less не может, но со своей основной задачей — просмотром длинных файлов — он справляется «на отлично».

Для просмотра файлов также могут быть полезными команды cat, head и tail.

Команда cat вываливает на экран все содержимое файла без разбиения на его страницы:

$ cat имя_файла.txt

А команды head и tail используются для просмотра начала и конца длинных файлов, соответственно. Количество строк файла для просмотра указывается в параметре, следующем за командой:

$ head -5 имя_файла.txt

В этом случае будут отображены первые пять строк файла имя_файла.txt. Подобным образом команда:

$ tail -10 filename.txt

выводит на экран последние десять строк файла имя_файла.txt.

Команды cat, head и tail очень полезны, когда нужно объединить несколько программ в одну. Эти процедуры рассматриваются в следующем разделе.

Объединение нескольких программ в одну

Операционная система UNIX разрабатывалась по философии «набора малых компонентов со слабыми связями». Иными словами, каждая запускаемая из командной строки программа (такие программы часто называются процессами, хотя одна программа может иногда запускать множественные процессы) должна выполнять только одну задачу, но выполнять ее хорошо. Кроме того, каждая такая программа должна обладать гибкой возможностью автоматического объединения с другими подобными программами. Поскольку результатом работы любой программы командной строки является текстовый вывод, вывод одной программы легко использовать в качестве ввода для другой. Например, при выполнении программы ls для каталога с большим количеством объектов, объекты в начале списка вытесняются с экрана последующими объектами. Но вывод программы ls можно передать программе less, которая уже будет выводить список объектов, помещающихся на экране. Делается это следующим образом:

$ ls -la . | less

В интерфейсах командной строки оператор вертикальная черта (|) называется оператором канала, посредством которого выходные данные одной программы передаются на вход другой для дальнейшей обработки.

Вместо вывода на экран выходные данные программы можно также перенаправлять в какое-либо другое место — например, в файл. Так, список объектов каталога можно сохранить в файл, выполнив следующую команду:

$ ls -la . > список_файлов.txt

Эта команда создает файл список_файлов.txt и сохраняет в нем вывод команды ls. Если файл с таким именем уже существует, его содержимое заменяется выводом команды ls. Вместо замены содержимого существующего файла, новые данные можно добавить к нему в конец:

$ ls -la . >> список_файлов.txt

Одна из причин, по которой такие операции являются возможными, заключается в том, что POSIX-системы рассматривают многие объекты как потоки данных, каждый из которых может заменяться любым другим. Например, выводимый на экран текст называется стандартным потоком выходных данных — standard out, или stdout. А выдаваемые клавиатурой данные являются стандартным потоком входных данных — standard in, или stdin. Файл также является потоком данных, в результате чего с помощью операторов канала и перенаправления можно осуществлять запись байтов в файл (stdin) и чтение из него (stdout).

Поток данных можно представить в виде трубы, в которую байты входят с одного конце, а выходят из другого. Таким образом, первый входящий в такую трубу байт первым же и выходит из нее. Такая организация входа/выхода называется FIFO[2]: первый на входе — первый на выходе. Эти команды совместно с рядом рассмотренных ранее команд и понятий позволяют выполнять довольно-таки хитроумные операции. Мы увидим некоторые примеры таких операций далее в этой главе и в книге.

Кроме рассмотренных, существует много других команд командной оболочки[3]. Список наиболее употребляемых можно получить, выполнив в терминале команду help, а информацию об определенной команде — выполнив команду:

man имя_команды

Чтобы закрыть подключение к серверу или завершить сеанс работы с терминалом на локальном компьютере, выполните команду logout. В некоторых вариантах Linux для этого вместо команды loguot используется команда exit.

На машинах с операционной системой в стиле POSIX — будь то машина под macOS, Linux или одноплатный компьютер — все только что рассмотренные команды должны работать в программе терминала локальной машины так же, как они работают на удаленном сервере через подключение ssh. Большинство этих команд работают и в среде Cygwin на машинах под Windows. Их также можно использовать и на одноплатных компьютерах, как мы увидим далее в этой главе.

Дополнительную информацию о работе с интерфейсом командной строки операционных систем UNIX и Linux вы сможете найти, например, в книге Аарона Ньюкомба (Aaron Newcomb) «Linux for Makers» (издательство Maker Media).

  1. POSIX, Portable Operating System Interface — интерфейс переносимой операционной системы.
  2. FIFO, First In, First Out — первым вошел, первым вышел.
  3. От англ. command shell — программа, которая обрабатывает команды интерфейса командной строки.
Опубликовано

Среда Processing

Одним из программных средств, с которым нам придется иметь дело в этой книге, является многоцелевая программная среда, именуемая Processing. Это бесплатный инструмент с открытым исходным кодом, и его можно загрузить с веб-сайта www.processing.org. Среда Processing основана на платформе Java и предназначена для тех пользователей, которые хотят реализовывать свои проекты без необходимости глубоко вникать в программирование. Тем не менее, Processing — весьма полезный инструмент для знакомства с принципами программирования, поскольку для осуществления серьезных действий: создания сетевого соединения, подключения к внешнему устройству через последовательный порт, управления камерой — требуется сравнительно небольшой объем кода Processing. Поскольку, как уже отмечалось, среда Processing основана на Java, в программы Processing можно включать классы и методы языка Java. Среда может исполняться под macOS, Windows и Linux. Существует также версия Processing для Android. Если по какой-либо причине вам не нравится работать в среде Processing, вы можете использовать приведенные в этой книге примеры ее кода и комментарии к ним в качестве исходных для создания таких примеров в любой среде, которой вы отдаете предпочтение.

Загрузив и установив среду Processing на своем компьютере, запустите ее на выполнение. Откроется окно, наподобие показанного на рис. 1.2.

Рис. 1.2. Окно редактора кода среды Processing

Пишем код

Теперь давайте создадим нашу первую программу в Processing. Введите в окно редактора следующий текст:

1
println("Здравствуй, мир!");

а затем нажмите кнопку Run (Исполнить) — самую левую кнопку на панели инструментов Processing

Не ахти какая программа, но это классическая первая программа на любом языке программирования. Исполнение этой программы выводит текст: Здравствуй, мир! в текстовом поле в нижней области окна редактора. Как видим, ничего сложного.

Программы Processing называются скетчами (sketch), и все данные скетча по умолчанию сохраняются на компьютере в каталоге с именем скетча подкаталога Processing каталога Документы. Впрочем, вы можете сохранять их в любом каталоге на свое усмотрение. Редактор Processing весьма прост и не содержит каких-либо «примочек», отвлекающих внимание. Панель инструментов редактора состоит из кнопок для запуска и остановки исполнения скетчей, открытия существующих скетчей, сохранения скетчей и экспортирования скетчей в апплеты Java. Кроме того, скетчи можно экспортировать в виде автономных приложений.

Пишем код

Рассмотрим теперь более сложную программу, которая демонстрирует некоторые основные структуры программирования Processing.

Контекст использования кода

Все примеры кода в этой книге сопровождаются комментариями, указывающими контекст, в котором они должны использоваться: Processing, Arduino, node.js и т. п.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
/*
Программа рисования треугольников
Контекст: Processing
Рисует треугольник при отпущенной левой кнопке мыши. Очищает окно рисования при нажатии левой кнопки мыши.
*/
 
// объявляем переменные:
float redValue = 0; // переменная для красного цвета
float greenValue = 0; // переменная для зеленого цвета
float blueValue = 0; // переменная для синего цвета
// метод setup() исполняется один раз в начале программы:
void setup() {
size(320, 240); // устанавливаем размер окна рисования
background(0); // устанавливаем черный фон окна рисования
fill(0); // задаем цвет для заполнения фигур (0 = черный)
smooth(); // рисуем фигуры со сглаженными кромками
}
 
// Метод draw() исполняется непрерывно, пока открыто окно рисования.
// Он обновляет окно, а также выполняет любые запрограммированные в нем действия:
void draw() {
// Выбираем произвольные значения красной, зеленой и синей составляющих цвета:
 
redValue = random(255);
 
greenValue = random(255);
blueValue = random(255);
// задаем цвет линии:
stroke(redValue, greenValue, blueValue);
// рисуем при отпущенной левой кнопке мыши (игнорируя все обычные правила):
if (mousePressed == false) {
// рисуем треугольник
triangle(mouseX, mouseY, width/2, height/2, pmouseX, pmouseY);
}
// очищаем окно рисования при нажатии левой кнопки мыши:
else {
background(0);
fill(0);
}
}

Любая программа Processing должна содержать два основных метода (процедуры): setup() и draw(). Метод setup() исполняется один раз в начале программы, устанавливая все начальные условия, — такие как размер окна апплета, начальные значения переменных и т. п. А метод draw() — основной цикл программы, исполняющийся непрерывно, пока окно апплета открыто.
Для переменных Processing нужно задавать тип их данных. В приведенной здесь программе переменные redValue, greenValue и blueValue — плавающего типа (float), т. е. они могут содержать числа с плавающей запятой. Другие распространенные типы данных переменных, с которыми нам придется работать, это:

  1. int — целочисленные значения;
  2. char — однобайтовые значения символов ASCII;
  3. boolean — значения true (истина) или false (ложь);
  4. string — текст;
  5. byte — байт.

Язык программирования Java, а, следовательно, и производный от него язык Processing, являются языками программирования со строгим контролем типов данных. Иными словами, это означает, что переменные должны быть объявлены, прежде чем их можно будет использовать в программе. При этом для каждой объявленной переменной резервируется определенный объем памяти. Например, для переменной типа byte требуется один байт памяти, типа int — четыре байта и т. д. Каждый язык, с которым вам придется иметь дело в этой книге, обрабатывает переменные своим способом, который слегка отличается от способов других языков, поэтому при объявлении и использовании переменных в каждом языке следует быть осторожным.

Подобно языкам Java и JavaScript, синтаксис программ в среде Processing близок по стилю к синтаксису языка С. Как и переменные, все функции в нем также имеют тип данных (и у многих из них тип данных void — т. е. они не возвращают никаких значений в результате исполнения). Все строки кода должны заканчиваться точкой с запятой, а блоки кода заключаются в фигурные скобки. Условные операторы (if-then), операторы цикла (for-next) комментарии также используют синтаксис языка С. За исключением цикла for-next, все эти операторы вы могли видеть в приведенной ранее программе рисования треугольников.

А пример цикла for-next демонстрируется в следующем фрагменте кода:

1
2
for (int myCounter = 0; myCounter &lt;=10; myCounter++) {
println(myCounter);

Попробуйте создать свой скетч с использованием этого цикла. Для создания нового скетча выполните команду New в меню File среды Processing.

Пользователям BASIC и Python

Если вы никогда не использовали цикл for-next в стиле С, этот пример может показаться вам чем-то страшным. В действительности, ничего сложного в нем нет. Все, что приведенный здесь код делает, это сначала устанавливает значение переменной myCounter, а затем исполняет заключенные в фигурные скобки инструкции до тех пор, пока это значение остается меньшим или равным 10. Инструкция myCounter++ указывает программе добавить единицу к значению myCounter при каждом прохождении цикла. Эквивалентный код в BASIC выглядит следующим образом:

1
2
3
for myCounter = 0 to 10
Print myCounter
next

А на языке Python этот же код будет выглядеть так:

1
2
for myCounter in range (0, 10):
print myCounter

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

Поскольку среда Processing предназначена для использования в качестве инструмента исследования визуального дизайна, в ней отсутствуют многие стандартные элементы пользовательского интерфейса — такие как кнопки и меню с выбором позиций. Это дает вам свободу как дизайнеру, но при этом заставляет быть более изобретательным в программировании, чтобы создавать свои собственные элементы пользовательского интерфейса с нуля.

Дополнительную информацию по синтаксису Processing легко найти в руководстве, которое можно загрузить с веб-сайта www.processing.org. Узнать больше о программировании в Processing можно также из книги «Processing: A Programming Handbook for Visual Designers and Artists» (издательство MIT Press), написанной создателями этого языка Кэйси Ризом и Беном Фрайем, или из их более короткой книги «Getting Started with Processing» (издательство O’Reilly). Также можно воспользоваться отличной книгой для начинающих «Learning Processing» (издательство Morgan Kaufmann), написанной Даниэлем Шифманом (Daniel Shiffman).

Опубликовано

Последовательный обмен данными с использованием двух протоколов последовательной связи: TTL Serial и USB

По материалам книги Т.Иго «Умные вещи: Arduino, датчики и сети для связи устройств: Пер. с англ. 3-е изд.»  (глава 2 «Простейшая сеть»)

Умные вещи: Arduino

Устанавливаем соединение: нижние уровни

Мы уже знакомы с одним примером последовательного обмена данными — между микроконтроллером и персональным компьютером. В частности, в главе 1 мы подключили микроконтроллерный модуль к персональному компьютеру через порт USB. Это подключение является примером асинхронного последовательного обмена данными с использованием двух протоколов последовательной связи: TTL Serial и USB.

Первый из них — это протокол, понимаемый микроконтроллером, и называется он последовательный ТТЛ (TTL[1] Serial). Этот протокол можно разделить на следующие концептуальные уровни:

  • Физический. Определяет контакты, используемые контроллером для обмена данными. В модуле Arduino данные принимаются на контакт, обозначенный RX (от Receive, прием), а передаются с контакта, обозначенного TX (от Transmit, передача).
  • Электрический. Определяет напряжения для представления битов данных. В некоторых микроконтроллерах применяется напряжение 3,3 В, в других — 5 В.
  • Логический. Высокий уровень напряжения (3,3 или 5 В) представляет логическое значение 1, а низкий (0 В) — логическое значение 0.
  • Уровень данных. Обмен данными обычно осуществляется со скоростью 9600 битов в секунду. Для представления одного символа требуется один байт, который содержит 8 битов данных, а также стартовый и стоповый биты (которые мы никогда не будем использовать).
  • Уровень приложений. На этом уровне мы отправляем один байт от ПК на микроконтроллер, который обрабатывает его и возвращает один байт на ПК.

Но это еще не все. Импульсы напряжения не идут на ПК напрямую. Сначала они поступают на TTL/USB микросхему на плате, которая преобразовывает последовательные TTL-сигналы в последовательные USB-сигналы. На некоторых микроконтроллерных платах — например, на Arduino Uno, преобразователь USB сигналов в сигналы ТТЛ реализован в виде отдельной микросхемы. На других же — например, на MKR1000 и Arduino 101, эта функциональность встроена в микросхему микроконтроллера.

Обработка преобразованных в формат USB сигналов осуществляется с использованием соответствующего протокола USB[2], который во многом отличается от протокола последовательного обмена TTL. Он разбивается на следующие концептуальные уровни:

  • Физический. Шина USB состоит из двух проводов для передачи данных: Data+ и Data– и двух проводов питания (+5 В и общего).
  • Электрический. Сигнал на линии Data– всегда противоположен сигналу на линии Data+, в результате чего сумма напряжений этих сигналов всегда равна нулю. Эта особенность используется приемником для проверки на наличие ошибок электрического сигнала — для этого он складывает напряжения обеих этих линий. Если полученная сумма не равна нулю, приемник отбрасывает такой сигнал.
  • Логический. Логическое значение 1 представляется сигналом напряжения +5 В (на линии Data+) или –5 В (на линии Data–), а логическое значение 0 — сигналом напряжения 0 В.
  • Уровень данных. Уровень данных модели протокола USB более сложный, чем соответствующий уровень протокола последовательного обмена ТТЛ. В USB скорость обмена данными может достигать 480 мегабит в секунду. Один символ представляется одним байтом, который содержит 8 битов данных, а также стартовый и стоповый биты. Несколько устройств USB под управлением ПК могут использовать для обмена данными одну и ту же пару проводов (набор проводов для обмена сигналами называется шиной). Поскольку к одной шине может быть подсоединено несколько устройств, операционная система присваивает каждому из этих устройств однозначный адрес и обеспечивает обмен данными между каждым подсоединенным к шине устройством и его соответствующим приложением на компьютере.
  • Уровень приложений. На уровне приложения преобразователь USB/TTL-Serial на плате Arduino отправляет операционной системе компьютера несколько байтов, чтобы идентифицировать себя. Операционная система использует эти байты для того, чтобы сопоставить плату с программой ее драйвера, который другие программы могут использовать для обмена данными с этим устройством.

Все это управление прозрачно для пользователя, так как контроллер USB компьютера передает ему только те байты, которые предназначены для него. Микросхема преобразователя USB/TTL-Serial на плате Arduino представляет себя операционной системе компьютера в качестве последовательного порта и отправляет данные через разъем USB с выбранной пользователем скоростью (9600 битов в секунду — как в примере из главы 1).

 

Кабель-переходник USB/TTL-Serial компании FTDI

 

Рис. 2.4. Кабель-переходник USB/TTL-Serial компании FTDI

Распиновка разъема TTL

Рис. 2.5. Распиновка разъема TTL кабеля USB/TTL-Serial компании FTDI. Кроме линий передачи, приема и питания он также имеет линии для аппаратного управления обменом данных: RTS (Request-to-send, запрос на передачу) и CTS (Clear-to-send, готовность к передаче). Некоторые устройства используют эти линии для управления потоком последовательных данных

Есть и еще один протокол — если вы используете микроконтроллерный модуль BASIC Stamp или другой микроконтроллерный модуль с интерфейсом иным, чем USB, он, скорее всего, оснащен 9-контактным разъемом для подключения к компьютеру или к адаптеру USB/RS-232 (распиновка разъемов USB и RS-232 показана на рис. 2.6). Этот разъем называется DB-9 или D-sub-9 и является стандартным разъемом для другого последовательного протокола: RS-232. Протокол RS-232 был стандартом для последовательного интерфейса компьютеров до протокола USB и все еще встречается на некоторых специализированных периферийных устройствах. Этот протокол состоит из следующих концептуальных уровней:

  • Физический. Данные в разъеме RS-232компьютера принимаются на контакт 2, а передаются с контакта 3. Контакт 5 — «земля».
  • Электрический. Данные в стандарте RS-232 передаются двумя уровнями напряжения: от +3 В до +25 В и от –3 В до –25 В.
  • Логический. Высокий уровень напряжения (от +3 В до +25 В) представляет логическое значение 0, а низкий (от –3 В до –25 В) — логическое значение 1. Как можно видеть, эта схема построена на основе отрицательной (или инвертированной) логики.
  • Уровень данных. Такой же, как и в протоколе TTL, — 8-битовый байт данных с дополнительными стартовым и стоповымбитами.

Распиновка разъемов: USB и RS-232

Рис. 2.6. Распиновка разъемов: USB и RS-232

 

Спрашивается, как же подключать некоторые микроконтроллеры — например, BASIC Stamp, непосредственно к последовательному порту RS-232? Поскольку микроконтроллеры обычно не могут создавать отрицательные напряжения, для преобразования выходных сигналов ТТЛ микроконтроллера в уровни RS-232 обычно используется отдельная специальная микросхема. Протокол RS-232 намного проще, чем протокол USB, но, к сожалению, он, по большому счету, сильно устарел. Большинство современных микроконтроллеров оснащены встроенным преобразователем USB/TTL-Serial.

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

Преобразователи USB/Serial

Большинство современных электронных модулей, с которыми вам придется иметь дело, будут, скорей всего, оснащены каким-либо последовательным интерфейсом для взаимодействия с микроконтроллерами. Самым распространенным из таких интерфейсов является последовательный TTL-интерфейс — TTL-Serial. Например, большинство модулей системы GPS[5] (с одним из которых мы познакомимся в главе 8) оснащены интерфейсом TTL-Serial.  Для любого, кто интересуется созданием современных электронных устройств, преобразователь USB/TTL-Serial станет одним из самых необходимых инструментов.

На рынке доступен ряд микросхем преобразователя USB/Serial. Одной из наиболее популярных является микросхема FT232RL, изготавливаемая уже упомянутой ранее компанией FTDI. Но основе этой микросхемы компания делает кабель-переходник, другие компании также используют эту микросхему для изготовления плат-преобразователей. Кабель-переходник компании FTDI (см. рис. 2.4) приобрел такую популярность, что его распиновка (см. рис. 2.5) была принята в качестве де-факто стандарта на рынке любительской электроники  и используется во многих устройствах.

Кроме кабеля-преобразователя компании FTDI, преобразовательные платы изготавливают такие компании как Adafruit, SparkFun, Parallax и ряд других. Микросхемой FT232RL также оснащаются многие устройства, включая адаптеры XBee компании Digi и платы-клоны Arduino RedBoard компании SparkFun.

Эта микросхема удобна тем, что она может обрабатывать последовательные TTL-сигналы разных напряжений:  5 В и 3,3 В. Компания SparkFun изготавливает отдельные версии плат для каждого напряжения,  а у платы FTDI Friend компании Adafruit на тыльной стороне предусмотрен ряд перемычек, перепаивая которые можно менять рабочее напряжение контактов для приема и передачи последовательных сигналов. Кроме того, эта плата также способна работать с уровнями напряжения сигналов RS-232. Для работы с RS-232 предназначена  и адаптерная плата компании Parallax, оснащенная к тому же разъемом DB-9.

Использование адаптера USB/TTL-Serial не представляет собой ничего сложного. Контакт передачи (TX) этого адаптера подсоединяется к контакту приема (RX) устройства и наоборот. Общий («земляной») контакт платы подключается к соответствующему контакту устройства, а при питании устройства от адаптерной платы контакт питания VCC платы подключается к контакту питания устройства. Прежде чем запитывать устройство от адаптера, необходимо убедиться в том, что устройство может работать на уровне напряжения, подаваемого адаптером. Напряжение питания большинства адаптеров USB/TTL-Serial составляет 5 В, что может повредить устройства с питанием 3,3 В. В главе 1 мы узнали, как с помощью адаптера USB/TTL-Serial компании FTDI подключиться через монитор порта к плате Raspberry Pi (см. рис. 1.17). Но в том случае плата микроконтроллера не запитывалась от адаптерной платы.

Чтобы использовать с компьютером любой из адаптеров USB/Serial, на компьютер нужно установить драйверы микросхемы этого адаптера. Качество работы адаптера USB/TTL-Serial во многом зависит от качества его драйвера. Драйверы более дешевых адаптеров обычно совместимы с более узким диапазоном платформ. Поэтому имеет смысл немного переплатить, но приобрести устройство с доступными, качественными и многоплатформенными драйверами. В этом отношении особенно выделяется компания FTDI —драйверы от этой компании всегда вовремя обновляются для поддержки текущих версий Windows, macOS и различных дистрибутивов Linux.

Но кроме компании FTDI, адаптеры USB/TTL-Serial изготавливаются и другими компаниями —  например, компаниями Prolific (адаптер PL2303), Silicon Labs (адаптер CP2102), Jiangsu Heng Qin (адаптер CP340) и другими. Драйверы для упомянутых адаптерных плат этих компаний можно загрузить со следующих веб-сайтов:

  • ftdichip.com/FTDrivers.htm (FTDI);
  • silabs.com/products/mcu/Pages/USBtoUARTBridgeVCPDrivers.aspx (Silicon Labs);
  • prolific.com.tw/US/Show-Product.aspx?pcid=41 (Prolific);
  • wch.cn/download/CH341SER_ZIP.html (Jiangsu Heng Qin).

В плате Arduino Uno в качестве адаптера USB/TTL-Serial используется микроконтроллер общего назначения Atmel 16U2, запрограммированный под эту задачу. Для этого адаптера не требуются драйверы под macOS и Linux, а драйверы USB для Windows устанавливаются автоматически установщиком Windows. Исходный код адаптера USB/TTL-Serial для Arduino Uno можно загрузить из каталога hardware/arduino/avr/firmwares/atmegaxxu2 репозитория https://github.com/arduino, а дополнительную информацию о конструкциях устройств USB вы найдете на веб-сайте www.usb.org/developers/usbfaq.

При использовании адаптера USB/TTL-Serial для программирования микроконтроллера вам, вероятно, нужно будет также задействовать выводы CTS (clear-to-send, готовность к передаче) и RTS (request-to-send, запрос на передачу). Большинство микроконтроллеров, полагающихся на адаптеры USB/TTL-Serial, — такие, как адаптерная плата Huzzah! на микросхеме ESP8266 компании Adafruit или плата ESP8266 Thing компании SparkFun, оснащены контактами для этих выводов, так что вам не нужно беспокоиться об этом. Дополнительную информацию по использованию адаптеров USB/TTL-Serial для программирования микроконтроллеров ищите в руководстве по программированию вашей платы.

Использование платы Arduino в качестве адаптера USB/TTL-Serial

Если у вас нет под рукой отдельного адаптера USB/TTL-Serial, вместо него можно воспользоваться совместимой с Arduino платой, запрограммировав ее должным образом.

В частности, для этой цели подойдут платы MKR1000 или Arduino 101. Обе платы используют одинаковые процессоры, оснащенные встроенными средствами работы с USB, и последовательные порты этих плат, отображаемые в мониторе порта, подключены непосредственно к процессору. Для обращения к выводам TX (передача) и RX (прием) платы обычно используется объект Serial1. Далее приводится скетч для реализации этой задачи. В нем вывод передачи USB перенаправляется на вывод приема (RX) платы, а вывод приема USB — на вывод передачи (TX) платы. Таким образом, любая микроконтроллерная плата на микроконтроллере со встроенными средствами работы с USB превращается в адаптер USB/TTL-Serial.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
void setup() {
 
// инициализируем оба последовательные подключения:
Serial.begin(9600);  // USB
 
Serial1.begin(9600); // TTL
}
 
 
 
void loop() {
 
// считываем RX TTL, отправляем на USB:
 
if (Serial1.available()) {
 
char c = Serial1.read();
 
Serial.write(c);
 
}
 
 
 
// считываем USB, отправляем на TX TTL:
 
if (Serial.available()) {
 
char c = Serial.read();
 
Serial1.write(c);
 
}
 
}

Микроконтроллеры более старых плат — например, Arduino Uno, не имеют встроенных средств для работы с USB. Поэтому, чтобы позволить таким платам взаимодействовать с компьютером через порт USB, они оснащаются отдельной микросхемой адаптера USB/TTL-Serial. Выход передачи (TX) такого адаптера подсоединен к контакту приема (RX) микроконтроллера и наоборот. Это означает, что здесь можно обойти микроконтроллер и напрямую использовать плату Arduino в качестве адаптера USB/TTL-Serial. Для этого в микроконтроллер нужно загрузить скетч, который ничего не делает:

1
2
3
void setup() {}
 
void loop() {}

Затем подсоединить требуемое последовательное устройство следующим образом  (обратите внимание: на первый взгляд может казаться, что подключение должно выполняться наоборот):

  • контакт приема внешнего устройства — к контакту RX (0) платы Arduino;
  • контакт передачи внешнего устройства — к контакту TX (1) платы Arduino.

Теперь наше устройство может обмениваться данными напрямую с адаптером USB/TTL-Serial платы Arduino, обходя микроконтроллер. Когда же снова нужно будет использовать микроконтроллер, просто отсоедините устройство и загрузите требуемый скетч.

 

 

[1] TTL, Transistor-Transistor Logic — транзисторно-транзисторная логика (ТТЛ).

[2] USB, Universal Serial Bus (protocol) — протокол универсальной последовательной шины.

[3] TTY, Teletype Unit — телетайпное устройство.

[4] CU, Сalling Unit — вызывающее устройство.

[5] GPS, Global Positioning System — система глобального позиционирования.[/vc_column_text]

USB — неисчерпаемый источник последовательных портов

Одна из примечательных особенностей микроконтроллеров — их низкая стоимость, что позволяет не особенно ограничивать себя в их числе. Например, для проекта с большим числом датчиком можно или разработать сложную программу, чтобы один микроконтроллер мог выполнять опрос всех датчиков, или же дать каждому датчику свой собственный микроконтроллер. А если информацию с этих датчиков нужно передать в персональный компьютер, поначалу может показаться, что будет легче использовать для этого один микроконтроллер — по причине ограниченного количества последовательных портов. Однако благодаря шине USB количеством доступных последовательных портов можно не озабочиваться. Если микроконтроллер оснащен портом USB, его можно подсоединить к любому разъему USB компьютера, и он будет распознаваться операционной системой компьютера как еще один последовательный порт. А количество разъемов USB компьютера можно увеличить, подключив к одному из них USB-концентратор (хаб).

Например, если к компьютеру подсоединить три модуля Arduino через USB-хаб, в операционной системе появится три новых последовательных порта. На машинах под Mac OS они будут отображаться примерно так:

/dev/cu.usbmodem1441

/dev/cu.usbmodem1461

/dev/cu.usbmodem1471

В системах POSIX, включая macOS, порты часто указываются дважды: один раз как /dev/tty.usbmodemXX и еще раз как /dev/cu.usbmodemXX. Эта особенность является пережитком эпохи телефонных модемов: порты TTY[3] служили для коммутации входящих звонков, а CU[4] — для исходящих. Для устройств USB/TTL-Serial, которые применяются в этой книге, тип используемого порта не имеет существенной важности.

На машинах под Windows эти порты будут отображаться, например, так: COM8, COM9, COM10.

Большинство современных микроконтроллерных плат оснащены встроенным модулем преобразователя USB/TTL-Serial. Для тех плат, которые не имеют встроенного преобразователя, на рынке предлагаются отдельные модули ценой порядка $15–20. Один из наиболее популярных таких преобразователей с разъемом для макетных плат, который удобно использовать для подсоединения устройств, оснащенных последовательным интерфейсом технологии TTL, выпускает компания FTDI (Future Technology Devices International), сайт которой находится по адресу www.ftdichip.com. Этот преобразователь можно прибрести в разделе макетных плат и кабелей магазинов фирм Maker SHED, SparkFun, Adafruit и многих других. Доступен он в двух версиях: 5 В и 3,3 В — любую из них можно использовать для всех проектов этой книги. Кабель-переходник USB/TTL-Serial компании FTDI показан на рис. 2.4, а распиновка его разъема TTL — на рис. 2.5.

[/vc_column][/vc_row]
Опубликовано

Уровни согласования взаимодействия устройств

По материалам книги Т.Иго «Умные вещи: Arduino, датчики и сети для связи устройств: Пер. с англ. 3-е изд.»  (глава 2 «Простейшая сеть»)

Умные вещи: Arduino

Самая простая сеть — это соединение двух объектов один к одному. В этой главе подробно рассматривается двусторонняя связь, и начнем мы с характеристик, которые нужно оговорить прежде всего. Мы познакомимся с некоторыми логистическими элементами сетевой связи: протоколами данных, управлением потоками и адресацией. Эти теоретические понятия мы применим на практике, создав два устройства, реализующих примеры использования последовательной связи между микроконтроллером и персональным компьютером. Мы также рассмотрим модемную связь и узнаем, как заменить кабель, соединяющий микроконтроллер и компьютер, на приемопередатчики беспроводной связи Bluetooth. Наконец, мы научимся программировать микроконтроллеры низкого уровня с тем, чтобы распределять вычислительные потребности наших проектов между разными процессорами.

Уровни согласования

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

  • Физический. Каким образом вводы и выводы каждого устройства соединяются с другими? Сколько необходимо соединений между двумя устройствами для возможности обмена сообщениями?
  • Электрический. Какие уровни напряжения использовать для представления битов данных? 5 вольт? 3,3 В? Какое-либо другое напряжение?
  • Логический. Какую схему логики использовать — положительную или отрицательную? Схема, при которой высокий уровень напряжения представляет логическую 1, а низкий — логический 0, называется положительной, а когда значения уровней инвертированы: высокий уровень напряжения представляет логический 0, а низкий — логическую 1, — отрицательной.
  • Уровень данных. Как осуществляется синхронизация битов? Сколько битов считывается за раз: 8, 9, 10 или больше? Обозначаются ли группы битов в начале и в конце специальными битами?
  • Уровень приложений. Как организовываются группы битов для создания сообщений? Каков порядок обмена сообщениями для того, чтобы что-то сделать?

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

Какой бы сложной ни была бы сеть, никогда не забывайте о том, что связь между электронными устройствами — это всего лишь электрические импульсы. Устройства, осуществляющие обмен данными по последовательному каналу, соединены между собой электрически. Посылающее устройство изменяет уровень напряжения на соединяющей линии через согласованные интервалы времени, и каждый такой интервал представляет собой один бит данных. Чтобы отправить значение 0 или 1 очередного бита, отправитель меняет уровень напряжения, а получатель определяет уровень полученного сигнала: высокий он или низкий.

Отправитель и получатель могут согласовывать скорость отправки битов двумя способами (рис. 2.3). Скорость асинхронного последовательного обмена данными согласовывается между обеими сторонами обмена и синхронизируется (иногда говорят: тактируется) отправителем и получателем независимо друг от друга. А скорость синхронного последовательного обмена данными управляется отправителем, который подает постоянный сигнал синхронизации (тактирования) на отдельную линию (на рис. 2.3 показаны два интерфейса синхронного последовательного обмена: интерфейс SPI и интерфейс I2C). Синхронный последовательный обмен данными в основном применяется для связи между интегрированными схемами (например, между процессором компьютера и его микросхемами памяти). В этой главе рассматривается только асинхронный последовательный обмен данными, так как именно этот тип последовательной связи лежит в основе сетей, которым посвящена эта книга: от Ethernet-соединений по проводам до беспроводной радиосвязи.

Асинхронный обмен данными

Асинхронный обмен данными: каждое устройство использует свой  собственный генератор тактовых (синхронизирующих) сигналов, обмен данными осуществляется с заранее согласованной скоростью

Синхронный обмен данными (интерфейс SPI, Serial Peripheral Interface)

Синхронный обмен данными (интерфейс SPI, Serial Peripheral Interface): ведущее устройство подает  сигнал тактирования на ведомое устройство и инициирует обмен, подавая сигнал выбора схемы. Обмен данными происходит по смене уровня напряжения сигнала тактирования на обратное

Синхронный обмен данными (интерфейс I2C)

Синхронный обмен данными (интерфейс I2C): ведущее устройство подает сигнал тактирования на ведомое устройство, выбирая ведомое по его адресу. Обмен данными происходит по смене уровня напряжения сигнала тактирования на обратное

Рис. 2.3. Типы последовательной связи

Опубликовано

Введение в интерфейс SPI

По материалам книги Т.Иго «Умные вещи: Arduino, датчики и сети для связи устройств: Пер. с англ. 3-е изд.»  (глава 2 «Простейшая сеть»)

Умные вещи: Arduino

Для внутрисхемного программирования электронных устройств используется разновидность синхронного последовательного интерфейса, носящая название SPI[1]. Интерфейс SPI вместе с другим последовательным синхронным протоколом I2C[2] (который иногда также называется интерфейсом TWI[3]) — представляют собой два наиболее распространенных последовательных протокола, с которыми вам когда-либо придется иметь дело. Этот интерфейс используется для реализации обмена данными с устройствами разных видов — например, с адаптером Wi-Fi на плате MKR100 или с SD-картами памяти, а также с разного рода датчиками.

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

Интерфейс SPI реализуется тремя или четырьмя линиями между управляющим устройством (ведущим устройством, или мастером) и периферийным (ведомым) устройством:

  • сигнал тактирования(SCK) — вывод, на который ведущее устройство подает регулярные сигналы тактирования (синхронизации);
  • выход ведущего, вход ведомого (MOSI, Master Out, Slave In): по этой линии ведущее устройство на каждый импульс тактирования посылает данные ведомому устройству;
  • вход ведущего, выход ведомого (MISO, Master In, Slave Out): по этой линии ведомое устройство на каждый импульс тактирования посылает данные ведущему устройству. Если ведомому устройству нет надобности посылать данные ведущему, вывод MISO отсутствует;
  • выбор ведомого(SS, Slave Select) или выбор схемы (CS, Chip Select) — поскольку к шине может быть подключено несколько ведомых устройств, каждое из них имеет контакт CS для его выбора ведущим устройством. Чтобы выбрать определенное ведомое устройство, ведущее устройство устанавливает низкий уровень на этом контакте. Если на этом контакте установлен высокий уровень, устройство отключено от шины.

интерфейс SPI

Поскольку интерфейс SPI является стандартным способом программирования контроллеров AVR, большинство плат на этих контроллерах, включая Arduino Uno и более ранние модели, оснащены разъемом ICSP, на который выведены линии SPI. Этот разъем выглядит следующим образом:

разъем ICSP

Если ваша плата имеет разъем ICSP, вы можете быть уверены, что его распиновка будет такой, как показано на рисунке. Но функции SPI в разных микроконтроллерных платах выводятся на разные контакты. В следующей таблице дается информация о выводе функций SPI на контакты плат Arduino Uno, 101 и MKR1000:

Функция Uno 101 MKR1000
MOSI 11 или ICSP4 ICSP4 8
MISO 12 или ICSP1 ICSP1 10
CLK 13 или ICSP3 ICSP3 9
CS 10 10 по выбору пользователя

[1] SPI, Serial Peripheral Interface — последовательный интерфейс периферийных устройств.

[2] I2C, Inter-Integrated Circuit — шина данных для связи интегральных схем.

[3] TWI, Two-Wire Interface — двухпроводной интерфейс.