esp-open-rtosを使ってみる

PWM出力(サーボモータ)

exampleディレクトリーには、センサーやTFT/LCDを扱うための沢山のサンプルコードが含まれています。
example/pwm_testにPWMのサンプルが有りますが、LチカのPWMサンプルです。
そこで、 SG90のサーボモータを使ってPWMを試してみました。
サーボモータ(SG90) ESP8266
オレンジ GPIO14(*)
5V
茶色 GND

(*)ESP8266にはハードウェアPWMの機能はありません。
ソフトウェアPWMなので使えるピンに制限はありません。

SG90のデータ シートによると、SG90はPWM Periodが20mSecとなっています。
PWM Period(20mSec)は周波数に換算すると1/0.02=50Hzとなります。
また、デー タシートにポジションごと のパルス幅が記載されています。
データシートの値を使って、実際に動作させましたが、少し誤差があるようなので、動きを見ながら微調整しました。
ポジション データシートのパルス幅 実際に動作させてみたパルス幅 Duty cycle(計算値)
1.45mSec 1.45mSec 1.45/20=0.0725
+90° 2.4mSec 2.35mSec 2.35/20=0.1175
-90° 0.5mSec 0.625mSec 0.625/20=0.03125

以下のコードを実行するとGPIO14に接続したSG90が0°→ +90° → -90° → 0° に動きます。
/* The example of esp-free-rtos
 *
 * This sample code is in the public domain.
 */
#include "espressif/esp_common.h"
#include "esp/uart.h"
#include "FreeRTOS.h"
#include "task.h"
#include "pwm.h"

void task1(void *pvParameters)
{
    printf("Hello from task1!\r\n");
    // Move to center
    pwm_set_duty(UINT16_MAX / (1.0 / 0.0725));
    vTaskDelay(200);
    // Move to +90
    pwm_set_duty(UINT16_MAX / (1.0 / 0.1175));
    vTaskDelay(200);
    // Move to -90
    pwm_set_duty(UINT16_MAX / (1.0 / 0.03125));
    vTaskDelay(200);
    // Move to center
    pwm_set_duty(UINT16_MAX / (1.0 / 0.0725));
    vTaskDelay(200);

    while(1) {
      vTaskDelay(100);
    }
}

void user_init(void)
{
    uint8_t pins[1];
    uart_set_baud(0, 115200);

    printf("SDK version:%s\n", sdk_system_get_sdk_version());

    printf("pwm_init(1, [14])\n");
    pins[0] = 14;
    pwm_init(1, pins, false);

    printf("pwm_set_freq(50)     # 50 Hz\n");
    pwm_set_freq(50);

    printf("pwm_start()\n");
    pwm_start();

    xTaskCreate(task1, "task1", 256, NULL, 2, NULL);
}

ライブラリソースを見てみましたが、同時に8ポートまでのPWMを制御できます。
サーボモータを1つしか持っていないので、確認することができません。
サーボモータを複数使って、サーボモータの数だけタスクを起動し、タスク毎にそれぞれのサーボ制御をやらせたら面白いかもしれません。

続く....