tijdschakelaar

Arduino specifieke Software
Berichten: 88
Geregistreerd: 16 Jul 2015, 21:02

Re: tijdschakelaar

Berichtdoor wim2584 » 06 Nov 2016, 18:23

vandaag in een kastje gezet (LCD en een mini pro 168), de rest relais voeding enz komt later wel.

ik wist niet hoe je een code goed op forum zet, bedankt voor de tip.

ik had wel Ctrl-T gebruikt, misschien door knippen plakken?

voor UpdateLCD()

moet ik dan IN de loop UpdateLCD(); in de Loop zetten, en dan NA de Loop Void UpdateLCD() { }

het gebruik van" if (current - backlightTime >= Timer) " gebruik ik om backlight 10 sec aan te zetten (als er geen accu laad).
geprobeerd, de eerste keer (na reset) is de tijd willekeurig tussen 0 en 10 sec, maar daarna iedere keer 10 sec.

ik wil het backlight dus op drie manieren aan zetten

1- laden accu Rita
2- laden accu Wim
3- als er geen accu laad, druk op knop (pin 10 LOW) , dan 10 sec aan.

ik begrijp van jou dat dat nu fout is?

cpp code
// "http://arduinoforum.nl/viewtopic.php?f=8&t=2054">viewtopic.php?f=8&t=2054</a><!-- l -->
// Tested with Arduino.cc 1.6.12, Arduino Uno.
// This sketch uses a software timer of 1 second.
// changed by Wim Lemson 06-11-2016


#include <Wire.h> // Comes with Arduino IDE
#include <LiquidCrystal_I2C.h>
#define WAIT 0 // WAIT means 30 days waiting
#define CHARGE 1 // CHARGE means 10 hours charging

// set the LCD address to 0x27 for LCD display
// Set the pins on the I2C chip used for LCD connections:addr, en,rw,rs,d4,d5,d6,d7,bl,blpol

LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE); // Set the LCD I2C address

const int pinKnop[2] = { 8, 9}; // first button at pin 8, second at pin 9
const int pinUitgang[2] = { 2, 3}; // first output at pin 2, second at pin 3
const int backlightPin = 10; // backlight pushbutton pin
const int backlight = 4;

unsigned long battery_count[2]; // counter in seconds for both batteries
unsigned long backlightTime = 0; // timer for backlight LCD
const long Timer = 10000; //time in millis LCD on after active
int battery_state[2] = { WAIT, WAIT}; // state of software (waiting or charging)

// Variables for the 1 second software timer with millis()
unsigned long previousMillis;
unsigned long interval = 1000UL; // 1000 milliseconds interval

// Very short test values or real value.
// Very short test values:
//const unsigned long TenHoursInSeconds = 10UL; // 10 seconds for test
//const unsigned long ThirtyDaysInSeconds = 30UL; // 30 seconds for test
// Real values:
const unsigned long TenHoursInSeconds = 10UL * 60UL * 60UL; // 10 hours
const unsigned long ThirtyDaysInSeconds = 30UL * 24UL * 60UL * 60UL; // 30 days


void setup()
{
pinMode(backlight, OUTPUT);
pinMode(backlightPin, INPUT_PULLUP);
digitalWrite(backlight, HIGH); // during startup backlight on
Serial.begin( 9600);
Serial.println(F( "\nStarted"));

lcd.begin( 20, 4);
lcd.setCursor( 3, 0);
lcd.print(F( "Laad timer"));
lcd.setCursor( 3, 2);
lcd.print(F( "Fietsaccu's"));

delay( 3000);

lcd.clear();
lcd.setCursor( 2, 0);
lcd.print(F( "Wim Lemson"));
lcd.setCursor( 2, 1);
lcd.print(F( "november 2016"));
lcd.setCursor( 2, 2);
lcd.print(F( "30 dagen wachten"));
lcd.setCursor( 2, 3);
lcd.print(F( "10 uur laden"));

delay( 3000);

lcd.clear();
lcd.setCursor( 1, 1);
lcd.print(F( "-- Dagen --:--:--"));
lcd.setCursor( 1, 3);
lcd.print(F( "-- Dagen --:--:--"));

// A test added to tell if the test values are used.
if ( TenHoursInSeconds < ( 60UL * 60UL) || ThirtyDaysInSeconds < ( 24UL * 60UL * 60UL))
{
Serial.println(F( "Running in test mode"));
lcd.clear();
lcd.setCursor( 1, 2);
lcd.print(F( "Running in "));
lcd.setCursor( 1, 3);
lcd.print(F( "test mode"));
delay (3000);
lcd.clear();
lcd.setCursor( 1, 1);
lcd.print(F( "-- Dagen --:--:--"));
lcd.setCursor( 1, 3);
lcd.print(F( "-- Dagen --:--:--"));
}

for ( int i = 0; i < 2; i++)
{
pinMode( pinKnop[i], INPUT_PULLUP);
pinMode( pinUitgang[i], OUTPUT);
}
digitalWrite(backlight, LOW); // backlight off after setup
}
void loop()
{

// Backlight on for 10 sec
unsigned long current = millis();

if (digitalRead(backlightPin) == LOW)
{
digitalWrite(backlight, HIGH);
}
if (current - backlightTime >= Timer)
{
backlightTime = current;
digitalWrite(backlight, LOW);
}

if (digitalRead(3) == HIGH || digitalRead(2) == HIGH || digitalRead(4) == HIGH) // check of one of the accus
{ //charging or backlight timer active
digitalWrite(backlight, HIGH);
}
else
digitalWrite(backlight, LOW);


// A single currentMillis for the whole loop.
unsigned long currentMillis = millis();

// Has one second passed ?
if ( currentMillis - previousMillis >= interval)
{
// Special case here, add the interval to keep time accurate.
// Normally it would be: previousMillis = currentMillis;
// But here is is: previousMillis += interval;
// That way the timing is not influenced by a delay in the code.
previousMillis += interval;

// -------------------------------------------
// This section is executed once every second.
// -------------------------------------------

for ( int i = 0; i < 2; i++)
{
// Increment the time in minutes for this battery.
battery_count[i]++;

if ( battery_state[i] == CHARGE)
{
// state is CHARGE, count 10 hours.
if ( battery_count[i] >= TenHoursInSeconds)
{
// Stop charging, return to WAIT
battery_state[i] = WAIT;
battery_count[i] = 0; // reset counter
digitalWrite( pinUitgang[i], LOW);
}
}
else
{
// state is WAIT, count a month
if ( battery_count[i] >= ThirtyDaysInSeconds)
{
// 30 days are over, start charging.
battery_state[i] = CHARGE;
battery_count[i] = 0; // reset counter
digitalWrite( pinUitgang[i], HIGH);

}
}
}

ShowEverything();
}

// check buttons for direct charging and act.

for ( int i = 0; i < 2; i++)
{
if ( digitalRead( pinKnop[i]) == LOW)
{
// start cycle right now.
battery_state[i] = CHARGE;
battery_count[i] = 0;
digitalWrite( pinUitgang[i], HIGH);

}
}
}

// The function ShowEverything() shows everything.
void ShowEverything()
{
Serial.println(F( "----------------------------------"));

for ( int i = 0; i < 2; i++)
{
Serial.print(F( "Accu "));
Serial.print( i == 0 ? "A" : "B");
Serial.print(F( " : "));

if ( battery_state[i] == WAIT)
Serial.print( "Waiting ");
else if ( battery_state[i] == CHARGE)
Serial.print( "Charging");
else
Serial.print( "Error");

// Show the counter in days,hh:mm:ss
int days = (int) (battery_count[i] / (24UL * 60UL * 60UL));
int hours = (int) ((battery_count[i] / (60UL * 60UL)) % 24UL);
int minutes = (int) ((battery_count[i] / (60UL)) % 60UL);
int seconds = (int) (battery_count[i] % 60UL);

// A sprintf with formatting is easer
char buffer[40];
sprintf( buffer, " %d days, %02d:%02d:%02d", days, hours, minutes, seconds);
Serial.print( buffer);

Serial.println();

void UpdateLCD();
{
for ( i = 0; i < 2; i++)
{
// When 'i' is zero, it will be the first battery "A".
// When 'i' is one, it will be the second battery "B".

// print battery status. L = laden, W = wachten
if (i == 0)
lcd.setCursor( 12, 0);
else
lcd.setCursor( 12, 2);
if ( battery_state[i] == WAIT)
lcd.print(F( "WACHTEN"));
else if ( battery_state[i] == CHARGE)
lcd.print(F( "LADEN "));

// Show the counter in days,hh:mm:ss
int days = (int) (battery_count[i] / (24UL * 60UL * 60UL));
int hours = (int) ((battery_count[i] / (60UL * 60UL)) % 24UL);
int minutes = (int) ((battery_count[i] / (60UL)) % 60UL);
int seconds = (int) (battery_count[i] % 60UL);

// print days
if (i == 0)
lcd.setCursor( 1, 1);
else
lcd.setCursor( 1, 3);
if ( days < 10)
lcd.print(F( " "));
lcd.print( days);

// print hours
if (i == 0)
lcd.setCursor( 10, 1);
else
lcd.setCursor( 10, 3);
if ( hours < 10) // functie onbekend
lcd.print(F( "0"));
lcd.print( hours);

// print minutes
if (i == 0)
lcd.setCursor( 13, 1);
else
lcd.setCursor( 13, 3);
if ( minutes < 10) // functie onbekend
lcd.print(F( "0"));
lcd.print( minutes);

// print seconds
if (i == 0)
lcd.setCursor( 16, 1);
else
lcd.setCursor( 16, 3);;
if ( seconds < 10)
{
lcd.print(F( "0"));
}
lcd.print( seconds);
if (i == 0)
lcd.setCursor( 0, 0);
else
lcd.setCursor( 0, 2);
lcd.print( i == 0 ? "Fiets Rita:" : "Fiets Wim :");
}
}
}
}

Advertisement

Gebruikers-avatar
Berichten: 2655
Geregistreerd: 06 Aug 2016, 01:03

Re: tijdschakelaar

Berichtdoor Koepel » 06 Nov 2016, 18:37

Bij de aanroep zou het handiger zijn om dit te doen:
Code: Alles selecteren
  ShowEverything();
  UpdateLCD();

Dat geeft de mogelijkheid om het LCD display iedere seconde te doen en de seriële monitor eens per 5 seconden.

En dan de rest zoals ik schreef graag nakijken. Dus een aparte functie:
Code: Alles selecteren
void UpdateLCD()
{
  for ( i = 0; i < 2; i++)
  ...


Als je op de knop drukt zou ik de millis() onthouden (in "backlightTime") en een vlag zetten (een boolean variabele op true zetten) die aangeeft dat de tijd loopt.
De waarde van millis in die variabele "backlightTime" kan niet gebruikt worden om aan te geven of het wel of niet aktief is, aangezien millis() alles kan zijn.

Helaas lukt het mij niet om het te compileren. Ik denk dat ik de verkeerde LiquidCrystal_I2C geïnstalleerd heb.

Berichten: 88
Geregistreerd: 16 Jul 2015, 21:02

Re: tijdschakelaar

Berichtdoor wim2584 » 06 Nov 2016, 19:50

ik ga morgen een week op dienstreis, dus nu even geen tijd , helaas...

het stukje dat ik had gemaakt om de backlight aan te zetten voor 10 sec is dus niet zoals het moet zijn..., ik zal als ik terug ben eea nog eens bekijken en proberen aan te passen

Code: Alles selecteren
unsigned long current = millis();
 
  if (digitalRead(backlightPin) == LOW)
  {
    digitalWrite(backlight, HIGH);
  }
  if (current - backlightTime >= Timer)
  {
    backlightTime = current;
    digitalWrite(backlight, LOW);
  }
 
  if (digitalRead(3) == HIGH || digitalRead(2) == HIGH || digitalRead(4) == HIGH) // check of one of the accus
  {                                                                                                              //charging or backlight timer active
    digitalWrite(backlight, HIGH);
  }
  else
    digitalWrite(backlight, LOW);


ook het updateLCD() zal ik dan (proberen) aan te passen.

Berichten: 88
Geregistreerd: 16 Jul 2015, 21:02

Re: tijdschakelaar

Berichtdoor wim2584 » 14 Nov 2016, 20:59

weer bezig met de code,

Ik heb de volgende problemen:


1- ondanks de goede aanwijzingen van Koepel lukt het mij niet de "backkight LCD timer "goed werkend te krijgen, ik maak denk ik steeds dezelfde fout?

(zie code stuk hieronder)

2- als in (net zoals showeverything) Update LCD(): in de code zet, krijg ik foutmelding "not defined in scope" , als ik hem echter define, dan krijg ik foutmelding (bij void UpdateLCD()) not allowed to be a function?

ik zie het Niet wat ik fout doe bij beide punten? Graag hulp.

Complete Code:

cpp code
// "http://arduinoforum.nl/viewtopic.php?f=8&t=2054">viewtopic.php?f=8&t=2054</a><!-- l -->
// Tested with Arduino.cc 1.6.12, Arduino Uno.
// This sketch uses a software timer of 1 second.
// changed by Wim Lemson 06-11-2016


#include <Wire.h> // Comes with Arduino IDE
#include <LiquidCrystal_I2C.h>
#define WAIT 0 // WAIT means 30 days waiting
#define CHARGE 1 // CHARGE means 10 hours charging

// set the LCD address to 0x27 for LCD display
// Set the pins on the I2C chip used for LCD connections:addr, en,rw,rs,d4,d5,d6,d7,bl,blpol

LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE); // Set the LCD I2C address

const int pinKnop[2] = { 8, 9}; // first button at pin 8, second at pin 9
const int pinUitgang[2] = { 2, 3}; // first output at pin 2, second at pin 3
const int backlightPin = 10; // backlight pushbutton pin
const int backlight = 4;

unsigned long battery_count[2]; // counter in seconds for both batteries
unsigned long backlightTime; // timer for backlight LCD
const long Timer = 10000; //time in millis LCD on after active
int battery_state[2] = { WAIT, WAIT}; // state of software (waiting or charging)

// Variables for the 1 second software timer with millis()
unsigned long previousMillis;
unsigned long current;
unsigned long interval = 1000UL; // 1000 milliseconds interval


// Very short test values or real value.
// Very short test values:
//const unsigned long TenHoursInSeconds = 10UL; // 10 seconds for test
//const unsigned long ThirtyDaysInSeconds = 30UL; // 30 seconds for test
// Real values:
const unsigned long TenHoursInSeconds = 10UL * 60UL * 60UL; // 10 hours
const unsigned long ThirtyDaysInSeconds = 30UL * 24UL * 60UL * 60UL; // 30 days


void setup()
{
pinMode(backlight, OUTPUT);
pinMode(backlightPin, INPUT_PULLUP);
digitalWrite(backlight, HIGH); // during startup backlight on
Serial.begin( 9600);
Serial.println(F( "\nStarted"));
backlightTime=current;
lcd.begin( 20, 4);
lcd.setCursor( 3, 0);
lcd.print(F( "Laad timer"));
lcd.setCursor( 3, 2);
lcd.print(F( "Fietsaccu's"));

delay( 3000);

lcd.clear();
lcd.setCursor( 2, 0);
lcd.print(F( "Wim Lemson"));
lcd.setCursor( 2, 1);
lcd.print(F( "november 2016"));
lcd.setCursor( 2, 2);
lcd.print(F( "30 dagen wachten"));
lcd.setCursor( 2, 3);
lcd.print(F( "10 uur laden"));

delay( 3000);

lcd.clear();
lcd.setCursor( 1, 1);
lcd.print(F( "-- Dagen --:--:--"));
lcd.setCursor( 1, 3);
lcd.print(F( "-- Dagen --:--:--"));

// A test added to tell if the test values are used.
if ( TenHoursInSeconds < ( 60UL * 60UL) || ThirtyDaysInSeconds < ( 24UL * 60UL * 60UL))
{
Serial.println(F( "Running in test mode"));
lcd.clear();
lcd.setCursor( 1, 2);
lcd.print(F( "Running in "));
lcd.setCursor( 1, 3);
lcd.print(F( "test mode"));
delay (3000);
lcd.clear();
lcd.setCursor( 1, 1);
lcd.print(F( "-- Dagen --:--:--"));
lcd.setCursor( 1, 3);
lcd.print(F( "-- Dagen --:--:--"));
}

for ( int i = 0; i < 2; i++)
{
pinMode( pinKnop[i], INPUT_PULLUP);
pinMode( pinUitgang[i], OUTPUT);
}
digitalWrite(backlight, LOW); // backlight off after setup
}
void loop()
{

// Backlight on for 10 sec
unsigned long current = millis();

if (digitalRead(backlightPin) == LOW)
{
digitalWrite(backlight, HIGH);
}
if (current - backlightTime >= Timer)
{
backlightTime = current;
digitalWrite(backlight, LOW);
}

if (digitalRead(3) == HIGH || digitalRead(2) == HIGH || digitalRead(4) == HIGH) // check of one of the accus
{ //charging or backlight timer active
digitalWrite(backlight, HIGH);
}
else
digitalWrite(backlight, LOW);


// A single currentMillis for the whole loop.
unsigned long currentMillis = millis();

// Has one second passed ?
if ( currentMillis - previousMillis >= interval)
{
// Special case here, add the interval to keep time accurate.
// Normally it would be: previousMillis = currentMillis;
// But here is is: previousMillis += interval;
// That way the timing is not influenced by a delay in the code.
previousMillis += interval;

// -------------------------------------------
// This section is executed once every second.
// -------------------------------------------

for ( int i = 0; i < 2; i++)
{
// Increment the time in minutes for this battery.
battery_count[i]++;

if ( battery_state[i] == CHARGE)
{
// state is CHARGE, count 10 hours.
if ( battery_count[i] >= TenHoursInSeconds)
{
// Stop charging, return to WAIT
battery_state[i] = WAIT;
battery_count[i] = 0; // reset counter
digitalWrite( pinUitgang[i], LOW);
}
}
else
{
// state is WAIT, count a month
if ( battery_count[i] >= ThirtyDaysInSeconds)
{
// 30 days are over, start charging.
battery_state[i] = CHARGE;
battery_count[i] = 0; // reset counter
digitalWrite( pinUitgang[i], HIGH);

}
}
}

ShowEverything();

}

// check buttons for direct charging and act.

for ( int i = 0; i < 2; i++)
{
if ( digitalRead( pinKnop[i]) == LOW)
{
// start cycle right now.
battery_state[i] = CHARGE;
battery_count[i] = 0;
digitalWrite( pinUitgang[i], HIGH);

}
}
}

// The function ShowEverything() shows everything.
void ShowEverything()
{
Serial.println(F( "----------------------------------"));

for ( int i = 0; i < 2; i++)
{
Serial.print(F( "Accu "));
Serial.print( i == 0 ? "A" : "B");
Serial.print(F( " : "));

if ( battery_state[i] == WAIT)
Serial.print( "Waiting ");
else if ( battery_state[i] == CHARGE)
Serial.print( "Charging");
else
Serial.print( "Error");

// Show the counter in days,hh:mm:ss
int days = (int) (battery_count[i] / (24UL * 60UL * 60UL));
int hours = (int) ((battery_count[i] / (60UL * 60UL)) % 24UL);
int minutes = (int) ((battery_count[i] / (60UL)) % 60UL);
int seconds = (int) (battery_count[i] % 60UL);

// A sprintf with formatting is easer
char buffer[40];
sprintf( buffer, " %d days, %02d:%02d:%02d", days, hours, minutes, seconds);
Serial.print( buffer);

Serial.println();

void UpdateLCD();
{
for ( i = 0; i < 2; i++)
{
// When 'i' is zero, it will be the first battery "A".
// When 'i' is one, it will be the second battery "B".

// print battery status. L = laden, W = wachten
if (i == 0)
lcd.setCursor( 12, 0);
else
lcd.setCursor( 12, 2);
if ( battery_state[i] == WAIT)
lcd.print(F( "WACHTEN"));
else if ( battery_state[i] == CHARGE)
lcd.print(F( "LADEN "));

// Show the counter in days,hh:mm:ss
int days = (int) (battery_count[i] / (24UL * 60UL * 60UL));
int hours = (int) ((battery_count[i] / (60UL * 60UL)) % 24UL);
int minutes = (int) ((battery_count[i] / (60UL)) % 60UL);
int seconds = (int) (battery_count[i] % 60UL);

// print days
if (i == 0)
lcd.setCursor( 1, 1);
else
lcd.setCursor( 1, 3);
if ( days < 10)
lcd.print(F( " "));
lcd.print( days);

// print hours
if (i == 0)
lcd.setCursor( 10, 1);
else
lcd.setCursor( 10, 3);
if ( hours < 10) // functie onbekend
lcd.print(F( "0"));
lcd.print( hours);

// print minutes
if (i == 0)
lcd.setCursor( 13, 1);
else
lcd.setCursor( 13, 3);
if ( minutes < 10) // functie onbekend
lcd.print(F( "0"));
lcd.print( minutes);

// print seconds
if (i == 0)
lcd.setCursor( 16, 1);
else
lcd.setCursor( 16, 3);;
if ( seconds < 10)
{
lcd.print(F( "0"));
}
lcd.print( seconds);
if (i == 0)
lcd.setCursor( 0, 0);
else
lcd.setCursor( 0, 2);
lcd.print( i == 0 ? "Fiets Rita:" : "Fiets Wim :");
}
}
}
}


stuk Timer code backlight:

cpp code
// Backlight on for 10 sec
unsigned long current = millis();

if (digitalRead(backlightPin) == LOW)
{
digitalWrite(backlight, HIGH);
}
if (current - backlightTime >= Timer)
{
backlightTime = current;
digitalWrite(backlight, LOW);
}

if (digitalRead(3) == HIGH || digitalRead(2) == HIGH || digitalRead(4) == HIGH) // check of one of the accus
{ //charging or backlight timer active
digitalWrite(backlight, HIGH);
}
else
digitalWrite(backlight, LOW);

Berichten: 88
Geregistreerd: 16 Jul 2015, 21:02

Re: tijdschakelaar

Berichtdoor wim2584 » 14 Nov 2016, 23:04

Nogmaals naar het stukje van de backlight timer gekeken, en vergeleken met het voorbeeld "blink without delay" ik zie het verschil niet echt, toch gaat de Timer in de fietsaccu code niet goed, hij gaat nl altijd uit bij volle 10 sec , als ik dus start bij 08 gaat hij uit na 2 sec, als ik start bij 0 sec gaat hij uit na 10 sec??

alleen het stukje van de backlight in een arduino lijkt wel goed te werken?

Voorbeeld van mijn timer code :

cpp code
const int backlight =  4;
const int backlightPin = 10;
int backledState = LOW;

unsigned long backlightTime;

const long Timer = 5000;

void setup() {

pinMode(backlight, OUTPUT);
pinMode(backlightPin, INPUT_PULLUP);
}

void loop() {
unsigned long current = millis();

if (digitalRead(backlightPin) == LOW)

{
digitalWrite(backlight, HIGH);
}
if (current - backlightTime >= Timer)
{
backlightTime = current;
digitalWrite(backlight, LOW);
}


}


Ik doe ergens iets fout, maar ik lijd aan tunnelvisie??

Gebruikers-avatar
Berichten: 2655
Geregistreerd: 06 Aug 2016, 01:03

Re: tijdschakelaar

Berichtdoor Koepel » 14 Nov 2016, 23:50

Op dit moment doet de code zelf er even niet toe, omdat de structuur van de sketch niet klopt. Daarna de variabelen correct gebruiken, en dan misschien eens kijken of de code ook doet wat het moet doen.

Kun je functies maken van functies ?
Code: Alles selecteren
...

void setup()
{
  ...
}

void loop()
{
  ...
      ShowEverything();
      UpdateLCD();
  ...
}

void ShowEverything()
{
  ...
}

void UpdateLCD()
{
  ...
}


Wil je vervolgens eens kijken naar het gebruik van de variabele 'currentMillis'. Als je één 'currentMillis' gebruikt voor in de loop(), dan kun je die in bijna alle gevallen in heel de loop() gebruiken. Dat geeft duidelijkheid. Het gemakkelijkst is om die bovenin de functie loop() te zetten. Zou je alle andere 'current' willen verwijderen.
Wanneer je millis() in de setup() nodig hebt, dan kun je millis() gebruiken. Waarom wil je eigenlijk millis() in setup() gebruiken ?

Volgens mij schreef ik eerder dat er maar een paar manieren zijn waarop millis() goed werkt. Een eenmalige vertraging (van de backlight) gaat met een aparte "unsigned long", bijvoorbeeld: "unsigned long previousMillisBackground" en een tweede boolean variabele, bijvoorbeeld: "boolean delayIsActive".
Je kunt de waarde van millis() namelijk niet gebruiken om aan te geven dat die eenmalige vertraging op dat moment actief is, die waarde kan alles zijn. Daarom is een tweede variabele nodig die aangeeft of de vertraging actief is of niet.

Vertraging starten:
Code: Alles selecteren
  previousMillisBackground = currentMillis;          // timestamp this moment
  delayIsActive = true;    // enable the delay


In loop() de tijd checken:
Code: Alles selecteren
  if( delayIsActive)
  {
    if( currentMillis - previousMillisBackground >= 10000UL)
    {
      delayIsActive = false;    // disable the delay

      // turn of backlight
    }
  }


Nu je in je sketch een deel hebt dat iedere seconde werkt, kun je dat ook gebruiken voor de eenmalige vertraging van de backlight. Dat is misschien eenvoudiger. Gewoon een teller die bij nul begint, en die steeds met één ophoogt. Dan zou ik er nog steeds een tweede variabele bij maken, die aangeeft of de vertraging actief is.

Berichten: 88
Geregistreerd: 16 Jul 2015, 21:02

Re: tijdschakelaar

Berichtdoor wim2584 » 15 Nov 2016, 21:47

Hallo (koepel),

Het begint (eindelijk , ik ben traag van begrip :D ) iets duidelijker te worden, met de laatste uitleg Code aangepast (zie hieronder), alles lijkt nu goed te werken, alleen zit er 1 sec? reactie-tijd in voordat backlight aan gaat?

nogmaals bedankt , zal eea nu gaan afwerken , een verbeterslag kan dan als ik het beter kan.

groet Wim

Code: Alles selecteren
// "http://arduinoforum.nl/viewtopic.php?f=8&t=2054">viewtopic.php?f=8&t=2054</a><!-- l -->
// Tested with Arduino.cc 1.6.12, Arduino Uno.
// This sketch uses a software timer of 1 second.
// changed by Wim Lemson 15-11-2016


#include <Wire.h>  // Comes with Arduino IDE
#include <LiquidCrystal_I2C.h>
#define WAIT   0       // WAIT means 30 days waiting
#define CHARGE 1       // CHARGE means 10 hours charging

// set the LCD address to 0x27 for LCD display
// Set the pins on the I2C chip used for LCD connections:addr, en,rw,rs,d4,d5,d6,d7,bl,blpol

LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);  // Set the LCD I2C address

const int pinKnop[2] = { 8, 9};         // first button at pin 8, second at pin 9
const int pinUitgang[2] = { 2, 3};      // first output at pin 2, second at pin 3
const int backlightPin = 10;           // backlight pushbutton pin
const int backlight = 4;               // backlight voeding

unsigned long battery_count[2];         // counter in seconds for both batteries
unsigned long backlightTime = 0;        // timer for backlight LCD
const long Timer = 10000;                //time in millis LCD on after active
int battery_state[2] = { WAIT, WAIT};   // state of software (waiting or charging)

unsigned long previousMillisBackground;  // for backlight
boolean delayIsActive;                   // for backlight

// Variables for the 1 second software timer with millis()
unsigned long previousMillis;
unsigned long interval = 1000UL;        // 1000 milliseconds interval
const long Timebacklight = 1000UL;

// Very short test values or real value.
// Very short test values:
//const unsigned long TenHoursInSeconds = 10UL;   // 10 seconds for test
//const unsigned long ThirtyDaysInSeconds = 30UL; // 30 seconds for test
// Real values:
const unsigned long TenHoursInSeconds = 10UL * 60UL * 60UL; // 10 hours
const unsigned long ThirtyDaysInSeconds = 30UL * 24UL * 60UL * 60UL; // 30 days


void setup()
{
  pinMode(backlight, OUTPUT);
  pinMode(backlightPin, INPUT_PULLUP);
  digitalWrite(backlight, HIGH);   // during startup backlight on
  Serial.begin( 9600);
  Serial.println(F( "\nStarted"));

  lcd.begin( 20, 4);
  lcd.setCursor( 3, 0);
  lcd.print(F( "LAAD TIMER"));
  lcd.setCursor( 3, 2);
  lcd.print(F( "FIETSACCU'S"));

  delay( 3000);

  lcd.clear();
  lcd.setCursor( 2, 0);
  lcd.print(F( "Wim Lemson"));
  lcd.setCursor( 2, 1);
  lcd.print(F( "november 2016"));
  lcd.setCursor( 2, 2);
  lcd.print(F( "30 dagen wachten"));
  lcd.setCursor( 2, 3);
  lcd.print(F( "10 uur laden"));

  delay( 3000);

  lcd.clear();
  lcd.setCursor( 1, 1);
  lcd.print(F( "-- Dagen --:--:--"));
  lcd.setCursor( 1, 3);
  lcd.print(F( "-- Dagen --:--:--"));

  // A test added to tell if the test values are used.
  if ( TenHoursInSeconds < ( 60UL * 60UL) || ThirtyDaysInSeconds < ( 24UL * 60UL * 60UL))
  {
    Serial.println(F( "Running in test mode"));
    lcd.clear();
    lcd.setCursor( 1, 2);
    lcd.print(F( "Running in "));
    lcd.setCursor( 1, 3);
    lcd.print(F( "test mode"));
    delay (3000);
    lcd.clear();
    lcd.setCursor( 1, 1);
    lcd.print(F( "-- Dagen --:--:--"));
    lcd.setCursor( 1, 3);
    lcd.print(F( "-- Dagen --:--:--"));
  }

  for ( int i = 0; i < 2; i++)
  {
    pinMode( pinKnop[i], INPUT_PULLUP);
    pinMode( pinUitgang[i], OUTPUT);
  }
  digitalWrite(backlight, LOW);  // backlight off after setup
}
void loop()
{
  // A single currentMillis for the whole loop.
  unsigned long currentMillis = millis();

  // Has one second passed ?
  if ( currentMillis - previousMillis >= interval)
  {
    // Special case here, add the interval to keep time accurate.
    // Normally it would be: previousMillis = currentMillis;
    // But here is is: previousMillis += interval;
    // That way the timing is not influenced by a delay in the code.

    previousMillis += interval;

    // Backlight on for 10 sec after input 10 = low (switch)

    if (digitalRead(backlightPin) == LOW)
    {
      digitalWrite(backlight, HIGH);
      previousMillisBackground = currentMillis;          // timestamp this moment
      delayIsActive = true;    // enable the delay
    }
    if ( delayIsActive)

    {
      if ( currentMillis - previousMillisBackground >= 10000UL)
      {
        delayIsActive = false;    // disable the delay

        digitalWrite(backlight, LOW);// turn of backlight
      }
    }

    // check of one of the accus charging or backlight timer active

    if (digitalRead(3) == HIGH || digitalRead(2) == HIGH || digitalRead(4) == HIGH) // check of one of the accus
    {
      digitalWrite(backlight, HIGH);
    }
    else
      digitalWrite(backlight, LOW);

    // -------------------------------------------
    // This section is executed once every second.
    // -------------------------------------------

    for ( int i = 0; i < 2; i++)
    {
      // Increment the time in minutes for this battery.
      battery_count[i]++;

      if ( battery_state[i] == CHARGE)
      {
        // state is CHARGE, count 10 hours.
        if ( battery_count[i] >= TenHoursInSeconds)
        {
          // Stop charging, return to WAIT
          battery_state[i] = WAIT;
          battery_count[i] = 0; // reset counter
          digitalWrite( pinUitgang[i], LOW);
        }
      }
      else
      {
        // state is WAIT, count a month
        if ( battery_count[i] >= ThirtyDaysInSeconds)
        {
          // 30 days are over, start charging.
          battery_state[i] = CHARGE;
          battery_count[i] = 0; // reset counter
          digitalWrite( pinUitgang[i], HIGH);
        }
      }
    }
    ShowEverything();
    UpdateLCD();
  }

  // check buttons for direct charging and act.

  for ( int i = 0; i < 2; i++)
  {
    if ( digitalRead( pinKnop[i]) == LOW)
    {
      // start cycle right now.
      battery_state[i] = CHARGE;
      battery_count[i] = 0;
      digitalWrite( pinUitgang[i], HIGH);

    }
  }
}

// The function ShowEverything() shows everything.
void ShowEverything()
{
  Serial.println(F( "----------------------------------"));

  for ( int i = 0; i < 2; i++)
  {
    Serial.print(F( "Accu "));
    Serial.print( i == 0 ? "A" : "B");
    Serial.print(F( " : "));

    if ( battery_state[i] == WAIT)
      Serial.print( "Waiting ");
    else if ( battery_state[i] == CHARGE)
      Serial.print( "Charging");
    else
      Serial.print( "Error");

    // Show the counter in days,hh:mm:ss
    int days = (int) (battery_count[i] / (24UL * 60UL * 60UL));
    int hours = (int) ((battery_count[i] / (60UL * 60UL)) % 24UL);
    int minutes = (int) ((battery_count[i] / (60UL)) % 60UL);
    int seconds = (int) (battery_count[i] % 60UL);

    // A sprintf with formatting is easer
    char buffer[40];
    sprintf( buffer, " %d days, %02d:%02d:%02d", days, hours, minutes, seconds);
    Serial.print( buffer);

    Serial.println();
  }
}
void UpdateLCD()
{
  for (int i = 0; i < 2; i++)
  {
    if (i == 0)
      lcd.setCursor( 12, 0);
    else
      lcd.setCursor( 12, 2);
    if ( battery_state[i] == WAIT)
      lcd.print(F( "WACHTEN"));
    else if ( battery_state[i] == CHARGE)
      lcd.print(F( "LADEN  "));

    // Show the counter in days,hh:mm:ss
    int days = (int) (battery_count[i] / (24UL * 60UL * 60UL));
    int hours = (int) ((battery_count[i] / (60UL * 60UL)) % 24UL);
    int minutes = (int) ((battery_count[i] / (60UL)) % 60UL);
    int seconds = (int) (battery_count[i] % 60UL);

    // print days
    if (i == 0)
      lcd.setCursor( 1, 1);
    else
      lcd.setCursor( 1, 3);
    if ( days < 10)
      lcd.print(F( " "));
    lcd.print( days);

    // print hours
    if (i == 0)
      lcd.setCursor( 10, 1);
    else
      lcd.setCursor( 10, 3);
    if ( hours < 10)
      lcd.print(F( "0"));
    lcd.print( hours);

    // print minutes
    if (i == 0)
      lcd.setCursor( 13, 1);
    else
      lcd.setCursor( 13, 3);
    if ( minutes < 10)
      lcd.print(F( "0"));
    lcd.print( minutes);

    // print seconds
    if (i == 0)
      lcd.setCursor( 16, 1);
    else
      lcd.setCursor( 16, 3);;
    if ( seconds < 10)
    {
      lcd.print(F( "0"));
    }
    lcd.print( seconds);
    if (i == 0)
      lcd.setCursor( 0, 0);
    else
      lcd.setCursor( 0, 2);
    lcd.print( i == 0 ? "Fiets Rita:" : "Fiets Wim :");
  }
}


Berichten: 88
Geregistreerd: 16 Jul 2015, 21:02

Re: tijdschakelaar

Berichtdoor wim2584 » 15 Nov 2016, 22:34

late reactie van de backlight OPGELOST, ik had het backlight timer gedeelte na de 1 sec loop geplaatst :oops:

nu ok

Gebruikers-avatar
Berichten: 2655
Geregistreerd: 06 Aug 2016, 01:03

Re: tijdschakelaar

Berichtdoor Koepel » 16 Nov 2016, 08:49

Ja, dat was inderdaad ook mijn eerste gedachte: de structuur van de code.

Je kunt het deel dat iedere seconde loopt aangeven met wat commentaar. Ik bedoel zo iets:
Code: Alles selecteren
  // ---------------------------
  // This part runs every second
  // ---------------------------
 
  ...
 
  // ---------------------------
  // End of part that runs every second
  // ---------------------------


En dan daarbuiten, gewoon in de loop():
Code: Alles selecteren
  // ---------------------------
  // This part runs in the loop(),
  // every time the loop() runs
  // ---------------------------

Als je niet de seconde timer gebruikt, maar gewoon millis(), dan hoort dat eigenlijk gewoon in de loop(), en niet binnen het deel dat iedere seconde draait. Op dit moment gaat het goed, want iedere seconde kijken of de 10 seconden om zijn, dat werkt prima. Maar als je er 250ms van maakt, dan lukt dat niet.


Je hebt alleen tussen de loop() en ShowEverything() een lege regel. Ik heb de code graag overzichtelijk met voldoende lege regels, en zeker tussen de functies. Het lijkt wel alsof sommigen bang zijn voor lege regels :shock:
Je kunt misschien ook wat commentaar boven een functie zetten.
Code: Alles selecteren
  }
}




// ---------------------------
// UpdateLCD
// This function is called every second
// and it show the current status
// on the display.
// ---------------------------
void UpdateLCD()
{


Tip: Maak een tekst met alleen lege regels en print dat uit. Mooi hè :lol:

Berichten: 88
Geregistreerd: 16 Jul 2015, 21:02

Re: tijdschakelaar

Berichtdoor wim2584 » 22 Nov 2016, 21:25

@ Koepel, ja dit zijn goede tips!, ik heb trouwens heel veel geleerd van deze sessie,

in weekend alles bij elkaar in kastje gezet, helaas verkeerde relais (active LOW ipv High), maar de code aangepast, nu dus LOW als accu laad.

alles lijkt goed te werken, echter wel 2 x een "storing" gehad waardoor backlight uitgaat tijdens laden (zou eigenlijk ook 10 uur moeten aanblijven?) , moet ik nog eens naar kijken.

voor de rest tevreden met resultaat, hieronder de laatste versie v/d code:

cpp code
// "http://arduinoforum.nl/viewtopic.php?f=8&t=2054">viewtopic.php?f=8&t=2054</a><!-- l -->
// Tested with Arduino.cc 1.6.12, Arduino Uno.
// This sketch uses a software timer of 1 second.
// changed by Wim Lemson 20-11-2016


#include <Wire.h> // Comes with Arduino IDE
#include <LiquidCrystal_I2C.h>
#define WAIT 0 // WAIT means 30 days waiting
#define CHARGE 1 // CHARGE means 10 hours charging

// set the LCD address to 0x27 for LCD display
// Set the pins on the I2C chip used for LCD connections:addr, en,rw,rs,d4,d5,d6,d7,bl,blpol

LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE); // Set the LCD I2C address

const int pinKnop[2] = { 8, 9}; // first button at pin 8, second at pin 9
const int pinUitgang[2] = { 2, 3}; // first output at pin 2, second at pin 3
const int backlightPin = 10; // backlight pushbutton pin
const int backlight[2] = { 4, 4}; // backlight voeding


unsigned long battery_count[2]; // counter in seconds for both batteries
unsigned long backlightTime = 0; // timer for backlight LCD
const long Timer = 10000; //time in millis LCD on after active
int battery_state[2] = { WAIT, WAIT}; // state of software (waiting or charging)

unsigned long previousMillisBackground; // for backlight
boolean delayIsActive; // for backlight

// Variables for the 1 second software timer with millis()
unsigned long previousMillis;
unsigned long interval = 1000UL; // 1000 milliseconds interval
const long Timebacklight = 1000UL;

// Very short test values or real value.
// very short
//const unsigned long TenHoursInSeconds = 10UL; // 10 seconds for test
//const unsigned long ThirtyDaysInSeconds = 30UL; // 30 seconds for test
// Real values:
const unsigned long TenHoursInSeconds = 10UL * 60UL * 60UL; // 10 hours
const unsigned long ThirtyDaysInSeconds = 30UL * 24UL * 60UL * 60UL; // 30 days


void setup()
{
pinMode(backlight, OUTPUT);
pinMode(backlightPin, INPUT_PULLUP);
digitalWrite(backlight, HIGH); // during startup backlight on
Serial.begin( 9600);
Serial.println(F( "\nStarted"));

lcd.begin( 20, 4);
lcd.setCursor( 3, 0);
lcd.print(F( "LAAD TIMER"));
lcd.setCursor( 3, 2);
lcd.print(F( "FIETSACCU'S"));

delay( 3000);

lcd.clear();
lcd.setCursor( 2, 0);
lcd.print(F( "Wim Lemson"));
lcd.setCursor( 2, 1);
lcd.print(F( "november 2016"));
lcd.setCursor( 2, 2);
lcd.print(F( "30 dagen wachten"));
lcd.setCursor( 2, 3);
lcd.print(F( "10 uur laden"));

delay( 3000);

lcd.clear();
lcd.setCursor( 1, 1);
lcd.print(F( "-- Dagen --:--:--"));
lcd.setCursor( 1, 3);
lcd.print(F( "-- Dagen --:--:--"));

// A test added to tell if the test values are used.
if ( TenHoursInSeconds < ( 60UL * 60UL) || ThirtyDaysInSeconds < ( 24UL * 60UL * 60UL))
{
Serial.println(F( "Running in test mode"));
lcd.clear();
lcd.setCursor( 1, 2);
lcd.print(F( "Running in "));
lcd.setCursor( 1, 3);
lcd.print(F( "test mode"));
delay (3000);
lcd.clear();
lcd.setCursor( 1, 1);
lcd.print(F( "-- Dagen --:--:--"));
lcd.setCursor( 1, 3);
lcd.print(F( "-- Dagen --:--:--"));
}

for ( int i = 0; i < 2; i++)
{
pinMode( pinKnop[i], INPUT_PULLUP);
pinMode( pinUitgang[i], OUTPUT);
digitalWrite(pinUitgang[i], HIGH);
}
digitalWrite(backlight, LOW); // backlight off after setup
}
void loop()
{
// A single currentMillis for the whole loop.
unsigned long currentMillis = millis();

// Backlight on for 10 sec after input 10 = low (switch)

if (digitalRead(backlightPin) == LOW)
{
digitalWrite(backlight, HIGH);
previousMillisBackground = currentMillis; // timestamp this moment
delayIsActive = true; // enable the delay
}
if ( delayIsActive)
{
if ( currentMillis - previousMillisBackground >= 10000UL)
{
delayIsActive = false; // disable the delay

digitalWrite(backlight, LOW);// turn of backlight
}
}


// Has one second passed ?
if ( currentMillis - previousMillis >= interval)
{
// Special case here, add the interval to keep time accurate.
// Normally it would be: previousMillis = currentMillis;
// But here is is: previousMillis += interval;
// That way the timing is not influenced by a delay in the code.

previousMillis += interval;


// -------------------------------------------
// This section is executed once every second.
// -------------------------------------------

for ( int i = 0; i < 2; i++)
{
// Increment the time in minutes for this battery.
battery_count[i]++;

if ( battery_state[i] == CHARGE)
{
// state is CHARGE, count 10 hours.
if ( battery_count[i] >= TenHoursInSeconds)
{
// Stop charging, return to WAIT
battery_state[i] = WAIT;
battery_count[i] = 0; // reset counter
digitalWrite( pinUitgang[i], HIGH);
digitalWrite(backlight[i], LOW);
}
}
else
{
// state is WAIT, count a month
if ( battery_count[i] >= ThirtyDaysInSeconds)
{
// 30 days are over, start charging.
battery_state[i] = CHARGE;
battery_count[i] = 0; // reset counter
digitalWrite( pinUitgang[i], LOW);
digitalWrite(backlight[i], HIGH);
}
}
}
ShowEverything();
UpdateLCD();
}

// check buttons for direct charging and act.

for ( int i = 0; i < 2; i++)
{
if ( digitalRead( pinKnop[i]) == LOW)
{
// start cycle right now.
battery_state[i] = CHARGE;
battery_count[i] = 0;
digitalWrite( pinUitgang[i], LOW);
digitalWrite(backlight[i], HIGH);

}
}
}

// The function ShowEverything() shows everything.
void ShowEverything()
{
Serial.println(F( "----------------------------------"));

for ( int i = 0; i < 2; i++)
{
Serial.print(F( "Accu "));
Serial.print( i == 0 ? "A" : "B");
Serial.print(F( " : "));

if ( battery_state[i] == WAIT)
Serial.print( "Waiting ");
else if ( battery_state[i] == CHARGE)
Serial.print( "Charging");
else
Serial.print( "Error");

// Show the counter in days,hh:mm:ss
int days = (int) (battery_count[i] / (24UL * 60UL * 60UL));
int hours = (int) ((battery_count[i] / (60UL * 60UL)) % 24UL);
int minutes = (int) ((battery_count[i] / (60UL)) % 60UL);
int seconds = (int) (battery_count[i] % 60UL);

// A sprintf with formatting is easer
char buffer[40];
sprintf( buffer, " %d days, %02d:%02d:%02d", days, hours, minutes, seconds);
Serial.print( buffer);

Serial.println();
}
}
void UpdateLCD()
{
for (int i = 0; i < 2; i++)
{
if (i == 0)
lcd.setCursor( 12, 0);
else
lcd.setCursor( 12, 2);
if ( battery_state[i] == WAIT)
lcd.print(F( "WACHTEN"));
else if ( battery_state[i] == CHARGE)
lcd.print(F( "LADEN "));

// Show the counter in days,hh:mm:ss
int days = (int) (battery_count[i] / (24UL * 60UL * 60UL));
int hours = (int) ((battery_count[i] / (60UL * 60UL)) % 24UL);
int minutes = (int) ((battery_count[i] / (60UL)) % 60UL);
int seconds = (int) (battery_count[i] % 60UL);

// print days
if (i == 0)
lcd.setCursor( 1, 1);
else
lcd.setCursor( 1, 3);
if ( days < 10)
lcd.print(F( " "));
lcd.print( days);

// print hours
if (i == 0)
lcd.setCursor( 10, 1);
else
lcd.setCursor( 10, 3);
if ( hours < 10)
lcd.print(F( "0"));
lcd.print( hours);

// print minutes
if (i == 0)
lcd.setCursor( 13, 1);
else
lcd.setCursor( 13, 3);
if ( minutes < 10)
lcd.print(F( "0"));
lcd.print( minutes);

// print seconds
if (i == 0)
lcd.setCursor( 16, 1);
else
lcd.setCursor( 16, 3);;
if ( seconds < 10)
{
lcd.print(F( "0"));
}
lcd.print( seconds);
if (i == 0)
lcd.setCursor( 0, 0);
else
lcd.setCursor( 0, 2);
lcd.print( i == 0 ? "Fiets Rita:" : "Fiets Wim :");
}
}



groet Wim

VorigeVolgende

Terug naar Arduino software

Wie is er online?

Gebruikers in dit forum: Geen geregistreerde gebruikers en 93 gasten