Электронный замок с беспроводным управлением на базе Energia Launchpad

ccb216e079574ef4b9fdf915df891ce9.JPGГлядя на множество хабро-статей на базе Arduino мне показалось несколько странным отсутствие интересных беспроводных решений из мира Energia Launchpad. Пора исправить эту вселенскую несправедливость! Сегодня я познакомлю вас с отладочной платой CC3200-launchpad, расскажу об ее преимуществах перед ESP8266, подключу к ней пару launchpad по радиоканалу и буду щелкать большими советскими релюхами. Поехали!

CC3200-LAUNCHXL Ланчпад с большой буквыСегодняшний рассказ я начну с микроконтроллера CC3200[1] от Texas Instruments.Этот контроллер представляет собой симбиоз ядра TIVA-C Cortex-M4 и Simplelink Wi-Fi процессора CC3100 в одном корпусе43880eea45ed45568f802943b5730e2d.jpgРисунок 1: Структурная схема контроллера

Немного о приятных и интересных свойствах данного камня, применимо к встраиваемым микромощным решениям[2]:

80МГц ядро Cortex-M4; ОЗУ 256Кбайт; Драйвера периферии в ПЗУ, отсутствует встроенная Flash память программ; Поддержка внешней микросхемы Serial Flash памяти — вешай сколько хочется; Аппаратное шифрование AES, DES, SHA2, MD5, CRC; 2xI2S, 1xSD-card, 2xUART, 1xSPI, 1×2C, 8-разрядный интерфейс камеры; 4 таймера с 16-бит ШИМ; 4 канала 12-разрядного АЦП Сертифицированный 802.11g/b/n Wi-Fi модуль с поддержкой шифрования WEP, WPA2-PSK и WPA-Enterprise. Работа как в режиме устройства, так и в режиме хоста 256-bit AES для SSLv3 и TSLv1. Да-да, он тащит SSL! Микромощное потребление и множество режимов управления питанием CC3200 vs ESP8266 С одной стороны ESP8266 обладает следующими преимуществами: Во-первых, он очень маленький и интегрированный — хренька размером и стоимостью с монетку требует лишь пару батареек питания и ее уже можно втыкать в утюг или чайник.Во-вторых, у него хорошо проработаны режимы питания — если подойти с умом, то получается диетический продукт.В-третьих, у него простой старт — достаточно подключить его к компьютеру, открыть среду Arduino и можно работать.С другой стороны, CC3200 — мощный процессор, способный держать в себе множество активных задач. Кроме того, у него намного более богатая периферия — хочешь — подключай камеру, хочешь аудиоустройства (по I2S) или SD-карту. Хочешь — еще с десяток всякой всячины навешай — выдержит и железо и прошивка. Ну и конечно же SSL. Здесь мой маленький параноик просто ликует от счастья.Но тут же просыпается жаба и начинает душить вашего покорного слугу — ланчпад у производителя стоит 30 баксов/штука. В РФ есть шанс купить за 40–50 долларов+доставка. Бесплатная доставка у TI кончилась.

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

CC3200-LAUNCHXL Быстрый старт[3] f373577580f64b97b379ba732cced149.jpgРисунок 2: комплектацияКак и подобается любому ланчпаду, CC3200 приходит в аккуратной картонной коробке с базовой комплектацией — сама плата, шнур micro-USB, пара джамперов и пара буклетов.Плата — типичный представитель 40-контактных launchpad, несет на себе сам контроллер CC3200 в 64-ногом корпусе QFN. Не самый страшный корпус для ручной пайки. Также, на плате имеется программатор на базе FT2232 чипа (официальная поддержка openOCD). Микросхема Flash памяти на 8Мбит данных.Отдельно стоит упомянуть трехосевой ±16G акселерометр BMA222[4] и бесконтактный ИК датчик температуры TMP006[5]

23321483689443d7a2aedad3631add49.jpgРисунок 3: ланчпад в деталях

Одним словом — все что нужно растущему разработчику IoT.

Подключим плату к питанию изучим имеющуюся на нем демо-прошивку.Прошивка предлагает немного датащитов, и 4 микродемки. И все это в режиме точки доступа, с http сервером на борту.Дабы не быть многословным, небольшой видеообзор:

[embedded content]

CC3200 SDK[6] С помощью CCS UniFlash[7] обновим наш SDK.19d9232901a14e90958753cf635246bf.jpgРисунок 4: CCS UniFlash внешний вид

Для начала, плату необходимо перевести в режим программирования Flash, для чего замкнуть пины 2 разъема SOP. После этого, подключаемся к UART порту, форматируем Flash память по объем 1Мбайт. После чего указываем путь к нашему ServicePack. на момент написания статьи актуальный Service Pack: 1.0.0.10.0, SDK: 1.1.0.

Программирование в среде Code Composer Studio 6.0.1[8] Для больших проектов и нормальной отладки идеальным вариантом является разработка программ в среде Code Composer Studio (хозяйке на заметку — CCS6 бесплатен для любого применения при использовании компилятора GCC). Производитель поддерживает также и IAR.Установка и настройка CCS IDE Первым делом, сконфигурируем джамперы как указано на рисунке: 97a3e89dbf074ff58fac99870971a1c3.jpgРисунок 5: установка джамперов для программирования в среде CCS

Кроме того, устанавливая Code Composer Studio не забудем выставить галочку возле соответствующего пакета:

9a322b74c2384e75a12f30b1a119ebeb.jpgРисунок 6: установка CCS с поддержкой CC3200

Любителям TI-RTOS[9] рекомендую после установки в магазине расширений установить пакет TI-RTOS for SImplelink

422def6a34504b8d817244e64add68f5.jpgРисунок 7: установка TI-RTOS для CC3100&CC3200

Импортируем один из демо-проектов. Я выбрал HTTP server[10].Наша задача — добавить таргет для подключения к плате. Для этого заходим в пункт меню View→Target Configurations, импортируем файл C:\TI\CC3200SDK_1.1.0\cc3200-sdk\tools\ccs_patch\cc3200.ccxml и после этого, в его контекстном меню указываем, что он будет использоваться по умолчанию.f81a86789f724c6da10eefdf45d644de.jpgРисунок 7: настройка дебаг-интерфейса

Жмем F11 для запуска Debug-режима, потом F8 для запуска программы и лезем в приложение Wi-Fi Starter для Android[11] или iOS[12]

Wi-Fi Starter Указав название точки доступа и пароль к ней, нажимаем кнопку старт50c5aa346fc74afc97ad888846d0d9f9.jpgРисунок 8: Поиск и настройка устройств

Как только устройство будет найдено, оно отобразится во вкладке Devices07dbc156420f4d59a98abc16e83ea0dc.jpgРисунок 9: Список подключенных устройствтапаем по нему и попадаем на страничку в браузере, которая говорит о том, что все работает. там же можно перенастроить данные для Wi-Fi подключения и перевести устройство в режим точки доступа.

b1fc10f90e204d92a6d27cc0657b20ae.jpgРисунок 10: Демо-приложение

Дальше мы можем лезть куда нам надо и не надо и писать свои приложения.Создание электронного замка Перейдем уже наконец к практике! Давайте сделаем электронный замок с датчиком открывания двери и радиобрелком для управления, и чтобы при несанкционированном доступе мне приходила СМС неприличного содержания.Для этого нам понадобится: CC3200 launchpad в роли Wi-Fi шлюза TIVA-C launchpad[13] в роли платы управления электронным замком MSP430F5529[14] launchpad в роли платы радиобрелока и три штуки радиомодулей Anaren CC110L boosterpack в роли радиомодулей[15]. Принцип действия следующий: Исполнительный механизм снабжен двухпозиционным соленоидом и датчиком периметра. В нашем случае роль соленоида будет исполнять двухпозиционное советское реле РП-12[16], а роль датчика периметра фотореле РФ-8300, столь знакомое сердцу посетителя советского метро (ни один турникет не пострадал). Логика работы следующая: С помощью радиокоманды можно выставить либо дежурный режим, либо режим охраны. В режиме охраны соленоид «запирает» дверь, и срабатывание датчика приведет к тревоге. Переход в дежурный режим отпирает дверь. Статус регулярно передается на Wi-Fi шлюз через радиоканал.Брелок имеет две кнопки — поставить на охрану/снять с охраны. Передача команд осуществляется непосредственного на исполнительное устройство. тип передачи данных UDP, т.е. без подтверждения приема пакета (губа треснет). Данные передаем без шифрования по той же причине. Исполнительное устройство передает свое состояние на wi-fi шлюз. В случае тревоги Wi-Fi шлюз инициирует передачу SMS.

Зафиксируем команды:

enum {IDLE=0×01, ACTIVE, ALERT}; Программирование в среде Energia[17] Для поклонников Arduino применимо к launchpad существует замечательный форк в виде среды программирования Energia. Он активно поддерживается сообществом: 84b072b1fdcb4637a92cd2afafd8ead4.jpgРисунок 11: Список плат, поддерживаемых версией Energia-15

Для того, чтобы CC3200 можно было запрограммировать из Energia, необходимо сделать маленький хак — верхний пин TCK соединить с нижним пином SOP-2:

e65bc44a3e6b4332af43376e2e189343.jpgРисунок 12: Подключение режима автопрограммирования

Брелок Здесь все просто. Нажали кнопку 1 — передали на механизм команду «ACTIVE».нажали кнопку 2 — передали на механизм команду «IDLE».Накопипастим из примеров простенькую программку:

Листинг программы для брелка #include #include

//define addresses. #define ADDRESS_LOCAL 0×02 #define ADDRESS_REMOTE 0×03

//FSM states. And commands enum { IDLE=0×01, ACTIVE, ALERT};

unsigned char txData[60] = { »\0» };

const int setButton = PUSH1; //set to active mode const int releaseButton = PUSH2;//set to idle mode const int ledPin = GREEN_LED; const int redPin = RED_LED;

void setup () { //define pinouts and add serial outputr pinMode (ledPin, OUTPUT); pinMode (redPin, OUTPUT); Serial.begin (9600);

pinMode (setButton, INPUT_PULLUP); pinMode (releaseButton, INPUT_PULLUP); Radio.begin (ADDRESS_LOCAL, CHANNEL_1, POWER_MAX); Serial.println («RF start»); txData[0] = ADDRESS_LOCAL;//set zer0 byte as our address }

void loop (){ //check set button if (digitalRead (setButton) == LOW){ //if button is pressed, send command Serial.println («Active mode»); digitalWrite (redPin, HIGH); txData[1] = ACTIVE;//Set command txData[2] = 0×00; Radio.transmit (ADDRESS_REMOTE, (unsigned char*)&txData, 2); } else{ digitalWrite (redPin, LOW); } //check release button if (digitalRead (releaseButton) == LOW){ Serial.println («IDLE mode»); digitalWrite (ledPin, HIGH); txData[1] = IDLE;//Set command txData[2] = 0×00; //send packet Radio.transmit (ADDRESS_REMOTE, (unsigned char*)&txData, 2); } else{ digitalWrite (ledPin, LOW); } sleepSeconds (1);//Low-power mode delay delay (50);//to Clock stabilization } Исполнительный механизм Задача исполнительного механизма — управлять двустабильным соленоидом. У такого соленоида имеется две обмотки, подавая напряжение на одну обмотку мы втягиваем сердечник, на другую — отпускаем. Постоянно держать напряжение на обмотках не требуется. Наше реле РП-12 немного не такое — у него обмотка одна, а выбор действия определяется полярностью. Обойдемся парой диодов.Подключать будем через симисторы MOC3052 по следующей схеме:

6d43cb17e3ab4f1a91a93b5700e7698d.jpgРисунок 13: Схема подключения симистора.

У меня в загашниках нашлась платка с двумя симисторами, так что не пришлось городить макетку.Датчик контроля периметра на фотореле РФ-8300 работает автономно, группой замыкающих контактов подавая сигнал на актуатор.

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

Получив от брелка команду, выполняем ее, и дублируем на wi-Fi шлюз.Копипастим программку: Листинг программы для актуатора #include #include

#define ADDRESS_LOCAL 0×03 #define ADDRESS_REMOTE 0×01

unsigned char rxData[60] = { »\0» }; unsigned char txData[60] = { »\0» }; /* Finite state machine: 1. IDLE mode 2. Action Mode 3. Alert mode 1 → 2 Received command 0×01 2 → 1 received command 0×02 2 → 3 sensor triggered. Send alert */ enum {IDLE=0×01, ACTIVE, ALERT}; unsigned int fsm = IDLE;

static unsigned char sensor = 11; static unsigned char releopen = 9; static unsigned char releclose = 10; static unsigned char releopenled = BLUE_LED; static unsigned char relecloseled = GREEN_LED;

// ----------------------------------------------------------------------------- // Main example

void setup () { pinMode (sensor, INPUT_PULLUP); pinMode (releopen, OUTPUT); digitalWrite (releopen, HIGH); pinMode (releopenled, OUTPUT); pinMode (relecloseled, OUTPUT); pinMode (releclose, OUTPUT); digitalWrite (releclose, HIGH); pinMode (12, OUTPUT); pinMode (12, LOW); //return pin for sensor Radio.begin (ADDRESS_LOCAL, CHANNEL_1, POWER_MAX);

// Setup serial for debug printing. Serial.begin (9600); txData[0] = ADDRESS_LOCAL;//set zer byte as our address } uint8_t length = 0;

void loop () { switch (fsm){ case IDLE: length = Radio.receiverOn (rxData, sizeof (rxData), 1000); if (length > 0){ if (rxData[1] == ACTIVE){ //change state stage fsm = ACTIVE; txData[1] = ACTIVE;//Set command txData[2] = 0×00; Radio.transmit (ADDRESS_REMOTE, (unsigned char*)&txData, 2); //send 500ms inpuls to actuator digitalWrite (releclose, LOW); digitalWrite (relecloseled, HIGH); delay (500); digitalWrite (releclose, HIGH); digitalWrite (relecloseled, LOW); } else{ fsm = IDLE; } } else{ } break; case ACTIVE: length = Radio.receiverOn (rxData, sizeof (rxData), 100); if (length > 0){ if (rxData[1] == IDLE){ //change state stage fsm = IDLE; txData[1] = IDLE;//Set command txData[2] = 0×00; Radio.transmit (ADDRESS_REMOTE, (unsigned char*)&txData, 2); //send 500ms inpuls to actuator digitalWrite (releopen, LOW); digitalWrite (releopenled, HIGH); delay (500); digitalWrite (releopen, HIGH); digitalWrite (releopenled, LOW); } else{ fsm = ACTIVE; } } else{ } checkperimeter (); break; case ALERT: length = Radio.receiverOn (rxData, sizeof (rxData), 1000); if (length > 0){ if (rxData[1] == IDLE){ //change state stage fsm = IDLE; txData[1] = IDLE;//Set command txData[2] = 0×00; Radio.transmit (ADDRESS_REMOTE, (unsigned char*)&txData, 2); //send 500ms inpuls to actuator digitalWrite (releopen, LOW); digitalWrite (releopenled, HIGH); delay (500); digitalWrite (releopen, HIGH); digitalWrite (releopenled, LOW); } else{ fsm = ALERT; } } else{ } break; default: break; }

}

void checkperimeter (){ uint8_t sensorstate = digitalRead (sensor); if (sensorstate == LOW){ Serial.println («Alert!»); //alert! fsm = ALERT; txData[1] = ALERT;//Set command txData[2] = 0×00; Radio.transmit (ADDRESS_REMOTE, (unsigned char*)&txData, 2); } } Шлюз Задача шлюза не сложнее — дублировать светодиодами состояние системы (для теста) и в случае тревоги отправить сообщение на телефон.Temboo+NEXMO Но для начала подготовим API-почву. Для этого регистрируемся на сервисах Temboo[18] и Nexmo[19]. В задачи Nexmo входит подключение к любому мобильному телефону в любой точке мира. При регистрации дают стартовые 2 Евро, которых вполне достаточно, чтобы опробовать этот сервис.В задачи Temboo будет входить организация связи между нашим устройством и сервисом Nexmo. Здесь для старта дается 250 запросов, которые можно бесплатно расширить на добрый десяток тысяч, приглашая друзей. Что до тарифов — смски мне обошлись в 2 евроцента за штуку.

В списке возможных API выбираем Nexmoo.SMS.TextMessage.

Выбираем нашу плату — CC3200 и указываем параметры Wi-Fi подключения

5b09d37cffb14c809b2e4f3d862167eb.jpgРисунок 14: Настройка Wi-Fi

Указываем параметры подключения. От нас требуют указать API ключи от нашего аккаунта Nexmoo, номер телефона отправителя, который привязан к нашему аккаунту, номер телефона получателя и текстовое сообщение.

3f9d999db153474dbe5d19e19841f30d.jpgРисунок 15: Выбор получателя и настройка сообщения

Нажатием на кнопку Run можно проверить что все работает.Копипастим код из блоков и «докопипасчиваем» ему поддержку режимов работы:

Листинг кода Wi-Fi шлюза #include #include #include #include #include #include «TembooAccount.h» // Contains Temboo account information

WiFiClient client;

#define ADDRESS_LOCAL 0×01

unsigned char rxData[60] = { »\0» };

unsigned char txData[60] = { »\0» }; /* Finite state machine: 1. IDLE mode 2. Action Mode 3. Alert mode 1 → 2 Received command 0×01 2 → 1 received command 0×02 2 → 3 sensor triggered. Send alert */ enum { IDLE=0×01, ACTIVE, ALERT}; unsigned int fsm = IDLE;

// ----------------------------------------------------------------------------- // Main example

void setup () { pinMode (GREEN_LED, OUTPUT); pinMode (RED_LED, OUTPUT); pinMode (YELLOW_LED, OUTPUT); digitalWrite (YELLOW_LED, LOW); digitalWrite (RED_LED, LOW); digitalWrite (GREEN_LED, LOW);

Radio.begin (ADDRESS_LOCAL, CHANNEL_1, POWER_MAX);

// Setup serial for debug printing. txData[0] = ADDRESS_LOCAL;//set zer byte as our address

Serial.begin (9600);

int wifiStatus = WL_IDLE_STATUS;

// Determine if the WiFi Shield is present Serial.print (»\n\nShield:»); if (WiFi.status () == WL_NO_SHIELD) { Serial.println («FAIL»);

// If there’s no WiFi shield, stop here while (true); }

Serial.println («OK»);

// Try to connect to the local WiFi network while (wifiStatus!= WL_CONNECTED) { Serial.print («WiFi:»); wifiStatus = WiFi.begin (WIFI_SSID, WPA_PASSWORD);

if (wifiStatus == WL_CONNECTED) { Serial.println («OK»); } else { Serial.println («FAIL»); } delay (5000); } digitalWrite (YELLOW_LED, HIGH); Serial.println («Setup complete.\n»); } uint8_t length = 0;

void loop () { length = Radio.receiverOn (rxData, sizeof (rxData), 1000); if (length > 0){ Serial.print («Get state:»); Serial.println (rxData[1], DEC);

switch (fsm){ case IDLE: if (rxData[1] == ACTIVE){ fsm = ACTIVE; digitalWrite (GREEN_LED, HIGH); } break;

case ACTIVE: if (rxData[1] == IDLE){ fsm = IDLE; digitalWrite (GREEN_LED, LOW); digitalWrite (RED_LED, LOW); } if (rxData[1] == ALERT){ fsm = ALERT; digitalWrite (RED_LED, HIGH); sendmessage (); } break;

case ALERT: if (rxData[1] == IDLE){ fsm = IDLE; digitalWrite (GREEN_LED, LOW); digitalWrite (RED_LED, LOW); } break; } } }

void sendmessage (){ Serial.println («Running SendMessage — Run #» + String (numRuns++));

TembooChoreo SendMessageChoreo (client);

// Invoke the Temboo client SendMessageChoreo.begin ();

// Set Temboo account credentials SendMessageChoreo.setAccountName (TEMBOO_ACCOUNT); SendMessageChoreo.setAppKeyName (TEMBOO_APP_KEY_NAME); SendMessageChoreo.setAppKey (TEMBOO_APP_KEY);

// Set Choreo inputs String TextValue = «Testing! Testing! 1, 2, 3»; SendMessageChoreo.addInput («Text», TextValue); String APIKeyValue = »000»; SendMessageChoreo.addInput («APIKey», APIKeyValue); String ToValue = »000»; SendMessageChoreo.addInput («To», ToValue); String APISecretValue = »000»; SendMessageChoreo.addInput («APISecret», APISecretValue); String FromValue = »000»; SendMessageChoreo.addInput («From», FromValue);

// Identify the Choreo to run SendMessageChoreo.setChoreo (»/Library/Nexmo/SMS/SendMessage»);

// Run the Choreo; when results are available, print them to serial SendMessageChoreo.run ();

while (SendMessageChoreo.available ()) { char c = SendMessageChoreo.read (); Serial.print©; } SendMessageChoreo.close (); } Компилируем, тыкаем кнопочки и убеждаемся, что все работает.Демонстрация Наглядная демонстрация с большими релюшками:[embedded content]

Подведу итоги — отладочная плата CC3200 — весьма приятная железка имеющая свою нишу для применений. Показанное здесь демо сделано по принципу «слепила из того что было» и призвано показать часть возможностей плат Energia lauchpad. В планах — в подробностях рассказать об особенностях подключения датчиков и исполнительных механизмов с учетом надежности и устойчивости к электромагнитным помехам.

Исходный код проекта доступен в репозитории[20].

Полезные ссылки: 1. CC3200 Product Brief http://www.ti.com/product/cc32002. CC3200 Datasheet http://www.ti.com/lit/ds/symlink/cc3200.pdf3. CC3200-LAUNCHXL User Guide http://www.ti.com/lit/ug/swru372b/swru372b.pdf4. BMA222 Accelerometer Datasheet https://ae-bst.resource.bosch.com/media/products/dokumente/bma222/bst-bma222-ds002–05.pdf5. TMP006 IR Thermopile Sensor Datasheet http://www.ti.com/lit/ds/sbos518e/sbos518e.pdf6. CC3200 SDK http://www.ti.com/tool/cc3200sdk7. CCS UniFlash http://www.ti.com/tool/uniflash8. Code Composer Studio 6 IDE http://www.ti.com/tool/ccstudio9. TI-RTOS http://www.ti.com/tool/TI-RTOS10. CC3200 HTTP server User Guide http://processors.wiki.ti.com/index.php/CC32xx_HTTP_Server11. Wi-Fi Starter App for Android https://play.google.com/store/apps/details? id=com.pandaos.smartconfig12. Wi-Fi Starter App for iOS https://itunes.apple.com/us/app/texas-instruments-simplelink/id884122493? ls=1&mt=813. TIVA-C launchpad http://www.ti.com/tool/ek-tm4c123gxl14. MSP430F5529 launchpad http://www.ti.com/tool/msp-exp430f5529lp15. CC110L Air Module Boosterpack https://www.anaren.com/air/cc110l-air-module-boosterpack-embedded-antenna-module-anaren16, Реле РП-12. Описание: http://www.cheaz.ru/ru/production/ustroystva-releynoy-zashchity/rele-promezhutochnye-dvukhpozitsionnye-rp-8–9–11–1217. Energia IDE http://energia.nu/18. Temboo https://temboo.com/19. Nexmo https://www.nexmo.com/20. Electronic Lock GitHub repo https://github.com/radiolok/electronic_lock_energia

© Habrahabr.ru