Hey,
I want to create a string of the actual time.
It works pretty well if the minute count is above 9.
Then It shows like this: 20:12
If it's not higher than 9, it shows like this: 20:5
I need 20:05 not 20:5.
How can I create the string in a way which can correct this effect?
void ntp()
{
//Seperate the components of the time/date for using it to trigger the event of sending a mail in "void triggermail()".
//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
time(&now); // read the current time
localtime_r(&now, &tm); // update the structure tm with the current time
Serial.print("year:");
Serial.print(tm.tm_year + 1900); // years since 1900
Serial.print("\tmonth:");
Serial.print(tm.tm_mon + 1); // January = 0 (!)
Serial.print("\tday:");
Serial.print(tm.tm_mday); // day of month
Serial.print("\thour:");
Serial.print(tm.tm_hour); // hours since midnight 0-23
Serial.print("\tmin:");
Serial.print(tm.tm_min); // minutes after the hour 0-59
Serial.print("\tsec:");
Serial.print(tm.tm_sec); // seconds after the minute 0-61*
Serial.print("\twday");
Serial.println(tm.tm_wday); // days since Sunday 0-6
t = String(tm.tm_hour) + ":" + String(tm.tm_min);
Serial.println(t);
}
Maybe someone can show it to me.
Thanks a lot!
checking for number beeing lower than 10
and building the string in multiple steps
if (number < 10) {
//add a "leading zero "0"
}
by the way you should not use String at all
variabletype String is dangerous to use if you don't know exactly what you are doing
I recomend using SafeString. The name is program
The function posted below works this way
you have defined a variable as SafeString with big enough length
createSafeString(myTime_SS, 256);
and then "handover" the variable as a parameter
StoreTimeStampIntoSS(myTime_SS);
Serial.println(myTime_SS);
// my personal naming-convention parameter of functions start with prefix "p_"
void StoreTimeStampIntoSS(SafeString& p_RefToSS) {
time(&now); // read the current time
localtime_r(&now, &myTimeInfo); // update the structure tm with the current time
//p_RefToSS = " ";
p_RefToSS = myTimeInfo.tm_year + 1900;
p_RefToSS += ".";
if (myTimeInfo.tm_mon + 1 < 10) {
p_RefToSS += "0";
}
p_RefToSS += myTimeInfo.tm_mon + 1;
p_RefToSS += ".";
if (myTimeInfo.tm_mday < 10) {
p_RefToSS += "0";
}
p_RefToSS += myTimeInfo.tm_mday;
p_RefToSS += "; ";
if (myTimeInfo.tm_hour < 10) {
p_RefToSS += "0";
}
p_RefToSS += myTimeInfo.tm_hour;
p_RefToSS += ":";
if (myTimeInfo.tm_min < 10) {
p_RefToSS += "0";
}
p_RefToSS += myTimeInfo.tm_min;
p_RefToSS += ":";
if (myTimeInfo.tm_sec < 10) {
p_RefToSS += "0";
}
p_RefToSS += myTimeInfo.tm_sec;
//p_RefToSS += ",";
}
best regards Stefan
1 Like
Hey, thank you!
I think I am not able to do it like you suggested by converting it to a SaveString.
I tried to do it the first way you said, but I also failed.
I have this pathetic thing now and it does not work and I remembered, that I have to do the same thing with hours too
if (tm.tm_min < 10) {
String corrected("0" + tm.tm_min);
Serial.println(corrected);
t = String(tm.tm_hour) + ":" + corrected;
}
else {
t = String(tm.tm_hour) + ":" + String(tm.tm_min);
}
Serial.println(t);
you should really start experimenting more with small demo-codes
You seem to be stuck into "modify the code as less as possible to keep it working"
you can have mutliple variables
and then add them to one variable as you are already doing it.
SafeString is a library that can be installed with the library-manager
best regards Stefan
hm. Unfortunately, that does not help me I do not have the so much time to do things super clean and learning things from scratch.
I have to take care of two little kids and only sometimes, when they are sleeping, I can tinker at this code.
Anyway, thanks for your help. Maybe sometime I am able to get things working.
Thank you.
If you post your complete sketch
by using this method that adds the code-tags
There is an automatic function for doing this in the Arduino-IDE
just three steps
press Ctrl-T for autoformatting your code
do a rightclick with the mouse and choose "copy for forum"
paste clipboard into write-window of a posting
The community can make suggestions including functions that can be added to your existing code.
best regards Stefan
but it is a bloody mess of a code...
there is a webserver included and I make time inputs which are strings and which I use to trigger events.
#include <esp-fs-webserver.h> // https://github.com/cotestatnt/esp-fs-webserver
#include <MobaTools.h>
#include <FS.h>
#ifdef ESP8266
#include <LittleFS.h>
#define FILESYSTEM LittleFS
#elif defined(ESP32)
#include <FFat.h>
#define FILESYSTEM FFat
#endif
// Define NTP properties
#define NTP_ADDRESS "de.pool.ntp.org" // change this to whatever pool is closest (see ntp.org)
#define MY_TZ "CET-1CEST,M3.5.0/02,M10.5.0/03" //Timezone
time_t now; // this is the epoch
tm tm; // the structure tm holds time information in a more convient way
String t; //
String sunset = "";
String sunrise = "";
String sunriseonoff = "off";
int flag = 0; //flag for trigger event
int flag2 = 0;
int flag3 = 0;
unsigned long previousMillis = 0;
const long interval = 10000;
unsigned long previousMillissun = 0; // will store last time sunset/sunrise was updated
unsigned long intervalsun = 20000; // interval at which the illumination is reduced/rised (milliseconds)
// In order to set SSID and password open the /setup webserver page
// const char* ssid;
// const char* password;
bool apMode = false;
char* hostname = "fsbrowser";
#ifdef ESP8266
ESP8266WebServer server(80);
#elif defined(ESP32)
WebServer server(80);
#endif
FSWebServer myWebServer(FILESYSTEM, server);
// Adjust pins, steps and time as needed
const byte stepPin = 0;
const byte dirPin = 2;
const int stepsProUmdr = 960; // Steps per Revolution ( exammple with 1/4 microsteps ) //800 ---- 960
int stepsProTickf = -100; // Steps to be executed every intervall
int stepsProTickr = 100; // Steps to be executed every intervall
const int switch1 = 14;
const int switch2 = 12;
const int enablepin = 13;
int switchval1 = 1;
int switchval2 = 1;
int positionvalue = 0;
int positionvalueold = 0;
int prozent = 0;
int stepsint = 0;
byte intervallZaehler;
const int maxdistance = 250; //2560
MoToStepper myStepper ( stepsProUmdr, STEPDIR );
MoToTimebase intervall;
//Variables to save values from HTML form
String direction = "STOP";
String steps = "0";
String message = "";
bool notifyStop = false;
String reply;
void nullposition() {
//er soll 2600 in eine Richtung fahren bis zum Endschalter. So wird die Nullposition ermittelt.
Serial.println("Nullposition einnehmen");
steps = "-2600"; //-2600
//myStepper.setSpeedSteps(100);
myStepper.setSpeed( 100 );
myStepper.doSteps(steps.toInt());
positionvalue = 0;
}
void startmove()
{
if ( switchval1 == 1 && switchval2 == 1 ) {
myStepper.setSpeed( 600 );
myStepper.doSteps(steps.toInt());
}
}
void calcreverse() {
positionvalue = maxdistance * prozent / 100;
if (positionvalueold > positionvalue) {
stepsint = positionvalue - positionvalueold;
steps = String(stepsint);
positionvalueold = positionvalue;
startmove();
}
if (positionvalueold < positionvalue) {
stepsint = positionvalue - positionvalueold;
steps = String(stepsint);
positionvalueold = positionvalue;
startmove();
}
}
void sunriseset() {
if ( prozent >= 90 ) {
flag2 = 0;
}
if (flag2 == 1) {
//sunrise
//pro Minute 3% hoch fahren bis positionvalue maximal 90%
prozent = prozent + 1; //in percent. needed for illumination value
Serial.println(prozent);
calcreverse(); //set illumination
}
}
void sunsetset() {
if ( prozent == 0 ) {
flag3 = 0;
}
if (flag3 == 1) {
prozent = prozent - 1;
Serial.println(prozent);
calcreverse(); //set illumination
}
}
//////////////////////////////// Filesystem /////////////////////////////////////////
void startFilesystem() {
// FILESYSTEM INIT
if ( FILESYSTEM.begin()) {
File root = FILESYSTEM.open("/", "r");
File file = root.openNextFile();
while (file) {
const char* fileName = file.name();
size_t fileSize = file.size();
Serial.printf("FS File: %s, size: %lu\n", fileName, (long unsigned)fileSize);
file = root.openNextFile();
}
Serial.println();
}
else {
Serial.println("ERROR on mounting filesystem. It will be formmatted!");
FILESYSTEM.format();
ESP.restart();
}
}
//////////////////////////// HTTP Request Handlers ////////////////////////////////////
void handleSetTime() {
if (myWebServer.webserver->hasArg("switch")) {
String reply = "Switch state: ";
reply += myWebServer.webserver->arg("switch");
Serial.println(reply);
sunriseonoff = myWebServer.webserver->arg("switch");
}
if (myWebServer.webserver->hasArg("sunrise")) {
String reply = "Sunrise: ";
reply += myWebServer.webserver->arg("sunrise");
Serial.println(reply);
sunrise = myWebServer.webserver->arg("sunrise");
Serial.println(sunrise);
}
if (myWebServer.webserver->hasArg("sunset")) {
String reply = "Sunset: ";
reply += myWebServer.webserver->arg("sunset");
Serial.println(reply);
Serial.println(reply);
sunset = myWebServer.webserver->arg("sunset");
Serial.println(sunset);
}
myWebServer.webserver->send(200, "text/plain", "setup automated illumination done");
}
void handleIllumination() {
if (myWebServer.webserver->hasArg("light-level")) {
reply = "Illumination level: "; //String reply
reply += myWebServer.webserver->arg("light-level").toInt();
prozent = myWebServer.webserver->arg("light-level").toInt();
Serial.println(reply);
Serial.print("prozent: ");
Serial.println(prozent);
calcreverse();
myWebServer.webserver->send(200, "text/plain", reply);
}
}
void ntp()
{
//Seperate the components of the time/date for using it to trigger the event of sending a mail in "void triggermail()".
//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
time(&now); // read the current time
localtime_r(&now, &tm); // update the structure tm with the current time
Serial.print("year:");
Serial.print(tm.tm_year + 1900); // years since 1900
Serial.print("\tmonth:");
Serial.print(tm.tm_mon + 1); // January = 0 (!)
Serial.print("\tday:");
Serial.print(tm.tm_mday); // day of month
Serial.print("\thour:");
Serial.print(tm.tm_hour); // hours since midnight 0-23
Serial.print("\tmin:");
Serial.print(tm.tm_min); // minutes after the hour 0-59
Serial.print("\tsec:");
Serial.print(tm.tm_sec); // seconds after the minute 0-61*
Serial.print("\twday");
Serial.println(tm.tm_wday); // days since Sunday 0-6
tm.tm_min = 8; //only for testing
if (tm.tm_min < 10) {
String corrected("0" + tm.tm_min);
Serial.println(corrected);
t = String(tm.tm_hour) + ":" + corrected;
}
else {
t = String(tm.tm_hour) + ":" + String(tm.tm_min);
}
Serial.println(t);
}
void triggerevent() {
unsigned long currentMillis = millis();
if (currentMillis - previousMillis >= interval) {
ntp();
Serial.println(sunrise);
Serial.println(sunset);
//sunrise
if ((t) == sunrise) {
Serial.println(" sunrise ");
flag2 = 1;
}
//sunset
if ((t) == sunset ) {
flag3 = 1;
}
previousMillis = currentMillis;
}
}
void setup() {
Serial.begin(115200);
configTime(MY_TZ, NTP_ADDRESS);
pinMode(switch1, INPUT);
pinMode(switch2, INPUT);
pinMode(enablepin, INPUT);
digitalWrite(enablepin , LOW);
myStepper.attach( stepPin, dirPin );
myStepper.setSpeed( 600 ); // 60 Umdrehungen/Min 600
// uint16_t myStepper.setSpeedSteps( uint32_t speed10 );
myStepper.setRampLen( 10 );
myStepper.attachEnable( enablepin, 50, LOW);
// FILESYSTEM INIT
startFilesystem();
// Try to connect to flash stored SSID, start AP if fails after timeout
IPAddress myIP = myWebServer.startWiFi(15000, "ESP8266_AP", "123456789" );
// Add custom page handlers to webserver
// myWebServer.addHandler("/led", HTTP_GET, handleLed);
myWebServer.addHandler("/setIllumination", HTTP_GET, handleIllumination);
myWebServer.addHandler("/setTime", HTTP_POST, handleSetTime);
// Start webserver
if (myWebServer.begin()) {
Serial.print(F("ESP Web Server started on IP Address: "));
Serial.println(myIP);
Serial.println(F("Open /setup page to configure optional parameters"));
Serial.println(F("Open /edit page to view and edit files"));
}
nullposition();
ntp();
}
void loop() {
myWebServer.run();
switchval1 = digitalRead(switch1);
switchval2 = digitalRead(switch2);
if ( switchval2 == 0 ) {
Serial.println("Switch 1 aktiviert");
steps = "10";
prozent = 0;
myStepper.doSteps(steps.toInt());
delay(500);
}
if ( switchval1 == 0 ) {
Serial.println("Switch 2 aktiviert");
positionvalue = 0;
steps = "-10";
myStepper.doSteps(steps.toInt());
prozent = 100;
delay(500);
}
triggerevent();
unsigned long currentMillissun = millis();
if (currentMillissun - previousMillissun > intervalsun && sunriseonoff == "on" ) {
ntp();
Serial.println("flag2: ");
Serial.println(flag2);
Serial.println("flag3: ");
Serial.println(flag3);
sunriseset();
sunsetset();
previousMillissun = currentMillissun;
}
}
On an ESP, the "String" is fairly safe to use, but standard C formatters are better and more versatile:
const char HOUR_MINUTE_FORMAT[] = "%02d:%02d";
char buf[10];
sprintf(buf, HOUR_MINUTE_FORMAT, hour, minute);
Serial.println(buf);
EDIT: Link to a reference for the (s)printf methods .
1 Like
Hey,
thank you very much! That's what I was looking for!
const char HOUR_MINUTE_FORMAT[] = "%02d:%02d";
char buf[10];
sprintf(buf, HOUR_MINUTE_FORMAT, tm.tm_hour, tm.tm_min);
Serial.println(buf);
t = buf;
That's not true. Pretty good organised code using functions with self-descriptive names. I estimate you are in the upper third of all coders with your formatting and structuring style.
best regards Stefan
StefanL38:
e n
self-descriptive names? not sure. I steal most of the code somewhere and put the stuff together. sometimes I forget to change the commentary so that it turns step by step into a chaos.
But thank you.
system
Closed
July 17, 2022, 7:54am
12
This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.