ESP23 импульсы на ноге есть. Но осциллограф их не видит.

progman
Offline
Зарегистрирован: 26.01.2019

Нужен хелп. Использую для приема сигнала от датчика пины 36 39 34 35.

В даташите помечены как input only и без подтягивающих резисторов внутри ( типа аналоговые они ). подтягивающие резисторы 330 ом на плате имеются. 

Проинициализировно так: pinMode( inputChannels[ i ], INPUT_PULLUP );

Далее в цикле читаю состояние ноги: int v = digitalRead( inputChannels[ i ] );

и если состояние изменилось с 1 на 0 то вызываю функцию счетчика импульсов.

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

Если подключить датчик то левые импульсы не исчезают но и импульсы с датчика начинают приходить.

Длина паразитного импульса от 0,05 - 1,5 миллисекунды.

Длина импульса с датчика примерно 2-3 миллисекунды.

Перепробовал с десяток плат - думал может брак. У всех поведение идентичное.

Иногда после перезагрузки платы импульсы не появляются.

Закономерность не нашел. Что делать? Куда копать?

andycat
andycat аватар
Offline
Зарегистрирован: 07.09.2017

У меня похожая ситуация с 26 и 25 пином были - прерывания срабатывали.

1 попробовать другие пины
2 отключить АЦП

http://arduino.ru/forum/programmirovanie/esp32-srabatyvanie-preryvaniya-...

progman
Offline
Зарегистрирован: 26.01.2019

нашел таки помехи осциллографом по шине питания. 4-6 микросекунды импульсы с амплитудой 30 милливольт.

источник - плата питания с встроенной подзарядкой аккумулятора.

Очевидно аналоговым пинам достаточно 30 милливольт чтобы состояние с 1 на 0 переключить и обратно

Клапауций 003
Offline
Зарегистрирован: 20.07.2019

progman пишет:

Очевидно аналоговым пинам достаточно 30 милливольт чтобы состояние с 1 на 0 переключить и обратно

очевидно, что пины без аппаратной подтяжки - ставь резисторы снаружи.

INPUT_PULLUP для этих пинов не имеет смысла.

!всё отсальное ты выдумал - уровни 0 и 1 для этих пинов аналогичны отсальным.

progman
Offline
Зарегистрирован: 26.01.2019

весело.

digitalRead походу потоко не безопасная функция.

у меня на первом ядре обрабатывается вся графика и опрос тачскрина дисплея идет.

на втором ядре постоянно читаются пины от датчиков и кидаются эвенты что дисплею рисовать.

В общем если в первом потоке тачскрина не опрашивать то все отлично.

если все делать в одном потоке - то тоже отлично.

progman
Offline
Зарегистрирован: 26.01.2019
uint32_t addr = SPI_CMD_REG( SPI_PORT );
(( volatile uint32_t* )addr)[ 0 ] = ( ( volatile uint32_t* )addr )[ 0 ] | SPI_USR;
while( ( ( volatile uint32_t* )addr )[ 0 ] & SPI_USR );
 
вот эта последовательность команд внутри драйвера LCD ( тут работа с драйвером SPI ) приводит к генерации импульса на GPIO36, GPIO39
 
при этом что странно чтение/запись происходят по адресу  0x3ff65000 а GPIO находятся по адресу 0x3ff44000 и чтение/запись ну никак в адресное пространство структуры GPIO не попадает
 
Клапауций 003
Offline
Зарегистрирован: 20.07.2019

progman пишет:

вот эта последовательность команд внутри драйвера LCD ( тут работа с драйвером SPI ) приводит к генерации импульса на GPIO36, GPIO39

тебя же производитель пердупредил, что 36 39 34 35 - input only.

не пиши ничего в эти пины - только читай из этих пинов, если желаешь нормальной работы.

progman
Offline
Зарегистрирован: 26.01.2019

Клапауций 003 пишет:

тебя же производитель пердупредил, что 36 39 34 35 - input only.

не пиши ничего в эти пины - только читай из этих пинов, если желаешь нормальной работы.

Мил человек, вы вообще читаете внимательно? Я ничего не пишу в эти пины :-/

Есть два потока. Один поток только читает из 36 39 34 35

Второй поток рисует на экран картинку. Дисплей ILI9341, протокол SPI. Я ковырялся там пол дня в итоге нашел место где драйвер SPI пишет битовую маску по адресу 0x3ff65000, а второй поток в это время ловит изменение уровня на пинах 36 39 34 35 ( и только на них!!! ).

Чтение для быстроты идет напрямую из GPIO.in и GPIO.in1.val

При этом адрес GPIO откуда чтение идет 0x3ff44000. 

 

progman
Offline
Зарегистрирован: 26.01.2019

Вот кратчайший код чтобы багу поймать. Создаем два потока для ядра 0 и ядра 1.

Поток 1 работает на ядре 0:

for( ;; )
{

    uint32_t addr = SPI_CMD_REG( VSPI  );//addr == 0x3ff65000 
    uint32_t v    = ( ( uint32_t* )addr )[ 0 ] | ( 1 << 18 );
    v             = (( uint32_t* )addr )[ 0 ];

    delay( 1 );
}

Поток 2 работает на ядре 1:

uint32_t gpioin1val = GPIO.in1.val;
for(;;)
{
  if( gpioin1val != GPIO.in1.val )
      exit( ); // <- there is a bug
  delay( 1);
};

В результате записи байта по адресу 0x3ff65000 изменяются биты по адресу 0x3ff44000 ( это GPIO.in1.val  )

Если повесить прерывания на 36 39 34 35, то прерывания срабатывают. Такое поведение адресного пространства SPI в документации не описано. Саппорт разумеется морозится.

Клапауций 003
Offline
Зарегистрирован: 20.07.2019

progman пишет:

Нужен хелп. Использую для приема сигнала от датчика пины 36 39 34 35.

В даташите помечены как input only и без подтягивающих резисторов внутри ( типа аналоговые они ). подтягивающие резисторы 330 ом на плате имеются. 

Проинициализировно так: pinMode( inputChannels[ i ], INPUT_PULLUP );


невнимательно читаю - сказано: только для чтения, но всё равно пишу в пин пуллап...
какие, в пень подтяжки 330 Ом? - публикуй схему.

progman
Offline
Зарегистрирован: 26.01.2019

INPUT_PULLUP   или INPUT роли не играет совершенно в данном случае.

Зачем тут схема тоже не понимаю, впрочем мне не жалко: