Boa noite garagistas, estou com um problemão que não estou conseguindo resolver. Vamos lá.

No meu esp32, criei duas tarefas, uma atrelada ao núcleo 0 e outra ao núcleo 1.

A do núcleo 0 é responsável por controlar um dimmer e ler um sensor de temperatura ds18b20, ajusta a saída do dimmer (triac) conforme a temperatura lida.

A tarefa do núcleo 1 é responsável por fazer a parte da comunicação, ou seja, tem um webserver rodando lá, que quando há um cliente conectado manda o html que está salvo na memoria do esp... Ai está o problema, pois quando vou ler o html no spiffs ele da pane e reinicia devido a interrupção do núcleo 0. Pesquisei se é possível cancelar as interrupções e depois retoma-las e vi que não é possível, pois um núcleo não pode acessar o outro.

Alguém tem alguma ideia de como contornar este problema?

Se eu usar o esp fora da rede elétrica (nao havendo interrupções do zero cross) o webserver funciona certinho. Se eu usar o esp na rede elétrica, as interrupções são realizadas normalmente e ele controla corretamente o dimmer. Agora se eu usar as duas coisas ao mesmo tempo o esp reinicia porque estou usando o spiffs e há interrupções do outro núcleo no meio.

Então, é possível usar spiffs com interrupções?

print do terminal serial anexo, e o erro é o seguinte: Guru Meditation Error: Core 0 panic'ed (Cache disabled but cached memory region accessed)

Código que estou usando: https://pastebin.com/fjnza3HR

São códigos de exemplo que achei na internet.

Exibições: 1172

Anexos

Responder esta

Respostas a este tópico

Olá.

  Não sei o que pode ser, mas estou desconfiado desse trecho pq as variáveis dentro de uma interrupção precisam ser volatile e vc não pode ficar chamando coisas complexas. Mesmo uma conta com float (não é o caso) precisa ser evitado. Não sei se é possivel chamar de dentro de uma interrupção uma função de controle de interrupções. É muito pesado... 

Se tirar esse trecho funciona ?

  1. void IRAM_ATTR setTimerPinLow(){ // executa as configuracoes de pwm e aplica os valores da luminosidade ao dimmer no tempo em que ra ficar em low
  2.   timerToPinLow = timerBegin(1, 80, true);
  3.   timerAttachInterrupt(timerToPinLow, &ISR_turnPinLow, true);
  4.   timerAlarmWrite(timerToPinLow, TRIGGER_TRIAC_INTERVAL, false);
  5.   timerAlarmEnable(timerToPinLow);
  6. }

Oi Eduardo,

não é esse o problema, na verdade eu o contornei com uma forma meio inusitada, criei duas variaveis de controle volateis, e entao nelas eu "desatacho" a interrupção externa e após ler a memória spiffs eu "atacho" a interrupção novamente. Ou seja, removo as interrupções no momento que preciso usar o spiffs.

Assim consegui contornar, não resolve, mas ajuda. Se alguém tiver ideias melhores...

Boa noite Mateus, 

O ESP32 tem todos os GPIOS configuráveis, pelo que sei. 

Você esta usando o GPIO 2 para a interrupção do Zero cross da rede elétrica. 

Acho que você pode desabilitar essa porta no núcleo 1. Você já pesquisou isso? 

https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-ref...

External Peripheral Interrupts

Disabling and enabling external interrupts from another core is allowed.

Dependendo das limitações de tempo das suas operações, um outra opção seria usar o RTOS

RTOS com ESP32: Como Programar Multitarefas  (muito bom!) 

https://blog.eletrogate.com/rtos-com-esp32-como-programar-multitare...

No manual  ESP32 Technical Reference Manual:

https://www.espressif.com/sites/default/files/documentation/esp32_t...

3.3.3 Allocate Peripheral Interrupt Sources to Peripheral Interrupt on CPU  (página 38) 

Allocate peripheral interrupt source Source_X to CPU (PRO_CPU or APP_CPU)
Set PRO_X_MAP_REGor APP_X_MAP_REGto Num_P. Num_P can be any CPU peripheral interrupt
number. CPU interrupts can be shared between multiple peripherals (see below).


• Disable peripheral interrupt source Source_X for CPU (PRO_CPU or APP_CPU)
Set PRO_X_MAP_REGor APP_X _MAP_REGfor peripheral interrupt source to any Num_I. The specific
choice of internal interrupt number does not change behaviour, as none of the interrupt numbered as
Num_I is connected to either

Vai ter que ler, estudar e pesquisar. 

O acesso ao sistema de arquivos não é assíncrono e tem um delay. Você não deve esperar o retorno de uma leitura de arquivos para um processo de tempo-real, então o ideal é carregar o arquivo para uma variável previamente. Outra opção é carregar algo como um "Loading" com meta refresh de, por exemplo, 2 segundos. Enquanto isso seu processo pode carregar a página para a memória e o refresh vai poder realimentar a requisição com o novo valor.

Uma forma de fazer IPC é criar uma task que gerencie uma queue, usar um mutex ou algo do tipo. 

O SPIFFS está sendo descontinuado, recomendo (como mera sugestão) que já passe a utilizar o LittleFS.
https://www.dobitaobyte.com.br/sistema-de-arquivos-no-esp8266/

Se precisar de um gerenciador de arquivos para o ESP8266 e ESP32:
https://www.dobitaobyte.com.br/espfilemanager-gerenciador-de-arquiv...

O vídeo do gerenciador de arquivos:

https://youtu.be/Vbi9dyfyFfo

RSS

© 2024   Criado por Marcelo Rodrigues.   Ativado por

Badges  |  Relatar um incidente  |  Termos de serviço