Diese Library ermöglicht es eine “einfache” Graphische Benutzeroberfläche
mit dem STM32F429 und einem Grafik-Display (mit Touch) zu realisieren.
Hier ein paar Bilder wie das ganze aussieht :
File-Aufbau :
Die SGUI-Library besteht aus mehreren Files.
Als Hierachiebaum sieht das ganze so aus :
User-Projekt | +stm32_ub_sgui | +ub_sgui_screen +ub_sgui_window +ub_sgui_text | +ub_sgui_panel +ub_sgui_button +ub_sgui_led +ub_sgui_label +ub_sgui_checkbox +ub_sgui_gauge +ub_sgui_radiobtn
Wie zu sehen ist, muss der User nur ein File includen “stm32_ub_sgui”
der Rest wird automatisch “angehängt”
“SGUI_SCREEN” , “SGUI_Window” und “SGUI_Text” muss im Projekt vorhanden sein
die anderen Objekte (Button, LED usw) können falls nicht benötigt
auch weggelassen werden.
Funktionsweise :
Der User muss folgende Dinge in seinem Programm einbauen :
1. Die Init-Funktion von SGUI muss als erstes nach Power-On aufgerufen werden
2. Alle Seiten (Windows) die später zu sehen sein sollen,
müssen einmal “erstellt” werden. (Erklärung folgt)
(das muss bzw. darf nur einmal nach Power-On gemacht werden)
3. Die Funktion “SGUI_DO” muss zyklisch aufgerufen werden
(die kümmert sich um das zeichen/touchabfrage usw)
Hello-World Beispiel :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | #include "stm32_ub_sgui.h" int main(void) { SBUTTON_t* btn; SystemInit(); SGUI_Init(); SGUI_WindowCreateMain(1); btn=SGUI_ButtonCreate(10,20,100,50); SGUI_ButtonSetText(btn,"Hello"); while(1) { SGUI_Do(); } } |
Hier ein miminal Beispiel das ein leeres Fenster erzeugt (mit Nr. 1),
darauf einen Button platziert und die Beschriftung vom Button ändert.
Der Button hat zwar keine Funktion aber die SGUI-Library kümmert sich
(durch die SGUI_DO) das man den Button per Touch drücken kann.
Allgemeine Hinweise :
Alle Objekte besitzen Parameter die beim “Create” erstmal auf einen
Standardwert gesetzt werden (z.B. Farbe, Schriftart, Rahmendicke usw)
Alle Parameter können aber nachträglich (auch während dem Programmlauf)
geändert werden. Falls der User einen Parameter von einem Objekt ändert,
und dieses gerade sichtbar ist, wird es automatisch neu gezeichnet.
Die Software reserviert erst beim “Create” Speicherplatz im RAM für das Objekt.
So das es eigentlich (außer der RAM-Größe) kein oberes Limit für die Anzahl
der Objekte gibt. Ich habe aber eine “maximal Anzahl” für die Objekte
im jeweiligen H-File festgelegt (im Moment 100 von jeder Art). nur zur Info.
Wer das Display im Landscape-Mode betreiben will, muss den Define
im File “ub_sgui_screen.h” ändern.
Objekt : Window
Ein “Window” ist die Zeichenunterlage für alle anderen Objekte (außer andere Windows)
Es gibt zwei Typen : “Main” und “Child”
Main-Windows füllen den kompletten Screen (Größe kann nicht eingestellt werden)
Child-Windows können eine beliebige Größe und Position besitzen.
Wenn ein Child-Window angezeigt wird, bleibt das darunter liegende Main-Window
zum Teil sichtbar. Das Child liegt also im Vordergrund.
Hinweis : ohne ein Window , kann kein anderes Objekt erzeugt werden.
Jedes Objekt wird beim erzeugen dem aktuellen Window zugeordnet.
Beim zeichnen von einem Window werden alle Objekte gezeichnet,
die diesem Window zugeordnet sind. Und nur diese Objekte reagieren
auf Touch eingaben.
Objekt-Liste :
Hier eine Liste aller im Moment verfügbaren Objekte
die auf einem Window platziert werden können.
Einige davon können per Touch gesteuert werden.
(Eine Doku zu allen Objekten ist in der Library dabei)
> Text
> Panel
> Button
> LED
> Label
> Checkbox
> Radio-Button
> Gauge
> Slider
> Select-Button
> Listbox
> DropDown-Box
> IntEdit
> FloatEdit
> Picture
> Graph
Beispiel :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 | //-------------------------------------------------------------- // File : main.c // Datum : 17.01.2015 // Version : 1.0 // Autor : UB // EMail : mc-4u(@)t-online.de // Web : www.mikrocontroller-4u.de // CPU : STM32F429 // IDE : CooCox CoIDE 1.7.4 // GCC : 4.7 2012q4 // Module : CMSIS_BOOT, M4_CMSIS_CORE // Funktion : Demo der SGUI // Hinweis : Diese zwei Files muessen auf 8MHz stehen // "cmsis_boot/stm32f4xx.h" // "cmsis_boot/system_stm32f4xx.c" // In Configuration diese Define hinzufügen : // "STM32F429_439xx" , "__ASSEMBLY__" , "USE_STDPERIPH_DRIVER" //-------------------------------------------------------------- #include "main.h" #include "stm32_ub_sgui.h" SLABEL_t *label; SBUTTON_t *btn1, *btn2; //-------------------------------------------------------------- void create_Window1(void); void create_Window2(void); //-------------------------------------------------------------- void btn1_fkt(bool aktiv); void btn2_fkt(bool aktiv); //-------------------------------------------------------------- //-------------------------------------------------------------- // Demoprogramm der "Simple-GUI" // es werden zwei Fenster erzeugt mit jeweil einem Button // mit den Buttons kann zwischen den Fenstern gewechselt werden //-------------------------------------------------------------- int main(void) { SystemInit(); // Quarz Einstellungen aktivieren // init der SGUI SGUI_Init(); // Fenster erzeugen create_Window1(); create_Window2(); // Window-1 anzeigen SGUI_WindowShow(1); while(1) { SGUI_Do(); // SGUI bearbeiten } } //-------------------------------------------------------------- void create_Window1(void) { // ein Window erstellen (Nr. 1) SGUI_WindowCreateMain(1); // ein Label platzieren und beschriften label=SGUI_LabelCreate(10,10,220,50); SGUI_LabelSetText(label,"Window-1"); // einen Button platzieren und beschriften btn1=SGUI_ButtonCreate(10,100,100,50); SGUI_ButtonSetText(btn1,"Btn-1"); // einen Handler fuer den Button einrichten SGUI_ButtonSetHandler(btn1,btn1_fkt); } //-------------------------------------------------------------- void create_Window2(void) { // ein Window erstellen (Nr. 2) SGUI_WindowCreateMain(2); // ein Label platzieren und beschriften label=SGUI_LabelCreate(10,10,220,50); SGUI_LabelSetText(label,"Window-2"); // einen Button platzieren und beschriften btn2=SGUI_ButtonCreate(10,100,100,50); SGUI_ButtonSetText(btn2,"Btn-2"); // einen Handler fuer den Button einrichten SGUI_ButtonSetHandler(btn2,btn2_fkt); } //-------------------------------------------------------------- void btn1_fkt(bool aktiv) { // beim verlassen von Button-1 das Window-2 anzeigen if(aktiv==false) SGUI_WindowShow(2); } //-------------------------------------------------------------- void btn2_fkt(bool aktiv) { // beim verlassen von Button-2 das Window-1 anzeigen if(aktiv==false) SGUI_WindowShow(1); } |
Hier die komplette Doku als PDF-File (Danke an Michael dafür) :
Hier die Library zum Download :
Hier der komplette CooCox-Projektordner zum Download : (Hello-World)
Hier der komplette CooCox-Projektordner zum Download : (Demo aller Objekte)
wow, das ist wirklich cool!
Allerdings muss man sich dort definitiv mehr einlesen und probieren als in andere Projekte, nur includen und loslegen ist da nicht möglich.
Ist die grüne Led PG13 unabhängig von der blinkenden Led auf dem Display?
Die sind nämlich je nach Zustand nicht synchron.
Ja, wenn man es richtig machen will brauchen Code und Doku ca 50:50 der Zeit vom Projekt. Ich spare mir meist die Doku und versuche das mit Kommentaren im Code auszugleichen. Versuche die Kommentare zu verstehen und ich versuche hier zu jedem Objekt zumindest ein Beispiel zu bringen.
Nice,
I’m waiting for function like SGUI_WindowGetPrevActive() to get previous active window.
Why would this be good?
If you make child window with “Are you sure?” box and “Close/OK” buttons, if you click “Close”, you get back previous window and you don’t need to take care for that.
I’ve added already this in your implementation for testing, works great.
I’m also missing relative path.
So if you make a child window (like alert message), then I’m expecting that all buttons/labels/whatever’s position is relative to this window.
If window is at location 10,10, then if button has x,y = 10,10 then this is actual value in LCD at x,y = 20,20. If you understand.
please try Version B.02 for “SGUI_WindowShowPrev” and offset in Child-Windows.
I have also changed the touch behavior : to aktivate an object the touch must be released first. And the function “TextCreateDec” now needs a parameter for the digits and leading zeros can be enabled.
You are going nice
One feature will be to select whether LED is circle or rectangle.
yep, no problem. what do you think about the syntax ? too many single
functions to set the properties of one objekt ? Or should i use “global” settings
like “SGUI_SetFont” and all other created objekts use this font ?
Use global functions and one structure with default settings.
For single LED: SGUI_LedSetMode(ledpointer, LED_RECTANGLE);
For global default led settings
SGUI_LedSetDefaultMode(LED_RECTANGLE);
Example on how you can use “Are you sure?” alert box for more than just 1 operation.
http://pastebin.com/HRDxtNsW
nice example
Really nice.
I was trying the one I was also expecting that it will be bug.
If I use drowdown for example in child window, which is smaller than dropdown, then when I open dropdown, and close it back, not all is cleared, because it is on inactive window.
This is hard to make easy to clean.
I suggest you that you don’t allow that dropdown goes outside the child box.
Keep up a great work!
Also, I saw your great sollution for strings using double pointers! Nice work!
thanks for testing, its hard to think at all combinations.
You are right i must restrict the size of the box and i must add a scroll bar too.
(or should i repaint both windows ?) i will add one more objekt to show decimal values with arrows to change
and then i make a bugfix week. so please post all bugs you found in B.04
(e.g how many objekts can you add before a RAM overflow
I think that you don’t need to repaint both windows.
Just add limit to where you can go.
And maybe integrated slider for that if list is longer than window.
Another very useful feature will be that every function returnes pointer.
For example: If I work with buttons I would like that all button related functions returns button pointer.
Then, this can be done:
SGUI_ButtonSetColor(SGUI_ButtonSetText(SGUI_ButtonCreate(…),…));
i think thats hard to read with all functions in one line.
but you have the source, include it if you want.
Hi UVE.
I have found another bug.
If I have slider akt_value set to 10 and then I changed Max to 100 and Min to greater than current, everything fails
When you set min and max value, you should also check for actual current value.
fixed in B.07
DropDown-Box is now with scrollbar if too many items.
The function “SGUI_WindowGetUsedRam” returns the used ram space.
Try to set string larger than is dropdown’s width
You are going nice through, but you still need a lot of work for that.
I have a lot of ideas but as I know you don’t allow your libs for production mode, so I won’t tell it here.
Will do my own gui with them.
of course you can spend 100 h to reprogram STemWin…but that was not my intent. the project name is “simple” gui ..so its a running base gui and the user can add the features he want and fix bugs like the string length limitation by its own
Hallo,
wird es die Möglichkeit geben, die GUI zu drehen (also Landscape Mode)?
Gruß
Also Markus, genau das war auch meine erste Frage… ich hab mal kurz herumgespielt und habe folgende Zeile entdeckt:
ub_sgui_screen.h
in Zeile 28: SGUI_SCREEN_ORIENTATION 1 // 1=landscape
Danach dreht sich die Orientierung von Display- Inhalt und Touch. Ob es noch andere Auswirkungen gibt, kann ich derzeit noch nicht sagen…
Hi I could help, just ask him to place their information in English please in text files.
Greetings …
Very good job UB,
I’m from Mexico and I’m learning to program in C language, I’m learning with ARM microcontrollers, and your libraries are helping me to make things easier.
Thank you very much for their libraries.
I wonder if you could develop something similar to the development environment “GUIBuilder” but focused on your graphics libraries.
SGUI with SGUI_Builder.
This would be very interesting.
Again thank you very much.
Greetings …
Sorry for my bad English.
hi,
“sgui” is “simple”, so its not made to load an external file
and create a gui out of this.
the onle simplification with a computer-tool is to genereate
“scripts-snippets” e.g. to add a buttton :
SBUTTON_t* btn;
btn=SGUI_ButtonCreate(10,20,100,25);
SGUI_ButtonSetText(btn,"Text");
and the user must cop&paste this script into the c-file.
But thats a lot of work and in my opinion not usefull at all.
Hi,
gibt es die Möglichkeit Bilder auf einem Window anzuzeigen?
Ich habe versucht einfach in das Create eines Windows das Bild miteinzubinden, leider wird das Bild nur ganz am Anfang ganz kurz angezeigt.
void create_Window1(void)
{
// ein Window erstellen (Nr. 1)
SGUI_WindowCreateMain(1);
// ein Label platzieren und beschriften
label=SGUI_LabelCreate(10,10,220,50);
SGUI_LabelSetText(label,”Window-1″);
// einen Button platzieren und beschriften
btn1=SGUI_ButtonCreate(10,100,100,50);
SGUI_ButtonSetText(btn1,”Btn-1″);
// einen Handler fuer den Button einrichten
SGUI_ButtonSetHandler(btn1,btn1_fkt);
// Ein Image (aus dem Flash) Zeichnen
UB_Graphic_DrawImage(&Druck,50,50);
}
nein, das Bild (oder ein Text) wird immer wieder überschrieben bei redraw.
Man müsste ein neues Objekt “Picture” zu diesem Zweck erstellen.
Klingt nicht so schwer…besonders wenn es nur aus dem Flash gezeichnet werden muss…gib mir ein paar Tage.
Das wäre echt super wenn Du da etwas einbauen könntest.
Ein Bild aus dem Flash reicht voll und ganz.
Gruß
probier mal die Version 1.2 aus. Es gibt zwei neue Befehle
“CreatePicture” erstellt eine Picture-Objekt
“PictureSetImage” teilt ein Bild aus dem Flash zu.
Funktioniert super. Wäre toll wenn Du das bei Gelegenheit auch noch in die sgui Lib für den 407er integrieren könntest.
Gruß
theoretisch könnte man daraus auch einen “Button” machen. event. mit zwei gleich großen Bildern für die zwei Zustände.
Das wäre natürlich absolut perfekt. So könnte man z.B. ein Zahnrad Bild für einen Einstellungsbutton nutzen.
Wäre super wenn Du das einbauen könntest.
schon fertig (Versionsnummer hab ich nicht hochgezählt)
pro Picture können zwei Bilder definiert werden damit
man gedrückt/nicht gedrückt unterscheiden kann.
Super, konnte auf Anhieb einen Zahnrad Button erstellen.
Danke für die schnelle Umsetzung.
Kann ich die neuen Funktionen auch in die Lib für den 407er integrieren?
Gruß
die Version für den F407 ist auch schon fertig und online.
Top, vielen Dank.
Eine etwas spezifische Frage hätte ich jedoch noch.
Wie würdest Du vorgehen wenn Du ähnlich dem Oszi Show Projekt einen kleinen Graphen in ein Main Window plotten wolltest?
Gruß Joe
du kannst mit der Funktion “SGUI_ScreenDrawPixel(x,y,color)” beliebige
Kurven auf das Display zeichnen. Damit diese allerdings sichtbar bleibt,
muss das Window schon komplett gezeichnet sein.
Ich würde in der Main-Loop unterhalb der “SGUI_Do”
mit einem “if(SGUI_WindowGetActivNr()==oszi_page)”
prüfen ob die richtige Seite angezeigt wird und dann mit einer For-n
die Kurve plotten.
mir ist gerade eingefallen…natürlich könnte man auch ein Objekt daraus machen.
Wenn es nicht auf die Updategeschwindigkeit ankommt sondern nur um das darstellen von einem Zahlen-Array geht. Mehr wie 300 Punkte machen eh keinen Sinn (weil das Display nur 320 Pixel breit ist) und ein uint8 pro Wert würde theoretisch auch reichen.
Schreib mal was du genau vorhast und ob es eine statische Anzeige sein soll oder etwas das schnell refreshed werden muss.
Ich logge u.a. die Werte eines externen Temperatursensors minütlich auf eine SD Karte. Ich dachte es wäre dann nicht schlecht den Temperaturverlauf auf dem Display darstellen zu können.
Also schnell refreshed werden müsste es nicht, eher im Sekunden/Minutenbereich.
Gruß
Also die Werte wären dann wie von Dir schon geschrieben in einem Zahlenarray welches dann “nur” dargestellt werden müsste.
Gruß
ok, ich muss mal schauen wie man das am einfachsten implementieren kann.
Das wäre super, danke.
Gruß
ich habe mal eine Alpha hochgeladen (auf der Startseite) damit kannst du mal rumspielen. Die Grundfunktionen habe ich getestet. Das könnte man jetzt noch beliebig komplex machen (Grid, Y-Offset usw)
Super, werde ich mal testen.
Gruß
Hallo Uwe,
ich wollte mal eben schnell mit deiner Gui ein kleines Programm schreiben….
Jetzt bin ich gerade etwas Ratlos. Wie gebe ich einen sich ständig ändernden Wert als Text in einem Fenster aus?
Echt mal Hut ab, da hast du ein wirklich nettes Tool mal wieder geschrieben. Ich wünschte ich hätte so viel Zeit das selbst zu können
Grüße
Jörg
Da ist zwar dein Beispiel:
Beispiel-4 :
—————————————-
Wert von einer Zahl ändern
void foo(void) {
int a=12;
STEXT_t *txt;
SGUI_WindowCreateMain(1); // nr=1
SGUI_TextCreateString(“Messwert=”);
txt=SGUI_TextCreateInt(a,4,true); // mit 4 stellen mit führende Null
SGUI_TextCreateString(“mV”); Anzeige = “Messwert=0012mV”
a+=13;
SGUI_TextSetInt(txt, a); // neuen Zahlenwert darstellen
// Anzeige = “Messwert=0025mV”
}
Da wird der Wert ja aber in Foo geändert. Ich will / muss den Wert ja aus der while Schleife des Mains ändern
mach einfach den Pointer auf den Text “global”
Ok habs selbst raus bekommen… War mal wieder blind
Hallo Uwe,
an dieser Stelle möchte ich Dir ein dickes Lob aussprechen. Die SGUI ist genau das was ich gesucht habe.
LG Michael DD4MS
Hallo Uwe,
erstmal ein großes Dankeschön für deine Bibliotheken.
SGUI_FloatEditSetStyle funktioniert leider nicht mit STYLE_RAISED, es wird lowered angezeigt. Ich habe zwar hinbekommen, dass alle 3 Styles normal nutzbar sind, kommt mir aber ziemlich komisch vor. Vor allem weil ich unter anderem (ub_sgui_floatedit.c, Zeile 504)
if((ptr->status&SFLOATEDIT_BIT_3DSTYLE)==0) zu
if((ptr->status&SFLOATEDIT_BIT_3DSTYLE)!=0) ändern musste.
Bei der Listbox müsste dann, glaube ich, das selbe Problem sein. Vielleicht auch noch bei paar anderen. Ich bitte um Nachbesserung.
Schöne Grüße, Pavel
Hi,
I’m trying to understand how this library works, but I can’t find the definition of the UB_… functions like e.g. UB_Graphic2D_DrawPixelNormal. Where can I find them?
Thanks
sorry there is no english translation for the manual.
please download the complete project files from “Demo_F429_27″
So you have all necessary files included.
You find all my “lolevel” libs in sub-folder “ub_lib”
and the grafic-functions e.g.”UB_Graphic2D_DrawPixelNormal”
in the file “stm32_ub_graphic2d.c”.
dont hesitate to ask another question
Hello,
First I’d like to thank you for your amazing work, I downloaded the SGUI library and demo project for STM32F429 disc, and after setting up the project for the lite version of atollic, I noticed that all objects work as expected but the integer ones , only letters are displayed instead of values (Integer=d, Integer=5d etc, while it should be Integer=123, Integer=00123), is this related to your library?
PS: The coocox version is working out of the box
Thanks in advance
I fixed this, it’s because the Newlib-nano