[DUVIDA] o millis tem o mesmo tempo real no arduino rodando em 3.3v 8mhz e no 5v 16mhz ?

Galera,

    Tô sem um arduino que funcione em 3.3v 8mhz aqui comigo, dai me pintou uma duvida:

     Será que o millis()  funciona na mesma velocidade se usado em um arduino rodando em 3.3v 8Mhz em comparação com outro rodando em 5V 16Mhz???

     Tipo se eu der um delay de 10.000 millis() em um e no outro,  o tempo real de parada vai ser o mesmo ?

      E se não será que dá pra corrigir e fazer os dois rodarem de forma igual ?

Exibições: 359

Responder esta

Respostas a este tópico

Acredito que o comando millis() seja baseado em milésimos de segundo e não em ciclos de maquina, sendo assim, ele deverá ser igual em qualquer frequência.

millis()

Description

Returns the number of milliseconds since the Arduino board began running the current program. This number will overflow (go back to zero), after approximately 50 days.

Quando compila o seu programa na IDE do Arduino, você selecionou que a placa roda em 8MHz ?

Para ter certeza, analise as rotinas de millis. Parece que o programa escolhe o clock :

https://github.com/arduino/Arduino/blob/2bfe164b9a5835e8cb6e194b928...

#elif F_CPU >= 8000000L
// for the 8 MHz internal clock

Ou mais fácil, faça o teste com o seu Arduino 8 MHz...

Ao Rodrigo,

    Cara, valeu por responder, obrigado.

    Porem, tudo que conta tempo, é baseado em algo, no caso dos microcontroladores no cristal,  ou seja, um equipamento não tem como saber o que é segundos ou milesimos de segundos,  até onde eu saiba ele reaje a um numero de pulsos do cristal e assim faz a associação.

    Porem, no caso dos arduinos a 8 e a 16Mhz eu não sei se ha uma correção interna, por isso a duvida.

É que a função interna do millis lê qual a velocidade setada no processador e se baseia no ciclo de maquina para gerar o tempo, mas essa questão é interna no compilador, o usuário não precisa fazer nada.

Um milissegundo em 8Mhz é x ciclos, em 16Mhz é y, e assim por diante..Mas essa parte quem faz é a IDE.

Olá Zé gustavo,

     Sim, quando compilamos um codigo e o enviamos pra um microcontrolador que possua bootloader arduino, temos que informar qual é o tipo de bootloader que esta nele, isso se usarmos só o microcontrolador e a estrutura standalone,  fora isso, se usar o arduino mesmo, tem que dizer se estamos upando um arduino pro mini 3.3v 8mhz  ou pra um arduino Uno 5v 16mhz.

   

     Adorei, sua dica de leitura da biblioteca wiring.c,  tem muita coisa lá realmente.

   

Parece que ele faz a correção de acordo com o clock do cristal,  acho que a resposta tá nessa parte aqui:

/* Delay for the given number of microseconds. Assumes a 1, 8, 12, 16, 20 or 24 MHz clock. */
void delayMicroseconds(unsigned int us)
{
// call = 4 cycles + 2 to 4 cycles to init us(2 for constant delay, 4 for variable)
// calling avrlib's delay_us() function with low values (e.g. 1 or
// 2 microseconds) gives delays longer than desired.
//delay_us(us);
#if F_CPU >= 24000000L
// for the 24 MHz clock for the aventurous ones, trying to overclock
// zero delay fix
if (!us) return; // = 3 cycles, (4 when true)
// the following loop takes a 1/6 of a microsecond (4 cycles)
// per iteration, so execute it six times for each microsecond of
// delay requested.
us *= 6; // x6 us, = 7 cycles
// account for the time taken in the preceeding commands.
// we just burned 22 (24) cycles above, remove 5, (5*4=20)
// us is at least 6 so we can substract 5
us -= 5; //=2 cycles
#elif F_CPU >= 20000000L
// for the 20 MHz clock on rare Arduino boards
// for a one-microsecond delay, simply return. the overhead
// of the function call takes 18 (20) cycles, which is 1us
__asm__ __volatile__ (
"nop" "\n\t"
"nop" "\n\t"
"nop" "\n\t"
"nop"); //just waiting 4 cycles
if (us <= 1) return; // = 3 cycles, (4 when true)
// the following loop takes a 1/5 of a microsecond (4 cycles)
// per iteration, so execute it five times for each microsecond of
// delay requested.
us = (us 2) + us; // x5 us, = 7 cycles
// account for the time taken in the preceeding commands.
// we just burned 26 (28) cycles above, remove 7, (7*4=28)
// us is at least 10 so we can substract 7
us -= 7; // 2 cycles
#elif F_CPU >= 16000000L
// for the 16 MHz clock on most Arduino boards
// for a one-microsecond delay, simply return. the overhead
// of the function call takes 14 (16) cycles, which is 1us
if (us <= 1) return; // = 3 cycles, (4 when true)
// the following loop takes 1/4 of a microsecond (4 cycles)
// per iteration, so execute it four times for each microsecond of
// delay requested.
us = 2; // x4 us, = 4 cycles
// account for the time taken in the preceeding commands.
// we just burned 19 (21) cycles above, remove 5, (5*4=20)
// us is at least 8 so we can substract 5
us -= 5; // = 2 cycles,
#elif F_CPU >= 12000000L
// for the 12 MHz clock if somebody is working with USB
// for a 1 microsecond delay, simply return. the overhead
// of the function call takes 14 (16) cycles, which is 1.5us
if (us <= 1) return; // = 3 cycles, (4 when true)
// the following loop takes 1/3 of a microsecond (4 cycles)
// per iteration, so execute it three times for each microsecond of
// delay requested.
us = (us 1) + us; // x3 us, = 5 cycles
// account for the time taken in the preceeding commands.
// we just burned 20 (22) cycles above, remove 5, (5*4=20)
// us is at least 6 so we can substract 5
us -= 5; //2 cycles
#elif F_CPU >= 8000000L
// for the 8 MHz internal clock
// for a 1 and 2 microsecond delay, simply return. the overhead
// of the function call takes 14 (16) cycles, which is 2us
if (us <= 2) return; // = 3 cycles, (4 when true)
// the following loop takes 1/2 of a microsecond (4 cycles)
// per iteration, so execute it twice for each microsecond of
// delay requested.
us = 1; //x2 us, = 2 cycles
// account for the time taken in the preceeding commands.
// we just burned 17 (19) cycles above, remove 4, (4*4=16)
// us is at least 6 so we can substract 4
us -= 4; // = 2 cycles

Ou seja,

    Em teoria o millis() vai ser o mesmo independente do clock do cristal.

    Pooooorem,  hoje pela manha fiz uma montagem com um sensor optico daqueles que tem em imprssoras, e ouve diferença sim na pratica,  o resultado foi muito proximo,  mas tive que fazer uma correção baseada em porcentagem,  o resultado foi de 2% de defasagem.

    Como foi um teste simples,  vou fazer outras montagens,  tipo eu só comparei um pro mini 3.3v 8mhz com um arduino Uno 5v 16mhz,   a ideia é montar dois standalones um com bootloader e montagem de 3.3v 8mhz e o outro com 5v 16mhz  mas ambos com o mesmo microcontrolador e mesma montagem, exceto os cristais.

   Ai comparando vou ver se continua dando essa diferença de 2%.

   Apesar que é pouca coisa, pois eu imaginada que daria 50% de diferença.

    Teoria é bom,  mas meter a mão na massa e testar é otimo kkk.

Rodrigo,

    Como visto acima,  todo ciclo de maquina é baseado no cristal,  mais especificamente nos temporizadores time0, time1, time2. veja aqui:  (  http://playground.arduino.cc/Main/TimerPWMCheatsheet  )

     No caso do millis, mais especificamente no time0,  se mudar ele,  ele muda o tempo do millis.

     A duvida que estou é realmente o quanto isso afeta o sistema com um cristal de 8 ou 16mhz,  mas parece que eles fazem correção pra ficarem proximos,

Tava pensando (divagando ! )

    Se realmente for isso, ou seja, mesmo com clocks e tensões diferente, tudo é corrigido no bootloader do arduino,  é ai que vejo o quanto é maravilhoso esses sistema.

    De certo que tem suas falhas, como colocar camada, sobre camada de codigo pra acesso a processos,  mas vale a pena o preço a ser pago,  se pensarmos na produtividade.

    Então quem quiser que fale mal do arduino.   Esse sisteminha é simplesmente incrivel.

Incrível é a programação assembly rsrsrsrsrsrsr

RSS

© 2024   Criado por Marcelo Rodrigues.   Ativado por

Badges  |  Relatar um incidente  |  Termos de serviço