Variablen mit 0 am Anfang

Servus, ich programmiere gerade eine RTC die eigentlich auch geht. Das Problem ist jedoch das es mir meine Uhrzeit im 1 Stelligen bereich 9:5:8 anstatt 09:05:08 darstellt.
Klar könnte man auf dem Seriellen Monitor oder auch display zuerst ne 0 for dem Eigentlichen Wert ausgeben, jedoch möchte ich lieber die 0 von der Variable dann bekommen und es dann komplett ausgeben.

Hat jemand ne idee Wie ich den Arduino zwingen kann die 0 am Anfang beizubehalten?

jedoch möchte ich lieber die 0 von der Variable dann bekommen und es dann komplett ausgeben.

Öhmm...

Du unterliegst einem Irrtum.
Es gibt keine 0, die man beibehalten könnte.
Numerische Variablen haben sowas nicht.

Schau mal nach printf oder sprintf und vorlaufender Null

Numerische Variablen mögen eigenlich nie vorangestellte Nullen.

Klaus_ww:
Numerische Variablen mögen eigenlich nie vorangestellte Nullen.

Doch, das mögen sie!!
Kann man gut zuweisen, die vorlaufende Null geht allerdings dabei verloren. Für die ist in der Variablen kein Platz.
Ausnahme: Zeichenketten.

0x138C (hexadezimal)
0234234 (oktal)
80028 (dezimal)

0x138C = 0234234 = 80028
Alles das gleiche, nur andere Schreibweise.

Wobei, das sind Konstante, besser: Konstante Literale.

Poste doch mal deinen Sketch. Am einfachsten ist es die Zahl als 2-stellige Zahl zu definieren.

combie:
Du unterliegst einem Irrtum.
Es gibt keine 0, die man beibehalten könnte.
Numerische Variablen haben sowas nicht.

Wenn ich Dich mal zitieren darf: Öhmm... ein Beispiel:

uint16_t zahl = 9;

Im Speicher steht dann binär 0000000000001001 oder hex 0009. Die Variable hat also schon irgendwie Nullen im Speicher.

Es ist eher eine Frage der Darstellung von Zahlen. Es ist üblich, Zahlen ohne führende Nullen zu schreiben oder auszugeben. Das ist aber eine willkürliche Festlegung. Serial.print() könnte also durchaus einen Parameter bereitstellen, der entsprechend des Variablentyps auch alle führenden Nullen mit ausgibt. Die formatierte Ausgabe wurde ja schon in #1 genannt.

combie:
0x138C = 0234234 = 80028
Alles das gleiche, nur andere Schreibweise.

Hier bist Du beim Thema Wertezuweisung, auch wichtig. Aber die Uhrzeit ist ja schon in der Variablen drin :wink:

gamer1:
... jedoch möchte ich lieber die 0 von der Variable dann bekommen und es dann komplett ausgeben.

Du bekommst die Null, nur wird sie bei der Anzeige unterdrückt. Wähle also eine Anzeige, die die Null nicht unterdrückt.

gamer1:
Servus, ich programmiere gerade eine RTC die eigentlich auch geht. Das Problem ist jedoch das es mir meine Uhrzeit im 1 Stelligen bereich 9:5:8 anstatt 09:05:08 darstellt.

Dann wirst Du das wohl entweder so programmiert haben, oder Du hast es so per copy-and-paste irgendwoher so kopiert.

gamer1:
Hat jemand ne idee Wie ich den Arduino zwingen kann die 0 am Anfang beizubehalten?

Hast Du eine Idee vom Programmieren?
Dann programmiere die formatierte Zeitausgabe anders, so wie Du es haben möchtest!

Oder beschränken sich Deine Ideen auf Copy-and-Paste von fremdem Code?
Dann kopiere Dir einen Code, der die Zeitausgabe anders formatiert!

Ganz unten auf der Seite Bildschirmausgaben | C-HowTo findest du Hinweise, wie du elegant die Null durch Formatierung der Ausgabe bekommst.

Sollen beim Auffüllen keine Leerzeichen, sondern führende Nullen verwendet werden, erreichen wir dies mit einer Null nach %, also %0. In diesem Beispiel sind die Variablenwerte tag und monat einstellig, zweistellig wird es mit einer führenden Null.

int tag=3, monat=9, jahr=2007;

printf("Ein Datum: %02d.%02d.%4d\n", tag, monat, jahr);



Ein Datum: 03.09.2007

printf() geht aber auf dem Arduino so standardmäßig nicht. Da braucht man schon sprintf() oder snprintf().

Oder man fragt einfach ab ob die Zahl < 10 ist und gibt dann per Serial.print() noch eine ‘0’ davor aus

@Theseus: C-HowTo sieht auf den ersten Blick ganz gut aus, habe ich mir gemerkt. Der Anfänger muß beachten, daß es um C allgemein und nicht um den Arduino und seine IDE geht. Leider kann ich keinen Index finden. Ich benutze auch C von A bis Z. Näher am Arduino ist Standard C library for AVR-GCC.

Serenifly:
printf() geht aber auf dem Arduino so standardmäßig nicht. Da braucht man schon sprintf() oder snprintf().

Danke für den Hinweis. Ich hatte es aus Zeitmangel nicht praktisch ausprobiert. Da ich das Problem immer wieder auch habe, will ich mich mal mit diesen Formatieranweisungen beschäftigen.

Eine gute allgemeine Doku zu printf() gibt es hier:
http://www.cplusplus.com/reference/cstdio/printf/

Und spezifisch für den Arduino:
http://www.nongnu.org/avr-libc/user-manual/group__avr__stdio.html#gaa3b98c0d17b35642c0f3e4649092b9f1

Da gibt es ein paar Dinge die nicht implementiert sind. Oder auch %S aus zusätzlichen Parameter für Flash-Strings.
sprintf_P(), bzw. snprintf_P() sind auch interessant.

Aber wie gesagt braucht man s(n)printf() um erst mal in ein char Array zu schreiben:
http://www.cplusplus.com/reference/cstdio/sprintf/
http://www.cplusplus.com/reference/cstdio/snprintf/

Hallo,
ist wohl so richtig keiner beigegangen…

Also, Du möchtest die “0” in einer Variable.

Das ist einfach:

int UhrZeitNull = 0;

Als Anfänger ist es Dir sicher noch nicht möglich, eine fachliche Frage mit
den nötigen Informationen zu stellen.
Das ist aber nichts schlimmes, wie Du siehst sind schon einige Anworten
aufgelaufen. Auch bist Du schon gefragt worden ob Du programmieren kannst. Oder
wie Dein Sketch denn zustande gekommen ist.
Diese Fragen tauchen immer wieder auf, weil man einfach zu wenig Informationen
hat um richtig helfen zu können. An anderer Stelle wird dann darüber beraten,
wie man Dir eine schöne Antwort geben könnte. Hilfe ist aber auch von dort
nicht zu erwarten.

Da hier nur sehr wenige Informationen vorliegen, muß auch ich leider raten,
wie Du Dir das vorstellst.
Wie Du einer Variable eine “0” als Wert vorgeben könntest, habe ich weiter
oben ja schon beschrieben.

Nun möchtest Du Deine Uhrzeit 9:5:8 als 09:05:08 ausgeben.

9 sind Deine Stunden
5 sind Deine Minuten
8 sind Deine Sekunden

Du könntest folgendes probieren:

if (Stunden < 10)
{
Serial.print (UhrZeitNull);
Serial.print (Stunden);
}
else
{
Serial.print (Stunden);
}
Serial.print (":");

if (Minuten < 10)
{
Serial.print (UhrZeitNull);
Serial.print (Minuten);
}
else
{
Serial.print (Minuten);
}
Serial.print (":")

if (Sekunden < 10)
{
Serial.print (UhrZeitNull);
Serial.println (Sekunden);
}
else
{
Serial.println (Sekunden);
}

das sollte eigentlich funktionieren. Wie gesagt, nur geraten.
Es gibt aber sicher noch eine Menge anderer Lösungen, einige findest Du in
den obigen Antworten.

Viel Spaß mit Deiner Arduino-Uhr, und auch hier im Forum.
Gruß
Andreas

Da das Thema immer wieder mal kommt, hier eine Funktion als Ansatz:

char * vorNull(int wert) {
  static char arr[3];
  byte zehner, einer;
  zehner = wert / 10; 
  einer = wert % 10;
  arr[0] = zehner + 48; // 48 ist der ASCII-Code der '0'
  arr[1] = einer + 48;
  arr[2] = '\0';
  return arr;
}

void setup() {
  Serial.begin(9600);
  Serial.println("Start");
  Serial.println(vorNull(3));
  Serial.println(vorNull(10));
  Serial.println(vorNull(24));
}

Die Funktion kann man noch straffen aber ich denke das kann jeder dann machen. So halte ich sie für verständlicher.

Gruß Tommy

Moin, danke schonmal für die ganzen Antworten.

Posted by jurs

  • Oct 14, 2016, 10:57 am
    Hast Du eine Idee vom Programmieren?

mal so mal so, aber momentan gerade nicht deswegen hab ich gefragt.
Und bevor die Frage auftaucht ich bin EGS Azubi in ner Firma die nicht wirklich was mit Programmieren am Hut hat (ausser unsere Techniker aber die machen nur Labview, Logos oder das Excelmakrose). Aber da die Abschlussprüfung im Februar mit nem Uno ist musst man das ja noch kurz 1/2 lernen.

PS. also in der Schule war das größte Aufgabe bisher in C einen Binärzähler machen und im Geschäft in Arduinoisch:

#include "TimerOne.h"  
int a = 0;
int b = 1800;
int c = 0;
int d = 1800;
int e = 0;
int f = 1800;
int g = 0;
int h = 1800;
int i = 0;
int j = 1800;
int k = 0;
int l = 1800;
int m = 0;
int n = 1800;
int o = 0;
int p = 1800;
int alle_x_sekunden=1;

void setup() {

pinMode(0, OUTPUT);
pinMode(1, OUTPUT);
pinMode(8, OUTPUT);
pinMode(9, OUTPUT);
pinMode(10, OUTPUT);
pinMode(11, OUTPUT);
pinMode(12, OUTPUT);
pinMode(13, OUTPUT);

Timer1.initialize(alle_x_sekunden*1000000);
Timer1.attachInterrupt(abfrage);


}

void abfrage (){
  //Wenn A0>(5V*(60/1024)) dann start
  if( a > 60 ){
  b--; }
  else if( a == LOW)
  { b = 1800;}
   if( b == 0 ){digitalWrite(13, LOW);}
  else if( b > 0 ){digitalWrite(13, HIGH);}
//a ist der Analog Read von CH1

   if( c > 60 ){
  d--; }
  else if( c == LOW)
  { d = 1800;}
   if( d == 0 ){digitalWrite(12, LOW);}
  else if( d > 0 ){digitalWrite(12, HIGH);}
//c ist der Analog Read von CH2

  if( e > 60 ){
  f--; }
  else if( e == LOW)
  { f = 1800;}
   if( f == 0 ){digitalWrite(11, LOW);}
  else if( f > 0 ){digitalWrite(11, HIGH);}
//e ist der Analog Read von CH3

  if( g > 60 ){
  h--; }
  else if( g == LOW)
  { h = 1800;}
   if( h == 0 ){digitalWrite(10, LOW);}
  else if( h > 0 ){digitalWrite(10, HIGH);}
//g ist der Analog Read von CH4

    if( i > 60 ){
  j--; }
  else if( i == LOW)
  { j = 1800;}
   if( j == 0 ){digitalWrite(9, LOW);}
  else if( j > 0 ){digitalWrite(9, HIGH);}
//i ist der Analog Read von CH5
  
    if( k > 60 ){
  l--; }
  else if( k == LOW)
  { l = 1800;}
   if( l == 0 ){digitalWrite(8, LOW);}
  else if( l > 0 ){digitalWrite(8, HIGH);}
//k ist der Analog Read von CH6

      if( m > 60 ){
  n--; }
  else if( m == LOW)
  { n = 1800;}
   if( n == 0 ){digitalWrite(1, LOW);}
  else if( n > 0 ){digitalWrite(1, HIGH);}
//m ist der Analog Read von CH7

   if( o > 60 ){
  p--; }
  else if( o == LOW)
  { p = 1800;}
   if( p == 0 ){digitalWrite(0, LOW);}
  else if( p > 0 ){digitalWrite(0, HIGH);}
  //o ist der Analog Read von CH8
  
  }
  
void loop() {
 a = analogRead(A0);
 c = analogRead(A1);
 e = analogRead(A2);
 g = analogRead(A3);
 i = analogRead(A4);
 k = analogRead(A5);
 m = analogRead(A6);
 o = analogRead(A7);
}

Posted by SkobyMobil

  • Oct 14, 2016, 04:50 pm
    Also, Du möchtest die “0” in einer Variable.

Das ist einfach:

Code: [Select]

int UhrZeitNull = 0;

Das ist zwar ne einfache Lösung, aber genau so will ichs ja nicht da die Zahl dann per Ethernet zu einem Labview-programm meines Meisters versendet wird und ich sie dann beim Programm auch nicht bekomme.
Also das die 0 auf dem Arduino Monitor fehlt ist egal. Jedoch schätz ich mal wenn sie hier im seriellen Monitor auftaucht, sollte sie dann auch im Labviewprogramm auftauchen.

So Sketch zum Beschreiben des Arduino:

#include <Wire.h>



void setup()
{

   Serial.begin(9600);
   Wire.begin();
   
       WriteRTCByte(0,0);       //STOP RTC
  WriteRTCByte(1,0x05);    //MINUTE=05
  WriteRTCByte(2,0x09);    //HOUR=09
  WriteRTCByte(3,0x09);    //DAY=1(MONDAY) AND VBAT=1
  WriteRTCByte(4,0x14);    //DATE=28
  WriteRTCByte(5,0x10);    //MONTH=2
  WriteRTCByte(6,0x16);    //YEAR=11
  WriteRTCByte(0,0x80);    //START RTC, SECOND=00

}
  
void loop(){

}

void WriteRTCByte(const unsigned char adr, const unsigned char data)
{
  Wire.beginTransmission(0x6f);
  Wire.write(adr);
  Wire.write(data);
  Wire.endTransmission();
}

Und zum Lesen:

#include <Wire.h>
int Stunden;
int Minuten;
int Sekunden;
int v=01;
boolean a=true;

void setup()
{
   Serial.begin(9600);
   Serial.println(v);
   Wire.begin();
}
  
void loop(){
   Stunde(2,6); //Stunde
   Serial.print(Stunden,HEX);
    Serial.print(":");
     Minute(1,7); //Stunde
   Serial.print(Minuten,HEX);
    Serial.print(":");
    Sekunde(0,7);
   Serial.print(Sekunden,HEX);
    Serial.println();
      delay(1000);
}


unsigned char ReadRTCByte(const unsigned char adr)
{
  unsigned char data;
   Wire.beginTransmission(0x6f);
    Wire.write(adr);
     Wire.endTransmission();
      Wire.requestFrom(0x6f,1);
       while (Wire.available()) data=Wire.read();
        return data;
}


void Stunde(const unsigned char adr, const unsigned char validbits)
{
   Stunden=ReadRTCByte(adr);
    Stunden=Stunden & 0xff>>(8-validbits);
}

void Minute(const unsigned char adr, const unsigned char validbits)
{
   Minuten=ReadRTCByte(adr);
    Minuten=Minuten & 0xff>>(8-validbits);
}

void Sekunde(const unsigned char adr, const unsigned char validbits)
{
   Sekunden=ReadRTCByte(adr);
    Sekunden=Sekunden & 0xff>>(8-validbits);
    if(Sekunden<10){;}
}

int alle_x_sekunden=1;
...
Timer1.initialize(alle_x_sekunden*1000000);

Bist du sicher dass das ok ist ?
Ich fürchte, da wird erst eine int -Multiplikation gemacht und dann daraus ein long. (= 16.960 ms )

Vorschlag:

#define TIMER_SEKUNDEN(x) (x*1000000UL)

Timer1.initialize(TIMER_SEKUNDEN(1));

Bist du sicher dass das ok ist ?

Also bis 2 Minuten hat ich keine Differenz beim Zeitmessen und bei 30 min ist mir die Abweichung egal da die Angeschlossenen Geräte nur Versorgt werden sollen, um auf die ungefähre Arbeitstemperatur zu kommen.

Dennoch danke auch dafüre werde ich mal Ausprobieren

Lösung Gefunden

String nulll = String("0");
String stringh;
String stringmin;
String stringsek;
String doppel = String(":");
String stringges;

void Uhr(){
   Stunde(2,6); //Stunde
   Minute(1,7); //Stunde
    Sekunde(0,7);
      myGLCD.setFont(GroteskBold24x48);
        myGLCD.setBackColor(VGA_WHITE);
         myGLCD.setColor(VGA_BLACK); //Benutze Schwarz
         stringges= stringh + doppel+ stringmin/*+ doppel + stringsek*/;
          myGLCD.print(stringges, 100,20);
       
}


void Stunde(const unsigned char adr, const unsigned char validbits)
{
   Stunden =ReadRTCByte(adr);
    Stunden = Stunden & 0xff>>(8-validbits); 

    if(Stunden<10)
    { stringh =  nulll+ String (Stunden,HEX);}
     else {
    stringh = String (Stunden,HEX);
     }

Sogar noch besser wie gedacht da ich es Später sowieso als String brauche

gamer1:
Sogar noch besser wie gedacht da ich es Später sowieso als String brauche

Da kann ich dir nicht zustimmen. Später wirst du wahrscheinlich feststellen, dass genau das das Problem ist.
Zudem es sich ja bei einer Uhrzeit ein char array[9] geradezu anbietet.

Tja, was soll man da sagen, wenn es geht. Und neben der Ansteuerung der myGLCD und ihrer Library kommt es auf ein bisschen Verschwendung wohl nicht an.

Aber wenn du schon eine Funktion wieReadRTCBytehast, hätte dir auch auffallen können, dass alle Ziffern deiner Zeit, inclusive führender Nullen back to topic schon in der RTC fix und fertig drin sind:

char zeit[] = "00:00:00";
StundeBCD = ReadRTCByte(2);  // oder gleich alle 3 Byte mit einem I2C Aufruf lesen ...
MinuteBCD = ReadRTCByte(1);
...

zeit[0] = '0' + (StundeBCD >>4) & 0x03;
zeit[1] = '0' + StundeBCD & 0x0F;
zeit[3] = '0' + (MinuteBCD >>4) & 0x07;
...
myGLCD.print(zeit, 100, 20);