[RESOLVIDO] sugestões para problemas com delay/millis/interrupção

Prezados,


recentemente recebi ajuda nesse projeto, tive alguns avanços mas não consegui ainda concluir, por isso recorro a vocês mais uma vez.

O que o sistema faz:
Busca garantira a alimentação de cargas de forma ininterrupta oriunda de fontes distintas (não é um no-break)
As fontes são alimentadas em 220VAC e fornecem uma tensão de 12VCC (Fonte A e Fonte B)
O sistema opera de duas formas, MANUAL e AUTOMÁTICO

Quando em automático ele verifica o flag PRIOR que indica qual a fonte prioritária, depois verifica o flag de status da fonte SVA ou SVB e depois a entrada de sincronismo SINCRO que indica que as fontes estão em fase (esta indicação é uma entrada do arduino que vem de um circuito eletrônico a parte, responsável por controlar o ângulo de fase das fontes e também por fazer o acionamento através de chaves estáticas). Atendendo a todas as condições a troca de fontes e feita de forma instantânea, desliga uma, liga outra.

Quando em manual a sequência de verificação é a mesma descrita acima, mas com a ressalva de que a comutação não pode ocorrer de forma instantânea, deve haver um retardo entre o desligamento e a entrada da outra fonte. (proteção). Esse retardo deve ser da ordem de 20 milissegundos

Obs: testes com delay não funcionam, ficam muito acima do tempo. Testes com millis() consegui chegar a 300 milissegundos, abaixo disso se perde. Tentei interrupção mas não consegui aplicar no programa. Acredito que resolva com interrupção, mas não soube aplicar.

A análise dos tempos de comutação são realizadas com osciloscópio.

Estou anexando o código e um desenho simplificado.

muito obrigado,

Teodoro

Exibições: 148

Anexos

Responder esta

Respostas a este tópico

Você pode estar utilizando a opção delayMicroseconds(20), no lugar de Delay, é bem util ele faz umas pausas imperceptíveis.

https://www.arduino.cc/en/Reference/DelayMicroseconds

você pode tambem estar utilizando a biblioteca SimpleTimer, para o uso do millis ela é bem pratica quando o código fica muito grande, simplifica a programação.

http://playground.arduino.cc/Code/SimpleTimer

Tiago,

farei os testes sugeridos e retorno.

obrigado

Olá Tiago

testes com delayMicro não funcionaram. Ficam com tempo superior ao desejado.

Vou testar com a biblioteca SimpleTimer

Senhores,

dando continuação as tentativas de resolver um problema, hoje encontrei na página abaixo o seguinte texto

http://playground.arduino.cc/Main/AVR

Timing

The Arduino delayMicroseconds() function creates the shortest delay possible from within the Arduino language. The shortest delay possible is about 2 us (microseconds).

Se diz que o menor tempo possível é de 2us então para o tempo de 16ms ele deveria fazer com uma mão nas costas.

Alguma ideia do motivo de não respeitar o tempo que requisito?

Senhores,

descobri a origem do erro, mas não sei como resolver.

em determinado trecho do código existe:

if (SELECAO == "CA" && SVA ) {
  CB = false;
  Delay_ms(delay_comutacao);
  CA = true;
}


if (SELECAO == "CB" && SVB) {
  CA = false;
  Delay_ms(delay_comutacao);
  CB = true;
}

como a condição do if se mantém por determinado tempo, ele entra no if por sucessivas vezes gerando delay repetidamente, quando deveria gerar somente uma vez, até que mudasse a condição.

Tentei com um flag mas não rolou. Existe uma maneira mais elegante de fazer isso?

Teodoro, desculpe não ter respondido, eu comecei a responder no meu celular, mas acabei não publicando.

Eu iria dizer exatamente isso, o problema do delay é que o controlador para de executar uma ação para poder aguardar o delay, enquanto no millis ele continua contando o tempo, como se fosse uma Thread, alias de uma pesquisada sobre Threads no arduino existem excelente dicas.

tente refazer a lógica com swithcase é um pouco mais rapido a leitura que os if's

http://playground.arduino.cc/Referencia/SwitchCase

ou tente fazer algo assim mais quebradinho

if (SELECAO == "CA" && SVA&&   CB ==true) {
  CB = false;
  Delay_ms(delay_comutacao);

}

if (SELECAO == "CA" && SVA&&   CB ==false) {
  CA = true;
  Delay_ms(delay_comutacao);

}

Tiago,

quanto a questão de executar mais de uma vez consegui resolver com flag.
Agora como mudou a questão de comandos sucessivos de delay vou refazer os testes.
Retorno mais tarde

Senhores,

hoje descobri um gatilho na programação que passou despercebido. Eu estava aplicando um delay entre duas atribuições de set em variáveis bool.

Mais adiante no código que faço os acionamentos conforme seus valores. Isso nuncao iria funcionar mesmo.

Então substitui as atribuições das variáveis bool pelos respectivos acionamentos (digitalWrite) e mesmo assim não temporiza


Já não sei mais o que fazer com esse simples comando

digitalWrite(o_CARGA_A, false);

delay de 16ms

digitalWrite(o_CARGA_A, true);

resultado dos testes:

com millis ele aciona direto e com delayMicroseconds ele dá um delay de 2s para um tempo requisitado de 16000us = 16ms

Por favor alguma luz!

olá Senhores!

uma luz por favor!

RSS

Destaques

Registre-se no
Lab de Garagem
Clicando aqui

Convide um
amigo para fazer
parte

curso gratis de arduino

© 2017   Criado por Marcelo Rodrigues.   Ativado por

Badges  |  Relatar um incidente  |  Termos de serviço