esp-open-rtosを使ってみる

アナログ入力(LM35DZ)

ESP8266には1ポートだけアナログ入力のポートが有ります。
素のESPでは最大1Vまでしか測れませんが、WeMosやNodeMCUではボード上の抵抗で分圧しているので、
最大3.2Vまで計ることができます。
アナログポートからアナログデータを読み込む方法を探していましたが、examples\http_server\http_server.cに
そのやり方が有りました。

アナログポートにLM35DZのアナログ温度計を付けて、温度を計ってみました。
LM75は温度が1/100の電圧値として出力されます。
(例)
0℃=0V
20℃=200mV
40℃=400mV
素のESPを使うときは1Vまでしか入力できませんが、1V=100℃度なので、室温を計るのであれば、そのまま使うことができます。
以下のコードを実行するとLM35DZの出力電圧を温度に変換して表示します。
/* The example of esp-free-rtos
 *
 * This sample code is in the public domain.
 */
#include <stdlib.h>
#include <string.h>
#include "espressif/esp_common.h"
#include "esp/uart.h"
#include "FreeRTOS.h"
#include "task.h"
#include "esp8266.h"

#define Vref 3.3

void user_init(void)
{
    uart_set_baud(0, 115200);
    printf("SDK version:%s\n", sdk_system_get_sdk_version());
    printf("pcTaskGetName=%s\n",pcTaskGetName(0));

    //Connect to TOUT Pin(Voltage Range between 0~3.2V)
    uint16_t adc_read;
    float voltage,temp;
    while (1) {
      adc_read = sdk_system_adc_read();
      voltage = (adc_read * Vref) / 1023.0;
      temp = voltage * 100.0;
      printf("adc_read=%d temp=%f\n",adc_read,temp);
      vTaskDelay(100);
    }

}

アナログ温度計なので、精度は余り良くありません。大体の温度が表示されます。
adc_read=52 temp=16.774195
adc_read=53 temp=17.096775
adc_read=53 temp=17.096775
adc_read=53 temp=17.096775
adc_read=53 temp=17.096775
adc_read=53 temp=17.096775
adc_read=53 temp=17.096775
adc_read=53 temp=17.096775
adc_read=53 temp=17.096775



examples/pcf8591のサンプルを使うと、PCF8591経由でアナログデータを読むことができます。
なお、サンプルコードはチャネル3を使っています。
8ビットのA/Dなので、あまり精度はよくありません。



手元にMCP3002のA/Dコンバータが有ったので試してみました。
MCP3002はSPIの10BitADCです。
以下のコードでA/D変換できました。
spi_set_settings()は、spi_init()のラップ関数なので、どちらを使っても同じですが、
spi_set_settings()を使うと、SPIの設定を元の状態に戻すことができます。
SPIの基本関数はcore/include/esp/spi.hに使い方が記載されています。
/* The example of esp-free-rtos
 *
 * This sample code is in the public domain.
 */
#include <stdlib.h>
#include "espressif/esp_common.h"
#include "esp/uart.h"
#include "esp/spi.h"
#include "FreeRTOS.h"
#include "task.h"

#define SPI_BUS       1
#define SPI_CS_GPIO   15   // GPIO 15, the default CS of SPI bus 1

#define Vref 3.26

static const spi_settings_t bus_settings = {
    .mode         = SPI_MODE0,
    .freq_divider = SPI_FREQ_DIV_1M,
    .msb          = true,
    .minimal_pins = false,
    .endianness   = SPI_LITTLE_ENDIAN
};


static void measure(void *pvParameters)
{
#if 0
    spi_settings_t old_settings;
    spi_get_settings(SPI_BUS, &old_settings);
    spi_set_settings(SPI_BUS, &bus_settings);
#endif

#if 1
    spi_init(SPI_BUS, bus_settings.mode,
             bus_settings.freq_divider,
             bus_settings.msb,
             bus_settings.endianness,
             bus_settings.minimal_pins);
#endif

    uint8_t mosi[2];
    uint8_t miso[2];
    uint16_t adc_read;
    float voltage;

    gpio_enable(SPI_CS_GPIO, GPIO_OUTPUT);
    while (1)
    {
        vTaskDelay(1000 / portTICK_PERIOD_MS);
        gpio_write(SPI_CS_GPIO, false);
        mosi[0] = 0x60;
        mosi[1] = 0x00;
        size_t transfered = spi_transfer (SPI_BUS, (const void*)mosi, (void*)miso, 2, SPI_8BIT);

        gpio_write(SPI_CS_GPIO, true);
        printf("spi_transfer=%x 0x%02x 0x%02x\n",transfered,miso[0],miso[1]);
        adc_read = miso[1]  | (miso[0] & 0x03) << 8;
        voltage = (adc_read * Vref) / 1023.0;
        printf("adc_read=0x%04x voltage=%f\n",adc_read,voltage);
    }
}

void user_init(void)
{
    uart_set_baud(0, 115200);

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

    xTaskCreate(measure, "measure_task", 256, NULL, 2, NULL);
}

続く....