Mittelwert von 16-bit messwerten



  • hoi,
    habe ein teilprogramm vorgegeben bekommen und sollte es so erweitern, dass es korrekt funktioniert. ich habe es auch zum laufen gebracht, nur funktioniert es nicht richtig. was muss ich noch abändern, damit es richtig funtkioniert ?
    komme einfach nicht weiter, finde die fehler nicht. bin über jede hilfe froh !

    #include<string.h>
    #include<conio.h>
    
    #include<stdio.h>   
    
    typedef enum {FALSE, TRUE} BOOL;
    typedef unsigned short word16;
    
    /*
    Aufbau der 16bit-Messwerte
    5432109876543210
    ITTTWWWWWWWWWWXX
    ||||||||||||||++--- Nachkommastellen Messergebnis, nicht signifikante Stellen
    ||||++++++++++----- Vorkommastellen Messergebnis, signifikante Stellen
    |+++--------------- Zeitstempel der Messung
    +------------------ MesswertID
    Zur Berechnung des Mittelwerts werden nur signifikante Stellen herangezogen
    */
    
    double BerechneMittelwert(word16 *md, word16 MesswertID, word16 AnzahlMesswerte){
    	double Mittelwert = 0;  // Initialiword1sierung der Ausgabe
    	word16 i, IDmaske;
    	// Mittelwert für die gewünschte Anzahl Werte mit gewünschter MesswertID berechnen
    	IDmaske = MesswertID<<16; // Vergleichsmaske aufbauen, MesswertID aus {0,1}
    	for (i=0; i<AnzahlMesswerte; i++)
    		if ((md[i] & 0x8000) == IDmaske){
    			Mittelwert += (double) ((md[i] & 0xFFF));
    		}
       Mittelwert /= (double) AnzahlMesswerte;
    	return Mittelwert;      
    	}
           // } zu viel
    
    word16 LiesMesswerte(word16 *md){
      word16 AnzahlGelesen = 0;
      int eingegeben;
      printf("\n");
      do {
      	printf ("Bitte 16Bit-Messwert hexadezimal eingeben (Form HHHH), Ende mit X :\t");
    	  eingegeben = scanf ("%X", &md[AnzahlGelesen]);
    	  fflush (stdin);
        AnzahlGelesen += eingegeben;
      } while (eingegeben>0);
      return (AnzahlGelesen);
    }
    
    BOOL LiesParameter (word16 *anr, word16 *key, word16 gnr){
      BOOL error = FALSE;
      printf ("\nWieviele Messwerte sollen im Mittelwert beruecksichtigt werden ? :\t");
      scanf ("%hd", anr);
      fflush (stdin);
      if (*anr > 0){
        printf ("Fuer welche Messwert-ID soll der Mittelwert berechnet werden ? :\t");
        scanf ("%hd", key);
        fflush (stdin);
      }
      if ((*key > 1) || (*anr == 0) || (*anr > gnr)){
    	   error = TRUE;
      }
      return (error);
    }
    
    void main (){
      word16   Messwerte[100];     
      word16   AnzahlEingelesen, Anzahl, ID, i;
      double   Mittelwert;
      BOOL     ende;
    
      // Einlesen der Messwerte, hier stellvertretend von der Konsole einlesen
      AnzahlEingelesen = LiesMesswerte(Messwerte);
      printf ("\nAnzahl eingelesener Messwerte:\t %d", AnzahlEingelesen);
      // Ende Einlesen der Messwerte
    
      do{
    	// Abfrage der zur Bestimmung des Mittelwerts zu verarbeitenden MesswertID und Messwertanzahl
    	ende = LiesParameter(&Anzahl, &ID, AnzahlEingelesen);
    
        if (ende){
         // Mittelwert der ersten N Messwerte des Typs ID berechnen
    	   Mittelwert = BerechneMittelwert(Messwerte, ID, Anzahl);
    
    	   // tabellarische Ausgabe der im Mittelwert berücksichtigten Messwerte
    	   for (i=0; i<Anzahl; i++){
               printf ("\nID = %d \t Messwert = %d", (Messwerte[i] & 0x8000) > 0, (Messwerte[i] & 0x0FFF)>>2);
    	   }
    
    	   // Ausgabe des Mittelwerts
         printf("\nID %d: Mittelwert= %f ", ID, Mittelwert);
        }
    
      } while(ende == FALSE);
    
      printf("Ende");
      getch();
    
    }
    

    die messwerte mit denen ich testen soll sind :

    1010 0001 0010 1100 ↔ A12C ↔ 41260

    0000 0100 1111 1111 ↔ 04FF ↔ 1279

    1011 0001 0101 1010 ↔ B15A ↔ 45402

    0001 0101 0000 0101 ↔ 1505 ↔ 5381

    0010 0011 1111 1011 ↔ 23FB ↔ 9211

    1101 0000 1111 1001 ↔ B0F9 ↔ 45305

    😞 🙄



  • Sehe ich das richtig, die ID besteht nur aus einem Bit? Wenn ja, hast du den Wert vermutlich zu weit geschoben (von Bit 0 zu Bit 15 mußt du um 15 Stellen verschieben). Außerdem solltest du die "Nachkommastellen" auch ausmaskieren und mitzählen, wieviele der Werte tatsächlich in die Summe eingerechnet wurden.



  • hmmm da bin ich mir jetzt gar nicht sicher, ich hab es jetzt mal um 12 bits verschoben, denn da sind ja noch 3 bits für den zeitstempel, der soll ja glaub ich auch nicht mitberechnet werden.
    die nachkommastellen sind so viel ich weiß nich von bedeutung, die soll man glaube ich aussortieren.



  • ich habs noch mal überarbeitet. mit den 15 stellen war doch richtig.
    problem jetzt ist aber das die ID nich richtig angezeigt wird. es kommt immer eine 0. bei messwerten mit dem 1. bit als 1 soll die ID 1 sein.

    [code]#include <string.h>
    #include <conio.h>
    #include <stdio.h>

    typedef enum {FALSE, TRUE} BOOL;
    typedef unsigned short word16;

    /*
    Aufbau der 16bit-Messwerte
    5432109876543210
    ITTTWWWWWWWWWWXX
    ||||||||||||||++--- Nachkommastellen Messergebnis, nicht signifikante Stellen
    ||||++++++++++----- Vorkommastellen Messergebnis, signifikante Stellen
    |+++--------------- Zeitstempel der Messung
    +------------------ MesswertID
    Zur Berechnung des Mittelwerts werden nur signifikante Stellen herangezogen
    */

    double BerechneMittelwert(word16 *md, word16 MesswertID, word16 AnzahlMesswerte){
    double Mittelwert = 0; // Initialisierung der Ausgabe
    word16 i, IDmaske;
    int zaehl = 0;
    // Mittelwert für die gewünschte Anzahl Werte mit gewünschter MesswertID berechnen
    IDmaske = MesswertID<<15;
    for (i=0; i<AnzahlMesswerte; i++)
    {
    if ((md[i] & 0x8000) == IDmaske)
    {
    Mittelwert += (double) ((md[i] & 0xFFF)>>2); // Nachkommastellen sollen wegeshiftet werden
    zaehl++;
    }
    }
    if (zaehl == 0)
    {
    Mittelwert = -1;
    }
    else
    {
    Mittelwert /= (double) zaehl;
    }
    return (Mittelwert);
    }

    word16 LiesMesswerte(word16 *md){
    word16 AnzahlGelesen = 0;
    int eingegeben;
    printf("\n");
    do {
    printf ("Bitte 16Bit-Messwert hexadezimal eingeben (Form HHHH), Ende mit X :\t");
    eingegeben = scanf ("%X", &md[AnzahlGelesen]);
    fflush (stdin);
    AnzahlGelesen += eingegeben;
    } while (eingegeben>0);
    return (AnzahlGelesen);
    }

    BOOL LiesParameter (word16 *anr, word16 *key, word16 gnr){
    BOOL error = FALSE;
    printf ("\nWieviele Messwerte sollen im Mittelwert beruecksichtigt werden ? :\t");
    scanf ("%hd", anr);
    fflush (stdin);
    if (*anr > 0){
    printf ("Fuer welche Messwert-ID soll der Mittelwert berechnet werden ? :\t");
    scanf ("%hd", key);
    fflush (stdin);
    }
    if ((*key > 1) || (*anr == 0) || (*anr > gnr)){
    error = TRUE;
    }
    return (error);
    }

    void main (){
    word16 Messwerte[100]={0}; // Deklaration 0 fehlt
    word16 AnzahlEingelesen, Anzahl, ID, i;
    double Mittelwert;
    BOOL ende;

    // Einlesen der Messwerte, hier stellvertretend von der Konsole einlesen
    AnzahlEingelesen = LiesMesswerte(Messwerte);
    printf ("\nAnzahl eingelesener Messwerte:\t %d", AnzahlEingelesen);
    // Ende Einlesen der Messwerte

    do{
    // Abfrage der zur Bestimmung des Mittelwerts zu verarbeitenden MesswertID und Messwertanzahl
    ende = LiesParameter(&Anzahl, &ID, AnzahlEingelesen);

    if (ende == FALSE){
    // Mittelwert der ersten N Messwerte des Typs ID berechnen
    Mittelwert = BerechneMittelwert(Messwerte, ID, Anzahl);

    // tabellarische Ausgabe der im Mittelwert berücksichtigten Messwerte
    for (i=0; i<Anzahl; i++){
    printf ("\nID = %d \t Messwert = %d", (Messwerte[i] & 0x8000) > 0, (Messwerte[i] & 0x0FFF)>>2);
    }

    // Ausgabe des Mittelwerts
    printf("\nID %d: Mittelwert= %f ", ID, Mittelwert);
    }

    } while(ende == FALSE);

    printf("Ende");

    }



  • Randbemerkungen:
    Erstens: Das ANSI C Board ist eine Etage höher 😉
    Zweitens: "fflush(stdin)" und "void main()" sind nicht Teil des ANSI-Standards.
    Drittens: Wenn du schon Syntaxcoloring verwendest, dann bitte richtig (dazu gehört (a) die {cpp}-Tags und (b), daß du die Code-Blöcke auch wieder schließt).

    Zu deinem Problem: Gib doch mal zusätzlich die Hex-Darstellung der Werte aus, denen dein Programm eine falsche ID zugeordnet hat (oder noch besser - alle).



  • Ergänzend Viertens: Man kann seine Beiträge nach dem Abschicken auch bewundern und als registrierter User sogar ändern. Darüberhinaus gibt es eine Vorschaufunktion!



  • oh hab mich vertan mitm forum... also wollte schon ins ANSI C forum posten, bitte um entschuldigung. ohje stimmt hab vergessen den block wieder zu schließen.

    er ordnet den werten die richtige ID zu und berechnet den mittelwert von den gewünschten IDs, nur wird die ID ansich nicht richtig ausgegeben.

    hier mal ein testdurchlauf.

    Bitte 16Bit-Messwert hexadezimal eingeben (Form HHHH), Ende mit X : a12c
    Bitte 16Bit-Messwert hexadezimal eingeben (Form HHHH), Ende mit X : 1505
    Bitte 16Bit-Messwert hexadezimal eingeben (Form HHHH), Ende mit X : x

    Anzahl eingelesener Messwerte: 2
    Wieviele Messwerte sollen im Mittelwert beruecksichtigt werden ? : 2
    Fuer welche Messwert-ID soll der Mittelwert berechnet werden ? : 1

    ID = 0 Messwert = 75
    ID = 0 Messwert = 321
    ID 1: Mittelwert= 75.000000

    a12c hat die ID 1, da das erste Bit eine 1 hat und den Messwert 75, da die ersten 4 bits wegfallen und die letzten 2.
    1505 hat die ID 0, da das erste Bit keine 1 hat und den Messwert 321, da die ...

    das programm gibt jedoch für den ersten Messwert die ID 0 aus. Es geht nur um die Ausgabe, die Berechnung funktioniert mitlerweile.



  • Dieser Thread wurde von Moderator/in HumeSikkins aus dem Forum C++ in das Forum ANSI C verschoben.

    Im Zweifelsfall bitte auch folgende Hinweise beachten:
    C/C++ Forum :: FAQ - Sonstiges :: Wohin mit meiner Frage?

    Dieses Posting wurde automatisch erzeugt.


Anmelden zum Antworten