Worstelen met Arduino variabelen

blackdog

Golden Member

Hi,

Ik ben bezig wat code aan het schrijven zodat ik voor de reisreferentie zeg 1x in de 5 minuten wat data uit mijn BME280 sensor op haal.
Als ik continu de data op haal, wordt de dissipatie in deze te hoog en resulteerd in een te hoge temperatuur.
Dus ik heb een stukje code geschreven dat voor test dit 1x in de 5 seconde doet wat natuurlijk later naar iets van 2 a 10 minuten gaat.

Ik heb er voor gekozen, of beter gezegt ik probeer aan de hand van millis timing 1x per 5 seconde de data uit de BME280 op te halen.
Deze probeer ik dan in een variabel te stoppen die ik dan zo vaak als ik wil kan uitlezen zonder dat de sensor warm wordt.

Dit lukt echter niet, hoe krijg ik wat hier uit komt: (mySensor.readFloatHumidity(), 0) en (mySensor.readTempC(), 2);
in een variabel wel ik dan naar het scherm kan schijven zo vaak als ik dit nodig vind.

Dit is de code om een variabel naar het scherm(buffer) te schrijven: u8g2.print(dt.second);
En tekst doe je op de ze manier: u8g2.drawStr(0,62,"Celsius");

Ik ben dit probleem al eens meer tegengekomen maar kan het niet meer terug vinden.

De code

c code:

#include <Arduino.h>
#include <U8g2lib.h>
#include <Wire.h>
#include <DallasTemperature.h>
#include <DS3231.h>
#include "SparkFunBME280.h"

BME280 mySensor;

DS3231 clock;
RTCDateTime dt;

U8G2_SH1106_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE);

long tmp = 0;
long hum = 0;

unsigned long currentTime;
unsigned long loopTime;



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

Wire.begin();
  
mySensor.setI2CAddress(0x76);
mySensor.beginI2C();
  
mySensor.setFilter(4); //0 to 4 is valid. Filter coefficient. See 3.4.4
mySensor.setStandbyTime(7); //0 to 7 valid. Time between readings. See table 27.

mySensor.setTempOverSample(16); //0 to 16 are valid. 0 disables temp sensing. See table 24.
mySensor.setPressureOverSample(16); //0 to 16 are valid. 0 disables pressure sensing. See table 23.
mySensor.setHumidityOverSample(16); //0 to 16 are valid. 0 disables humidity sensing. See table 19.
  
mySensor.setMode(MODE_NORMAL); //MODE_SLEEP, MODE_FORCED, MODE_NORMAL is valid. See 3.3

// Initialize DS3231
  Serial.println("Initialize DS3231");;
  clock.begin();

// Start display
  u8g2.begin();

//Timing setup for Temperature measurement samples
  currentTime = millis();
  loopTime = currentTime;
}



void loop(void) {

dt = clock.getDateTime();
  
  u8g2.clearBuffer();					                            // clear the internal memory
  u8g2.drawRFrame(0,0,128,14,6);
  
  u8g2.setFont(u8g2_font_ncenB08_tr);	                     // choose a suitable font
  u8g2.drawStr(0,12,"  ****                       ****");	 // write something to the internal memory
  u8g2.drawStr(0,10,"            NoiseAmp ");              // write something to the internal memory

  u8g2.setCursor(0,35);
  u8g2.print(dt.hour);
  u8g2.drawStr(12,35,":");
  u8g2.setCursor(15,35);
  u8g2.print(dt.minute);
  u8g2.drawStr(28,35,":");
  u8g2.setCursor(31,35);
  u8g2.print(dt.second);

// code voor het 1x in de 5 seconde uitlezen van de temperatuur en de luchtvochhtigheidsgraad
  currentTime = millis();
  if(currentTime >= (loopTime + 5000)){                             // Every 5 second measure temperature
  
hum = (mySensor.readFloatHumidity(), 0);                            // plaats vochtighaidsgraad in tijdelijke variabel "hum" 
tmp = (mySensor.readTempC(), 2);                                    // plaats temperatuur in tijdelijke variabel "tmp"
loopTime = currentTime;                                             // Updates loopTime
}


u8g2.drawStr(0,45,"H = : ");
u8g2.setCursor(38,45);
u8g2.print("hum");                                                    // write something to the internal memory

u8g2.drawStr(0,55,"T  = : ");
u8g2.setCursor(38,55);     
u8g2.print("tmp");


  u8g2.sendBuffer();                                                // transfer internal memory to the display
  delay(400);
  

}

Weet een van jullie de oplossing?

Groet,
Bram

[Bericht gewijzigd door blackdog op dinsdag 4 juni 2019 00:31:08 (55%)

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 dacht dat je per abuis variabelen als hum en tmp in loop zou hebben gedeclareerd. Dan worden die iedere aanroep van loop.... ehhh niet geinitialiseerd. Maar dat zit hier zo goed.

Ik zie even niet wat er mis is. Wat gaat er fout?

Het is een beetje raar om read...float in een long op te slaan. Gaat dat goed? I.e. voldoende integer deel?

Ik zou de plus 5000 1x uitrekenen.

c code:

nextsenstime = currenttime+5000;.

en dan dus:

code:

if (millis > nextsenstime) { // ... nieuwe meting

Als het na 49 dagen moet blijven werken(*), zal je het weer anders moeten doen. Reken het tijdsverschil uit en stop dat in een signed variabele:

code:


  dt = nextsenstime - millis();
  if (dt < 0) //read sensor.

(*) Dan loopt de millis teller van groot positief getal ineens weer naar een in-de-buurt-van-nul.

P.S. Ik heb vannacht te veel naar die variabelen gekeken en niet naar het printen daarvan, hetgeen Fatbeard en Stijnos dus wel opgevallen is.

[Bericht gewijzigd door rew op dinsdag 4 juni 2019 07:43:43 (25%)

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

Honourable Member

Ik spreek weliswaar geen Arduino, maar volgens mij zou u8g2.print("hum"); zonder aanhalingstekens moeten zijn: je print nu een string literal...

Een goed begin is geen excuus voor half werk; goed gereedschap trouwens ook niet. Niets is ooit onmogelijk voor hen die het niet hoeven te doen.

ik zou ook zeggen dat je de aanhalingstekens weg moet halen.
Je wilt immers de waarde van de variabele printen neem ik aan en niet de tekst "hum" en "tmp"

Dit stukje:

Op 4 juni 2019 00:17:36 schreef blackdog:

c code:


hum = (mySensor.readFloatHumidity(), 0);
tmp = (mySensor.readTempC(), 2);                                    

Snap ik niet, en ik vraag me af wat de compiler ervan maakt. Het is i.i.g. geen C (of "Arduinees") zoals ik het ken.

Zou eerder dit verwachten:

c code:


hum = mySensor.readFloatHumidity();
tmp = mySensor.readTempC();                                    

En die aanhalingstekens, die moeten sowieso weg.

wat komt er uit die mySensor.readFloatHumidity() uit met die regel? voor wat is die ",0" er dan achter?
oh, ik ben mee, dat komt van serial print.
Serial.print(mySensor.readFloatHumidity(),0) zal enkel de integer waarde serieel uitprinten. je moet die ,0 weglaten dan of via andere tools een integer mee maken.
bv
hum = (int)mySensor.readFloatHumidity();
en voor die temperatuur zal je met een float moeten werken, aangezien je daar 2 decimalen wil behouden.

of vermenigvuldig alles met 10 of 100 en print dan met een komma uit.
String TextToPrint; (ergens bovenaan definieren)

//neem de float, vermenigvuldig met 10 of 100 en neem dan enkel het getal voor de komma
hum = (int)(mySensor.readFloatHumidity()*10);
tmp = (int)(mySensor.readTempC()*100);

// deel het getal door 10 en maak er een string van.voorbeeld 110 => "11.0"
TextToPrint = String(hum/10);
u8g2.print(TextToPrint);
...
// deel het getal door 100 en maak er een string van.voorbeeld 2134 => "21.34"
TextToPrint = String(tmp/100);
u8g2.print(TextToPrint);

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

Golden Member

Hi,

rew
Klopt, ik heb even gedacht het zo te laten met de timing, want 49 dagen is wel al vrij lang.
Meestal zal de Microcontroler wel al een hetstart hebben gehad binnen die tijd.
Ik wou de Microcontroler welke nu een Adafruit Feather M0 logger is toch al 1x per zoveel tijd een automatische herstart geven.
Ik ga je code in ieder geval proberen, dank hoef ik dat in ieder geval niet meer uit te zoeken.
Verder was het niet zo handig dat ik de fout hier niet vermelde die ik op het scherm zag.
Voor "hum" werd er niets vermeld en voor "tmp" verscheen er alleen een 2 op het display.
( Verder is het niet de bedoeling dat ik je uit je slaap hou :-) )

fatbeard, Stijnos en blurp
Jullie hebben het gezamelijk bij het rechte eind!
Ik had de code gekopieerd uit serial.print regel, en die is dus duidelijk anders van opbouw als een
opdracht zoals deze werkende code: hum = mySensor.readFloatHumidity(), 0;

Toen ik deze fout had aangepast, dus veranderd naar wat er in bovenstaande regel staat kreeg ik per item twee karakters op het scherm.
De variabel "hum" en "temp" waren in eerste instantie een "float" omdat ik het niet werkend kreeg ben ik ook met het type variabel gaan spelen.
Door het weer aanpassen van de variabelen naar een "float" kreeg ik voor beide waarden weer 4 digits in beeld op de goede manier geformatteerd.

fcapri
Jouw bewerking is niet nodig, dit omdat de code nu goed werkt zoals gewenst, maar ik begrijp je bedoeling.

Zo is het nu.

c code:

#include <Arduino.h>
#include <U8g2lib.h>
#include <Wire.h>
#include <DallasTemperature.h>
#include <DS3231.h>
#include "SparkFunBME280.h"

BME280 mySensor;

DS3231 clock;
RTCDateTime dt;

U8G2_SH1106_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE);

float tmp = 0;
float hum = 0;

unsigned long currentTime;
unsigned long loopTime;



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

Wire.begin();
  
mySensor.setI2CAddress(0x76);
mySensor.beginI2C();
  
mySensor.setFilter(4); //0 to 4 is valid. Filter coefficient. See 3.4.4
mySensor.setStandbyTime(7); //0 to 7 valid. Time between readings. See table 27.

mySensor.setTempOverSample(16); //0 to 16 are valid. 0 disables temp sensing. See table 24.
mySensor.setPressureOverSample(16); //0 to 16 are valid. 0 disables pressure sensing. See table 23.
mySensor.setHumidityOverSample(16); //0 to 16 are valid. 0 disables humidity sensing. See table 19.
  
mySensor.setMode(MODE_NORMAL); //MODE_SLEEP, MODE_FORCED, MODE_NORMAL is valid. See 3.3

// Initialize DS3231
  Serial.println("Initialize DS3231");;
  clock.begin();

// Start display
  u8g2.begin();

//Timing setup for Temperature measurement samples
  currentTime = millis();
  loopTime = currentTime;
}



void loop(void) {

dt = clock.getDateTime();
  
  u8g2.clearBuffer();					                            // clear the internal memory
  u8g2.drawRFrame(0,0,128,14,6);
  
  u8g2.setFont(u8g2_font_ncenB08_tr);	                     // choose a suitable font
  u8g2.drawStr(0,12,"  ****                       ****");	 // write something to the internal memory
  u8g2.drawStr(0,10,"            NoiseAmp ");              // write something to the internal memory

  u8g2.setCursor(0,35);
  u8g2.print(dt.hour);
  u8g2.drawStr(12,35,":");
  u8g2.setCursor(15,35);
  u8g2.print(dt.minute);
  u8g2.drawStr(28,35,":");
  u8g2.setCursor(31,35);
  u8g2.print(dt.second);

// code voor het 1x in de 5 seconde uitlezen van de temperatuur en de luchtvochtigheidsgraad
  currentTime = millis();
  if(currentTime >= (loopTime + 5000)){                             // Every 5 second measure temperature
  
hum = mySensor.readFloatHumidity(), 0;                              // plaats vochtighaidsgraad in tijdelijke variabel "hum" 
tmp = mySensor.readTempC(), 2;                                      // plaats temperatuur in tijdelijke variabel "tmp"
loopTime = currentTime;                                             // Updates loopTime
}


u8g2.drawStr(0,45,"H = : ");
u8g2.setCursor(38,45);
u8g2.print(hum),2;                                                    // write something to the internal memory

u8g2.drawStr(0,55,"T  = : ");
u8g2.setCursor(38,55);     
u8g2.print(tmp), 2;

  Serial.println(hum);
  Serial.println(tmp);
  
  u8g2.sendBuffer();                                                // transfer internal memory to the display
  delay(400);
  

}

Dan heb ik nog een vraag, deze heb ik lang terug ook al eens gesteld.
Deze heeft betrekking op de weergave van de klok waarde, zie ook het plaatje hieronder.
Bij waarden kleiner dan 10 worden de digits niet op de gewenste plaatst getoond, zie op het plaatje de seconde positie "1".

Ik denk dan b.v. voor ieder item, dus uren, minuten en seconden een if/els op te nemen om te kijken of er een extra "0" nodig is.
Misschien hebben jullie ene inteligentere manier?

Mijn dank vast voor de hulp!

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.

If/else voor de extra 0 zou mijn eerste ingeving ook zijn.
ps leuk dat het project nog stilletjes aan doorgaat, volgde het andere topic met veel interesse.

[Bericht gewijzigd door Titatommeke op dinsdag 4 juni 2019 18:30:45 (46%)

buckfast_beekeeper

Golden Member

Ik ben nu niet thuis, kan dus niet aan de code. Ik heb in mijn lib voor lcd displays een routine gestoken waarmee je kan aangeven uit hoeveel karakters een getal moet bestaan. Je kan met een boolean ook aangeven of je een voorlopende 0 wil of niet. Ik zoek het morgen vroeg even op.

Van Lambiek wordt goede geuze gemaakt.

Op 4 juni 2019 17:49:40 schreef blackdog:

c code:


hum = mySensor.readFloatHumidity(), 0;                              

Die ',0' kan weg, want hij doet niets. Compiler zal hem wegoptimaliseren.

Bij waarden kleiner dan 10 worden de digits niet op de gewenste plaatst getoond, zie op het plaatje de seconde positie "1".

Ik denk dan b.v. voor ieder item, dus uren, minuten en seconden een if/els op te nemen om te kijken of er een extra "0" nodig is.
Misschien hebben jullie ene inteligentere manier?

if/else kan. De gebruikelijke manier in C (ook embedded C, maar arduino is soms een buitenbeentje) is de printf-formatting te gebruiken.

Als je bovenaan #include <stdio.h> opneemt, dan kun je de snprintf functie gebruiken:

c code:


char buf[10];
snprintf(buf, 10, "%02i", dt.second);
u2g8.print(buf);

Google "printf formatting codes" voor de betekenis van die "%02i". Dat zul je met enige regelmaat doen zodra je snprintf gaat gebruiken (of print de lijst uit naast je PC, kan ook)

blackdog

Golden Member

Hi,

blurp
Ik had geen zin mijn klokje van de goede tijd te halen maar de seconden en minuten lopen nu goed met je voor gestelde code. :-)

Ik heb met Google gezocht, maar net snel gegevens gevonden hoe de "printf-formatting" nu eigenlijk werkt.
Zal er nog eens naar zoeken, ik heb altijd in het begin Jip en Janneke voorbeelden nodig om het eerste stukje te gaan begrijpen.
Zo'n uitleg voor de printf-formatting heb ik vandaag nog niet gevonden.

Bij analoge electronica gaat dit bijna vanzelf als ik iets extra wil leren. :-)
Ondanks dat ik programmatjes maken leuk vind voor mijn meetinstrumentjes, blijft het moeilijk voor mij.

Dit is de code zoals hij nu is en ik kan nu verder gaan met de volgende stap.

c code:

#include <Arduino.h>
#include <U8g2lib.h>
#include <Wire.h>
#include <DallasTemperature.h>
#include <DS3231.h>
#include "SparkFunBME280.h"
#include <stdio.h>

U8G2_SH1106_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE);

BME280 mySensor;

DS3231 clock;
RTCDateTime dt;

float tmp = 0;
float hum = 0;

unsigned long currentTime;
unsigned long loopTime;




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

Wire.begin();
  
mySensor.setI2CAddress(0x76);
mySensor.beginI2C();
  
mySensor.setFilter(4);                          //0 to 4 is valid. Filter coefficient. See 3.4.4
mySensor.setStandbyTime(7);                     //0 to 7 valid. Time between readings. See table 27.

mySensor.setTempOverSample(16);                 //0 to 16 are valid. 0 disables temp sensing. See table 24.
mySensor.setPressureOverSample(16);             //0 to 16 are valid. 0 disables pressure sensing. See table 23.
mySensor.setHumidityOverSample(16);             //0 to 16 are valid. 0 disables humidity sensing. See table 19.
  
mySensor.setMode(MODE_NORMAL);                  //MODE_SLEEP, MODE_FORCED, MODE_NORMAL is valid. See 3.3

// Initialize DS3231
Serial.println("Initialize DS3231");;
clock.begin();

// Start display
u8g2.begin();

//Timing setup for Temperature measurement samples
currentTime = millis();
loopTime = currentTime;
}







void loop(void) {

dt = clock.getDateTime();
  
u8g2.clearBuffer();					                             // clear the internal memory
u8g2.drawRFrame(0,0,128,14,6);

// Set logo aan de bovenzijde van het display
u8g2.setFont(u8g2_font_ncenB08_tr);	                     // choose a suitable font
u8g2.drawStr(0,12,"  ****                       ****");	 // write something to the internal memory
u8g2.drawStr(0,10,"            NoiseAmp ");              // write something to the internal memory


// Plaatst het aantal uren van de DS3231 klok IC op het display
u8g2.setCursor(0,35);
char uur[10];
snprintf(uur, 10, "%02i", dt.hour);
u8g2.print(uur);

// Plaatst de eerste dubbele punt van het DS3231 klok IC op het display
u8g2.drawStr(12,35,":");

// Plaatst het aantal minuten van de DS3231 klok op het display
u8g2.setCursor(15,35);
char min[10];
snprintf(min, 10, "%02i", dt.minute);
u8g2.print(min);

// Plaatst de tweede dubbele punt van het DS3231 klok IC op het display
u8g2.drawStr(28,35,":");

// Plaatst het aantal seconden van de DS3231 klok op het display
u8g2.setCursor(31,35);
char sec[10];
snprintf(sec, 10, "%02i", dt.second);
u8g2.print(sec);

 
// code voor het één maal in de 25 seconde uitlezen van de temperatuur en de luchtvochtigheidsgraad
currentTime = millis();
if(currentTime >= (loopTime + 25000)){                           // Every 25 second measure temperature
  
hum = mySensor.readFloatHumidity();                              // plaats vochtigheidsgraad in tijdelijke variabele "hum" 
tmp = mySensor.readTempC();                                      // plaats temperatuur in tijdelijke variabele "tmp"

loopTime = currentTime;                                          // Updates loopTime
}


u8g2.drawStr(0,45,"H = : ");
u8g2.setCursor(38,45);
u8g2.print(hum),2;                                               // Plaatst de vochtigheidswaarde op het scherm

u8g2.drawStr(0,55,"T  = : ");
u8g2.setCursor(38,55);     
u8g2.print(tmp), 2;                                             // Plaatst de temperatuur op het scherm

 
u8g2.sendBuffer();                                              // Plaatst de vochtigheidswaarde op het scherm
delay(400);
  

}

Dank!

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.
KGE

Golden Member

Je kunt snprintf ook meerdere getallen in één keer laten schrijven in een string, scheelt een hoop regels.
Zoiets als dit:

c code:


// buffer voor tijdaanduiding
char buffer[30];

// positie op display
u8g2.setCursor(0,35);

// zet uren, minuten, seconden en dubbele punten in buffer
snprintf(buffer,30,"%02i:%02i:%02i",dt.hour,dt.minute,dt.second);

// laat zien op het display
u8g2.print(buffer);

code:


u8g2.print(hum),2;        

De ,2 is ook hier niet goed. Kun je net zo goed weglaten.
Het lijkt wel te werken maar de print() funktie geeft bij default altijd al 2 decimals voor float getallen.

Als je het aantal decimalen wilt aanpassen dan moet dat binnen de haakjes:

code:


u8g2.print(hum,3);        

snprintf() is wel een handig format funktie. Even in het kort:

De funktie wordt gebruikt om een text string te genereren.
De eerte 2 parameters geven het adres en de lengte van een buffer in ram waar het resultaat wordt weggeschreven. De lengte is belangrijk want de resulterende string wordt daardoor beperkt tot de beschikbare ruimte in de string. Je moet wel een buffer aanmaken die groot genoeg is.

De derde parameter is een text string. Die is ook verplicht:

code:


char buffer[30];
snprintf(buffer, sizeof(buffer), "Test");

In principe wordt de string naar de buffer gecopieerd.
Na de derde parameter kun je optioneel extra parameters toevoegen. maar die worden alleen gebruikt als er binnen de string een format specifier staat. Zo een format specifier begint altijd met een '%' teken en wordt gevolgd door een type. Dus %d (of %i) voor een integer, %f voor een float en %s voor een string.

code:


char buffer[30];
snprintf(buffer, sizeof(buffer), "Uren %d, Minuten %d, Seconden %d", 1,2,3 );

Dit geeft als resultaat : "Uren 1, Minuten 2, Seconden 3" (en past nog precies in de buffer van 30 bytes).

En tussen de % en het type kun je nog een getal zetten om de minimale lengte van het getal aan te geven.

code:


char buffer[30];
snprintf(buffer, sizeof(buffer), "Uren %3d", 2);

geeft als resultaat : "Uren     2" want standaard worden er spaties toegevoegd om de gewenste lengte te krijgen. Als je liever voorloopnullen wilt dan moet je dat aangeven door een extra 0 in de format string : "Uren %03d".

Voor floats kun je ook het aantal decimalen opgeven.

code:


char buffer[30];
snprintf(buffer, sizeof(buffer), "H = : %6.2f", hum);
u8g2.drawStr(0,45,buffer);

Probleem met de printf() is wel dat je heel vreemde resultaten kunt krijgen als je fouten maakt, bijvoorbeeld door een %f te gebruiken voor een integer getal of voor een string, of %d voor een float, en ook als je te veel of te weinig format specifiers in je string hebt.

blackdog

Golden Member

Hi,

Mooi!
Ik heb jullie info in een stukje basis code gezet voor het uitlezen van de klok en dit ook netjes op een scherm te plaatsen.
Deze code voor de klok is dan een sjabloon voor ook andereprojecten.
De uitleg van deKees heb ik in een tekstfile geplaatst om het later nog een keer te kunnen doornemen.
Tot nog toe is dit de beste uitleg die ik ben tegengekomen van de "sprintf" functie.

Deze sketch ga ik dan als een basis gebruiken om de alarm functie van de DS3231 te testen.
Dat kan ik nu niet goed testen, omdat ik geen echte verbinding kan maken met de DS3231 die ik hier beschikbaar heb.
Kan alleen hier een draadje of mijn multimetertje tegen de pen van het smd chipje zetten,
wat niet echt confortabel als ik mijn microcontroler uit zijn slaap wil halen of wil testen met een LED.

De tip die rew gaf i.v.m. het 49 dagen millis probleem ga ik ook in een ander stukje code testen en opslaan.
Ook dit moet aan de hand van een voorbeeld, hier het uitlezen van de luchtdruk en luchtvochtigheidsgraad van een BME280 sensor.
Als ik dan een database van wat voorbeelden heb zal het schijven van de code een stuk makkelijker worden.

c code:

//   Formatteren van tekst DS3231 klok IC op een 128x64 pixel OLED i2c display
//   De DS3231 Driver is van: https://github.com/JChristensen/DS3232RTC
//   De Display driver is van: https://github.com/olikraus/u8g2/wiki
//   Getest met Adafruit Feather M0

#include <Wire.h>
#include <U8g2lib.h>
#include <DS3231.h>

U8G2_SH1106_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE);

DS3231 clock;
RTCDateTime dt;


void setup(void) {

// Start i2c
Wire.begin();
  
// Start DS3231
clock.begin();

// Start display
u8g2.begin();
}


void loop(void) {

// Plaatst actuele tijd in de variabele "dt"
dt = clock.getDateTime();

// Maakt de schermbuffer leeg
u8g2.clearBuffer();

// Tekend kader in het scherm buffer
u8g2.drawRFrame(0,0,128,14,6);

// Set het "NoiseAmp" logo aan de bovenzijde van het display en kies een font voor het logo
u8g2.setFont(u8g2_font_ncenB08_tr);
u8g2.drawStr(0,12,"  ****                       ****");
u8g2.drawStr(0,10,"            NoiseAmp ");

// aanmaak van "snprintf" buffer voor het formatteren van de tijdaanduiding
char buffer[30];
 
// bepaald positie op display voor de tijd, "0" is de kolom en "35" is het aantal pixels vanaf boven en kies een font voor de klok
u8g2.setCursor(0,45);
u8g2.setFont(u8g2_font_px437wyse700b_mn);
 
// zet uren, minuten, seconden en dubbele punten in de "buffer" van snprintf
snprintf(buffer,30,"%02i:%02i:%02i",dt.hour,dt.minute,dt.second);
 
// Plaats de //   Formatteren van tekst DS3231 klok IC op een 128x64 pixel OLED i2c display
//   De DS3231 Driver is van: https://github.com/JChristensen/DS3232RTC
//   De Display driver is van: https://github.com/olikraus/u8g2/wiki
//   Getest met Adafruit Feather M0

#include <Wire.h>
#include <U8g2lib.h>
#include <DS3231.h>

U8G2_SH1106_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE);

DS3231 clock;
RTCDateTime dt;


void setup(void) {

// Start i2c
Wire.begin();
  
// Start DS3231
clock.begin();

// Start display
u8g2.begin();
}


void loop(void) {

// Plaatst actuele tijd in de variabele "dt"
dt = clock.getDateTime();

// Maakt de schermbuffer leeg
u8g2.clearBuffer();

// Tekend kader in het scherm buffer
u8g2.drawRFrame(0,0,128,14,6);

// Set het "NoiseAmp" logo aan de bovenzijde van het display en kies een font voor het logo
u8g2.setFont(u8g2_font_ncenB08_tr);
u8g2.drawStr(0,12,"  ****                       ****");
u8g2.drawStr(0,10,"            NoiseAmp ");

// aanmaak van "snprintf" buffer voor het formatteren van de tijdaanduiding
char buffer[30];
 
// bepaald positie op display voor de tijd, "0" is de kolom en "35" is het aantal pixels vanaf boven en kies een font voor de klok
u8g2.setCursor(0,45);
u8g2.setFont(u8g2_font_px437wyse700b_mn);
 
// zet uren, minuten, seconden en dubbele punten in de "buffer" van snprintf
snprintf(buffer,30,"%02i:%02i:%02i",dt.hour,dt.minute,dt.second);
 
// Plaats de "snprintf" bufferinhoud in het schermbuffer
u8g2.print(buffer);

// Plaatst de schermbuffer inhoud naar het scherm
u8g2.sendBuffer();

delay(100);
} bufferinhoud in het schermbuffer
u8g2.print(buffer);

// Plaatst de schermbuffer inhoud naar het scherm
u8g2.sendBuffer();

delay(100);
}

Natuurlijk weer dank voor de hulp en als laatste studio.h schijn ik niet nodig te hebben, klopt dit?

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.

studio.h schijn ik niet nodig te hebben, klopt dit?

De arduino heeft geen standaard input en/of output apparaat. Daarom hoef je het niet toe te voegen volgens mij. Als het moet runnen op je pc dan wel.

zie ook:https://forum.arduino.cc/index.php?topic=144685.0

stdio.h heb je in principe wel nodig, want daarin wordt de snprintf() funktie gedeclareerd. Zonder declaratie gaat dat nooit werken. Maar waarschijnlijk komt stdio.h al mee met de andere header files.

Wel leuk dat je die vraag stelt. Ik zie nu dat er ook een variant snprintf_P() bestaat die de format string uit PROGMEM haalt. Ik wist niet dat die bestaat.

De uitleg van snprintf() hier is erg beknopt. Dat geeft maar een klein deel van de mogelijkheden, maar wel genoeg om te beginnen.

[Bericht gewijzigd door deKees op woensdag 5 juni 2019 20:14:33 (20%)

blackdog

Golden Member

Hi,

Ik heb de opmerking over "stdio.h" opgenomen in de voorbeeld code, zodat als nodig dat ik er aan herinnert word.

Nog iets, Doordat alles nu op één regel word weggeschreven heb ik maar één positie regel commando nodig.
Jullie kunen je wel voorstelen dat dit erg veel tijd scheeld als ik met font type en grotes bezig ben!

Plaatje om te laten zien dat het gelukt is, jammer genoeg is het hier nog geen 00:00:00
maar omdat de minuten en de seconde kloppen geloof ik de uren wel :-)

De weergegeven namen zijn random, iedereen dus bedankt!

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.

Hoi blackdog,

offtopic vraagje, je hebt daar een bijzonder breadbordje met IC gootjes dwars op de richting die ik normaal zie. Dat lijkt mij een handige layout.
Weet je toevallig hoe dat heet of waar te vinden?

Action expresses priorities LH
blackdog

Golden Member

Hi LetterHenk, :-)

Dat was even zoeken, ik had in mijn hoofd dat het breadboard bij Farnell vandaan komt...
Dat was ook zo, maar ze leveren het niet meer.

Maar ik ben op mijn bestelbon het typenummer tegen gekomen en het is een product van Wolfson en zoek met deze tekst
er naar met je zoekmachine "WBU-501 ebay.com"

Ondermeer TME moet hem kunnen leveren.

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.