- 3D-Druck Einstieg und Tipps         
Ergebnis 1 bis 9 von 9

Thema: 16bit int über UART versenden

  1. #1
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    15.08.2006
    Ort
    Budapest
    Alter
    37
    Beiträge
    563

    16bit int über UART versenden

    Anzeige

    Praxistest und DIY Projekte
    Hallo!

    Ich möchte folgendes realisieren, bin mir aber nichts sicher, dass das so richtig ist. Bei einer AD-Wandlung im Atmega8 hab ich ein 10bit Ergebnis, den ich per UART versenden möchte.
    Die Funktion der AD-Wandlung sieht so aus:

    Code:
    uint16_t ReadChannel(uint8_t mux){
    	ADMUX=mux;
    	ADMUX|=(1<<REFS1) | (1<<REFS0);
    	ADCSRA |= (1<<ADSC);  
    	while ( ADCSRA & (1<<ADSC) ) {}
    	//uart_putc(ADCL);
    	//uart_putc(ADCH);
    	return ADCW;
    
    }
    Das Ergebnis liegt also in der Variable result, die als 16bit int deklariert wird.
    Versenden möchte ich das aus dem Hauptprogramm folgendermassen:

    Code:
    uint16_t result;
    result=ReadChannel(3);
    uart_putc((uint8_t)(result));
    uart_putc((uint8_t)(result >> 8));
    Ist das so richtig? Also wird hiermit zuerst das Low-Byte, dann das High-Byte versendet, oder ist das schwachsinn? Wie würdet ihr das lösen?

    Danke für die Hilfe, mfg

    pongi

  2. #2
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    02.11.2005
    Alter
    49
    Beiträge
    1.146
    Sieht doch gut aus!
    Ich würd's auch nicht anders machen.

    Gruß,
    askazo

  3. #3
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    06.02.2005
    Ort
    Hamburg
    Alter
    38
    Beiträge
    4.255
    Es könnte nur Probleme geben, wenn Sender und Empfänger nicht genau gleichzeitig eingeschaltet werden. Dann könnte es vorkommen, dass der Empfänger als erstes ein high-byte empfängt, es aber als low-byte ansieht, weil das ja immer zuerst kommen sollte. Daher müsste man ein Protokoll einführen oder die Daten vom Empfänger über den Rückkanal anfordern lassen. Würden dir 8bit reichen, hättest du das Problem nicht.

  4. #4
    Erfahrener Benutzer Robotik Einstein Avatar von SprinterSB
    Registriert seit
    09.06.2005
    Ort
    An der Saar
    Beiträge
    2.802

    Re: 16bit int über UART versenden

    Zitat Zitat von pongi
    Ist das so richtig? Also wird hiermit zuerst das Low-Byte, dann das High-Byte versendet, oder ist das schwachsinn? Wie würdet ihr das lösen?
    Prinzipiell ist es richtig.

    Es kommt aber immer drauf an, wie ein INT dargestellt ist. Es gibt Maschinen, da stehen die low-Bits im unteren Teil (little Endian) und es gibt solche, da stehen die low-Bits im oberen Teil (big Endian).

    Man muss also sicherstellen, daß auf Sende- und Empfangsseite die gleiche Darstellung verwendet wird.

    Zum Versenden kann man allgemeiner sowas machen:
    Code:
    void uart_send_buf (void*, uint8_t);
    
    // n Bytes (max 255) ab Adresse vbuf verschicken
    void uart_send_buf (void * vbuf, uint8_t nBytes)
    {
    	uint8_t i;
    	uint8_t * buf = (uint8_t*) vbuf;
    
    	for (i=0; i < nBytes; i++)
    	{
    		uart_putc (*buf++);
    	}
    }
    
    ...
    {
    	// result als static weil es aufwändig ist, 
    	// die Adresse einer auto-Variablen zu nehmen
    	static uint16_t result;
    	result = ReadChannel (3);
    	
    	uart_putc (& result, sizeof (result)); 
    }
    Disclaimer: none. Sue me.

  5. #5
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    15.08.2006
    Ort
    Budapest
    Alter
    37
    Beiträge
    563
    Danke! Dann haperts noch an der Verarbeitung der Daten, denn da kommen Werte vor, die überhaupt nicht glaubhaft sind... (Werte über 10000, obwohl bei der ADC-Auflösung von 10Bit höchstens nur 1024 ankommen dürfte).

    @uwegw
    Die Daten werden erst gesendet, falls der Laptop danach fragt, also das Problem gibts nicht.

    @SprinterSB
    Senden geht über Atmega8, programmiert in AVR-GCC, empfangen werden die Daten am Laptop mit WinXP und LabView. Die benutzen meines Wissens nach little Endian, oder? (big Endian gibts nur bei MAC, oder so ähnlich, oder?)

    Gruß

    pongi

  6. #6
    Erfahrener Benutzer Robotik Einstein Avatar von SprinterSB
    Registriert seit
    09.06.2005
    Ort
    An der Saar
    Beiträge
    2.802
    sorry, soll natürlich heissen
    Code:
       uart_send_buf (& result, sizeof (result));
    Disclaimer: none. Sue me.

  7. #7
    Benutzer Stammmitglied
    Registriert seit
    19.03.2006
    Beiträge
    44
    Hallo, ich hätte 2 noch etwas dazu zu sagen, da ich in letzter Zeit auch ein Lab View Projekt hatte.
    1. Ist CR und LF in Lab View deaktiviert könnt sonst Ärger geben wenn eins der Bytes 10 oder 13 ist.
    2. Wieso konvertierst du nicht einfach den Wert zu einer 4 stelligen Hex Zahl und fügst ein Trennzeichen wie / oder: ein, dann ist die Syncronisierung kein Problem. Ich hab das ganze in Assembler und LAB View 7 am Laufen, hier mal die Umrechnung, müsste sich ja in C integrieren lassen.

    ;-------------------------------------------------------------------
    ;Schreibt den Inhalt des Registerpaars X als 5 Dezimalstellen an RS232
    ;VORSICHT! durch dual2BCD wird das Registerpaar X verändert
    ;-------------------------------------------------------------------
    ;Mit Steuerzeichen
    ;-----------------------
    ;
    schreibe_X_5_MS:


    ldi temp1, '/'
    rcall serout ; Unterprogramm aufrufen

    schreibe_X_5_OS:

    rcall dual2BCD ;Subroutine dual2BCD aufrufen

    ldi Temp, 48 ;48 ins Temp laden (ASCII Code)

    mov temp1,Erg2
    add temp1,Temp ;48 addieren (ASCII Code)
    rcall serout ;10.000er ausgeben

    mov temp1,Erg1
    swap temp1
    andi temp1, 0b00001111
    add temp1,Temp ;48 addieren (ASCII Code)
    rcall serout ;1.000er ausgeben

    mov temp1,Erg1
    andi temp1, 0b00001111
    add temp1,Temp ;48 addieren (ASCII Code)
    rcall serout ;100er ausgeben

    mov temp1,Erg0
    swap temp1
    andi temp1, 0b00001111
    add temp1,Temp ;48 addieren (ASCII Code)
    rcall serout ;10er ausgeben

    mov temp1,Erg0
    andi temp1, 0b00001111
    add temp1,Temp ;48 addieren (ASCII Code)
    rcall serout ;1er ausgeben
    ret ;Rücksprung

  8. #8
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    15.08.2006
    Ort
    Budapest
    Alter
    37
    Beiträge
    563
    Die Zahlen werden von mir in LabView als 8bit ints empfangen, und dann zusammengefügt, also nix mit Strings und so.
    Trotzdem danke!
    Hatte noch keine Zeit, das ganze jetzt wieder auszuprobieren, also weiss ich nicht, obs jetzt läuft.

  9. #9
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    15.08.2006
    Ort
    Budapest
    Alter
    37
    Beiträge
    563
    Nach zahlreichen Tests bin ich zum folgenden -für mich ziemlich schleirhaften- Ergebnis gekommen:
    Die ersten hundert Werte die Übertragen werden, stimmen (sie sind zumindest im Bereich wo sie sein sollten). Danach kommt aber völliger quatsch.

    Zum besseren Verständnis beschreibe ich das ganze Projekt ein bisschen näher.

    Damit der Roboter seine Umgebung erkunden kann, bekam er eine Art Radar. Dieser besteht aus einer drehbaren Scheibe, mit zwei Sharp GP2Y0A02 (20-150 cm) oben drauf, jeweils eine für die zwei Kreishälften (also 180°). Der Schrittmotor der die Scheibe dreht, macht in 256 Schritten eine halbe Umdrehung, und es wird bei jedem Schritt gemessen.
    Wie gesagt: die ersten 100 Werte (einmal die ersten 97, dann die ersten 106, also keine bestimmte Anzahl) kommen von beiden Sensoren an, die gemessene Spannung liegt also zwischen 0 und 2,56V (interne Referenz). Danach kommen bei beiden Sensoren Werte um die 160, auf alle Fälle um einiges größer als 2,56V.

    Woran kann das liegen, habt ihr Ideen?

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •  

Labornetzteil AliExpress