collapse

* Links de Robótica

* Posts Recentes

RN42 e TP-Link MR3020 por doiga
[Ontem às 19:22]


Ajuda Projecto IR / RF por senso
[Ontem às 13:15]


Recomendação de um opamp para um DAC r2r por Njay
[Ontem às 12:33]


Ideias para construir um quadrúpede simples por dropes
[21 de Novembro de 2017, 22:43]


Ajuda com TRIAC por senso
[17 de Novembro de 2017, 18:00]


TV LG White Screen por almamater
[15 de Novembro de 2017, 08:37]


Pergunta sobre prototipagem ( Pesquisa ) por luisjustin
[14 de Novembro de 2017, 23:22]


Medir Agua que está no Poço por Njay
[14 de Novembro de 2017, 13:28]


Amplificador audio por beirao
[12 de Novembro de 2017, 23:43]


Power_OK Enermax por edeweld
[12 de Novembro de 2017, 17:15]

Autor Tópico: como ter um delay ou millis sem este interferir com o loop.  (Lida 3399 vezes)

0 Membros e 1 Visitante estão a ver este tópico.

Offline r16

  • Mini Robot
  • *
  • Mensagens: 337
como ter um delay ou millis sem este interferir com o loop.
« em: 27 de Dezembro de 2014, 19:49 »
vivas companheiros,
tenho o seguinte codigo:

tenho um sensor dht11, que le a temperatura e humidade, e quero ter no mesmo codigo um outro que me ligue um pin durante 5 segundos que espere 20 e volte a ligar o pin por mais 5 segundos e por ai adiante...
so que eu fiz com um delay... e este delay que fiz interfere com o resto do codigo e eu nao queria isso alguem me ajuda a modificar sff:

Código: [Seleccione]
#include <DHT11.h>
int motor = 10; // Motor liga no pino 10 do mini pro
int fogger = 11; // fogger liga no pino 11 do mini pro

int sensor=4;
DHT11 dht11(sensor);
void setup()
{
   
    pinMode(fogger, OUTPUT);
   pinMode(motor, OUTPUT);
   Serial.begin(9600);
  while (!Serial) {
      ;
    }
 }

void loop()
{
digitalWrite(motor, HIGH); //Motor Liga durate 5 segundos
delay(5000);
digitalWrite(motor, LOW);
delay(20000); //Espera 20 segundos


{
  int err;
  float temp, humi;
  if((err=dht11.read(humi, temp))==0)
  {
    Serial.print("temperatura:");
    Serial.print(temp);
    Serial.print(" humidade:");
    Serial.print(humi);
      Serial.println();
  if (humi<=40){
      Serial.print(" FOGGER LIGADO");
       Serial.println();
      digitalWrite(fogger,HIGH);
     }
  if (humi>=50){
      Serial.print(" FOGGER DESLIGADO");
       Serial.println();
         digitalWrite(fogger,LOW);
     }
   
     

   
  delay(DHT11_RETRY_DELAY); //delay for reread
 
 
 }
  }
  }
 
 
 

Offline Njay

  • Mini Robot
  • *
  • Mensagens: 3.141
    • Tróniquices
Re: como ter um delay ou millis sem este interferir com o loop.
« Responder #1 em: 27 de Dezembro de 2014, 19:59 »
Podes usar "multitasking cooperativo":

http://troniquices.wordpress.com/2010/05/24/arduino-a-fazer-varias-coisas-ao-mesmo-tempo/

Se aprenderes a técnica, que é simples, depois fazes qualquer coisa.

Quando já tiveres "pro" podes aprender mais umas coisas no 2º artigo, mas este só tenho em Inglês:

http://embeddeddreams.com/site/2011/07/23/more-on-doing-several-things-at-the-same-time/
« Última modificação: 27 de Dezembro de 2014, 20:03 por Njay »

Offline senso

  • Global Moderator
  • Mini Robot
  • *****
  • Mensagens: 9.402
  • Helpdesk do sitio
Re: como ter um delay ou millis sem este interferir com o loop.
« Responder #2 em: 27 de Dezembro de 2014, 20:07 »
Ou a solução básica, abrir o exemplo blink without delay no IDE do arduino, está lá, comentado e explicado, faz-me confusão como é que tanta gente nem para os exemplos olha  ::)
Avr fanboy

Offline r16

  • Mini Robot
  • *
  • Mensagens: 337
Re: como ter um delay ou millis sem este interferir com o loop.
« Responder #3 em: 27 de Dezembro de 2014, 20:17 »
senso foi a primeira coisa que fiz,...
no entanto esse exemplo faz com que o led pisque 1 em 1 segundo.
nao entendo como é que a partir dele consigo fazer com que ligue 5 seg e espere 20
obrigado

Offline senso

  • Global Moderator
  • Mini Robot
  • *****
  • Mensagens: 9.402
  • Helpdesk do sitio
Re: como ter um delay ou millis sem este interferir com o loop.
« Responder #4 em: 27 de Dezembro de 2014, 20:47 »
É mudar os tempos no if.
Introduz mais que um if, faz um if para meter on, outro para meter off.
Avr fanboy

Offline r16

  • Mini Robot
  • *
  • Mensagens: 337
Re: como ter um delay ou millis sem este interferir com o loop.
« Responder #5 em: 27 de Dezembro de 2014, 22:10 »
ok,,,alterei para:

Código: [Seleccione]
#include <DHT11.h>
    int motor = 13; // Motor liga no pino 10 do mini pro
    int fogger = 11; // fogger liga no pino 11 do mini pro
    unsigned long time = 0;
    int sensor=4;
    int aciona = 0;
    DHT11 dht11(sensor);
    void setup()
    {
       
        pinMode(fogger, OUTPUT);
       pinMode(motor, OUTPUT);
       Serial.begin(9600);
      while (!Serial) {
          ;
        }
     }
     

     
     
     
     
    void loop()
    {
      if(millis() - time < 4999 && aciona ==0)
    {
      digitalWrite(motor,HIGH);
      aciona = 1;
    }
    if (millis() - time > 5000 && millis() - time < 20000 && aciona ==1)
    {
    digitalWrite(motor, LOW);
    time = millis();
    aciona = 0;
    }
     
     
    {
      int err;
      float temp, humi;
      if((err=dht11.read(humi, temp))==0)
      {
        Serial.print("temperatura:");
        Serial.print(temp);
        Serial.print(" humidade:");
        Serial.print(humi);
          Serial.println();
      if (humi<=40){
          Serial.print(" FOGGER LIGADO");
           Serial.println();
          digitalWrite(fogger,HIGH);
         }
      if (humi>=50){
          Serial.print(" FOGGER DESLIGADO");
           Serial.println();
             digitalWrite(fogger,LOW);
         }
       
         
     
       
      delay(DHT11_RETRY_DELAY); //delay for reread
     
     
     }
      }
      }


no entanto o pino 10 fica ligado por 5 segundos depois desliga mas nao volta a ligar passado os 20 segundos.... onde estou a errar?

Offline senso

  • Global Moderator
  • Mini Robot
  • *****
  • Mensagens: 9.402
  • Helpdesk do sitio
Re: como ter um delay ou millis sem este interferir com o loop.
« Responder #6 em: 27 de Dezembro de 2014, 22:24 »
só fazes o update da variavel time num dos milis, para esse tipo de coisas prefiro usar uma variavel para cada if.
Avr fanboy

Offline r16

  • Mini Robot
  • *
  • Mensagens: 337
Re: como ter um delay ou millis sem este interferir com o loop.
« Responder #7 em: 27 de Dezembro de 2014, 22:46 »
nao consigo atinar com isto.... ajuda -me  :o

Offline ralex

  • Mini Robot
  • *
  • Mensagens: 69
Re: como ter um delay ou millis sem este interferir com o loop.
« Responder #8 em: 27 de Dezembro de 2014, 23:29 »

Offline r16

  • Mini Robot
  • *
  • Mensagens: 337

Offline Srgiofonseca

  • Mini Robot
  • *
  • Mensagens: 34
Re: como ter um delay ou millis sem este interferir com o loop.
« Responder #10 em: 28 de Dezembro de 2014, 02:58 »
Eu não percebi bem o que queres
mas se for o que penso teria resolvido assim,
/************************************************************************************
**** Autor: Sérgio Fonseca
**** Data: 28-12-2014
**** Versão: 1.1
****
**** Descrição: Envia para a porta serial a temperatura a cada segundo e ao
**** mesmo tempo executa ciclicamente ligar um LED 5 segundos e desligar 20 segundos
****
**** Observações: Não tem grande precisão no tempo uma vez que cada instrução influencia o tempo
****
***********************************************************************************/

/*____Declarações e variáveis ________________________________*/
int led1=13;         //LED Que acende 5 segundos e esta apagado 20segundos (cíclico)
int sensor=4;       // Sensor de temperatura ligado no pin 4 (analógico)
int contador;        // contador que incrementa aproximadamente a cada 1 segundo
int temperatura;   //variável que guarda o valor da temperatura

/*________________Rotina de configuração ao iniciar o Arduíno______________________*/
void setup()
{
 
  Serial.begin(9600);
  pinMode(led1,OUTPUT);
  contador=0;
}

/*________________Programa____________________________________*/
void loop()
{
  if (contador <4)   
    {ligaled();}       // se contador for menor que 4 chama a função ligaled
  desligaled();       // se for maior que 4 chama a função desligaled

}

/*_______________Função ligaled_______________________________________*/

void ligaled()
{
  digitalWrite(led1, HIGH);        // liga o led
  incrementa();                        // chama a função incrementa
}

/*___________Função desligaled_________________________________________*/

void desligaled()
{
  if (contador > 4)
  {digitalWrite(led1, LOW);}       // se o contador for maior que 4 desliga o led
  incrementa();                         // caso o contador seja inferior a 4 chama a função incrementa
}

/*___________________Função incrementa____________________________________________*/

void incrementa()                            // função que demora aproximadamente um segundo a ser executada
{
//____ trata os dados do sensor de temperatura e envia__________
 
  temperatura = analogRead(sensor);     //Coloca o valor analógico do pino na variavel
  Serial.println("sensor temperatura");   //envia o valor da variável para a porta serie com quebra de linha
  Serial.println(temperatura);
  Serial.println(contador);     

// ________Fim do tratamento de dados a enviar___________       

  contador = contador + 1;              // incrementa o contador
  delay(998);                                 // espera aproximadamente um segundo (1s)
  if (contador == 25)                     // 20 segundos + 5 segundos
  {contador = 0;}                           // inicia o contador
}

/*__________________________FIM____________________________________________________*/


Agradecia que comentassem o código, este é apenas um exemplo.
O fórum serve para (ajudar) aprender e ensinar.
« Última modificação: 28 de Dezembro de 2014, 12:10 por Srgiofonseca »

Offline samc

  • Mini Robot
  • *
  • Mensagens: 403
Re: como ter um delay ou millis sem este interferir com o loop.
« Responder #11 em: 28 de Dezembro de 2014, 15:04 »
O link que enviaram acima está muito claro e deve ter sido só fazer copy paste para ter o problema resolvido
O teu código abaixo "não interfere" com o loop de uma forma um bocado relativa. Ou seja, não está na função principal mas quando é chamado utilizas delays e caso leias o link da adafruit vês que essa não é a forma mais "profissional" de fazeres as coisas
Simplesmente estás a dizer ao microcontrolador para durante esses milisegundos ficar em idle e não executar nenhuma tarefa (de forma simplista)
O ideal é usar a função milis e mais algum código para verificar a alteração no tempo em vez de utilizares delays. É claro que nesse exemplo simples e meio de experimentação não vale a pena elaborar muito o código. Em aplicações mais complexas, isso sim elimina o delay por completo (para mim a única função mais razoável que poderia ter seria na inicializacao do programa em que podes querer estabilizar as leituras de alguns sensores ou escrever algum texto via série para debug)

Offline senso

  • Global Moderator
  • Mini Robot
  • *****
  • Mensagens: 9.402
  • Helpdesk do sitio
Re: como ter um delay ou millis sem este interferir com o loop.
« Responder #12 em: 28 de Dezembro de 2014, 15:40 »
Com ifs e milis(ou implementação caseira do mesmo), por exemplo código retirado de um projecto adormecido para exemplo:
Código: [Seleccione]
if(milis() - lastMilis > 250){
LEDPORT ^= ((1<<LED1));
lastMilis = milis();
//printEncoders();
encoder1Count += encode1_read4();
encoder2Count += encode2_read4();

setDac(0,0,1,encoder1Count);

getPowerData();
debug1();
updateScreen();
}

if(milis() - buttonsMilis > 10){
buttonsMilis = milis();
getBtnStatus();
}

if(milis() - measureMilis > 50){
measureMilis = milis();

}
Avr fanboy

Offline LuísR.A.

  • Mini Robot
  • *
  • Mensagens: 1.223
    • Clube de Robotica
Re: como ter um delay ou millis sem este interferir com o loop.
« Responder #13 em: 28 de Dezembro de 2014, 16:46 »
vou só aproveitar um pouco para perguntar uma cena.

Njay tive uma idea e gostava da tua opinião.
Para fazer tipo 2-3 programas a correr em paralelo poderia fazer isto?

Criar um interrupt periódico com um timer de 1 em 1 ms.
Programa1 começa.
Interrupt é chamado - salta para Programa2.
Interrupt é chamado - salta para Programa3.
Interrupt é chamado - salta para Programa1.
Por ai a fora.

A ideia é ter um interrupt handler que tem tipo um variavel que vai de 0-2, ou seja o numero do programa a correr (usando um if), e chama essa função.
O meu problema é que isto teria de ser de forma a que o interrupt chama-se a função mas era mesmo um Jump, não um jump and link para voltar. Não é?
Claro que teria de ter cuidados para os programas não se atropelarem mas isso é trabalho que teria de ser feito e cuidados a ter. Tambem algumas funções criticas podiam desativar o interrupt por momentos.
Isto seria para um ARM-M0 de 48Mhz ou um MCU mais rápido.
Se disser alguma asneira calem-me :p
Tiva MCU é que é.

Tutoriais Tiva+codigos exemplo:
https://sites.google.com/site/luiselectronicprojects/

Offline senso

  • Global Moderator
  • Mini Robot
  • *****
  • Mensagens: 9.402
  • Helpdesk do sitio
Re: como ter um delay ou millis sem este interferir com o loop.
« Responder #14 em: 28 de Dezembro de 2014, 17:15 »
Tens de guardar stack para garantir que não dás cabo das variaveis todas.
Tens tanto RTOS para micros que até doi, o mais comum actualmente é o ChibiOS, permite fazer o que queres, e muito mais.
Avr fanboy