Go Down

Topic: Nahezu gleiche zeitungenauigkeit auf zwei verschiedenen Arduinos (Read 3512 times) previous topic - next topic

big-maec

Hi,

na ist doch alles geklärt. Jetzt können auch richtige Anfänger die das hier lesen wenigstens abschätzen auf was sie sich einlassen wenn Sie  ein Uhren Projekt realisieren.
Gruesse
big-maec

Lena

So ganz kann ich Euer Problem nicht nachvollziehen.
Meine Uhr läuft nun seit einer Woche ohne Synchronisation vom Rechner und die Abweichung beträgt gerade mal 4 Sekunden.
Als Hardware komm ein Atmega8 mit 8MHz-Quarz auf dem Steckbrett zum Einsatz, es sind 20 Igittipfui-50ms-Delays, die obligatorischen Millis und noch etwas Spielkram für gedimmte Hintergrundbeleuchtung und Thermoneter in der Software und der Quarz ist ein ganz normaler (verm. 25ppm) ohne Abgleichkapazität.
Kann das nur Glück sein und mein Quarz ist gerade soviel zu schnell, wie meine "Sünden" Zeit und Interupts verschlucken, oder liegt das Problem der geschilderten Ungenauigkeiten doch woanders.
Entschuldigt meine dumme Frage, aber ist es sicher, daß wirklich der Quarz und nicht versehentlich der unkalibrierte Oszillator verwendet wird?
Für die, die es interessiert hier mein Sketch:
Code: [Select]
/*
* TimeSerialDateStrings.pde
* example code illustrating Time library date strings
*
* This sketch adds date string functionality to TimeSerial.pde
*
*/
#include <Time.h> 
#include <LiquidCrystal.h>
const int led_heartbeat_Pin = 2;  // pin that the blink LED is attached to
const int lightSensorPin = A0;    // pin that the sensor is attached to (vcc>ldr>A0>4.7k>gnd)
const int tempSensorPin = A1;    // pin that the sensor is attached to (vcc>3,3k>tsens+>10k>A1>10k>gnd tempsens->gnd)
const int led_dim_Pin = 9;        // pin that the dimmed LED is attached to

boolean heartbeat = true;
int mode = 0;    // switch telling what to display

const int sample = 20;  // number of samples for temperatur integration
int sumRaw;      // sum of temperature samples
float sumAverage;  //  sum over 16 loops fetching 20 samples
float celsius;    // result in degree celsius
float fahrenheit;    // result in degree celsius
const float tempCorrection = 4;

int rawLight = 0;         // the lightsensor value
int lightValue = 0;         // remapped light value
const int lightMin = 50;        // minimum sensor value
const int lightMax = 850;           // maximum sensor value

LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

#define TIME_MSG_LEN  11   // time sync to PC is HEADER followed by unix time_t as ten ascii digits
#define TIME_HEADER  'T'   // Header tag for serial time sync message
#define TIME_REQUEST  7    // ASCII bell character requests a time sync message

void setup()  {
  pinMode(led_heartbeat_Pin, OUTPUT);  //  define as digital output
  pinMode(lightSensorPin, INPUT);    //  define as analog input
  pinMode(tempSensorPin, INPUT);    //  define as analog input
  analogReference(INTERNAL);    //  use the 2.56V internal referece at atmega8
  lcd.begin(8, 2);          //  DEM16101 16*1 display is organized as 8*2
  Serial.begin(9600);
  setSyncProvider( requestSync);  //set function to call when sync required
  Serial.println("Waiting for sync message");
}

void loop(){
  digitalWrite(led_heartbeat_Pin, heartbeat);
  heartbeat = !heartbeat;
  if (mode > 16){    //  reset modecounter if 10 sec time + 3 sec date + 3 sec temp  displayed
    mode = 0;
    sumAverage = 0;
  }
  mode += 1;    //  increment displaymode counter

  rawLight = analogRead(lightSensorPin);  // read the light sensor
  lightValue = map(rawLight, lightMin, lightMax, 255, 0);  // apply the calibration to the sensor reading
  lightValue = constrain(lightValue, 0, 255);  // in case the sensor value is outside the range seen during calibration

  analogWrite(led_dim_Pin, lightValue);  // fade the LED using the calibrated value:

  sumRaw = 0;    //  reset raw temperature sum
  for (int i = 0; i < sample; i++){    //  read 20 samples from temp in
    delay (50);     //  wait 50ms to give adc time and define heartbeat to 20*50ms
    sumRaw += analogRead(tempSensorPin);    //  summerize 20 readings
  }
  sumAverage += (sumRaw/sample);
  celsius = (((float(sumAverage) / mode)/2) - 273.15 + tempCorrection); //
  fahrenheit = (( celsius * 9 ) / 5 ) + 32;

  if(Serial.available() ){
    processSyncMessage();
  }
  if(timeStatus()!= timeNotSet){
    digitalClockDisplay(); 
    if (mode <= 10){
      timeLcdDisplay();
    }
    else if (mode <=13){
      dateLcdDisplay();
    }
    else if (mode <=16){
      tempLcdDisplay();
    }
  }
}

void timeLcdDisplay(){
  lcd.clear();
  lcd.setCursor(0,0);
  printLcdDigits(hour());
  lcd.print(":");
  printLcdDigits(minute());
  lcd.print(":");
  printLcdDigits(second());
  lcd.setCursor(0,1);
  lcd.print(" Uhr");
}

void dateLcdDisplay(){
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print(dayShortStr(weekday()));
  lcd.print(" ");
  lcd.print(day());
  lcd.print(". ");
  lcd.setCursor(0,1);
  lcd.print(monthShortStr(month()));
  lcd.print(" ");
  lcd.print(year());
}

void tempLcdDisplay(){
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print(celsius);
  lcd.print(" C");
  lcd.setCursor(0,1);
  lcd.print(fahrenheit);
  lcd.print(" F");
}

void printLcdDigits(int digits){
  // Utility function for digital clock display: prints leading 0
  if(digits < 10)
    lcd.print('0');
  lcd.print(digits);
}
void digitalClockDisplay(){
  // digital clock display of the time
  Serial.print(hour());
  printDigits(minute());
  printDigits(second());
  Serial.print(" ");
  Serial.print(dayShortStr(weekday()));
  Serial.print(" ");
  Serial.print(day());
  Serial.print(" ");
  Serial.print(monthShortStr(month()));
  Serial.print(" ");
  Serial.print(year());
  Serial.print(" ");
  Serial.print(celsius);
  Serial.println(" C");
}

void printDigits(int digits){
  // utility function for digital clock display: prints preceding colon and leading 0
  Serial.print(":");
  if(digits < 10)
    Serial.print('0');
  Serial.print(digits);
}

void processSyncMessage() {
  // if time sync available from serial port, update time and return true
  while(Serial.available() >=  TIME_MSG_LEN ){  // time message consists of a header and ten ascii digits
    char c = Serial.read() ;
    Serial.print(c); 
    if( c == TIME_HEADER ) {       
      time_t pctime = 0;
      for(int i=0; i < TIME_MSG_LEN -1; i++){   
        c = Serial.read();         
        if( c >= '0' && c <= '9'){   
          pctime = (10 * pctime) + (c - '0') ; // convert digits to a number   
        }
      }   
      setTime(pctime);   // Sync Arduino clock to the time received on the serial port
    } 
  }
}

time_t requestSync()
{
  //  Serial.print(TIME_REQUEST,BYTE); 
  Serial.write(TIME_REQUEST);
  return 0; // the time will be sent later in response to serial mesg
}


Bleiben verschwenderische 2 Byte(!) in einem Atmega8 ohne Bootloader frei  ]:D

Also es lohnt sich offensichtlich durchaus auch mal Versuche ohne RTC-Chip zu wagen, obgleich die Dinger wirklich klasse sind - keine Frage.

LG Lena
„Zwei Dinge sind unendlich, das Universum und die menschliche Dummheit, aber bei dem Universum bin ich mir noch nicht ganz sicher."

Albert Einstein

derder

Lena, ich stimme dir voll und ganz zu, wie du sicher bei mir gelesen hast komme ich auch auf absolut normale abweichungen (innerhalb der vom hersteller angegeben maßstäbe), wenn ich einen ATmega328 auf einem steckbrett mit 16MHz quarz betreibe ;) meine messungen weisen lediglich daraufhin das die in den käuflich erwerbbaren arduinos verbauten quarze ziemlich unpräzise sind.

Lena

Können die wirklich so grottenschlecht sein, so daß die von Dir beobachteten Abweichungen auftreten?
Das wäre ja normalerweise nur noch als Ausschuß zu betrachten!
Die Dinger werden ja von jedem Keramikresonator mit "Hallo LC-Kreis" begrüßt :D
Na dann wühlt mal schön in Euren Grabbelkisten oder schaut bei Eurem Händler des Vertraues vorbei und holt Euch einen halbwegs brauchbaren Quarz, den so wird das ja auch irgendwann mal für den Baudrategenerator der UART eng.

LG Lena
„Zwei Dinge sind unendlich, das Universum und die menschliche Dummheit, aber bei dem Universum bin ich mir noch nicht ganz sicher."

Albert Einstein

derder

da ich eigentlich ohnehin nie vor hatte die 20 euro platine irgendwo zu verbauen ist mir das eigentlich ziemlich egal, was am ende fertig irgendwo landet besteht dann eh aus nem atmega328 und selbstgekauftem quarz auf steckbrettern oder rasterplatinen...

Go Up