Onderdrukking flikker bij TFT display

blackdog

Golden Member

Hi,

Wat info voor een redelijk beeld waarmee ik bezig ben
Er lopen hier nog twee projectjes waar ik al lang geleden al eens mee was gestart maar door problemen was ik er mee gestopt.
Het gaat om twee meetkastjes waarop meerdere NTC kunen worden aangesloten, één kastje zal 8 aansluitingen hebben en de tweede vier NTC thermistors.
Het gebruik zal onderling wat anders zijn, de gene met 4x een NTC thermistor zal wneller moeten reageren dan de gene waar ik uiteindelijk de vraag over ga stelen, die doet alleen trage metingen.

Hieronder staat een plaatje dat ik gisteren en vandaag aan het indelen ben geweest, deze heeft dus acht meet ingangen en datum en tijd notatie, maar ook Lucht vochtigheid en luchtdruk.
Alle aangegeven waarde gaan uiteindelijk op een manier het lokale netwerk op en/of op een geheugen kaartje.
Misschien ook via USB naar een meetcomputer, Miedema wees mij vorige week op wat software die via USB kan loggen.

Nu het plaatje en dan de vraag, de indeling is nog niet optimaal, maar zeg 90% is al OK.
Een deel van de tekst wordt in de setup op het scherm geschreven, maar ik heb nog niet alles wat statisch, is naar het setup stukje verplaatst.
Het op het plaatje is het wegvallen de oorzaak van aliassing.
https://www.bramcam.nl/NA/8x-NTC-Logger/8x-NTC-Logger-01.png

.
Op dit plaatje is goed te zien dat vooral de onderste twee regels het een en ander niet goed gaat.
Om Ghosting tegen te gaan overschrijf ik de variabe waarden zoals de tijd met een zwart kader die de oude waarde wist, dat werkt verder goed om Ghosting te onderdrukken.

Als we de LAB temepratuur nemen die hier als 20.91 wordt aangegeven dan kan ik vrij makkelijk controleren of deze variabel is veranderd, zo ja, dan kan deze waarde worden ververst.
Nemen we nu de datum en de tijd waarde, die variabelen kan ik volgens mij niet zomaar vergelijken ondat deze variabeleen speciale karakters in zich hebben, dit zijn het streepje - en de dubbele punt :

De Hum en de hPa kan ik zonder problemen oplossen en die veranderen ook niet zo veel, dit net als de uiteindelijke waarde die van de NTC thermistors komen voor de acht kanalen.

Nog wat info, de controler wordt een Teense of een b.v. een ESP32, moet ik nog beslissen, vooral om het deel van het loggen, via WiFi doen of geheugenkaartje.
De ADC die ik ga gebruikej heb ik wel al bepaald en dat wordt de ADS1115, ik leg nu nog even niet uit waarom, dat komt in een apart topic voor deze meetkastjes.

Hier de code, zeg versie V0.1 de hele ADC zit er nog niet in verwerkt en ook het loggen nog niet.

c code:


/***************************************************
  Adafruit invests time and resources providing this open source code,
  please support Adafruit and open-source hardware by purchasing
  products from Adafruit!

  Written by Limor Fried/Ladyada for Adafruit Industries.
  MIT license, all text above must be included in any redistribution
 ****************************************************/

#include <Adafruit_GFX.h>    // Core graphics library
#include <Adafruit_ST7735.h> // Hardware-specific library for ST7735
#include <SPI.h>
#include "RTClib.h"
#include <Adafruit_Sensor.h>
#include <Adafruit_BME280.h>

RTC_DS3231 rtc;

Adafruit_BME280 bme; // I2C
unsigned long delayTime;


// Extra SPI pin configuratie
  #define TFT_CS        10
  #define TFT_RST        8 
  #define TFT_DC         9

  // For 1.44" and 1.8" TFT with ST7735 (including HalloWing) use:
  Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS, TFT_DC, TFT_RST);
    


void setup(void) {
  Serial.begin(9600);

  bme.begin(0x76, &Wire);

  rtc.begin();

  tft.initR(INITR_144GREENTAB);       // initialize a ST7735S chip, green tab
  tft.setTextWrap(false);             // Allow text to run off right edge
  tft.fillScreen(ST77XX_BLACK);
  tft.setSPISpeed(40000000);
  tft.setRotation(3);

// BME280 Sensor settings
    bme.setSampling(Adafruit_BME280::MODE_NORMAL,
                    Adafruit_BME280::SAMPLING_X2,  // temperature
                    Adafruit_BME280::SAMPLING_X16, // pressure
                    Adafruit_BME280::SAMPLING_X1,  // humidity
                    Adafruit_BME280::FILTER_X16,
                    Adafruit_BME280::STANDBY_MS_0_5 );

  
// vaste waarden op het display
    tft.fillScreen(ST77XX_BLACK);
    tft.setCursor(5, 3);
    tft.setTextSize(1);
    tft.setTextColor(ST77XX_CYAN);
    tft.print("Sensor-1 = ");


    tft.setCursor(5, 14);
    tft.setTextSize(1);
    tft.setTextColor(ST77XX_RED);
    tft.print("Sensor-2 = ");


    tft.setCursor(5, 25);
    tft.setTextSize(1);
    tft.setTextColor(ST77XX_GREEN);
    tft.print("Sensor-3 = ");

    tft.setCursor(5, 36);
    tft.setTextSize(1);
    tft.setTextColor(ST77XX_YELLOW);
    tft.print("Sensor-4 = ");


    tft.setCursor(5, 47);
    tft.setTextSize(1);
    tft.setTextColor(ST77XX_CYAN);
    tft.print("Sensor-5 = ");


    tft.setCursor(5, 58);
    tft.setTextSize(1);
    tft.setTextColor(ST77XX_RED);
    tft.print("Sensor-6 = ");
    // Plaats het C karakter met punt op het display
    tft.fillRect(103, 56, 2, 2, ST77XX_RED);       // Graden circeltje
    tft.setCursor(107, 56);
    tft.print("C");                                   // "C" van de graden eenheid



    tft.setCursor(5, 69);
    tft.setTextSize(1);
    tft.setTextColor(ST77XX_GREEN);
    tft.print("Sensor-7 = ");


    tft.setCursor(5, 80);
    tft.setTextSize(1);
    tft.setTextColor(ST77XX_YELLOW);
    tft.print("Sensor-8 = ");
    
    tft.setCursor(5, 92);
    tft.setTextSize(1);
    tft.setTextColor(ST77XX_GREEN);
    tft.print("Hum:100%");

    tft.setCursor(65, 92);
    tft.setTextSize(1);
    tft.setTextColor(ST77XX_GREEN);
    tft.print("hPa: 1004");

    tft.setCursor(5, 118);
    tft.setTextSize(1);
    tft.setTextColor(ST77XX_GREEN);
    tft.print("LAB Temp = ");
    tft.setCursor(1, 111);
    // Plaats het C karakter met punt op het display
    tft.fillRect(107, 118, 2, 2, ST77XX_GREEN);       // Graden circeltje
    tft.setCursor(110, 118);
    tft.print("C");                                   // "C" van de graden eenheid



// Teken kader en lijnen
    tft.drawRect(0, 0, 128, 128, ST77XX_CYAN);
    tft.drawFastHLine(0, 89, 128, ST77XX_CYAN);
    tft.drawFastHLine(0, 101, 128, ST77XX_CYAN);
    tft.drawFastHLine(0, 115, 128, ST77XX_CYAN);
}



void loop(void) {

    DateTime time = rtc.now();


    tft.setCursor(70, 56);
    tft.setTextSize(1);
    tft.setTextColor(ST77XX_RED);
    tft.print("103,2");

    tft.setCursor(70, 67);
    tft.setTextSize(1);
    tft.setTextColor(ST77XX_GREEN);
    tft.print("Blah");

    tft.setCursor(70, 78);
    tft.setTextSize(1);
    tft.setTextColor(ST77XX_YELLOW);
    tft.print("xxxxxxx");

    // Overschrijf met zwart vierkant de oude datum en daarna de nieuwe datum op het scherm vanuit de DS3231 klok
    tft.fillRect(4, 104, 60, 9, ST77XX_BLACK);
    tft.setCursor(5, 105);
    tft.setTextSize(1);
    tft.setTextColor(ST77XX_GREEN);
    tft.print(time.timestamp(DateTime::TIMESTAMP_DATE));


    // Overschrijf met zwart vierkant de oude tijd en daarna de nieuwe tijd op het scherm vanuit de DS3231 klok
    tft.fillRect(74, 104, 49, 9, ST77XX_BLACK);
    tft.setCursor(75, 105);
    tft.setTextSize(1);
    tft.setTextColor(ST77XX_GREEN);
    tft.print(time.timestamp(DateTime::TIMESTAMP_TIME));


    // Overschrijf eerst met een zwart vierkant de oude temperatuur en daarna de nieuwe temperatuur uit de BME280 sensor
    tft.fillRect(74, 117, 31, 9, ST77XX_BLACK);
    tft.setCursor(75, 118);
    tft.setTextSize(1);
    tft.setTextColor(ST77XX_GREEN);
    tft.print(bme.readTemperature());

//  tft.fillRect(Begin Links Boven, Start Vanaf Boven, Lengte Kader, Hoogte Kader, ST77XX_CYAN);

 //   delay(50);
}

De vraag
Dus hoe los ik het flikkeren op, dat is de vraag, ik dacht dus de laatste waarde met de nieuwe waarde te vergelijken en dan alleen de waarde te updaten.
In de code is te zien dat ik het meeste Adafruit library's gebruik.
Het display is een 128x128 model 1.44-Inch SPI display.

Er staat mij iets bij dat er een font is die altijd de zelfde "real estate" of misschien in Nederlands de totale pixel ruimte, dus een 1 en een 8 nemen evenveel ruimte in.
Heb ik dat goed onthouden?

Hoe zouden jullie dit aanpakken om de flikkering te onderdrukken?
Bij de 8-kanaals versie denk ik aan 1 a 2 per seconde het updaten van de waarde en bij de tweede versie die meer 4 kanalen krijgt aan zeg 4x per seconde updaten voor de gemeten temperaturen.

Dank alvast weer voor de inzichten.

Groet,
Bram

You have your way. I have my way. As for the right way, the correct way, and the only way, it does not exist.

Als je een STRING hebt als "19:53:06" dan kan je die met "strcmp" vergelijken met de oude waarde en herschrijven als ze verschillend zijn (strcmp (oud, nieuw) geeft dan een waarde != 0).

De chip die het LCD bestuurt heeft een framebuffer die alle pixels kan bevatten die de chip OOIT aan kan sturen. Als deze chip ook 240*160 kan aansturen dan heeft ie 2x meer pixel-opslag dan wat er nodig is voor de 128*128. Dan zou je mogelijk de boel kunnen intialiseren zodanig dat je kan dubbelbufferen. (je initialseert dan een framebuffer van 128*256 en zet TOP=0 of TOP=128. Of de Adafruit lib daar voorzieningen voor heeft weet ik niet. De hardware kan het waarschijnlijk wel. ...

four NANDS do make a NOR . Kijk ook eens in onze shop: http://www.bitwizard.nl/shop/

Ik moest even spitten in die library van Adafruit.

Probleem is

code:


    tft.setTextColor(ST77XX_CYAN);

Die funktie zet zowel de text kleur als de achtergrond kleur op dezelfde waarde (CYAN). De text funktie test daarop en dan tekent die alleen de tekst, en laat de achtergrond ongemoeid.

Je kunt met diezelfde funktie ook 2 kleuren opgeven. Dan hoeft je niet meer eerst een zwarte achtergrond te tekenen ( dus met tft.fillrect(..) ), want de text funktie tekent dan zowel de letters als ook de bijbehorende achtergrond:

code:


   tft.setTextColor(ST77XX_CYAN, ST77XX_BLACK);
blackdog

Golden Member

Hi,

Ik was al bezig rew zijn opmerkingen uit te zoeken toen deKees zijn post binnen kwam en BINGO het flikkeren is over.
De zwarte blokjes die ik schijf zijn nu uit de code verwijderd en het flikkert niet meer!

Waarschijnlijk ga ik de opmerking van rew nog wel voor een deel gebruiken als ik de code niet snel genoeg loopt in de loop en ik doel dan op "strcmp" voor stukjes die echt weinig veranderen.

Ik gebruik nu een Teensy 3.2 dat een vrij krachtige controller is, dus ik denk dat het wel goed komt hiermee.
Maar het blijven 8 ADC's die ik moet gaan uitlezen en een beetje middelen, dat loopt bij elkaar wel een beetje op.
Gelukkig kan ik veel middelen aan de ADS1115 over laten, testen hiermee zullen uitmaken hoeveel middeling er nodig is.
Natuurlijk voor ieder van de acht ingangen is er ook een temperatuur conversie nodig met wat smooting.

Dat komt allemaal komende week, ik ben nu al blij dat het in de basis simpel is opgelost, met minder code en alleen een tweede kleur bij de tekst toevoegen, toppy!

Dank beide,
Bram

You have your way. I have my way. As for the right way, the correct way, and the only way, it does not exist.
buckfast_beekeeper

Golden Member

Op 12 maart 2023 21:42:09 schreef deKees:
[...]

Je kunt met diezelfde funktie ook 2 kleuren opgeven. Dan hoeft je niet meer eerst een zwarte achtergrond te tekenen ( dus met tft.fillrect(..) ), want de text funktie tekent dan zowel de letters als ook de bijbehorende achtergrond:

code:


   tft.setTextColor(ST77XX_CYAN, ST77XX_BLACK);

Wees er je wel van bewust dat dit NIET lukt met elke font. Zo lang de geschreven waarde niet wijzigt, geen probleem. Maar bijvoorbeeld bij seconden krijg je dan al snel een vierkantje of je moet inderdaad een zwarte rechthoek tekenen. Maar die neemt meer tijd in beslag.

De time.h librarie en vele andere tijd gerelateerde librarie hebben eenvoudige functies om weekdag, dag van de maand, maand, jaar, uur, minuten en seconden op te vragen. Numerieke variabelen vergelijken gaat een stuk sneller dan een string die letter per letter wordt gecontroleerd.

strcmp is niet de meest zekere functie. Letter per letter wordt er naar de ascii waarde gekeken. str.equalsIgnoreCase(str2) heeft dat probleem niet. Het hangt er vanaf wat je wil beogen. Correcte tekst of correct geschreven. Uiteraard kan je ook eerst de string naar upper of lower case converteren. Als je strings kan vermijden, doe het.

c code:


String str1 = "Tekst"
String str2 = "tekst"
str1==str2 = fout
str1.equalsIgnoreCase(str2) = waar

Dit werkt altijd.

c code:


tft.setTextColor(backcolor)
tft.print(oudeTekst)
tft.setTextColor(tekstColor)
tft.print(nieuweTekst);
oudeTekst = nieuweTekst

Edit: bij datum en tijd wijzig ik alleen wat moet gewijzigd worden. Datum om middernacht. Uur elk nieuw uur, .... Zo schrijf je niet overbodig naar het display.

Edit 2: heb je een reden waarom je 103,2°C, blah en xxxxx 2 pixels hoger plaatst dan de tekst ervoor? Ook inconsistentie in je weergave 103,2°C en onderaan 20.91°C.

@hardbass hier onder: Elke library heeft voor en nadelen. Zelf gebruik ik zeer veel de Bodmer TFT_eSPI library. Met ESP32 of beter kan je mooi smoothed fonts gebruiken.

Van Lambiek wordt goede geuze gemaakt.

Als je toch een teensy of esp pakt, zou je ook kunnen gaan voor een library zoals LVGL. Dan hoef je je over dat soort dingen geen zorgen meer te maken.

Ook fijn als je later nog eens wat met touchscreens zou willen werken.

PE2BAS
blackdog

Golden Member

Hi,

Kijk eens aan nog meer input! ;)

hardbass
Ik ga uitzoeken wat LVGL is, voorals nog is het Japans voor me.

buckfast_beekeeper
Ook jouw opmerkingen ga ik doornemen, dat van de datum had ik al besloten dat te doen wanneer nodig.

Wat betreft de tekst van de klok, ik zal het eens proberen.

En hoeveel de pixels bepaalde tekst links/rechts en boven/onder staat hangt af hoe mijn pet staat tijdens het inddelen en het testen van de code.
De indeling is al weer drie keer veranderd, b.v. gisteren heb ik omdat ik wat ruimte had vrijgemaakt Hum: vervangen door Humidity: dat paste goed op het display,
maar maakte het er niet duidelijker op, dus vanmiddag als ik weer wat tijd heb, gaat dat stukje tekst weer terug naar Hum:

Als ik weer wat aanpassingen heb gedaan zal ik een nieuw plaatje laten zien en dan staat alle tekst recht op een lijn.

Wat betreft de resoluties van de weergegeven temperaturen, die zullen niet allemaal de zelfde opmaak hebben.
De acht sensoren zullen niet meer dan één cijfer achter de komma krijgen, dat is alleen om te kunnen zien of er drift is en welke kant het op gaat.
1 graad is verder voor de acht kanaals versie voldoende om er mee te kunnen werken, ook de precisie is in princiepe daar met één graad voldoende.

Het een en ander probeer ik zo goed mogelijk uit te leggen in het topic dat voor dit meetinstrumenje op CO komt.

Beide weer dank voor de input, de input resulteerd bij mij steeds meer enthousiasme bij het maken van de code omdat het zo lekker leert.

Groet,
Bram

PS
Voor iets dat ik misschien ga doen in de code, wordt het hele scherm gewist, daarna wil ik de standaard tekst en lijnen weer terug hebben.
Is er een mogelijkheid om vanuit de loop de "Setup" weer te runnen, zodat ik de basis weer op beeld krijg?
Of is daar een betere manier voor?

You have your way. I have my way. As for the right way, the correct way, and the only way, it does not exist.
miedema

Golden Member

Is er een mogelijkheid om vanuit de loop de "Setup" weer te runnen, zodat ik de basis weer op beeld krijg?
Of is daar een betere manier voor?

Ha Blackdog :-)

Als er in je "Setup" een blokje code staat dat je later weer wilt aanroepen, zet dat blokje code dan in een aparte procedure.
Dan kun je die procedure aanroepen vanuit "Setup", maar ook later, elke keer dat je dat blokje code weer nodig hebt.

groet! Gertjan.

Wat betreft LVGL, kijk hier eens naar: https://learn.adafruit.com/using-littlevgl-with-adafruit-displays?view…

In principe kan je de setup aanroepen wanneer je wilt, alleen dit zou ik afraden. De setup is hier namelijk niet voor bedoeld. Ik zou het zo doen:

c code:




void DrawScreenLayout()
{
	
}

void DrawScreenValues()
{

}

void Setup()
{
	//Init screen
	//Init ...
	DrawScreenLayout();
}


void Loop()
{
	//Do something...
	DrawScreenLayout();
	DrawScreenValues();
}

[Bericht gewijzigd door hardbass op maandag 13 maart 2023 10:45:10 (13%)

PE2BAS

setup() is -net als loop()- een gewone functie net als alle andere die je kunt aanroepen wanneer je wilt. Het enige speciale is dat die door de arduino library automatisch wordt aangeroepen bij opstarten.

Ergens diep in de Arduino library zit de standaard main() funktie, iets als :

code:


int main()
{  setup();
   for(;;)
   { loop();
   }
}

Maar waarschijnlijk wil je niet alles herhalen wat daar gebeurt. Dus dan kun je inderdaad beter een functie maken met dat deel dat je wilt herhalen.

buckfast_beekeeper

Golden Member

Mijn docent Java zei altijd, als je iets meer als 2 keer wil doen, gooi het in een functie (geeft een waarde terug) of procedure.

Nog toevoegen dat de tekst op het klok display gemaakt is met 1 font. Het scherm werd gemaakt met een screengrabber functie van Bodmer. Je hebt dan geen last van flikkering zoals je wel hebt met een fototoestel. Elke pixel wordt opgevraagd van het display. MOSI dient dus wel gebruikt.

Van Lambiek wordt goede geuze gemaakt.
blackdog

Golden Member

Hi,

Ik heb nog een foto gemaakt van het display om nog wat test te doen met de opmaak.
Alles staat nu op de goede regel hoogte maar nog niet alles is zoals ik het hebben wil.
https://www.bramcam.nl/NA/8x-NTC-Logger/8x-NTC-Logger-02.png

.
Ik heb net geexperimenteerd met het weg halen van de rode kleur in de tekst, want deze wil ik gebruiken voor de errors, zoals een kortgesloten of open NTC.
Dus toen dacht ik MAGENTA daar voor te gebruiken en op de foto is ook te zien dat dit niet echt mooi is.

Dus dat wordt nog wat spelen met verschillende kleuren, vanavond heb ik wat tijd om jullie info en hints door te nemen.

Groet,
Bram

You have your way. I have my way. As for the right way, the correct way, and the only way, it does not exist.

Een kleine tip voor de kleuren: https://color.adobe.com/create/color-wheel
Daar kan je kleur combinaties kiezen die goed bij elkaar passen.

Wat ook handig is, google op de woorden "distinctive color palette" en ga dan naar plaatjes. Dan vind je kleuren die allemaal uniek genoeg zijn om van elkaar te onderscheiden. Dit gebruik ik vaak voor grafieken met meerdere lijnen.

PE2BAS
blackdog

Golden Member

Hi,

Als eerste dit, hardbass dank voor de links, ik heb met de pagina's gespeeld en het een en ander overlegd met mijn vriendin. :-)
Zij is fotografe en houd zich ook regelmatig bezig met kleurbeheer, goede combinaties enz. en ik heb nu een boekje hierover naast me liggen.

Ok, ik heb niet zoveel tijd gehad, lange dagen met werk e.d. vandaar wat weinig output betreffende dit project.
Maar wel nog wat stappen kunnen doen, hieronder b.v. een plaatje waarop zichtbaar is dat ik nu ook een iets groter scherm gebruik,
misschien moet het dan toch ook een iets groter kastje worden.

Maar er is een rede voor dit schermpje welke 1,54 Inch groot is en het heeft een resolutie van 240x240 pixels, het merk van dit display is Waveshare.
Op het oog kan ik de tekst mooier plaatsen en wat voor mij belangrijk is, is dat als je van de basis kleuren afwijkt, de weergave van dit schermpje beter is.
Ook de iets grotere weergave van de tekst is aardig voor mijn ogen. :)

De gekozen kleuren liggen nog niet vast, wel de rode kleur van de Error melding.
De foto doet niet echt recht aan de kwaliteit van het grotere display, ik heb vijf foto's genomen, maar ik krijg het niet echt mooi vastgelegd.
Is ook niet zo vreemd, de aansluit bedrading voelt aan als verenstaal. :+
https://www.bramcam.nl/NA/8x-NTC-Logger/8x-NTC-Logger-03.png

.
De error meldingen zijn verschillend en voor nu alleen hard gecodeerd om te zien hoe het er uit ziet.
Voor nu betekenen de Error melding dit.
Error O = Te hoge temperatuur dus Over range
Error U = Te lage temperatuur dus Under range
Error W = Bedrading fout van de NTC sensor dus open of kortgesloten

Under range zal worden gemeld als de temperatuur lager is dan 10C waarschijnlijk komt de limit rond de 8C te liggen.
Over range zal worden gemeld als de temperatuur hoger is dan 110C waarschijnlijk tegen de 115C.

Ik wil met dit meetinstrumentje dat ik goed kan meten tussen de 15 en 100°C.
De echte waarden die het gaan worden, hangt van de NTC waarde af, de Referentie spanning die ik ga gebruiken voor de Pull Up weerstand en de range van de ADC.
Ik heb voor de ADS1115 gekozen, deze heb ik hier liggen en heeft een resolutie als je ze unipolaire gebruikt van 15-Bit.
En bij een gebruik van een 5V referentie spanning en een ingang schaal van de ADS1115 van +-2,048V, dan hou ik een redelijk stuk van die 15-Bit resolutie beschikbaar.
Ik ga hier nog meer aan rekenen en zal later laten zien wat het geworden is.
Deze week zijn van Mitsubishi meerdere NTC waarden binnen gekomen, welke 10K 50K en 100K zijn.
Mooi dat was het analoge deel waar ik mee bezig ben geweest.

De code

Ondertussen krijg ik bijna ieder type schermpje wat ik heb beeld op, i2c schermpjes was al geen probleem meer, maar SPI had ik duidelijk meer moeite mee.
Iedere keer noemen die Apen de pennen anders, ik heb wat notities gemaakt wat waar meestal op komt, mooi dan heb je dat gehad, maar in de code moet het ook nog goed staan.
Ook daar heb ik bij de Adafruit Library nu notities voor gemaakt, dit had ik natuurlijk veel eerder moeten doen!
Dat is nu onder de knie en de volgende stap is het gene waar jullie mij op wezen i.v.m. met mijn vraag dat ik waarschijnlijk een groot deel van het scherm
opnieuw wil plaatsen, dus de standaard karakters en de lijnen en kaders.

De eerste stap is gelukt, ik heb groter stukken code in een functie geplakt, die onder de Loop gezet en ik roep die functie nu alleen nog aan in de setup.
Misschien morgen teken ik voor een bepaald menu item iets anders op het scherm die ik dan ook in een functie daarvoor hang, zodat ik makkelijk kan omschakelen.

In de onderstaande code is nog geen ADC te bekennen, dat komt later, eerst de interface onder de knie krijgen.

c code:


/*
 * This is an example sketch that shows how to toggle the display
 * on and off at runtime to avoid screen burn-in.
 * 
 * The sketch also demonstrates how to erase a previous value by re-drawing the 
 * older value in the screen background color prior to writing a new value in
 * the same location. This avoids the need to call fillScreen() to erase the
 * entire screen followed by a complete redraw of screen contents.
 * 
 * Originally written by Phill Kelley. BSD license.
 * Adapted for ST77xx by Melissa LeBlanc-Williams
 */

#include <Adafruit_GFX.h>    // Core graphics library
#include <Adafruit_ST7789.h> // Hardware-specific library for ST7789
#include <SPI.h>
#include "RTClib.h"
#include <Adafruit_Sensor.h>
#include <Adafruit_BME280.h>

RTC_DS3231 rtc;

Adafruit_BME280 bme; // I2C
unsigned long delayTime;

  #define TFT_CS        10
  #define TFT_RST        8
  #define TFT_DC         9

  // For 1.3", 1.54", and 2.0" TFT with ST7789:
  Adafruit_ST7789 tft = Adafruit_ST7789(TFT_CS, TFT_DC, TFT_RST);


void setup() {
    
  tft.init(240, 240);           // Init ST7789 240x240
  tft.fillScreen(ST77XX_BLACK);
  tft.setRotation(3);
  tft.setSPISpeed(40000000);

  bme.begin(0x76, &Wire);

  rtc.begin();

// BME280 Sensor settings
    bme.setSampling(Adafruit_BME280::MODE_NORMAL,
                    Adafruit_BME280::SAMPLING_X16,  // temperature
                    Adafruit_BME280::SAMPLING_X16, // pressure
                    Adafruit_BME280::SAMPLING_X16,  // humidity
                    Adafruit_BME280::FILTER_X16,
                    Adafruit_BME280::STANDBY_MS_0_5 );


// Deze functie plaatst de basis lijnen en karakters op het scherm
    Basic_Screen_Setup();
// Deze functie plaatst de basis lijnen en karakters op het scherm

}


void loop() {
    DateTime time = rtc.now();


    tft.setCursor(135, 5);
    tft.setTextSize(2);
    tft.setTextColor(ST77XX_RED, ST77XX_BLACK);
    tft.print("ERROR O ");
    
    tft.setCursor(135, 25);
    tft.setTextSize(2);
    tft.setTextColor(ST77XX_GREEN, ST77XX_BLACK);
    tft.print("103.5");

    tft.setCursor(135, 45);
    tft.setTextSize(2);
    tft.setTextColor(ST77XX_RED, ST77XX_BLACK);
    tft.print("ERROR W ");

    tft.setCursor(135, 65);
    tft.setTextSize(2);
    tft.setTextColor(ST77XX_YELLOW, ST77XX_BLACK);
    tft.print("101,8");

    tft.setCursor(135, 85);
    tft.setTextSize(2);
    tft.setTextColor(ST77XX_WHITE, ST77XX_BLACK);
    tft.print("23,6");

    tft.setCursor(135, 105);
    tft.setTextSize(2);
    tft.setTextColor(ST77XX_GREEN, ST77XX_BLACK);
    tft.print("45,9");

    tft.setCursor(135, 125);
    tft.setTextSize(2);
    tft.setTextColor(0xCB5F, ST77XX_BLACK);
    tft.print("45,6");

    tft.setCursor(135, 145);
    tft.setTextSize(2);
    tft.setTextColor(ST77XX_RED, ST77XX_BLACK);
    tft.print("ERROR U ");


    // Plaast de nieuwe datum op het scherm vanuit de DS3231 klok
    tft.setCursor(7, 196);
    tft.setTextSize(2);
    tft.setTextColor(ST77XX_GREEN, ST77XX_BLACK);
    tft.print(time.timestamp(DateTime::TIMESTAMP_DATE));


    // Plaast de nieuwe tijd op het scherm vanuit de DS3231 klok
    tft.setCursor(138, 196);
    tft.setTextSize(2);
    tft.setTextColor(ST77XX_GREEN, ST77XX_BLACK);
    tft.print(time.timestamp(DateTime::TIMESTAMP_TIME));


// onderstaande code wordt iedere twee seconde ververst.    



    
    // plaast de nieuwe luchdruk uit de BME280 sensor op het scherm, iedere 2 seconde
    tft.setCursor(55, 170);
    tft.setTextSize(2);
    tft.setTextColor(ST77XX_GREEN, ST77XX_BLACK);
    tft.print(bme.readHumidity(), 0);  

    // plaast de nieuwe vochtigheids graad uit de BME280 sensor op het scherm, iedere 2 seconde
    tft.setCursor(162, 170);
    tft.setTextSize(2);
    tft.setTextColor(ST77XX_GREEN, ST77XX_BLACK);
    tft.print(bme.readPressure()/100,1);  
        
    // plaast de nieuwe temperatuur uit de BME280 sensor op het scherm, iedere 2 seconde
    tft.setCursor(138, 221);
    tft.setTextSize(2);
    tft.setTextColor(ST77XX_GREEN, ST77XX_BLACK);
    tft.print(bme.readTemperature());

//  Volgorde coordinaten rechthoek en de kleur
//  tft.fillRect(Begin Links Boven, Start Vanaf Boven, Lengte Kader, Hoogte Kader, ST77XX_WHITE);
}


void Basic_Screen_Setup() {

// Plaatst vaste waarden op het display
    tft.fillScreen(ST77XX_BLACK);
    tft.setCursor(7, 5);
    tft.setTextSize(2);
    tft.setTextColor(0xD7FE);
    tft.print("Sensor-1 = ");
    tft.fillRect(206, 6, 4, 4, 0xD7FE);                 // Graden circeltje
    tft.setCursor(215, 5);
    tft.print("C");                                     // "C" van de graden eenheid

    tft.setCursor(7, 25);
    tft.setTextSize(2);
    tft.setTextColor(ST77XX_GREEN);
    tft.print("Sensor-2 = ");
    tft.fillRect(206, 26, 4, 4, ST77XX_GREEN);          // Graden circeltje
    tft.setCursor(215, 25);
    tft.print("C");                                     // "C" van de graden eenheid

    tft.setCursor(7, 45);
    tft.setTextSize(2);
    tft.setTextColor(0xCB5F);
    tft.print("Sensor-3 = ");
    tft.fillRect(206, 46, 4, 4, 0xCB5F);                // Graden circeltje
    tft.setCursor(215, 45);
    tft.print("C");                                     // "C" van de graden eenheid

    tft.setCursor(7, 65);
    tft.setTextSize(2);
    tft.setTextColor(ST77XX_YELLOW);
    tft.print("Sensor-4 = ");
    tft.fillRect(206, 66, 4, 4, ST77XX_YELLOW);         // Graden circeltje
    tft.setCursor(215, 65);
    tft.print("C");                                     // "C" van de graden eenheid


    tft.setCursor(7, 85);
    tft.setTextSize(2);
    tft.setTextColor(0xD7FE);
    tft.print("Sensor-5 = ");
    tft.fillRect(206, 86, 4, 4, 0xD7FE);                // Graden circeltje
    tft.setCursor(215, 85);
    tft.print("C");                                     // "C" van de graden eenheid

    tft.setCursor(7, 105);
    tft.setTextSize(2);
    tft.setTextColor(ST77XX_GREEN);
    tft.print("Sensor-6 = ");
    tft.fillRect(206, 106, 4, 4, 0xCB5F);               // Graden circeltje
    tft.setCursor(215, 105);
    tft.print("C");                                     // "C" van de graden eenheid

    tft.setCursor(7, 125);
    tft.setTextSize(2);
    tft.setTextColor(0xCB5F);
    tft.print("Sensor-7 = ");
    tft.fillRect(206, 126, 4, 4, 0xCB5F);               // Graden circeltje
    tft.setCursor(215, 125);
    tft.print("C");                                     // "C" van de graden eenheid

    tft.setCursor(7, 145);
    tft.setTextSize(2);
    tft.setTextColor(ST77XX_YELLOW);
    tft.print("Sensor-8 = ");
    tft.fillRect(206, 146, 4, 4, ST77XX_YELLOW);        // Graden circeltje
    tft.setCursor(215, 145);
    tft.print("C");                                     // "C" van de graden eenheid
    
//-----------------------------------------------

    
    tft.setCursor(7, 170);
    tft.setTextSize(2);
    tft.setTextColor(ST77XX_GREEN);
    tft.print("Hum:");
    tft.setCursor(87, 170);
    tft.print("%");


    tft.setCursor(114, 170);
    tft.setTextSize(2);
    tft.setTextColor(ST77XX_GREEN);
    tft.print("hPa:");

    tft.setCursor(7, 221);
    tft.setTextSize(2);
    tft.setTextColor(ST77XX_GREEN);
    tft.print("LAB Temp = ");
    tft.setCursor(1, 111);
    tft.fillRect(206, 220, 4, 4, ST77XX_GREEN);       // Graden circeltje
    tft.setCursor(212, 221);
    tft.print("C");                                   // "C" van de graden eenheid


// Teken het kader en lijnen op het scherm
    tft.drawRect(0, 0, 240, 240, ST77XX_WHITE);
    tft.drawFastHLine(0, 164, 240, ST77XX_WHITE);
    tft.drawFastHLine(0, 190, 240, ST77XX_WHITE);
    tft.drawFastHLine(0, 216, 240, ST77XX_WHITE);
}

Deze code is gebruikt om het grotere scherm me aan te sturen en nu ik weet hoe het werkt kan ik het meerdere keren gaan toepassen.
Ook wil ik in de setup bij het opstarten een logo op het scherm tonen, ik denk dat ik daar in het weekeinde de tijd er voor heb om dit uit te zoeken,

Dank weer voor de input en ik wou even wat feedback geven op jullie tips.

Groet,
Bram

You have your way. I have my way. As for the right way, the correct way, and the only way, it does not exist.

@Bram, misschien beetje mm n...n maar je gebruikt een amerikaanse datumnotatie. De nederelandse notatie zou fraaier zijn. Net even vluchtig in de RTClib gekeken maar zie niet zo snel een oplossing.

Mijn twee eurocent, voor de rest ziet het er fraai uit.

Gr,

Paul

I thought, I thought of everything
blackdog

Golden Member

Hi paulp, :-)

Weet je dat dit het eerste was toen ik de tijdcode ging toepassen, kijken of ik de notatie kon kiezen die wij hier gewend zijn.
Hoe het nu staat ben ik te vreden mee, dit omdat het jaar, maand en dan dag is, daar kan ik goed mee leven.
Als ik tijd over heb(komt eigenlijk nooit voor :-) ) dan zou ik daar aan kunnen frutten door het op te delen en daarna weer bij elkaar te plakken.
Of in de Library duiken of daar iets aan te passen is, maar zoals ik net al zij, het is eigenlijk wel goed zo.

Gisterenavond kon ik niet goed in slaap komen, dit omdat de code door mijn hoofd bleef spelen.

Er zijn aardig wat vergelijkingen die opgelost moet worden met de acht ingangen voor de Sensoren en dit dan samen met een paar drukknopjes.
Ik weet nu hoe ik een soort "Go To" kan doen in de "Arduino C" dus de functie die ik nu gebruik voor het vaste deel van wat er op het scherm geplaatst moet worden.
Ik noem het even zo, omdat ik de Go To regelmatig gebruikte in .bat bestanden die ik maakte voor klanten.
Dus zo kan ik de code die nodig is, beter opsplisen en het voor mij duidelijker houden, voor jullie waarschijnlijk ook.

Het volgende stapje is de BME code in een apart stukje zetten en dit één keer per seconde of 1x per twee seconde uit te lezen, nu is dat nog iedere keer dat de loop doorlopen wordt.
Dus ik ga zelf proberen de loop zo schoon mogelijk te houden, door dit hopelijk zinnig op te lossen met ondermeer functies en lukt me dat niet, dan kom ik vast weer terug bij jullie. ;)

Dank voor het compliment.

Groet,
Bram

You have your way. I have my way. As for the right way, the correct way, and the only way, it does not exist.

Ik geef ook altijd de voorkeur aan jaar-maand-dag. Als het jaar achteraan staat dan weet je nooit of het dag-maand-jaar is of maand-dag-jaar 8)7 .
Volgens mij komt jaar-dag-maand nooit voor dus met jaar vooraan weet je direct de volgorde.

Bovendien kun je dan alfabetisch sorteren en krijg je meteen ook chronologische volgorde. Vooral handig met een datum in bestand- namen.

je typt ook veel dezelfde tekst. geen idee om dat in een subroutine te gooien?

c code:


void printline (int x, int y, int size, string tekst, string eenheid, color)
    tft.setCursor(x, y);
    tft.setTextSize(size);
    tft.setTextColor(color);
    tft.print(tekst);
    tft.fillRect(x+200, y+1, 4, 4, color);         // Graden circeltje
    tft.setCursor(x+208, y);
    tft.print(eenheid);    

en die roep je dan vanuit het hoofdprogramma als:
printline (7,25,2, "Sensor-2 = ","C",ST77XX_GREEN);
printline (7,45,2, "Sensor-3 = ","C",0xCB5F);
printline (7,65,2, "Sensor-4 = ","C",ST77XX_YELLOW);
...

maakt het ook heeeeeeeeeeeeel makkelijk om verschillende displays of roterende displays te gebruiken. enkel de X-Y veranderd. als het een vaste aanpassing is, kan dat in die subroutine ipv je hele programma te doorspitten (bv roteren is enkel X en Y van plaats veranderen dan).

vroeger had ik zo een routine ook om tekst te schrijven. ik gaf de oude value, de nieuwe value en de X-Y coordinaten mee.
die ging dan karakter per karakter vergelijken.
als je bv 18,2 veranderd naar 18,3
dan liet die de "1" staan, de "8" staan, de "," staan, schreef dan een zwarte 2 en een gekleurde 3 op positie x/y + 27pixels (3karakters van 9 pixels die gelijk blijven). dan verspringt enkel dat 1 karakter en zie je nog veel minder flikkeren.

heb ook nog men eigen font gedefinieerd in bytes (8x 13karakter is dan 13 bytes die ik doorstuurde). en daar zette ik dan de pixels om.
2 => 3 is maar een paar regels die veranderen. de bovenste regels van 2 en 3 zijn gelijk. t is pas vanaf de 5de regel dat er pixels veranderen.

dit dan vooral om veel ruimte te besparen want die libraries vreten geheugen

ik hou van werken ..., ik kan er uren naar kijken
buckfast_beekeeper

Golden Member

De rtc library ondersteund DateTime. Dan kan je de datetimeformatter gebruiken.

c code:


time_t nu = DateTime.now();
tijd = DateFormatter::format("%d-%m-%Y", nu);

Voor de gebruikte combinaties kan je hier terecht.

Wil je ergens een datum en tijd opslaan, bijvoorbeeld database, gebruik dan altijd UTC tijd. Dan krijg je geen overlappende gegevens bij de overgang van zomertijd naar wintertijd en geen 'gat' bij de overgang naar zomertijd.

Van Lambiek wordt goede geuze gemaakt.
blackdog

Golden Member

Hi, :-)

deKees & buckfast_beekeeper
Ik nijg er ook naar om het zo te houden maar om wat kennis op te doen ga ik wel even spelen met de code die buckfast_beekeeper liet zien voor het formatteren van de tekt.
Ook de tip betreffende de tijd formattering als er gelogt gaat worden om dit in UTC te doen, heb ik er direct een vraag over, kan b.v. Exel daar mee omgaan?

fcapri
Klopt reperterende code, dat is ook iets wat mij vannacht bezich hield zodat ik minder goed in slaap kwam. :-)
Wat betreft de standaard teks die op beeld komt vind ik het niet zo'n probleem, maar het echte werk moet nog komen met de acht kanalen van de twee ADC printjes uit te lezen,
de waarde bewerken en een aantal vergelijkingen doen op de waarde die uit iedere ingang komt.

Ik ga het stukje code dat je liet zien: void printline vandaag in een proef je testen.
En daarna beslis ik of ik het toe wil passen.

Dit nog en keer even hier uitleggen, bij het maken van teksten en ook code voor dit project zit mijn dyslectie mij aardig in de weg.
De meeste tijd bij het schrijven zit in het controleren wat ik type.

Het overzicht ben ik snel kwijt in de Arduino code en ben blij dat ik nu weet hoe ik stukjes code "apart" kan zetten in een functie, dat geeft duidelijk meer rust.
Maar ik kan niet te veel tegelijk "leren", wat ik geleerd heb moet eerst goed indalen en zich vast zetten.
Daarom gebruik ik niet altijd alles wat jullie voorstellen en dat is niet uit dwarsheid. ;)

Verder een Notepad lijstje gemaakt voor de handige links en andere zaken die jullie aangeven, dan hoef ik niet het hele topic door te spitten.

Dank weer voor de input!

Groet,
Bram

You have your way. I have my way. As for the right way, the correct way, and the only way, it does not exist.
buckfast_beekeeper

Golden Member

Een timestamp is een unix time. Start op 1/1/1970 00:00:00. Elke seconde wordt er 1 opgeteld. De correcte unixtime hier te vinden.

Excel heeft een andere manier van werken en datum codering.

Excel telt de dagen sinds 1/1/1900. De uren en minuten worden weergegeven als een deel van een dag. Vandaag zijn we dag 45002. Om 00:00:00 noteerde Excel dit getal. 06:00:00 wordt dan weer opgeslagen als 45022,25. 12h 45022,5 18h 45022,75.

Tel je 12h en 18h op, dat zou 30h moeten geven, dan zal dat 1dag en 6h worden. Wil je de uren zien, dan moet je als veldopmaak [ u ]:mm (spaties weglaten maar forum neemt het zonder de spaties als onderstrepen) gebruiken. Je kan ook geen negatieve tijden maken. 6h - 12h geeft #####################. Wil je dat toch doen moet je ofwel er een datum aanplakken of de Excel instellingen wijzigen. Maar dat is dan weer iets meer voor een computer of Excel forum.

Je kan van een unixtimestamp een Excel waarde maken. Hier een voorbeeld.

Databases zoals MariaDb ondersteunen unixtimestamp. Je kan die timestamp automatisch laten genereren.

Van Lambiek wordt goede geuze gemaakt.

Brr, datums / tijden... Daar zijn boekdelen over geschreven.
https://github.com/kdeldycke/awesome-falsehood#dates-and-time

Let me tell you a quick story.

Do you remember what you were doing on December 30, 2011? You have three seconds. Go.

Nope? Nothing? Well then, if you don’t know what you were doing December 30, 2011, then there’s one obvious explanation for this: you must be Samoan.

You see, Samoa didn’t have December 30, 2011. They went straight from December 29 to December 31, do not pass Go, do not collect $200.

Erg leuk stukje over fouten die gemaakt zijn met datum en tijd en de gevolgen ervan.
https://zachholman.com/talk/utc-is-enough-for-everyone-right

PE2BAS

die color weet ik niet hoe je die definieert, dus dat is fout. het was maar een snel stuk code uit de losse pols.
maar wel om een idee te geven.
als je 10x naar een X-Y coordinaat gaat en data wegschrijft, kun je zoiets in een routine steken, de X-Y en data meegevens als variabele en laat die de boel maar 10x herhalen.

Op 17 maart 2023 14:23:10 schreef blackdog:

Klopt reperterende code, dat is ook iets wat mij vannacht bezich hield zodat ik minder goed in slaap kwam. :-)

dat is net programmeren
1) houd de regels code in elke routine compact, max 8-10regels.
zijn het teveel regels, moet je weer opsplitsen en de taken in kleinere programmas gooien.

ik zou een hoofdprogramma maken met daar een 4tal routines in

code:

void setup(){
 **tft_init**
 **inputs init **
 **rtc **
 print_scherm_layout();
}

void loop () {
 inlezen_data();
 verwerk_gegevens();
 print_gegevens();
}

void inlezen_data () {
  **hier ga je dan alle 8 sensoren uitlezen en de data verzamelen**
}

void verwerk_gegevens(){
  **hier ga je dan bepaalde berekeningen doen**
}

print_scherm_layout (){
  printline (7,25,2, "Sensor-2 = ","C",ST77XX_GREEN);
  printline (7,45,2, "Sensor-3 = ","C",0xCB5F);
  printline (7,65,2, "Sensor-4 = ","C",ST77XX_YELLOW);
 **layout opbouwen van kaders en alle tekst
}

void print_gegevens (){
 **hier ga je dan alle data op het scherm weergeven. eventueel een subroutine die bekijkt of de data nog hetzelfde is als de vorige en niks doen, en enkel schrijven als het veranderd is **
}

met kleine blokken tekst is het heel overzichtelijk en uw programma heeft maar 3 grote regels. loopt er wat fout, zet je de beeld weergeven in commentaar, en dan zal je enkel data lezen en verwerken.
dan doe je met een serial.print de output naar pc om na te rekenen

ik hou van werken ..., ik kan er uren naar kijken
buckfast_beekeeper

Golden Member

Op 17 maart 2023 18:29:54 schreef fcapri:
die color weet ik niet hoe je die definieert, dus dat is fout. het was maar een snel stuk code uit de losse pols.

[...]

De kleur is een uint16_t of unsigned int.

c code:


void printline (int x, int y, int size, string tekst, string eenheid, uint16_t color)
    tft.setCursor(x, y);
    tft.setTextSize(size);
    tft.setTextColor(color);
    tft.print(tekst);
    tft.fillRect(x+200, y+1, 4, 4, color);         // Graden circeltje
    tft.setCursor(x+208, y);
    tft.print(eenheid);  

Uit de ST7735 library van adafruit

c code:


// Some ready-made 16-bit ('565') color settings:
#define ST77XX_BLACK 0x0000
#define ST77XX_WHITE 0xFFFF
#define ST77XX_RED 0xF800
#define ST77XX_GREEN 0x07E0
#define ST77XX_BLUE 0x001F
#define ST77XX_CYAN 0x07FF
#define ST77XX_MAGENTA 0xF81F
#define ST77XX_YELLOW 0xFFE0
#define ST77XX_ORANGE 0xFC00
Van Lambiek wordt goede geuze gemaakt.
blackdog

Golden Member

Hi

Even iets anders, ik wil een aantal stukjes code via een timer uitvoeren.
In het voorbeeld hier beneden gebruik ik het uitlezen en op het displat brengen van de BME sensor en het klok IC hiervoor.

Ik gebruik hier een Library voor omdat dit voor mij makeklijk is en overzichtelijk en bespaard tijd, nou niet helemaal, ik heb iets veranderd in de code waardoor het niet meer werkt, daar gaat mijn winst!

De library heet: UniversalTimer.h
En wat voorbeeldjes waarvan ik er een laat zien hieronder, draait op een Arduino Uno en op de Teenst 3.2 waarop ik het getest het.

Dit is de "basic code" om te laten zien hoe de UniversalTimer library werkt.
Je maakt een timer aan, geeft aan hoelang het moet runnen en daarna of het wel of niet herhaald moet worden, kan bijna niet simpeler.

In de setup start je de aangemaakte timers en in de loop die je voor iedere aangemaakte timer dit blahblahTimer.check en als dat waar is run je de opdracht die er onder staat.
Een kind en zelfs Bram kan de was doen, nou die laatste kan het dus duidelijk niet, de "if" functie blijkt niet bij mij te werken....
Oja in mijn code staan lange tijden, dat is voor het testen, zodat ik goed kan zien of de code uitgevoerd wordt na de opgegeven tijd.
Mijn code heeft maling aan de ingestelde tijd, hij runt gewoon altijd, ik zal iets over het hooft zien, maar zelfs na een goede nachtrust zie ik niet wat ik verkeerd doe...

Voorbeedl code van de UniversalTimer.h library

c code:


/**
 * In this example we create three diffrent timer.
 */

#include <UniversalTimer.h>

// Create a timer with 1000ms(default) and non-repeating(default)
UniversalTimer defaultTimer;

// Create a timer with 3000ms and non-repeating
UniversalTimer delay3sTimer(3000, false);

// Create a timer with 5000ms and repeating
UniversalTimer every5sTimer(5000, true);

void setup()
{
    // Start serial connection
    Serial.begin(9600);

    // Start the timer
    defaultTimer.start();
    delay3sTimer.start();
    every5sTimer.start();
}

void loop()
{
    // Check timer. Returns true after 1s
    if (defaultTimer.check())
    {
        Serial.println("Triggered after 1 second!  (defaultTimer)");
    }

    // Check timer. Returns true after 3s
    if (delay3sTimer.check())
    {
        Serial.println("Triggered after 3 seconds! (delay3sTimer)");
    }

    // Check timer. Returns true every 5s
    if (every5sTimer.check())
    {
        Serial.println("Triggered every 5 seconds! (every5sTimer)");
    }

    // Do something else (non-blocking of course)...
}

En dit is mijn stukje code waarin ik de UniversalTimer.h probeer te gebruiken.

c code:


#include <Adafruit_GFX.h>    // Core graphics library
#include <Adafruit_ST7789.h> // Hardware-specific library for ST7789
#include <SPI.h>
#include "RTClib.h"
#include <Adafruit_Sensor.h>
#include <Adafruit_BME280.h>
#include <UniversalTimer.h>
#include "ADS1X15.h"

// adjust addresses for the ADS1115
//ADS1115 ADS_1(0x49);
//ADS1115 ADS_2(0x48);


RTC_DS3231 rtc;

Adafruit_BME280 bme; // I2C

unsigned long delayTime;

  #define TFT_CS        10
  #define TFT_RST        8 
  #define TFT_DC         9

  // For 1.3", 1.54", and 2.0" TFT with ST7789:
  Adafruit_ST7789 tft = Adafruit_ST7789(TFT_CS, TFT_DC, TFT_RST);

// Code timing voor de aangemaakte functies
//
// Make een timer aan voor het uitlezen van de BME280
  UniversalTimer bme_Timer(5000, true);

// Make een timer ann voor het uitlezen van de DS3231 
  UniversalTimer klok_Timer(2000, true);
//
// Code timing voor de aangemaakte functies



void setup(void) {
    
// Use this initializer if using a 1.54" 240x240 TFT:
  tft.init(240, 240);                                              // Init ST7789 240x240
  tft.fillScreen(ST77XX_BLACK);
  tft.setRotation(3);
  tft.setSPISpeed(30000000);

// start de BME sensor op het goede i2c adres
  bme.begin(0x76, &Wire);

// BME280 Sensor configuratie
   bme.setSampling(Adafruit_BME280::MODE_NORMAL,
                   Adafruit_BME280::SAMPLING_X16,               // temperature
                   Adafruit_BME280::SAMPLING_X16,               // pressure
                   Adafruit_BME280::SAMPLING_X16,               // humidity
                   Adafruit_BME280::FILTER_X16,
                   Adafruit_BME280::STANDBY_MS_250 );

// Srart de klok functie
   rtc.begin();

// Plaatst standaard karakters en lijnen op het scherm
    Basic_Screen_Setup();
// Plaatst standaard karakters en lijnen op het scherm

    // Start the timers
    bme_Timer.start();
    klok_Timer.start();
//  xxxTimer.start();

}




void loop() {

// Debug tekst om te zien of de positie klopt en de kleuren van de tekst goed zijn
    tft.setCursor(135, 5);
    tft.setTextSize(2);
    tft.setTextColor(ST77XX_RED, ST77XX_BLACK);
    tft.print("ERROR O ");
    
    tft.setCursor(135, 25);
    tft.setTextSize(2);
    tft.setTextColor(ST77XX_GREEN, ST77XX_BLACK);
    tft.print("103.5");

    tft.setCursor(135, 45);
    tft.setTextSize(2);
    tft.setTextColor(ST77XX_RED, ST77XX_BLACK);
    tft.print("ERROR W ");

    tft.setCursor(135, 65);
    tft.setTextSize(2);
    tft.setTextColor(ST77XX_YELLOW, ST77XX_BLACK);
    tft.print("101,8");

    tft.setCursor(135, 85);
    tft.setTextSize(2);
    tft.setTextColor(ST77XX_WHITE, ST77XX_BLACK);
    tft.print("23,6");

    tft.setCursor(135, 105);
    tft.setTextSize(2);
    tft.setTextColor(ST77XX_GREEN, ST77XX_BLACK);
    tft.print("45,9");

    tft.setCursor(135, 125);
    tft.setTextSize(2);
    tft.setTextColor(0xCB5F, ST77XX_BLACK);
    tft.print("45,6");

    tft.setCursor(135, 145);
    tft.setTextSize(2);
    tft.setTextColor(ST77XX_RED, ST77XX_BLACK);
    tft.print("ERROR U ");
// Debug tekst om te zien of de positie klopt en de kleuren van de tekst goed zijn


// Hier worden de timers gecontroleerd of de functies al moeten worden uitgevoerd
 // Check timer. Returns true after 1s
 
 if  (bme_Timer.check()); 
    {
     Print_bme();
    }
 if (klok_Timer.check());
     {
      Print_tijd();
     }
// Hier worden de timers gecontroleerd of de functies al moeten worden uitgevoerd

}
// ------------------------ einde void loop ---------------------------------------




// --------------------------------------------------------------------------------
// hieronder staat de code van de verschillende functies
// --------------------------------------------------------------------------------

void Print_tijd() {

    DateTime time = rtc.now();

    tft.setCursor(7, 196);
    tft.setTextSize(2);
    tft.setTextColor(ST77XX_GREEN, ST77XX_BLACK);
    tft.print(time.timestamp(DateTime::TIMESTAMP_DATE));

    tft.setCursor(138, 196);
    tft.setTextSize(2);
    tft.setTextColor(ST77XX_GREEN, ST77XX_BLACK);
    tft.print(time.timestamp(DateTime::TIMESTAMP_TIME));
}


// --------------------------------------------------------------------------------
// hieronder staat de functie vande BME luchdruk sensor
// --------------------------------------------------------------------------------

void Print_bme() {
    
    tft.setCursor(55, 170);
    tft.setTextSize(2);
    tft.setTextColor(ST77XX_GREEN, ST77XX_BLACK);
    tft.print(bme.readHumidity(), 0);  

    tft.setCursor(162, 170);
    tft.setTextSize(2);
    tft.setTextColor(ST77XX_GREEN, ST77XX_BLACK);
    tft.print(bme.readPressure()/100,1);  
        
    tft.setCursor(138, 221);
    tft.setTextSize(2);
    tft.setTextColor(ST77XX_GREEN, ST77XX_BLACK);
    tft.print(bme.readTemperature());
}


// ----------------------------------------------------------------------------------
// Hieronder staat de functie voor het plaatsen van de standaard tekst op het scherm
// ----------------------------------------------------------------------------------

void Basic_Screen_Setup() {

    tft.fillScreen(ST77XX_BLACK);                       // Maak eerst het scherm total zwart

    // Teken kader en lijnen op hetscherm
    tft.drawRect(0, 0, 240, 240, ST77XX_WHITE);
    tft.drawFastHLine(0, 164, 240, ST77XX_WHITE);
    tft.drawFastHLine(0, 190, 240, ST77XX_WHITE);
    tft.drawFastHLine(0, 216, 240, ST77XX_WHITE);
        
    tft.setCursor(7, 5);
    tft.setTextSize(2);
    tft.setTextColor(0xD7FE);
    tft.print("Sensor-1 = ");
    tft.fillRect(206, 6, 4, 4, 0xD7FE);                 // Graden circeltje
    tft.setCursor(215, 5);
    tft.print("C");                                     // "C" van de graden eenheid

    tft.setCursor(7, 25);
    tft.setTextSize(2);
    tft.setTextColor(ST77XX_GREEN);
    tft.print("Sensor-2 = ");
    tft.fillRect(206, 26, 4, 4, ST77XX_GREEN);          // Graden circeltje
    tft.setCursor(215, 25);
    tft.print("C");                                     // "C" van de graden eenheid

    tft.setCursor(7, 45);
    tft.setTextSize(2);
    tft.setTextColor(0xCB5F);
    tft.print("Sensor-3 = ");
    tft.fillRect(206, 46, 4, 4, 0xCB5F);                // Graden circeltje
    tft.setCursor(215, 45);
    tft.print("C");                                     // "C" van de graden eenheid

    tft.setCursor(7, 65);
    tft.setTextSize(2);
    tft.setTextColor(ST77XX_YELLOW);
    tft.print("Sensor-4 = ");
    tft.fillRect(206, 66, 4, 4, ST77XX_YELLOW);         // Graden circeltje
    tft.setCursor(215, 65);
    tft.print("C");                                     // "C" van de graden eenheid

    tft.setCursor(7, 85);
    tft.setTextSize(2);
    tft.setTextColor(0xD7FE);
    tft.print("Sensor-5 = ");
    tft.fillRect(206, 86, 4, 4, 0xD7FE);               // Graden circeltje
    tft.setCursor(215, 85);
    tft.print("C");                                     // "C" van de graden eenheid

    tft.setCursor(7, 105);
    tft.setTextSize(2);
    tft.setTextColor(ST77XX_GREEN);
    tft.print("Sensor-6 = ");
    tft.fillRect(206, 106, 4, 4, 0xCB5F);               // Graden circeltje
    tft.setCursor(215, 105);
    tft.print("C");                                     // "C" van de graden eenheid

    tft.setCursor(7, 125);
    tft.setTextSize(2);
    tft.setTextColor(0xCB5F);
    tft.print("Sensor-7 = ");
    tft.fillRect(206, 126, 4, 4, 0xCB5F);               // Graden circeltje
    tft.setCursor(215, 125);
    tft.print("C");                                     // "C" van de graden eenheid

    tft.setCursor(7, 145);
    tft.setTextSize(2);
    tft.setTextColor(ST77XX_YELLOW);
    tft.print("Sensor-8 = ");
    tft.fillRect(206, 146, 4, 4, ST77XX_YELLOW);        // Graden circeltje
    tft.setCursor(215, 145);
    tft.print("C");                                     // "C" van de graden eenheid
    
// Tekst nodig voor de BME sensor   
    tft.setCursor(7, 170);
    tft.setTextSize(2);
    tft.setTextColor(ST77XX_GREEN);
    tft.print("Hum:");
    tft.setCursor(87, 170);
    tft.print("%");

    tft.setCursor(114, 170);
    tft.setTextSize(2);
    tft.setTextColor(ST77XX_GREEN);
    tft.print("hPa:");

    tft.setCursor(7, 221);
    tft.setTextSize(2);
    tft.setTextColor(ST77XX_GREEN);
    tft.print("LAB Temp = ");
    tft.setCursor(1, 111);
    tft.fillRect(206, 220, 4, 4, ST77XX_GREEN);       // Graden circeltje
    tft.setCursor(212, 221);
    tft.print("C");                                   // "C" van de graden eenheid
}

Ik hoor graag van jullie waar ik de fout in ga waardoor de code iedere loop gewoon draait.
Alvast mijn dank.

Bram

You have your way. I have my way. As for the right way, the correct way, and the only way, it does not exist.