Мини-кейс 1: Переключатель

Переключатель светодиода, переключатель реле.

Создание мини-проекта

Сделаем мини-проект с модулем светодода, который управляется через интерфейс RainMaker.

  1. Нужно собрать устройство. К GPIO 16 подключить светодиод или светодиодный модуль Troyka. Распиновка платы на родительской странице "О ESP32". Питание для него от пина 3.3v.

  2. Создаём новый файл в Arduino IDE с кодом:

    #include <RMaker.h>
    #include <WiFi.h>
    #include <WiFiProv.h>
    
    #define SERVICE_NAME "PROV_1" // Имя устройства при подключении по bluetooth, нужно для настройки, когда плата ещё не настроена на WI-FI точку
    #define POP "abcd1" // ? Пароль для устройства при подключении по bluetooth
    
    #define BOOT_BTN_PIN 0 // GPIO пин кнопки BOOT
    
    #define LED_BUILTIN 2 // Определить GPIO пин встроенного светодиода
    #define BOARD_LED_DEFAULT_STATE false // Состояние встроенного светодиода при старте
    
    #define LED_PIN 16 // GPIO пин для модуля с светодиодом
    #define LED_DEFAULT_STATE false // Состояние светодиода при старте
    
    #define DEFAULT_LED_BRIGHTNESS 128 // Значение слайдера для LED по умолчанию
    
    int led_gpio = LED_PIN; // Переменная вашего светодиода
    bool board_led_state = BOARD_LED_DEFAULT_STATE; // Переменная для хранения состояния встроенного светодиода
    bool led_state = LED_DEFAULT_STATE; // Переменная для хранения состояния вашего светодиода
    int led_brightness = DEFAULT_LED_BRIGHTNESS; // Значение яркости вашего светодиода
    
    // Фреймворк предоставляет некоторые стандартные типы устройств, такие как выключатель, лампочка, вентилятор, датчик температуры.
    // Но вы также можете определить пользовательские устройства, используя объект базового класса 'Device', как показано здесь
    Device my_device("Swither", ESP_RMAKER_DEVICE_SWITCH, &led_gpio);
    
    void sysProvEvent(arduino_event_t *sys_event)
    {
        switch (sys_event->event_id) {      
            case ARDUINO_EVENT_PROV_START:
              // Для ESP32
              Serial.printf("\nProvisioning Started with name \"%s\" and PoP \"%s\" on BLE\n", SERVICE_NAME, POP);
              printQR(SERVICE_NAME, POP, "ble");   
              // Для ESP32S2
              //Serial.printf("\nProvisioning Started with name \"%s\" and PoP \"%s\" on SoftAP\n", service_name, pop);
              //printQR(service_name, pop, "softap");   
              break;
        }
    }
    
    // Функция обработки изменений
    void write_callback(Device *device, Param *param, const param_val_t val, void *priv_data, write_ctx_t *ctx)
    {
        const char *device_name = device->getDeviceName();
        const char *param_name = param->getParamName();
        
        if(strcmp(param_name, ESP_RMAKER_DEF_POWER_NAME) == 0) { // Если параметр с именем Power
          led_state = val.val.b; // Записываем значение состояния вашего светодиода в переменную, обратите внимание, что b - это тип bool
          Serial.printf("Received param %s = %s for %s\n", param_name, (led_state? "true" : "false"), device_name);
          if (!led_state) {
            analogWrite(LED_PIN, 0); // Выключаем светодиод
            //digitalWrite(LED_PIN, LOW); // Такую запись использовать нельзя - не работает!
          } else analogWrite(LED_PIN, led_brightness); // Включаем светодиод на яркость с переменной
          param->updateAndReport(val);
        } else if (strcmp(param_name, ESP_RMAKER_DEF_BRIGHTNESS_NAME) == 0) { // Если параметр с именем Brightness
          led_brightness = val.val.i; // Записываем значение яркости вашего светодиода в переменную, i - это тип int
          if (led_state) { // Если тумблер светодиода вкл, тогда установим новую яркость
            analogWrite(LED_PIN, led_brightness); // Устанавливаем новую яркость светодиода с переменной
            if (led_brightness == 0) { // На слайдере установлено 0
              led_state = false; // Установить переменную состояния светодиода на выключен
              my_device.updateAndReportParam(ESP_RMAKER_DEF_POWER_NAME, false); // Изменяем состояние тумблера на выкл в RainMaker
              Serial.printf("Toggle State to false.\n");
            }
          }
          Serial.printf("Received param %s = %d for %s\n", param_name, led_brightness, device_name);
          param->updateAndReport(val);
        }
    }
    
    void setup()
    {
        Serial.begin(115200); // Инициализируем скорость Serial
        pinMode(BOOT_BTN_PIN, INPUT); // Настраиваем пин кнопки BOOT на INPUT
        pinMode(LED_BUILTIN, OUTPUT); // Настраиваем пин встроенного светодиода в плате
        pinMode(LED_PIN, OUTPUT); // Настроиваем пин светодида на OUTPUT
        digitalWrite(LED_BUILTIN, BOARD_LED_DEFAULT_STATE); // Светодиод при запуске примет значение BOARD_LED_DEFAULT_STATE
        digitalWrite(LED_PIN, LED_DEFAULT_STATE); // Светодиод при запуске примет значение LED_DEFAULT_STATE
        
        Node my_node; // Объявляем Node
        my_node = RMaker.initNode("ESP RainMaker Node"); // Инициализируем Node
    
        // Создаём устройство для управления светодиодом
        my_device.addNameParam(); // Устнаваливаем имя устройства
        my_device.addPowerParam(LED_DEFAULT_STATE); // Устанавливаем стандатное значение
        my_device.assignPrimaryParam(my_device.getParamByName(ESP_RMAKER_DEF_POWER_NAME)); // Устанавливаем имя параметра Power
    
        // Создаём и добавляем слайдер
        Param brightness_param(ESP_RMAKER_DEF_BRIGHTNESS_NAME, ESP_RMAKER_PARAM_SPEED, value(DEFAULT_LED_BRIGHTNESS), PROP_FLAG_READ | PROP_FLAG_WRITE); // Первым аргументом указывается название создаваемого параметра
        brightness_param.addBounds(value(0), value(255), value(1)); // Значение от 0 до 255
        brightness_param.addUIType(ESP_RMAKER_UI_SLIDER); // Устанавливаем тип отображения как слайдер
        my_device.addParam(brightness_param); // Добавляем параметр устройству
        
        my_device.addCb(write_callback); // Устанавливаем функцию на обработчик
        my_node.addDevice(my_device); // Добавить девайс на ноду
    
        // Опционально
        RMaker.enableOTA(OTA_USING_PARAMS); // Включить беспроводное обновление
        RMaker.setTimeZone("Europe/Moscow"); // Установить часовой пояс https://rainmaker.espressif.com/docs/time-service.html
        RMaker.enableTZService(); // Кроме того, включите службу часового пояса и позвольте приложениям телефона установить соответствующий часовой пояс
    
        RMaker.enableSchedule(); // Включить расписание для нашего устройства
        
        RMaker.start(); // Запуск сервиса на устройстве
    
        WiFi.onEvent(sysProvEvent);
        WiFiProv.beginProvision(WIFI_PROV_SCHEME_BLE, WIFI_PROV_SCHEME_HANDLER_FREE_BTDM, WIFI_PROV_SECURITY_1, POP, SERVICE_NAME);
    }
    
    void loop()
    {
      // Обрабатываем нажатие на кнопка BOOT
      if(digitalRead(BOOT_BTN_PIN) == LOW) {
          delay(100); // Для исключения дребезка на тактовой кнопке
          int startTime = millis(); // Время на номент нажатия кнопки
          while(digitalRead(BOOT_BTN_PIN) == LOW) delay(50); // Цикл, который создаёт паузу для ожидания отжатия кнопки
          int endTime = millis(); // Время на момент отжатия кнопки
          int pressTime = endTime - startTime; // Время, на которое кнопка была нажата
          // Условия по времени нажатия
          if (pressTime > 10000) { // Если кнопка была зажата на более 10 секунд, тогда сбросить всё
            Serial.printf("Reset to factory.\n");
            RMakerFactoryReset(2);
          } else if (pressTime > 3000) { // Иначе если кнопка была зажата больше чем на 3 секунды, но меньше 10, тогда сбросить настройки WI-FI
            Serial.printf("Reset Wi-Fi.\n");
            RMakerWiFiReset(2);
          } else { // В остальных случаях
            // Переключение состояния встроенного светодиода
            board_led_state = !board_led_state; // Меняем запись в переменной состояния вашего светодиода
            Serial.printf("Toggle State to %s.\n", (board_led_state ? "true" : "false"));
            if (!board_led_state) { // Включаем или выключаем встроенный светодиод
              digitalWrite(LED_BUILTIN, LOW);
            } else {
              digitalWrite(LED_BUILTIN, HIGH);
            }
         }
      }
      delay(10);
    }

    Изучите код, прочитайте комментарии к коду!

  3. В инструментах вы должны выбрать:

    • Плата: ESP32 Arduino > ESP32 Dev Module;

    • Partition Scheme: RainMaker.

    И выберите порт платы. Загрузите прошивку. Никаких пинов для перевода контроллера в режим прошивки зажимать не нужно.

  4. Далее зайдите в монитор порта, установить скорость 115200. Выведется информация о том, как подключить плату к сервису. Там должна быть строка с QR-кодом и ссылка. Скопируйте ссылку и вставьте в адресную строку браузера.

    На этом этапе могут возникнуть две известные проблемы...

    • Плата пишет что-то на английском, но не выдаёт ссылку, тогда нужно сбросить настройки WI-FI, зажав BOOT на 3 секунды и отпустив. * Если плата уже была до этого настроена, тогда она будет выводить после прошивки текст на английском, QR-код уже не выведется. Это нормально, но пользоваться дальше можно!

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

  5. Скачайте приложение RainMaker, если это вы ещё не сделали из Google Play. В приложении RainMaker нажать на кнопку с иконкой ПЛЮС, запуститься сканер QR-кода.

  6. Отсканировать сканером QR-код с страницы с браузера.

  7. В приложении RainMaker выбрать точку доступа для устройства, дать пароль и подождать подключения и всяких других настроек.

  8. На главной странице RainMaker появится ваш девайс.

Теперь при нажатии на кнопку в RainMaker устройство будет включать и выключать светодиод, а слайдер управлять яркостью вашего светодиода. 💡

Дополнительное задание:

  • Для параметра яркости поменять тип на более подходящий - Brightness Slider. * Подсказка, UI типы вы найдёте тут.

  • Нужно переделать устройство и модуль светодиода заменить на модуль реле. Соотвественно переписать код, который будет управлять уже реле модулем, а не светодиодом. Лишнее из кода нужно удалить, чтобы в интерфейсе не отображались не нужные параметры.

Проблема с настрокой точки доступа:

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

Last updated