Ich lese mit dem PIC18F452 Strings mit der Länge von 40 Character über die serielle Schnittstelle ein und jeweils vier dieser Character (16bit), welche Hex-Werte sind, möchte ich einem binären Wert zuweisen laut einer Codetabelle. In LabVIEW habe ich das Ganze vorher laut der Tabelle unterhalb codiert. Wie kann ich das grundsätzlich machen? Muss ich hier den String in ein Array umwandeln mit 40 Zeichen? Wie kann ich dann jedem Array-Wert einem decodierten Wert zuweisen? Codetabelle: 0000000000, /* 0 */ 0000001111, /* 1 */ 0000110011, /* 2 */ 0000111100, /* 3 */ 0001010101, /* 4 */ 0001011010, /* 5 */ 0001100110, /* 6 */ 0001101001, /* 7 */ 0010010110, /* 8 */ 0010011001, /* 9 */ 0010100101, /* : */ 0010101010, /* A */ 0011000011, /* B */ 0011001100, /* C */ 0011110000, /* D */ 0011111111, /* E */ 1100000011, /* F */ 1100001100, /* G */ 1100110000, /* H */ 1100111111, /* I */ 1101010110, /* J */ 1101011001, /* K */ 1101100101, /* L */ 1101101010, /* M */ 1110010101, /* N*/ 1110011010, /* O */ 1110100110, /* P*/ 1110101001, /* Q */ 1111000000, /* R */ 1111001111, /* S */ 1111110011, /* T */ 1111111100, /* U */
Hans M. schrieb: > Wie kann ich das grundsätzlich machen? In welcher Programmiersprache? C? > Muss ich hier den String in ein > Array umwandeln mit 40 Zeichen? Wie hast du denn den String gespeichert? Der ist ja wahrscheinlich schon in einem Array gespeichert. > Wie kann ich dann jedem Array-Wert einem > decodierten Wert zuweisen? Durch eine Umcodiertabelle. Die hast du ja schon aufgestellt. Jetzt musst du sie nur noch implementieren. 2. Array als Umkodiertabelle aufstellen, mit den jeweiligen Werten füllen, nach dem Empfang der Zeichen mit jedem Zeichen in die Tabelle gehen und den jeweiligen Ersatzwert dafür holen. Anstatt einer Tabelle wäre es vorteilhaft, wenn es einen mathematischen Zusammenhang gäbe. Schau ich mir deine Tabelle an, so gibt es da wohl nichts. Auf der anderen Seite habe ich mir die Werte auch nur ein paar Sekunden angesehen und nicht weiter gesucht, ich kann also einen Zusammenhang schlicht und ergreifend übersehen haben.
Programmiersprache C mit CCS-C Compiler Microchip MPLAB 8.36. Der String sieht folgendermaßen aus. Tippt man in LabVIEW die Nachricht "0123456789" ein, so wird der Hexadezimalstring "0000 000F 0033 003C 0055 005A 0066 0069 0096 0099" an den PIC gesendet. Der mathematische Zusammenhang ist derer, dass dies ein Code ist, welcher zwei Fehler erkennen und einen korrigieren kann, bestehend aus einem 10bit Codewort mit der Hamming-Distanz 4, also jedes Codewort unterscheidet sich vom anderen um 4 Zeichen, daher auch die Fehlererkennung von 2 und -korrektur von 1. Die Tabelle habe ich einfach mit Hilfe von diesem Calculator erzeugt: http://www.ee.unb.ca/cgi-bin/tervo/hamming.pl?X=+Generate+&L=10&D=4&T=0000000000 Da ich mehr als 16 Zeichen benötige und eine Fehlererkennung von 2, habe ich diesen ausgewählt.
Wenn du am PC die eingegebenen Zahlen per Labview in einen fehlerredundanten Code umwandeln lässt, wieso sendest du diese Zahlen dann noch als ASCII? Du könntest diese doch gleich im Binärformat schicken und würdest dann nur noch 2 anstatt 4 Bytes pro Zahl benötigen. Dann kannst du die umgewandelten Zahlen zwar nicht mehr direkt als ASCII mitlesen, aber du gibst ja sowieso nur die ursprüngliche Zahl von Hand ein. Aber das ist natürlich deine Sache, wie du das machen willst. Und zu dem Umwandeln würde ich gar nicht erst warten bis du alle 40 Zeichen empfangen hast und diese dann anfangen umzuwandeln. Es reicht schon wenn du nach 4 empfangenen Zeichen diese sofort umwandelst und dann wieder auf die nächsten vier wartest. Dadurch reicht auch ein 4 Byte Array anstatt ein 40 Byte Array. Denn Speicher ist immer zu wenig da. ;) Ciao, Rainer
Ich sende diese Zeichen als Hex-Zahl, da LabVIEW nur Byte und Word senden kann und da ein Codewort 10bit hat, müsste ich dann im C-Programm, im Decoder, diese gesendeten Bytes wieder auf 10bit umformatieren und das ist programmiertechnisch weit schwieriger, als wenn ich einfach 2Bytes für diese 10bit nehme. Kannst du mir vielleicht den Befehl sagen, wie ich das machen kann oder ein Beispielprogramm geben, wo ich immer diese 4 Byte umwandeln und dann die nächsten 4 Byte betrachten kann?
Hans M. schrieb: > Kannst du mir vielleicht den Befehl sagen, 'den Befehl' gibt es selten. Eines der Hauptdinge in der Programmierung ist es nunmal, mehrere Befehle zu einer Sequenz zusammenzusetzen, die das gewünschte Verhalten zeigt. Und dazu muss man natürlich seinen 'Werkzeugkasten' kennen. Und da scheint es mir bei dir zu hapern. > ein Beispielprogramm geben, wo ich immer diese 4 Byte umwandeln und dann > die nächsten 4 Byte betrachten kann? Wie empfängst du denn jetzt?
> Wie empfängst du denn jetzt?
Beispielsweise so einen String, den mir LabVIEW generiert hat:
0000 000F 0033 003C 0055 005A 0066 0069 0096 0099
jede 4 Byte sind 1 Zeichen, das codiert wurde. z.b. ist hier 0000 0 oder
000F 1.
Dies müsste ich binär umwandeln, damit ich auf Fehler überprüfen kann,
denn ich simuliere in LabVIEW auch Fehler, d.h. ich tausche entweder 1,2
oder 3 Bits aus, um die Funktion des Codes zu zeigen.
Also ich programmiere keine PIC, aber ich kann dir den Ablauf schildern. Diesen musst du dann nur noch in dein C Programm umsetzen. Hier der Pseudocode:
1 | unsigned byte zahl; |
2 | unsigned byte array[4], ergebnis[10]; |
3 | unsigned int zeiger, teiler; |
4 | |
5 | for (int i = 0, i < 10, i++) { |
6 | // 10x 4er Blöcke empfangen
|
7 | |
8 | for (int j = 0, j < 4, j++) { |
9 | // Vier Zeichen empfangen und in Array schreiben
|
10 | while(!zeichen empfangen); |
11 | array[j] = empfangenes zeichen; |
12 | }
|
13 | |
14 | // Hex-Ascii Zahl (4Bytes) in einen einzelnen Int (2Bytes) zurückwandeln
|
15 | zeiger = 0; |
16 | teiler = 4096; |
17 | for (int j = 0, j < 4, j++) { |
18 | zahl = array[j] - 48; |
19 | if (zahl >= 0 && zahl <= 9) |
20 | // Zahl zwischen 0-9
|
21 | zeiger += zahl * teiler; |
22 | else if (zahl >= 17 && zahl <= 22) |
23 | // Zahl zwischen A-F
|
24 | zeiger += (zahl - 7) * teiler; |
25 | else if (zahl >= 49 && zahl <= 54) |
26 | // Zahl zwischen a-f
|
27 | zeiger += (zahl - 39) * teiler; |
28 | else
|
29 | // Fehler da kein HEX-Code Zeichen eingegeben wurde
|
30 | break; |
31 | teiler = teiler / 16; |
32 | }
|
33 | |
34 | // Nun steht in "zeiger" die übertragene codierte Zahl
|
35 | // Diese kannst du nun per Zuordnungstabelle oder direkt mit
|
36 | // dem Hamming Algorithmus wieder zurückwandeln
|
37 | |
38 | ...
|
39 | |
40 | ergebnis[i] = zurückgewandelte Zahl; |
41 | }
|
Ciao, Rainer
Hans M. schrieb: >> Wie empfängst du denn jetzt? > > Beispielsweise so einen String, den mir LabVIEW generiert hat: > 0000 000F 0033 003C 0055 005A 0066 0069 0096 0099 > > jede 4 Byte sind 1 Zeichen, das codiert wurde. z.b. ist hier 0000 0 oder > 000F 1. Nicht beispielsweise! Code muss her! Also nochmal die Frage: Wie empfängst du denn jetzt?
> Also nochmal die Frage: > Wie empfängst du denn jetzt? Was ich empfange, das kommt darauf an, was ich in LabVIEW als zu übertragende Nachricht eintippe, ich habe ganz oben schon eine Codetabelle entworfen, nach derer die String-Nachricht mit den möglichen Zeichen 0 bis 9, : und A bis U codiert wird. Die fehlenden Bits zum Word werden einfach mit Nullen aufgefüllt. Die Nachricht hat halt genau 10 Zeichen, also 10 mal 4 Byte. @ Rainer Danke Reiner, super Hilfe! :] Ich werde das versuchen, mit der Codetabelle zu lösen wie in LabVIEW, denn das ist ja eigentlich kein Hamming-Code, nur ein linearer 10bit Code mit der Hamming-Distanz 4.
Hans M. schrieb: >> Also nochmal die Frage: >> Wie empfängst du denn jetzt? > > Was ich empfange, Noch mal. Ich will nicht wissen, WAS du empfängst sondern WIE! WIE sieht dein jetziger Code aus! Der Empfang eines Bytes ist immer von der verwendeten Hardware abhängig. Ab dort kommt man dann mit Standard-C weiter, aber die unterste Ebene, 1 Byte empfangen, ist von deiner Hardware abhängig. Diesen Code musst du ja schon haben und den würden wir hier gerne sehen. Denn dann brauchen wir nicht raten, sondern können auf dem was du schon hast aufbauen.
Achso verstehe, was du meinst. Ja ich werde jetzt einmal dass vom Rainer einbauen und dann werd ich ihn hochladen.
So ich habe einmal den sozusagen "Grundcode" ist aber momentan noch mehr wie ein Müll, entschuldige mich gleich im Vorhinein dafür, aber ich habe mich halt in dieses Forum gewendet, da ich ziemlich schlecht im Programmieren bin. Hier ist sicher schon einiges falsch, also ab der while(1)-Schleife zumindest einmal.
@Hans M. Was soll eigentlich der ganze Quatsch mit dem Hamming Code? Eine Umcodiertabelle ist vielleicht zum senden gut, aber was machst du wenn du Daten mit Bitfehlern empfängst? Dein Code sieht nicht so aus, als ob du eine Fehlerbehandlung mittels Hamming Code umsetzten kannst. Gruß Marcus
Das stimmt. Hamming Code zu benutzen macht nur Sinn, wenn du beim Empfangen auch den Hamming Code verifizierst und nicht einfach nur eine Codetabelle benutzt. Denn ohne die zusätzlichen Bits beim Empfang zur Verifikation zu benutzen hättest du dir den Hamming Code auch sparen können. ;)
Das ist kein Hamming-Code. Er hat die HAMMING-DISTANZ 4, ABER ER IST KEIN HAMMING-CODE! >Eine Umcodiertabelle ist vielleicht zum senden gut, aber was machst >du wenn du Daten mit Bitfehlern empfängst? Dein Code sieht nicht so >aus, als ob du eine Fehlerbehandlung mittels Hamming Code umsetzten >kannst. Was ich mit Bitfehlern machen, sag ich dir. Nehmen wir einmal an, die ersten 4 Byte meiner Nachricht, die ich empfangen habe, sind 0000 hex, also, wenn man die vorderen 4 Stellen zur Auffüllung zu einem Word (16bit) weglässt, ist das die Nachricht 0000000000bin Kommt jetz aber die Nachricht 0000000001 oder 0000000100, ... an (1 bit verändert sich), dann weiß ich, dass dies immer noch 0000000000 ist und kann dies korrigieren, da meine Codewörter sich immer um 4 Bit änder. Erhalte ich eine Nachricht 0000000011, dann weiß ich, das ein Fehler aufgetreten ist, aber nicht wo, daher kann ich an das LabVIEW-Programm zurücksenden, das es die Nachricht noch einmal senden soll. Ich kann also 1 Fehler korrigieren (Zuordnung zu einem Codewort klar) und 2 erkennen (Zuordnung nicht mehr klar), bei 3 Fehlern ist dann die Zuordnung klarerweise falsch, da dann das Codewort zu einer anderen Nachricht zugeordnet wird, da es nur 1 Unterschied hat zum anderen Codewort. Wie soll ich dann das nun anders lösen?
Hans M. schrieb:
> Wie soll ich dann das nun anders lösen?
Du hast das missverstanden.
Wir glauben dir hier, dass du in der Theorie weißt, wie man das macht.
Alleine glaubt hier keiner daran, dass du in der Lage bist, das auch so
umzusetzen :-) Nicht nach der Performance, die du so an den Tag legst
> Du hast das missverstanden. > Wir glauben dir hier, dass du in der Theorie weißt, wie man das macht. > Alleine glaubt hier keiner daran, dass du in der Lage bist, das auch so > umzusetzen :-) Nicht nach der Performance, die du so an den Tag legst Haha, ja OK, ihr habt ja e Recht, aber was soll ich machen, in der Schule sind wir mit Programmieren nicht viel weiter gekommen, als eine Temperaturmessung über I2C oder mit Hilfe eines Potis ADC-Werte messen, deswegen wundert euch nicht über meine Kenntnisse. Das ist jetzt mein wirklich letzter C-Code, den brauch ich für eine Abschlussarbeit und ohne den bin ich im A****. Bitte helft mir, dann nerv ich Mikrocontroller mit C-Programmierung nie mehr. Ich bin ja sonst nicht so ein Vollidiot, aber was das Programmieren angeht, ihr seht es ja e.
Hans M. schrieb: > Temperaturmessung über I2C oder mit Hilfe eines Potis ADC-Werte messen, > deswegen wundert euch nicht über meine Kenntnisse. Doch, das wundert mich jetzt eigentlich schon. Denn im Vergleich zu den angeführten Projekten, ist das bischen Byteschubserei, dass du bei dieser Code-Umsetzerei brauchst, Kinderkram. Übrigens: Ich würde die Zusammenfassung von jeweils 4 Bytes gleich in der Empfangsroutine machen, dort dann auch die Code-Umsetzung und Abspeicherung als Klartext im String. Da hab ich aber auch gleich noch eine Frage: wie synchronisierst du eigentlich Sender und Empfänger? Der Empfänger sollte doch eigentlich auch zuverlässig feststellen können, wann im Datenstrom die nächste 4-er Sequenz beginnt. > Das ist jetzt mein wirklich letzter C-Code, den brauch ich für > eine Abschlussarbeit und ohne den bin ich im A****. Das Problem bei deinem Code ist: Das Bischen, das du selbst geschrieben hast, steckt so voller Grundlagenfehler, dass einem Angst und Bang wird. Und der Teil, den du dazukopiert hast, passt nicht wirklich dazu. Das Alles mit dem Hintergrund, dass es sich eigentlich um eine eher triviale bis leichte Aufgabe handelt, lässt mich darüber nachdenken, ob ich wirklich will, dass dir hier deine Abschlussarbeit auf dem Silbertablett präsentiert werden soll (denn anders wird es nicht gehen) und du einen Abschluss dafür kriegst, dass andere deine Arbeit machen.
Karl heinz Buchegger schrieb: > Hans M. schrieb: > >> Temperaturmessung über I2C oder mit Hilfe eines Potis ADC-Werte messen, >> deswegen wundert euch nicht über meine Kenntnisse. Super, I2C, SPI, ADC, CCP-Register und das ganze Zeug habe sicher 100 mal schon gemacht, das ist für mich überhaupt kein Problem mehr, aber nun habe ich halt für die Abschlussarbeit etwas anderes einmal bekommen, da habe ich einfach kein Wissen, weil in den ersten Schuljahren, wo wir so etwas machen sollten, hatten wir einen alten, dicken und faulen Lehrer, dem unsere Ausbildung eigentlich ziemlich ihr wisst schon wo vorbei gegangen ist und daher ist mein Programmierwissen mehr als nur beschränkt. > Doch, das wundert mich jetzt eigentlich schon. > Denn im Vergleich zu den angeführten Projekten, ist das bischen > Byteschubserei, dass du bei dieser Code-Umsetzerei brauchst, Kinderkram. Sorry, ich bin einfach unfähig, ich kann das nicht anderes ausdrücken und nach der Schule werde ich im Falle eines Studiums komplett von der Programmierung weggehen, nur dieses eine letzte Mal muss ich noch so etwas programmieren. > Übrigens: Ich würde die Zusammenfassung von jeweils 4 Bytes gleich in > der Empfangsroutine machen, dort dann auch die Code-Umsetzung und > Abspeicherung als Klartext im String. > Da hab ich aber auch gleich noch eine Frage: wie synchronisierst du > eigentlich Sender und Empfänger? Der Empfänger sollte doch eigentlich > auch zuverlässig feststellen können, wann im Datenstrom die nächste 4-er > Sequenz beginnt. Ich verwende ja den RS485-Bus (mit MAX485) auf dem PIC-Board und bei LabVIEW VISA Write und für die Verwendung auf einem Laptop habe ich einen USB/RS485-Konverter. Meine Projektarbeit ist ja nur noch eine vertiefende Arbeit zum Gesamtprojekt und im Gesamtprojekt macht mein Projektpartner die Kommunikation mit dem PIC-Board, ich habe sonst nur das LabVIEW Programm und die Hardware zu erstellen. Jedenfalls, was ich sagen, im Gesamtprojekt funktioniert diese Kommunikation ohne Probleme, der PIC wartet einfach und empfängt Daten, sobald in LabVIEW so ein String weggesendet wurde. Im Gegenzug wartet auch LabVIEW ab, bis wieder ein Signal vom PIC zurückkommt und wertet dieses aus.
Hans M. schrieb: > Ich verwende ja den RS485-Bus (mit MAX485) auf dem PIC-Board und bei > LabVIEW VISA Write und für die Verwendung auf einem Laptop habe ich > einen USB/RS485-Konverter. Das hat nichts damit zu tun. Angenommen du empfängst diese Byte-Sequenz (*) 0F 00 33 00 00 00 00 55 00 Woher weißt du, wie diese Bytes zusammengehören? ist das jetzt 0F00 3300 0000 0055 00 mit einem Übertragungsfehler in den ersten beiden Bytes oder ist das 0F 0033 0000 0000 5500 mit einem Übertragungsfehler im ersten und letzten Datenwort? (*) stelle dir einfach folgendes Szenario vor: Die Verbindung steht und läuft. Jetzt kommt die Putzfrau und wischt auf. Wie es der Teufel so haben will, zieht sie dabei den Stecker om PIC-Bord ab. Sie bemerkt ihren Fehler und steckt den Stecker einfach wieder rein. Dein PIC weiß nicht wieviele Bytes er in der Zwischenzeit verpasst hat. Er muss sich wieder mit dem Sender synchronisieren um zu wissen, wie 2 hintereinander empfangene Bytes wieder zusammengehören. Genau das ist nämlich eines der Probleme bei einer Übertragung, bei der immer mehrere Bytes gemeinsam einen Datensatz bilden. Sicherzustellen, dass Empfänger und Sender synchron laufen. Und solange du das nicht lösen kannst, hat es auch keinen Sinn, sich über Hamming-Distanzen oder dergleichen zu unterhalten. Das ist so, wie wenn wir uns darüber unterhalten, wie wir ein Atomkraftwerk ausfallsicher machen und dabei komplett übersehen, dass Klingeldraht als Überlandleitung einfach nicht taugt.
Ja das mit dem Synchronisieren ist wieder so die Sache. In 99,9 Prozent der Fälle wird es bei meiner überhaupt keine Fehler geben, ich simuliere sie nur mit LabVIEW, indem ich einfach je nach eingestellter Fehleranzahl Bits invertiere. Das mit Synchronisieren, ist das überhaupt mit einer Codetabelle möglich?
Hans M. schrieb: > Das mit Synchronisieren, ist das überhaupt mit einer Codetabelle > möglich? Synchronisieren der Übertragung hat nichts mit einer Codetabelle zu tun. Ein einfaches Beispiel für eine Synchronisierung wäre, wenn du z.b. bei dem ersten Byte eines Viererblocks immer das MSB Bit setzen würdest, welches du sowieso nicht für die eigentlchen Daten verwendest. Dann beim Empfänger eine neue Vierersequenz erst startest sobald im empfangenen Byte das MSB gesetzt ist und dieses Bit bei der Rückwandlung dann natürlich ignorierst. So könntest du auf einfache Weise feststellen, ab welchem Byte eine neue Sequenz beginnt. Du könntest aber auch einfach ein Byte vor jedem Block vornedranstellen (insgesamt dann 5 Bytes) welches sich von allen möglichen Datenbytes unterscheidet und auf dieses den Start triggern. Ciao, Rainer
Achso, verstehe, wie du das meinst, das wäre eigentlich überhaupt kein Problem, wenn ich das realisieren würde. Ich würde einfach in LabVIEW ein Zeichen zu dem String hinzufügen, was sich von den anderen unterscheidet und auf welches das C-Programm reagiert.
Karl heinz Buchegger schrieb: > Das ist so, wie wenn wir uns darüber > unterhalten, wie wir ein Atomkraftwerk ausfallsicher machen und dabei > komplett übersehen, dass Klingeldraht als Überlandleitung einfach nicht > taugt. YMMD! :D
Kann oder besser gesagt will mir hier überhaupt jemand helfen oder könnt ihr nur blöd herumMAULEN? Ich glaub, ich suche mir lieber ein anderes Forum, hier gibt es wieder einmal nur blödes Herumgerede, wenn einer nicht den Wissensstand der Moderatoren etc hat.
Hans M. schrieb: > Kann oder besser gesagt will mir hier überhaupt jemand helfen oder könnt > ihr nur blöd herumMAULEN? > Ich glaub, ich suche mir lieber ein anderes Forum, hier gibt es wieder > einmal nur blödes Herumgerede, wenn einer nicht den Wissensstand der > Moderatoren etc hat. Was du als 'Wissenstand der Moderatoren' bezeichnest, bezeichnet die Mehrheit hier als 'Basiswissen der C-Programmierung'. Arbeiten mit Arrays ist in einem 20-teiligen C-Kurs irgendwo im Teil 4 oder 5 drann. Das Einzige was ich dir zugestehe nicht zu wissen, ist wie man aus 4 einzelnen Bytes einen long zusammensetzt und dafür hast du ja bereits einen Vorschlag erhalten (den ich zwar nicht für besonders gut halte, aber darauf kommts jetzt nicht an, zum jetzigen Zeitpunkt ist nur wichtig, dass er funktionieren wird). Wo liegt also das Problem? Hast du schon ausprobiert, ob du die richtigen Zahlen bekommst? Wahrscheinlich nicht. Denn dann hättest du schon bemerkt, dass dein empfangendes Array viel zu klein dimensioniert ist. Heck. du solltest vielleicht erst mal ausprobieren, ob du überhaupt die 40 Zeichen korrekt empfangen kannst. Auch das hast du noch nicht ausprobiert. Und da sind wir noch gar nicht beim eigentlichen Problem: Wie kann ich die Codierung wieder rückgängig machen bzw. auflösen. Kümmere dich zuerst darum, dass du die 40 Codes korrekt empfangen kannst! (Und ich rede jetzt nicht vom Synchronisierproblem. Nur damit das klar ist) Du verlässt diich darauf, dass dir hier alles vorgekaut wird. Und dafür gibt es zumindest in diesem Forum kein Verständnis. Vor allen Dingen dann nicht, wenn es sich um eine Abschlussarbeit handelt, mit der du eigentlich dokumentieren sollst, dass du von deinem Fach etwas verstehst.
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.