Tijd programmeren

Arduino specifieke Software
Berichten: 1
Geregistreerd: 07 Dec 2012, 18:58

Tijd programmeren

Berichtdoor Koefoe » 07 Dec 2012, 19:06

Beste forummers,

Ik wil een klok gaan maken met een Arduino(voor school). Ik heb op internet de Time librarie gevonden van Arduino. Alleen krijg ik die niet werkend want ik wil graag zonder een RTC de tijd programmeren. Ik las dat het met die librarie mogelijk moet zijn maar ik kom er niet helemaal uit.

Is dit mogelijk?

Want de RTC komt pas over enkele weken terwijl ik al een prototype moet laten zien op school.

Advertisement

Gebruikers-avatar
Berichten: 700
Geregistreerd: 05 Mrt 2012, 21:56
Woonplaats: Appingedam

Re: Tijd programmeren

Berichtdoor pjh » 08 Dec 2012, 00:49

Dit is zeker mogelijk. Maar zonder rtc moet je wel steeds de huidige tijd instellen.
Makkelijkste manier lijkt me een timer op precies een seconde te zetten.
Het is nu laat, maar ik heb de code daarvoor wel ergens.
Dat heb je precies een seconde teller, zonder dat je hiervoor iets in de loop hoeft te doen.
Mocht je klem zitten, ik kan je moregn wel een rtc toesturen. Heb je het maandag.
Laat maar weten.

Gebruikers-avatar
Berichten: 700
Geregistreerd: 05 Mrt 2012, 21:56
Woonplaats: Appingedam

Re: Tijd programmeren

Berichtdoor pjh » 08 Dec 2012, 04:11

Alle microcontrollers hebben timers.
Deze timers tellen de kloktikken.
Dit doen ze buiten je programma om.
Deze timers zijn wel vanuit je programma te benaderen.

de Arduino heeft een 16Mhz kristal.
Dus 16.000.000 x per seconde.
TIMER1 telt tot 65.536 (16 bits)
Dus per seconde loopt TIMER1 16.000.000 / 65.536 = 244,14 keer "over".

Dit "overlopen" van zo'n TIMER kun je aan een interrupt verbinden.
Een interrupt is een klein stukje code die je zelf bepaalt in je sketch.

Je kunt het overlopen van een timer beinvloeden met een factor 1, 8, 64, 256 en 1024.
Bij een factor 8 loopt de klok dus niet 244,14, maar 30,52 keer per seconde "over".

En dan kun je ook nog opgeven WAAR tussen de 0 - 65.536 de TIMER overloopt.

Wanneer ik de factor op 1 zet en de TIMER al bij 1 laat overlopen, gebeurt dit dus 16.000.000 keer per seconde.

Maar als je een factor 256 neemt en de TIMER laat overlopen bij 62.500 dan krijg je deze berekening:

16.000.000 Hz / 256 = 62.500 Hz
Bij 62.500 loopt TIMER over
Dus: 62.500 / 62.500 = 1 Hz ==> en daar heb je je "ongeveer een seconde" op de arduino zonder RTC.

Omdat de TIMER begint te tellen bij wat je opgeeft, vind je in onderstaande sketch niet het getal 62500 terug, maar 65.536 - 62.500 = 3036. Dat is als het ware 'de voorsprong' die de timer krijgt om precies op tijd bij het "overlopen" op 65536 aan te komen. En hexadecimaal schrijf je 3036 als 0xBDC.

Hier een tabel in Excel, waarin ik een aantal 'mooie' frequenties in Hz heb weergeven. Alleen de frequenties > 1 staan hier. De 1 Hz zelf, staat rechts bovenin de tabel.
Afbeelding

Groet. Hieronder de code die per seconde "tijd" geeft.

Code: Alles selecteren
volatile unsigned long seconden = 0;
unsigned long seconden_oud = 0;

int seco;
int minu;
int uren;

ISR(TIMER1_OVF_vect) {
  TCNT1=0xBDC;
  seconden = seconden+1;
}

void setup() {
  Serial.begin(9600);
 
  TIMSK1=0x01;   //   Bij een overflow wordt dat ISR stukje hierboven uitgevoerd
  TCCR1A = 0x00; // normale functie timer
  TCNT1=0xBDC;  //  0xBDC = 3036 decimaal (stukje vroegtijdige overflow)
  TCCR1B = 0x04; // dit is de deler. 1=1; 2=8; 3=64; 4 = 256; 5=1024
};

void loop () {
  if (seconden_oud != seconden){
   
    seconden_oud = seconden;
    seco = seconden % 60;
    minu = (seconden % (60*60))/60;
    uren = minu/60;

    Serial.print("De Arduino staat ");
    Serial.print(seco);
    Serial.print(" Seconden, ");
    Serial.print(minu);
    Serial.print(" Minuten en  ");
    Serial.print(uren);
    Serial.println("  uur aan.");
  }
};
Laatst gewijzigd door pjh op 08 Dec 2012, 15:58, in totaal 2 keer gewijzigd.

Gebruikers-avatar
Berichten: 700
Geregistreerd: 05 Mrt 2012, 21:56
Woonplaats: Appingedam

Re: Tijd programmeren

Berichtdoor pjh » 08 Dec 2012, 13:15

Heb code even aangepast.
Nu neemt de arduino de tijd over van je computer.
Moet je wel na compileren direct uploaden, anders loopt hij meteen een seconde of wat achter.

Code: Alles selecteren
volatile unsigned long seconden = 0;
unsigned long seconden_oud = 0;

int seco;
int minu;
int uren;

ISR(TIMER1_OVF_vect) {
  TCNT1=0xBDC;
  seconden = seconden+1;
}

void setup() {
  Serial.begin(9600);
 
  TIMSK1=0x01; // enabled global and timer overflow interrupt;
  TCCR1A = 0x00; // normal operation page 148 (mode0);
  TCNT1=0xBDC; // set initial value to remove time error (16bit counter register)
  TCCR1B = 0x04; // start timer/ set clock
 
  zetTijd();
};

void loop () {
  if (seconden_oud != seconden){
    seconden_oud = seconden;
    seco++;
    if (seco == 60){
      seco = 0;
      minu++;
      if (minu == 60){
        minu = 0;
        uren++;
        if (uren == 24){
          uren = 0;
        }
      }
    }
    Serial.print(uren);
    Serial.print(':');
    Serial.print(minu);
    Serial.print(':');
    Serial.println(seco);
  }
};

void zetTijd(){
  String tijd = __TIME__;
  uren = (tijd.charAt(0)-48)*10+tijd.charAt(1)-48;
  minu = (tijd.charAt(3)-48)*10+tijd.charAt(4)-48;
  seco = (tijd.charAt(6)-48)*10+tijd.charAt(7)-48;
}

Berichten: 29
Geregistreerd: 01 Dec 2012, 18:34

Re: Tijd programmeren

Berichtdoor h.lith » 15 Jan 2013, 00:14

Hoi Paul, dus die timers kan je gewoon een interupt laten creeren, van zeg een seconde als op bovenstaande wijze, met de pre scaler!
Ik wil een paar timers gebruiken, om de maximale voorgloei, maar ook de maximale nagloeitijd in mijn MB 200D te bewaken.
iedere seconde komt een timerinterupt, en een interupt routine moet dan een register met 1 ophogen, dan volgt er in het programma een regelmatige test op dit register of een bepaalde waarde bereikt is, zeg 30, is die waarde dus na 30 seconde geconstateerd door het programma dan wordt het voorgloeien gedwongen! door de uC. afgeschakeld.
Dit principe wordt meer malen op diverse punten gebruikt, ook om te zorgen voor een maximale nagloeitijd na dat de motor loopt.
Ik heb al een flowshart gemaakt, deze moet ik nu alleen nog omzetten in C. code pfff... een nieuw vak voor mij :lol:
De flowshart moet nog wat verfijnder gemaakt worden, maar in principe moet het zo werken.
Groet, Henk Lith

Gebruikers-avatar
Berichten: 700
Geregistreerd: 05 Mrt 2012, 21:56
Woonplaats: Appingedam

Re: Tijd programmeren

Berichtdoor pjh » 15 Jan 2013, 00:49

Hoi Henk,

Timers zijn echt de moeite waard. Ze staan zo lekker los van je loop. Groot voordeel. :P

Nog even over het toppic Tijd programmeren zelf. Ik bedacht me een nog simpelere manier om een seconde te triggeren.
Ditmaal heel lelijk in de loop. :oops:

Code: Alles selecteren
unsigned long teller = 0;

void setup(){
  Serial.begin(9600);
}

void loop(){
  if(millis()%1000 == 666){
    teller++;
    Serial.println(teller);
    delay(1);
  }
// loop verder vrij. Geen delay van 1000 ms, maar van 1 ms en een beetje...
}


wat ik hier doe is dit:
het '%' teken is de modulus.
millis() modulus 1000 betekend: hak net zolang 1000 van millis() af, tot je minder dan 1000 hebt. Wat je overhoud is de modulus.
Het maakt dus niet uit of je nu 666 of 123 of wat dat ook.
1 x per 1000 miliseconden zal de modulus millis() 1000 gelijk zijn aan elk getal onder de duizend.
1x per seconde dus.
lekker duidelijk
(niet)
:mrgreen:

Berichten: 29
Geregistreerd: 01 Dec 2012, 18:34

Re: Tijd programmeren

Berichtdoor h.lith » 15 Jan 2013, 01:36

Ik geloof,,, dat ik hier eerst toch even een nachtje over moet slapen mr. Green :mrgreen: of mr. 666?
Maar het leuke van deze hobby is natuurlijk dat je er zo lekker creatief mee om kunt gaan he.
Over 28800 seconde laat ik de timer naast mijn bed aflopen, geen tijd te verliezen dus!
Groet, Henk Lith

Berichten: 85
Geregistreerd: 10 Jan 2013, 14:51
Woonplaats: Waddinxveen

Re: Tijd programmeren

Berichtdoor Karel » 22 Jan 2013, 22:42

pjh schreef:Het maakt dus niet uit of je nu 666 of 123 of wat dat ook.
1 x per 1000 miliseconden zal de modulus millis() 1000 gelijk zijn aan elk getal onder de duizend.


Maar dan ga je er wel van uit dat andere delen in de code (schrijven naar SD-card, interrupt handler) niet net die milliseconde die jij hebt gekozen gebruikt. Als modulus millis() 1000 van 665 naar 667 springt mis je een seconde. Of zie ik iets over het hoofd?

Groet, Karel
If you think education is expensive, try ignorance! (Derek Bok)

Gebruikers-avatar
Berichten: 700
Geregistreerd: 05 Mrt 2012, 21:56
Woonplaats: Appingedam

Re: Tijd programmeren

Berichtdoor pjh » 22 Jan 2013, 23:59

Volgens mij onderbreekt een interrupt een delay. Maar dat kan ik mis hebben.
Mijn mening: Dat is heel slecht programmeer werk van mij als het op klokken en timing aankomt.
Het reduceert een delay van 1000 ms wel tot 1 miliseconden, die hij voor 'blanking' nodig heeft. In mijn voorbeeld wordt de teller niet elke seconde naar de seriele poort geschreven, maar wordt er 1 miliseconden lang de teller naar de poort geschreven. Op 3600 baud ziet de output er ongeveer zo uit:
1111111111 - niks - 22222222222- niks -33333333-etc3444444444. Korte pulsen zelfde getallen met bij de overgangen 999 ms niks.

Was meer een demonstratie van de modulus. Weet niet of veel mensen het veel gebruiken, maar als beginner was het een ontdekking voor me. Makkelijk ding, die modulus.

Maar nogmaals: niet gebruiken die code van mij. Iesz baggûh. :lol:




,

Berichten: 85
Geregistreerd: 10 Jan 2013, 14:51
Woonplaats: Waddinxveen

Re: Tijd programmeren

Berichtdoor Karel » 23 Jan 2013, 15:09

pjh schreef:Volgens mij onderbreekt een interrupt een delay. Maar dat kan ik mis hebben.


Ja, onderbreekt een delay, dat klopt. Maar de klok tikt door, en volgens mij dan ook de waarde van millis().

Dus een interrupthandler die (heel slecht) bijv een of meer delingen doet met doubles, die is best lang onderweg. Ik schat zo in dat millis() bij de aanroep kijkt naar de actuele klokwaarde, en die kan dan te ver zijn doorgeschoten om 'm nog op te vangen.

groet, Karel
If you think education is expensive, try ignorance! (Derek Bok)

Volgende

Terug naar Arduino software

Wie is er online?

Gebruikers in dit forum: eyivoku en 10 gasten