klok datum met dag aanduiding

algemene C code
Gebruikers-avatar
Berichten: 10
Geregistreerd: 17 Sep 2016, 20:31
Woonplaats: groesbeek

klok datum met dag aanduiding

Berichtdoor Henkie » 19 Apr 2019, 20:15

beste mensen,

volgens mij staat deze tekst in het verkeerde topic??
mocht dit zo zijn kan het dan naar het juiste topic verplaatst worden.



ik heb al even bezig met een klokje & thermometer te maken.

ik heb een sketch (klokje) op het internet gevonden en heb deze al behoorlijk aangepast en in mijn eigen sketch geïmplementeerd.

maar ik zou graag een toevoeging nog willen maken.
maar helaas weet ik niet hoe.

ik wil graag de dagen ook tonen in het display.

ik gebruik een LCD 40x4 hiervoor.




Code: Alles selecteren

/*
              By Henk van Bergen 2019 ©
          --- LCD 40x4 - I2C aansturing ---
      Digitalle temperatuur meter met 2 x DS18B20
                         &
                RTC instelbare klok
*/


#include <OneWire.h>
#include <DallasTemperature.h>
#include <DS3231.h>
#include <LCD.h>
#include <LiquidCrystal_I2C.h>
#include <Wire.h>

#define BACKLIGHT_PIN  3
#define ONE_WIRE_BUS 8
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
DS3231  rtc(SDA, SCL);

// adres LCD screen
LiquidCrystal_I2C  lcd1(0x27, 2 , 1, 0, 4, 5, 6, 7);  // LCD 40x4

// sensor adres
DeviceAddress tempSensor = { 0x28, 0x5E, 0x2B, 0x77, 0x91, 0x13, 0x02, 0x03 }; // Buiten sensor 1 meter hoog
DeviceAddress tempSensor1 = { 0x28, 0x06, 0x6F, 0x77, 0x91, 0x07, 0x02, 0xAD }; // Buiten sensor grond nivo

// Benaming sensors in LCD scherm
float Buiten_hoog, Buiten_grond;

//Filter waardes
const int RunningAverageCount = 10; //aantal seconden waarover gefilterd wordt
float RunningAverageBuffer[RunningAverageCount];
int NextRunningAverage;

//Sample filter interval
int sampleInt = 5;
int sampleNr = 6;

//LCD write Delay
int WriteDelayLoops = 50;
int WriteDelayCurrent = 0;
float Buiten_hoog_old = 0;
float Buiten_grond_old = 0;



// grade rondje & pijlenteken
byte graden[8] =
{
  0b00111,
  0b00101,
  0b00111,
  0b00000,
  0b00000,
  0b00000,
  0b00000,
  0b00000
};
byte pijl_omhoog[8] =
{
  0b00100,
  0b01110,
  0b11111,
  0b00100,
  0b00100,
  0b00100,
  0b00100,
  0b00100
};
byte pijl_omlaag[8] =
{
  0b00100,
  0b00100,
  0b00100,
  0b00100,
  0b00100,
  0b11111,
  0b01110,
  0b00100
};



void setup(void)

{
  lcd1.setBacklightPin(BACKLIGHT_PIN, POSITIVE);  // LCD Verlichting aan aan

  rtc.begin();                                   // initialiseren RTC modulle
  Wire.begin();                                  // i2c bus


  pinMode(10, INPUT_PULLUP);                      // Knop klok instellen naar pin 10
  pinMode(11, INPUT_PULLUP);                      // Knop klok instellen naar pin 11



  /* Increment Time van Resolution instellen
     9 bit  0.5    grade C 93.75 mSec
    10 bit  0.25   grade C 187.5 mSec
    11 bit  0.125  grade C 375   mSec
    12 bit  0.0625 grade C 750   mSec     */
  sensors.setResolution(tempSensor,  10);
  sensors.setResolution(tempSensor1, 10);

  lcd1.begin(20, 4);        // initialize the lcd for 20 chars 4 lines, turn on backlight


  {
    lcd1.clear();
    delay(1000);
    lcd1.setCursor(2, 1);
    lcd1.print("*** Booting ***");
    lcd1.backlight();                               // LCD Verlichting aan
    delay(500);
    lcd1.noBacklight();                             // LCD Verlichting uit
    delay(500);
    lcd1.backlight();                               // LCD Verlichting aan
    delay(500);
    lcd1.noBacklight();                             // LCD Verlichting uit
    delay(500);
    lcd1.backlight();                               // LCD Verlichting aan
    delay(500);
    lcd1.noBacklight();                             // LCD Verlichting uit
    delay(500);
    lcd1.backlight();                               // LCD Verlichting aan
    delay(500);
    lcd1.noBacklight();                             // LCD Verlichting uit
    delay(1000);
    lcd1.clear();
    delay(1000);
  }
  lcd1.backlight();                               // LCD Verlichting aan

  lcd1.setCursor(1, 0);
  lcd1.print("By Henk van Bergen");
  delay(1000);
  lcd1.setCursor(4, 1);
  lcd1.print("Klok & Datum");
  delay(1000);
  lcd1.setCursor(4, 2);
  lcd1.print("Thermometer");
  lcd1.setCursor(2, 3);
  //delay(2000);
  //  lcd1.print("Thermometer");
  delay(5000);
  lcd1.clear();
}
//char Time[]     = "TIME:  :  :  ";
//char Calendar[] = "DATE:  -  -20  ";

char Time[]     = "        :  :  ";
char Calendar[] = "       -  -20  ";
byte i, second, minute, hour, date, month, year;

void DS3231_display() {
  // Convert BCD to decimal
  second = (second >> 4) * 10 + (second & 0x0F);
  minute = (minute >> 4) * 10 + (minute & 0x0F);
  hour   = (hour >> 4)   * 10 + (hour & 0x0F);
  date   = (date >> 4)   * 10 + (date & 0x0F);
  month  = (month >> 4)  * 10 + (month & 0x0F);
  year   = (year >> 4)   * 10 + (year & 0x0F);
  // End conversion
  Time[13]     = second % 10 + 48;
  Time[12]     = second / 10 + 48;
  Time[10]     = minute % 10 + 48;
  Time[9]      = minute / 10 + 48;
  Time[7]      = hour   % 10 + 48;
  Time[6]      = hour   / 10 + 48;
  Calendar[14] = year   % 10 + 48;
  Calendar[13] = year   / 10 + 48;
  Calendar[9]  = month  % 10 + 48;
  Calendar[8]  = month  / 10 + 48;
  Calendar[6]  = date   % 10 + 48;
  Calendar[5]  = date   / 10 + 48;
  lcd1.setCursor(0, 0);
  lcd1.print(Time);                               // Display time
  lcd1.setCursor(0, 1);
  lcd1.print(Calendar);                           // Display calendar
}
void blink_parameter() {
  byte j = 0;
  while (j < 10 && digitalRead(10) && digitalRead(11)) {
    j++;
    delay(25);
  }
}
byte edit(byte x, byte y, byte parameter) {
  char text[3];
  while (!digitalRead(10));                       // Wait until button (pin #10 released
  while (true) {
    while (!digitalRead(11)) {                    // If button (pin #11 is pressed
      parameter++;
      if (i == 0 && parameter > 23)              // If hours > 23 ==> hours = 0
        parameter = 0;
      if (i == 1 && parameter > 59)              // If minutes > 59 ==> minutes = 0
        parameter = 0;
      if (i == 2 && parameter > 31)              // If date > 31 ==> date = 1
        parameter = 1;
      if (i == 3 && parameter > 12)              // If month > 12 ==> month = 1
        parameter = 1;
      if (i == 4 && parameter > 99)              // If year > 99 ==> year = 0
        parameter = 0;
      sprintf(text, "%02u", parameter);
      lcd1.setCursor(x, y);
      lcd1.print(text);
      delay(200);                                // Wait 200ms
    }
    lcd1.setCursor(x, y);
    lcd1.print("  ");                             // Display two spaces
    blink_parameter();
    sprintf(text, "%02u", parameter);
    lcd1.setCursor(x, y);
    lcd1.print(text);
    blink_parameter();
    if (!digitalRead(10)) {                       // If button (pin #10 is pressed
      i++;                                       // Increament 'i' for the next parameter
      return parameter;                          // Return parameter value and exit
    }
  }
}
void loop(void) {

  {
    if (!digitalRead(10)) {                         // If button (pin #10 is pressed
      i = 0;
      hour   = edit( 6, 0, hour);
      minute = edit( 9, 0, minute);
      date   = edit( 5, 1, date);
      month  = edit( 8, 1, month);
      year   = edit(13, 1, year);
      // Convert decimal to BCD
      minute = ((minute / 10) << 4) + (minute % 10);
      hour   = ((hour   / 10) << 4) + (hour   % 10);
      date   = ((date   / 10) << 4) + (date   % 10);
      month  = ((month  / 10) << 4) + (month  % 10);
      year   = ((year   / 10) << 4) + (year   % 10);
      // End conversion
      // Write data to DS3231 RTC
      Wire.beginTransmission(0x68);               // Start I2C protocol with DS3231 address
      Wire.write(0);                              // Send register address
      Wire.write(0);                              // Reset sesonds and start oscillator
      Wire.write(minute);                         // Write minute
      Wire.write(hour);                           // Write hour
      Wire.write(1);                              // Write day (not used)
      Wire.write(date);                           // Write date
      Wire.write(month);                          // Write month
      Wire.write(year);                           // Write year
      Wire.endTransmission();                     // Stop transmission and release the I2C bus
      delay(200);                                 // Wait 200ms
    }
    Wire.beginTransmission(0x68);                 // Start I2C protocol with DS3231 address
    Wire.write(0);                                // Send register address
    Wire.endTransmission(false);                  // I2C restart
    Wire.requestFrom(0x68, 7);                    // Request 7 bytes from DS3231 and release I2C bus at end of reading
    second = Wire.read();                         // Read seconds from register 0
    minute = Wire.read();                         // Read minuts from register 1
    hour   = Wire.read();                         // Read hour from register 2
    Wire.read();                                  // Read day from register 3 (not used)
    date   = Wire.read();                         // Read date from register 4
    month  = Wire.read();                         // Read month from register 5
    year   = Wire.read();                         // Read year from register 6
    DS3231_display();                             // Diaplay time & calendar
    delay(50);                                    // Wait 50ms




  }



  if (sampleNr > sampleInt)
  {
    // opvragen van sensor adres
    sensors.requestTemperaturesByAddress(tempSensor) ; // Send the command to get temperatures
    sensors.requestTemperaturesByAddress(tempSensor1); // Send the command to get temperatures

    // Get the temperature that you told the sensor to measure
    Buiten_hoog  = sensors.getTempC(tempSensor);
    Buiten_grond = sensors.getTempC(tempSensor1);
    sampleNr = 0;
  }
  else
  {
    sampleNr++;
  }

  float RawTemperature = Buiten_hoog;
  RunningAverageBuffer[NextRunningAverage++] = RawTemperature;
  if (NextRunningAverage >= RunningAverageCount)
  {
    NextRunningAverage = 0;
  }
  float RunningAverageTemperature = 0;
  for (int i = 0; i < RunningAverageCount; ++i)
  {
    RunningAverageTemperature += RunningAverageBuffer[i];
  }
  RunningAverageTemperature /= RunningAverageCount;

  //binnen = RunningAverageTemperature;


  //LCD write delay


  {
    /*Display settings regel 3 */

    lcd1.createChar(1, graden);
    lcd1.createChar(2, pijl_omhoog);
    lcd1.setCursor(3, 2);
    lcd1.print("Temp. ");
    lcd1.write(2);
    lcd1.print(" ");
    //lcd1.print(Buiten_hoog );
    if (WriteDelayCurrent > WriteDelayLoops)
    {
      lcd1.print(Buiten_hoog );
      Buiten_hoog_old = Buiten_hoog;
    }
    else
    {
      lcd1.print(Buiten_hoog_old );
    }
    lcd1.write(1);
    lcd1.print("C    ");

    /*Display settings regel 4 */
    lcd1.createChar(3, pijl_omlaag);
    lcd1.setCursor(3, 3);
    lcd1.print("Temp. ");
    lcd1.write(3);
    lcd1.print(" ");
    //lcd1.print(Buiten_grond );
    //Zie regel 42
    if (WriteDelayCurrent > WriteDelayLoops)
    {
      lcd1.print(Buiten_grond );
      Buiten_grond_old = Buiten_grond;
      WriteDelayCurrent = 0;
    }
    else
    {
      lcd1.print(Buiten_grond_old );
      WriteDelayCurrent++;
    }
    lcd1.write(1);
    lcd1.print("C    ");
    delay(100);
  }
}



wie o wie kan mij hier mee helpen.

de dagen in een afkorting.

maa, dins, woe, don, vrij, zat, zon

zoiets ongeveer.

alvast hartelijk bedankt voor jullie moeite.

met vriendelijk groet,
Henk van Bergen

Advertisement

Berichten: 4064
Geregistreerd: 16 Okt 2013, 14:31
Woonplaats: s hertogenbosch

Re: klok datum met dag aanduiding

Berichtdoor shooter » 20 Apr 2019, 21:20

even opgezocht en het zit er gewoon in namelijk op 3 (die jij niet gebruikt tot het jaar 2100 (dan ben ik al dood).
daar staat dus dag van week.
in jouw programma dus of een lijstje of een array opnemen met de teksten maandag,disndag etc.
dan kun je dus schrijven dagnaam[day] etc.
ik zou overigens die schrijfinstructie in een functie wegstoppen want die doe je echt maar 1 keer als je start.
paul deelen
shooter@home.nl

Gebruikers-avatar
Berichten: 10
Geregistreerd: 17 Sep 2016, 20:31
Woonplaats: groesbeek

Re: klok datum met dag aanduiding

Berichtdoor Henkie » 20 Apr 2019, 22:13

Beste Shooter,

thanks voor je uitleg.

maar dat ik nu net het probleem.

mijn kennis is nog niet genoeg om uit jou uitleg iets te kunnen schrijven.

kun je mij misschien een beetje op weg helpen.
daar zo ik je heel dankbaar voor zijn alvast bedankt voor je moeite.


gr.
henk

Gebruikers-avatar
Berichten: 2655
Geregistreerd: 06 Aug 2016, 01:03

Re: klok datum met dag aanduiding

Berichtdoor Koepel » 22 Apr 2019, 05:04

Het is handig om de "dag van de week" duidelijk anders te noemen dan de "dag van de maand". Ik maakte daar zelf soms een rommeltje van.

In de datasheet van de DS3231 gebruiken ze "Day (1-7)" en "Date (01-31)" bij de beschrijving van de registers en ook "day-of-week".

Hoe vaak heb je de datasheet van de DS3231 gelezen ?
Dan zie je dat register 3 de "Day" is, dus de dag van de week.
Daar staat een opmerking over, dat het helemaal los is van de rest. Hij telt van 1 tot en met 7, en dat is alles. Je kunt dus zelf bepalen met welke "dag van de week" je het wilt laten beginnen en je moet zelf een keer invullen welke "dag van de week" het vandaag is.

Register drie wordt niet gebruikt, dus die zul je moeten aanpassen:
Code: Alles selecteren
Wire.read();                                  // Read day from register 3 (not used)
en
Code: Alles selecteren
 Wire.write(1);                              // Write day (not used)


Voor een array zou ik een vaste grootte nemen. Dat is gemakkelijker.
Code: Alles selecteren
const char DagVanDeWeek[7][4] =
{
  "Maa", "Din", "Woe", "Don", "Vri", "Zat", "Zon",
};


Kun je zo'n tekst bijvoorbeeld eens naar de seriele monitor sturen ?

De RTC gebruikt de I2C bus. Daarom wordt de "#include <Wire.h>" gedaan voor de voor "#include <DS3231.h>" en de "Wire.begin()" wordt gedaan voor de "rtc.begin()".

Wat jij wilt is niet gangbaar. De Adafruit RTCLib en de TimeLib hebben berekeningen voor de "dag van de week". Die libraries kunnen berekenen dat "22 april 2019" een maandag is. Dat is dus uiteindelijk veel handiger.

Berichten: 4064
Geregistreerd: 16 Okt 2013, 14:31
Woonplaats: s hertogenbosch

Re: klok datum met dag aanduiding

Berichtdoor shooter » 22 Apr 2019, 11:32

lees de laatste code van koepel maar dat is uitgewerkt wat ik je vertel, maar koepel geeft graag de oplossing erbij, en ik denk dat je dat eigenlijk zelf moet zoeken.
paul deelen
shooter@home.nl

Gebruikers-avatar
Berichten: 2655
Geregistreerd: 06 Aug 2016, 01:03

Re: klok datum met dag aanduiding

Berichtdoor Koepel » 22 Apr 2019, 14:00

Het was maar een klein duwtje in de goede richting omdat het Pasen is ;)

Uiteindelijk is de RTCLib of TimeLib handiger. Bijvoorbeeld bij het wijzigen van de datum, dan is het niet nodig om ook nog eens zelf de dag van de week er in te zetten.

Gebruikers-avatar
Berichten: 10
Geregistreerd: 17 Sep 2016, 20:31
Woonplaats: groesbeek

Re: klok datum met dag aanduiding

Berichtdoor Henkie » 22 Apr 2019, 17:21

even ter info,

Het is helemaal gelukt.
nogmaals bedankt voor jullie info & moeite.

gr.
henk
Bijlagen
lcd klok.jpg
lcd klok.jpg (115.6 KiB) 8407 keer bekeken

Gebruikers-avatar
Berichten: 2655
Geregistreerd: 06 Aug 2016, 01:03

Re: klok datum met dag aanduiding

Berichtdoor Koepel » 22 Apr 2019, 18:19

Dat ziet er goed uit :D

Ideeën voor later:

Ik heb zo'n goedkope DS3231 module waar een oplaadbare batterij in kan. In plaats van een batterij heb ik er een kleine 0.1F supercap van 5V in gezet. Die zou het twee dagen moeten kunnen volhouden.

Het graden symbool als vierkantje ? Die heb ik anders, met minder pixels.

Wat dacht je van een automatische omschakeling van zomer en wintertijd ?

Met een display van 4 regels van 40 tekens kun je een font maken over twee of vier rijen. Dan kun je bijvoorbeeld de tijd groot laten zien.

De DS3231 heeft gaan extra ram zoals de DS3232. De DS3231 heeft wel 7 byte voor de alarm-instellingen. Die 7 byte kunnen gebruikt worden als ram. Dan is er geen beperking voor het aantal keren schrijven zoals een EEPROM. Ik zit er zelf nog op te broeden wat ik er mee zal doen. Bijvoorbeeld bijhouden wanneer de stroom is uitgevallen.

Gebruikers-avatar
Berichten: 10
Geregistreerd: 17 Sep 2016, 20:31
Woonplaats: groesbeek

Re: klok datum met dag aanduiding

Berichtdoor Henkie » 22 Apr 2019, 18:29

Koepel schreef:
1. Ik heb zo'n goedkope DS3231 module waar een oplaadbare batterij in kan. In plaats van een batterij heb ik er een kleine 0.1F supercap van 5V in gezet. . Die zou het twee dagen moeten kunnen volhouden.

2. Het graden symbool als vierkantje ? Die heb ik anders, met minder pixels.

3. Wat dacht je van een automatische omschakeling van zomer en wintertijd ?



Thanks Koepel:

ik moet zeggen dat ik het wel lastig vind om code te schrijven.

vooral als er geen goede boeken hiervan heb.
ik zo beste wel een cursus willen volgen maar die zijn er bijna niet.
en dan is het toch wel lastig om iets te programmeren.
en moet ik het veel van internet hebben.

maar het is me toch aardig gelukt..



1. ik heb er nu zo'n lir 2032 in zitten. maar dat van jou is ook goed idee die arduino gaat eigenlijk nooit uit maar wel handig voor spannings-uitval.

2. hoe heb jij de punt dan gemaakt

dit is die van mij
{
0b00111,
0b00101,
0b00111,
0b00000,
0b00000,
0b00000,
0b00000,
0b00000
};

3. nu maak je mij wel lekker.
heb je misschien een voorbeeld hoe dit moet.


alvast bedankt


gr.
henk

Gebruikers-avatar
Berichten: 2655
Geregistreerd: 06 Aug 2016, 01:03

Re: klok datum met dag aanduiding

Berichtdoor Koepel » 22 Apr 2019, 18:51

Ik zat me al af te vragen waar ik dat graden symbool heb gebruikt. Maar ik kan het niet vinden.
Het is met 4 pixels (rondom één pixel) of met 8 pixels (rondom een blokje van 2x2).
Je kunt het hier proberen: https://maxpromer.github.io/LCD-Character-Creator/.
Ik zocht nog even naar plaatjes met Google, en er zijn toch wel best veel vierkante graden symbooltjes.

Het laadcircuit is een weerstand en een diode. Dat vindt die LIR2032 niet leuk. De spanning kan te hoog worden. Dat is precies de reden dat ik een 5V supercap er in heb gesoldeerd.

Voor de zomer- en wintertijd is het is mogelijk om "de laatste zondag van de maand" wiskundig te berekenen.
Daarbij is het belangrijk om de RTC altijd op wintertijd te draaien en alleen op het display de gecorrigeerde waarde te laten zien. Dat vergt dus (heel wat) extra code om in de zomer steeds een uur er bij op te tellen. Dat vergt nog meer extra code als je in de zomertijd de tijd wilt wijzigen.
Volgens mij gaat dat niet lukken met jouw code. De variabele "hour" ophogen is niet voldoende. Misschien is een uur later de volgende dag. Dat lukt alleen met zo'n RTCLib of TimeLib library.

Mocht je toch willen zien hoe het er uit ziet:
cpp code
// ---------------------------
// isDstEurope
// ---------------------------
// Uses the normal local time (winter time) to determine
// if the daylight saving is active.
//
// In Europe, the summer time (+1 hour) starts at
// the last Sunday of March. At 02:00 (am) the clock
// jumps to 03:00 (am).
// The end if the summer time is at the last Sunday
// of October. At 03:00 (am) the clock jumps back
// to 02:00 (am).
// When the winter time is the base, it means that the DST
// becomes active at 02:00 (winter time) but also inactive at 02:00 (winter time).
//
// The parameters are the winter time, don't use the summertime for them.
// day : 1...31
// month : 1...12
// dow : 1...7 1 = Sunday
// hour : 0...23
//
// Returns:
// boolean that indicates that an hour should be added.
// Note that this is not an increment of the hour, but
// everything advances an hour into the future.
//
boolean isDstEurope( int day, int month, int dow, int hour)
{
boolean dst = false;

// day 1...31, dow 1...7
// calculate the current or previous Sunday of this month.
// the result could be negative, which is no problem.

int previousSunday = day - (dow - 1);

// The range for a switch-case statement is a non-standard 'c' usage !
switch( month)
{
case 1 ... 2:
dst = false;
break;
case 3:
// The lowest day for sunday is 25, the highest is 31
if( previousSunday >= 25)
{
if( dow == 1) // is it sunday right now ?
{
if( hour >= 2)
{
dst = true; // dst starts at two in the night
}
else
{
dst = false; // it is the right date, but not yet time
}
}
else
{
dst = true; // it is past the last sunday
}
}
else
{
dst = false; // the date is before the last sunday
}
break;
case 4 ... 9:
dst = true;
break;
case 10:
if( previousSunday >= 25)
{
if( dow == 1) // is it sunday right now ?
{
if( hour < 2)
{
dst = true; // dst stops at two in the night
}
else
{
dst = false; // it is the right date, but beyond the DST
}
}
else
{
dst = false; // it is past the last sunday
}
}
else
{
dst = true; // the date is before the last sunday
}
break;
case 11 ... 12:
dst = false;
break;
default:
// wrong parameter for the month
dst = false;
}
return dst;
}

Volgende

Terug naar C code

Wie is er online?

Gebruikers in dit forum: Geen geregistreerde gebruikers en 11 gasten