image

Часть 2 < — Часть 1

Продолжим эксперементировать с микроконтроллером STM32F103C8T6, подключим некоторые датчики/дисплеи с интерфейсом I2C к «голубой таблетке».

Реализована поддержка популярных дисплеев I2C:

  • LCD 1602
  • SSD1306

Реализована поддержка следующих датчиков:

  • BH1750 — датчик освещенности
  • BME280 — датчик температуры, давления, влажности
  • CCS811 — датчик СО2, ЛОВ ( Летучие Органические Вещества )

Для того, чтобы начать работать с новыми функциями необходимо создать новый проект.
Ссылка для загрузки программы MIOC приведена в первой части.

Датчики


Датчик BH1750


image

BH1750 16-битный датчик освещённости (люксметр) с интерфейсом I2C. Фотодиод на BH1750 определяет интенсивность света, которая преобразуется в выходное напряжение с помощью операционного усилителя. Встроенный АЦП выдает 16-битные цифровые данные. Внутренняя логика BH1750 избавляет от необходимости каких-либо сложных вычислений, поскольку он напрямую выводит значимые цифровые данные в люксах (лк).

Согласно документации, датчик BH1750 чувствителен к видимому свету и практически не подвержен влиянию инфракрасного излучения, т.е. реагирует примерно на тот же спектральный диапазон, что и человеческий глаз.

Для работы с этим датчиком на закладке «Configuration» выбрать BH1750.

Результаты измерений будут находиться в глобальной переменной:
uint32_t BH_L;

Подключение датчика к шине I2C2:

image

Датчик BME280


image

Данный датчик измеряет параметры окружающей среды: температура, атмосферное давление, а также влажность воздуха.

Есть ещё подобный датчик — BMP280, в котором отсутствует возможность измерять влажность. Но зато стоит он гораздо дешевле.

Помимо того, что датчик измеряет все вышеперечисленные параметры, он также умеет фильтровать шумы, в него встроена калибровка показаний. Так же в отличие от других датчиков, данный датчик проделывает все эти измерения не только быстро, но и в более широких диапазонах. Например, многие датчики не умеют измерять влажность воздуха менее 20 процентов.

Заявленные характеристики у датчика следующие:

image
Датчики подключаются к шине I2C2 следующим образом:

image

Если будет использован BMP280, то в файле main/bme280.c нужно закоментировать все строки помеченные // Comment for BMP.

Результаты измерений будут находиться в глобальных переменных:

image

Пример программы, работающей с датчиками BH1750, BME280, и дисплея 1602:

#include "mx_init_hw.c"

int main()
{
    char s[64];
    float t=0, p=0, h=0;

    Init_HW();

    // ---------------------
    // The main program loop
    // ---------------------
    while( TRUE )
    {
        delay_ms( 300 );

        t = BME_T / 10.0;
        p = BME_P / 100.0;
        h = BME_H / 10.0;

        sprintf( s, "t=%-7.1fC", t );
        SSD1306_write_string( 1, s );

        sprintf( s, "p=%-7.1fPa", p );
        SSD1306_write_string( 2, s );

        sprintf( s, "h=%-7.1f%% ", h );
        SSD1306_write_string( 3, s );

        sprintf( s, "T=%-7.1fH=%.1f", t, h );
        LCD_write_string( 1, s );

        sprintf( s, "P=%-7.1fL=%u", p, BH_L );
        LCD_write_string( 2, s );
    }
}

Результат работы программы:

image
Эта же программа будет отображать температуру, давление, влажность на дисплее SSD1306
(подключить данный дисплей, и выбрать его в конфигурации):

image

Датчик BME280 может измерять температуру с большей точностью. Для этого его нужно откалибровать. В файле main/bme280.h для этого есть макроопределение:
#define DT 3520

Датчик CCS811


image

Окружающий нас воздух представляет собой смесь газов и состоит в основном из азота (около 78%) и кислорода (около 21%). Оставшийся процент приходится на долю различных примесей (инертные газы, углекислый газ, угарный газ, органические летучие вещества (ЛОВ) и т. д). Несмотря на то, что в процентном соотношении количества примесей мало, изменение их концентрации может оказаться очень неприятным и даже опасным для человека. Качество воздуха в офисных и бытовых помещениях чаще всего связывают с содержанием CO2 и ЛОВ.

К органическим летучим веществам относятся более 5000 соединений. Образование большей части из них так или иначе связано с процессами жизнедеятельности человека.

Таким образом, даже простое присутствие человека в замкнутом помещении приводит к «загрязнению» воздуха и необходимости проветривания. Оценка концентрации ЛОВ в воздухе затруднена. Раньше для оценки концентрации ЛОВ применяли датчики CO2. При этом учитывался тот факт, что в нормальных условиях концентрации ЛОВ и CO2 оказываются связанными. Зная процентное содержание CO2, можно косвенно определить концентрацию ЛОВ. Если содержание углекислого газа в воздухе достигло некоторого предела — необходимо включать вентиляцию.

На практике взаимосвязь между ЛОВ и CO2 не всегда однозначна. Например, курение в помещении вызывает резкий скачок содержания ЛОВ, который датчики CO2 не фиксируют, так концентрация углекислого газа при этом сильно не меняется. Датчики углекислого газа также будут бессильны, если в помещении используется бытовая химия, чистящие средства, лакокрасочные материалы или обычная парфюмерия. Компания AMS предлагает свое решение проблемы измерения концентрации ЛОВ — датчики CCS811.

Характеристики датчиков качества воздуха CCS811B:

image

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

image

Пользователю также необходимо помнить, что каждый раз после включения датчик CCS811 должен «прогреваться». Время такого «прогрева» составляет более 30 минут, в течение которых погрешность оказывается недопустимо большой:

image

Эту особенность CCS811 крайне важно учитывать.

Результаты измерений датчика находятся в глобальных переменных:
uint32_t CCS_CO2;
uint32_t CCS_TVOC;

Подключение датчика к шине I2C2:

image

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

Примеры прочих датчиков



Датчик движения HC-SR501


image

Некоторые датчики, например датчики движения HC-SR501 не требуют написания каких либо дополнительных сниппетов.

Для данного датчика — объявить переменную, выбрать Type=GPIO_Mode_IN_FLOATING, выбрать порт.

Генерировать BSP, компилировать, загрузить в МК. Далее работаем с этим датчиком так же, как с кнопкой (на получение данных).

Подключение датчика HC-SR501:

image

Датчик температуры/влажности DHT22


image

Датчик измерения температуры/влажности

Подключение датчика:

image

Работа с этим датчиком будет как пример пользовательского сниппета ( аналог скетча arduino ).

Сниппет можно взять здесь:
dht22.c
Поместить его в папку main
В данном файле отредактировать строки:

#define PORT GPIOA
#define PIN GPIO_Pin_5

по фактическому подключению датчика

Текст программы для работы с данным сниппетом:

#include "mx_init_hw.c"
#include "dht_22.c"

int main()
{
    int16_t dht_t, dht_h;

    Init_HW();

    dht_init();

    // ---------------------
    // The main program loop
    // ---------------------
    while( TRUE )
    {
        delay_ms( 5000 );
        if( !get_dht_data( &dht_t, &dht_h ) )
            print( "t=%.1f h=%.1f\r\n", (float)dht_t / 10.0, (float)dht_h / 10.0 )
        else
            print( "DHT 22 - ERR\r\n" );
    }
}

Результат работы:

image

Чаще, чем раз в 4-5 секунд датчик опрашивать нет смысла. Причины: вычисление температуры происходит в течении 800-900 mS, второе: если опрашивать чаще, то идет саморазогрев датчика.

CLI


Прошивка содержит небольшой командный интерпретатор, работающий с консолью. Посмотреть какие команды есть можно в файле main/mx_cli.c

При желании можно добавить какие либо свои команды.

CLI начинает работать в режиме No Echo, т. е. Вводимые символы не отображаются. Для отображения вводимых символов необходимо напечатать: echo on.

Команда «sh on» будет выводить два раза в секунду значения переменных, объявленных в конфигураторе и переменных связанных с датчиками. Номер в первой позиции соответствует номеру строки в таблице конфигуратора. Данная команда сделана для передачи данных в систему подключенную к консоли.

Никаких флагов и мьютексов, анализирующих занятость консоли — нет. Поэтому при совместном использовании оператора «print» и «echo on» может произойти перемешивание выводимой информации. Не следует применять оба метода одновременно. Для решения данной проблемы можно использовать два канала вывода. Например консоль на UART1, а вывод пользовательской информации на VCP. Или наоборот.

Использовать функции:

send_uart1( char *data, int len )
send_usb( char *data, int len )

Для облегчения использования этих функций можно в файле gbl.h изменить макроопределение printf. Например на следующее:

#define printf(fmt,argv...){char s[128];sprintf(s,fmt,##argv);send_usb(s,strlen(s));} // вывод на VCP

Пример вывода на консоль (echo on):

image

Сканирование шины I2Cx


Для сканирования шины I2C1 или I2C2 есть готовые «прошивки» *.hex
scanner I2Cx
Вывод информации на UART1, скорость — 115200,8,N,1
После загрузки сканера нажать кнопку «Reset».

Прошивки показывают адреса найденных устройств на шине.

image

Все три подключенных датчика, описанных выше.

Комментарии (30)


  1. NikitOS9
    20.10.2019 10:13
    +2

    таблетки мощнее STM32F411CEU6 / STM32F401CCU6
    100mhz 128ram 512rom / 84mhz 64ram 256rom


    1. DanilinS
      20.10.2019 10:36

      А смысл? Там F0 и F1 хватит с избытком. А F4 серия — там она сильно избыточна.


      1. NikitOS9
        20.10.2019 15:06

        смотря чего и на что. мегагерц возможно да, но памяти маловато, например есть проект где несколько таблеток с разными датчиками общаются по радиоканалу между собой и главной мощной 'таблеткой'.
        на 20к придется больше думать над оптимизацией всего и работе с памятью, проще мощнее железку поставить.
        20к у stm32 != 20k у ti или atmel


        1. alex323
          21.10.2019 10:20

          В stm32F103C8T6 64k памяти, а не 20.
          — P.S. а, речь о RAM… Не ахти какая задача, хватит с избытком.


          1. alex-open-plc Автор
            21.10.2019 10:21

            ОЗУ — 20


          1. NikitOS9
            21.10.2019 16:37

            >Не ахти какая задача, хватит с избытком
            это обещание 100% и текст задачи изучен?


            1. alex323
              21.10.2019 18:10

              это обещание 100% и текст задачи изучен?

              Все задачи в статье расписаны — простые эксперименты. Если у вас проект где несколько таблеток с разными датчиками общаются по радиоканалу между собой и главной мощной 'таблеткой', думаю, вполне хватит. Если вы хотите в ОЗУ кучу логов с датчиков хранить — тогда уже от вас зависит. Хотя при чем все это, если речь в статье про простые эксперименты?


              1. NikitOS9
                21.10.2019 18:41

                >думаю, вполне хватит
                это было не полное описание, есть работа с lcd, логика на разные случаи и тд…
                если коммент был к статье то он не в той ветке.


                1. alex-open-plc Автор
                  22.10.2019 15:27

                  Про LCD, была мысь описать, да сильно «развесистая» статья получится…
                  См. фалы main\mx_lcd_i2c.c и main\mx_ssd1306.c. Там описаны все функции работы с дисплеями.


  1. DanilinS
    20.10.2019 10:30

    Сорри, нечаянно сделал дубль. Удалите плизз ...


  1. DanilinS
    20.10.2019 10:40

    Есть еще BME680. Это BME280 + ЛОВ.

    Я для своей разработки использовал:
    1) плата «HDC1080 CCS811»: снимаю температуру+влажность+СО2+ЛОВ.
    2) ZH03B — лазерный сенсор пыли.
    В принципе все что нужно человеку. В будущем возможно добавлю датчик на атмосферное давление. Старый уже — стал замечать за собой метеочуствительность.
    Все крутиться на «ESP32 TTGO dev board OLED». Правда пока все в стадии отладки.


  1. engine9
    20.10.2019 10:43

    А можно еще прикрутить к этому МК флешку, куда бы вёлся лог показаний?


    1. alex-open-plc Автор
      20.10.2019 11:04

      Можно. Но в планах первой очереди реализация сетей.


    1. VBKesha
      20.10.2019 11:06
      +1

      В теории достаточно просто SPI+SDCard и пошло поехало.


      1. alex323
        21.10.2019 11:19

        Зачем такой ардуинский подход. У STM32 есть SDIO для работы с картами SD.


        1. VBKesha
          21.10.2019 12:37
          +1

          А ещё у SMT32 есть Ethernet и графический контроллер.
          Но это не значит что всё это есть в STM32F103 про которую собственно статья и написана.
          www.st.com/en/microcontrollers-microprocessors/stm32f103c8.html


          1. alex323
            21.10.2019 12:56

            Да, пардон, у 103 серии только в high density


  1. torgeek
    20.10.2019 18:01

    Говорят, что есть похожая совместимая голубая таблетка, только на RISC-V.
    Насколько примеры требуется изменить, что бы работать на ней?

    Wio Lite RISC-V на GD32VF103


    1. alex-open-plc Автор
      20.10.2019 18:54

      Не знаю. С этой китайской поделкой не работал…


    1. DanilinS
      20.10.2019 22:21

      GD32VF103 — это немного кривой клон STM32F103. Для прошивки требует особый программатор.
      Т.е. на плате GD32VF103 + ESP8266.


      Брать такую плату смысла нет. Комбинация устаревшего ESP8266 и GD32VF103. Возьми лучше ESP32 на плате с необходимым обвесом.


      1. torgeek
        22.10.2019 11:30

        Говорят об энергоэффективности в 3 раза лучше, чем у STM32F103, и превосходстве по быстродействию. Для автономных применений это важно.
        Плюс есть перспектива поработать с новой системой команд RISC-V привлекает.


  1. sim2q
    21.10.2019 00:42

    Главное, не тащить порочный ногодрыг где это возможно…


  1. monah_tuk
    21.10.2019 07:46

    CCS811

    Я правильно понимаю, что его возможно использовать для детектирования загрязнения воздуха в туалете результатами человеческой жизнедеятельности? Вопрос актуальный в части предстоящего рукоблудства.


    1. alex-open-plc Автор
      21.10.2019 08:04

      Да. И в силу того, что объём туалетов обычно невелик, то и наличие живого организма сразу видно (увеличение уровня СО2 и ЛОВ).


      1. monah_tuk
        21.10.2019 08:07

        Спасибо! Стоит заложить возможный апгрейд


  1. vektory79
    21.10.2019 09:35

    А ни у кого не бывало, что CCS811 периодически виснет, блокируя i2c шину напроч?


    1. OvO
      21.10.2019 09:53

      Бывало, лечу насильным передергиванием обоих линий вниз и вверх.


  1. Tabke
    22.10.2019 11:03

    Предлагаю в следующих уроках рассмотреть работу с адресуемыми светодиодами, — WS2811 и иже с ними. Достаточно актуальная и интересная задача с множественным применением.


    1. alex-open-plc Автор
      22.10.2019 13:52

      Проект github.com/Silencer2K/stm32f10x-ws2812b-lib (spl)
      Подключить как сниппет.


  1. mctMaks
    22.10.2019 14:12

    Если будет использован BMP280, то в файле main/bme280.c нужно закоментировать все строки помеченные // Comment for BMP.


    почему тогда не воcпользоваться #ifndef… #endif для того чтобы исключать не нужные строки? зачем пользователя то заставлять лазить в код, искать и комметировать строки? Вроде ж очевидное решение и прямо таки просится…