Já criei um tópico no Forum do ESP32, mas se alguém quiser e puder me ajudar ficarei grato ! 

https://www.esp32.com/viewtopic.php?f=19&t=11261#p45725

Em fevereiro de 2018, eu rodei o Sketch (arduino IDE) no meu projeto - voltímetro digital ESP32 e funcionou perfeitamente - Arduino IDE 1.8.5 e ESP32 Board versão 1.0.0. 


A comunicação do voltímetro digital é feita com o chip PCF8574 através da interface I2C.

 Resistores de Pullups são 3K3 ohms (VCC = 3.3V) 

https://www.elektormagazine.com/labs/esp32-digital-voltmeter#/comme...

https://github.com/Gustavomurta/ESP32-DVM

O sketch completo para teste do voltímetro ESP32 é esse :

https://github.com/Gustavomurta/ESP32-DVM/blob/master/ESP32_DVM7135...

Agora, com o Arduino 1.8.9 e o ESP32 Board versão 1.0.2, a interface I2C funciona em um modo louco. O pino SCL envia pulsos contínuos e o SDA envia dados errados (verificados com o analisador lógico). 


Meu ESP32 é DOIT ESP32 DevKit V1 e o hardware está OK e verificado com meu scanner I2C. (baseado em Nick Gammon). 

https://github.com/Gustavomurta/ESP32-DVM/blob/1bc07438e89eac39ae83...


Pesquisando este problema com a opção Debug (Arduino IDE), encontrei essas mensagens, mas não sei o que significam :

debugFlags=0x00000000
[I][esp32-hal-i2c.c:311] i2cDumpDqData(): Debug Buffer not Enabled
[I][esp32-hal-i2c.c:354] i2cDumpInts(): Debug Buffer not Enabled
[D][esp32-hal-i2c.c:1336] i2cProcQueue(): Busy Timeout start=0x303a4, end=0x303a4, =0, max=50 error=0
[E][esp32-hal-i2c.c:318] i2cDumpI2c(): i2c=0x3ffbebe0
[I][esp32-hal-i2c.c:319] i2cDumpI2c(): dev=0x60013000 date=0x16042000
[I][esp32-hal-i2c.c:321] i2cDumpI2c(): lock=0x3ffb84ec
[I][esp32-hal-i2c.c:323] i2cDumpI2c(): num=0
[I][esp32-hal-i2c.c:324] i2cDumpI2c(): mode=1
[I][esp32-hal-i2c.c:325] i2cDumpI2c(): stage=3
[I][esp32-hal-i2c.c:326] i2cDumpI2c(): error=0
[I][esp32-hal-i2c.c:327] i2cDumpI2c(): event=0x3ffb8570 bits=0
[I][esp32-hal-i2c.c:328] i2cDumpI2c(): intr_handle=0x3ffb85a0
[I][esp32-hal-i2c.c:329] i2cDumpI2c(): dq=0x3ffb854c
[I][esp32-hal-i2c.c:330] i2cDumpI2c(): queueCount=1
[I][esp32-hal-i2c.c:331] i2cDumpI2c(): queuePos=0
[I][esp32-hal-i2c.c:332] i2cDumpI2c(): errorByteCnt=0
[I][esp32-hal-i2c.c:333] i2cDumpI2c(): errorQueue=0
[I][esp32-hal-i2c.c:334] i2cDumpI2c(): debugFlags=0x00000000

Alguém pode me ajudar? Obrigado ! 

Exibições: 2456

Responder esta

Respostas a este tópico

Bom dia Rui,

O I2C scanner funciona perfeitamente.

https://github.com/Gustavomurta/ESP32-DVM/blob/1bc07438e89eac39ae83...

rst:0x1 (POWERON_RESET),boot:0x17 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:1
load:0x3fff0018,len:4
load:0x3fff001c,len:928
ho 0 tail 12 room 4
load:0x40078000,len:8424
ho 0 tail 12 room 4
load:0x40080400,len:5868
entry 0x4008069c

I2C scanner. Scanning ...
Found address: 32 (0x20)
Found 1 device(s).

I2C scanner. Scanning ...
Found address: 32 (0x20)
Found 1 device(s).

I2C scanner. Scanning ...
Found address: 32 (0x20)
Found 1 device(s).

DEBUG mode :

- clique em Ferramentas (Arduino IDE)

- logo abaixo da  placa DOIT ESP32

- Em Core Debug level altere para Debug

Olá Murta.

      Recentemente, devido a uma questão postada pela Marcela de Souza, analisei a implementação da Interface SPP da biblioteca Bluetooth do ESP32. Fiz a análise para a LIB da IDF 1.0.0 e também para a 1.0.2 (que se não me engano é a mais recente). Em ambas encontrei "falhas" graves de implementação. São falhas que permitem que a LIB funcione corretamente em praticamente todos os exemplos disponíveis no pacote disponibilizado pela Espressif (que são praticamente todos muito simples). Mas se vc precisar de algo mais "sofisticado", provavelmente terá grandes problemas de funcionamento (chegando inclusive a provocar resets automáticos, como o famigerado "Guru Meditation Error Exception").

      Não fiz esta análise para a I2C do ESP32. Mas recentemente fiz uma análise detalhada da implementação da LIB I2C (o "Wire") para o Arduino AVR (UNO, Nano, Mega, etc). Não fiquei surpreso quando vi grandes problemas de temporização. Claro que ela funciona, mas está quase sempre "por um fio" pra falhar. E mundo afora, de tempos em tempos aparece alguém reclamando que a I2C do Arduino "travou". Vendo a LIB em detalhes, ficou bem evidente pra mim, os motivos destes problemas, mas não convém falar sobre eles aqui, porque são muito técnicos e assim tomariam um bom tempo.

      Assim, caso a LIB I2C do ESP32 tenha sua lógica de funcionamento baseada na implementação da mesma LIB para o AVR, então poderá haver grande chance de que tenha os mesmos problemas (ou semelhantes).

      Neste momento, não poderei analisar a LIB I2C do ESP32, no nível de detalhes necessário pra chegar a alguma conclusão mais concreta, e assim poder ajudar no sentido de tentar elucidar o problema que vc relatou no seu Projeto com o PCF8574 e TLC7135.

      Mas tomei a liberdade de ajustar o código que vc disponibilizou, e eventualmente este ajuste poderá resolver o problema que vc relatou.

      Caso vc teste o código e conclua que é efetivo, então postarei a metodologia que utilizei.

      Importante: observe que na rotina "TLC7135_ADC_ISR", eu deixei comentadas as duas linhas de início e fim da "Execução Atômica". Aconselho que teste dessa forma primeiro. Caso tenha um bom resultado, então deixe assim mesmo. Do contrário, vc pode descomentar as duas linhas (tem que ser as duas juntas), e ver se consegue um resultado efetivo.

      Mas veja que na rotina "TLC7135_INFO_get",  isto não é opcional, e obrigatoriamente tem que ter as duas linhas de início e fim da "Execução Atômica" (sem elas, ocorrerão falhas no funcionamento).

      Segue o código ajustado:    ESP32_DVM7135_PT_V1_01.zip

      Espero ter ajudado.

      Abrçs,

      Elcids

Grande Elcids bom dia, 

Muito obrigado pelo esforço em me ajudar. 

Talvez não tenha tido tempo para entender como o meu programa funciona. 

Com o meu programa, como a interface I2C esta maluca, aparece somente a mensagem Over Voltage. 

Com o seu programa não aparece nenhuma mensagem na Console serial. 

Mas com o analizador lógico percebi que esta tentando ler o PCF8574. E esta conseguindo ler dois Bytes com FF ! (meu programa lê um byte somente de cada vez). 

Mas o que esta me intrigando é a linha de SCL que esta pulsando direto quando não existe comunicação.

Isso mudou. Não era assim. 

A leitura dos dados do Voltímetro é feita através de interrupções no pino GPIO4 (-STB do TLC7135). 

Circuito Digital do ESP32 Voltmeter: 

https://www.elektormagazine.com/labs/esp32-digital-voltmeter#/comme...

No meu design, os sinais de controle STROBE, RUN / HOLD e CLOCK IN são conectados diretamente no ESP32. CLOCK IN recebe pulsos de clock do ESP32. RUN / HOLD é usado para ativar / desativar o DVM. 
E a linha STROBE gera interrupções de pulsos no ESP32. Os outros dados do DVM são adquiridos pelo expansor de E / S PCF8574. Ele usa a interface I2C para se comunicar com o ESP32. 

O único dígito usado é DS5 (MSD) para receber dados, e a saída BUSY é ignorada. A saída do STROBE é LOW cinco vezes por ciclo de conversão. Cada pulso STROBE do TLC7135 gera uma interrupção no ESP32 para adquirir dados BCD e status das linhas de sobretensão, subtensão e polaridade. 

O primeiro pulso STROBE ocorre no meio do DS5 quando os dados BCD para o dígito mais significativo (MSD) estão disponíveis nas saídas B1 – B8. O STROBE também pulsa LOW durante os seguintes sinais DS4 a DS1, após o qual o STROBE permanece HIGH até o próximo ciclo de conversão. Portanto, apenas um pulso STROBE ocorre para cada seleção de dígito e cada STROBE corresponde a um dígito BCD na ordem MSD-para-LSD. Ao ler os dados do ADC, o ESP32 simplesmente lê os dados do BCD durante cada pulso do STROBE e armazena os dados na memória correspondentes ao número de pulsos do STROBE recebidos. 

Vejam que beleza de imagem como era antes ! Tudo funcionando corretamente. 

Vejam que a linha SCL não ficava pulsando direto. 

Elcids , 

Veja que seu programa esta lendo dois bytes FF.

Depois irei analisar o seu programa. Pode ser uma luz no fim do tunel ! 

olá Murta.

      Vi no "Wire.h", que eles sugerem que o método "Wire.begin()" seja utilizado caso a Interface "trave". Claro, isto é um método arcaico de recuperação.  Mas também vi que na ISR do seu código original Murta, vc colocou justamente o "Wire.begin()" antes de iniciar a leitura do I2C.

      Dado a temporização da figura que vc postou acima, peço que acrescente o "Wire.begin()" na minha ISR (a rotina "TLC7135_ADC_ISR"), imediatemente antes da linha onde está o "Wire.requestFrom". Peço que teste assim, pois se o I2C estiver travando, então isto poderá fazer sua recuperação.

      Abrçs,

      Elcids

Elcids, o seu programa funciona diferentemente do meu...

A leitura do byte do PCF8574 só pode ser feita quando o dado é válido.

O pino D5 (dgito 5) tem que ser verificado. 

O sintoma continuou - não parece nada na console serial. 

Obrigado. 

//--------------------------------------------------
byte I2C_data;
static byte index = 0;
//--------------------------------------------------
// portENTER_CRITICAL_ISR( &PCF_port_MUX ); // inicia trecho de execucao atomica.
//..................................................

Wire.begin();      // Start I2C
Wire.requestFrom( PCF8574_address, 1 );     // faz leitura de um byte do TLC7135
I2C_data = Wire.read();       // obtem byte do TLC7135, lido via I2C (PCF8574).

//..................................................

Então Murta,

      Realmente os dois códigos tem princípio diferente.

      No entanto, a ISR "TLC7135_ADC_ISR" também é cadenciada pela Interrupção gerada pelo "Strobe". Ou seja, após o ADC terminar uma conversão, os 5 pulsos sequenciais do Strobe, cada um, gera uma Interrupção, chamando a ISR "TLC7135_ADC_ISR".

      Nesta ISR, também é detectado o "D5", o que é feito nesta linha:

    if ( I2C_data & TLC_D5_mask ) index = 0;   // faz sincronismo dos bytes.

    Com isso, os Bytes lidos são inseridos sequencialmente num Vetor, e posteriormente extraídos do mesmo, com todas as informações relevantes, as quais são tratadas uma a uma (mas isso fora  da  ISR, pois ali não é o lugar correto de fazer isso).

     Não tenho o TLC7135 para testar. Então, assim que possível, tentarei fazer uma emulação do mesmo, para verificar a efetividade da leitura dos Bytes via I2C.

      Independente disso, outra sugestão: para obter uma temporização mais folgada, reduza pela metade o clock do TLC7135, ou seja, de 480kHz para 240kHz. Isso dobrará o intervalo de tempo entre dois pulsos "Strobe" consecutivos, o que dará mais tempo para o tratamento correto das Interrupções e do próprio Protocolo I2C (que está rodando a apenas 100kHz, dando uma margem muito estreita para quaisquer flutuações na temporização geral, principalmente se "mexeram" na LIB I2C na versão 1.0.2).

     Abrçs,

     Elcids

Elcids, 

Já tinha testado o meu programa com vários clocks. Até 100 KHz. E o mesmo sintoma.

O meu problema não esta na rotina de interrupção.

A interrupção esta ocorrendo corretamente ( vide imagem do analisado lógico). 

O problema esta somente na rotina de leitura do I2C. Simples, mas não esta funcionando. 

void ReadData ()
{
     Wire.begin(); // Start I2C
     Wire.requestFrom(PCF8574, 1); // Read One Byte from PCF8574
     pcfData = Wire.read(); // Byte Read
}

Obrigado pelo esforço ! 

Sim, o problema provavelmente é temporização, pois ela é crítica neste ponto do I2C que mostro na figura a seguir (seta rosa), durante a subida do pulso 9 do SCL:

      Assim, mesmo uma alteração sutil feita na LIB I2C, poderá em alguma situação, ocasionar um travamento do Protocolo de Hardware.

      Como tenho o PCF8574, logo que possível, farei testes para verificar a questão.

       Já o TLC7135, apenas se eu conseguir emular.

      Abrçs,

      Elcids

Legal Elcids, 

Só lembrando que tudo funcionava perfeitamente, no ano passado. 

Acho que alguma mudança feita na Biblioteca Wire do ESP32   pode estar conflitando com algum timer que esteja usando (PWM Channel 0). 

Ou algum detalhe de conflito que eu ainda não descobri. 

Bom dia José Gustavo Abreu Murta,

carreguei o seu sketch no meu ESP32  (MH ET LIVE ESP32DevKIT).

Como não disponho do TCL7135,  e não teria interrupt,

forcei a chamada à função TestData() no loops(), dando um delay de 5 ms entre cada chamada da rotina.

O meu PCF8574 tem o endereço 0x39.

Aparecem leitura em ambos poirts SCL e SDA.

Anexo o arquivo do analisador lógico.

RV

Anexos

Rui obrigado pelo apoio ! 

Veja que na linha SCL esta pulsando direto !! Isso não é normal !  (Entre as rotinas de I2C)

O seu teste esta recebendo vários NAKs. Funcionou corretamente o seu programa ?

RSS

© 2024   Criado por Marcelo Rodrigues.   Ativado por

Badges  |  Relatar um incidente  |  Termos de serviço