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
unsignedbytezahl;
2
unsignedbytearray[4],ergebnis[10];
3
unsignedintzeiger,teiler;
4
5
for(inti=0,i<10,i++){
6
// 10x 4er Blöcke empfangen
7
8
for(intj=0,j<4,j++){
9
// Vier Zeichen empfangen und in Array schreiben
10
while(!zeichenempfangen);
11
array[j]=empfangeneszeichen;
12
}
13
14
// Hex-Ascii Zahl (4Bytes) in einen einzelnen Int (2Bytes) zurückwandeln
15
zeiger=0;
16
teiler=4096;
17
for(intj=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
elseif(zahl>=17&&zahl<=22)
23
// Zahl zwischen A-F
24
zeiger+=(zahl-7)*teiler;
25
elseif(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
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.
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.