Hallo Leute,
Logge bei einer Kleinsteuerung auf eine MicroSD Karte.
Leider ist bei dieser Chinesensteuerung kein vernünftiger Support
gegeben.
Darum muss ich mir selbst ein Programm zum einlesen und konvertiren in
CSV schreiben. Wie kann ich aber folgende Wertetabelle vernünftig
konvertiren ???
6 = 0.6
5 = 0.5
4 = 0.4
3 = 0.3
2 = 0.2
1 = 0.1
0 = 0.0
65535 =-0.1
65534 =-0.2
65533 =-0.3
65532 =-0.4
65531 =-0.5
Habe es wie folgt probiert, aber leider rundet mir VB was weg.
Function CorrectNumber(ByRef Analogflag As String) As String
Dim Zahl As Double
Zahl = Val(Analogflag)
If Zahl >= 32767 Then
CorrectNumber = ((65535 - Zahl) * -1) / 10
Else
CorrectNumber = Analogflag / 10
End If
End Function
Weis jemand Rat?
ist doch ein ganz normales Zweierkomplement
http://de.wikipedia.org/wiki/Zweierkomplement
warum willst du es überhaupt als Double verwenden? Lass doch das /10 weg
und rechne mit int. Dann gibt es auch kein Roundungsproblem. Für die
Anzeige rechtest du dann durch 10 und rundest auf 1 stelle nach dem
Komma.
Hallo,
also im vorgenannten Text muß Zahl natürlich als Long definiert werden,
sonst läuft der Wert bereits bei der VAL-Funktion über.
Integer ist niemals größer als 32767 !
Übrigens ist die Darstellung des Dezimalkommans als "." oder "," hier
abhängig von den Einstellungen der Locales des Users, sollte man so
nicht formulieren.
Gruß,
Michael
Katastrophe schrieb:> Aber wie in VB ordentlich lösen?>> Zahl -> Binär -> Alle 0 und 1 invertieren -> wieder nach Zahl -> Zahl /> 10
wozu binär, du hast doch schon den int wert?
Was kommt bei mir genau rein? eien CSV mit Text oder binary daten?
Habe gerade folgende probiert:
Zahl -> Binär -> Alle 0 und 1 invertieren -> wieder nach Zahl ->
Zahl = Zahl * -1 -> Zahl / 10
Das funktioniert.
Müsste doch irgendwie ohne Umweg zu binär gehen, oder?
Katastrophe schrieb:> Von der SD Karte lese ich Integer Werte in einer TXT Datei.
wie genau liest du ein.
Wenn du in eine 16 Bit vorzeichenbehaftete Integer Variable (wie auch
immer dieser Datentyp im VB heißt) die beiden Bytes direkt einliest,
brauchst du normalerweise überhaupt nichts tun.
Denn die Bytes (jetzt mal abgesehen von der Bytereihenfolge) sind schon
im 2-er Komplement, welches auch dein 16-Bit Integer mit Vorzeichen
benutzt.
Du machst dir da zu viel Arbeit und verkomplizierst die Dinge unnötig.
Lese mit System.IO.File.ReadAllLines ein.
Diese werden in eine Listbox kopiert, weil die einzelnen Zeilen noch "0"
und "1" für Relais und andere Zustände der Kleinsteuerung enthalten.
Darum kann ich es nicht besser einlesen.
Katastrophe schrieb:> Diese werden in eine Listbox kopiert, weil die einzelnen Zeilen noch "0"> und "1" für Relais und andere Zustände der Kleinsteuerung enthalten.> Darum kann ich es nicht besser einlesen.
was soll denn das für ein Grund sein. eine Listbox ist ein GUI element
das nimmt man nicht für eine Datenverarbeitung. Was ist wenn dein
Programm kein Gui hat?
Kannst du mal so eine Textdatei hochladen?
Habe mal die Dateien angehangen.
Din Binflags hat binäre Zustände der Steuerung.
Die Dezflags hat die analogen Zustände der Steuerung.
Beide müssen kombiniert werden, und über einen Filter ausgewertet
werden.
> Habe mal die Dateien angehangen.> Din Binflags hat binäre Zustände der Steuerung.> Die Dezflags hat die analogen Zustände der Steuerung.
kannst du noch dazu sagen um welchs Feld es geht?
Katastrophe schrieb:> Habe mal die Dateien angehangen.
Noch größere hast du nicht gefunden?
Mann, mann, mann.
Bissi mitdenken! Keiner hier wusste, dass deine Dateien so groß sind. In
diesem Fall hätte es ein Auszug aus dem Dateianfang auch getan. Wir
wollen doch nur sehen, wie die prinzpiell aussehn, mehr nicht.
Und dafür lad ich mir sicher nicht 25MB runter.
Ganz davon abgesehen, dass eine 'kleine Version' der Daten auch während
der Programmentwicklung nützlich ist. Oder willst du während der
Entwicklung laufend riesige Files wieder und immer wieder einlesen?
axelr schrieb:> 65534 -> StrToInt -> / 10
Würde dann aber 6553.4 ergeben :-(
Sorry wegen der Grösse.
Habe ich bei VDSL übersehen ;-)
Die Felder mit den >65000 sind gefragt. Codierung wie schon oben
beschrieben:
Zahl -> Binär -> Alle 0 und 1 invertieren -> wieder nach Zahl ->
Zahl = Zahl * -1 -> Zahl / 10
Kriegst Du die Textdatei in genau der Form oder hast Du die schon
bearbeitet?
Denn da steht ja gar nicht 65535 drin, sondern schon 6553.5. Ist das
Komma original?
Das dämlichste, was den Daten auf dem Weg in diese Darstellung passiert
ist, ist ja, dass ein 16 signed int (der * .1 skaliert zu interpretieren
ist) als 16-bit unsigned int (und dann evtl. schon * .1 skaliert ist)
ausgegeben wird.
So oder so:
1. Komma entfernen, falls es nicht erst durch Dich da rein gekommen ist
2. Textdarstellung in 16-bit unsigned int umwandeln
3. Ergebnis von #2 brutal nach 16-bit signed int casten
4. Ergebnis von #3 unter Umwandlung in Fest- oder Fließkomma durch 10
teilen
Schritte #2-#4 in C:
(int16_t)strtoul(string_value_without_decimal_point, NULL, 10) / 10.0
Schritt #3 ist der alles entscheidende. Ob VB zu dieser Verrenkung in
der Lage ist, ohne eben über die Binärdarstellung zu gehen, weiß ich
nicht. Aber vielleicht findest Du ja dazu was. Uminterpretation unsigned
=> signed.
Rudi schrieb:> Würde trotzdem einen kürzeren Code als angenehm entfinden :-D
Zwar C#
double d = Convert.ToInt16("1111111111111110", 2) / 10.0;
bzw.
double d = (Int16)Convert.ToUInt16(65535) / 10.0;
korrekt ist.
Warum ihr da unbedingt über binär gehen müsst erschliesst sich mir
überhaupt nicht.
Selbst wenn ein int in VB mitlerweile 32 Bit groß ist, wo genau liegt
jetzt das Problem in
1
Zahl = int( string )
2
3
if( Zahl > 32767 )
4
Zahl = Zahl - 65536
5
6
Ergebnis = Zahl / 10
Das die Gleitkommadarstellung der Zehntel nicht immer 100% exakt ist,
liegt an der Gleitkommadarstellung an sich und muss in den weiteren
Berechnungen berücksichtigt werden.
Arc Net schrieb:> Zwar C#> double d = Convert.ToInt16("1111111111111110", 2) / 10.0;> bzw.> double d = (Int16)Convert.ToUInt16(65535) / 10.0;
Das geht unter VB schief !!!
Kurt schrieb:> Arc Net schrieb:>> Zwar C#>> double d = Convert.ToInt16("1111111111111110", 2) / 10.0;>> bzw.>> double d = (Int16)Convert.ToUInt16(65535) / 10.0;>> Das geht unter VB schief !!!
Ja, hatte tatsächlich vergessen, dass so was in VB einen Overflow
ergibt...
Dann die Holzhammermethode...
Arc Net schrieb:> Dann die> Holzhammermethode...BitConverter.ToInt16(BitConverter.GetBytes(Convert.T
oUInt16(65535)),
> 0) / 10.0
Wahnsinn. Das funktioniert wirklich super !!!!
Dankeschön!!!