пятница, 25 ноября 2016 г.

ESP8266 продолжение. Модуль ESP-12

В прошлой части я мучал модуль ESP-01 с AT-прошивкой. С тех пор прошло много времени, я успел заказать и получить более развитые модули ESP-12-E, о которых и пойдет речь в этот раз.
Будем прошивать NodeMCU, подключать SD-карту, дисплей на SSD1306, энкодер (rotary encoder) и FM-модуль RDA5807. После соединения всех этих модулей между собой в правильном порядке проводочками и правильного расположения бесчисленного количества байтиков во флеше ESP-12 должно получиться радио.

NodeMCU, стоит отметить, занятная штука! После прошивки в терминале доступно что-то типа командной строки языка Lua, где можно выполнять отдельные команды или целые скрипты, не компилируя каждый раз код и не перепрошивая модуль!

От гавеного usb-ttl адаптера такой модуль уже не смог прошиться, один вечер я его уговаривал разными программами - безрезультатно. Общение идет, MAC выдается, но потом все помирает, прошивка даже не начинает заливаться.
На следующий день я догадался измерить напругу на модуле, меньше 2В! Конечно нихрена не прошьется, нужно 3.3В.
Адаптер в качестве питальника тут совсем не годится. Запитал модуль от 2 батареек AAA и наконец прошил NodeMCU.
Использовал хорошую статью http://www.benlo.com/esp8266/esp8266QuickStart.html

Как подключить

По-моему самая годная схема подключения приведена в этой статье. Тут предусмотрено и использование режима сна (GPIO16 к ресету через 470R), и перемычка прошивки (Burn), и все нужные "подтяжки" - reset, gpio2, gpio0, gpio15, ch_pd (enable). 
Да уж, целая гора ног должна быть подтянута для старта железяки, я по незнанию боялся, что эти ноги не удастся использовать, однако напрасно - gpio 0, 2 и 15 доступны в приложении.

GPIO0 управляет режимом загрузки. Подтяжка к земле - режим программирования, заливки прошивки. Подтяжка к питанию - нормальная загрузка модуля
GPIO2 - должно быть притянуто к питанию всегда. низкий уровень инициирует специальные режимы загрузки
GPIO15 - должно быть притянуто к земле всегда. высокий уровень инициирует специальные режимы загрузки
GPIO16 должно быть замкнуто с пином RESET, если планируется использовать спящий режим. иначе модуль из спячки не выйдет никогда.
Вообще по вышеуказанной статье все намного лучше расписано.
И вот еще интересная страничка http://www.esp8266.com/wiki/doku.php?id=esp8266-module-family#esp-12-e_q
Специальные режимы загрузки кратко описаны тут https://github.com/esp8266/esp8266-wiki/wiki/Boot-Process, есть даже загрузка с SD карты, во как.. Может быть для этого и выведены с торца модуля пины CS0, MISO, MOSI, SCLK?

Что имеется в распоряжении ESP?

Свободных GPIO - 9 ног: GPIO 0/2/4/5/12/13/14/15/16.
Последний (GPIO16) ограничен в функционале.
GPIO9 и 10 хоть и выведены, однако вообще не работают в модуле версии ESP-12-E (они только на ESP-12D, на али я такой не нашел, что интересно). Более того, попытка их использовать ведет к зависанию и ребуту по watchdog.

Есть ADC - можно контроль разряда батареи сделать или опрос клавы, но только что-то одно. Т.е. модуль измеряет либо внутреннее напряжение vdd33, либо внешнее, подаваемое на ногу ADC.

Выведены пины SPI, однако забудьте о них - в версии ESP-12-E они точно не пашут.
Подключение SD карты делается через несколько GPIO и софтовый SPI, об этом позже.

Ну и UART. Из железных возможностей это все. Остальное реализуется через GPIO, и, надо сказать, эти ноги очень быстро заканчиваются.

Где взять прошивку

Прошивал я программой ESP8266Flasher, в данном случае вариант первый - использовать прошивку NodeMCU, которая уже содержится в программе.
Она не особо свежая, однако для "пощупать" и быстрого старта вполне годится. В качестве bin-файла указывается INTERNAL://NODEMCU, см. скрин.

Способ второй, которым обычно и пользуюсь - пройти на сайт https://nodemcu-build.com/ и собрать себе бинарник со всеми нужными модулями. Через какое-то время (минуты 2-3) на почту придет ссылка для скачивания.

Способ третий, хардкорный. Скачать исходники из репозитория https://github.com/nodemcu/nodemcu-firmware и безжалостно собрать их.

Вернемся к способу 2.

К великой радости поклонников NodeMCU прошивка оная обновила мажорную версию на 1 и уже обросла множеством вкусных модулей, в частности, наконец-то, поддержка SD-карт и файловой системы FatFS (я пробовал карту с FAT32 - работает)! Этого-то мне и не хватало для счастья, погнал на https://nodemcu-build.com/ собирать себе бинарник прошивки.
Собрал один, другой, третий - ни один не пашет, модуль после прошивки бесконечно ребутается и выдает rf_cal[0] !=0x05,is 0xFF

Нашел заметку, где описана эта проблема http://nodemcu.readthedocs.io/en/latest/en/flash/#sdk-init-data, нашел в инете пустой bin-файл на blank_1MB.bin (8MBit), залил его, потом снова прошивку, но даже это не помогло.
т.е. после записи пустого бинарника выдалось esp_main.c, как положено, но после накатывания прошивки - опять та же фигня с ребутами.
upd: так ведь модуль у меня 32Мбит, наверное надо было 4 раза его заливать с разными offset, теперь уже проверять лень

В итоге я в очередной раз выбрал заливку собранного бинарника, но добавил еще заливку esp_init_data_default.bin в соответствии с рекомендацией. Адрес (оффсет) поначалу вписал 0xfc000 (т.к. чип при старте выдавал инфо 512+512кб), но в последний момент отчего-то решил сменить на 0x3fc000 (вариант для 32Мбитного флеша), и прокатило!
Запускаю LuaLoader и вижу приветственное сообщение на скорости 115200
NodeMCU custom build by frightanic.com
branch: master
commit: 7b83bbb2ea134cd85ac9d63108603cc02c4e20f7
SSL: true
modules: adc,bit,file,gpio,http,i2c,net,node,spi,tmr,u8g,uart,wifi,ws2812
 build  built on: 2016-11-16 16:26
 powered by Lua 5.1.4 on SDK 1.5.4.1(39cb9a32)
lua: cannot open init.lua
Chip info выдает
> =node.info()
1 5 4 654602 1458400 4096 0 40000000
NodeMCU version (1.5.4), chipid, flashid, flash size (4096!), flash mode, flash speed

Connect them all

Карта соответствия I/O индексов пинам GPIOx тут.
IO indexESP8266 pinIO indexESP8266 pin
0 *GPIO167GPIO13
1GPIO58GPIO15
2GPIO49GPIO3
3GPIO010GPIO1
4GPIO211GPIO9
5GPIO1412GPIO10
6GPIO12
* D0(GPIO16) can only be used as gpio read/write. No support for open-drain/interrupt/pwm/i2c/ow.
Первым делом втыкаем FM-модуль RDA5807 и OLED дисплей на SSD1306. Оба через интерфейс I2C. Я выбрал ноги GPIO4 и GPIO5. Требуется модуль i2c, а для дисплея еще u8g.

Чтобы включить радио нужно выполнить такой скрипт
fm_addr = 0x11
id  = 0
sda = 1 -- gpio5
scl = 2 -- gpio4
i2c.setup(id, sda, scl, i2c.SLOW)
-- включаем железку
reg_addr = 0x02
i2c.start(id)
i2c.address(id, fm_addr, i2c.TRANSMITTER)
i2c.write(id, reg_addr, 0xC0, 0x0D)
i2c.stop(id)
-- запускаем автопоиск станции
reg_addr = 0x02
i2c.start(id)
i2c.address(id, fm_addr, i2c.TRANSMITTER)
i2c.write(id, reg_addr, 0xC3, 0x0D)
i2c.stop(id)
Разумеется стоит оформить запись регистров в виде функций
Для вывода чего-нибудь на дисплей простейший скрипт такой
sla = 0x3c -- oled address
disp = u8g.ssd1306_128x64_i2c(sla)
disp:firstPage()
disp:setFont(u8g.font_6x10)
disp:drawStr(40, 8, "SSD1306 OLED")
disp:nextPage()
Более подробно о работе с FM-модулем и дисплеем - в следующей статье.

Далее подключаем SD-карту. У меня был специальный китайский модуль для SD, см.фото. Требуется модуль spi.
Линии подключения SD-карты описаны тут https://nodemcu.readthedocs.io/en/master/en/sdcard/#sd-card-connection
Хорошая документация по всем модулям NodeMCU с примерами.
  • CK, CLK, SCLK to pin5 / GPIO14 
  • DO, DAT0, MISO to pin 6 / GPIO12 
  • DI, CMD, MOSI to pin 7 / GPIO13 
  • CS, DAT3, SS to pin 8 / GPIO15 recommended 
  • VCC, VDD to 3V3 supply 
  • VSS, GND to common ground
Подключил, причем GPIO15 так и остался подтянут к земле через 1к2 (надо 10к, да, но их не было), загрузил ESP-12 - все ок. GPIO 12, 13, 14, 15 теперь заняты.

Далее для проверки карты выполнил следующее
spi.setup(1, spi.MASTER, spi.CPOL_LOW, spi.CPHA_LOW, 8, 8)
vol = file.mount("/SD0", 8) -- 8 is GPIO15
file.chdir("/SD0")
l = file.list()
for k,v in pairs(l) do
    print("name:"..k..", size:"..v)
end
и получил заветный список файлов на карте!

Пробуем записать тестовый текстовый файл
file.open("test.txt", "w")
file.write('foo bar')
file.close()
-- теперь прочитаем
file.open("test.txt", "r")
print(file.readline())
file.close()
чтобы вернуться на внутреннюю память ESP выполняем file.chdir("/FLASH")
а еще можно не меняя папки
file.open("/FLASH/file.txt") или file.open("/SD0/somefile.txt")

И последнее - подключаем энкодер. Требуется модуль rotary. У нас осталось 3 свободных ноги - GPIO16, 0 и 2.
Но засада в том, что GPIO16 не годится ни на что, кроме как вручную выставить на этой ноге уровень или прочитать его. С этой ногой не работает ни один интерфейс, и прерывания тоже не работают. Так что, выходит, событие "нажатие на энкодер" не удастся подключить.
Стартовый скрипт - простейший.
rotary.setup(0, 3, 4)
rotary.on(0, rotary.ALL, function (type, pos, when)
  print ("Position=" .. pos .. " event type=" .. type .. " time=" .. when)
end)
Заняли оставшиеся 2 GPIO - 2 и 0.

Да уж, после AVR Assembler тут все слишком легко, подключаешь - и все сразу работает, даже неинтересно.
Правда с энкодером загвоздка вышла. При старте ESP он-таки влияет на пины GPIO0/2 и модуль не грузится как надо.
Эту проблему я решил перестановкой - повесил I2C на пины GPIO0+2, а энкодер - на GPIO4+5, все нормально запускается и работает.

Теперь можно все это запрограммировывать.

Немного замеров

Питание от литиевой батареи 3.7В формата 18650.
Только что загруженная NodeMcu dev ветка - 3.12В, 77мА
Дисплей OLED 128x64 при выводе изображения добавил еще 8мА.
Проект ESP8266_MP3_DECODER: динамик 1Вт 8Ом подключен напрямую к ноге ESP-12E, измеряю ток мультиметром в разрыве питания - 131мА.
Напряжение до тестера - 3.58В, после - 2.7В, вот уж не думал, что он такое влияние вносит! Напругу при включенном тестере измерял осциллографом.

2 комментария:

  1. Ну что-то уж очень много на мультиметре падает при токе 130 мА, даже не верится, проверьте как-то, попросите у соседа второй мультиметр.

    ОтветитьУдалить
  2. а можно исходник проекта?

    ОтветитьУдалить