arduino i2c probleem

goedenavond heren.
Ben op het moment bezig met het programmeren van een motor. Deze moet een bepaalde tijd een bepaalde snelheid kunnen draaien. Nu heb ik een display 128x32 i2c. Hier heb ik nu het volgende staan:
Rotary tumbler
Snelheid; 0 % <
Tijd; 0 Minuten <

Nu heb ik er ook een potmeter en een button op aangesloten. Met de potmeter kan ik dan de snelheid of tijd wijzigen. En met de button kan ik selecteren wat ik wil wijzigen (snelheid of tijd). De selectie moet dan weergegeven worden op het display door achter tijd of snelheid een "<" te zetten. Nu heb ik het probleem dat bij beide regels een "<"staat.

Wat doe ik fout en hoe kan ik ervoor zorgen dat ik dit goed krijg?
Dit is mijn eerste keer met i2c displays op arduino.

de code is als volgt:

code:



#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

#define OLED_RESET 4
Adafruit_SSD1306 display(OLED_RESET);


 int Motorpin = 3; //pwmpin
 int Potmeter = A1;
int motorspeed = 0;
int tijd = 0;
int button = 2;
int buttonstate = HIGH;
int reading;
int previous = LOW;
long time = 0;         // the last time the output pin was toggled
long debounce = 200;   // the debounce time, increase if the output flickers

void setup() 
{
display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
display.clearDisplay();
pinMode(Potmeter, INPUT);
pinMode(button, INPUT);
pinMode(Motorpin, OUTPUT);
}

void loop() 
{
      reading = digitalRead(button);

    // if the input just went from LOW and HIGH and we've waited long enough
    // to ignore any noise on the circuit, toggle the output pin and remember
    // the time
    if (reading == HIGH && previous == LOW && millis() - time > debounce) 
{
    if (buttonstate == HIGH)
        buttonstate = LOW;
    else
        buttonstate = HIGH;

    time = millis();    
}

previous = reading;
    
if (buttonstate == HIGH);
{

  display.setCursor(122,10);
  display.println("<");
}

if (buttonstate == LOW);
{
  display.setCursor(122,20);
  display.println("<");
}

   display.setTextSize(1);
  display.setTextColor(WHITE);

  display.setCursor(0,0);
  display.println("Rotary tumbler");
  
  display.setCursor(0,10);
  display.println("Snelheid :");
  
  display.setCursor(0,20);
  display.println("Tijd     :");
  
  display.setCursor(60,10);
  display.println(motorspeed);
  
  display.setCursor(60,20);
  display.println(tijd);

  display.setCursor(80,10);
  display.println("%");
  
  display.setCursor(80,20);
  display.println("Minuten");
  display.display();
  

}


  



(zie foto voor display)

buckfast_beekeeper

Golden Member

Je wist de '<' nergens. Als je de tekst bij de ene zet moet die bij de andere gewist worden.

Ondertussen gebeurd:
Zet je code ook even tussen code tags. Dan is die stukken beter leesbaar. Velen haken hier al af als het in plain tekst staat.

Van Lambiek wordt goede geuze gemaakt.

is het verstandig om te doen:

code:



if (buttonstate == HIGH);
{

  display.setCursor(122,10);
  display.println("<");
  display.setCursor(122,20);
  display.println("");
}

if (buttonstate == LOW);
{
  display.setCursor(122,20);
  display.println("<");
  display.setCursor(122,10);
  display.println("");
}

en waar kan ik dit het beste plaatsen?

met vriendelijke groeten, Sven

buckfast_beekeeper

Golden Member

Je moet een " " spatie op je display zetten om het vorige karakter te wissen.

Van Lambiek wordt goede geuze gemaakt.

Dit geprobeerd. Helaas staat het display nog steeds met bij elke regel een "<". Wat zou hiervan het probleem in mijn code zijn? hoe los ik dit op.

Met vriendelijke groeten,
Sven

Arco

Special Member

Stuur gewoon de hele regel naar het display, inclusief spaties en pijltjes, dan klopt 't altijd...
I2C is niet echt de beste keuze voor grafische displays: het is traag...

[Bericht gewijzigd door Arco op maandag 17 augustus 2020 21:48:27 (27%)

Arco - "Simplicity is a prerequisite for reliability" - hard-, firm-, en software ontwikkeling: www.arcovox.com

Heb deze code erin geschoten:

code:




#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

#define OLED_RESET 4
Adafruit_SSD1306 display(OLED_RESET);


 int Motorpin = 3; //pwmpin
 int Potmeter = A1;
int motorspeed = 0;
int tijd = 0;
int button = 2;
int buttonstate = HIGH;
int reading;
int previous = LOW;
long time = 0;         // the last time the output pin was toggled
long debounce = 200;   // the debounce time, increase if the output flickers

void setup() 
{
display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
display.clearDisplay();
pinMode(Potmeter, INPUT);
pinMode(button, INPUT);
pinMode(Motorpin, OUTPUT);
}

void loop() 
{
      reading = digitalRead(button);

    // if the input just went from LOW and HIGH and we've waited long enough
    // to ignore any noise on the circuit, toggle the output pin and remember
    // the time
    if (reading == HIGH && previous == LOW && millis() - time > debounce) 
{
    if (buttonstate == HIGH)
        buttonstate = LOW;
    else
        buttonstate = HIGH;

    time = millis();    
}

previous = reading;
    
if (buttonstate == HIGH);
{
  display.clearDisplay();
  display.setCursor(122,10);
  display.println("<");
  display.setCursor(122,20);
  display.println(" ");
}

if (buttonstate == LOW);
{
    display.clearDisplay();
  display.setCursor(122,20);
  display.println("<");
  display.setCursor(122,10);
  display.println(" ");
}



   display.setTextSize(1);
  display.setTextColor(WHITE);

  display.setCursor(0,0);
  display.println("Rotary tumbler");
  
  display.setCursor(0,10);
  display.println("Snelheid :");
  
  display.setCursor(0,20);
  display.println("Tijd     :");
  
  display.setCursor(60,10);
  display.println(motorspeed);
  
  display.setCursor(60,20);
  display.println(tijd);

  display.setCursor(80,10);
  display.println("%");
  
  display.setCursor(80,20);
  display.println("Minuten");
  display.display();
 
  

}


  



Nu heb ik alleen bij minuten een "<". Dit is al een stap in de goede richting. Maar wanneer ik nu D2 hoog maak (of laag), zie ik geen verandering. Ik wil dat dan het pijltje 1 regel naar boven gaat. (zie foto).
Waar zou dit aan kunnen liggen?
Met vriendelijke groeten,

Sven

Arco

Special Member

Het is trouwens veel simpeler en duidelijker om het pijltje voor de tekst te zetten i.p.v. erachter, omdat tekst niet altijd even lang is.
Ik doe het meestal zo: (ik gebruik wel meestal een 'dicht' pijltje, is duidelijker...)

code:


  1.Regel 1
  2.Regel 2
> 3.Regel 3
  4.Regel 4
Arco - "Simplicity is a prerequisite for reliability" - hard-, firm-, en software ontwikkeling: www.arcovox.com
buckfast_beekeeper

Golden Member

c code:

if (reading == HIGH && previous == LOW && millis() - time > debounce) 
{
    if (buttonstate == HIGH)
        buttonstate = LOW;
    else
        buttonstate = HIGH;

    time = millis();    
}
previous = reading;

Volgens mij wordt dit niet uitgevoerd. Zodra je knop deftig is ingedrukt, krijg je nooit meer een previous == LOW.

Het gevolg is dat buttonstate altijd LOW zal zijn. Maak van die previous == LOW eens HIGH.

Edit: zet eens een println in je if. Dan weet je tenminste zeker dat je if effectief wordt uitgevoerd.

[Bericht gewijzigd door buckfast_beekeeper op dinsdag 18 augustus 2020 21:40:49 (10%)

Van Lambiek wordt goede geuze gemaakt.

c code:

if (reading == HIGH && previous == LOW && millis() - time > debounce) 

Trouwens, hier zou ik wat extra haakjes tussen zetten:

ik ben altijd bang dat de compiler dit leest als

c code:

millis() - (time > debounce)

en ook de rest doe ik extra haakjes bij. Worst case ziet de compiler:

c code:

reading == (HIGH && previous) == LOW

Het kan zijn dat de prioriteiten van de operators er voor zorgen dat dit nooit gebeurt, maar ik ben een keer in het verleden er in getrapt. Toen bleek dat de ene compiler het zus en de andere compiler het zo deed. Daarvan heb ik geleerd: Niet meer op prioriteiten vertrouwen, altijd extra haakjes.

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

goedenavond mannen, ik was vanavond weer even bezig met het programmeren van de motor. op internet heb ik via de volgende link: https://github.com/inflop/Countimer een mooie functie gezien voor het instellen van de tijd.

De volgende hardware heb ik voor de motor:
1 knop voor het instellen van de uren
1 knop voor het instellen van de minuten
1 knop voor het instellen van de seconden
1 knop voor het starten van de motor(nadat de tijd is ingesteld)
en een oled display 128 x 32.
Wanneer de relaispin hoog is draait de motor. De relaispin moet dus hoog zijn wanneer ik op de startknop druk en laag wanneer de timer op 00:00:00 staat.

Ook heb ik de volgende code in arduino:

code:


#include "Countimer.h"
int buttonA = 2; //button voor instellen uren
int buttonB = 3; //button voor instellen minuten
int buttonC = 4; //button voor instellen secondes
int buttonD = 5;  //Start button
int A = 1;
int B = 0;
int C = 0; 
int readingA = 0;
int readingB = 0;
int readingC = 0;
int readingD = 0;
int relaispin = 6; //Pin naar relais
#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

#define OLED_RESET 4
Adafruit_SSD1306 display(OLED_RESET);
Countimer timer;

void setup() {
display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
display.clearDisplay();
pinMode(buttonA, INPUT); //ingang voor uren button
pinMode(buttonB, INPUT); //ingang voor minuten button
pinMode(buttonC, INPUT); //ingang voor seconden button
pinMode(buttonD, INPUT); //ingang voor startbutton
pinMode(relaispin, OUTPUT); //uitgang naar relais
Serial.begin(9600); //begin serial monitor
timer.setCounter(A, B, C, timer.COUNT_DOWN, onComplete); //instellen timer
// Print current time every 1s on serial port by calling method refreshClock().
timer.setInterval(refreshClock, 1000);
}

void refreshClock() {
Serial.print("Current count time is: ");
Serial.println(timer.getCurrentTime());
display.setTextSize(1);
display.setTextColor(WHITE);
display.setCursor( 40, 20 );
display.print(timer.getCurrentTime());
display.display();
display.clearDisplay(); 
}

void onComplete() {
Serial.println("Complete!!!");
display.setTextSize(1);
display.setTextColor(WHITE);
display.setCursor( 40, 20 );
display.print("DONE");
display.display();
display.clearDisplay(); 
digitalWrite(relaispin, LOW); //hier zetten we de motor uit
}

void loop() {
// Run timer
readingD = digitalRead(buttonD); 
if (readingD ==HIGH);{
timer.run();
}
// Now timer is running and listening for actions.
// If you want to start the timer, you have to call start() method.

if(!timer.isCounterCompleted()) {
timer.start();
}


}

Nu probeer ik alvast ervoor te zorgen dat de timer pas start wanneer ik op de startknop druk maar dit wilt helaas niet werken.

Kan iemand mij opweg helpen met de code zodat ik dit kan laten werken? Dus 3 knoppen voor het instellen van de tijd en 1 knop voor het starten van de motor.

met vriendelijke groeten,

Sven

Je "if" statement heeft een puntkomma teveel.

c code:

if (readingD ==HIGH);{
timer.run();
}

Moet zijn:

c code:

if (readingD ==HIGH){
timer.run();
}

Op 27 augustus 2020 10:35:26 schreef coldrestart:
Je "if" statement heeft een puntkomma teveel.

c code:

if (readingD ==HIGH);{
timer.run();
}

Meestal geeft een ; te veel of te weinig een hoop foutmeldingen, maar een enkele keer verandert de betekenis van je programma significant.

Er staat nu:

c code:


if (readingD ==HIGH)
   /* Do nothing special */;
{
  timer.run();
}
four NANDS do make a NOR . Kijk ook eens in onze shop: http://www.bitwizard.nl/shop/

code:


if (readingD ==HIGH)
   /* Do nothing special */;
{
  timer.run();
}

Dat betekent dus dat de puntkomma na het comment "Do nothing special" afhankelijk wordt van readingD, en het blok met timer.run(); altijd wordt uigevoerd, onafhankelijk van de if. Ik zou hier wel een waarschuwing van de compiler verwachten trouwens. Compilers zien dit vaak als 'verdacht en waarschijnlijk niet goed.

In C (en C++) mag je zoveel puntcomma's toevoegen als je wilt, en je mag ook krulhaakjes toevoegen, zoveel als je wilt. Krulhaakjes kun je gebruiken om een context te maken voor locale variabelen die weer weg zijn als het blok wordt gesloten.

Oh, daar heb ik het pas nog met de Gcc-gasten over gehad.

Het gebeurt tegenwoordig regelmatig dat de compiler na wat optimalisaties ziet dat een if altijd "false" wordt of misschien heb je een

code:


if (iets_semi_raars) 
   DEBUG_PRINTF ("Semi-raar gebeurt nu!\n");

waarbij je voor niet-debuggen dus

code:


#define DEBUG_PRINTF() /*nothing*/

doet. En zie daar precies de code waarvan je een waarschuwing had verwacht. Tja. Dit is dus te "normaal" om daar een waarschuwing van te maken: Het kan makkelijk in normale code voorkomen die eigenlijk zonder waarschuwingen door de compiler moet kunnen komen....

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

STM32CubeIDE

code:


   if(tickStart == 1000);
   {  CDC_Flush();
   }

Geeft toch een warning:

../Core/Src/Main.cpp:120:10: warning: this 'if' clause does not guard... [-Wmisleading-indentation]
if(tickStart == 1000);
^~
../Core/Src/Main.cpp:121:10: note: ...this statement, but the latter is misleadingly indented as if it were guarded by the 'if'
{ CDC_Flush();

Maar dat kan wel afhangen van de warning levels in de compiler settings.

Oke, de startknop werkt. wanneer ik nu de volgende code uploadt, krijg ik 01:00:00 te zien. Maar wanneer ik nu buttonA, button B, of button C indruk, verandert de waarde op het display niet. Weet iemand de oorzaak hiervan? En hoe kan ik de drukknoppen optimaal laten werken zodat er per druk op de knop de tijdwaarde met 1 omhoog gaat en niet met 4 bijvoorbeeld (antibounce).

code:


#include "Countimer.h"
int buttonA = 2; //button voor instellen uren
int buttonB = 3; //button voor instellen minuten
int buttonC = 4; //button voor instellen secondes
int buttonD = 5;  //Start button
int A = 1; //uren
int B = 0; //minuten
int C = 0;  //seconden
int readingA = 0;
int readingB = 0;
int readingC = 0;
int readingD = 0;
int relaispin = 6; //Pin naar relais
#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

#define OLED_RESET 4
Adafruit_SSD1306 display(OLED_RESET);
Countimer timer;

void setup() {
display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
display.clearDisplay();
pinMode(buttonA, INPUT); //ingang voor uren button
pinMode(buttonB, INPUT); //ingang voor minuten button
pinMode(buttonC, INPUT); //ingang voor seconden button
pinMode(buttonD, INPUT); //ingang voor startbutton
pinMode(relaispin, OUTPUT); //uitgang naar relais
Serial.begin(9600); //begin serial monitor
timer.setCounter(A, B, C, timer.COUNT_DOWN, onComplete); //instellen timer
// Print current time every 1s on serial port by calling method refreshClock().
timer.setInterval(refreshClock, 1000);
}

void refreshClock() {
Serial.print("Current count time is: ");
Serial.println(timer.getCurrentTime());
display.setTextSize(1);
display.setTextColor(WHITE);
display.setCursor( 40, 20 );
display.print(timer.getCurrentTime());
display.display();
display.clearDisplay(); 
}

void onComplete() {
Serial.println("Complete!!!");
display.setTextSize(1);
display.setTextColor(WHITE);
display.setCursor( 40, 20 );
display.print("DONE");
display.display();
display.clearDisplay(); 
digitalWrite(relaispin, LOW); //hier zetten we de motor uit
}

void loop() {
// Run timer
readingA = digitalRead(buttonA);
readingB = digitalRead(buttonB);
readingC = digitalRead(buttonC);
readingD = digitalRead(buttonD); 
timer.run();

if (readingA ==HIGH)
{
(A+1);
}

if (readingB == HIGH)
{
(B+1);
}

if (readingC == HIGH)
{
(C+1);
}

if (A >= 99)
{
 A = 99; //max uren begrenzen
}

if (B >= 59)
{
 B = 59; //max minuten begrenzen
}

if (C >= 59)
{
 C = 59; //max secondes begrenzen
}


if(readingD == HIGH){
timer.start();
digitalWrite(relaispin, HIGH); //hier zetten we de motor aan
} 
}

Nog steeds niet de waardes omhoog kunnen krijgen. Weet iemand wat ik hier fout doe?

met vriendelijke groeten,

Sven

In je "loop" worden alleen de variabelen timerA enz. opgehoogd. De waardes worden nooit naar het display geschreven. Daarnaast gaat bij het drukken van een toets de waarde niet met 1 verhogen, maar telkens als de "loop" doorlopen wordt (dit kan makkelijk 1000 maal/s) zijn.
Tip : begin eerst met één toets en één variabele om op te hogen. Zoek eens naar het begrip "flank" detectie. En denk eraan, de "loop" wordt 1000 den maal/sec doorlopen, dus als je toets 100 ms ingedrukt houdt, zal het programma op die plaats mogelijk de opdracht 100 maal uitvoeren !

Maar wanneer ik bijvoorbeeld Waarde A ophoog verander ik toch ook de tijdwaarde? En die tijdwaarde wordt dan weer weergegeven op het scherm.

Ik zal even kijken naar de flank detectie
dank

buckfast_beekeeper

Golden Member

Persoonlijk zou ik buttonA... buttonD vervangen door een duidelijke naam. btnUren, btnMinuten, btnSec, btnStart. Weet je verderop in het programma ook met welke knop je nu aan de slag gaat. Net zo voor A, B, C... veel cryptischer kan het niet. In een kort programma kom je er nog wel uit maar als het wat meer wordt, geraak je snel de weg kwijt.

Laat je code ook inspringen zodat deze leesbaarder wordt.

c code:


void setup(){
   if(vergelijking){
       doe wat
   }
   else{
      if(wat anders){
          doe wat anders
      }
      else if (weer wat anders{
          doe weer wat anders
      }
   }
}

Zo is direct duidelijk wat de scope is van dat bepaald stukje code.

c code:


if (readingA ==HIGH){
    (A+1);
}

Je gaat een int vergelijken met een boolean. Gaat dat goed? A+1 werkt volgens mij ook niet. Moet dat niet zijn A=A+1 of A+=1 of A++
Persoonlijk zou ik schrijven

c code:


if (readingA == 1){
    (A++);
}

edit: wat RP6conrad zegt klopt uiteraard ook. Je moet je programma laten wachten tot de knop is losgelaten. En dan je waarde wegschrijven naar timer.setcounter

c code:


void refreshClock() {
    Serial.print("Current count time is: ");
    Serial.println(timer.getCurrentTime());
    display.setTextSize(1);
    display.setTextColor(WHITE);
    display.setCursor( 40, 20 );
    display.print(timer.getCurrentTime());
    display.display();
    display.clearDisplay(); 
}

Dit gaat ook niet doen wat je wil. Je gaat zaken op het display zetten en direct erna ga je het display terug wissen. Wat is het nut daarvan? De clear verwacht je bij het begin van de refresh(). Het nadeel is dat je een flikkerend display krijgt. Je kan beter alleen de gegevens wijzigen die nodig zijn. Of gewoon alle gegevens terug schrijven. Duurt niet gigantisch lang. Hoewel een gewoon LCD nu ook weer niet vliegensvlug is.

edit 2:
debounce kan je voor een groot deel ondervangen door een delay_ms(200) te voorzien

c code:


if(BTN_LOW){
   delay_ms(200);
   While(BTN_LOW){
      waarde++;
      delay_ms(200);
      if(waarde > MaxWaarde){
          waarde = 0;
      }
   }
}

Zodra je op de knop duwt en je programma passeert voor het eerst deze passage, gaat er 200ms gewacht worden om contactdender weg te werken. Zodra is de knop dan nog laag, dan wordt de waarde verhoogd en wordt er weer 200ms gewacht. Is de knop nog steeds ingedrukt wordt de waarde weer verhoogd. Zodra de max waarde overschreden is begint het tellen vanaf 0. Uiteraard kan je de wachttijden aanpassen aan je eigen gevoel.

[Bericht gewijzigd door buckfast_beekeeper op zondag 30 augustus 2020 09:41:51 (15%)

Van Lambiek wordt goede geuze gemaakt.

code:


(A+1);

Dat werkt natuurlijk niet. Je berekent wel A+1, maar vervolgens doe je niks met het resultaat. A verandert hier dus niet.

Dat kan wel zo:

code:


A = (A+1);
A++;
A += 1;

Hoe komt het trouwens dat de indenting niet werkt? De Je code wordt zo wel erg moeilijk leesbaar.

hopelijk is dit duidelijker:

code:


#include "Countimer.h"
int btnhours = 2; //button voor instellen uren
int btnminutes = 3; //button voor instellen minuten
int btnseconds = 4; //button voor instellen secondes
int btnstart = 5;  //Start button
int hourvalue = 1; //uren
int minutevalue = 0; //minuten
int secondsvalue = 0;  //seconden
int readinghours = 0;
int readingminutes = 0;
int readingseconds = 0;
int readingstart = 0;
int relaypin = 6; //Pin naar relais
#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

#define OLED_RESET 4
Adafruit_SSD1306 display(OLED_RESET);
Countimer timer;

void setup() {
display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
display.clearDisplay();
pinMode(btnhours, INPUT); //ingang voor uren button
pinMode(btnminutes, INPUT); //ingang voor minuten button
pinMode(btnseconds, INPUT); //ingang voor seconden button
pinMode(btnstart, INPUT); //ingang voor startbutton
pinMode(relaypin, OUTPUT); //uitgang naar relais
Serial.begin(9600); //begin serial monitor
timer.setCounter(hourvalue, minutevalue, secondsvalue, timer.COUNT_DOWN, onComplete); //instellen timer
// Print current time every 1s on serial port by calling method refreshClock().
timer.setInterval(refreshClock, 1000);
}

void refreshClock() {
Serial.print("Current count time is: ");
Serial.println(timer.getCurrentTime());
display.setTextSize(1);
display.setTextColor(WHITE);
display.setCursor( 40, 20 );
display.print(timer.getCurrentTime());
display.display();
display.clearDisplay(); 
}

void onComplete() {
Serial.println("Complete!!!");
display.setTextSize(1);
display.setTextColor(WHITE);
display.setCursor( 40, 20 );
display.print("DONE");
display.display();
display.clearDisplay(); 
digitalWrite(relaypin, LOW); //hier zetten we de motor uit
}

void loop() {
// Run timer
readinghours = digitalRead(btnhours);
readingminutes= digitalRead(btnminutes);
readingseconds = digitalRead(btnseconds);
readingstart = digitalRead(btnstart); 
timer.run();

if (readinghours = HIGH)
{
(hourvalue++);
}

if (readingminutes = HIGH)
{
(minutevalue++);
}

if (readingseconds = HIGH)
{
(secondsvalue++);
}

if (hourvalue >= 99)
{
 hourvalue = 99; //max uren begrenzen
}

if (minutevalue >= 59)
{
 minutevalue = 59; //max minuten begrenzen
}

if (secondsvalue >= 59)
{
 secondsvalue = 59; //max secondes begrenzen
}


if(readingstart = HIGH){
timer.start();
digitalWrite(relaypin, HIGH); //hier zetten we de motor aan
} 
}

Waar moet de displayclear komen?
Jammer dat op internet niet codes zijn die ik gelijk kan gebruiken voor wat ik wil/

mvg

sven

buckfast_beekeeper

Golden Member

Soms kan je iets vinden wat doet wat je exact wil. Wat leer je daar uit? Meestal is het toch zelf wat schrijven.

clearDisplay aan het begin van de void. Ik vraag me ook af of je telkens de kleur en de grootte moet instellen. Is die niet blijvend tot je ze ergens wijzigt?

Tip 1: kijk eens naar de naamgeving van je display functies. clear en display zijn normaal 2 woorden. Het is good practice elk nieuw woord met een hoofdletter te beginnen. dus btnHours ipv btnhours.
Tip 2: probeer de variabele zo klein als mogelijk te houden. Een byte is ruim voldoende voor je knoppen. Je kan ook schrijven uint8_t ipv byte.
Tip 3: de knoppen wijzigen nooit. Maak er een constante van. Neemt minder geheugen in.

if (waarde1 = waarde2) gaat niet werken. if (waarde1 == waarde2) gebruik je bij een vergelijking. Ik denk dat je in het eerste geval zelfs waarde1 gelijk gaat maken aan waarde2.

Je werkt jezelf ook in de problemen met

c code:


if (minutevalue >= 59){
   minutevalue = 59; //max minuten begrenzen
}

Je hebt geen knop om af te tellen, wil je 46 instellen en je duwt een keer te veel, kan je niet meer terug. Zorg dat er dan terug vanaf 0 geteld wordt.

c code:


if (minutevalue >= 59){
    minutevalue = 0; //max minuten begrenzen
}
Van Lambiek wordt goede geuze gemaakt.

heb nu dit geschreven met de debounce functie:

code:


#include "Countimer.h"
int btnhours = 2; //button voor instellen uren
int btnminutes = 3; //button voor instellen minuten
int btnseconds = 4; //button voor instellen secondes
int btnstart = 5;  //Start button
int hourvalue = 1; //uren
int minutevalue = 0; //minuten
int secondsvalue = 0;  //seconden
int readinghours = 0;
int readingminutes = 0;
int readingseconds = 0;
int readingstart = 0;
int relaypin = 6; //Pin naar relais
int btnstatehours;
int btnstateminutes;
int btnstateseconds;
int btnstatestart;
int lastbtnstatehours = LOW;
int lastbtnstateminutes = LOW;
int lastbtnstateseconds = LOW;
int lastbtnstatestart = LOW;
unsigned long lastDebouncehours = 0;
unsigned long lastDebounceminutes = 0;
unsigned long lastDebounceseconds = 0;
unsigned long lastDebouncestart = 0;
unsigned long debouncedelay = 50;
#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

#define OLED_RESET 4
Adafruit_SSD1306 display(OLED_RESET);
Countimer timer;

void setup() {
display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
display.clearDisplay();
pinMode(btnhours, INPUT); //ingang voor uren button
pinMode(btnminutes, INPUT); //ingang voor minuten button
pinMode(btnseconds, INPUT); //ingang voor seconden button
pinMode(btnstart, INPUT); //ingang voor startbutton
pinMode(relaypin, OUTPUT); //uitgang naar relais
Serial.begin(9600); //begin serial monitor
timer.setCounter(hourvalue, minutevalue, secondsvalue, timer.COUNT_DOWN, onComplete); //instellen timer
// Print current time every 1s on serial port by calling method refreshClock().
timer.setInterval(refreshClock, 1000);
}

void refreshClock() {
Serial.print("Current count time is: ");
Serial.println(timer.getCurrentTime());
display.setTextSize(1);
display.setTextColor(WHITE);
display.setCursor( 40, 20 );
display.print(timer.getCurrentTime());
display.display();
display.clearDisplay(); 
}

void onComplete() {
Serial.println("Complete!!!");
display.setTextSize(1);
display.setTextColor(WHITE);
display.setCursor( 40, 20 );
display.print("DONE");
display.display();
display.clearDisplay(); 
digitalWrite(relaypin, LOW); //hier zetten we de motor uit
}

void loop() {
// Run timer
readinghours = digitalRead(btnhours);
readingminutes= digitalRead(btnminutes);
readingseconds = digitalRead(btnseconds);
readingstart = digitalRead(btnstart); 
timer.run();

if (readinghours != lastbtnstatehours) {
// reset the debouncing timer               //debounce voor de uren button
lastDebouncehours = millis();
}

if ((millis() - lastbtnstatehours) > debouncedelay) {
if (readinghours != btnstatehours) {
btnstatehours = readinghours;
}
}

if (btnstatehours = HIGH)
{
(hourvalue++);
}

if (readingminutes != lastbtnstateminutes) {
// reset the debouncing timer               //debounce voor de minutes button
lastDebounceminutes = millis();
}

if ((millis() - lastbtnstateminutes) > debouncedelay) {
if (readingminutes!= btnstateminutes) {
btnstateminutes = readingminutes;
}
}
if (btnstateminutes = HIGH)
{
(minutevalue++);
}

if (readingseconds != lastbtnstateseconds) {
// reset the debouncing timer               //debounce voor de seconds button
lastDebounceseconds = millis();
}

if ((millis() - lastbtnstateseconds) > debouncedelay) {
if (readingseconds!= btnstateseconds) {
btnstateseconds = readingseconds;
}
}
if (btnstateseconds = HIGH)
{
(secondsvalue++);
}

if (hourvalue >= 99)
{
 hourvalue = 99; //max uren begrenzen
}

if (minutevalue >= 59)
{
 minutevalue = 59; //max minuten begrenzen
}

if (secondsvalue >= 59)
{
 secondsvalue = 59; //max secondes begrenzen
}

if (readingstart != lastbtnstatestart) {
// reset the debouncing timer               //debounce voor de start button
lastDebouncestart = millis();
}

if ((millis() - lastbtnstatestart) > debouncedelay) {
if (readingstart != btnstatestart) {
btnstatestart = readingstart;
}
}


if (readingstart = HIGH){
timer.start();
digitalWrite(relaypin, HIGH); //hier zetten we de motor aan
} 
}