Go Down

Topic: Probleme mit dem Befehl Struct (Read 254 times) previous topic - next topic

LOOIIS

May 22, 2019, 07:15 pm Last Edit: May 22, 2019, 08:16 pm by LOOIIS
Hallo,
hat jemand von euch eine Ahnung warum die folgende Struktur nicht funktioniert:
"error: 'uhrzeitA' does not name a type"

Code: [Select]
struct Zeiten {
  uint8_t Second;
  uint8_t Minute;
  uint8_t Hour;
  uint8_t Wday;   // day of week, sunday is day 1
  uint8_t Day;
  uint8_t Month;
  uint8_t Year; // offset from 1970;
  unsigned long unixTime;
};

Zeiten uhrzeitA;


uhrzeitA.Hour = 15;
uhrzeitA.Minute = 20;
uhrzeitA.Second = 00;
uhrzeitA.Wday = 22;
uhrzeitA.Month = 05;
uhrzeitA.Year = 2019 - 1970;


vielen Dank!

combie

Zuweisungen dürfen nur in einem Anweisungsblock erfolgen.

Vielleicht möchtest du den Datensatz ja lieber initialisieren.....
Alle sagen: Das geht nicht!
Einer wusste das nicht und probierte es aus.
Und: Es ging nicht.


Doc_Arduino

Hallo,

wenn ich ergänzen darf, weil es geht ja um die Time Lib. Vielleicht besser du nimmst das interne struct der Lib, dann bleibst zu der Datenstructur (Reihenfolge) kompatibel und musst nichts nachbauen. Eine Fehlerquelle weniger.

Code: [Select]

#include <TimeLib.h>

tmElements_t uhrA;
tmElements_t uhrB;

void setup()  {
  uhrA.Second = 45;
  uhrA.Day = 22;
  uhrA.Month = 5;
  uhrA.Year = 19;
}

void loop(){    
  
}


Ansonsten kommt mir das Problem mit der Zuweisung irgendwie bekannt vor ... :smiley-mr-green: ... irgendwann war da mal was ...  :smiley-mr-green:  
Tschau
Doc Arduino '\0'

Messschieber auslesen: http://forum.arduino.cc/index.php?topic=273445
EA-DOGM Display - Demos: http://forum.arduino.cc/index.php?topic=378279

LOOIIS

Super, das ging aber schnell.
Vielen Dank an euch!

LOOIIS

#5
May 23, 2019, 10:50 am Last Edit: May 23, 2019, 10:51 am by LOOIIS
Hallo,
Wie kann ich diese Funktion timetoStr ändern, dass diese Funktion die Zeit in eine Struktur abspeichert? Möchte nämlich die Array durch Strukturen ersetzen und dabei auf die Struktur von der Bibliothek timelib zurückgreifen (tmElements_t).

Code: [Select]
char *timeToStr(time_t t, char * buf) {
int ja;
  buf[0] = (hour(t) / 10) + '0'; // Zehner
  buf[1] = (hour(t) % 10) + '0'; // Einer
  buf[2] = ':';
  buf[3] = (minute(t) / 10) + '0';
  buf[4] = (minute(t) % 10) + '0';
  buf[5] = ':';
  buf[6] = (second(t) / 10) + '0';
  buf[7] = (second(t) % 10) + '0';
  buf[8] = ' '; // die abschließende 0
  buf[9] = (day(t) / 10) + '0'; // Zehner
  buf[10] = (day(t) % 10) + '0'; // Einer
  buf[11] = '.';
  buf[12] = (month(t) / 10) + '0';
  buf[13] = (month(t) % 10) + '0';
  buf[14] = '.';
  ja = year(t);
  buf[15] = (ja / 1000) + '0'; // Tausender
  ja = ja % 1000;             // Rest 3-stellig
  buf[16] = (ja / 100) + '0';  // Hunderter
  ja = ja % 100;              // Rest 2-stellig
  buf[17] = (ja / 10) + '0';   // Zehner
  buf[18] = (ja % 10) + '0';   // Einer
  buf[19] = 0; // die abschließende 0
  return buf;
}


Habe bis jetzt diese Funktion geschrieben:
Code: [Select]
void timeToStruct (time_t t) {
  uhrzeit.Hour = hour(t);
  uhrzeit.Minute = minute(t);
  uhrzeit.Second = second(t);
  uhrzeit.Wday = day(t);
  uhrzeit.Month = month(t);
  uhrzeit.Year = year(t);  
  Serial.println(uhrzeit.Wday);
}


Habe leider keine Ahnung wie der Funktion eine Struktur übergeben wird, denn zB die uhrzeit.* sollte Variable sein... :smiley-confuse:

vielen Dank für eure Hilfe!

Doc_Arduino

#6
May 23, 2019, 11:38 am Last Edit: May 23, 2019, 11:39 am by Doc_Arduino
Hallo,

ein Vorschlag, vielleicht gehts noch eleganter, Zeiger sind immer ein etwas heißes Eisen.  :)
Code: [Select]
#include <TimeLib.h>

tmElements_t uhrA;
tmElements_t uhrB;

void setup()  {
  Serial.begin(9600);
  
  uhrA.Day = 22;
  uhrA.Month = 5;

  Serial.println(uhrA.Day);
  Serial.println(uhrA.Month);
  Serial.println(uhrB.Day);
  Serial.println(uhrB.Month);
  Serial.println();
  
  timeTo_uhrB (&uhrA);
  
  Serial.println(uhrA.Day);
  Serial.println(uhrA.Month);
  Serial.println(uhrB.Day);
  Serial.println(uhrB.Month);
  Serial.println();

  uhrB.Day = 11;
  uhrB.Month = 2;
  
  time_uhrB_to_uhrA (&uhrA, &uhrB);

  Serial.println(uhrA.Day);
  Serial.println(uhrA.Month);
  Serial.println(uhrB.Day);
  Serial.println(uhrB.Month);
}

void loop() {

}

void timeTo_uhrB (tmElements_t *ptr)
{
  uhrB.Day = (*ptr).Day;
  uhrB.Month = (*ptr).Month;
}


void time_uhrB_to_uhrA (tmElements_t *ptrA, tmElements_t *ptrB)
{
  (*ptrA).Day = (*ptrB).Day;
  (*ptrA).Month = (*ptrB).Month;
}



Tschau
Doc Arduino '\0'

Messschieber auslesen: http://forum.arduino.cc/index.php?topic=273445
EA-DOGM Display - Demos: http://forum.arduino.cc/index.php?topic=378279

LOOIIS

Super, großes DANKE Doc_Arduino!!!

Serenifly

Auch das ist wieder ein Fall wo Zeiger völlig überflüssig sind und man stattdessen Referenzen verwenden sollte. Siehe auch die Time Library (makeTime() und breakTime())

michael_x

Wenn Zeiger,  dann
Quote
uhrB.Day = (*ptr).Day;
schreibt man normalerweise einfacher

 uhrB.Day = ptr->Day;

Genau dafür wurde die Schreibweise -> erfunden.

LOOIIS

#10
May 23, 2019, 02:48 pm Last Edit: May 23, 2019, 02:51 pm by LOOIIS
@michael_X:
Danke für deine Info!

@Serenifly:
Danke für deinen Beitrag und vielen Dank für deinen Tipp!
Aller Anfang ist schwer... Freut mich immer wieder wenn ihr uns Anfänger konstruktiv weiterhilft!
Warum bekomme ich bei
Quote
Serial.println(makeTime(actualTime));
Serial.println(s_tm1);
unterschiedliche Ergebnisse? Müsste ich nicht die selben Ergebnisse bekommen?


Code: [Select]
#include <Arduino.h>

#include <TimeLib.h>  // https://github.com/PaulStoffregen/Time
#include <ESP8266WiFi.h>
#include <WiFiUdp.h>


#ifndef WifiConfig
#define YOUR_WIFI_SSID ""
#define YOUR_WIFI_PASSWD ""
#endif

//Struktur der Timelib
tmElements_t Startzeit;
tmElements_t lastSyncStr;
tmElements_t actualTime;

// den 5 gibt es nicht, der ist nur zum Fehlertest drin
static const char ntpServerName[][20] = {"1.de.pool.ntp.org","2.de.pool.ntp.org", "3.de.pool.ntp.org","4.de.pool.ntp.org","5.de.pool.ntp.org"};
time_t lastSyncTime;
time_t prevDisplay = 0; // when the digital clock was displayed
const int timeZone = 2;     // Central European Time + Sommerzeit
boolean newSync = false;
WiFiUDP Udp;
unsigned int localPort = 8888;  // local port to listen for UDP packets

time_t getNtpTime();
void sendNTPpacket(IPAddress &address);



// das muss ins setup
void setup() {
  Serial.begin(115200);

//We start by connecting to a WiFi network
Serial.print("Connecting to: ");
Serial.println(YOUR_WIFI_SSID);
WiFi.mode(WIFI_STA);
WiFi.begin(YOUR_WIFI_SSID, YOUR_WIFI_PASSWD);

while (WiFi.status() != WL_CONNECTED) {
  delay(500);
  Serial.print(".");
}
Serial.println("");

Serial.println("WiFi connected");
Serial.println("IP adress: ");
Serial.println(WiFi.localIP());
Serial.println("Starting UDP");
Udp.begin(localPort);
setSyncProvider(getNtpTime);
setSyncInterval(3600); // einmal pro Stunde

//Uhrzeit Startzeit
Startzeit.Hour = 15;
Startzeit.Minute = 20;
Startzeit.Second = 0;
Startzeit.Wday = 22;
Startzeit.Month = 5;
Startzeit.Year = 2019 - 1970;  

}


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

void printDigits_Date(int digits) {
  if(digits < 10) {
    Serial.print('0');
 }
 Serial.print(digits);
}

void digitalClockDisplay()  {
 /*  Serial.print(hour());
  printDigits_Time(minute());
  printDigits_Time(second());
  Serial.print("  ");
  printDigits_Date(day());
  Serial.print(".");
  printDigits_Date(month());
  Serial.print(".");
  Serial.print(year());
  Serial.println(); */

  Serial.print(actualTime.Hour);
  Serial.print(":");
  Serial.print(actualTime.Minute);
  Serial.print(":");
  Serial.print(actualTime.Second);
  Serial.print("---");
  Serial.print(actualTime.Wday);
  Serial.print(".");
  Serial.print(actualTime.Month);
  Serial.print(".");
  Serial.print(actualTime.Year + 1970);
  Serial.print(".");
}





void timeToStruct (time_t t, tmElements_t *ptrA) {
  ptrA->Hour = hour(t);
  ptrA->Minute = minute(t);
  ptrA->Second = second(t);
  ptrA->Wday = day(t);
  ptrA->Month = month(t);
  ptrA->Year = year(t) - 1970;          //offeset from 1970
  //Serial.println(ptrA->Wday);
  
}


//https://forum.arduino.cc/index.php?topic=508716.0
void unixdiff(uint32_t zeit1, uint32_t zeit2) {      
uint32_t diff;
uint8_t sec, mi, hr;
  if (zeit1 > zeit2) diff = zeit1 - zeit2;
  else diff = zeit2 - zeit1;
  sec = diff % 60;
  diff /= 60;
  mi = diff % 60;
  diff /=60;
  hr = diff % 24;
  diff /= 24;
  /* Serial.print(F("Tage: ")); Serial.print(diff);
  Serial.print(F(" Stunden: ")); Serial.print(hr);
  Serial.print(F(" Minuten: ")); Serial.print(mi);
  Serial.print(F(" Sekunden: ")); Serial.println(sec); */
}




time_t tmConvert_t(int YYYY, byte MM, byte DD, byte hh, byte mm, byte ss) {
  tmElements_t tm;
  tm.Year = YYYY - 1970;    // offset from 1970;
  tm.Month = MM;    // 1 to 12
  tm.Day = DD;      // 1 to 31
  tm.Hour = hh;   //0 to 23
  tm.Minute = mm;   // 0 to 59
  tm.Second = ss;   //0 to 59
  //Serial.println(makeTime(tm));
  return makeTime(tm);
}


/*-------- NTP code ----------*/
void loop() {
if (timeStatus() != timeNotSet) {
  //vergleiche mit Vorstellung Weihnachtsstern von Tommy56 und bezogen auf NTP Client Example
  if (newSync)  {
    timeToStruct(lastSyncTime, &lastSyncStr);
    newSync = false;
  }
  if (now() != prevDisplay)   {     //update the display only if time has changed
    prevDisplay=now();
    timeToStruct(prevDisplay, &actualTime);
    digitalClockDisplay();
  }
}

Serial.println();
Serial.print("SynTime: ");
Serial.print(lastSyncStr.Hour);
  Serial.print(":");
  Serial.print(lastSyncStr.Minute);
  Serial.print(":");
  Serial.print(lastSyncStr.Second);
  Serial.print("---");
  Serial.print(lastSyncStr.Wday);
  Serial.print(".");
  Serial.print(lastSyncStr.Month);
  Serial.print(".");
  Serial.print(lastSyncStr.Year + 1970);
  Serial.print(".");



Serial.println("-----------------");
time_t s_tm1= tmConvert_t(year(),month(),day(),hour(),minute(),second());
Serial.println(makeTime(actualTime));
Serial.println(s_tm1);
Serial.println("-----------------");


/* Serial.println(Startzeit.Year);
Serial.println(Startzeit.Month);
Serial.println(Startzeit.Wday);
Serial.println(Startzeit.Hour);
Serial.println(Startzeit.Minute);
Serial.println(Startzeit.Second); */

//time_t s_tm2= tmConvert_t(Startzeit.Year, Startzeit.Month, Startzeit.Wday, Startzeit.Hour, Startzeit.Minute, Startzeit.Second);    //year, month, day, hour, minute, second
//unixdiff(s_tm1, s_tm2);
delay(1500);
}



const int NTP_PACKET_SIZE = 48; // NTP time is in the first 48 bytes of message
byte packetBuffer[NTP_PACKET_SIZE]; //buffer to hold incoming & outgoing packets

// return 0 wenn kein Sync
time_t getNtpTime(){
  IPAddress ntpServerIP; // NTP server's ip address
  static uint8_t num = 0;  // Nummer des NTP-Pool-Servers 4 für Fehlertest
 
  while (Udp.parsePacket() > 0) ; // discard any previously received packets
  WiFi.hostByName(ntpServerName[num], ntpServerIP);
  sendNTPpacket(ntpServerIP);
  uint32_t beginWait = millis();
  while (millis() - beginWait < 1500) {
    int size = Udp.parsePacket();
    if (size >= NTP_PACKET_SIZE) {
      Udp.read(packetBuffer, NTP_PACKET_SIZE);  // read packet into the buffer
      unsigned long secsSince1900;
      // convert four bytes starting at location 40 to a long integer
      secsSince1900 =  (unsigned long)packetBuffer[40] << 24;
      secsSince1900 |= (unsigned long)packetBuffer[41] << 16;
      secsSince1900 |= (unsigned long)packetBuffer[42] << 8;
      secsSince1900 |= (unsigned long)packetBuffer[43];
      lastSyncTime = secsSince1900 - 2208988800UL + timeZone * SECS_PER_HOUR;
      newSync = true;
      return lastSyncTime;
    }
  }
  Serial.println("No NTP Response");
  num = ++num %4;
  now();
  return 0; // return 0 if unable to get the time
}

// send an NTP request to the time server at the given address
void sendNTPpacket(IPAddress &address){
  // set all bytes in the buffer to 0
  memset(packetBuffer, 0, NTP_PACKET_SIZE);
  // Initialize values needed to form NTP request
  // (see URL above for details on the packets)
  packetBuffer[0] = 0b11100011;   // LI, Version, Mode
  packetBuffer[1] = 0;     // Stratum, or type of clock
  packetBuffer[2] = 6;     // Polling Interval
  packetBuffer[3] = 0xEC;  // Peer Clock Precision
  // 8 bytes of zero for Root Delay & Root Dispersion
  packetBuffer[12] = 49;
  packetBuffer[13] = 0x4E;
  packetBuffer[14] = 49;
  packetBuffer[15] = 52;
  // all NTP fields have been given values, now
  // you can send a packet requesting a timestamp:
  Udp.beginPacket(address, 123); //NTP requests are to port 123
  Udp.write(packetBuffer, NTP_PACKET_SIZE);
  Udp.endPacket();
}



Also dann bräuchte ich also die genannte Funktion timetoStruct nicht. Ich kann es also mit der Funktion breakTime() machen. Stimmt das?

Serenifly

Du hast vielleicht irgendwo die Umrechnung zur Epoche vergessen

Dazu gibt es entsprechende Makros in der Library (schau dir unbedingt die Header an):
Code: [Select]

#define  tmYearToCalendar(Y) ((Y) + 1970)  // full four digit year
#define  CalendarYrToTm(Y)   ((Y) - 1970)

LOOIIS

Das Offset habe ich berücksichtigt:

Code: [Select]
void timeToStruct (time_t t, tmElements_t *ptrA) {
  ptrA->Hour = hour(t);
  ptrA->Minute = minute(t);
  ptrA->Second = second(t);
  ptrA->Wday = day(t);
  ptrA->Month = month(t);
  ptrA->Year = year(t) - 1970;          //offeset from 1970
  //Serial.println(ptrA->Wday);
 
}


Code: [Select]
Serial.print(actualTime.Hour);
  Serial.print(":");
  Serial.print(actualTime.Minute);
  Serial.print(":");
  Serial.print(actualTime.Second);
  Serial.print("---");
  Serial.print(actualTime.Wday);
  Serial.print(".");
  Serial.print(actualTime.Month);
  Serial.print(".");
  Serial.print(actualTime.Year + 1970);


Die Ausgabe auf den seriellen Monitor ist aber richtig :-\

LOOIIS

Unterschied zwischen WDay und Day könnte Grund für den Unterschied des Time Stamps sein:

uint8_t Wday;   // day of week, sunday is day 1
uint8_t Day;

Wenn auch sonst noch irgendwo der Teufel im Detail steckt, auf alle Fälle das ist auch mit ein Grund warum das Ergebnis nicht das Richtige ist!

Go Up