Arduino:Примеры/YunFirstConfig
Содержание | Знакомство с Arduino | Продукты | Основы | Справочник языка Arduino | Примеры | Библиотеки | Хакинг | Изменения | Сравнение языков Arduino и Processing |
Первая настройка Yun[1]
Этот пример показывает, как подключить устройство Yun к WiFi-сети, используя в качестве интерфейса монитор порта в IDE Arduino.
Загрузите скетч на Yun и откройте монитор порта. Он покажет доступные WiFi-сети, а затем спросит, какой из них вы хотите воспользоваться. Вам нужно будет ввести пароль для этой сети, а затем система попросит вас дать название устройству Yun и пароль к нему. Если соединение к выбранной сети будет выполнено успешно, вам придет подтверждающее сообщение, после чего устройству Yun будет присвоен IP-адрес.
Если вставить этот адрес с адресную строку браузера, откроется панель Yun, содержащая дополнительные настройки и опции.
Если что-то пойдет не так, процедуру можно перезапустить. Если нужной сети не окажется в списке доступных сетей, ее можно будет выбрать вручную, указав SSID и пароль.
Примечание: Для этого скетча требуется, чтобы на устройстве Yun стояла прошивка версии 1.6.2 или новее. Руководство по апгрейду можно прочесть тут, и убедитесь, что у вас стоит самая последняя версия.
Необходимое оборудование
- Плата или модуль Yun
- Беспроводная сеть, подключенная к интернету
Цепь
Для этого примера никакой цепи строить не нужно.
Наиболее важные части скетча
Библиотеки
- Библиотека Process.h, запускающая процессы (и прочие операции вроде shell-скриптов) на процессоре Linux. В данном случае она используется для получения списка точек доступа и выполнения других действий, позволяющих узнать параметры WiFi.
Функции
- Функция getUserInput(out, obfuscated), берущая данные, которые пользователь вводит через монитор порта, и снова показывающая их в мониторе порта. Переменная obfuscated (тип данных – boolean) используется для того, чтобы при введении пароля печатались звездочки («*»).
- Функция wifiConfig(yunName, yunPsw, wifissid, wifipsw, wifiAPname, countryCode, encryption), выполняющая при помощи библиотеки Process серию команд и скриптов (под Linux), которые настраивают WiFi и сетевые параметры, выбранные пользователем.
- Функция startSerialTerminal(), просто инициализирующая два последовательных порта, которые нужны для выполнения действий, требуемых для этого скетча.
- Функция loopSerialTerminal(), создающая соединение между двумя последовательными портами: один «общается» с PC при помощи USB, а другой – с процессором Linux. У нее есть командный режим, который можно вызвать нажатием на «~». Это выключает Bridge и позволяет выставить разные скорости соединения с чипом Atheros.
Использование
Этот скетч через монитор порта в IDE Arduino запрашивает у пользователя информацию для настройки сетевого соединения. Аппаратный последовательный порт (он находится на 0-ом и 1-ом контактах) уже используется устройством Yun для коммуникации с платой, поэтому данному скетчу для корректной работы потребуется второй последовательный порт. Также стоит подготовить SSID (название точки доступа) и пароль для доступа к WiFi-сети. Загрузите скетч, а затем откройте монитор порта, кликнув на увеличительную лупу в правом верхнем углу IDE Arduino. Вы увидите сообщение – такое же, как на картинке ниже:
Спустя какое-то время на модуле Yun Shield начнет мигать синий светодиод. Когда сканирование завершится, скетч покажет в мониторе порта список доступных точек доступа. Время, необходимое для сканирования, зависит от количества точек доступа и мощности их сигнала. Чтобы выбрать точку доступа, впишите ее номер в поле ввода. Не забудьте выбрать в выпадающем меню, находящемся в правом нижнем углу окна, пункт «NL» (он добавляет символ новой строки).
Выбор точки доступа запускает процесс подключения, после чего Yun «прощупает» сеть на предмет того, открытая она или защищенная. Если сеть защищена, вас попросят ввести пароль (или ключ). Для быстрого и безопасного соединения устройство Yun должно иметь название и быть защищено паролем. После этого ваше устройство готово выключить режим точки доступа и инициировать доступ к выбранной WiFi-сети. В конце этого процесса скетч покажет IP-адрес, полученный при помощи DHCP-сервера.
Если подключение не удастся, скетч сообщит об этом и предложит перезапустить процедуру при помощи сброса Yun.
Код
/*
Первая настройка Arduino Yún
При помощи Bridge настраивает WiFi и сетевые параметры на
Yún101/YunShield/Yún. Для корректной работы скетча Line Ending нужно
выставить на «NewLine». Если у вашей платы два USB-порта,
используйте штатный USB-порт.
Цепь:
Arduino Yún/Yún101/YunShield с прошивкой > 1.6.1
Создан в марте 2016 года Arduino LLC.
Этот код не защищен авторским правом.
http://www.arduino.cc/en/Tutorial/YunFirstConfig
*/
#include <Process.h>
#define MAX_WIFI_LIST 10
String networks[MAX_WIFI_LIST];
String yunName;
String yunPassword;
void setup() {
SERIAL_PORT_USBVIRTUAL.begin(9600); // инициализируем последовательную коммуникацию
while (!SERIAL_PORT_USBVIRTUAL); // ничего не делаем, пока не откроется последовательный монитор
SERIAL_PORT_USBVIRTUAL.println(F("Hi! Nice to see you!")); // "Привет! Рад видеть тебя!"
SERIAL_PORT_USBVIRTUAL.println(F("I'm your Yun101 assistant sketch")); // "Я – скетч-помощник для работы с Yun101"
SERIAL_PORT_USBVIRTUAL.println(F("I'll help you configuring your Yun in a matter of minutes")); // "Я помогу настроить твою Yun за несколько минут"
SERIAL_PORT_USBVIRTUAL.println(F("Let's start by communicating with the Linux processor")); // "Давай начнем с коммуникации с процессором Linux"
SERIAL_PORT_USBVIRTUAL.println(F("When LED (L13) will light up we'll be ready to go!")); // "Если загорелся 13-ый светодиод, значит, все готово!"
SERIAL_PORT_USBVIRTUAL.println(F("Waiting...")); // "Ждем..."
SERIAL_PORT_USBVIRTUAL.println(F("(in the meanwhile, if you are using the IDE's serial monitor, make sure that it's configured to send a \"Newline\")\n")); // "(если используешь монитор порта в IDE Arduino, убедись, что он настроен на отправку символа новой строки (NL)\n"
pinMode(13, OUTPUT);
digitalWrite(13, LOW);
Bridge.begin(); // начинаем контактировать с процессором Linux
digitalWrite(13, HIGH); // когда Bridge будет готова, включаем 13-ый светодиод
Process wifiList;
bool master = false;
wifiList.runShellCommand(F("iwinfo | grep \"Mode: Master\""));
while (wifiList.available() > 0) {
wifiList.read();
master = true;
}
// получаем список доступных сетей:
wifiList.runShellCommand(F("iwinfo wlan0 scan | grep ESSID | cut -d\"\\\"\" -f2"));
uint8_t num_networks = 0;
uint8_t i = 0;
char c;
bool dropNet = false;
networks[0].reserve(32);
while (wifiList.available() > 0) {
c = wifiList.read();
if (c != '\n') {
networks[i] += c;
} else {
// проверяем, нет ли в списке повторяющихся сетей, и если есть, удаляем их:
for (uint8_t s = 0; s < i; s++) {
if (networks[i].equals(networks[s])) {
dropNet = true;
}
}
if (i <= MAX_WIFI_LIST && dropNet == false) {
networks[i++].reserve(32);
} else {
dropNet = false;
networks[i]="";
}
}
}
num_networks = i;
String encryption;
String password;
int chose = 0;
// если сетей не найдено, запускаем ручную настройку:
if (num_networks == 0) {
SERIAL_PORT_USBVIRTUAL.println(F("Oops, it seems that you have no WiFi network available")); // "Упс! Похоже, доступных сетей нет"
SERIAL_PORT_USBVIRTUAL.println(F("Let's configure it manually")); // "Значит, запускаем ручную настройку"
SERIAL_PORT_USBVIRTUAL.println(F("SSID of the network you want to connect to: ")); // "SSID сети, к которой вы хотите подключиться: "
networks[0] = getUserInput(networks[0], false);
SERIAL_PORT_USBVIRTUAL.println(F("Password for the network you want to connect to: ")); // "Пароль для сети, к которой вы хотите подключиться: "
password = getUserInput(password, true);
SERIAL_PORT_USBVIRTUAL.print(F("Encryption (eg WPA, WPA2, WEP): ")); // "Шифрование (например, WPA, WPA2, WEP): "
encryption = getUserInput(encryption, false);
} else {
// если сети найдены, показываем их, но сначала показываем их количество:
SERIAL_PORT_USBVIRTUAL.print(F("It looks like you have ")); // "Итак, мы нашли "
SERIAL_PORT_USBVIRTUAL.print(num_networks);
SERIAL_PORT_USBVIRTUAL.println(F(" networks around you ")); // " сетей вокруг нас"
SERIAL_PORT_USBVIRTUAL.println(F("Which one do you want to connect to?\n")); // "К какой из них вы хотите подключиться?\n"
for (i = 0; i < num_networks && i < MAX_WIFI_LIST; i++) {
SERIAL_PORT_USBVIRTUAL.print(i);
SERIAL_PORT_USBVIRTUAL.println(") " + networks[i]);
}
String selection;
selection = getUserInput(selection, false);
chose = atoi(selection.c_str());
}
// извлекаем информацию о шифровании выбранной сети:
bool openNet = false;
wifiList.runShellCommand("iwinfo wlan0 scan | grep \"" + networks[chose] + "\" -A5 | grep Encryption | cut -f2 -d\":\"");
while (wifiList.available() > 0) {
c = wifiList.read();
encryption += c;
}
if (encryption.indexOf("none") >= 0) {
openNet = true;
encryption = "none";
}
if (encryption.indexOf("WPA2") >= 0) {
encryption = "psk2";
}
if (encryption.indexOf("WPA") >= 0) {
encryption = "psk";
}
if (encryption.indexOf("WEP") >= 0) {
encryption = "wep";
}
if (openNet == false && password.length() == 0) {
SERIAL_PORT_USBVIRTUAL.print(F("It looks like you need a password to connect to ")); // "Похоже, для подключения нужен пароль: "
SERIAL_PORT_USBVIRTUAL.println(networks[chose]);
SERIAL_PORT_USBVIRTUAL.print(F("Write it here: ")); // "Пишем его здесь: "
password = getUserInput(password, true);
}
// меняем пароль для устройства Yun:
SERIAL_PORT_USBVIRTUAL.println(F("We are almost done! Give a name and a password to your Yun")); // "Почти готово! Впишите название и пароль для Yun"
SERIAL_PORT_USBVIRTUAL.print(F("Name: ")); // "Название: "
yunName = getUserInput(yunName, false);
SERIAL_PORT_USBVIRTUAL.print(F("Password: ")); // "Пароль: "
yunPassword = getUserInput(yunPassword, true);
// выбираем код страны:
String countryCode;
SERIAL_PORT_USBVIRTUAL.println(F("One last question: where do you live?")); // "Последний вопрос: где вы живете?"
SERIAL_PORT_USBVIRTUAL.print(F("Insert a two letters county code (eg IT, US, DE): ")); // "Впишите две буквы для кода страны (например, RU, BY, UA и т.д.): "
countryCode = getUserInput(countryCode, false);
yunName.trim();
yunPassword.trim();
networks[chose].trim();
password.trim();
countryCode.trim();
// настраиваем Yun при помощи данных, введенных пользователем:
wifiConfig(yunName, yunPassword, networks[chose], password, "YUN" + yunName + "AP", countryCode,encryption);
SERIAL_PORT_USBVIRTUAL.print(F("Waiting for the Yun to connect to the network")); // "Ждем, пока Yun подключится к сети"
}
bool Connected = false;
bool serialTerminalMode = false;
int runs = 0;
void loop() {
if (!serialTerminalMode) {
String resultStr = "";
if (!Connected) {
SERIAL_PORT_USBVIRTUAL.print(".");
runs++;
}
// если подключение занимает более 20 секунд, останавливаем попытки подключения:
if (runs > 20) {
SERIAL_PORT_USBVIRTUAL.println("");
SERIAL_PORT_USBVIRTUAL.println(F("We couldn't connect to the network.")); // "Подключиться к сети не удалось."
SERIAL_PORT_USBVIRTUAL.println(F("Restart the board if you want to execute the wizard again")); // "Если вы вновь хотите запустить мастер настройки, перезапустите плату"
resultStr = getUserInput(resultStr, false);
}
// проверяем, есть ли IP-адрес:
Process wifiCheck;
wifiCheck.runShellCommand(F("/usr/bin/pretty-wifi-info.lua | grep \"IP address\" | cut -f2 -d\":\" | cut -f1 -d\"/\"" )); // команда, которую вы хотите запустить
while (wifiCheck.available() > 0) {
char c = wifiCheck.read();
resultStr += c;
}
delay(1000);
if (resultStr != "") {
// IP-адрес получен, значит, останавливаем блок loop(),
// показываем значение и запускаем терминал:
Connected = true;
resultStr.trim();
SERIAL_PORT_USBVIRTUAL.println("");
SERIAL_PORT_USBVIRTUAL.print(F("\nGreat! You can now reach your Yun from a browser typing http://")); // "\nОтлично! Теперь вы можете получить доступ к Yun из браузера, вписав туда http://"
SERIAL_PORT_USBVIRTUAL.println(resultStr);
SERIAL_PORT_USBVIRTUAL.print(F("Press 'Enter' key twice to start a serial terminal")); // "Дважды нажмите Enter, чтобы запустить терминал в мониторе порта"
resultStr = getUserInput(resultStr, false);
serialTerminalMode = true;
//startSerialTerminal();
SERIAL_PORT_HARDWARE.write((uint8_t *)"\xff\0\0\x05XXXXX\x7f\xf9", 11); // отсылаем команду выключения Bridge
delay(100);
SERIAL_PORT_HARDWARE.println("\nreset\n\n");
SERIAL_PORT_HARDWARE.flush();
SERIAL_PORT_HARDWARE.println("\nreset\n\n");
SERIAL_PORT_HARDWARE.write((uint8_t *)"\n", 1);
}
} else {
loopSerialTerminal();
}
}
String getUserInput(String out, bool obfuscated) {
/*
while (SerialUSB.available() <= 0) {}
while (SerialUSB.available() > 0) {
char c = SerialUSB.read();
out += c;
}
return out;
*/
while (SERIAL_PORT_USBVIRTUAL.available() <= 0) {}
while (1) {
char c = SERIAL_PORT_USBVIRTUAL.read();
if (c == '\n' || c == '\r')
break;
else {
if (c != -1) {
out += c;
if (obfuscated)
SERIAL_PORT_USBVIRTUAL.print("*");
else
SERIAL_PORT_USBVIRTUAL.print(c);
}
}
}
SERIAL_PORT_USBVIRTUAL.println("");
return out;
}
void wifiConfig(String yunName, String yunPsw, String wifissid, String wifipsw, String wifiAPname, String countryCode, String encryption) {
Process p;
p.runShellCommand("blink-start 100"); // запускаем мигание синим светодиодом
p.runShellCommand("hostname " + yunName); // меняем текущее имя хоста
p.runShellCommand("uci set system.@system[0].hostname='" + yunName + "'"); // меняем имя хоста в UCI
p.runShellCommand("uci set arduino.@arduino[0].access_point_wifi_name='" + wifiAPname + "'");
// этот блок сбрасывает пароль для WiFi:
p.runShellCommand("uci set wireless.@wifi-iface[0].encryption='" + encryption + "'");
p.runShellCommand("uci set wireless.@wifi-iface[0].mode='sta'\n");
p.runShellCommand("uci set wireless.@wifi-iface[0].ssid='" + wifissid + "'");
p.runShellCommand("uci set wireless.@wifi-iface[0].key='" + wifipsw + "'");
p.runShellCommand("uci set wireless.radio0.channel='auto'");
p.runShellCommand("uci set wireless.radio0.country='" + countryCode + "'");
p.runShellCommand("uci delete network.lan.ipaddr");
p.runShellCommand("uci delete network.lan.netmask");
p.runShellCommand("uci set network.lan.proto='dhcp'");
p.runShellCommand("echo -e \"" + yunPsw + "\n" + yunPsw + "\" | passwd root"); // меняем пароли
p.runShellCommand("uci commit"); // сохраняем режимы, настроенные через UCI
p.runShellCommand("blink-stop"); // запускаем мигание синего светодиода
p.runShellCommand("wifi ");
}
long linuxBaud = 250000;
void startSerialTerminal() {
SERIAL_PORT_USBVIRTUAL.begin(115200); // открываем последовательную коммуникацию USB-Serial
SERIAL_PORT_HARDWARE.begin(linuxBaud); // открываем последовательную коммуникацию к Linux
}
boolean commandMode = false;
void loopSerialTerminal() {
// копируем из USB-CDC в UART
int c = SERIAL_PORT_USBVIRTUAL.read(); // считываем из USB-CDC
if (c != -1) { // есть что-то?
if (commandMode == false) { // если мы не в командном режиме...
if (c == '~') { // Нажата клавиша '~'?
commandMode = true; // входим в командный режим
} else {
SERIAL_PORT_HARDWARE.write(c); // в противном случае записываем символ в UART
}
} else { // если мы в командном режиме...
if (c == '0') { // нажата клавиша '0'?
SERIAL_PORT_HARDWARE.begin(57600); // задаем скорость на 57600
SERIAL_PORT_USBVIRTUAL.println("Speed set to 57600"); // "Выставляем скорость на 57600"
} else if (c == '1') { // нажата ли клавиша '1'?
SERIAL_PORT_HARDWARE.begin(115200); // задаем скорость на 115200
SERIAL_PORT_USBVIRTUAL.println("Speed set to 115200"); // "Выставляем скорость на 115200"
} else if (c == '2') { // нажата ли клавиша '2'?
SERIAL_PORT_HARDWARE.begin(250000); // задаем скорость на 250000
SERIAL_PORT_USBVIRTUAL.println("Speed set to 250000"); // "Выставляем скорость на 250000"
} else if (c == '3') { // нажата ли клавиша '3'?
SERIAL_PORT_HARDWARE.begin(500000); // задаем скорость на 500000
SERIAL_PORT_USBVIRTUAL.println("Speed set to 500000"); // "Выставляем скорость на 500000"
} else if (c == '~') { // нажата ли клавиша '~'?
SERIAL_PORT_HARDWARE.write((uint8_t *)"\xff\0\0\x05XXXXX\x7f\xf9", 11); // отправляем команду выключения Bridge
SERIAL_PORT_USBVIRTUAL.println("Sending bridge's shutdown command"); // "Отправляем команду выключения Bridge"
} else { // нажата ли какая-либо клавиша?
SERIAL_PORT_HARDWARE.write('~'); // записываем '~' на UART
SERIAL_PORT_HARDWARE.write(c); // записываем символ на UART
}
commandMode = false; // во всех случаях выходим из командного режима
}
}
// копируем из UART в USB-CDC:
c = SERIAL_PORT_HARDWARE.read(); // считываем из UART
if (c != -1) { // получили что-нибудь?
SERIAL_PORT_USBVIRTUAL.write(c); // записываем на USB-CDC
}
}
См.также
Внешние ссылки
Arduino продукты | |
---|---|
Начальный уровень | Arduino Uno • Arduino Leonardo • Arduino 101 • Arduino Robot • Arduino Esplora • Arduino Micro • Arduino Nano • Arduino Mini • Arduino Starter Kit • Arduino Basic Kit • MKR2UNO • TFT-дисплей Arduino |
Продвинутые функции | Arduino Mega 2560 • Arduino Zero • Arduino Due • Arduino Mega ADK • Arduino Pro • Arduino Motor Shield • Arduino USB Host Shield • Arduino Proto Shield • MKR Proto Shield • MKR Proto Large Shield • Arduino ISP • Arduino USB 2 Serial Micro • Arduino Mini USB Serial Adapter |
Интернет вещей | Arduino Yun • Arduino Ethernet • Arduino MKR1000 • Arduino WiFi 101 Shield • Arduino GSM Shield V2 • Arduino WiFi Shield • Arduino Wireless SD Shield • Arduino Wireless Proto Shield • Arduino Ethernet Shield V2 • Arduino Yun Shield • Arduino MKR1000 Bundle |
Носимые устройства | Arduino Gemma • Lilypad Arduino Simple • Lilypad Arduino Main Board • Lilypad Arduino USB • LilyPad Arduino SimpleSnap |
3D-печать | Arduino Materia 101 |
Устаревшие устройства | - |
Примеры Arduino | |
---|---|
Стандартные функции | |
Основы |
|
Цифровой сигнал |
|
Аналоговый сигнал |
|
Связь |
|
Управляющие структуры |
|
Датчики |
|
Дисплей |
Примеры, объясняющие основы управления дисплеем:
|
Строки |
|
USB (для Leonardo, Micro и Due плат) |
В этой секции имеют место примеры, которые демонстрируют использование библиотек, уникальных для плат Leonardo, Micro и Due.
|
Клавиатура |
|
Мышь |
|
Разное |
- Страницы, использующие повторяющиеся аргументы в вызовах шаблонов
- Справочник языка Arduino
- Arduino
- Перевод от Сubewriter
- Проверка:myagkij
- Оформление:myagkij
- Редактирование:myagkij
- Страницы, где используется шаблон "Навигационная таблица/Телепорт"
- Страницы с телепортом
- Пример
- Примеры
- Пример программирования Arduino
- Примеры программирования Arduino