Go Down

Topic: influence de la fréquence du quartz sur la fonction millis (Read 1 time) previous topic - next topic

Rigolo

Bonjour,
Certaines cartes comme la DCcduino uno (clone de uno) ont un quartz à 12Mhz ou lieu de 16 pour d'autres. Ceci a t il une influence quelconque sur les fonctions faisant reference au temps comme Millis. En d'autre termes, le même programme a t il un comportement different suivant le type de carte, lorsqu'on utilise les fonctions comme delay ou millis?
Merci

B@tto

Salut,

Non car c'est pris en compte. Rdv dans wiring.c dans \arduino 1.0.5\hardware\arduino\cores\arduino pour trouver micros() qui sert de base à millis() :

Code: [Select]
unsigned long micros() {
unsigned long m;
uint8_t oldSREG = SREG, t;

cli();
m = timer0_overflow_count;
#if defined(TCNT0)
t = TCNT0;
#elif defined(TCNT0L)
t = TCNT0L;
#else
#error TIMER 0 not defined
#endif

 
#ifdef TIFR0
if ((TIFR0 & _BV(TOV0)) && (t < 255))
m++;
#else
if ((TIFR & _BV(TOV0)) && (t < 255))
m++;
#endif

SREG = oldSREG;

return ((m << 8) + t) * (64 / clockCyclesPerMicrosecond());
}


on remarque à la fin clockCyclesPerMicrosecond() => rdv dans le arduino.h toujours dans le même dossier :

Code: [Select]
#define clockCyclesPerMicrosecond() ( F_CPU / 1000000L )

Et F_CPU c'est la fréquence spécifiée pour ta board dans board.txt situé dans \arduino 1.0.5\hardware\arduino. Exemple pour la UNO :

uno.name=Arduino Uno
uno.upload.protocol=arduino
uno.upload.maximum_size=32256
uno.upload.speed=115200
uno.bootloader.low_fuses=0xff
uno.bootloader.high_fuses=0xde
uno.bootloader.extended_fuses=0x05
uno.bootloader.path=optiboot
uno.bootloader.file=optiboot_atmega328.hex
uno.bootloader.unlock_bits=0x3F
uno.bootloader.lock_bits=0x0F
uno.build.mcu=atmega328p
uno.build.f_cpu=16000000L
uno.build.core=arduino
uno.build.variant=standard
Blog électronique : battomicro.wordpress.com
Photographie : www.interactive-celebration.fr
Fablab de Montpellier : www.labsud.org

BrUnO14200

Salut

Désolé , je décrasse mon tractopelle :D !


Mais je ne comprends pas ton explication @Batoo ... justement les clones ont un quartz à 12MHz donc à mon sens , ça ne peut pas fonctionner ...

J'ai un programme qui tourne , qui me renvoie les secondes écoulées avec un DS1307 et avec la fonction millis() , le tout sur un clone chinois ..

En comparant avec l'heure du PC , j'ai déjà 5 sec de décalage avec millis() et rien avec le DS1307 .. d'où mon interrogation ?!

Projet aquaponique  :https://forum.arduino.cc/index.php?topic=677286.msg4584918#new

kamill

Bonjour,

Personnellement je n'ai jamais vu de clone chinois avec un quartz 12 MHz. Tu es sur de la fréquence du quartz?

fdufnews

La fréquence du quartz utilisé est prise en compte à la compilation et donc la fonction millis (mais pas qu'elle d'ailleurs) en tient compte. Cette fréquence est prise en compte si le compilateur reçoit les bons paramètres de compilation. Sinon évidemment ....
Maintenant la précison sera celle du quartz utilisé sur la carte et là il y a de grosses disparités entre les cartes suivant qu'elles sont équipés d'un quartz ou d'un résonateur piezo (ou va de 100ppm à 1000ppm).
Ensuite la stabilité de la fréquence est fonction de nombreux paramètres (tension d'alimentation, température, ...)

Tu parles de 5s de décalage mais tu ne dis pas sur quelle période de temps donc on ne peux pas trop juger.

@kamill, les seules cartes avec un quartz à 12MHz que j'ai vues, tournaient à cette fréquence pour faire de l'USB à moindre coût en utilisant V-USB.

Artouste

Certaines cartes comme la DCcduino uno (clone de uno) ont un quartz à 12Mhz ou lieu de 16 pour d'autres.
bonjour
non
le QZ de 12 MHz n'est utilisé que pour cadencer le CH340
le 328P utilise normalement un 16 MHz (entre C5 et C6 sur la photo)


BrUnO14200

Bonjour,

Personnellement je n'ai jamais vu de clone chinois avec un quartz 12 MHz. Tu es sur de la fréquence du quartz?
bonjour
non
le QZ de 12 MHz n'est utilisé que pour cadencer le CH340
le 328P utilise normalement un 16 MHz (entre C5 et C6 sur la photo)


Je me suis fait avoir :D ! J'ai effectivement confondu les 2 quartz !

Bon j'ai quand même un delta en 1 heure de mesure avec les fonctions millis() et micros() de l'ordre de 30s , dans le même temps mon DS1307 n'a aucun décalage avec l'heure du PC ..

Si qqun a une explication ...

Mon code de test (écran en I2C comme le DS1307) :

Code: [Select]

#include <OneWire.h>
#include <Wire.h>
#include "RTClib.h"
#include <DataTimeStrings.h>
#include <LiquidCrystal_I2C.h>
#include <SPI.h>

LiquidCrystal_I2C lcd(0x27,20,4);

RTC_DS1307 rtc;
int tps;
int chrono;
int avant;
char buff2[30]="";
int old_tps=0;

float TIME =0;
float TIME2 =0;

void setup(void) {
 
 
//  Serial.begin(9600);
  lcd.begin();
  delay(100);
  rtc.begin();
  delay(100);
  DateTime TOP = rtc.now(); delay(50);

  avant = TOP.second();
 
 


 
}

void loop(void) {
 
 
 
 

  DateTime HEURE = rtc.now(); delay(50);

 
  int maintenant = HEURE.second();
  tps = maintenant - avant ;
 
  if(tps<0){tps = 60 - abs(tps);}
 
 chrono = chrono + tps;
 


 TIME = millis(); 
 TIME2 = micros();

  // lcd.setCursor colonne ligne
  lcd.setCursor(0,0);
  lcd.print("RTC");
  lcd.setCursor(0,1);
  lcd.print("millis()");
  lcd.setCursor(0,2);
  lcd.print("micros()");
 
  lcd.setCursor(13,0);
  lcd.print(chrono);
  lcd.setCursor(13,1);
  lcd.print(TIME/1000,1);
  lcd.setCursor(13,2);
  lcd.print(TIME2/1000000,1);
/*

 Serial.print(chrono);
 Serial.print(" ");
 Serial.print(TIME/1000,1);
 Serial.print(" ");
 Serial.print(TIME2/1000000,1);
 Serial.println(" ");
 
*/

avant = maintenant ;
delay(750);
}




A la base , je voulais utiliser millis() car mon DS1307 a une dérive de quelques minutes par semaine mais là c'est pire ^^ !
Projet aquaponique  :https://forum.arduino.cc/index.php?topic=677286.msg4584918#new

Artouste

Bon j'ai quand même un delta en 1 heure de mesure avec les fonctions millis() et micros() de l'ordre de 30s , dans le même temps mon DS1307 n'a aucun décalage avec l'heure du PC ..

Si qqun a une explication ...
la derive represente ~0.8% , c'est beaucoup , mais pas forcement étonnant avec des résonateurs bas de gamme

68tjs

En cherchant bien sur Ebay, par période (lancement d'un lot de fab de temps en temps ?) on trouve des cartes UNO équipées de quartz.
Il ne faut pas rêver non plus il y a quartz et quartz et tous ne pas au top niveau mais un quartz restera meilleur qu'un résonnateur.

Sinon il y a la solution de trouver un oscillateur à quartz à 16 MHz, de virer le résonateur et ses caps et de connecter la sortie de l'oscillateur sur l'entrée "oscillateur IN" coté atmega Mega.
La précision sera celle de l'oscillateur extérieur.

Autre (possible ? ) solution :
Sur les UNO équipées atmega16U2 il y a toujours un quartz sur le 16U2 (USB oblige) et un résonnateur sur le 328p.
Je me suis toujours demandé s'il n'était pas possible de virer le résonnateur du 328p et de tirer un fil à partir du 16U2.
Est-ce que l'oscillateur du 16U2 ne sera pas trop chargé et continuera d'osciller ?

Go Up