Підключення arduino до телефону. Складання макетної плати реле. WeMos на базі esp8266

У цій статті інформація про те, як зібрати свій танк, оснащений Web Камероюта керований за допомогою Wifi роутера.

Необхідні матеріали:

  1. Web Camera
  2. Роутер TP-Link TL-MR3020
  3. Сервоприводи SG90 - 2шт
  4. Camera Platform Anti-Vibration
  5. Акумулятор 7.2V 5000mah
  6. Акумулятор 5V 2000mah
  7. Nano 3.0 Atmel ATmega328
  8. L298N motor driver
  9. Провід, термотрубки, USB хаб, діоди та інше.
  10. Платформа на ваш смак, я вибрав DD1-1

Складання нашого монстра
Налаштування Роутера MR3020.
Насамперед почнемо з роутера. Я довго думав, що вибрати OR-WRT або CyberWRT. OR-WRT є гнучким у налаштуваннях, але все редагування та внесення своїх налаштувань здійснюється через термінал за допомогою програми Putty. А так як Я боявся на той момент працювати через термінал, Я вибрав де є графічний інтерфейсце CyberWRT, плюс можливе підключення через порт USB.
Для того щоб змінити прошивку нашого роутера, потрібно завантажити прошивку CyberWrt MR3020.

Як ми завантажили, робимо таке:

1) Увімкнути роутер і зачекати на завантаження.
2) Зайти та залогінитися на 192.168.0.254 (за замовчуванням admin\admin)
3) Знайти в меню зліва System Tools, там пункт System Upgrade та залити прошивку через веб-форму
4) Дочекатися перезавантаження (близько 4х хвилин)
Роутер готовий до налаштування.

Можна вибрати один із режимів:«Точка доступу» та «Клієнт Wi-Fi мережі». Для налаштування режиму Клієнта:
- виберіть режим "Клієнт Wi-Fi мережі"
- IP-адреса Вашого пристрою (за цією адресою буде доступний Ваш пристрій. Постарайтеся вибрати незайнятий IP. Наприклад: 192.168.1.100)
- Маска підмережі (255.255.255.0)
- Шлюз (наприклад, IP Вашого домашнього роутераабо шлюзу - 192.168.1.1)
- Тип шифрування (тип шифрування, який використовується у Вашій домашньої мережі)
- Пароль (пароль, для доступу до Вашої домашньої мережі)

Якщо все зробили правильно, то у вас піде RSS рядок в нижній частині екрана.

Коли все запрацювала, у вас з'являться розділ модулі, там ви знаходите модуль "РОБОТ". Встановлюйте. Готово.

Підключення L298N, Arduino Nano, MR3020, Камера та інше

На картинці все показано, але про всяк випадок напишу.

Висновок Arduino DIGITAL 4 – до IN1 піну модуля.
Висновок Arduino DIGITAL 5 – до IN2 піну модуля.
Висновок Arduino DIGITAL 6 – до IN3 піну модуля.
Висновок Arduino DIGITAL 7 – до IN4 піну модуля.
Висновок Arduino GND – до GND клемі модуля.
GND клема модуля - мінус акумулятора.
7.2V клема модуля - Плюс акумулятора.
RM клема модуля - Правий моторчик.
LM клема модуля - Лівий моторчик.
USB порт Arduino - Підключаємо до USB хаб
Web Камера - Підключаємо до USB хаб
USB хаб - Підключаємо до USB роутера

Харчування так, скажімо, логістики, здійснюється другим акумулятором. Місткість 2000 mA/h 5v, щоб не спалити роутер. Та й із двома акумуляторами робот стабільніше працює. Так ось, його ми підключаємо просто до роз'єму мікро USB. Через USB хаб який підключений до роутету живлення вже отримує камера і наша ардуїнка.

Скетч для Arduino Nano
Вам необхідно завантажити бібліотеку CyberLib, вона призначена тільки для Atmega 328.

/* Версія 1.5 WIFI Tanka на DD1-1 Реалізовано: 1) Рух камери по X та Y 2) Гудок 3) Фари 4) Звук при включенні */ #include // Підключаємо бібліотеку #include // Підключаємо бібліотеку сервоприводів Servo myservo1; Servo myservo2; long previousMillis; // Потрібно для таймера int LedStep = 0; // Лічильник LED int i; #define robot_go (D4_High; D5_Low; D6_Low; D7_High;) #define robot_back (D4_Low; D5_High; D6_High; D7_Low;) #define robot_stop (D4_Low; D5_Low; D6_Low; D6_Low; D6_Low; 5_Low;D6_High;D7_Low ;) #define robot_rotation_left (D4_Low; D5_High; D6_Low; D7_High;) #define LED_ON (D13_High;) #define LED_OFF (D13_Low;) #define Headlamp_ON (D8_Low;) #define 1 , 494, 500);) #define init (D4_Out; D5_Out; D6_Out; D7_Out; D8_Out; D13_Out;) uint8_t inByte; void setup() ( myservo1.attach(9); // Підключення сервоприводів до порту myservo2.attach(10); // Підключення сервоприводів до порту D11_Out; D11_Low; // Динамік Headlamp_OFF; // Фари викл за замовчуванням for(uint8_t i = 0;<12; i++) beep(80, random(100, 2000)); //звуковое оповещение готовности робота init; // Инициализация портов //Buzzer; // Инициализация портов динамика UART_Init(57600);// Инициализация порта для связи с роутером wdt_enable (WDTO_500MS); } void loop() { unsigned long currentMillis = millis(); // Обновление таймера if (LedStep == 0 && currentMillis - previousMillis >500)( // Затримка 0,5 сек. previousMillis = currentMillis; // оновлення таймер LED_ON; // Включити LedStep = 1; // Лічильник кроків ) if (LedStep == 1 && currentMillis - previousMillis > 500)( // Затримка 0,5 секунди previousMillis = currentMillis; // оновлення таймер LED_OFF; // Вимкнути LedStep = 2; = 0; // Лічильник кроків ) if (UART_ReadByte(inByte)) //Якщо щось прийшло ( switch (inByte) // Дивимося яка команда прийшла ( case "x": // Зупинка робота robot_stop; break; case "W" // Рух вперед robot_go; break; case "D": // Повопорт вліво robot_rotation_left; break; case "A": // Поворот вправо robot_rotation_right; break; case "S": // Рух назад robot_back; break; case " U": // Серво піднімається myservo1.write(i -= 20); break; case "J": // Серво опускається myservo1.write(i += 20); break; case "H": // Серво повертається вліво myservo2.write(i += 20); break; case "K": // Серво повертається праворуч myservo2.write(i -= 20); break; case "Y": // Серво повертається 85 myservo1.write(85); myservo2.write(85); break; case "F": // Включити фари Headlamp_ON; break; case "V": // Вимкнути фари Headlamp_OFF; break; case "I" // Гудок Buzzer; break; ) ) wdt_reset(); )

Внесення змін до роутера
Для того, щоб керувати камерами були внесені зміни до бібліотеки роутера. Вам потрібно буде завантажити змінений код та замінити вихідні файлиним.

Як і багато інших саморобкіни, я регулярно використовую мікроконтролери AVR для будь-яких різних аматорських виробів. А завдяки концепції «Arduino» ці вироби тепер набувають ще й елегантний вигляд. Справді, за якісь 300-400 рублів ми отримуємо мініатюрну багатошарову платуз маскою, шовкографією та з повністю розведеною на ній периферією для мікроконтролера (причому в SMD виконанні!). Я вже не кажу про всілякі модулі цієї ж «Arduino» серії: датчики, контролери, дисплеї і цілі набори, так потрібної нам додаткової периферії. І знову ж таки також недорогих і в прекрасному виконанні. Практично вже немає необхідності щось розводити і допаювати на «колінці».

Але всі ці різноманітні аматорські вироби вимагають природно, попереднього програмування.Та й надалі при різних удосконаленнях, постійно доводиться ці вироби перепрошувати. Зрозуміло, що зручніше робити це дистанційно, ніж постійно тягати їх до звичайного програматора. Взагалі, завдяки тій же платформі Arduino, варіантів і тут багато: Bluetooth, ZigBee, радіоканал з вашим особистим протоколом, IR, і навіть Wi-Fi. Всі вони дозволяють налагодити бездротовий контакт із вашим мікроконтролером. Але ж ми зупинимося на останньому варіанті. Основних причин тут чотири:

1: сучасно, інтернет речей!

2: бездротовий роутерє в кожній квартирі, реєструй у домашній мережі свої пристрої та вуаля!

3: ваші вироби здійснюють революційний стрибок у своєму розвитку; мало того, що їх можна програмувати на відстані, вони тепер ще й самі можуть спілкуватися з навколишнім світом: електронний годинниксамостійно беруть точний часз вартових NTP-серверів, виконавчі пристроїуправляються з іншого кінця міста або країни, що реєструють аксесуари зберігають накопичені дані в хмару і т.д. і т.п.

4: є чудова серія мікросхем ESP8266, на якій не дуже легко все це реалізувати.

Далі, у цій статті на прикладі механічної рукина сервоприводах - буде розібрано та продемонстровано віддалене програмування та обмін даними з ПК (або будь-чого) з пристроями на базі AVR мікроконтролерів. Відразу хочу зазначити, що всі програми наведені надалі є чисто демонстраційними і жодної комерційної цінності не мають. Тому претензії, на кшталт, чому програматор такий кастрований і мало функціональний чи чому ні додаткових сервісівякі є скрізь, не приймаються. Оскільки коди відкриті, будь-який бажаючий може допиляти їх на свій розсуд, мені ж для роботи поки вистачає і таких.

Передбачається, що читач вже знайомий і з Arduino модулями (шилдами) і з підключенням і прошивкою ESP8266. Насправді в Мережі викладено величезну кількість матеріалів, які роз'яснюють ази роботи з цими девайсами і мені не хотілося б тут повторюватися. Для новачків наприкінці статті є список корисних посиланьз цих питань, де можна знайти купу інформації, чому все це у вас не працює. За своїм досвідом колишнього інженера електронника можу відповідально заявити, що 99% неполадок зводиться до наступного:

1. Погані контакти. Оскільки "Arduino" шилди, мають на увазі комутацію з один одним через дроти виду "тато-мама", а не через пайку, то дуже часто щось, де-небудь, та відходить. Перевіряйте. Та й взагалі, як кажуть, електроніка це наука про контакти.

2. Проблеми із харчуванням. Не подавайте 5 вольт живлення туди, де потрібно 3.3. Іноді з ESP8266 від цього йде дим. Хоча з іншого боку, логічні сигнали від п'ятивольтових пристроїв вона перетравлює без проблем.

3. Проблеми із достатньою потужністю харчування. ESP8266 має підлу натуру і іноді може споживати майже триста міліампер, хоча до цього могла задовольнятися і тридцятьма. Відповідно кволий стабілізатор 3.3 вольт плати «Arduino», до якого ви анітрохи не сумніваєтеся, її підключили, відразу просідає до мікроскопічних значень. А ви не можете зрозуміти, чому воно, то працює, то ні.

4. Плутанина з висновками. Завжди перевіряйте, які сигнали куди йдуть. Приймач RXD повинен з'єднуватися з передавачем TXD, як і TXD з RXD, але MOSI має з'єднуватися з MOSI, а MISO з MISO тощо.

5. Не розраховуйте на внутрішньосхемні резистори, що підтягують, в ESP8266, завжди підтягуйте висновки до нуля або живлення, через 5-10 кілоомні зовнішні резистори, а не просто перемичкою. Інакше можете у найкращому випадкуотримати небачений досі струм споживання, а потім нюхати неприємний запах горілого пластику.

6. Косяки програмного забезпечення. Оскільки ПЗ для індивідуальних користувачів пишеться такими ж ентузіастами, то періодично вилазять глюки самих прошивок і баги при оновленні версій цих прошивок. Лікується повзанням за відповідними форумами, іноді навіть англомовними. Деякі товариші навіть стверджували, що і сама мікросхема ESP сира як погода в Пітері, але з іншого боку існує також думка, що з 2014 року (року її першого випуску) ситуація з цим кардинально покращилася (на відміну від погоди).

7. Загадкові глюки. Це рідкісне, але знервоване явище. У мене, наприклад, не шилося віддалено один «Arduino» пристрій. Точніше шилося але з помилками. Але шилося без помилок, якщо на ньому висів шлейф від програматора (але без самого програматора). "АГА", сказав я собі і припаяв конденсатор 15 пФ, між виведенням передачі даних та виведенням синхронізації. Все запрацювало. Та день убив.

Отже, давайте почнемо з найпростішого. У нас є механічна кінцівка MechArm (але не така яку зібрав Говард Воловітс) зроблена в Китаї та персональний комп'ютерз Windows. Завдання - віддалена прошивка програми та керування її з комп'ютера.


Для управляючого контролера візьмемо симпатичну мініатюрну хустку Arduino Nano з каменем ATmega328P. Ця плата чудово впихається всередину механічної руки.


Тепер визначимося яким чином ми її програмуватимемо. Існують три основні способи найбільш підходящих для віддаленої прошивки: через інтерфейс SPI, через вбудований завантажувач через порт JTAG.

Найпростіший варіант, це, звичайно, вбудований завантажувач (бутлоадер). Це заздалегідь прописана в FLASH пам'ять, програма, яка за певним протоколом отримує код, (припустимо за найпростішим UART) і спеціальними командами записує його в місце розташування програми, що завантажується. Так працює, наприклад, сам завантажувач ARDUINO IDE. Після скидання або старту, завантажувач чекає певний час дані на прийом і якщо не чекає починає виконання програми з нульової адреси. Якщо дані надходять, він пише їх у програмну секцію. Після наступного скиданнязавантажена програма починає виконуватись. У деталях, можливо, я неточно описав, але суть саме така. У результаті нам потрібно лише три висновки для програмування: приймач RTD, скидання RESETта земля GND. Взагалі, використовується ще й передавач TRD для верифікації записаної програми, але для простих демонстраційних додатків (не для атомної електростанції), перевірку можна опустити.

Сам завантажувач пишеться мовою асемблера, є приклади простих завантажувачівв датасітах на AVR. Можна розкопати існуючий вже завантажувач, якщо він у відкритому доступіі просто використовувати його в готовому виглядіякщо відомий протокол за яким він працює. Єдиний нюанс, що для цього потрібно налаштувати AVR спеціальний режим, шляхом прошивки спеціальних фьюз-бітів, що робиться звичайним програматором, а потім їм же зашити сам завантажувач на згадку про мікроконтролера (тобто без програматора один раз все одно не обійтися).

Другий варіант, це програмування по послідовному інтерфейсу SPI. Тут вже внутрішнього завантажувача немає, а програмуємо ми, посилаючи спеціальні командиі потім дані, за вищезгаданим інтерфейсом. Тут у нас завантажувач вже зовнішній, але його все одно треба писати. При передачі використовуються на додаток до RESET і GND вже чотири додаткових висновків MOSI, MISO – дані, SLK синхронізація, СS – вибір кристала. Але взагалі також можна прибрати MISO та СS. Дані тільки прийматимуться (верифікації програми тоді не буде), а кристал у нас і так лише один.

Кожен підхід має свої плюси та мінуси (а JTAG я взагалі не розглядав, оскільки життя людське коротке). Але в результаті я схилився до SPI, оскільки на асемблері писати було ліньки, а відкритих готових завантажувачів я не знайшов (просто добре не шукав).

Для побудови бездротового каналуя, як уже говорилося, вибрав дуже широко відому в даний час мікросхему ESP8266 - мікроконтролер, а точніше цілий SoC (System-on-Chip) китайського виробника Espressif з інтерфейсом Wi-Fi. Крім Wi-Fi він відрізняється можливістю виконувати програми із зовнішньої флеш-пам'яті. А саме для власного проекту я взяв ESP8266-07 з 512 Кб пам'яті на борту.


Взагалі годиться будь-яка ESP8266, де є зайві ноги для реалізації SPI. Тому найпростіша ESP8266-01 нам не підійде, тому що у неї розведено зовсім мало ніжок для портів вводу-виводу. Але з іншого боку різниця в ціні на них менше ста карбованців, а доступні вони однаково. Ну і великі налагоджувальні плати з ESP, де для зручності розведена купа периферії, нам теж не годяться, тому що не влазять, туди куди ми їх хочемо впхнути в нашу механічну руку.

Глобальна суть ідеї загалом була такою. З комп'ютера на ESP без проводів по WI-FI (в рамках вашої домашньої мережі) передається тіло програми, що завантажується в мікроконтролер. А ESP вже по проводах з використанням інтерфейсу SPI записує цю програму безпосередньо у FLASH пам'ять мікроконтролера. Потім природно скидає його та дає можливість завантаженій програмі виконуватись. Крім того в ESP має бути незалежний блок, який управляє ще й обміном даними з мікроконтролером, тому що ми хочемо не тільки програмувати, а й обмінюватися з ним даними. Зокрема, для проекту з MechArm, після запису програми, ми ще передаємо сигнали керування сервоприводами, щоб привести цю руку в рух. Тому на самій ESP нам бажано підняти TCP сервер для передачі програми та UDP сервердля керування MechArm. Відповідно ці сервери приєднуються до домашньої мережі та уважно слухають, чи немає там охочих завантажити новий кодв MechaArm або помахати комусь нею.

Так, я знайшов у Мережі, що прошивки вже дозволяють виробляти програмування AVRповітрям, але там Головна проблемау тому, що для чого іншого цю прошивку використати вже не можна. А нам хотілося б після програмування та спілкуватися з AVR також віддалено.

Яке програмне забезпечення ми будемо використовувати:

Для ПК, я писав все на JAVA, середу IntelliJ IDEA. Але в принципі, можна на будь-чому, нам там головне написати клієнт, який буде відправляти програму для прошивки AVR на ESP8266.

Самі програми для AVR я пишу в ATMEL STUDIO, мовою С, рідко на асемблері. Скетчі Arduinoне використовую принципово, практично будь-яка потрібна бібліотекапишеться за годину інший, причому з повним розумінням її роботи. Я пробував скетчі, але поки що у вас немає на AVR операційної системи, Скетчі так і відбиратимуть у друга периферію і регулярно глючити. Та сама IDE Arduinoв порівнянні з ATMEL STUDIO, звичайно, річ дуже примітивна. Але тут питання, звичайно, спірне, гуманітаріям та школярам веселіше і простіше буде, напевно, зі скетчами.

Для програмування ESP8266 я використав прошивку NodeMCU, А програми писав мовою Lua. Ні, я б із задоволенням писав би на Java і на С, але їх на ESP немає. Luа мова у застосуванні до нашого завдання не складний, освоїти його пара дрібниць. А для завантаження програм та їх налагодження на ESP, я взяв IDE ESPlorer . Вітчизняний безкоштовний продукт(але можете зробити автору donation), який звичайно не порівняти з середами згаданими вище, але як то кажуть дарованому коневі… Але щоб користуватися ESPlorer і писати на LUA, нам спочатку необхідно змінити в мікросхемі ESP8266 базову прошивку(що поставляється від виробника) на нову. У цьому підприємстві допоможе програма NODE MCU PyFlasher. У сенсі допоможе її перепрошити. А саму прошивку ми самі створимо і отримаємо в руки на сайті творців: NodeMCU. А детальніше про цей процес ви можете прочитати

Все дуже доступно та зрозуміло. До базових бібліотек додаємо підтримку SPI та бітові операції (у LUA у нашому випадку бітові операції перевантажені і від них мало користі). Багато в прошивку бібліотек пхати не слід, тому що через наявність різноманітного софту на ESP8266 залишається зовсім мало пам'яті, якісь жалюгідні 20 кБ.

Звичайно, ви можете просто взяти готову прошивку, яких багато вже бовтається в Інтернеті, але не рекомендую. Хоча б тому, що на деяких немає підтримки бітових операцій (а вони нам потрібні) і немає регулювання швидкості передачі даних SPI.
Відповідно, вони передаються за умовчанням зі швидкістю 40 МГц поділені на якийсь невеликий коефіцієнт і тому AVR їх перетравлювати не встигає.

Кому ліньки створювати прошивку можете завантажити мою з хмари.

Тепер у нас є прошивка і нам треба завантажити її в ESP8266 замість базової. Для цього нам знадобиться найпростіший адаптер USB- UART.


Приєднуємо ніжки TXD до RXD, а RXD до TXD, робимо спільну землю, але не використовуємо, як здавалося, зручний виведення живлення 3.3 на адаптері. Найчастіше ESP8266 просадить його геть-чисто. Тому запитуємо її окремо. Потім переводимо ESP в режим програмування (GP0 на землю, якщо хтось забув) і запускаємо NODE MCU PyFlasher.

Головне, не забудьте стерти флеш-пам'ять (yes, wipes all data), інакше залежно від версії прошивки після програмування може залишитися непотрібне сміття, який у свою чергу сипатиме сміття в консоль при подальшій роботі. До цього я використовував софт, де не було опції стерти заздалегідь пам'ять, мучився страшно, тому що нічого не працювало. А скринька просто відкривалася, тільки правда на англомовному форумі творців NODE MCU.

Займівши ж потрібну прошивкуми тепер можемо писати та налагоджувати програми мовою LUA (там ще MicroPython, але я ним не користувався) використовуючи при цьому дуже зручні API від NODE MCU. Запускаємо вже згаданий раніше ESPlorer.

Також налаштовуємо його для роботи з ESP8266, встановлюємо параметри послідовного з'єднання. Все досить просто та багаторазово викладено в Інтернеті.

Тепер пишемо програму на LUA, яку потім завантажимо в ESP8266:

Завантажувач Lua для AVR, що записується в ESP8266

функція InstrProgrammingEnable () -- instruction for MC "enable programming" p=0 while p<31 do p=p+1 pin=8 gpio.write(pin, gpio.LOW) spi.send(1, 0xAC,0x53) read = spi.recv(1, 8) spi.send(1,0,0) gpio.write(pin, gpio.HIGH) if (string.byte(read)== 83) then print("connection established") p=33 if(p==31) then print("no connection") end end end end функція ProgrammingDisable () pin=2--END OF ESET FOR MK gpio.mode(pin, gpio.INPUT) pin=8 gpio.mode(pin, gpio.INPUT) pin=5-CLK MASTER for SPI gpio.mode(pin, gpio. INPUT) pin=6--MISO MASTER для SPI gpio.mode(pin, gpio.INPUT) pin=7--MOSI MASTER для SPI gpio.mode(pin, gpio.INPUT) end функція ProgrammingEnable () pin=2-- RESET FOR MK gpio.mode(pin, gpio.OUTPUT) gpio.write(pin, gpio.LOW) pin=2--POZITIV FOR 4MSEC RESET FOR MK gpio.mode(pin, gpio.OUTPUT) gpio .write(pin, gpio.HIGH) tmr.delay(4) gpio.mode(pin, gpio.OUTPUT) gpio.write(pin, gpio.LOW) tmr.delay(25000) end функція InstrFlashErase() pin=8 gpio.write(pin, gpio.LOW) spi.send(1,0xAC,0x80,0,0) gpio.write(pin, gpio.HIGH) tmr.delay(15000) pin=2--RESET FOR MK gpio.mode(pin, gpio.OUTPUT) gpio.write(pin, gpio.HIGH) tmr.delay(20000) gpio.write(pin, gpio.LOW) print("FLASH is erased") InstrProgrammingEnable() end функція InstrStorePAGE(H, address, data) pin=8 gpio.write(pin, gpio.LOW) spi.send(1,H,0,address,data) gpio.write(pin, gpio.HIGH) tmr.delay(500) end function InstrWriteFLASH(page_address_low,page_address_high) pin=8 gpio.write(pin, gpio.LOW) spi.send(1,0x4C,page_address_high,page_address_low,0) gpio.write(pin, gpio.HIGH) tmr.delay(5000)- іноді не прописуються флеш при малих затримок end функція Programming (payload) pin=8--CS MASTER для SPI gpio.mode(pin, gpio.OUTPUT, gpio.PULLUP) pin=4--LED LIGHTS ON LOW gpio.mode(pin, gpio.OUTPUT) gpio.write(pin, gpio. LOW) print(string.len(payload)) page_count = 7 -- пишемо 1 кілобайт for k =0 ,page_count ,1 do--quantity of pages for i=0 , 127, 2 do-- -1 address = i/ 2 data=payload:byte(i+1+128*k) if data == nil then data = 0xff end payload:byte(i+1+1+128*k) if data == nil then data = 0xff end InstrStorePAGE(0x48,address,data) -- tmr.delay(100) end page_address_low=bit.band(k ,3 )*64 -- 3 це двійкове 11 page_address_high=k/4+frame1024*2 tmr.delay(1000) InstrWriteFLASH(page_address_low,page_address_high) tmr.wdclr() end pin=4--. OUTPUT) gpio.write(pin, gpio.HIGH) end --MAIN BLOCK wifi.setmode(wifi.STATION) --wifi.sta.config("ім'я мережі","пароль") -- set SSID і password of access point station_cfg=() tmr.delay(30000) station_cfg.ssid=" ім'я мережі" tmr.delay(30000) station_cfg.pwd="пароль" tmr.delay(30000) wifi.sta.config(station_cfg) tmr.delay(30000) wifi.sta.connect() tmr.delay(10 (wifi.sta.status()) print(wifi.sta.getip()) while (wifi.sta.status()~=1) до if(wifi.sta.status()==5) then break end end sv=net.createServer(net.TCP,30) tmr.delay(100) print("SERVER READY") sv:listen(4000,функція(c) c:on("receive", function(c, payload) print (payload) if (payload =="program\r\n") then c:send("ready\r\n") print("ready for program\r\n") spi.setup(1, spi.MASTER , spi.CPOL_LOW, spi.CPHA_LOW, spi.DATABITS_8,320,spi.FULLDUPLEX) ProgrammingEnable () tmr.delay(100) InstrProgrammingEnable () tmr.delay(100) InstrFlashErase() 0mr0 -номер переданого фреймов st=net.createServer(net.TCP,30) st:listen(4001,function(c) c:on("receive", function(c, payload) tmr.wdclr() frame1024=frame1024+1 end) end) end if (payload =="data\r\n") then c:send("ready\r\n") print("ready for data\r\n") srv= net.createServer(net.UDP) tmr.delay(1000) pin=10 gpio.write(pin, gpio.HIGH) uart.setup(0,9600,8,0,1,0) srv:listen(5000) srv :on("receive", function(srv, pl) pl=pl*1 --print(pl) uart.write(0,pl) end end if (payload =="stop\r\ n") then if(st~=nil) then st:close() frame1024=0 ProgrammingDisable () print("stop program") end if(srv~=nil) then srv:close() print("stop data" ) end end end) end) end)


Де відповідні функції виконують такі дії:

function InstrProgrammingEnable ()- Переводить мікроконтролер в режим програмування спеціальною командою, що відправляється по SPI.

функція ProgrammingEnable ()– просто ресетимо AVR на 25 мс перед початком програмування

функція ProgrammingDisable ()– після закінчення програмування, переводимо висновки SPI ESP8266 в неактивний стан, щоб вони не заважали нам при виконання коду на мікроконтролері (раптом вони там використовуються)

функція InstrFlashErase()– затираємо флеш-пам'ять на мікроконтролер перед початком програмування. Навіщо це треба пояснювати, не треба.

функція InstrStorePAGE(H, address, data)– за цією командою у внутрішній буфер мікроконтролера записується байт програми. Але це ще не сам флеш запис, тому що флеш пишеться тут посторінково по 128 байт.

function InstrWriteFLASH(page_address_low,page_address_high)- А ось це вже запис флеш і вона вимагає часу, зверніть увагу на тимчасову затримку 5000 мкс.

функція Programming (payload)- Найбільша і важлива функція використовує і перераховані вище функції. Вона бере програму, що передається, шматками по 1024 байт, ділить їх на байтики і формує для них адреси, а потім відправляє в мікроконтролер у внутрішній буфер і через кожен 128 байт ініціалізує запис флеш. Потім бере наступний кілобайт коду і повторює операцію, природно зі зміщенням на адресах, щоб писати далі, а не затирати записане. Спочатку, я намагався пересилати програми повністю, але при перевищенні шести кілобайт в ESP8266 просто закінчується доступна пам'ять і вона вилітає. Один кілобайт виявився найзручнішою одиницею, бо акуратно ділиться на частини і зручно передається TCP (нам же треба його з комп'ютера ще отримати). Більший розмір теж не потрібен, TCP, самі знаєте, в поточній версії обмежує пакет, що передається, в 1500 чи байт (але у мене передавався чомусь 1440, начебто).

Як би нічого складного, але кілька підводних камінців довелося подолати.

Реєструємось у бездротовій мережі.

Створюємо спочатку TCP сервер, який слухає три команди:

1. “program” (програмуватимемо),

2. “data” (змінюватимемося даними),

3. ”stop” (все припиняємо).

Якщо ми програмуємо, то спочатку ініціалізуємо SPI і створюємо ще один TCP сервер, який вистачає дані (код програми, що прошивається) покилобайтно і викликає під них функції програмування мікроконтролера. Я розумію, що виглядає безглуздо створювати другий сервер, але це необхідність, бо місцеве API підтримує створення тільки одного сокету, а нам необхідно розділяти команди ”program” та “data” власне з даними, що передаються, бо на око вони не різняться, там байти і тут байти.

Якщо ж ми хочемо не програмувати, а обмінюватися даними, надсилаючи їх у нашому випадку в мікроконтролер, то спочатку відправляємо по TCP рядок ”data”. У відповідь на це буде створено вже UDP сервер (я нагадаю, що ми керуємо динамічно механічною рукою і нам затримки з формуванням TCP пакетів не потрібні, та взагалі відправляти один байт цілим TCP кадром моветон). А UDP дейтаграми у нас будуть маленькими і формуватимуться швидко.

Після ініціалізується UART, і кожен байт, що приймається в бездротовому вигляді, відправляється вже по проводу TXD на мікроконтролер, який зобов'язаний, буде там прошита відповідна програма, його прийняти. Обмін даними в іншому напрямку організувати також не складно, але я поки що його не реалізовував.

Ну і по команді ”stop” вищезгадані сервери (крім найпершого) закривають з'єднання і найголовніший сервер знову переходить у стан очікування команд ”program” та “data”.

Оскільки SPI інтерфейс програмно емулюється в ESP8266, то порти введення-виводу для сигналів CS, CLK, MISO, MOSI, RESET (для AVR), можете використовувати будь-які доступні, а не ті, що вказані в завантажувачі. Крім того, виявилося, що CS і MISO в принципі теж можна в цьому випадку обірвати, працюватиме і без них. Ну і один висновок задіюється на вбудований в плату ESP8266 світлодіод, щоб блимав іноді і показував, що програма ще жива.

Перевірок на помилки запису не робиться (за винятком першого запиту до AVR, але ця інформація просто виводиться на консоль), EEPROM не програмується, більше 32 Кб не шиється - коротше ще над чим попрацювати. Швидкість обміну SPI приблизно 115 Кбіт, за кілька секунд все прошивається, приблизно, як у звичайного послідовного програматора типу ISP500).

Беріть код, вписуйте свої мережі та паролі, компілюйте на ESplorer, обзывайте його “init” (щоб запускався під час рестарту) та відправляйте на ESP8266. Має працювати. У сенсі працювати бездротовим програматором, як мінімум.

Ми тепер займемося керуючою стороною – персональним комп'ютером.

По суті, нам потрібно взяти файл формату HEX, на який перетворюються ваші програми, написані в середовищі ATMEL STUDIO і відправити його WI-FI на відомий нам порт сокету (в даному випадку 4000). Невелика проблема в тому, що нам потрібний двійковий файл BIN для пересилки, а ATMEL STUDIO тішить нас тільки HEXом. Виходу тут два; або перевести його у формат BIN спеціальною програмою конвертером типу WinHex або зробити це самим у своїй програмі. Я поки не зробив, але начебто це не складно, там треба відрізати заголовок і зробити щось ще.

В результаті програму-завантажувач я написав на JAVA (в основному тому, що більше ні на чому не вмію), працюючи в просто чудовому та безкоштовному середовищі IntelliJ IDEA. У ній створюється TCP клієнт, який шукає сервер, запущений на ESP8266. Якщо знаходить, то зв'язується з ним і відправляє файл розташований за такою-то адресою. Код нижче.

Завантажувач файлів на JAVA, що працює на стороні ПК

import java.io.*; import java.net.*; import java.util.ArrayList; import java.util.List; public class Net ( public static void main(String args) ( new Http_client(4000); )) class Http_client extends Thread ( int port; String s; String Greetings_from_S; Http_client(int port)( this.port = port; start(); ) public void run() Але взагалі, дізнається зі спілкування з роутером // краще зробити його статичним, роутери це вміють try (Socket socket = new Socket ("192.168.1.113", port)) )), true), pw.println("program"); ​​// Greetings with SERVER System.out.println("program"); br.readLine(); System.out.println(Greetings_from_S); bis = New BufferedInputStream(New FileInputStream(file)), byte data = New Byte; int residy = data.length%1024; for (int i = 0; i< frames;i++) { for (int k = 0; k< (1024); k++) { data_buffer[k] = data; } sendingChunk(data_buffer); } byte data_buffer2= new byte; for (int i = 0; i < residy;i++) { data_buffer2[i] = data; } sendingChunk(data_buffer2); pw.println("stop");// System.out.println("stop program"); } catch (Exception e) { System.out.println(e); } } } catch (Exception e) { System.out.println(e); } } public void sendingChunk (byte data_buffer){ try (Socket socket = new Socket("192.168.1.113", 4001)){ BufferedOutputStream bos = new BufferedOutputStream((socket.getOutputStream())); bos.write(data_buffer); bos.flush(); System.out.println(data_buffer.length); } catch (Exception e) { System.out.println(e); } } }


Тут звичайно навкручено зайвого, всякі ready, в принципі не потрібні. Якщо вже TCP з'єднання встановлено, воно встановлено. Єдина проблема була в тому, що файл ніяк не хотів вирушати рівними шматками по 1024 байт, як мені потрібно було, хоча я і явно вказував розмір. Мабуть, там якийсь фінальний буфер недоступний з JAVA, і він відправляє пакети розміром, яким йому хочеться, що для приймальної сторони абсолютно неприйнятно. Спочатку я пробував зробити затримку, щоб буфер втомлювався чекати на наступні шматки і відправляв як є. Але затримка стала працювати, коли досягла 10 секунд, що мені якось здалося забагато на один кілобайт, що передається.

Але потім я помітив, що чомусь перший шматок завжди йде рівний, який був замовлений, а вже з другого починається непередбачувана вакханалія. Тому я зробив так, щоб клієнт відкривав з'єднання, відправляв порцію коду 1024 байт і закривав з'єднання. І так поки не вирушить весь файл. Все успішно запрацювало.

Єдине для запуску необхідно поставити на комп'ютер середовище виконання JAVA. Але я зазвичай запускаю відразу з IntelliJ IDEA, бо там у консолі завжди видно, що відбувається (але і тут середовище JAVA потрібне). Хоча, звичайно, розумно треба зробити GUI. Тобто віконце, де випадає шлях до файлу, можливість міняти там же у вікні номери портів та й інші потрібні речі. І все це зібрати у вигляді файлу, що виконується.

А таперіча, як казав Коровйов, повернемося громадяни, що до механічної кінцівки MechArm, що була згадана на самому початку. У нас тепер є можливість її запрограмувати віддалено, а потім нею покерувати. Перейдемо до програми управління за мікроконтролера.

В даному випадку нам необхідно контролювати чотири сервоприводи. Ось таких.


Такий привід керується прямокутними імпульсами періоду 20 мс (50Гц) з коефіцієнтом заповнення від 2 до 4 відсотків. Тобто 2% це повний поворот в один бік, 4% в інший. Завдання для вбудованого в AVR ШИМ.

Один сервопривід використовується для руху вправо-ліворуч; другий він – від себе; третій вгору-вниз; четвертий – сама клешня, яка має стискатися та розтискатися. Все написано на С і відкомпільовано до файлу HEX в ATMEL STUDIO. Дещо дивний вид програми пов'язаний з тим, що спочатку рука управлялася з клавіатури прив'язаної проводами до мікроконтролера. Але дроти вчорашній день, треба еволюціонувати далі.

Можна, звичайно, використовувати скетчі для сервоприводів від ”ARDUINO”, але мені вони не сподобалися. Самому писати цікавіше. До того ж, всі чотири сервоприводи повинні працювати одночасно, а не в мультиплексованому режимі, коли ШІМ перемикається на кожен сервопривід по черзі. Бо гравітацію ніхто не скасовував і піднята вгору кінцівка, моментально опуститься, якщо на відповідний сервопривід перестануть надходити імпульси, що управляють. Я не впевнений, що ”ARDUINO” скетч забезпечує одночасний режим роботи для чотирьох серво. А ось самі ми цілком можемо написати програму, яка відповідає потрібним вимогам. Та й взагалі за відсутності операційної системи, яка відокремлює ягнят від козлищ, застосування скетчів, що конкурують за периферійні пристрої мікроконтролера (а ми навіть і не знаємо заздалегідь якісь) справа надто багопродуктивна.

Ось сам код, який ми записуємо в Arduino Nano через ESP8266-07.

Програма для керування MechArm для мікроконтролера AVRmega328P

#define F_CPU 16000000 #include #include // Цілі цифри #include #include // математика # include //стандартне введення-виведення #include #include #include //стандартні можливості #define UART_BAUD_RATE 115200 // лічильник Т1 задає часовий інтервал 20мс #define COUNTER1_OFF TCCR1B=0b00000000 // CS02 CS01 CS00 - 000 - вимкнено; 001 без дільника; 010 з дільником 8; 011-64; 100 -256; 101 -1024 #define COUNTER1_ON TCCR1B=0b00000011 // лічильник Т0 задає ширину керуючого імпульсу для серво РВ0 і РВ1 #define COUNTER0_OFF TCCR0B=0b00000000 // CS02 CS01 CS00 - 0 001 без дільника; 010 з дільником 8; 011-64; 100 -256; 101 -1024 #define COUNTER0_ON TCCR0B=0b00000100 // лічильник Т2 задає ширину керуючого імпульсу для серво РB2(PD6) і РВ3(PD7) #define COUNTER2_OFF TCCR2B=0b00000000 //0 CS0 001 без дільника; 010 з дільником 8; 011-64; 100 -256; 101 -1024 #define COUNTER2_ON TCCR2B=0b00000110 volatile uint16_t period_20ms; volatile uint8_t State_of_keyboard; volatile uint8_t start_position; volatile int8_t number_servo; ISR(USART_RX_vect)// переривання для UART ( State_of_keyboard=UDR0; return; ) ISR(TIMER0_COMPA_vect)// серво РВ0 ширина керуючого імпульсу ( PORTB &=~(1<<0); TIMSK0&=~(1<
Суть програми зрозуміла з тексту та коментарів. Ми використовуємо лічильник Т1 для зразкового періоду 20 мс і лічильники Т0, Т2 для видачі ШИМ сигналів на чотири лінії порту введення-виведення, благо кожен з цих двох лічильників може працювати на два пристрої.
У програмі встановлюються початкові положення сервоприводів через завантаження рахункових регістрів OCR0A, OCR0B, OCR2A, OCR2B. Також вводяться константи обмежувачі, оскільки нам не завжди потрібний розмах 180 градусів. Ну і далі, за перериванням від UART, програма ловить число відправлене ESP8266 (від 1 до 8) і переводить його в команду для відповідного сервоприводу. Приводів чотири, кожен працює у двох напрямках, тому цілих чисел від одного до восьми цілком вистачає. Як тільки число вибрано, вміст вищезгаданих регістрів лічильників або інкрементується або декрементується відповідно змінюючи шпаруватість керуючого імпульсу і кут повороту вибраного сервоприводу. Ті приводи, які ми не вибирали, зберігають старе значення кута повороту (оскільки вміст відповідних регістрів хоч і оновлювався, але не змінювався) і продовжують утримувати механічну руку в колишньому положенні.

Тепер нам залишилося лише написати керуючу програму, вибачте за тавталогію, для керування механічною рукою вже безпосередньо з комп'ютера з WI-FI.
Код також написаний на JAVA, але трохи облагороджений. З'явився GUI та можливість редагувати номери портів та мережеву адресу ESP8266.

Що там відбувається зрозуміло з віконця. Текст програми я тут не наводжу (він доступний на

Добридень!

Нещодавно зацікавився ідеєю створення «розумного дому». Так як з необхідних компонентів у моєму розпорядженні поки є тільки arduino та телефон на андроїді, вирішено було почати з створення пульта управління та зв'язку його з рештою системи.

Моє бачення системи виглядає так:

Думаю варто поєднати домашній і веб-сервери, прикупивши статичний IP-адреса, але на перший час зійде і так. Почнемо з простого – навчимося віддалено керувати світлодіодом та LCD-дисплеєм.

Web-server
На веб-сервері створюємо БД із двома таблицями – leds та texts. Таблиця leds містить 2 поля – id та status. Вона містить один запис із актуальним станом світлодіода. Таблиця texts містить 2 поля – id та text. Вона також містить один запис з текстом, який відображається на LCD-дисплеї.

Тепер напишемо пару скриптів, які викликатимемо з телефону та передаватимемо інформацію для БД. Пишемо на php.

Скрипт led.php (управління світлодіодом):

Скрипт msg.php (управління LCD-дисплеєм):

Я думаю, що з коментарів зрозуміло, як ці скрипти працюють. Це все, що знаходиться на веб-сервері. Тепер перейдемо до домашнього сервера (або простіше кажучи, комп'ютера, до якого підключено ардуїно).

Домашній сервер
На ньому буде працювати програма (можна навіть назвати її - демон), що посилає запити до БД і при зміні інформації, що там знаходиться, посилає на COM-порт з ардуїно відповідну команду. Програму напишемо мовою Processing:

Import processing.serial.*; //бібліотека для роботи з COM-портом import de.bezier.data.sql.*; //Бібліотека для роботи з БД MySQL Serial port; MySQL dbconnection; int prevLEDState = 0; //Попередній стан світлодіода String prevS = ""; //Попередній текст, відпаврований на LCD-дисплей void setup() ( port = new Serial(this, "COM4", 9600); //ініціалізуємо COM-порт 4 (на не причеплена ардуїна), швидкість обміну - 9600 бод port. bufferUntil("\n"); String user = "ім'я користувача"; String pass = "пароль"; String database = "ім'я_бд"; dbconnection = new MySQL(this, "ваш_домен.ru", database, user, pass); / /з'єднуємося з БД dbconnection.connect(); ) void draw() ( //стежимо за інформацією про світлодіод у БД dbconnection.query("SELECT * FROM leds WHERE id = "1""); //робимо запит до таблиці leds while (dbconnection.next()) //обходимо вибірку з результату запиту ( int n = dbconnection.getInt("status"); //отримуємо значення з поля status if (n != prevLEDState) //якщо воно змінилося порівняно з попередньому "такту" роботи програми, то посилаємо команду на COM-порт ( prevLEDState = n; port.write("1"); // перший переданий символ означатиме код виконуваної операції: 1 - управління світлодіодом, 2 - управління LCD-дисплеєм port.write(n); )) // стежимо за інформацією про LCD-дисплей у БД dbconnection.query("SELECT * FROM texts WHERE id = "1""); //робимо запит до таблиці texts while (dbconnection.next())//обходимо вибірку з результату запиту (String s = dbconnection.getString("text"); //отримуємо значення з поля text if (s! = prevS) ( prevS = s; port.write("2"); port.write(s); ) ) delay(50); //робимо затримку в 50 мс, щоб не надсилати запити безперервно )
Поясняти цей код я теж не стану, все й так зрозуміло.
Ще один важливий момент. Щоб програма з нашого комп'ютера могла звертатися до бази даних, розташованої на віддаленому сервері, треба це дозволити. Вводимо наш IP у список дозволених:

Додаток для телефону
Телефон у мене андроїд, для нього і пишемо. Не сильно вдаватися в подробиці (дуже добре як про встановлення середовища програмування, так і про написання першого додатка написано ось у цій статті - посилання).

Зовнішній вигляд програми виглядає досить скромно, але в даному випадку це не головне:

Наведу лише уривки коду програми під Android. Функція, що викликає скрипт, що керує світлодіодом:
public void changeLED() ( try ( URL url1 = new URL("http://ваш_домен.ru/led.php"); HttpURLConnection urlConnection = (HttpURLConnection) url1.openConnection(); try ( InputStream in = new BufferedInputStream(urlConnection .getInputStream()); ) finally ( urlConnection.disconnect(); ) ) catch (Exception e) ( ) )
Функція, що надсилає текст для відображення на LCD-дисплеї:
public void submitMsg() ( final EditText tt = (EditText) findViewById(R.id.editText1); try ( URL url1 = new URL("http://ваш_домен.ru/msg.php?msg="+tt.getText ()) HttpURLConnection urlConnection = (HttpURLConnection) url1.openConnection();
Ну і головна функція, в якій відбувається прив'язка обробників подій до кнопок:
public void onCreate(Bundle savedInstanceState) ( super.onCreate(savedInstanceState); setContentView(R.layout.main); final Button btn1 = (Button) findViewById(R.id.button1); ( public void onClick(View v) // клік на кнопку ( changeLED(); ) )), final Button btn2 = (Button) findViewById(R.id.button2); void onClick(View v) // клік на кнопку ( submitMsg(); ) ));
І ще один важливий момент – додати дозвіл додатку на вихід до Інтернету. Для цього у файл AndroidManifest.xml (він знаходиться в директорії нашого андроїд-додатку) треба додати рядок:

Експортуємо нашу програму у файл APK і встановлюємо на телефон. Пульт керування розумним будинком готовий!

Arduino
Ну і нарешті останнє, але не за значенням – підключення Ардуїно та її прошивка. Схема підключення LCD-екрана та світлодіода до Arduino Uno виглядає так:

Резистор беремо на 220 Ом. Докладніше про підключення LCD-екрана можна прочитати тут - посилання

А ось як це все виглядає насправді:

Правда гарно?

Завдання ардуїно полягає у прослуховуванні того, що програма-демон на домашньому сервері посилає на COM-порт, до якого і підключено ардуїно (хоча фактично підключення йде USB-кабелем, але комп'ютер розпізнає його як послідовний порт). Після отримання будь-яких даних з комп'ютера, контролер за першим символом переданої інформації розпізнає код команди (тобто, що зараз належить управляти – LCD-дисплеєм або світлодіодом). Далі в залежності від коду та наступної за ним інформації виконується або увімкнення/вимкнення світлодіода, або виведення на дисплей надісланого повідомлення. Отже, ось власне код:

#include //Вбудована бібліотека для роботи з LCD-дисплеєм boolean isExecuting = false; //змінна, що відбиває, що йде виконання якоїсь команди //Одразу поясню, навіщо це потрібно. За кожен такт циклу loop ардуїно зчитує з COM-порту код одного символу. //Тому рядок передаватиметься за кілька тактів. При цьому перед кожною з двох можливих команд (зміна стану світлодіода та передача тексту на дисплей) // передається код цієї команди (1 та 2 відповідно). Щоб відокремити коди команд від інформації, що передається далі (стану світлодіода або тексту для дисплея), // використовується ця змінна. LiquidCrystal lcd(4,5,10,11,12,13); //ініціалізація дисплея int ledPin = 8; //номер піна ардуїно, на якому приєднаний світлодіод int prevLEDStatus = 0; //Попередній статус світлодіода (вкл/викл) int newLEDStatus = 0; //Новий статус світлодіода int cmd = 0; //код виконуваної команди void setup() ( Serial.begin(9600); //ініціалізація COM-порту (9600 - швидкість обміну в бодах) pinMode(ledPin,OUTPUT); //ініціалізація 8-го піна ардуїно як виходу lcd. begin(20,4);// ініціалізація LCD-дисплея (4 рядки по 20 символів) ) void loop() ( if (Serial.available() > 0) //якщо на COM-порт прийшла якась інформація ( if (isExecuting == false) //якщо в даний момент не йде виконання ніякої команди (cmd = Serial.read() - "0"; //зчитуємо код команди isExecuting = true; //тепер змінна показує, що почалося виконання команди ) if (cmd == 1) //управління світлодіодом ( newLEDStatus = (int) Serial.read(); //зчитуємо новий статус світлодіода if (newLEDStatus != prevLEDStatus) //якщо він змінився порівняно з поточним статусом, то змінюємо поточний статус ( digitalWrite(ledPin,newLEDStatus); prevLEDStatus = newLEDStatus; ) ) else //управління дисплеєм ( if (isExecuting == false) //якщо в даний момент не йде виконання ніякої команди ( lcd.clear(); //очищаємо екран ) else ( lcd.print((char)Serial.read()); //виводимо символ на дисплей ) ) ) else //якщо COM-порт не надійшла ніяка інформація ( delay(50); // робимо затримку 50 мс if (Serial.available()<= 0) //если информации по-прежнему нет isExecuting = false; //считаем, что никакая команда не выполняется } }
Я думаю, пояснень він не вимагає, тому що я докладно все розписав у коментарях. Єдине, що варто відзначити, так це деякі обмеження на рядки, що передаються для виведення на дисплей. Вони не повинні містити пробілів (це обмеження накладається недосконалістю мого алгоритму) і не повинні містити кирилиці (т.к. вона підтримується не всіма дисплеями, а якщо і підтримується, то вимагає передачі кодів символів у своєму власному кодуванні, перетворювати символи на яку немає ніякого) бажання).

Висновок
Ну от і все. Виявилось, що це досить просто.
Відео того як все працює:

У цій статті ви дізнаєтесь, як створити систему, яка може включати та вимикати навантаження постійного струму за допомогою мобільного додатка. Ви також дізнаєтесь, як виконати це завдання миттєво або за таймерами, заздалегідь встановленими для включення та вимкнення навантажень.

Огляд проекту

Ви можете реалізувати цю систему там, де потрібно включати навантаження постійного струму на певний час. У цьому вам допоможе наш Android додаток, не вимагаючи апаратного інтерфейсу, клавіатури та LCD дисплея.

Комплектуючі

Складання макетної плати ESP8266

ESP8266 - недорогий SoC-чіп із вбудованим мікроконтролером та повним стеком протоколів TCP/IP, що означає, що він може безпосередньо звертатися до вашої Wi-Fi мережі.

Оскільки цей чіп має свій мікроконтролер, ви можете помістити в нього код своєї програми або можете використовувати модуль просто як Wi-Fi приймач, що ми й збираємося зробити в даному проекті. Більш ефективно було б використовувати цей модуль і як приймач, і як контролер, але з метою навчання ми взаємодіятимемо з модулем, використовуючи Arduino.

Чіп ESP8266 поставляється у різних модулях. Ми будемо використовувати модуль ESP-01. Звичайно, ви можете використовувати будь-який інший модуль.

По-перше, ви повинні знати, що модуль працює з напругою 3,3 В, і напруга високого логічного рівня від Arduino має бути такою самою, щоб не пошкодити наш модуль. Для цього потрібно перетворювати рівень напруги між платою Arduino (яка працює на 5 В) і модулем. Хорошою новиною є те, що перетворювача потребуватиме тільки висновок для передачі на Arduino, оскільки приймальний висновок зазвичай розпізнає логічні сигнали з напругою 3,3 від ESP8266.

Одним із найпростіших способів виконання цього перетворення є схема від Sparkfun. Ви можете замовити готовий модуль.

Перетворювач рівня 5В → 3,3В

На малюнку нижче показано розпинування нашого модуля на ESP8266:

ВисновокПризначення
UTXDПередача даних через UART
URXDПрийом даних через UART. Вихід, до якого він підключається, має бути 3,3 Ст.
CH_PDВиняток: низький рівень на вході вимикає чіп, високий рівень на вході включає його; Для нормальної роботи модуля необхідно підтягнути його до лінії живлення.
GPIO0При завантаженні: має бути високий рівень, щоб входити до нормального режиму завантаження; низький рівень вводить у спеціальні режими завантаження.
GPIO2При завантаженні: низький рівень змушує завантажувач увійти в режим завантаження флеш-пам'яті; високий рівень викликає нормальний режим завантаження.
RSTСкидання; активний рівень – низький.
GNDЗемля.
VCCЖивлення/3,3В.

Я використовував LM317, лінійний регулятор напруги, що настроюється, з вихідним струмом до 1,5 А, для забезпечення модуля відповідним джерелом живлення 3,3 В.

Примітка:Не використовуйте висновок 3,3 від Arduino, оскільки стабілізатор напруги 3,3 на платі Arduino не може забезпечити необхідну для модуля величину струму, особливо при піковому споживанні енергії під час передачі.

Я використав BS170 (замість BSS138) для перетворювача логічних рівнів; обидва працюють добре.

Тепер ви можете підключити свій модуль до комп'ютера, використовуючи USB-TTL перетворювач, та випробувати його.

Складання макетної плати реле

Для керування реле я використовував біполярний NPN транзистор BC337 з резистором 1 ком на базі. Для захисту від зворотної напруги котушки я використав діод 1n4007.

Нормально замкнутий (NC) контакт реле я вирішив підключити до землі.

Код Arduino

Тепер ми стикаємося із проблемою. ESP8266 використовує UART як інтерфейс для AT-команд, а Arduino Uno (яка використовує Atmega328) має лише один порт UART. Цей порт вже підключено до мосту USB-TTL, а також висновків 0 і 1.

Як рішення можна використовувати емулятор для UART порту на іншому цифровому виводі Arduino за допомогою бібліотек AltSoftSerial або SoftwareSerial. Це дозволить вам, як і раніше, мати апаратний порт UART для налагодження та друку повідомлень у консолі, а програмний порт - для зв'язку з модулем.

Багато людей (включаючи мене) повідомляють про проблеми з послідовним програмним портом при високих швидкостях передачі - як на тих, що ми будемо використовувати з esp8266, 115200 біт/с. Я можу сказати, що у вас 50% прийнятих від модуля даних буде пошкоджено, якщо ви використовуєте програмний UART, а переданих від Arduino до модуля даних майже 100% буде коректно. Я отримав ці результати після відстеження сигналів на лініях RX та TX.

Як рішення я додав у код кілька директив define, щоб полегшити вам вибір між апаратним та програмним UART портами. Майте на увазі, що ви не можете використовувати один і той же порт для налагодження та спілкування з модулем, тому вам потрібно вибирати між ними.

//Розкомментуйте Serial.***, якщо хочете для зв'язку з ESP використовувати апаратний послідовний порт (висновки 0,1) //Розкомментуйте esp8266.***, якщо хочете для зв'язку з ESP використовувати програмний послідовний порт (висновки 2,3) #define esp8266_Available() Serial.available() //esp8266.available() #define esp8266_Find(ARG) Serial.find(ARG) //esp8266.find(ARG) #define esp8266_Read() Serial.read .read() #define esp8266_Write(ARG1,ARG2) Serial.write(ARG1,ARG2) //esp8266.write(ARG1,ARG2) #define esp8266_Print(ARG) Serial.print(ARG) //esp8266.print

У вихідному коді ви знайдете частину коду, яка встановлює модуля з вашим роутером:

SendCommand("AT+RST\n", 2000, DEBUG); // перезапустити модуль sendCommand("AT+CWMODE=1\r\n", 1000, DEBUG); // налаштувати як точку доступу sendCommand("AT+CWJAP="tur", "341983#tur", 3000, DEBUG); //**** ЗМІНИТИ SSID і ПАРОЛЬ У ВІДПОВІДНОСТІ З ВАШОЇ МЕРЕЖЕЮ ******// delay(10000); sendCommand("AT+CIFSR\r\n", 1000, DEBUG); // одержати ip адресу sendCommand("AT+CIPMUX=1\r\n", 1000, DEBUG); // налаштувати для кількох з'єднань sendCommand("AT+CIPSERVER=1,1337\r\n", 1000, DEBUG); // увімкнути сервер на порту 1337

Цикл скетчу чекає на команди, які повинні прийти через Wi-Fi з'єднання. В даний час підтримуються такі команди:

  • 'con' для одержання стану висновків, високий чи низький логічний рівень;
  • 'on=' включити відповідний висновок;
  • 'of=' вимкнути відповідний висновок;
  • 'Tm=n/fS' встановити таймер увімкнення (n) або вимикання (f) відповідного виводу.

Усі команди мають відгук підтвердження.

Примітки:

  • деякі частини скетчу засновані на ;
  • якщо ви використовуєте модулі зі старим SDK, у вас можуть бути такі ж помилки, як і у мене. Єдиним рішенням у цьому випадку є оновлення вашої прошивки до останньої версії. Перегляньте , щоб отримати допомогу в оновленні прошивки модуля на ESP8266. Я оновив програму з версії 1.3 до 1.5.4.

Повний код програми:

#include #define DEBUG 0 // якщо ви для зв'язку з ESP використовуєте апаратний послідовний порт, змініть значення на 0 #define ESPBaudRate 115200 #define HWSBaudRate 115200 #define OUTPUT1 11 #define OUTPUT2 12 #define OUT. якщо для зв'язку з ESP хочете використовувати апаратний послідовний порт (висновки 0,1) // розкоментуйте esp8266.*** , якщо для зв'язку з ESP хочете використовувати програмний послідовний порт (висновки 2,3) #define esp8266_Available() Serial.available( ) //esp8266.available() #define esp8266_Find(ARG) Serial.find(ARG) //esp8266.find(ARG) #define esp8266_Read() Serial.read() //esp8266.read() #define esp8266 ,ARG2) Serial.write(ARG1,ARG2) //esp8266.write(ARG1,ARG2) #define esp8266_Print(ARG) Serial.print(ARG) //esp8266.print(ARG) // Робить RX лінію Arduino виводом 2, а TX лінію Arduino виводом 3. // Це означає, що вам необхідно підключити TX лінію від ESP до 2 висновку Arduino, // а RX лінію від ESP до висновку 3 Arduino. SoftwareSerial esp8266(2, 3); /*************/ byte OUTPUTstate; byte OUTPUTTMRIsSet; byte OUTPUTTMRState; long OUTPUTTimer; /*************/ /***Commands**/ String GETSTATE = "con"; // Рядок запиту від мобільного додатка, щоб дізнатися про стан кожного виходу String SETON = "on="; // Рядок запиту від мобільного додатка, щоб увімкнути вихід String SETOFF = "of="; // Рядок запиту від мобільного додатка, щоб вимкнути вихід String TIMER = "tm ="; // Рядок запиту від мобільного додатка, щоб задати таймер для виходу /*************/ void setup() ( Serial.begin(HWSBaudRate); // Послідовний порт для відправки повідомлень від Arduino на комп'ютер esp8266.begin(ESPBaudRate);// Програмний послідовний порт для відправки повідомлень від Arduino на ESP8266 pinMode(OUTPUT1, OUTPUT);digitalWrite(OUTPUT1, LOW);pinMode(OUTPUT2, OUTPUT); OUTPUT3, OUTPUT);digitalWrite(OUTPUT3, LOW);// перезапустити модуль sendCommand("AT+RST\r\n", 2000, DEBUG); n", 1000, DEBUG); //**** ЗМІНИТИ SSID і ПАРОЛЬ У ВІДПОВІДНОСТІ З ВАШОЮ МЕРЕЖЮ ******// sendCommand("AT+CWJAP=\"tur\",\"341983#tur\ "\r\n", 3000, DEBUG), delay(10000); // отримати ip адресу sendCommand("AT+CIFSR\r\n", 1000, DEBUG); // налаштувати для кількох з'єднань sendCommand("AT+ CIPMUX=1\r\n", 1000, DEBUG); // включити сервер на порту 1337 sendCommand("AT+CIPSERVER=1,1337\r\n", 1000, DEBUG); if (DEBUG == true) Serial.println("Server Ready"); ) void loop() ( if (esp8266_Available()) // перевірити, чи надіслав esp повідомлення ( if (esp8266_Find("+IPD,")) ( // чекати, коли послідовний буфер заповниться (прочитаються всі послідовні дані)) delay(1000 ) // отримати id підключення, щоб ми могли відключитися int connectionId = esp8266_Read() - 48; // віднімаємо 48 тому, що функція read() повертає // десяткове значення в ASCII, а 0 (перше десяткове число) починається з 48 String closeCommand = "AT+CIPCLOSE="; // створення команди закриття підключення closeCommand += connectionId; // додати id підключення closeCommand += "\r\n"; esp8266_Find("? // Цей символ визначає початок команди тілі нашого повідомлення String InStream; InStream = (char) esp8266_Read(); InStream += (char) esp8266_Read(); true) Serial.println(InStream), if (InStream.equals(GETSTATE)) ( // відгук на команду Status =<состояние_выхода_1><состояние_выхода_2><состояние_выхода_3>String response="Status="; response += OUTPUTstate; response += OUTPUTstate; response += OUTPUTstate; sendHTTPResponse(connectionId, response); sendCommand(closeCommand, 1000, DEBUG); // закрити підключення ) else if (InStream.equals(SETON)) ( int pinNumber = (esp8266_Read() - 48); // отримати першу цифру, тобто, якщо висновок 13, то перша цифра дорівнює 1 int secondNumber = (esp8266_Read() - 48), if (secondNumber >= 0 && secondNumber<= 9) { pinNumber *= 10; pinNumber += secondNumber; // получить вторую цифру, т.е., если вывод 13, то 2-ая цифра равна 3, // и добавить ее к первой цифре } if (pinNumber == OUTPUT1) OUTPUTstate = 1; else if (pinNumber == OUTPUT2) OUTPUTstate = 1; else if (pinNumber == OUTPUT3) OUTPUTstate = 1; digitalWrite(pinNumber, 1); String response = "Confg="; // Отклик на команду Confg=<номер_вывода>response += pinNumber; sendHTTPResponse(connectionId, response); sendCommand(closeCommand, 1000, DEBUG); // закрити підключення ) else if (InStream.equals(SETOFF)) ( int pinNumber = (esp8266_Read() - 48); // отримати першу цифру, тобто, якщо висновок 13, то перша цифра дорівнює 1 int secondNumber = (esp8266_Read() - 48), if (secondNumber >= 0 && secondNumber<= 9) { pinNumber *= 10; pinNumber += secondNumber; // получить вторую цифру, т.е., если вывод 13, то 2-ая цифра равна 3, // и добавить ее к первой цифре } if (pinNumber == OUTPUT1) OUTPUTstate = 0; else if (pinNumber == OUTPUT2) OUTPUTstate = 0; else if (pinNumber == OUTPUT3) OUTPUTstate = 0; digitalWrite(pinNumber, 0); // изменить состояние вывода String response = "Confg="; // Отклик на команду Confg=<номер_вывода>response += pinNumber; sendHTTPResponse(connectionId, response); sendCommand(closeCommand, 1000, DEBUG); // закрити підключення ) else if (InStream.equals(TIMER)) ( int pinNumber = (esp8266_Read() - 48); // отримати першу цифру, тобто, якщо висновок 13, то перша цифра дорівнює 1 int secondNumber = (esp8266_Read() - 48), if (secondNumber >= 0 && secondNumber<= 9) { pinNumber *= 10; pinNumber += secondNumber; // получить вторую цифру, т.е., если вывод 13, то 2-ая цифра равна 3, // и добавить ее к первой цифре } if (esp8266_Read() == "n") { if (DEBUG == true) Serial.println("on"); if (pinNumber == OUTPUT1) OUTPUTTMRState = 1; else if (pinNumber == OUTPUT2) OUTPUTTMRState = 1; else if (pinNumber == OUTPUT3) OUTPUTTMRState = 1; } else { if (DEBUG == true) Serial.println("off"); if (pinNumber == OUTPUT1) OUTPUTTMRState = 0; else if (pinNumber == OUTPUT2) OUTPUTTMRState = 0; else if (pinNumber == OUTPUT3) OUTPUTTMRState = 0; } int j = 0; byte Atime; // Таймер может настроен на максимальное значение в 1 сутки // поэтому программа может принять 5 цифр, так как 1 сутки равны 86400 секундам long Time; // Прочитать секунды, значение имеет переменное количество цифр, поэтому читать, пока не получим "s", // что является символом завершения в теле моего сообщения от мобильного телефона while (1) { Time = esp8266_Read(); if (Time == "s") break; Atime[j] = Time - 48 ; j++; } switch (j) // секунды... { case 1: // одна цифра Time = Atime; break; case 2: // две цифры Time = Atime * 10 + Atime; break; case 3: // три цифры Time = Atime * 100 + Atime * 10 + Atime; break; case 4: // четыре цифры Time = Atime * 1000 + Atime * 100 + Atime * 10 + Atime; break; case 5: // пять цифр Time = Atime * 10000 + Atime * 1000 + Atime * 100 + Atime * 10 + Atime[j]; break; } if (DEBUG == true) { Serial.println("Timer:"); Serial.println(Time); } Time = Time * 1000 + millis(); if (DEBUG == true) { Serial.println("Pin:"); Serial.println(pinNumber); } if (pinNumber == OUTPUT1) { OUTPUTTMRIsSet = 1; OUTPUTTimer = Time; } else if (pinNumber == OUTPUT2) { OUTPUTTMRIsSet = 1; OUTPUTTimer = Time; } else if (pinNumber == OUTPUT3) { OUTPUTTMRIsSet = 1; OUTPUTTimer = Time; } String response = "tConfg="; // Отклик на команду tConfg=<номер_вывода>response += pinNumber; sendHTTPResponse(connectionId, response); sendCommand(closeCommand, 1000, DEBUG); // закрити підключення ) else // прийнята команда, що не підтримується ( String response = "ERROR"; sendHTTPResponse(connectionId, response); sendCommand(closeCommand, 1000, DEBUG); // закрити підключення ) ) ) /*****Перевірити таймер для кожного виходу******/ if (OUTPUTTMRIsSet != 0 && (OUTPUTTimer< millis())) { digitalWrite(OUTPUT1, OUTPUTTMRState); OUTPUTstate = OUTPUTTMRState; OUTPUTTMRIsSet = 0; } if (OUTPUTTMRIsSet != 0 && (OUTPUTTimer < millis())) { digitalWrite(OUTPUT2, OUTPUTTMRState); OUTPUTstate = OUTPUTTMRState; OUTPUTTMRIsSet = 0; } if (OUTPUTTMRIsSet != 0 && (OUTPUTTimer < millis())) { digitalWrite(OUTPUT3, OUTPUTTMRState); OUTPUTstate = OUTPUTTMRState; OUTPUTTMRIsSet = 0; } /***************************************/ } /* Name: sendData Description: Функция, используемая для отправки данных на ESP8266. Params: command - данные/команда для отправки; timeout - время ожидания отклика; debug - печатать в консоль?(true = да, false = нет) Returns: Отклик от esp8266 (если есть отклик) */ String sendData(String command, const int timeout, boolean debug) { String response = ""; int dataSize = command.length(); char data; command.toCharArray(data, dataSize); esp8266_Write(data, dataSize); // передача символов на esp8266 if (debug) { Serial.println("\r\n====== HTTP Response From Arduino ======"); Serial.write(data, dataSize); Serial.println("\r\n========================================"); } long int time = millis(); while ((time + timeout) >millis()) ( while (esp8266_Available()) ( // У esp є дані, тому вивести їх у консоль char c = esp8266_Read(); // прочитати наступний символ. response += c; ) ) if (debug) ( Serial .print(response); ) return response; ) /* Name: sendHTTPResponse Description: Функція, яка посилає HTTP 200, HTML UTF-8 відгук */ void sendHTTPResponse(int connectionId, String content) ( // створити HTTP відгук String httpResponse; String httpHeader; // HTTP HTTP/1.1 200 OK\nContent-Type: text/html; charset=UTF-8\n"; httpHeader += "Content-Length: "; httpHeader += content.length(); \r\n"; httpHeader += "Connection: close\r\n\r\n"; httpResponse = httpHeader + content + " "; // Тут у коді баг: останній символ в "content" не посилається, тому я додав додатковий пробіл sendCIPData(connectionId, httpResponse); ) /* Name: sendCIPDATA Description: посилає команду CIPSEND= ,<данные>*/ void sendCIPData(int connectionId, String data) ( String cipSend = "AT+CIPSEND="; cipSend += connectionId; cipSend += ","; cipSend += data.length(); cipSend += "\r\ n"; sendCommand(cipSend, 1000, DEBUG); sendData(data, 1000, DEBUG); ) /* Name: sendCommand Description: Функція, яка використовується для надсилання даних на ESP8266. Params: command – дані/команда для відправки; timeout - час очікування відгуку; debug - друкувати в консоль? (true = так, false = ні) Returns: Відгук від esp8266 (якщо є відгук) */ String sendCommand ) // передача символів на esp8266 long int time = millis();while ((time + timeout) > millis()) ( while (esp8266_Available()) = esp8266_Read(); // прочитати наступний символ. response += c; ) ) if (debug) ( Serial.print(response);

Android додаток

Щоб керувати всіма вище перерахованими апаратними компонентами, ми будемо використовувати простий додаток для Android. Ця програма дозволить нам включати або вимикати вихід безпосередньо або через певний період часу.

Примітка:Програма вимагає Android 4.0 (IceCreamSandwich) або вище.

  • Перш за все, ви повинні знати IP-адресу свого модуля. Якщо ви використовували програмний послідовний порт, IP адреса буде надрукована в консолі. Якщо ви використовували апаратний послідовний порт, то слід використовувати кабель для відстеження даних на лініях RX і TX, щоб побачити IP адресу. Вам також потрібно знати номер порту, який був вказаний у скетчі Arduino. Після цього натисніть "connect", щоб отримати стан усіх трьох виходів. Вам потрібно переконатися, що ваш Wi-Fi роутер увімкнено, і ви підключені до локальної мережі.
  • Тепер натисніть будь-який перемикач, який ви хочете увімкнути/вимкнути. Щоразу, коли захочете, ви можете натиснути "refresh", щоб оновити стан усіх виходів.
  • На вкладці "Timers" можна встановити будь-який з цих трьох виходів для включення/вимкнення через певний проміжок часу (від 0 до 24 годин).
  • Після будь-якої дії ви отримаєте повідомлення з підтвердженням, чи виконалася команда успішно, чи виникла якась помилка.

Демонстраційне відео

От і все! Сподіваюся, стаття виявилася корисною. Залишайте коментарі!

Мікросхема ESP8266 – один із найпопулярніших інструментів для організації бездротового зв'язку у проектах розумного будинку. За допомогою бездротового контролера можна організовувати зв'язок за інтерфейсом WiFi, забезпечуючи проектам Arduino вихід в інтернет та можливість дистанційного керування та збору даних. На основі ESP8266 створені такі популярні плати як WeMos та NodeMcu, а також величезна кількість саморобних проектів. У цій статті, ми дізнаємося, що являє собою ESP82266, які бувають її різновиди, як працювати з ESP8266 в середовищі Arduino IDE.

ESP8266 – мікроконтролер з інтерфейсом WiFi, який може виконувати програми з флеш-пам'яті. Пристрій було випущено в 2014 році китайською фірмою Espressif і практично відразу стало популярним.

Контролер недорогий, має невелику кількість зовнішніх елементів і має такі технічні параметри:

  • Підтримує Wi-Fi протоколи 802.11 b/g/n з WEP, WPA, WPA2;
  • Має 14 портів введення і виведення, SPI, I2C, UART, 10-біт АЦП;
  • Підтримує зовнішню пам'ять до 16 МБ;
  • Необхідне живлення від 2,2 до 3,6 В, споживаний струм до 300 мА залежно від вибраного режиму.

Важливою особливістю є відсутність користувальницької енергонезалежної пам'яті на кристалі. Програма виконується від зовнішнього SPI ПЗУ за допомогою динамічного завантаження необхідних елементів програми. Доступ до внутрішньої периферії можна отримати не з документації, а з набору бібліотек API. Виробником вказується приблизна кількість ОЗП – 50 кБ.

Особливості плати ESP8266:

  • Зручне підключення до комп'ютера через USB кабель, живлення від нього ж;
  • Наявність вбудованого перетворювача напруги 3,3В;
  • Наявність 4 Мб флеш-пам'яті;
  • Вбудовані кнопки для перезавантаження та перепрошивки;
  • Всі порти виведені на плату на два гребінки з кроком 2,5 мм.

Сфери застосування модуля ESP8266

  • Автоматизація;
  • Різні системи для розумного будинку: Бездротове керування, бездротові розетки, керування температурою, доповнення до сигналізаційних систем;
  • Мобільна електроніка;
  • ID мітки;
  • Дитячі іграшки;
  • Mesh-мережі.

Розпинування esp8266

Існує безліч різновидів модуля ESP8266. На малюнку представлені деякі з них. Найбільш популярним варіантом є ESP 01.

Виконання програми потрібно встановити станом портів GPIO0, GPIO2 і GPIO15, коли закінчується подача живлення. Можна виділити 2 важливі режими – коли код виконується з UART (GPIO0 = 0, GPIO2 = 1 та GPIO15 = 0) для перепрошивки флеш-карти і коли виконується із зовнішньої ПЗУ (GPIO0 = 1, GPIO2 = 1 та GPIO15 = 0) у штатному режимі.

Розпинування для ESP01 зображено на зображенні.

Опис контактів:

  • 1 – земля, 8 – харчування. По документації напруга подається до 3,6 У – це важливо врахувати під час роботи з Ардуїно, яку зазвичай подають 5 У.
  • 6 - RST, необхідна для перезавантаження мікроконтролера при подачі на нього низького логічного рівня.
  • 4 – CP_PD, також використовується для переведення пристрою в режим енергозбереження.
  • 7 та 0 – RXD0 та TXD0, це апаратний UART, необхідний для перепрошивки модуля.
  • 2 – TXD0, до цього контакту підключається світлодіод, який загоряється за низького логічного рівня на GPIO1 і передачі даних по UART.
  • 5 – GPIO0, порт введення та виведення, також дозволяє перевести пристрій у режим програмування (при підключенні порту до низького логічного рівня та подачі напруги) .
  • 3 – GPIO2, порт введення та виведення.

Розпинування ESP-12

Основні відмінності Ардуїно від ESP8266

  • ESP8266 має більший обсяг флеш-пам'яті, при цьому ESP8266 відсутня енергонезалежна пам'ять;
  • Процесор ESP8266 швидше, ніж у Ардуїно;
  • Наявність Wi-Fi у ESP8266;
  • ESP8266 споживає більше струму, ніж для Ардуїно;

Програмування ESP8266 в Arduino IDE

Програмний комплект розробника esp8266 включає:

  • Компілятор із пакету GNU Compiler Collection.
  • Бібліотеки, стеки протоколів WiFi, TCP/IP.
  • Засіб завантаження інформації у програму контролера.
  • Операційна IDE.

Спочатку модулі ESP8266 поставляються із прошивкою від фірми-виробника. З її допомогою можна керувати модулем із зовнішнього мікроконтролера, реалізовувати роботу з Wi-Fi як з модемом. Також існує багато інших готових прошивок. Деякі з них дозволяють настроювати роботу модуля за допомогою WEB-інтерфейсу.

Можна програмувати із середовища Arduino IDE. За її допомогою можна легко писати скетчі та завантажувати їх у ESP8266, прошивати ESP8266, при цьому не потрібно сама плата Ардуїно. Arduino IDE підтримує усі види модулів ESP8266.

На даний момент для ESP8266 можна реалізувати такі функції:

  • Основні функції мови Wiring. Керувати портами GPIO можна так само, як і пінами на платі Ардуїно: pinMode, digitalRead, digitalWrite, analogWrite. Команда analogRead(А0) дозволяє вважати значення АЦП. За допомогою команди analogWrite (pin, value) можна підключити ШІМ на потрібному виході GPIO. При value=0 ШІМ відключається, максимальне значення досягає константи, що дорівнює 1023. За допомогою функцій attachInterrupt, detachInterrupt можна виконувати переривання на будь-якому порту GPIO, крім 16.
  • Таймінг та delay. Використовуючи команди millis та micros можна повернути мс та мкс, які пройшли з моменту старту. Delay дозволяє призупинити виконання програми на потрібний час. Також функція delay(…) дозволяє підтримувати нормальну роботу Wi-Fi, якщо у скетчі є великі елементи, які виконуються більше 50 мс. Yield() – аналог функції delay(0).
  • Serial та Serial1 (UART0 та UART1). Робота Serial на ESP8266 аналогічна роботі на Ардуїно. Запис та читання даних блокують виконання коду, якщо FIFO на 128 байт та програмний буфер на 256 байт заповнені. Об'єкт Serial користується апаратним UART0, для нього можна встановити піни GPIO15 (TX) і GPIO13 (RX) замість GPIO1 (TX) і GPIO3 (RX). Для цього після функції Serial.begin(); потрібно викликати Serial.swap();. Аналогічно Serial1 використовує UART1, котрий працює на передачу. Необхідний пін для цього GPIO2.
  • Макрос PROGMEM. Його робота аналогічна роботі в Ардуїно. Дозволяє переміщати дані read only і рядкові незмінні у flash-пам'ять. При цьому ESP8266 не зберігаються однакові константи, що призводить до додаткової витрати флеш-пам'яті.
  • I2C. Перед початком роботи із шиною I2C вибираються шини з допомогою функції Wire.pins(int sda, int scl).
  • SPI, OneWire – повністю підтримуються.

Використання esp8266 для зв'язку Ардуїно WiFi

Перед підключенням до Ардуїно важливо пам'ятати, що у ESP8266 напруга живлення не може бути вищою за 3,6, у той час як на паті Ардуїно напруга дорівнює 5 В. З'єднувати 2 мікроконтролери потрібно за допомогою резистивних дільників. Перед підключенням модуля потрібно ознайомитися з розпинанням обраного ESP8266. Схема підключення для ESP8266-01 представлена ​​малюнку.

3,3 В з Ардуїно – на Vcc&CH_PD на модулі ESP8266, Земля з Ардуїно – до землі з ESP8266, 0 – TX, 1 – RX.

Для підтримки стабільної роботи ESP8266 необхідне джерело постійної напруги на 3,3 В та максимальний струм 250 мА. Якщо живлення походить від USB-TTL-конвертера, можуть виникати проблеми та збої в роботі.

Робота з бібліотекою Wi-Fi для ESP8266 схожа на бібліотеку для звичайного шилда. Є кілька особливостей:

  • mode(m) – вибір одного з трьох режимів: клієнт, точка доступу або обидва режими одноразово.
  • softAP(ssid) – необхідний створення відкритої точки доступу.
  • softAP(ssid, password) – створює точку доступу з паролем, який має складатися не менше ніж із 8 знаків.
  • WiFi.macAddress(mac) та WiFi.softAPmacAddress(mac) – визначає МАС адресу.
  • WiFi.localIP() та WiFi.softAPIP() – визначення IP адреси.
  • printDiag(Serial); – дозволять дізнатись дані про діагностику.
  • WiFiUDP – підтримка передачі та прийому multicast пакета в режимі клієнта.

Робота виконується за таким алгоритмом:

  • Підключення USB-TTL до USB та ESP.
  • Запустити Arduino IDE.
  • Вибрати в меню інструменти потрібний порт, плату, частоту та розмір flash-пам'яті.
  • Файл - Прімери - ESP8266WiFi - WiFiWebServer.
  • Записати в скетчі SSID та пароль мережі Wi-Fi.
  • Почати компіляцію та завантаження коду.
  • Дочекайтеся закінчення процесу прошивки, від'єднайте GPIO0 від землі.
  • Поставити швидкість 115 200.
  • З'явиться підключення, буде записано IP-адресу.
  • Відкрити браузер, ввести в адресному рядку номер IP/gpio/1
  • Переглянути монітор порту, якщо до виходу GPIO2 підключено світлодіод, він повинен спалахнути.

NodeMCU на базі esp8266

NodeMCU – це платформа, що базується на базі модуля esp8266. Використовується для керування схемою на відстані за допомогою інтернету через Wi-Fi. Плата малогабаритна, компактна, коштує дешево, на лицьовій стороні є роз'єм для USB. Поруч кнопки для налагодження та перезавантаження мікроконтролера. Також встановлений чіп ESP8266. Напруга живлення – від 5 до 12, бажано подавати більше 10 В.

Великою перевагою плати є її мале енергоспоживання. Нерідко їх використовують у схемах з автономним харчуванням. На платі розташовано лише 11 портів загального призначення, з них деякі мають спеціальні функції:

  • D1 та D2 – для інтерфейсу I2C/TWI;
  • D5-D8-для інтерфейсу SPI;
  • D9, D10 – для UART;
  • D1-D10 – можуть працювати як ШІМ.

Платформа має сучасне API для апаратного введення та виведення. Це дозволяє скоротити кількість дій під час роботи з обладнанням та при його налаштуванні. За допомогою прошивки NodeMCU можна використовувати весь робочий потенціал для швидкої розробки пристрою.

WeMos на базі esp8266

WeMos – ще один вид платформи, що базується на базі мікроконтролера esp8266. Відповідно є Wi-Fi модуль, підтримується Arduino IDE, є роз'єм для зовнішньої антени. Плата має 11 цифрових входів/виходів, які (крім D0) підтримують interrupt/pwm/I2C/one-wire. Максимальна напруга живлення досягає 3,3 В. Також на платформі є USB роз'єм. Аналоговий вхід 1 з максимальною напругою 3,2В.

Для роботи з модулем потрібно встановити драйвер CH340 та налаштувати Ардуїно IDE під ESP8266. Для цього потрібно в меню налаштування у рядку «додаткове посилання для менеджера плат» додати адресу http://arduino.esp8266.com/stable/package_esp8266com_index.json.

Після цього потрібно знайти пакет ESP8266 і встановити його. Потім потрібно вибрати в меню інструменти мікроконтролер Wemos D1 R2 та записати потрібний скетч.

Висновки по ESP8266

За допомогою плат на основі мікросхеми ESP8266 ви можете додати у свої проекти можливості великого інтернету, зробивши їх набагато інтелектуальнішими. Дистанційне керування, збирання та аналіз даних на сервері, обробка голосу та робота із зображенням – все це стає доступним, коли ми підключаємо наш проект по WiFi до інтернету. У наступних статтях ми докладно розглянемо, як можна програмувати пристрої на базі esp8266, а також приділимо увагу таким популярним платам як WeMos та NodeMcu.