Forum: Mikrocontroller und Digitale Elektronik schnelle und sichere Übertragung von Xmega an PC


von Hansi (Gast)


Lesenswert?

1
int wert1, wert2;
2
int buffer[];
3
sprintf(buffer,"%d %d ",wert1,wert2);       
4
serial_puts(buffer, C1);



Hallo an alle ,

ich möchte eine sichere und schnelle Datenübertragung zum PC 
realisieren. Als Übersetzer auf USB dient ein CP2102. Es soll eine große 
Anzahl an Werten. Immer 2 (wert1/2)
möglichst schnell und sicher zum PC übertragen werden. Wie realisiert 
man soetwas, wenn der oben genannte code einfach zu langsam ist? Bei den 
Werten handelt es sich um 12Bit Integer.

Danke und ein schönes WE vorab!

von Werner (Gast)


Lesenswert?

Hansi schrieb:
> Wie realisiert man soetwas, wenn der oben genannte code einfach zu
> langsam ist?

Wenn du deine Daten erstmal in langatmigen Text umwandelst, nutzt du nur 
einen kleinen Teil deines Zeichenvorrates und darfst dich nicht wundern, 
dass das auf die Geschwindigkeit schlägt.
Du verwendest grob nur etwa 1/20 deiner Datenrate zur 
Informationsübertragung. Warum machst du keine Binärübertragung mit 
Blocksicherung. Wie hoch ist die Fehlerrate auf deinem 
Übertragungskanal?
Die Geschwindigkeit hängt übrigens auch von der verwendeten Baudrate ab.

von Oliver (Gast)


Lesenswert?

Definiere langsam, und definiere schnell.

Oliver

von Hansi (Gast)


Lesenswert?

Hi und danke für deine Antwort,

ich bin der ezit schon mit 921,6 k unterwegs. Sollte auch reichen.
1
Du verwendest grob nur etwa 1/20 deiner Datenrate zur
2
Informationsübertragung. Warum machst du keine Binärübertragung mit
3
Blocksicherung. Wie hoch ist die Fehlerrate auf deinem
4
Übertragungskanal?

So schauts aus. Habe allerdings Probleme bei der Realisierung bzw weiß 
nicht wie ich es anstelle. Was meinst du mit Fehlerrate. Im Moment habe 
ich via Software einen handshake realisiert. Dieser frisst ebenfalls 
etwas Zeit aber alle Werte kommen richtig an. Momentan brauche ich für 
100000 Sendungen von oben genannter Datenmenge ca 3 Minuten. Ohne 
handshake ca 15 Sekunden.

von 123 (Gast)


Lesenswert?

lass mich mal kurz überschlagen.

2 hoch 12 sind irgendwas mit 8096

das dann 2 mal + 2 space macht dann 10 Zeichen für 24 bit.

so jedes zeichen bracht auf der Schnittstelle ca 11 bit macht dann ca 
110 bit für 24 bit nutzdaten.

so bei 115200 baud macht das dan ca 1000 wertepare je sekunde.

vorausgesetzt, du würdest dauernd werte senden.


1. Was soll schnell heissen?
 reichen dir ggf 100 messwerte je Sekunde oder müssen es mehr sein?

2. was soll sicher heissen?
Sicher gegen manipulationsversuche
Sicher gegen 1 bit fehler
Sicher gegen 2 bit fehler
Sollen bit fehler erkannt werden, wie viele müssen erkannt werden?
Sollen bit fehler ggf korrigiert werden? wenn ja wieviele davon?

grundlagen der Kodiertechnick.

von 123 (Gast)


Lesenswert?

so 921600 / 11 bit je zeichen macht somit 83781 zeichen je sekunde

10 zeichen je übertragung 8378 übertragungen / Werte
a 15 s sind dann 125670 übertragungen. die in 15s möglich währen.

für 100.000 somit ganz gut gegen über dem was möglich währe.

bei 180s ist dann dan faktor 12 Langsamer. ist die frage was du machst.
Handschake heist auch laufzeit. warten auf antworten, ... macht das 
ganze natürlich auch langsam.


So was willst du eigentlich erreichen? wieveile messwerte sind zu 
übertragen je s.
Welche anforderungen an sicherheit stellt du?
dürfen messwerte verloren gehen? ( sind alle messwerte wichtig? oder wie 
bei audio ein fehlendes sample ist egal. solange der stream nicht auser 
trit kommt)
Kommen die Messwerte on the fly oder liegen sie irgendwo im speicher und 
müssen nur irgend wann in kurzer zeit übertragen werden? (kompremieren, 
... )

Müssen umbedingt die 24 bit übertragen werden. oder ist der wertebereich 
einzugrenzen.

von Frank K. (fchk)


Lesenswert?

Hansi schrieb:
>
1
> int wert1, wert2;
2
> int buffer[];
3
> sprintf(buffer,"%d %d ",wert1,wert2);
4
> serial_puts(buffer, C1);
5
>
1
int wert1,wert2;
2
3
serial_putc((wert1&0x3f)|0x80);
4
serial_putc((wert1>>6)&0x3f);
5
serial_putc(wert2&0x3f);
6
serial_putc((wert2>>6)&0x3f);

Damit sendest Du ein 4 Byte Telegramm. Das erste Byte eines Telegramms 
ist durch ein gesetztes Bit 7 gekennzeichnet, alle folgenden Bytes haben 
Bit 7 gelöscht. So kannst Du auf den Beginn eines Telegramms 
synchronisieren. In jedem Schritt werden 6 Bit übertragen, die Du auf 
dem PC wieder zusammenfriemeln musst.

Wenn es dann noch zu langsam ist, versuche es mal mit gescheitem 
Systemdesign. Heißt also: keinen seriell-USB Wandler verwenden, das ist 
fast immer eine Bremse. Es gibt die XMegas mit AU-Suffix mit USB Device 
direkt eingebaut. Oder falls Dir das zu kompliziert ist, nimm einen 
FT245 (USB Full Speed) oder einen FT2232H (USB High Speed) und übertrage 
die Daten parallel.

fchk

von Roland H. (batchman)


Lesenswert?

Hansi schrieb:
> ich bin der ezit schon mit 921,6 k unterwegs. Sollte auch reichen.

Welcher atxmega ist das, und mit welchem Takt läuft der UART ?

von Hansi (Gast)


Lesenswert?

[codeSo was willst du eigentlich erreichen? wieveile messwerte sind zu
übertragen je s.
Welche anforderungen an sicherheit stellt du?
dürfen messwerte verloren gehen? ( sind alle messwerte wichtig? oder wie
bei audio ein fehlendes sample ist egal. solange der stream nicht auser
trit kommt)
Kommen die Messwerte on the fly oder liegen sie irgendwo im speicher und
müssen nur irgend wann in kurzer zeit übertragen werden? 
(kompremieren,[/code]

Erstmal danke für die großße Beteiligung. Es sollen alle Messwerte 
übertragen werden. Dabei handelt es sich um Signale aus einem 
magnetischen Sensor, welcher zur Wegmessung eingesetzt wird. Die Werte 
werden aus einem RAM gelesen.(da kommen die 100000 Messwerte her) Können 
aber auch direkt on the fly durchgereicht werden. Jeweils mit 100kHz. Es 
wird jedoch jeweils nur 100ms pro Sekunde gemessen. Die restliche zeit 
also 0,9 Sekunden stehen bis zur nächsten messung zur Übertragung 
bereit. Die hardware würde ich erstmal probieren beizubehalten.

@Frank K; Danke!
@Roland; ist ein 128A1

von 123 (Gast)


Lesenswert?

lass mich mal grübeln was ich mit den infos anfangen kann.

100.000 Messungen je s
24bit je Messung
macht dann 2.4 mBit je s an reinen Nutzdaten.

100ms wird gemessen 900ms wird nichts getan. noch ne info.
als nur 10% der möglichen messungen wird verwendet? egal.

dadurch verringert sich die reine nutdatenlast entsprechend auf ein 
zentel.

macht damit 240.000 bit je s.

wenn wir jetzt die bits wie oben beschrieben codieren machen wir aus den 
24 bit 32. oder 4 byte. ein byte auf der uart braucht 11 bit (8 Daten 1 
start 1 stop und 1 parity) sind damit 44 bit.
bei den 10.000 messungen (10% der 100.000) sind dass dann 440.000 bit je 
s bzw baud.

deine baudrate muss somit über den 440.000 baud liegen. die nur für die 
übertragung ohne unterbrechung für ggf andere aktivitäten wie z.B. 
Messung durchführen, ... benötigt werden.

und ab jetzt wirds vermutlich etwas kompliziert.

da du vermutlich werder fifos, dma noch irgend eine art von 
paralellisierung (irq, tasks, threads, queues, ... ) verwendest und 
alles sequenziall abarbeitest

Messen
Aufbereiten
übertragen

da du im sequenziellen betrieb nicht nur übertragen willst, musst du dir 
noch zeit zum messen und aufbereiten der daten verschaffen. die nur duch 
erhöhen der datenrate zu schaffen ist. Gehst du auf 880.000 baud, geht 
die hälfte der zeit für die übertragung drauf, den rest hast du dann für 
die messung und aufbereitung zur verfügung.

oder dir irgend eine art von paralellisierung überlegen in der du 
Messung, datenaufbereitung von der übertragung entkoppelst.

z.B. ein Timer IRQ führt die Messung durch. bereitet die messdaten auf 
und schiebt sie in einen ringpuffer. die main loop, die nur läuft, wenn 
gerade keine messung läuft, kümmert sich darum, die messdaten über den 
uart wieder loszuwerden. und synchronisieren muss man an ringpuffer 
nichts. da der IRQ nur am anfang reinschreibt, und die main am ende 
ausliest. da die main nur dann läuft wenn der IRQ nicht läuft, kommen 
die sich auch nicht in die quere, solang man mit einem read und einem 
write pointer arbeitet. und wenn read == write pointer dann buffer full 
oder empty.

oder FIFO / DMA (die HW die versendearbeit machen lassen )
oder ...

von Hansi (Gast)


Lesenswert?

serial_putc(wert2&0x3f);


Wie kommt man auf die 0x3f?

von Karl H. (kbuchegg)


Lesenswert?

Hansi schrieb:
> serial_putc(wert2&0x3f);
>
>
> Wie kommt man auf die 0x3f?

Weil Frank deine 24 Bit auf 4 Byte aufgeteilt hat.
Er hat das so gemacht, dass er sie regelmässig aufgeteilt hat. Also 
werden pro Byte 6 Bit Nutzdaten übertragen.
Er braucht aber auch eine Maske, mit der er sich die 6 Bit 
rausschneidet. Und ein Maskenbyte mit 6 (den untersten 6) Bit, sieht wie 
aus?

  0b00111111

oder in Hex eben 0x3F

von Werner (Gast)


Lesenswert?

Hansi schrieb:
> Es sollen alle Messwerte
> übertragen werden. Dabei handelt es sich um Signale aus einem
> magnetischen Sensor, welcher zur Wegmessung eingesetzt wird.

Und hast du schon mal über dein Systemkonzept nachgedacht. Wenn du nur 
den Weg messen willst, laß das doch den µC erledigen und liefere dann 
das Ergebnis beim PC ab. Der PC kann die Datenrate mit der Zeitauflösung 
sowieso nicht in Echtzeit verarbeiten, sofern du nicht ein dafür 
optimiertes Betriebssystem/Kerneltreiber verwendest. Oder geht es "nur" 
darum, die Daten irgendwie aufzuzeichnen und dabei nichts zu verpassen?

von Hansi (Gast)


Lesenswert?

@KGB Danke, Maske war das Stichwort. Gut erklärt.

@Werner, es wird einfach eine Lösung gesucht. Ja es wird auch der Ansatz 
verfolgt den du geschildert hast. Die dabei zu übertragende Datenmenge 
ließe sich drastisch reduzieren. Ich halte euch auf dem laufenden. Das 
Optimum wäre halt eine Onlinedarstellung am PC. Werde nächste Woche 
berichten obs geklappt hat. Wenn ich meine Informationsmenge auf 8 Bit 
(@100khz) beschrenke sollte ich diese im Idealfall permanent mit 921kbps 
übertragen können. Die Rechnung von oben mit den 0,1/0,9s würde dann 
entfallen.

von Werner (Gast)


Lesenswert?

Hansi schrieb:
> @Werner, es wird einfach eine Lösung gesucht. ... Das
> Optimum wäre halt eine Onlinedarstellung am PC.

Lösung wofür genau?
Für eine Onlinedarstellung auf dem PC, selbst wenn es technisch läuft, 
muß erst noch der Betrachter erfunden werden, der diese Datenrate 
visuell aufnehmen und bewerten kann. Da würde sicher auch eine erheblich 
reduzierte Update-Rate für die übertragene Position ausreichen. Wie 
schnell ändern sich denn die Meßwerte überhaupt?

von Oliver (Gast)


Lesenswert?

Hansi schrieb:
> Das
> Optimum wäre halt eine Onlinedarstellung am PC.

Na ja, für das menschliche Auge ist alles jenseits von 15 Werten/Sekunde 
Film ;)

Und für eine "Online"-Darstellung von Zahlenwerten reichen 10 
Werte/Sekunde mehr als aus.

Oliver

von Dennis P. (dennisp)


Lesenswert?

Ich habe vom Xmega schon die vollen 2MSample des ADC (8bit) zum PC 
übertragen. Per DMA und einem UM232H (im Bitbang Modus). Und die CPU war 
mit 0% ausgelastet.

von Olle Kammelle (Gast)


Lesenswert?

Dennis P. schrieb:
> Ich habe vom Xmega schon die vollen 2MSample des ADC (8bit) zum PC
> übertragen. Per DMA und einem UM232H (im Bitbang Modus). Und die CPU war
> mit 0% ausgelastet.

Mit einem TMS320F2802x übertrage ich auch mit 2MBaud Daten über einen 
FT232 an den PC. Und das ohne DMA!
Nebenher führt er noch ein paar Berechnungen durch und ließt 8 
Analogwerte ein.

Sollte also mit einem ATXmega mit DMA kein Problem sein.

Grüße

von Dennis P. (dennisp)


Lesenswert?

Nicht MBaud sondern Mbyte...

von Olle Kammelle (Gast)


Lesenswert?

Dennis P. schrieb:
> Nicht MBaud sondern Mbyte...

Noch einfacher...ein Zeichen besteht in meinem Fall aus 12 Bit!

von Hansi (Gast)


Lesenswert?

Moin Moin,

habe nun eine akzeptable Übertragung geschaffen. Dazu habe ich die zu 
übertragende Datenmenge etwas herabsetzten können (7Bit). Das ganze 
läuft nun bei ca 430kbps. 100000 ca 2,5 Sekunden.


Neues problem ist der Interruppt, der das Senden veranlasst. Die Werte 
werden permanent über die serielle Schnittstelle ausgegeben. Zufvor habe 
ich den Xmega über eine selbstgebaute Windowsoberfläche gesteuert und 
Anweisungen über die Schnittstelle übertragen. Da der X mega mir nun 
permanent werte über die Schnittstelle entgegen wirft, habe ich Problem 
ihm beizubringen, dass er aufhören soll. Komme ich da um Multithreading 
drum herum? Konstruktive Vorschläge um eine Abbruchkriterium zu 
realsisieren sind erwünscht. Das Abbruchkriterium soll jedoch erst auf 
Knopfdruck erfolgen.

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
Noch kein Account? Hier anmelden.