• Система автоматизации с открытым исходным кодом на базе esp8266/esp32 микроконтроллеров и приложения IoT Manager. Наша группа в Telegram

Разработка ‘библиотеки’ малого webсервера на esp8266.

nikolz

Well-known member
pvvx,
Добрый день,
Хотел бы узнать Ваше мнение, почему ADC в ESP работает так медленно.
Если схема поразрядного уравновешивания, то на 10 разрядов при 50 мкс (Ваши результаты) получаем 5 мкс на разряд,
т е скорость очень низкая .
Возможно Вы измеряли время преобразования разряда.
В документации сказано, что при работе WIFI теряется 20% скорости процессора.
Возможно, что для ацп еще больше?
Возможно подскажите какую-либо документацию по ADC в ESP
Спасибо
 

pvvx

Активный участник сообщества
Хотел бы узнать Ваше мнение, почему ADC в ESP работает так медленно.
Спасибо
20 кГц на отсчет и баста. ADC полу-программный, набор сумм с коррекциями из 8 регистров сумматоров.
Определение типа ADC: http://esp8266.ru/forum/threads/tochnost-adc.598/#post-10617
Возможно подскажите какую-либо документацию по ADC в ESP
Нет никакой документации по ADC, кроме моих собственных похождений и замеров с ним.
Данная прошивка выводит в UDP поток с ADC до 20кГц 14 бит. Что ещё надо?
 
Последнее редактирование:

nikolz

Well-known member
pvvx,
Благодарю за информацию.
-----------------------------
Просьба ответить на следующие вопросы:
--------------------
1) Если я правильно понял Вашу осциллограмму,
то время коммутации 8 сумматоров 10 мкс.
Т е без учета времени считывания их получаем скорость 100 кгц.
-------------------
2) Число разрядов результата не влияет на скорость преобразования а определяется лишь алгоритмом суммирования.
----------------
3) Можно ли управлять скоростью коммутации сумматоров.
-----------------
4) Если у нас 8 шагов, то каким образом получаем 14 разрядов
Верно?
Спасибо.
 
Последнее редактирование:

pvvx

Активный участник сообщества
1) Если я правильно понял Вашу осциллограмму,
то время коммутации 8 сумматоров 10 мкс.
Там писано - 20 мкс клетка, а "зубцы" чуть более. Далее открывайте как работает SAR...
Потом смотрите код и видите, что начало замера (заряд) включается в конце цикла обслуживания прерывания чтения регистров. Т.е. следующее прерывание считывает готовый результат и снова заряжает SAR
И прерывание с 12-ю i/o низко-скоростной шины не обслужить быстрее 1.5 us.
 
Последнее редактирование:

pvvx

Активный участник сообщества
4) Если у нас 8 шагов, то каким образом получаем 14 разрядов
Верно?
Значит 12. Перепутано с ~sys_adc~ - там ещё сумма. Но точно я не помню - очень давно это уже было. Запустите WDRV и считайте показания при установке у максимум ADC.
 
Последнее редактирование:

nikolz

Well-known member
pvvx,
Пардон,действительно 20 мкс+2 мкс, т е примерно 40 кгц . Это понятно.
----------------------
Но как за 8 тактов получаем 10 или 12 бит. Это не понятно.
В SAR число разрядов равно числу тактов.
или здесь такт - это несколько разрядов?
Ваше мнение?
Спасибо
 

pvvx

Активный участник сообщества
pvvx,
Пардон,действительно 20 мкс+2 мкс, т е примерно 40 кгц . Это понятно.
----------------------
Но как за 8 тактов получаем 10 или 12 бит. Это не понятно.
Не помню, что содержат сумматоры. Смотрите китайский код. Там вроде сдвиг результата суммы на 2 и выходит 10 бит.
Код:
    read_sar_dout(sardata);
    for (i = 0; i < 8; i++) {
        sar_dout += sardata[i];
        ADC_DBG("%d, ", sardata[i]);
    }
    tout = (sar_dout + 8) >> 4;   // tout is 10 bits fraction
Пример ещё https://github.com/mattcallow/esp8266-sdk/blob/master/apps/07switch/driver/adc.c
Сморите тип китайской коррекции - это что-то типа линеаризации простого RC спада.
Код:
; =============== S U B R O U T I N E =======================================


read_sar_dout:                          ; CODE XREF: readvdd33+125p
                                        ; test_tout+B0p ...
                l32r            a9, dw0x60000A00
                l32r            a8, dw0xF00_0
                movi.n          a11, 0
                addi            a1, a1, 0xF0
                s32i.n          a12, a1, 4
                s32i.n          a0, a1, 0
                s32i.n          a13, a1, 8
                movi.n          a0, 0
                movi            a13, 0xFF
                movi.n          a12, 0x7F

loc_4024EF84:                           ; CODE XREF: read_sar_dout+55j
                addx4           a6, a0, a9
                addx2           a7, a0, a2
                mov.n           a5, a13
                mov.n           a10, a11
                memw
                movi            a3, 0x117
                l32i            a6, a6, 0x380
                addi.n          a0, a0, 1
                extui           a0, a0, 0, 8
                xor             a6, a6, a12
                extui           a4, a6, 0, 8
                addi            a4, a4, 0xEB
                extui           a6, a6, 0, 0xB
                s16i            a6, a7, 0
                movgez          a10, a4, a4
                mull            a10, a10, a3
                and             a3, a6, a8
                srai            a10, a10, 8
                blt             a13, a10, loc_4024EFBC
                mov.n           a5, a10

loc_4024EFBC:                           ; CODE XREF: read_sar_dout+4Bj
                add.n           a3, a5, a3
                s16i            a3, a7, 0
                bnei            a0, 8, loc_4024EF84
                l32i.n          a12, a1, 4
                l32i.n          a13, a1, 8
                l32i.n          a0, a1, 0
                addi            a1, a1, 0x10
                ret.n
; End of function read_sar_dout
Эта функция переведена мной на Cи как mread_sar_dout() - https://github.com/pvvx/esp8266web/blob/master/app/driver/adc.c

По поводу readvdd33() - там, в самой функции, стоят задержки ets_delay_us(25) перед чтением регистров "сумматоров" read_sar_dout(), чтобы не опрашивать их готовность:
while (GET_PERI_REG_BITS(0x60000D50, 26, 24) > 0); //wait r_state == 0
Время после "заряда" измерения и выставлением битов готовности у данного SAR где-то дает предел опроса чуть более 22 кГц (22 тысяч опросов в секунду). С учетом времени считывания "сумматоров" и выходит предел к 20кГц. При другой тактовой потребуются другие коррекции и токи...

PS: Объяснять и капаться снова там не вижу смыслу - вы всё равно не напишите инструкции для всех.
 
Последнее редактирование:

pvvx

Активный участник сообщества
Переехало на SDK 1.5.0 (размер кода в flash немного увеличился, heap стало немного больше).
Ошибка с deep_sleep в китай-либах запатчена.
 

auara2

New member
pvvx, 26 ноя 2015
Эта функция переведена мной на Cи как mread_sar_dout() - https://github.com/pvvx/esp8266web/blob/master/app/driver/adc.c
Кажись, потеряно ограничение z на уровне 255 перед суммированием с x.
Сморите тип китайской коррекции - это что-то типа линеаризации простого RC спада.
Код:
...
                      blt             a13, a10, loc_4024EFBC    ;jmp if(aD < aA)
                       mov.n           a5, a10        ;a5 = aA
      
      loc_4024EFBC:                           ; CODE XREF: read_sar_dout+4Bj
                      add.n           a3, a5, a3    ;a3 += a5
...
Надо где-то так:
Код:
void ICACHE_FLASH_ATTR mread_sar_dout(uint16 * buf)
{
  volatile uint32 * sar_regs = &SAR_BASE[32]; // 8 шт. с адреса 0x60000D80
  int i;
  for(i = 0; i < 8; i++) {
    int x = ~(*sar_regs++);
    int z = (x & 0xFF) - 21;
    if(z < 0)  z = 0;
    z = (z * 279) >> 8;  // == (z * 279) / 256 == z * 1.08984375
    if(z > 255)  z = 255;
    buf[i] = (x & 0x700) + z;
  }
}
 

auara2

New member
Как я понял про АЦП из документаций:
  1. Рабочее напряжение чипа (самой микросхемы): 1.8В - 3.6В .
  2. В файле "esp_init_data_default.bin", длиной 128 байт, надо
    прописывать значение "vdd33_const" (по адресу 0x6B = 107) равное реальному
    напряжению питания чипа в единицах 0.1В (т.е. от 18 до 36, по умолчанию 33).
  3. Разрядность АЦП: 10 бит .
  4. АЦП не желательно использовать, когда чип передает. Иначе напряжение, может быть неточным.
  5. Диапазон измеряемых напряжений АЦП: 0.0В - 1.0В .
    Следовательно, внутреннее опорное напряжение д.б. в районе 1.0В (желательно 1.024В).
 
Последнее редактирование:

pvvx

Активный участник сообщества
из данного кода следует что АЦП имеет 8 разрядов. 11 получаем суммированием 8 отсчетов.
Кто больше?
& 0x700 + младшие 8 бит не есть 8 разрядов.
3+8=12 и так по 8.
Как я понял про АЦП из документаций
"Не читайте перед обедом китайских газет."
 
Последнее редактирование:

pvvx

Активный участник сообщества
вот они восемь разрядов:
if(z > 255) z = 255;
-----------------------------------
Не запивайте свежие огурцы молоком
WDRV из прошивки F=1000, прием по WiFi:
ADC14Bits.gif
ADC_no_k.gif
ADC_xx.gif
Это контроль, принятый на ADC 24 бита тестового сигнала (DAC = полные 16 бит 0..1.2В):
ADC-DAC_gen_test.gif
 
Последнее редактирование:

nikolz

Well-known member
WDRV из прошивки F=1000, прием по WiFi:
Посмотреть вложение 1135
Посмотреть вложение 1138
Посмотреть вложение 1137
Это контроль, принятый на ADC 24 бита тестового сигнала (DAC = полные 16 бит 0..1.2В):
Посмотреть вложение 1136
-------------------------
Я Вам верю. Это замечательно.
---------------------------
Согласен,что разрядов больше восьми, их одиннадцать.

----------------------------
Картинки хорошие,
но не ясно, как они должны выглядеть если разрядов будет 11,10,9,8.
Что на них доказывает, что разрядов 14, а АЦП имеет 16?
---------------------------
Для доказательства разрядности нужна таблица цифрового кода на выходе ацп для нескольких шагов входного напряжения. Пока получить эту таблицу не могу, вся надежда на Вас.
---------------------------
Есть еще программы, которые могут прояснить логику (возможно и число разрядов)
--------------------------
У меня получается следующая логика этой прогаммы
void ICACHE_FLASH_ATTR mread_sar_dout(uint16 * buf)
{
volatile uint32 * sar_regs = &SAR_BASE[32]; // 8 шт. с адреса 0x60000D80
int i;
for(i = 0; i < 8; i++) {
int x = ~(*sar_regs++);
int z = (x & 0xFF) - 21;
if(z < 0) z = 0;
z = (z * 279) >> 8; // == (z * 279) / 256 == z * 1.08984375
if(z > 255) z = 255;
buf = (x & 0x700) + z;
}

--------------------------
1) В цикле выполняются некоторые преобразования восьми равноценных значений , полученных с АЦП
Почему восемь ? -понятно.
Почему равноценных? - потому, что выполнение действий не зависит от номера значения
-------------
2) С каждым из значений выполняются следующие действия:
int x = ~(*sar_regs++); - х присваивается очередное инверсное значение из массива sar_regs
int z = (x & 0xFF) - 21; - z присваивается младший байт (8 бит) значения x уменьшенное на 21 ( для SAR вполне правдоподобно так как требуется вычитать остаток)
if(z < 0) z = 0; -- если z <21 то ноль. Предположительно, что это отсечка шума
z = (z * 279) >> 8; -- предположительно - это коррекция нелинейности младших разрядов результата
if(z > 255) z = 255; Предположительно, что это отсечка шума
buf = (x & 0x700) + z; -- т е получаем
buf=x & 111 0000 0000 + z & 1111 1111
из x выделяются старшие 9,10,11 разряды и к ним дописываются 8 младших разрядов из z
------------------------
Таким образом, эта программа корректирует нелинейность в выходном 11-ти разрядном коде 8 значений АЦП
Согласны?
---------------------
Из этого следует, что при каждом обращении к АЦП, мы обрабатывает не одно преобразование АЦП а восемь.
Поэтому скорость преобразования АЦП не 20 кгц , а в восемь раз больше.
--------------------------
Согласны?
 
Последнее редактирование:

nikolz

Well-known member
Вот еще разбор Вашей проги:
-------------------
read_sar_dout(&sar_x[0]);
z=0;
for(y=0;y<8;y++)z+=sar_x[y];
z+=8;
z>>=4;
*ptr++=z;
};
Здесь происходит суммирование 8 значений АЦП, т е добавляем еще 3 разряда к полученным ранее 11
после суммирования прибавляем константу 8 - зачем? не знаю.
Затем сдвигаем вправо на 4 разряда. В результате остается 10 бит.
--------------------------------
Резюме:
Программа получения данных с ацп
При каждом обращении выполняет 8 раз запуск ацп и сохранение этих значений
затем у 8 значений исправляется нелинейность в младших битах и формируется 11 бит
затем эти восемь значений суммируются (результат уже 14 бит) и сдвигаются на 4 бита - результат 10бит
---------------------------------
А хотелось бы при обращении к ацп выполнялось лишь одно преобразование.
Может подскажите как запустить однократно АЦП ( пуск, готовность чтение данных) - один раз, а не восемь.
 

pvvx

Активный участник сообщества
-------------------------
Согласен,что разрядов больше восьми, их одиннадцать.
Ну наконец-то подсчитали :)
но не ясно, как они должны выглядеть если разрядов будет 11,10,9,8.
Никак - у ADC ESP8266 шум за 5-тым битом, с выбросами от работы WiFi.
Что на них доказывает, что разрядов 14, а АЦП имеет 16?
Совместно с шумом, усреднение дает уточнение.
WDRV берет только 8 значений из регистров и суммирует - итого 14 бит (от 0 до 16383).
Запрос у HTTP сервера значения ADC делает дополнительно ещё 4 суммы, и выводит значение в 16 бит (0..65535)
 

nikolz

Well-known member
Ну наконец-то подсчитали :)

Никак - у ADC ESP8266 шум за 5-тым битом, с выбросами от работы WiFi.
Совместно с шумом, усреднение дает уточнение.
WDRV берет только 8 значений из регистров и суммирует - итого 14 бит (от 0 до 16383).
Запрос у HTTP сервера значения ADC делает дополнительно ещё 4 суммы, и выводит значение в 16 бит (0..65535)
--------------------------------------------------
Вы согласны с тем, что это 8 независимых значений АЦП ?
Полагаю, если для ввода c АЦП вырубить WIFI
кроме того вводить по одному значению за раз а не по восемь
кроме того коррекцию нелинейности вынести за цикл ввода массива данных
то получим 11 бит АЦП со скоростью 200 кгц и погрешностью в пределах 1 бита.
Вот за это будем бороться
Согласны?
------------------------------
Можете подсказать регистр и биты отвечающие за однократный запуск ацп проверку готовности и регистр данных?
Спасибо
 

pvvx

Активный участник сообщества
Вы согласны с тем, что это 8 независимых значений АЦП ?
Нет.
Полагаю, если для ввода c АЦП вырубить WIFI
кроме того вводить по одному значению за раз а не по восемь
кроме того коррекцию нелинейности вынести за цикл ввода массива данных
то получим 11 бит АЦП со скоростью 200 кгц и погрешностью в пределах 1 бита.
Нет. 20*8=160 - это раз, а второе что там сплошной шум.
Вот за это будем бороться
Согласны?
Нет.
Сказано уже - ничего из этого хорошего не выйдет.
С выключенным WiFi и не работающей Flash (исполнение из IRAM), вывод в UART:
ADC_ESP8266.gif
Всё равно наблюдается кривизна и нелинейности (пол шкалы и полная отличаются).
Вход ADC ESP напрямую включен на выход ОУ у ЦАП-а на 16 бит с REF=1.200В. За цикл в 10000 c копейкой замеров (прием 10 точек в секунду). Стандартная коррекция - код брался из WDRV прошивки (там есть отличия от китайского).
Вложен файл ADC_ESP8266.xlsx, с пересчетом - множитель 0,0612 чтобы примерно совпало с тестовым генератором (до 4-го знака на максимуме), введено Z0= - 9 mV, т.к. ADC ESP нуль не показывает. Старт генератора и запись запущена руками, т.е. начало не с начала, а где-то секунда :)
Одновременно при данном замере снятый на другой ADC тот-же выход (разница всего в длине проводков к ОУ DAC на 4 см короче, прием на Eval-ADuC7061MK плату):
Test_GEN.gif
Можете подсказать регистр и биты отвечающие за однократный запуск ацп проверку готовности и регистр данных?
Спасибо
Всё подписано в исходниках.
 

Вложения

Последнее редактирование:

nikolz

Well-known member
pvvx,
А как запустить SAR на одно преобразование, а не на восемь?
Судя по исходникам, даже Вам это неизвестно.
---------------------
Правильно я понял, что 16 бит Вы получаете путем суммирования еще 4 значений. Т е усреднением по 32 значениям.
Не пробовали применить медианный фильтр для удаления помех?
Будет более эффективно.
-----------------------
 
Последнее редактирование:

pvvx

Активный участник сообщества
Правильно я понял, что 16 бит Вы получаете путем суммирования еще 4 значений. Т е усреднением по 32 значениям.
Да.
Не пробовали применить медианный фильтр для удаления помех?
Будет более эффективно.
Больному это не поможет - зачем АЦП с линейностью не более 5 бит и опорным источником тоже не точнее 5 бит?
 

nikolz

Well-known member
Да.
Больному это не поможет - зачем АЦП с линейностью не более 5 бит и опорным источником тоже не точнее 5 бит?
Очень даже поможет.
Есть задачи в которых источник аналогового сигнала имеет нелинейную характеристику и приходится ее корректировать.
Нет никакой разницы корректировать лишь источник или суммарную характеристику источника и ацп.
Поэтому главное это -скорость преобразования, повторяемость и число разрядов - для максимального динамического диапазона.
А остальное можно скорректировать в цифре.
 
Сверху Снизу