Byte_to_String mit führenden Nullen

Termi

Level-2
Beiträge
105
Reaktionspunkte
7
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo,
ich möchte gerne Uhrzeiten darstellen der Form 03:00. Leider kappt mir Byte_to_String immer die führende Null. Als Anzeige habe ich dann 3:0. Erinnert mich eher an ein Bundesligaergebnis. Hat einer einen Tip wie ich die führenden Nullen hinbekomme. Der Weg dahin sollte möglichst kurz sein. Einen langen habe ich Netz gefunden. ist aber zuviel Schnack und Berechnung bei. Kostet bei 200 Zeiten zuviel Rechenzeit. Also quick and dirty ist gefordert.

Wenn 3S mitliest: Das wäre ein weiterer Verbesserungsvorschlag für das Object, nachdem ihr auf meinen letzten schon nicht geantwortet habt, vielleicht gibt es hier eine Antwort ;-).

Danke schon mal

Termi
 
Wer oder was soll denn die Uhrzeit darstellen? Kann da vielleicht die Ausgabe einer Time- oder Time_of_Day-Variable passend formatiert werden statt die SPS die Formatierung in einen String machen zu lassen?
Du könntest auch eine DATE_AND_TIME in String wandeln und mit MID die 5 Zeichen Uhrzeit-Teilstring entnehmen.
Falls Du eine Funktion zur Ausgabe als Hex hast, könntest Du die Stunden und Minuten in BCD wandeln und als 2 Ziffern hex in den String schreiben.

Ich weiß nicht, was für einen "langen Weg" Du im Netz gefunden hast, doch selbst ein zu-Fuß-zusammenbasteln des Strings aus einer DATE_AND_TIME-Variable braucht keine 200 Zeilen Code. (außerdem ist die Anzahl Codezeilen kein Maß für die benötigte Rechenzeit)

Hier mal eine Anregung:
Code:
    tmpT := '00:00' ; // String initialisieren

    tmpW.B0 := baDT.Hour ; // Stunde
    tmpW.B1 := DWORD_TO_BYTE( SHR(IN:=BYTE_TO_DWORD(baDT.Hour), N:=4) ) ;
    tmpWord := tmpWord AND W#16#0F0F OR W#16#3030 ;
    tbaT[1] := tmpW.B1 ;
    tbaT[2] := tmpW.B0 ;

    tmpW.B0 := baDT.Minute ; // Minute
    tmpW.B1 := DWORD_TO_BYTE( SHR(IN:=BYTE_TO_DWORD(baDT.Minute), N:=4) ) ;
    tmpWord := tmpWord AND W#16#0F0F OR W#16#3030 ;
    tbaT[4] := tmpW.B1 ;
    tbaT[5] := tmpW.B0 ;
(die je 3 Zeilen tmpW... lassen sich auch in nur 1 Zeile Code packen)
Hier ein ganzer Baustein mit den AT-Deklarationen zu diesem Beispielcode.

Harald
 
sorry, ich habe mich sehr missverständlich ausgedrückt und zu wenig Infos gegeben:
ich lese die Daten aus meiner Viessmann KW200 Heizungssteuerung. Jede Tageszeit im 10 Minutentakt bytecodiert. Bei 24h in nur einem Byte muss man halt ein bisschen "dekodieren". Ich muss sagen die Idee ist Top.

hier ist der Code:


Byte_Zeit := 0#18; (*für 03:00Uhr oder 16#B0 für 22:00Uhr, fürs Forum*)
IF Byte_Zeit = 16#FF THEN (* wenn ein FF, dann ist keine Zeit eingetragen *)
TextRet := '--:--';
ELSE
TextRet := ''; (*löschen nur zur Beruhigung ;-)*)
TextRet := concat(BYTE_TO_STRING(SHR(Byte_Zeit,3)) ,':');
TextRet := concat(TextRet,BYTE_TO_STRING((Byte_Zeit AND 07)*10));
END_IF

in TextRet steht das was ich nicht immer will ;-)

Danke schon mal für eure Ansätze


Gruß
Termi
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Wenn es denn unbedingt mit den rechenzeitaufwendigen Stringfunktionen gemacht werden soll ("Hauptsache nur 2 Codezeilen" ;) ), dann könnte es nach diesem Prinzip funktionieren:
Code:
TextRet := concat(mid(BYTE_TO_STRING(SHR(Byte_Zeit,3) + 100),2,1),':');
TextRet := concat(TextRet,mid(BYTE_TO_STRING((Byte_Zeit AND 7) * 10 + 100),2,1));

Harald
 
Zuletzt bearbeitet:
Rückmeldung:
klappt leider noch nicht. Folgendes Ergebnis ergibt sich:


2015-10-20_211620.jpg

dabei ist das eingestellt bei gleichen Eingangswerten

2015-10-20_211808.jpg

Ich werde deinen Ansatz mal näher untersuchen. Kann sich anscheinend nur um falsche Klammern handeln. Die Werte sind übrigens 16#2B für 5:30 und 16#B2 für 22:30

Gruß und Danke

Termi
 
Folgendes Ergebnis ergibt sich:
Es ist ziemlich deutlich zu sehen, daß die mid()-Funktion 1 Zeichen zu früh zurückgibt - weil das erste Zeichen im String hat die Positionsnummer 1. Es soll das zweite und dritte Zeichen geliefert werden. Versuche mal:
Code:
TextRet := concat(mid(BYTE_TO_STRING(SHR(Byte_Zeit,3) + 100),2,2),':');
TextRet := concat(TextRet,mid(BYTE_TO_STRING((Byte_Zeit AND 7) * 10 + 100),2,2));


Sollte das nicht 22:20 sein?

Harald
 
hallo, ist zwar schon erledigt ....... aber .....
wenn es um recourcenschonung geht würde ich das anders lösen :wink:
generiert je nach steuerung ca. 400 byte weniger code :cool:
gruß

Code:
VAR
    TextRet : STRING[5];
    pTextRet : POINTER TO ARRAY[0..3] OF BYTE;
    Byte_zeit : BYTE;
END_VAR

pTextRet := ADR(TextRet);
Byte_Zeit := %MB0;

IF Byte_Zeit > 16#BD THEN
    TextRet := '--:--';
ELSE
    TextRet := '00:00';
    pTextRet^[0] := 48 + (SHR(Byte_Zeit, 3) / 10);
    pTextRet^[1] := 48 + (SHR(Byte_Zeit, 3) MOD 10);
    pTextRet^[3] := 48 + (Byte_Zeit AND 2#0000_0111);
END_IF
 
Zuletzt bearbeitet:
Zurück
Oben