tijdschakelaar

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

tijdschakelaar

Berichtdoor wim2584 » 15 Okt 2016, 20:47

ik wil een tijdschakelaar maken om accu's minimaal 1 x per maand 10 uur te laden (en als wens direct starten na druk op knop) als volgt:
omgeving:

druk knop 1
druk knop 2
uitgang 1
uitgang 2
eventueel
16x2 display

programma voorwaarden :

1- uitgang 1 en 2 blijven 1 maand laag, worden dan 10 uur hoog

2- als druk knop 1 wordt ingedrukt output 1 hoog en na 10 uur laag, dan weer cycle #1

3- als druk knop 2 wordt ingedrukt output 2 hoog en na 10 uur laag, dan weer cycle #1

eventueel op display:

out 1: status aantal cycle: xx

out 2: status aantal cycle: xx

waarbij status is : hoog / laag
Cycle is : het aantal cycles hoog

Wie heeft een goed idee voor de code?

Wim

Advertisement

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

Re: tijdschakelaar

Berichtdoor Koepel » 15 Okt 2016, 22:38

En als de Arduino reset door een storing of even uit gaat ? Dan ben je kwijt hoe lang hij aan was.

Als het altijd goed moet gaan, dan kun je een RTC (Real Time Clock) module kopen. Kies dan een DS3231, die heeft het kristal in de chip en heeft een rekenkundige correctie voor de temperatuur.

Als je de tijd van de Arduino zelf wilt gebruiken (die van het 16MHz kristal is afgeleid) dan is daar de functie millis() voor.
Daarmee is het mogelijk om allerlei vertragingen en verschillende software timers maken. Een kalendermaand is lastig, maar precies 30 of 31 dagen is geen probleem. Die 10 uur is ook geen probleem trouwens.

millis: https://www.arduino.cc/en/Reference/Millis
De millis() geeft een unsigned long waarde van de milliseconden, dus na 50 dagen rolt hij door van 0xFFFFFFFF naar 0x00000000. Je kunt dus geen 60 dagen wachten.
Je zou millis() kunnen gebruiken voor de uren, en daar de dagen van afleiden, zodat je toch onbeperkt aantal dagen kunt kiezen.

Je hebt twee afzonderlijke processen, dat is met millis() geen probleem.

Kijk eens naar de Blink Without Delay : https://www.arduino.cc/en/Tutorial/BlinkWithoutDelay
Begrijp je wat er gebeurt ?
Hoe is je kennis van programmeren ?

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

Re: tijdschakelaar

Berichtdoor wim2584 » 16 Okt 2016, 09:26

Bedankt voor reactie

Ik snap wat er gebeurd, maar zelf een code schrijven is nog lastig .
Bij een reset alles kwijt.? Niet het grooste probleem,is toch maar indicatief.
Tijd en dagen zijn zeker niet kritisch.
Ik zal eea nog eens lezen

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

Re: tijdschakelaar

Berichtdoor Koepel » 16 Okt 2016, 18:09

Ik kan je een start geven. Als je echter een sketch hebt die je zelf niet begrijpt, dan heb je er weinig aan omdat het dan erg lastig wordt als je iets wilt wijzigen of toevoegen.

Ik koos voor een software timer met millis() van 1 minuut. Dan is de 10 uur nauwkeurig op 1 minuut. Dus die 1 minuut is het framework of paraplu waar alle timing onder hangt. Dus de 10 uur en de 30 dagen gebruiken dat.

Dit heb ik ongetest zomaar opgeschreven, er zal nog best een foutje in zitten. Graag zelf nog toevoegen dat er berichten naar de seriële poort gestuurd worden als er iets gebeurd.
Code: Alles selecteren
// Example with software timer of 1 minute.
// That 1 minute software timer is the framework.
// Everything else is under that framework.

const int pinKnop[2] = { 8, 9};
const int pinUitgang[2] = { 2, 3};

enum state { WAIT, CHARGE };   // WAIT is 30 days waiting

long battery_count[2];
int battery_state[2] = { WAIT, WAIT};


// DEBUG: to test it, make the interval very short and the rest will go along.
unsigned long previousMillis;
unsigned long interval = 1000UL * 60UL;   // 1 minute in milliseconds

const long TenHoursInMinutes = 10L * 60L;
const long ThirtyDaysInMinutes = 30L * 60L * 24L;


void setup()
{
  Serial.begin( 9600);
  Serial.begin(F( "Started"));
}

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

  // Has one minute passed ?
  if( currentMillis - previousMillis >= interval)
  {
    // Special case: add the interval to keep time accurate.
    // Normally it would be: previousMillis = currentMillis;
    previousMillis += interval;

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

    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] >= TenHoursInMinutes)
        {
          // 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] >= ThirtyDaysInMinutes)
        {
          // 30 days are over, start charging.
          battery_state[i] = CHARGE;
          battery_count[i] = 0;              // reset counter
          digitalWrite( pinUitgang[i], HIGH);
        }
      }
    }
  }

 
  // -------------------------------------------------------------------
  // Add things here that should be executed everytime the loop() runs.
  // The use of delay() will not influence the 1 minute software timer.
  // -------------------------------------------------------------------

  // check buttons and act.
  // Add debounce later.
  for( int i=0; i<2; i++)
  {
    if( digitalRead( pinKnop[i]) == LOW)
    {
      // start cycle
      battery_state[i] = CHARGE;
      battery_count[i] = 0;
      digitalWrite( pinUitgang[i], HIGH);
    }
  }
}


Zie je de verschillende onderdelen ?
Een software timer met millis(), de counter en de state die tot 10 uur of 30 dagen tellen, en de knoppen die het laden meteen kunnen activeren.

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

Re: tijdschakelaar

Berichtdoor wim2584 » 16 Okt 2016, 20:48

Beste Koepel,

hartstikke bedankt, uitgeprint en zal regel per regel proberen te snappen, en daarna op een arduino zetten.

Het is voor mij een uitdagende script... ik was veel eenvoudiger gestart, maar kreeg het ook niet goed werkend.

ik ben elektronisch goed onderlegd maar gezien mijn (leeftijd 57 J) is programmeren een hele uitdaging, verder wil ik vaak te snel en teveel...
ik heb tot nog toe enkele arduino projecten afgerond, maar steeds met een beetje "lenen"van internet en dan aanpassen, iets geheel zelf maken blijkt toch een stuk moeilijker.

als het uitgewerkt is meld ik mij.

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

Re: tijdschakelaar

Berichtdoor Koepel » 16 Okt 2016, 21:32

Ik heb er nog over nagedacht :o en het kan eenvoudiger.

De 'state' bij de "enum" declareer ik wel, maar gebruik ik niet, dat is slordig. En ik zou een gewone millis() kunnen nemen voor elk. Dan wordt je beperkt tot 50 dagen, maar ach. Als er dan toch een software timer gemaakt wordt, dan zou een logischer keuze zijn die 1 seconde te maken in plaats van 1 minuut.

Dus het gaat meer om het globale idee. Beide moeten onafhankelijk kunnen tellen tot 10 uur of 30 dagen. Dus millis() is sowieso nodig, en ook een variabele die telt en een variabele met de state (10 uur aan of 30 dagen uit).

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

Re: tijdschakelaar

Berichtdoor wim2584 » 16 Okt 2016, 22:49

hoi koepel,

een paar vraagjes,

wat bedoel je met:

const int pinKnop[2] = { 8, 9}; // ik kan dit in arduino niet echt terug vinden, ik denk 2 inputs op input 8 en 9 ?
const int pinUitgang[2] = { 2, 3}; // zelfde maar dan voor outputs 2 stuks en out 2 en 3?

maar in code vindt ik deze niet terug?


enum state { WAIT, CHARGE }; // WAIT is 30 days waiting // wat bedoel je met deze regel?

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

Re: tijdschakelaar

Berichtdoor Koepel » 17 Okt 2016, 05:11

Omdat ik beide accu's en beide knoppen helemaal onafhankelijk doe, maar wel met dezelfde code, kies ik voor een for-loop.
Code: Alles selecteren
  for( int i=0; i<2; i++)

Dat doe ik zowel voor het tellen van de tijd, als voor het inlezen van de knoppen.
Dan ontkom ik er niet aan om de pinnen waar de uitgang aan zit en de pinnen waar de knoppen aan verbonden zijn een array te maken.

Code: Alles selecteren
const int pinKnop[2] = { 8, 9};

Maak een array van 2 elementen die "pinKnop" heet omdat het de pin nummers zijn waarmee de knoppen verbonden zijn. Vul ze met de waarde 8 en 9. En vertel de compiler dat het constante waarden zijn met "const". Het is dus eigenlijk alleen maar een array.

Het "const" keyword is een extraatje. Dit doet hetzelfde:
Code: Alles selecteren
int pinKnop[2];   // array van twee elementen

void setup()
{
  pinKnop[0] = 8;   // vul dit element met 8
  pinKnop[1] = 9;   // vul dit element met 9
  .....

Vervolgens kan ik ze in de for-loop gebruiken als "pinKnop [ i ]", dan kies ik dus ofwel 8 ofwel 9.

Code: Alles selecteren
enum state { WAIT, CHARGE };

De 'enum' is een automatische opsomming van defines die een ophogende waarde wordt toegekend.

Dit doet hetzelfde:
Code: Alles selecteren
#define WAIT 0
#define CHARGE 1

Als je dit gemakkelijker vind, dan kun je ook de 'enum' weghalen en deze defines gebruiken.

Ik wil alleen maar een variabele die aangeeft wanneer de 10 uren geteld worden en wanneer de 30 dagen. Zo'n soort variabele wordt vaak een 'state' genoemd. De 'state' onthoudt vaak de huidige status van wat er gaande is. Heb je wel eens van een "state machine" gehoord ? Dat is een programma dat helemaal wordt bepaald door een 'state'.

De tekst "WAIT" en "CHARGE" heb ik zelf verzonnen, dit kan ook:
Code: Alles selecteren
#define DERTIG_DAGEN_WACHTEN 0
#define BEZIG_MET_TIEN_UREN_OPLADEN 1


In dit geval heeft iedere accu zijn eigen 'state', dus alweer een array om dat bij te houden:
Code: Alles selecteren
int battery_state[2];

Omdat ik er zeker van wil zijn dat ze beginnen met de 'state' WAIT, geeft ik ze tijdens het declareren ook meteen maar een waarde:
Code: Alles selecteren
int battery_state[2] = { WAIT, WAIT};

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

Re: tijdschakelaar

Berichtdoor wim2584 » 17 Okt 2016, 19:12

ik begrijp het niet helemaal, mijn vragen in rood.

verder werkt het ook niet, maar dat zal wel aan mij liggen


// Example with software timer of 1 minute.
// That 1 minute software timer is the framework.
// Everything else is under that framework.

const int pinKnop[2] = { 8, 9}; volgens mij hier gedefineerd pin 8 en 9 Input het heten pinKnop 1 of 2
const int pinUitgang[2] = { 2, 3}; volgens mij hier gedefineerd pin 2 en 3 output en heten PinUitgang 1of 2

enum state { WAIT, CHARGE }; // WAIT is 30 days waiting WAIT en Charge defineren

long battery_count[2]; niet duidelijk wat hier gebeurt
int battery_state[2] = { WAIT, WAIT}; starten met staus WAIT


// DEBUG: to test it, make the interval very short and the rest will go along.
unsigned long previousMillis;
unsigned long interval = 1000UL * 60UL; // 1 minute in milliseconds niet duidelijk waarom UL erachter, verder defineren dat 1 min 60000 millisec is

const long TenHoursInMinutes = 10L * 60L; de L is niet duidelijk, verder definitie 10 uur = 600 minuten
const long ThirtyDaysInMinutes = 30L * 60L * 24L;de L is niet duidelijk, verder definitie 30 dagen = 18000 minuten


void setup()
{
Serial.begin( 9600);
Serial.begin(F( "Started")); moet volgens mij zijn Serial.Print verder niet duidelijk wat de F er doet
}

void loop()
{
// A single currentMillis for the whole loop.
unsigned long currentMillis = millis(); gelijkzetten van de millis

// Has one minute passed ?
if( currentMillis - previousMillis >= interval) defineren dat curren - previous = interval
{
// Special case: add the interval to keep time accurate.
// Normally it would be: previousMillis = currentMillis; onduidelijk wat de bedoeling is
previousMillis += interval;

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

for( int i=0; i<2; i++) spiltsen battry 1 en 2
{
// Increment the time in minutes for this battery.
battery_count[i]++; aantal minuten dat battry 1 of 2 iets doet, ik denk WAIT omdat hij daar mee bezig is?

if( battery_state[i] == CHARGE) als hij in laad status staat dat hieronder verder , tellen van de 10 H?
{
// state is CHARGE, count 10 hours.
if( battery_count[i] >= TenHoursInMinutes)
{
// 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 wachten totdat de maand voorbij is
if( battery_count[i] >= ThirtyDaysInMinutes)
{
// 30 days are over, start charging.
battery_state[i] = CHARGE;
battery_count[i] = 0; // reset counter
digitalWrite( pinUitgang[i], HIGH);
}
}
}
}


// -------------------------------------------------------------------
// Add things here that should be executed everytime the loop() runs.
// The use of delay() will not influence the 1 minute software timer.
// -------------------------------------------------------------------

// check buttons and act.
// Add debounce later.
for( int i=0; i<2; i++) battery 1 of 2
{
if( digitalRead( pinKnop[i]) == LOW) uitlezen PinKnop 1 of 2 laag als laag dat verder
{
// start cycle
battery_state[i] = CHARGE;
battery_count[i] = 0;
digitalWrite( pinUitgang[i], HIGH); hierna mis is ELSE, als hoog dan....?
}
}
}

verder werkt het dus niet, branden beide uitgangen heel zacht, geen reactie op laag maken 8 of 9? tijden testen had ik interval op 1 sec (1000) gezet en 10 uur op 10 en 30 dagen op 30

Vraag : is deze code (nog) te hoog gegrepen voor mij of zie ik het redelijk goed?

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

Re: tijdschakelaar

Berichtdoor Koepel » 17 Okt 2016, 20:08

Helaas denk ik dat het nog te hoog gegrepen is. Je hebt het meeste wel goed. Ik ging er van uit, dat je voldoende kennis van 'c' en 'c++' zou hebben, en dat vooral het gebruik van millis() de moeilijkheid was.

Als een sketch niet werkt, dan hoeft het niet aan jou te liggen. Mijn sketch kan fout zijn; mijn uitleg kan niet goed zijn; de Arduino kan te weinig spanning hebben; enzovoorts.

Met name het gebruik van een array is basiskennis.
Bijvoorbeeld "pinKnop[i]", dan is 'i' de index en die is '0' of '1'.

De 'UL' achter een getal is de afkorting van "unsigned long". Het verteld de compiler dat het getal een unsigned long is.
De 'L' achter een getal is de afkorting van "long".

De 'F()' macro is een extraatje van Arduino. Zonder de 'F()' staat de tekst "Started" zowel in flash rom (waar de code zit) als ook in ram (dynamisch geheugen, waar de variabelen zitten). Met de 'F()' staat het alleen in flash rom.

Het gebruik van millis() zou je zo kunnen gebruiken. Er zitten zoveel ogen en haken aan het gebruik van millis(). Om de tijd altijd in de pas te houden heb ik een kleine variatie op de "Blink Without Delay". Dat hoef je niet helemaal te doorgronden.

De "battery_count" telt het aantal minuten. De '++' betekend: ophogen met 1.

De knop inlezen heeft geen "else", omdat die niet nodig is.

Ik weet verder niet hoe je de knoppen en uitgangen hebt aangesloten. In de sketch heb ik zomaar wat ingevuld. Een uitgang van de Arduino Uno kan ongeveer 20mA geven. De nieuwere processors zoals de Arduino Due en de Arduino Zero kunnen maar een paar milliampère leveren.

Wat je beter niet kunt doen:
Ik denk dat het beter is om niet met deze sketch verder te gaan. Als je iets wijzigt terwijl je de code niet begrijpt, dan zak je in het moeras.
Het nadeel van je project is, dat het met een paar korte zinnen te beschrijven is, maar het levert code op die nog best ingewikkeld is. Je hebt gewoon pech :( want soms is het net andersom.

Wat je wel kunt doen:
Je kunt een paar voorbeelden uitproberen (ze staan in het menu van de Arduino IDE).
Vervolgens een goede tutorial volgen. Goede tutorials vind je niet op instructables.com, maar wel bij Adafruit.
Ook online Nederlandse winkels verkopen spullen van Adafruit en Sparkfun. Koop bijvoorbeeld een Neopixel en maak iets moois om in de kerstboom te hangen 8-) Volg de tutorials van Adafruit van begin tot eind. Dit is de Neopixel tutorial: https://learn.adafruit.com/adafruit-neopixel-uberguide/overview.
Heb je een hekel aan Kerst :? dan is een barometer sensor of een servo motor ook heel leuk :D
Dat zijn voorbeelden waarbij de code redelijk recht-toe-recht-aan is, en toch leuk om kennis van Arduino op te doen.

Volgende

Terug naar Arduino software

Wie is er online?

Gebruikers in dit forum: Geen geregistreerde gebruikers en 2 gasten