Das schließt sich ja nicht gegenseitig aus. Man sollte beides machen. Auch wenn man nur bei Änderung aktualisiert sieht es immer noch schlecht aus wenn man ein Rechteck drüber malt
my_xy_projekt:
Das ist aber nicht Sinn der Übung.
Wenn du das meinst ?
Für mich ist Sinn der Übung, jeden erdenklichen Fehler auszuräumen.
Und irgendwo muss der TO ja anfangen.
Serenifly:
...sieht es immer noch schlecht aus wenn man ein Rechteck drüber malt
Bei einem Rechteck mag das noch gehen. Bei einem Sinus eher nicht.
Das mit der Reaktionszeit und dem menschlichen Auge war schon mal Thema. ![]()
maik_s:
Ich habe die Anzeige der Werte aus der Loop ausgelagert - nach ca.
1 Sekunde Refresh wird die Anzeige aktualisiert.
Wie ich schon anmerkte, finde ich die Sekundengeschichte nicht schick.
Das:
wno158:
So wie er da mit den Werten hantiert, bekommt er bei jedem Durchlauf einen (wenn auch nur geringfügig) anderen Messwert und dann schlägt der Vergleich mit den old_value immer fehl --> Display wird neu geschrieben.
brachte mich auf die Idee mal was eigenartiges zu basteln.
Der folgende Code ist ungetestet - ich hab weder den Display noch den Sensor bei.
Ich habe hier etwas gemacht, was ich sonst versuche zu vermeiden: In und für jedem Schritt wird eine weitere Variable benutzt.
Das aber nur, weil ich ermöglichen möchte (später) mit einer seriellen Ausgabe ggfls. zu debuggen und nachzusehen, was tatsächlich passiert.
Bitte mal probieren und vielleicht kann ja jemand nochmal drüber schaun, ob ich mich vertan habe.
// Forensketch - ungetestet
// basiert auf https://forum.arduino.cc/index.php?topic=729138.msg4905049#msg4905049
#include <INA219.h>
#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h> // include Adafruit graphics library
#include <Adafruit_ILI9341.h> // include Adafruit ILI9341 TFT library
#include <Fonts/FreeSerif24pt7b.h>
#include <Fonts/Seven_Segment30pt7b.h>
#define TFT_CS 14 // TFT CS pin is connected to arduino pin 8
#define TFT_RST 13 // TFT RST pin is connected to arduino pin 9
#define TFT_DC 12 // TFT DC pin is connected to arduino pin 10
// initialize ILI9341 TFT library
Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC, TFT_RST);
#define TFT_GREY 0x5AEB // New colour
#define TFT_Yellow 0xFFE0
#define TFT_AQUA 0x0000
#define TFT_GOLD 0xA508
#define TFT_SILVER 0xA510
/*
A few colour codes:
code color
#define ILI9341_BLACK 0x0000 ///< 0, 0, 0
#define ILI9341_NAVY 0x000F ///< 0, 0, 123
#define ILI9341_DARKGREEN 0x03E0 ///< 0, 125, 0
#define ILI9341_DARKCYAN 0x03EF ///< 0, 125, 123
#define ILI9341_MAROON 0x7800 ///< 123, 0, 0
#define ILI9341_PURPLE 0x780F ///< 123, 0, 123
#define ILI9341_OLIVE 0x7BE0 ///< 123, 125, 0
#define ILI9341_LIGHTGREY 0xC618 ///< 198, 195, 198
#define ILI9341_DARKGREY 0x7BEF ///< 123, 125, 123
#define ILI9341_BLUE 0x001F ///< 0, 0, 255
#define ILI9341_GREEN 0x07E0 ///< 0, 255, 0
#define ILI9341_CYAN 0x07FF ///< 0, 255, 255
#define ILI9341_RED 0xF800 ///< 255, 0, 0
#define ILI9341_MAGENTA 0xF81F ///< 255, 0, 255
#define ILI9341_YELLOW 0xFFE0 ///< 255, 255, 0
#define ILI9341_WHITE 0xFFFF ///< 255, 255, 255
#define ILI9341_ORANGE 0xFD20 ///< 255, 165, 0
#define ILI9341_GREENYELLOW 0xAFE5 ///< 173, 255, 41
#define ILI9341_PINK 0xFC18 ///< 255, 130, 198
*/
float shuntvoltage = 0.0;
float busvoltage = 0.0;
float current = 0.0;
float power = 0.0;
INA219 ina;
void setup(void)
{
// Default INA219 address is 0x40
ina.begin();
tft.begin();
tft.setRotation(1);
tft.fillScreen(ILI9341_BLACK);
tft.drawRect(0, 0, 320, 80, ILI9341_WHITE );
tft.drawRect(2, 2, 316, 76, ILI9341_WHITE );
tft.drawRect(0, 80, 320, 80, ILI9341_WHITE );
tft.drawRect(2, 82, 316, 76, ILI9341_WHITE );
tft.drawRect(0, 160, 320, 80, ILI9341_WHITE );
tft.drawRect(2, 162, 316, 76, ILI9341_WHITE );
tft.setTextColor( ILI9341_YELLOW);
tft.setFont(&FreeSerif24pt7b);
tft.setTextSize(1); // For double sized fonts
tft.setCursor(10, 50 );
tft.print("Volt:"); // show the new value busvoltage
tft.setCursor(10, 130 );
tft.print("Amp.:"); // show the new value current
tft.setCursor(10, 210 );
tft.print("Pow.:"); // show the new value power
// Configure INA219
ina.configure(INA219_RANGE_16V, INA219_GAIN_320MV, INA219_BUS_RES_12BIT, INA219_SHUNT_RES_12BIT_1S);
// Calibrate INA219. Rshunt = 0.1 ohm
ina.calibrate(0.10, 2);
}
void loop(void)
{
//Variablen festlegen
float busvalue = 0.0; // Zwischenvariable die berechnet wird
float curvalue = 0.0;
float powvalue = 0.0;
char busstr[8] = "\0"; // Zeichenkette für Wert
static char oldbusstr[8] = "\0"; // Zeichenkette zum zwischenspeichern und vergleichen
char current[8] = "\0";
static char oldcurstr[8] = "\0";
char powstr[8] = "\0";
static char oldpowstr[8] = "\0";
// Werte einlesen
busvoltage = ina.readBusVoltage();
current = ina.readShuntCurrent();
power = ina.readBusPower();
// berechnen
busvalue = (busvoltage * 1.025);
curvalue = (current * 1.11);
powvalue = (power * 1.105);
// umwandeln - wandelt float in Zeichenkette um, schneidet Nachkommastellen ab
dtostrf(busvalue, 6, 2, busstr); // float, Gesamtstellen, davon Nachkommastellen, string
strcat(busstr, " ");
dtostrf(curvalue, 6, 2, curstr);
strcat(curstr, " ");
dtostrf(powvalue, 6, 2, powstr);
strcat(powstr, " ");
// anzeigen
if (strcmp (busstr, oldbusstr) != 0) // vergleicht die Zeichenketten
{
tft.fillRect(160, 15, 115, 50, ILI9341_BLACK);
tft.setTextColor(ILI9341_GREEN);
tft.setFont(&Seven_Segment30pt7b);
tft.setTextSize(1); // For normal sized fonts
tft.setCursor(170, 60 );
tft.print(busstr); // gibt die Zeichenkette aus
strcpy(oldbusstr, busstr); // speichert die Zeichenkette für späteren Vergleich
}
if (strcmp (curstr, oldcurstr) != 0)
{
tft.fillRect(160, 95, 115, 50, ILI9341_BLACK);
tft.setTextColor( ILI9341_RED);
tft.setFont(&Seven_Segment30pt7b);
tft.setTextSize(1); // For normal sized fonts
tft.setCursor(170, 140 );
tft.print(curstr); // show the new value current
strcpy(oldcurstr, curstr);
}
if (strcmp (powstr, oldpowstr) != 0)
{
tft.fillRect(160, 175, 115, 50, ILI9341_BLACK);
tft.setTextColor(ILI9341_BLUE, ILI9341_BLACK);
tft.setFont(&Seven_Segment30pt7b);
tft.setTextSize(1); // For normal sized fonts
tft.setCursor(170, 220);
tft.print(powstr); // show the value new power
strcpy(oldpowstr, powstr);
}
}
Jetzt lässt du noch das Zeichnen des Rechtecks weg und dann passt es vielleicht. Wenn du schon den Text mit dtostrf() formatierst haben die alle die gleiche Breite. Wenn also mal eine Zahl kürzer ist als die vorherige wird der längere Teil mit einem Leerzeichen ersetzt
Wobei man da glaube ich diese Methode verwenden muss damit Zeichen richtig überschrieben werden:
void setTextColor(uint16_t c, uint16_t bg)
Und dann vielleicht den Hintergrund auf Schwarz setzen. Das wurde hier schon besprochen, aber selbst habe ich noch nicht mit Adafruit Displays gearbeitet
Serenifly:
Jetzt lässt du noch das Zeichnen des Rechtecks weg und dann passt es vielleicht.
Ah, gut zu wissen,das jemand tatsächlich draufgeschaut hat. Der code scheint also zu passen ![]()
Und dann vielleicht den Hintergrund auf Schwarz setzen. Das wurde hier schon besprochen, aber selbst habe ich noch nicht mit Adafruit Displays gearbeitet
Ich bin davon ausgegangen, das das Rechteck den Teil schwarz macht, damit sind die Zahlen gelöscht und dann die Zahlen neu schreibt.
Na mal sehn, was der TO so austestet.
Die Idee ist noch eigenartiger als meine (noch nur im Hinterkopf: abs(aktuell-alt)>schwelle).
Finde ich aber gelungen; das sollte so funktionieren.
Ob es effizient im Sinne von Laufzeit und RAM-Verbrauch ist sei mal dahingestellt, aber das ist ja die Verwendung von float auch nicht.
wno158:
Die Idee ist noch eigenartiger als meine
Finde ich aber gelungen;
![]()
Ob es effizient im Sinne von Laufzeit und RAM-Verbrauch ist sei mal dahingestellt, aber das ist ja die Verwendung von float auch nicht.
naja, vielleicht kann man ja die Vars runterbrechen. Alles was dann übrig bliebe:
char tmpstr[8] = "\0"; // Zeichenkette für Wert
static char oldbusstr[8] = "\0"; // Zeichenkette zum zwischenspeichern und vergleichen
static char oldcurstr[8] = "\0";
static char oldpowstr[8] = "\0";
// am Beispiel Busvoltage:
dtostrf(ina.readBusVoltage() * 1.025, 6, 2, tempstr);
Also nur eine temporäre Var und die vor dem Vergleich gefüllt
Und dann diese mit der static-var vergleichen. - Aber ist alles graue Theorie...
schwelle
das ist nicht ma so schwer, einfach mit den zwei NK-Stellen auf 0.01 vergleichen.
my_xy_projekt:
Ich bin davon ausgegangen, das das Rechteck den Teil schwarz macht, damit sind die Zahlen gelöscht und dann die Zahlen neu schreibt.
Das geht, aber es sieht nicht gut aus. Den Übergang sieht man sehr deutlich. Auch wenn man es nicht ständig macht. Einfach weil der Bereich erst mal Schwarz wird bevor der neue Text erscheint. Das resultiert auch in einer Art flimmern. Wenn man das nicht dauernd macht und nur bei Änderung ist das natürlich schon viel besser, aber richtig gut ist das immer noch nicht.
Vielen Dank an my_xy_projekt - Dein auf der schnelle geschriebener Code funktioniert.
Ich hatte erst heute wieder etwas Zeit gehabt um das zu testen und darüber nach zu denken.
Auf die Idee zwei Strings zu vergleichen bin ich nicht gekommen - mann lernt eben nie aus.
Wenn ich das richtig verstanden habe, wird bei float intern mit allen Nachkommastellen gerechnet.
Lediglich die Ausgabe auf den Display wird auf zwei Nachkommastellen abgeschnitten.
Daher auch das ständige Aktualisieren des angezeigten Wertes (incl. dem Flimmern).
Hier wurde auch erwähnt, dass man float zu int umwandeln sollte und das Ergebniss auf zwei Nachkommastellen
zu begrenzen (ich hoffe die Ausdrucksweise ist verständlich).
Ich habe noch das :
float u =((int) (value1*10)) / 10.0;
float i =((int) (value2*10)) / 10.0;
float p =((int) (value3*10)) / 10.0;
In den Code zusätzlich eingefügt.
"Gefühlt" wurde ich sagen, das die Anzeige noch etwas ruhiger geworden ist und nicht so
sensiebel auf Eingansspannungsänderungen reagiert.
Kann das möglich sein ?
Jetzt steht auch die Anzeige wie festgenagelt und kein zappeln oder flackern ist mehr vorhanden.
Nochmals danke an alle beteiligten - ich bin lernfähig aber mir fehlen eben noch sehr viel "Basics".
maik_s:
Dein auf der schnelle geschriebener Code funktioniert.
Boahh....
Na wenigstens eine Erfolgsmeldung heute ....
Wenn ich das richtig verstanden habe, wird bei float intern mit allen Nachkommastellen gerechnet.
Lediglich die Ausgabe auf den Display wird auf zwei Nachkommastellen abgeschnitten.
Ja.
Kann das möglich sein ?
Nochmals danke an alle beteiligten - ich bin lernfähig aber mir fehlen eben noch sehr viel "Basics".
- kann ich nicht aus dem stehgreif sagen
- Bitte. Nu noch ein [gelöst] im ersten Post von Dir in die Subject-Zeile reineditieren und schick isses.
2.1. Hähä! Was meinst Du wohl wem noch?
Danke fürs Feedback!
gelöst - ja.
Aber der eingefügte Code liefert nur eine signifikante Nachkommastelle. Das lässt sich leicht durch Nachrechnen zeigen:
Sei value1 = 123.456.
value1*10 = 1234.56 (ungefähr wg. float)
(int)1234.56 = 1234 (genau)
1234 / 10.0 = 123.4 (ungefähr wg. float)
Ob das jetzt der erwartete | erwünschte Wert ist - ich weiß nicht.
Wenn es zwei Stellen sein sollen:
float u =((int) (value1*100)) / 100.0;
Und die Alternative alles ganzzahlig zu rechnen und nur (wirklich nur) für die Ausgabe float zu verwenden gäbe es ja immer noch.
Man könnte auch ohne float Ganz- und Nachkommaanteil bestimmen und ausgeben.
Gruß Tommy
Yep.
Das Lästige daran wäre allerdings, dass man sich um das Einfügen evtl. führender Nullen im Nachkommaanteil selbst kümmern muß.
long value = 12304; // 123.04 (Zielwert)
long vorKomma = value / 100; // 123
long nachKomma = value - vorKomma; // 4
// und hier passt es beim print dann nicht mehr ohne Verrenkungen
wno158:
long value = 12304; // 123.04 (Zielwert)
long vorKomma = value / 100; // 123
long nachKomma = value - vorKomma; // 4
// und hier passt es beim print dann nicht mehr ohne Verrenkungen
Naja, was ist daran so schlimm, einfach zu prüfen, ob nachKomma < 10 ist und einfach zusätzlich eine 0 zu printen? Das geht bei der Anzeige der Uhr regelmäßig. ![]()
grad aus meinem letzten Code heraus:
void vornull(int i)
{
if (i<10) lcd.print("0");
}
Ist überhaupt nicht schlimm, nur etwas länger.
Wie immer: Viele Wege führen nach Rom
maik_s:
hier das fertige Netzteil in "Farbe" und Fertig.
Schick...
Im Code einfach prüfen, ob ampere vor dem Komma ein- oder zweistellig ist.
Wenn einstellig eine Leerstelle einfügen ![]()
Ich habe nur eine Stelle vor den Komma.
Das Netzteil geht bis ca. 12V bei max. 1,5A.
Für mich völlig ausreichend - da ist auch eine Frage der Auslegung des Trafos, Kühlkörper etc.
Die Zeiten von TTL Gräber sind vorbei ...
Das die Stellen "wandern" habe ich auch bemerkt - ich denke aber es liegt an den Font oder
auch an die Formatierung der Ausgabe auf den Displays.
Wenn das alles gleichmäßig aussehen soll, müsste ich alles auseinander dividieren und je nach
dargestellter Zahl die Position auf den Display anpassen ( eine 1 ist schmaler als die breite 8 ).
Aber soviel Aufwand wollte ich nicht treiben - oder geht das auch irgendwie "automatisch" ?
maik_s:
( eine 1 ist schmaler als die breite 8 ).
Sicher?
Stell mal 0.18 Volt ein. Die 0 bleibt an der Stelle unverändert?
Aber soviel Aufwand wollte ich nicht treiben - oder geht das auch irgendwie "automatisch" ?
Das wird sich dann zeigen. Wenn die 0 nicht wandert ist es einfach - Code aus #23?
