Offline
Jr. Member
Karma: 1
Posts: 65
3ª Idade ... in the house
|
 |
« on: March 09, 2013, 08:54:12 am » |
Boas,
Gostava de saber qual é a melhor maneira de gerir o tempo com o arduino sem ser com a função delay() que bloqueia o programa todo
Estou a usar neste momento a lib TIMER o que faz o trabalho mas acho muito chato cada ver ter que declarar t.every(xxxx, xxx) gostava guardar o tempo tipo numa array e la ir testar se o testo já passou ou não mas não sei como fazer nem se é uma boa ideia ... falei numa array pois tenho muito delay a usar
Cpts
Zé tretas
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Sr. Member
Karma: 4
Posts: 254
|
 |
« Reply #1 on: March 09, 2013, 04:24:57 pm » |
Fala ai Zé tretas, eu sofro do mesmo mal. Esse é um problema que vejo nos microcontroladores, o delay para tudo e a implementação de threads ainda me parece um pouco confuso. O site http://code.google.com/p/arduino-threads/ esta nos meu favoritos para eu ver quando tiver algum tempo, o que esta difícil ultimamente rs Eu uso algo parecido com o abaixo para que blocos/métodos sejam executados dentro de intervalos: #define TempSensor 0 #define StepperMotorX 1
//Array de timers int intDelay[] = {0,0,0,0}; //Array para armazenar a ultima execução unsigned long longLastMillis[] = {0,0,0,0};
void setup(){ intDelay[TempSensor] = 500; intDelay[StepperMotorX] = 15; }
void loop (){ unsigned long currentMillis = millis(); //verifico se o tempo já passou para executar o método if (currentMillis - longLastMillis[TempSensor] >= intDelay[TempSensor]) { //chamada do método de leitura dos sensores longLastMillis[TempSensor] = currentMillis; } }
Mas, como sempre, depende da aplicação, por exemplo, subistituir um delay entre duas partes de um mesmo bloco me forcou a criar dois blocos e um outro array tipo executar[TempSensor] = true. Assim, um método é executado após x milesimos de segundo: #define TempSensor 0 #define StepperMotorX 1
//Array de timers int intDelay[] = {0,0,0,0}; //Array para armazenar a ultima execução unsigned long longLastMillis[] = {0,0,0,0};
//Array para definir se o método será executado boolean Execute[] = {false, false, false, false};
void setup(){ Execute[TempSensor] = true; intDelay[TempSensor] = 500; intDelay[StepperMotorX] = 15; }
void loop (){ ReadSensor(); }
void ReadSensor(){ unsigned long currentMillis = millis(); //verifico se o tempo já passou para executar o método if ((Execute[TempSensor] == true) && currentMillis - longLastMillis[TempSensor] >= intDelay[TempSensor]) { //códigos... longLastMillis[StepperMotorX] = currentMillis; Execute[StepperMotorX] = true; //para que seja executado após o tempo definido em intDelay[StepperMotorX] longLastMillis[TempSensor] = currentMillis; } }
void StepperX() { unsigned long currentMillis = millis(); //verifico se o tempo já passou para executar o método if (Execute[StepperMotorX] == true && (currentMillis - longLastMillis[StepperMotorX] >= intDelay[StepperMotorX])) { //chamada do método de leitura dos sensores longLastMillis[StepperMotorX] = currentMillis; Execute[StepperMotorX] = false; //Evita que seja executado novamente } }
no exemplo acima, o método do sensor é executado o tempo todo (a cada 500 millis por causa do execute = true), mas o método stepperMotor só é executado após 15 millis depois de ser definido o execute = true pelo método. Vamos aguardar para ver se trazem outras soluções 
|
|
|
|
|
Logged
|
|
|
|
|
'round the world...
Offline
Edison Member
Karma: 20
Posts: 2308
|
 |
« Reply #2 on: March 09, 2013, 05:37:02 pm » |
O delay para tudo é perpetuado pelos senhores do Arduino que teimam em meter exemplos com delays absurdos. O delay é uma funcão que faz parte da biblioteca de C para AVRs e, ao contrário do que muita gente pensa ao ler os problemas de usar delay(), tem imensa utilidade e não pode simplesmente ser tirada da biblioteca. O problema é que o delay deve ser usado apenas para pequenas temporizacões. Estamos a falar de dezenas de milisegundos no máximo. Mas como isso não está limitado e a malta do Arduino mete isso como um exemplo, a maior parte das pessoas acha que é perfeitamente normal fazer delays de segundos... ou pior... minutos como já vi.
A solucão do Mortis é a mais correcta no Arduino. Se tiveres um RTC também podes usar isso para temporizar, mas aí só para intervalos de minutos ou horas.
Quanto a threads... enfim... tenho de ver a performance do microcontrolador para ver se realmente é uma solucão decente. No entanto, acho que provavelmente é apenas para os programadores de alto nível se entreterem com microcontroladores. LOL
|
|
|
|
|
Logged
|
Eu não sou o teu criado. Se respondo no fórum é para ajudar todos mediante a minha disponibilidade e disposição. Responder por mensagem pessoal iria contra o propósito do fórum e por isso evito-o. Se realmente pretendes que eu te ajude por mensagem pessoal, então podemos chegar a um acordo e contrato onde me pagas pela ajuda que eu fornecer e poderás então definir os termos de confidencialidade do meu serviço. De forma contrária toda e qualquer ajuda que eu der tem de ser visível a todos os participantes do fórum (será boa ideia, veres o significado da palavra fórum). Nota também que eu não me responsabilizo por parvoíces escritas neste espaço pelo que se vais seguir algo dito por mim, entende que o farás por tua conta e risco.
Dito isto, mensagens pessoais só se forem pessoais, ou seja, se já interagimos de alguma forma no passado ou se me pretendes convidar para uma churrascada com cerveja (paga por ti, obviamente).
|
|
|
|
Offline
Jr. Member
Karma: 1
Posts: 65
3ª Idade ... in the house
|
 |
« Reply #3 on: March 10, 2013, 08:10:17 am » |
Boas, Mortis eu também já fiz algo assim só que usei uma array de 2 dimensões (ou la como de diz em português), mas acho um método muito cansativo e quando o tamanho do programa aumenta fica tudo muito confuso ... mas como sou novato nisto (infelizmente não em tudo  ) pensava que existia algo mais simples e mais compreensível para uma manutenção e desenvolvimento futuro do programa em que estou a mexer visto que uso muitas pausas. PS: se alguém tiver algo a propor sou todos ouvidos Cpts Zé tretas
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Sr. Member
Karma: 4
Posts: 254
|
 |
« Reply #4 on: March 10, 2013, 09:49:36 am » |
O delay para tudo é perpetuado pelos senhores do Arduino que teimam em meter exemplos com delays absurdos.
Muito bem colocado bubulindo, delay de minutos é doído, as pessoas se esquecem que o microcontrolados para no delay. Mas pelo que vemos, muitos que usam arduino são aventureiros (o pior é que estou neste meio rs) e não possuem domínio em relação a microcontroladores e lógica de programação. E concordo que isso é o mínimo que devemos saber. A solucão do Mortis é a mais correcta no Arduino. Se tiveres um RTC também podes usar isso para temporizar, mas aí só para intervalos de minutos ou horas.
Minha solução ainda tem um problema a ser solucionado, quando millis retorna ao zero, mas como minhas aplicações ainda são de coisas que funcionam por poucas horas, não corri à procura de soluções. Quanto a threads... enfim... tenho de ver a performance do microcontrolador para ver se realmente é uma solucão decente. No entanto, acho que provavelmente é apenas para os programadores de alto nível se entreterem com microcontroladores. LOL
É, a coisa parece complexa mesmo rs... Mas é bom para distrair um pouco. Quem sabe não subimos um pouco o nível. mas como sou novato nisto (infelizmente não em tudo  ) pensava que existia algo mais simples e mais compreensível para uma manutenção e desenvolvimento futuro do programa em que estou a mexer visto que uso muitas pausas. Zé tretas, Somos todos novatos em alguma área, pois estamos sempre a aprender, e quando ficamos bons em uma área no aventuramos em outra, e somos novatos novamente rs Sim, diz-se array de 2 dimensões aqui também  , eu fiz de uma só para facilitar o entendimento. A lógica que coloquei pode ser encapsulada em uma lib, mas cai na solução que ja utilizas (timer lib). Vamos ver se alguém tem alguma outra solução, pois eu não consigo pensar em nada alem dos bons e velhos IFs e variáveis ^^
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Jr. Member
Karma: 1
Posts: 65
3ª Idade ... in the house
|
 |
« Reply #5 on: March 10, 2013, 10:00:40 am » |
Boas Minha solução ainda tem um problema a ser solucionado, quando millis retorna ao zero, mas como minhas aplicações ainda são de coisas que funcionam por poucas horas, não corri à procura de soluções.
penso se usares algo do estilo te deves safar ... if (abs (currentMillis - longLastMillis[TempSensor] >= intDelay[TempSensor])) { //chamada do método de leitura dos sensores longLastMillis[TempSensor] = currentMillis;
Cpts Zé tretas
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Sr. Member
Karma: 4
Posts: 254
|
 |
« Reply #6 on: March 10, 2013, 10:39:50 am » |
penso se usares algo do estilo te deves safar ... if (abs (currentMillis - longLastMillis[TempSensor] >= intDelay[TempSensor])) { //chamada do método de leitura dos sensores longLastMillis[TempSensor] = currentMillis;
Zé Tretas, obrigado pela dica! 
|
|
|
|
|
Logged
|
|
|
|
|
'round the world...
Offline
Edison Member
Karma: 20
Posts: 2308
|
 |
« Reply #7 on: March 10, 2013, 05:24:59 pm » |
Minha solução ainda tem um problema a ser solucionado, quando millis retorna ao zero, mas como minhas aplicações ainda são de coisas que funcionam por poucas horas, não corri à procura de soluções.
Se subtraires, creio que não tens problema algum... e não precisas do abs. Experimenta este programa: #include <Arduino.h> /* what really happens with timer function at millis() rollover? lets test it. */ unsigned long fakeMillis = 4294967290; //set fakeMillis to a number near the rollover point unsigned long mark = fakeMillis; // set a time marker start of timer //long mark = fakeMillis; // try other type variables //int mark = fakeMillis; void setup() { Serial.begin(9600); } void loop() { do { ++fakeMillis; //increment faketimer Serial.println(fakeMillis); // prints "timer output" through rollover event Serial.println(fakeMillis-mark); //perform typical subtraction for timer does it work through rollover? delay(1000); } while (fakeMillis>1); // whatever keep looping }
mas como sou novato nisto (infelizmente não em tudo  ) pensava que existia algo mais simples e mais compreensível para uma manutenção e desenvolvimento futuro do programa em que estou a mexer visto que uso muitas pausas. Usas pausas para quê? Em português array é vector. Mas pouca gente usa essa definicão.
|
|
|
|
|
Logged
|
Eu não sou o teu criado. Se respondo no fórum é para ajudar todos mediante a minha disponibilidade e disposição. Responder por mensagem pessoal iria contra o propósito do fórum e por isso evito-o. Se realmente pretendes que eu te ajude por mensagem pessoal, então podemos chegar a um acordo e contrato onde me pagas pela ajuda que eu fornecer e poderás então definir os termos de confidencialidade do meu serviço. De forma contrária toda e qualquer ajuda que eu der tem de ser visível a todos os participantes do fórum (será boa ideia, veres o significado da palavra fórum). Nota também que eu não me responsabilizo por parvoíces escritas neste espaço pelo que se vais seguir algo dito por mim, entende que o farás por tua conta e risco.
Dito isto, mensagens pessoais só se forem pessoais, ou seja, se já interagimos de alguma forma no passado ou se me pretendes convidar para uma churrascada com cerveja (paga por ti, obviamente).
|
|
|
|
Offline
Sr. Member
Karma: 4
Posts: 254
|
 |
« Reply #8 on: March 10, 2013, 08:35:07 pm » |
Se subtraires, creio que não tens problema algum... e não precisas do abs.
Bubulindo, obrigado novamente!  Teu programa já esclareceu. Resultado: 4294967291 1 4294967292 2 4294967293 3 4294967294 4 4294967295 5 0 6 1 7 2 8 No passado eu guardava "currentMillis + intDelay" em uma variável, e temia que isso causaria o estouro do unsigned long (as vezes nos previnimos até para o que não precisa rs), mas deu para perceber que quando a variável passa do limite (4294967295 + 1) ela recebe o valor zero. Excrevi o código abaixo para deixar mais claro que água rs unsigned long currentMillis = 4294967290; unsigned long longLastMillis = 4294967290;
void setup() { Serial.begin(9600); }
void loop() { currentMillis ++; if (currentMillis - longLastMillis >= 2) { Serial.print(currentMillis); Serial.print(" - "); Serial.print(longLastMillis); Serial.println(" >= 2"); longLastMillis = currentMillis; delay(1000); } }
e o resultado foi: 4294967292 - 4294967290 >= 2 4294967294 - 4294967292 >= 2 0 - 4294967294 >= 2 2 - 0 >= 2 4 - 2 >= 2 6 - 4 >= 2 8 - 6 >= 2 10 - 8 >= 2 12 - 10 >= 2 Agradeço novamente! Ah, aqui no Brasil também é difícil ver algum dizendo vetor...
|
|
|
|
|
Logged
|
|
|
|
|
BHZ, MG, Brazil
Online
Sr. Member
Karma: 9
Posts: 307
Android developer; Arduino enthusiast
|
 |
« Reply #9 on: March 14, 2013, 02:07:07 pm » |
Em português array é vector. Mas pouca gente usa essa definicão.
Discordo veementemente! Na engenharia a gente somente dizia vetor, cálculo vetorial, etc, etc, etc. Dizer "array" é coisa de programador que ainda não fez Cálculo!!!
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Sr. Member
Karma: 4
Posts: 254
|
 |
« Reply #10 on: March 14, 2013, 02:36:54 pm » |
Dizer "array" é coisa de programador que ainda não fez Cálculo!!!
kkkkk então vivo, e estou, nesse grupo!!!  Nunca fiz um curso de programação ou cálculo 
|
|
|
|
|
Logged
|
|
|
|
|
'round the world...
Offline
Edison Member
Karma: 20
Posts: 2308
|
 |
« Reply #11 on: March 15, 2013, 12:58:31 am » |
Em português array é vector. Mas pouca gente usa essa definicão.
Discordo veementemente! Na engenharia a gente somente dizia vetor, cálculo vetorial, etc, etc, etc. Dizer "array" é coisa de programador que ainda não fez Cálculo!!! Eu já fiz todas as cadeiras de Engenharia... e não vejo o problema de usar ambos os nomes no campo da programação em C. Tu vês?
|
|
|
|
|
Logged
|
Eu não sou o teu criado. Se respondo no fórum é para ajudar todos mediante a minha disponibilidade e disposição. Responder por mensagem pessoal iria contra o propósito do fórum e por isso evito-o. Se realmente pretendes que eu te ajude por mensagem pessoal, então podemos chegar a um acordo e contrato onde me pagas pela ajuda que eu fornecer e poderás então definir os termos de confidencialidade do meu serviço. De forma contrária toda e qualquer ajuda que eu der tem de ser visível a todos os participantes do fórum (será boa ideia, veres o significado da palavra fórum). Nota também que eu não me responsabilizo por parvoíces escritas neste espaço pelo que se vais seguir algo dito por mim, entende que o farás por tua conta e risco.
Dito isto, mensagens pessoais só se forem pessoais, ou seja, se já interagimos de alguma forma no passado ou se me pretendes convidar para uma churrascada com cerveja (paga por ti, obviamente).
|
|
|
|
Offline
Sr. Member
Karma: 4
Posts: 254
|
 |
« Reply #12 on: March 15, 2013, 08:21:48 am » |
O importante é ser entendido... ouvimos coisas piores por ai rs
|
|
|
|
|
Logged
|
|
|
|
|
|