Forum: Mikrocontroller und Digitale Elektronik Universelles Diagramobjekt erstellen


von Chris J. (Gast)


Lesenswert?

Moin!

Vielleicht weiss ja ein Spezi, wie man so ein Problem am besten löst?

Ich möchte in Ansi C für ARM für mein Display ein universelles Histogram 
Objekt erstellen. D.h. verschiedene Messwerte wie Druck, Feuchte, 
Temperatur werden von ein und derselben Routine erledigt. Sieht später 
so aus wie in Histogramm bei der Bildbearbeitung.

Also wurstel ich mir erstmal die Grundstruktur hin, nur ein Entwurf.
Prinzip soll sein, dass das Hauptprogramm einen Struct mit Werten 
vollpackt, dann eine InitRoutine aufruft, die einen Zeiger auf das neue 
Diagramm enthält, d.h. nur die Eckdaten und Werte. Halt so wie in der 
StdperiphLib auch.

Diagramm_t myDiagramm;
myDiagramm.blabla = Wert
myDiagramm.blubb  = Wert
ZeigeraufNeues Diagramm = CreateDiagramm(&myDiagramm);

Womit ich etwas rumeier und noch nicht weiss, wie lösen ist der Umstand 
dass die Werte diverse Datentypen haben. Druck ist float, Temperatur ist 
int8 usw. Ich kann bei 20k nicht mit dem Speicher herumasen, also muss 
ich schon sparen. Klar kann man alle max 200 Elemente float machen aber 
dass sind dann eben 200 x 4 Bytes = 1 kByte. Zzgl noch 1 "valid Byte", 
da ich 0 brauche und 0 nicht als ungültigen Datensatz deklarieren kann.

Also versuche ich für jedes erzeugte Diagramm den Datentyp mit zu geben 
an die Create Routine.

Gibt es da vielleicht etwas Eleganteres als das was ich verbrochen habe?
1
/* Datenformate */
2
typedef enum {t_float,
3
              t_int8,
4
              t_uint8,
5
              t_uint16}
6
DF_t;
7
8
typedef union {
9
    int8_t   zahl_8t;
10
    uint8_t  zahl_u8t;
11
    int16_t  zahl_16t;
12
    uint16_t zahl_u16t;
13
    float    zahl_f;
14
} werte_t;
15
16
17
typedef struct {
18
    uint16_t x_pxLen,       // X Ausdehnung in Pixel /2 teilbar
19
             y_pxLen,       // Y Ausdehnung in Pixel /2 teilbar
20
             x_Null,        // Nullpunkt
21
             y_Null;
22
    uint16_t entrys;        // Anzahl Einträge
23
    DF_t     DataFormat;    // Datentype: float, uint16_t, int16_t, uint8_t, int8_t
24
    uint32_t color;         // Farbe des Histogramms
25
    werte_t* valptr;        // Zeiger auf Wertetabelle
26
27
28
29
} DiaParam_t;
30
31
32
DiaParam_t* CreateNewDiagram(DiaParam_t* src)
33
{
34
    /* Prüfung auf gerade Zahlen*/
35
    if (src->x_pxLen & 1)
36
        return (NULL);
37
38
    if (src->y_pxLen & 1)
39
        return (NULL);
40
41
    /* Reserviere Speicher für Infostruct*/
42
    DiaParam_t* dest = malloc(sizeof(DiaParam_t));
43
    if (dest == NULL)
44
        return(NULL);
45
46
    /* Kopiere Infos in neuen Struct */
47
    memcpy(dest,src,sizeof(DiaParam_t));
48
49
    /* Reserviere Speicher für Wertetabelle */
50
    size_t len;
51
    switch (src->DataFormat) {
52
        case  t_float   :   len = sizeof(float);
53
                            break;
54
        case  t_int8    :   len = sizeof(int8_t);
55
                            break;
56
        case  t_uint8   :   len = sizeof(uint8_t);
57
                            break;
58
        case  t_uint16  :   len = sizeof(uint16_t);
59
                            break;
60
        default:            break;
61
    }
62
63
    dest->valptr = malloc(src->entrys * len);
64
    if (dest->valptr == NULL)
65
        return (NULL);
66
67
    return (dest);
68
}

: Verschoben durch Moderator
von Johannes S. (Gast)


Angehängte Dateien:

Lesenswert?

In C? Igitt.... Für meinen Reflow Ofen habe ich gerade ähnliches 
angefangen und brauche da auch ein Chart für T Soll und Ist. Ich dachte 
sowas findet man mäßig auf Github aber nach einiger Suche dachte ich das 
man sowas doch selbst hinbekommt.
Ich baue das in C++, basierend auf der Adafruit Grafik Lib. Die trennt 
sauber den HW Layer von den Grafik Primitiven, dadurch konnte ich die 
Grafik schon als Simu auf dem PC erstellen. Ist noch in den Grundzügen, 
aber kann ich bei Interesse hier vorstellen. Das basiert auf mbed und 
ist damit per Export einfach für Bluepill und EmBitz zu generieren.

von Johannes S. (Gast)


Angehängte Dateien:

Lesenswert?

So sieht das als Anfang aus bisher aus, einmal die Darstellung auf dem 
µC und das mit dem exaktamente gleichen Code erzeugte Bild in der PC 
Simu. Auf dem PC ist die Entwicklung einfach bequemer, auch wenn das 
Debuggen auf den Cortexen schon easy ist.
Der Text in der Simu fehlt noch weil die Grafik in mbed von der mbed 
Stream Klasse abgeleitet ist und putc/puts/printf zur Verfügung stellt, 
das wäre der nächste Schritt diese in der Simu zu implementieren. Bei 
den Arduinos wird ist das von einer vereinfachten printf abgeleitet, 
aber die Arduinos haben für mich eine untergeordnete Priorität.
Der Code für das Chart sieht bisher so aus:
1
  Chart chart(tft, 0, 0, 320, 200, WHITE);
2
3
  tft.begin();
4
  tft.reset();
5
  tft.setRotation(1);
6
  tft.fillScreen(BLACK);
7
8
  PlotArea* plotArea = chart.addPlotArea(6 * 6, 0, 0, 10, YELLOW);
9
  plotArea->addGridVertical(plotArea->_w / 10, RED);
10
  plotArea->addGridHorizontal(plotArea->_h / 5, GREEN);
11
  chart.draw();

Das ist wie gesagt noch nicht zu Ende modelliert und es fehlt noch die 
Anbindung von Skalen und Datenserien. Ist eigentlich 'nur' Fleissarbeit, 
aber ich muss mich gerade ziemlich teilen.

ooops, jetzt sind die Bilder doppelt. Beim Ändern des vorherigen Posts 
gabs Mecker, deshalb habe ich die noch nochmal angehängt. Könnte ein Mod 
im vorherigen Post löschen wenn er mag. Ist schon spät...
PS: angehängte Bilder kann man bei Editieren nicht wieder löschen?

von Chris J. (Gast)


Lesenswert?

Johannes S. schrieb:
> In C? Igitt....

Du Johannes.... das nennt man auch "einen Thread kapern" ;-)

Mir fällt bisher nichts ein, wie ich den Datentyp allgemeingültig halten 
kann. GNU CC ist doch so mächtig, vielleicht gibts da ja doch noch was.

von Johannes S. (Gast)


Lesenswert?

Naja, das Aufgabe hört sich zumindest gleich an, aber wenn ich dich 
nicht mit c++ überzeugen kann...

In C kann man Objektfunktionalität natürlich auch bauen. In C++ kann man 
dem Chart ein 'addDataSeries(DataSeries)' verpassen und die DataSeries 
kann eine virtuelle Funktion 'draw()' haben die dann ihren Datentyp in 
Pixel umrechnet.

In dein C Beispiel übersetzt heisst das in Diagram_t Funktionspointer zu 
definieren für dass Speicherhandling und die Zeichenfunktion. Dann 
kannst du auch ein drawFloat oder drawInt8 bauen das eben die Daten 
entsprechend interpretiert.

von pegel (Gast)


Angehängte Dateien:

Lesenswert?


von Johannes S. (Gast)


Lesenswert?

Warum ist dieser Thread in PC-Programmierung gelandet? Es geht doch 
eindeutig um uC Programmierung.

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Johannes S. schrieb:
> Warum ist dieser Thread in PC-Programmierung gelandet?

Habe das korrigiert.

von Johannes S. (Gast)


Lesenswert?

Danke!

von Chris J. (Gast)


Lesenswert?

pegel schrieb:
> Kennst du den?

Es macht wenig Sinn ein komplett neues Setup zu benutzen, was mehr 
braucht als einen Editor, wenn man bereits alles selbst gemacht hat.

Ich habe da mal reingeschaut.... bisher noch keinen Plan wie man das 
einsetzt, wenn man ein SPI Display vom Typ ILI9341 an einen STM32103 
gepappt hat. Da muss dann ja auch der LL Layer geschrieben werden. Das 
schreckt mich von solchen Libs auch immer ab.

Ok, es gibt Hoffnung, wenn ich so ein Demoprojekt irgendwie in Embitz 
reinkriege und die tausende Pfade zu den Libs richtig gesetzt habe...
1
  /* Configuration for SPI interfaced LCDs */
2
#if defined(USE_STM3210C_EVAL) || defined(USE_STM3210B_EVAL) ||\
3
  defined(USE_STM32100B_EVAL) ||   defined(USE_STM32L152_EVAL)
4
  pLcdParam->LCD_Ctrl_Port_NCS          = LCD_CTRL_PORT_NCS;
5
  pLcdParam->LCD_Gpio_Data_Port         = LCD_GPIO_DATA_PORT;
6
  pLcdParam->LCD_Ctrl_Pin_NCS           = LCD_CTRL_PIN_NCS;
7
  pLcdParam->LCD_Gpio_Pin_SCK           = LCD_GPIO_PIN_SCK;
8
  pLcdParam->LCD_Gpio_Pin_MISO          = LCD_GPIO_PIN_MISO;
9
  pLcdParam->LCD_Gpio_Pin_MOSI          = LCD_GPIO_PIN_MOSI;
10
  pLcdParam->LCD_Gpio_RemapPort         = LCD_GPIO_REMAP_PORT;
11
  pLcdParam->LCD_Rcc_BusPeriph_GPIO     = LCD_GPIO_RCC_BUS_PERIPH;
12
  pLcdParam->LCD_Rcc_BusPeriph_GPIO_Ncs = LCD_GPIO_RCC_BUS_PERIPH_NCS;
13
  pLcdParam->LCD_Bus_Port               = LCD_SPI_PORT;
14
#endif
15
16
}

von Chris J. (Gast)


Angehängte Dateien:

Lesenswert?

Vielleicht kannst Du mir mal Starthilfe geben, wie sowas grundsätzlich 
eingerichtet wird.

Das erzeugt mir das Tool, wie ich sehe... und wie wird das eingebunden? 
Welche Hardware brauche ich zum Testen? Möglichst ein Demoboard mit 
Display.
Ich arbeite mit EmBitz IDE, basiert auf CodeBlocks, kennt aber kein 
cmake.

Im Bild mein Projekt. Mein Code, der auf der SPL und TMLIB (Tilen 
Majerle) basiert, beides Middlewares. zB enthält die grundlegenede 
Grafikfunktionen und eine Kapselung fast aller Pripherie. Ich habe nur 
das Interface für mein Display geschrieben.

Wenn das mit diesem Grafikwunder auch so geht wäre das schon gut....

von pegel (Gast)


Lesenswert?

Hast schon Recht.
Wenn dein Board nicht in der Lib ist, wird schon einiges an Anpassung 
benötigt.

Da die Lib komplett im Quellcode vorliegt, im Gegensatz zu anderen wie 
STemWin, kann man aber vielleicht einige Ideen "ausleihen".

von uuu (Gast)


Lesenswert?

Ein allgemein gueltiger Datentyp ? Byte. Byte-Anzahl X-Werte & 
Byte-Anzahl Counts = Y Werte. Gebrochene Pixel gibt es ja nicht.

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.