Important update: Arm Announces End of Life Timeline for Mbed. This site will be archived in July 2026. Read the full announcement.
Important changes to forums and questions
All forums and questions are now archived. To start a new conversation or read the latest updates go to forums.mbed.com.
Problem's with the RTC
The error message: "no operator "*" matches these operands" in file "/main.cpp", Line: 256, Col: 48
Hello,
The problem is in the localtime function, from the API:
Quote:
returns - Pointer to the (statically allocated) tm structure
So the function returns a pointer to a tm structure. Now I guess you defined your 't' variable as:
struct tm t;
Then your assignment by localtime makes not much sense ;). Easiest option is to just define 't' right there, as showed in the example from the documentation:
struct tm *t = localtime(&seconds);
Or the equivalent, for example if 't' needs to be a global variable:
struct tm *t; t = localtime(&seconds);
In both cases now 't' is a pointer to a tm structure. Since localtime returns a pointer to a tm structure, this works good. Only thing you have to take into account is that your fprintf doesn't work anymore and needs some slight modifications. Since 't' is a pointer and not an object you have to address it either with t->tm_hour, or with (*t).tm_hour. (First one is the default when using pointers, second one first takes the object 't' points to).
But one more question. I'm writing this on an SD card in a file. But if the temperature is too high, then it print the fprintf line 10 times in a second. How can I get only one output?
One could either put an if to check if the second has changed or fix whatever is causing it. We'd more code to offer any more help..
Indeed for that we would need to see how your code works. The straight forward way would probably be to store the time of the last time it happened, then compare the current time to that time. If the difference is less than a certain amount you specify it ignores it.
@Erik: How can I write this? Because if I write for example if(seconds == seconds + 1000) or if(seconds != seconds), then the RTC stops.
This is the whole code:
#include "mbed.h" #include "TextLCD.h" #include "SDFileSystem.h" TextLCD lcd(p26, p25, p24, p23, p22, p20, p19, TextLCD::LCD20x4); SDFileSystem sd(p11, p12, p13, p14, "sd"); LocalFileSystem local("local"); Serial pc(USBTX,USBRX); DigitalOut myled1(LED1); DigitalOut myled2(LED2); DigitalOut myled3(LED3); DigitalOut myled4(LED4); AnalogIn temp(p15); FILE *fp; // Variablen fuer die Temperaturmessung float it = 0; int toowarm = 0; // Variablen fuer die Ueberpruefung der Zeit- und Temperaturuebereinstimmungen int time_u[16] = {0}; int temp_u[16] = {0}; // Variablen zum hochzaehlen der Schaltevent-Variablen int y = 0; int z = 0; // Variablen fuer die Zeitbasierte Schaltzeitenerfassung int led1time = 0; int led2time = 0; int led3time = 0; int led4time = 0; // Variablen fuer die Temperaturbasierte Schaltzeitenerfassung int led1temp = 0; int led2temp = 0; int led3temp = 0; int led4temp = 0; // Struktur mit den Variablen fuer die Zeiten und Daten der Schaltzeiten typedef struct chart { int function; int hour; int min; int start_day; int start_mon; int start_year; int stop_day; int stop_mon; int stop_year; int repeat; int action; int exit; float temperatur; } SCHALTTABELLE; SCHALTTABELLE schaltevent[16]; // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ // Hautpfunktion int main() { struct tm t; // fopen oeffnet die Textdatei "tabelle.txt" um Sie auszulesen fp = fopen("/local/tabelle.txt", "r"); // wenn fp NULL ist, konnte die Datei nicht geoeffnet werden, der Fehler wird ausgegeben if(fp == NULL) { pc.printf("Datei konnte nicht geoeffnet werden.\n"); } else { // Ueberschrift fuer die Ausgabe im HyperTerminal wird ausgegeben pc.printf("------------------------- [ Schaltuhr ] -------------------------\r\n\n\n"); // Inhalt der in die Textdatei gespeichert wurde (manuell) wird ausgelesen // 1. Funktion, 2. Zeit, 3. Startdatum, 4. Enddatum, 5. taeglich, 6. Aktion, 7. Ausgang, 8. Temperatur // Lese den Inhalt der Datei formatiert ein, speichere die Werte in Variablen und wiederhole es bis zum EOF while((fscanf(fp,"%d %d:%d %d.%d.%d %d.%d.%d %d %d %d %f\r\n", &schaltevent[y].function,&schaltevent[y].hour,&schaltevent[y].min,&schaltevent[y].start_day,&schaltevent[y].start_mon,&schaltevent[y].start_year, &schaltevent[y].stop_day, &schaltevent[y].stop_mon, &schaltevent[y].stop_year, &schaltevent[y].repeat,&schaltevent[y].action, &schaltevent[y].exit,&schaltevent[y].temperatur)) != EOF ) y++; for(z=0; z<16; z++) { // Gebe die eingelesenen Daten formatiert im HyperTerminal aus fprintf(stdout,"Funktion: %d\r\nZeit: %02d:%02d\r\nStartdatum: %02d.%02d.%04d\r\nEnddatum: %02d.%02d.%04d\r\ntaeglich: %d\r\nAktion: %d\r\nAusgang: %d\r\n" "Temperatur: %.1f\r\n\n\n", schaltevent[z].function, schaltevent[z].hour,schaltevent[z].min,schaltevent[z].start_day,schaltevent[z].start_mon,schaltevent[z].start_year, schaltevent[z].stop_day, schaltevent[z].stop_mon, schaltevent[z].stop_year, schaltevent[z].repeat,schaltevent[z].action,schaltevent[z].exit,schaltevent[z].temperatur); } // Datei wird geschlossen fclose(fp); } // Entnehme die Sekunden der RTC des mbed's zum stellen der aktuellen Uhrzeit void set_time(time_t t); // Das Programm wiederholt ab hier alles unendlich (bis die Bedingung nicht mehr erf�st) while (1) { // Temperatur "messen" und in eine Variable speichern float tmp = temp.read(); time_t seconds = time(NULL); // Gebe die Zeit, das Datum und die Temperatur auf dem LCD-Display aus char buffer[32]; strftime(buffer, 32, " %H:%M:%S\n%a, %d/%m/%Y\n", localtime(&seconds)); lcd.locate(0,0); lcd.printf("%s", buffer); lcd.locate(0,2); lcd.printf(" %2.1f C", tmp); lcd.locate(0,3); lcd.printf("BBR Verkehrstechnik"); // Vergleiche alle Schaltevents, ob sie jetzt ausgefuehrt werden sollen // Unterscheide zwischen Zeit und Temperaturevent for (z=0; z<16; z++) { // Zeitevent if(schaltevent[z].function == 1) { // aus dem Zeitevent eine Angabe in Sekunden bilden t.tm_sec = 0; t.tm_min = schaltevent[z].min; t.tm_hour = schaltevent[z].hour; t.tm_mday = schaltevent[z].start_day; t.tm_mon = schaltevent[z].start_mon-1; t.tm_year = schaltevent[z].start_year-1900; // in Sekunden konvertieren time_t event_seconds = mktime(&t); // Zeitueberpruefung // Bei Ueberweinstimmung setze time_u[z] auf 1 if((event_seconds) == (seconds)) { time_u[z] = 1; // wenn es taeglich ausgefuehrt werden soll (repeat == 1), zaehle den Starttag und den Endtag hoch if(schaltevent[z].repeat == 1) { schaltevent[z].start_day++; schaltevent[z].stop_day++; } // wenn der Starttag noch kleiner ist als der Endtag, dann fuehre die Aktion weiterhin taeglich um die selbe Uhrzeit aus if((schaltevent[z].start_day) <= (schaltevent[z].stop_day)) { schaltevent[z].start_day++; } } // Gibt es eine zeitliche Uebereinstimmungen if (time_u[z]==1) { // Unterscheide zwischen den auszufuehrenden Aktionen if (schaltevent[z].action == 1) { // Merker Einschalten setzen if(schaltevent[z].exit == 1) { led1time = 1; // Beziehe die SD-Karte als Datenlogger mit ein mkdir("/sd/mydir", 0777); // Oeffne die Datei Zeiten.txt um die Schaltzeit einmalig oder bei jedem neuen Event abzuspeichern fp = fopen("/sd/mydir/Zeiten.txt", "a"); fprintf(fp,"[ Z ] - Uhrzeit: %02d:%02d Datum: %02d.%02d.%04d Aktion: LED1 an\r\n" ,schaltevent[z].hour,schaltevent[z].min,schaltevent[z].start_day,schaltevent[z].start_mon,schaltevent[z].start_year); // Datei wird geschlossen fclose(fp); } if(schaltevent[z].exit == 2) { led2time = 1; // Beziehe die SD-Karte als Datenlogger mit ein mkdir("/sd/mydir", 0777); // Oeffne die Datei Zeiten.txt um die Schaltzeit einmalig oder bei jedem neuen Event abzuspeichern fp = fopen("/sd/mydir/Zeiten.txt", "a"); fprintf(fp,"[ Z ] - Uhrzeit: %02d:%02d Datum: %02d.%02d.%04d Aktion: LED2 an\r\n" ,schaltevent[z].hour,schaltevent[z].min,schaltevent[z].start_day,schaltevent[z].start_mon,schaltevent[z].start_year); // Datei wird geschlossen fclose(fp); } if(schaltevent[z].exit == 3) { led3time = 1; // Beziehe die SD-Karte als Datenlogger mit ein mkdir("/sd/mydir", 0777); // Oeffne die Datei Zeiten.txt um die Schaltzeit einmalig oder bei jedem neuen Event abzuspeichern fp = fopen("/sd/mydir/Zeiten.txt", "a"); fprintf(fp,"[ Z ] - Uhrzeit: %02d:%02d Datum: %02d.%02d.%04d Aktion: LED3 an\r\n" ,schaltevent[z].hour,schaltevent[z].min,schaltevent[z].start_day,schaltevent[z].start_mon,schaltevent[z].start_year); // Datei wird geschlossen fclose(fp); } if(schaltevent[z].exit == 4) { led4time = 1; // Beziehe die SD-Karte als Datenlogger mit ein mkdir("/sd/mydir", 0777); // Oeffne die Datei Zeiten.txt um die Schaltzeit einmalig oder bei jedem neuen Event abzuspeichern fp = fopen("/sd/mydir/Zeiten.txt", "a"); fprintf(fp,"[ Z ] - Uhrzeit: %02d:%02d Datum: %02d.%02d.%04d Aktion: LED4 an\r\n" ,schaltevent[z].hour,schaltevent[z].min,schaltevent[z].start_day,schaltevent[z].start_mon,schaltevent[z].start_year); // Datei wird geschlossen fclose(fp); } } else { if(schaltevent[z].exit == 1) { led1time = 0; } if(schaltevent[z].exit == 2) { led2time = 0; } if(schaltevent[z].exit == 3) { led3time = 0; } if(schaltevent[z].exit == 4) { led4time = 0; } } time_u[z]=0; } } // Temperaturevent if(schaltevent[z].function == 2) { // Temperaturueberpruefung // Bei zu hoher Temperatur setze temp_u auf 1 it = 0; it = it + tmp; if(it > schaltevent[z].temperatur) toowarm = 1; if(it < schaltevent[z].temperatur) toowarm = 0; if(toowarm == 1) { temp_u[z] = 1; } if(toowarm == 0) { temp_u[z] = 0; } if(temp_u[z] == 1) { // Unterscheide zwischen den auszufuehrenden Aktionen // Merker Einschalten setzen if(schaltevent[z].exit == 1) { led1temp = 1; // Beziehe die SD-Karte als Datenlogger mit ein mkdir("/sd/mydir", 0777); // Oeffne die Datei Zeiten.txt um die Schaltzeit einmalig oder bei jedem neuen Event abzuspeichern fp = fopen("/sd/mydir/Zeiten.txt", "a"); // Zeitpunkt holen bzw. den bereits geholten Wert umwandeln struct tm *t; t = localtime(&seconds); fprintf(fp, "[ T ] - Uhrzeit: %02d:%02d Datum: %02d.%02d.%04d Aktion: LED1 an\r\n", t->tm_hour, t->tm_min,t->tm_mday,t->tm_mon,t->tm_year); // Datei wird geschlossen fclose(fp); } if(schaltevent[z].exit == 2) { led2temp = 1; // Beziehe die SD-Karte als Datenlogger mit ein mkdir("/sd/mydir", 0777); // Oeffne die Datei Zeiten.txt um die Schaltzeit einmalig oder bei jedem neuen Event abzuspeichern fp = fopen("/sd/mydir/Zeiten.txt", "a"); // Zeitpunkt holen bzw. den bereits geholten Wert umwandeln struct tm *t; t = localtime(&seconds); fprintf(fp, "[ T ] - Uhrzeit: %02d:%02d Datum: %02d.%02d.%04d Aktion: LED1 an\r\n", t->tm_hour, t->tm_min,t->tm_mday,t->tm_mon,t->tm_year); // Datei wird geschlossen fclose(fp); } if(schaltevent[z].exit == 3) { led3temp = 1; // Beziehe die SD-Karte als Datenlogger mit ein mkdir("/sd/mydir", 0777); // Oeffne die Datei Zeiten.txt um die Schaltzeit einmalig oder bei jedem neuen Event abzuspeichern fp = fopen("/sd/mydir/Zeiten.txt", "a"); // Zeitpunkt holen bzw. den bereits geholten Wert umwandeln struct tm *t; t = localtime(&seconds); fprintf(fp, "[ T ] - Uhrzeit: %02d:%02d Datum: %02d.%02d.%04d Aktion: LED1 an\r\n", t->tm_hour, t->tm_min,t->tm_mday,t->tm_mon,t->tm_year); // Datei wird geschlossen fclose(fp); } if(schaltevent[z].exit == 4) { led4temp = 1; // Beziehe die SD-Karte als Datenlogger mit ein mkdir("/sd/mydir", 0777); // Oeffne die Datei Zeiten.txt um die Schaltzeit einmalig oder bei jedem neuen Event abzuspeichern fp = fopen("/sd/mydir/Zeiten.txt", "a"); // Zeitpunkt holen bzw. den bereits geholten Wert umwandeln struct tm *t; t = localtime(&seconds); fprintf(fp, "[ T ] - Uhrzeit: %02d:%02d Datum: %02d.%02d.%04d Aktion: LED1 an\r\n", t->tm_hour, t->tm_min,t->tm_mday,t->tm_mon,t->tm_year); // Datei wird geschlossen fclose(fp); } } else { if(schaltevent[z].exit == 1) { led1temp = 0; } if(schaltevent[z].exit == 2) { led2temp = 0; } if(schaltevent[z].exit == 3) { led3temp = 0; } if(schaltevent[z].exit == 4) { led4temp = 0; } } } // Abgleich ob der jeweilige Ausgang ueber die Temperatur oder die Zeit geschaltet wird if ((led1time == 1)||(led1temp == 1)) { myled1 = 1; } else { myled1 = 0; } if ((led2time == 1)||(led2temp == 1)) { myled2 = 1; } else { myled2 = 0; } if ((led3time == 1)||(led3temp == 1)) { myled3 = 1; } else { myled3 = 0; } if ((led4time == 1)||(led4temp == 1)) { myled4 = 1; } else { myled4 = 0; } } } }
Quote:
Because if I write for example if(seconds == seconds + 1000) or if(seconds != seconds), then the RTC stops.
Those are both situations that can (obviously) never happen, seconds can never be equal to seconds + 1000, and it also cannot be unequal to itself.
I hadn't used the RTC myself before, so had to figure it a bit out with the documentation, but something like this seems to work:
#include "mbed.h" int main() { set_time(0); time_t seconds; time_t seconds_prev = 0; while(1) { seconds = time(NULL); if (seconds>=seconds_prev+5) { printf("Time since start = %d\n\r", seconds); wait(.1); seconds_prev = seconds; } } }
Its output is:
Time since start = 5 Time since start = 10 Time since start = 15 Time since start = 20 Time since start = 25 Time since start = 30 Time since start = 35 Time since start = 40
Hey, I have a problem. I want to program a data logger for a time switch.
I always want when the temperature is too high to enable an LED,... that works. And then when the output is set to be simultaneously written purely unique in a file, the time, date and action. And because the temperature is not bound to specific times, I have to use the RTC. But it does not work the way I thought.
This is a part of the code (which works not)
Sorry for my bad English ;)