Teller voor een windmolen

Projecten die niet passen in bovenstaande onderwerpen
Berichten: 45
Geregistreerd: 08 Jan 2020, 17:23

Teller voor een windmolen

Berichtdoor RonalT » 27 Jan 2020, 00:52

ik ben vrijwillig molenaar op de Heimolen in Rucphen. Als molenaar ben je benieuwd naar het aantal omwentelingen wat je molen per jaar draait. In een recent verleden kregen we daar een premie voor. Per 100 omwentelingen een bedrag. Er waren daarvoor verzegelde tellers in de molens aanwezig die eenmaal per jaar werden opgenomen door de provincie. De molenaars keken daar ook naar.

Nu heeft onze molen geen teller meer en we blijven toch benieuwd hoeveel omwentelingen we maken. Dus hebben we vorig jaar een mechanische teller (Artikelnummer: 108527) bij Conrad gekocht. Armpje met een gewichtje er aan en dat telt.
Maar ik vind dit niet de meest handige oplossing omdat je boven moet kijken waar de teller op dat moment precies staat en hem dan aflezen.

Nu had ik nog een Arduino Uno liggen die overgebleven is nadat mijn zoon zijn ICT opleiding beëindigde. Dat ding lag al enkele jaren in de garage.
Zonder enige ervaring ben ik eind vorig jaar begonnen met het bekijken hoe de code voor een Uno in elkaar zit. Video's kijken, lessen doorlezen die op het internet te vinden zijn en ik ben nu zo ver dat ik een sketch heb die het aantal omwentelingen telt en deze opslaat.
Het tellen gebeurt door een reedschakelaar waarboven een molenwiel draait waar een magneetje in zit.
Door de tijd van een omwenteling te timen kan ik ook uitrekenen hoeveel omwentelingen de molen maakt.

Maar nu moet ik voor de niet-molenaars iets verduidelijken denk ik.
- De wieken van de molen zitten aan de bovenas. De bovenas ligt bijna horizontaal in de molen.
Het bovenwiel (die aan de bovenas zit) heeft 71 kammen (tanden).
- Er zit een (bijna) haakse overbrenging naar de koningsspil, deze staat in het midden van de molenromp rechtop.
Boven aan de koningsspil zit een rondsel (de bovenschijfloop) die 37 staven (soort tanden) heeft.
Onderaan de koningsspil zit het spoorwiel. Aan dit spoorwiel zit het magneetje vastgelijmd.
Dus het spoorwiel draait (71 gedeeld door 37 is) 1,9189 maal sneller dan de bovenas. Dit getal komt in de code terug.
- Een molenaar is niet geinteresseerd in het aantal omwentelingen van de bovenas, maar in het aantal enden wat de molen draait. Het aantal enden is het aantal wieken wat er per minuut passeert. Dat is dus 4 maal zo veel als het aantal omwentelingen van de bovenas. En bij ons is dat dus 1,9189 maal 4 is 7,6756 maal zo veel als het aantal omwentelingen per minuut van het spoorwiel. (ik hoop dat ik dit duidelijk genoeg heb beschreven)

De code omvat natuurlijk een VOID loop() en een VOID setup() om een en ander te sturen.
In de LOOP staat vrij weinig, alleen code om de zaken te sturen.
De tellingen e.d. worden in aparte VOID's gedaan.
Zo is er een die WIEKSNELHEID heet, hierin wordt de rotatiesnelheid van de koningsspil uitgerekend en omgerekend naar het aantal enden wat de molen draait. Dit wordt op een 20 x 4 display (line 0) weergegeven.
In de tweede VOID totaalOmw wordt het aantal omwentelingen van de bovenas geteld en weergegeven op het display op de tweede regel.
Daarna volgt VOID stilGevlucht waarin na een X aantal seconden (8) wordt gedetecteerd dat er geen pulsen meer zijn binnengekomen en we er van uitgaan dat de molen niet meer draait. Ook dit wordt weergegeven op het display.
Daarna komt de VOID bijwerk waarin de gegevens (aantal omwentelingen en jaartal) worden opgeslagen. Voor deze test in het EEprom geheugen, maar later op een SD-card.
Omdat de molenaar het aantal omwentelingen per jaar wil weten volgt er daarna een VOID resetTotaalOmw. Dan wordt het aantal omwentelingen terug op 1 gezet en het jaartal met 1 verhoogd.
De laatste VOID weetZekerDisplay. Hiervoor is een tweede reedschakelaar aangebracht in de behuizing waar je een magneet bij kunt houden en dan volgt de vraag "weet u dit zeker?". Dan moet de magneet binnen de tijd die een LED gaat knipperen nogmaals bij de reedschakelaar gehouden worden.

Ik hoop dat dit verhaal samen met de sketch duidelijk genoeg is om begrepen te worden.

Nu heb ik een paar vragen...

1. Als er spanning op de Arduino gezet wordt gaat deze aan en blijft het display leeg. Na de 8 seconden wordt de VOID stilGevlucht actief en krijg ik beeld. Maar dan blijft het aantal omwentelingen op 0 staan. Als ik de tel-reedschakelaar activeer wordt het juiste aantal zichtbaar.
Nu zou het leuker zijn als het display gelijk aan gaat geven en ook gelijk het juiste aantal omwentelingen aan geeft.

2. Nu wordt na elke omwenteling aangegeven hoeveel enden het gevlucht draait. Maar ik zou dit liever een beetje uitgemiddeld zien. Bv een gemiddelde van de laatste 5 omwentelingen.

3. Ik hoop het zo goed als mogelijk geprogrammeerd te hebben, maar misschien kan er door beter programmeren op programma-opslagruimte en dynamisch geheugen bespaart worden.

4. En verder zijn alle opmerkingen waar ik wat van kan leren welkom.


Code: Alles selecteren
/*
 * Eerste versie om enden te tellen
 *
 * This code is written by Ronald Troost and is in the public domain.
 *
 * My thanks go out to various writers who teach me Arduino / C ++ via the internet
 */


#include <Wire.h>                                                       // This library allows you to communicate with I2C / TWI devices.
#include <EEPROM.h>                                                     // This library allows you to read or write the EEprom.
#include <LiquidCrystal_I2C.h>                                          // Library for the LiquidCrystal LCD display connected to an Arduino board.

/*
 * Use 0x27 if you have a chip PCF8574 from NXP,
 * or use 0x3F if you have a chip PCF8574A from Ti (Texas Instruments),
 */

LiquidCrystal_I2C lcd(0x27, 20, 4);

/*
 * the mill symbol has been made with the generator on:
 * https://maxpromer.github.io/LCD-Character-Creator/
 */

byte mill[] = {                                                         // create mill-character
  0x00,
  0x11,
  0x0A,
  0x04,
  0x0E,
  0x15,
  0x0E,
  0x0E
};


/* The 3 color LED has 4 legs, one long, two short and 1 in between,
 * the long is the minus (ground or gnd), then there red next to it, the medium long leg.
 * On the other side, the first of the two short is blue and the last one is green.
 * So red-min-blue-green
 */



int reedSchakA = 2;                                                      // digital pin 2 reedswitch forward.
int reedSchakReset = 4;                                                  // digital pin 4 reedswitch reset.
int buttonAState = 0;                                                    // variable for reading the forward status.
int buttonResetState = 0;                                                // variable for reading the reset status.
int buttonSureState = 0;
int buttonAStateOld = 0;                                                 // variable for reading the previous forward status.
int buttonSureStateOld = 0;
int buttonResetStateOld = 0;                                             // variable for reading the previous reset status.
int LED_red = 8;                                                         // red LED.
int LED_Forward = 9;                                                     // green LED for forward detection.
int LED_Still = 10;                                                      // bleu LED for downtime detectie.
long rotationTimeA;                                                      // new time forward.
long rotationTimeAOld;                                                   // previous time forward.
int rotationSpeed;                                                       // difference between old time - new time.
int numberOfSails;                                                       // time for one revolution of the spur wheel (seconds).
float conversion = 2.084507043;                                          // time for one revolution of the spur wheel at 60 ends.
unsigned long numberOfRevolutions;                                       // "revolutionsSpurwheel" divided by ratio headwheel / crownwheel,
                                                                         // (verhouding bovenwiel / bovenrondsel) for Heimolen 1,9189.
unsigned long revolutionsSpurwheel = 22;                                 // total number of spurwheel rotations per year.
unsigned long bijwerkTijd;                                               // time variable for writing to memory.
unsigned int jaartal = 2019;                                             // declare year.


void wiekSnelheid();                                                     // Declare subroutine "wieksnelheid", this counts the sails.
void totaalOmw();                                                        // Declare subroutine "totaalOmw" counts the revolutions of the windshaft.
void stilGevlucht();                                                     // Declare subroutine "stilGevlucht" .
void bijwerk();                                                          // Declare subroutine "bijwerk" this write to memory.
void resetTotaalOmw();                                                   // Declare subroutine "resetTotaalOmw".
void weetZekerDisplay();                                                 // Declare subroutine "weetZekerDisplay".
void dots();


void wiekSnelheid()                                                      // subRoutine "wiekSnelheid bepalen".
{
  digitalWrite(LED_Still, LOW);                                          // turn blue LED off.
  delay(10);                                                             // delay
  digitalWrite(LED_Forward, HIGH);                                       // turn green LED on.
  rotationSpeed = rotationTimeA - rotationTimeAOld;                      // calculate time for one rotation spurwheel.
  rotationTimeAOld = rotationTimeA;                                      // previous time forward is time forward
  numberOfSails = 60000 / rotationSpeed * conversion;                    // calculate rotation-time spurwheel to number of revolutions windshaft.
  if (numberOfSails > 120 || numberOfSails < 0)                          // | correction for too great or too little rotations.
    {                                                                    // |
    numberOfSails = 0;                                                   // | too great or too little is 0
    }                                                                    // | correction for too great or too little rotations.
  lcd.setCursor(0, 0);                                                   // put the cursor on position 1, line 1.
  lcd.print("    ");                                                     // send 4 spaces to LCD display for empty space.
  lcd.setCursor(0, 0);                                                   // put the cursor on position 1, line 1.
  lcd.print(numberOfSails);                                              // send "aantal enden" to LCD display.
  lcd.setCursor(4, 0);                                                   // put the cursor on position 5, line 1.
  lcd.print("enden per minuut");                                         // send text to LCD display.
  lcd.setCursor(0, 3);                                                   // put the cursor on position 0, line 4.
  lcd.print("                    ");                                     // send 20 spaces to LCD display for empty space.
  digitalWrite(LED_Forward, LOW);                                        // turn green LED off.
  Serial.print("Aantal enden : ");                                       // print to serial monitor.
  Serial.println(numberOfSails);                                          // print to serial monitor.
}                                                                        // End of subRoutine "wieksnelheid".



void totaalOmw()                                                         // subRoutine "totaal aantal omwentelingen per jaar".
{
  numberOfRevolutions = revolutionsSpurwheel / 1.9189;                   // 1.9189 aanpassen aan de verhouding van bovenwiel / bovenschijfloop.
  lcd.setCursor(0, 1);                                                   // put the cursor on position 1, line 2.
  lcd.print("        ");                                                 // send 8 spaces to LCD display for empty space.
  lcd.setCursor(0, 1);                                                   // put the cursor on position 1, line 2.
  lcd.print(numberOfRevolutions);                                        // send text to LCD display.
  lcd.setCursor(7, 1);                                                   // put the cursor on position 8, line 2.
  lcd.print(" omw. in ");                                                // send text to LCD display.
  lcd.setCursor(16, 1);                                                  // put the cursor on position 17, line 2.
  lcd.print(jaartal);                                                    // send text to LCD display. 
  lcd.setCursor(0, 2);                                                   // put the cursor on position 1, line 3.
  lcd.print ("                    ");                                    // send text to LCD display.
  lcd.setCursor(0, 3);                                                   // put the cursor on position 1, line 4.
  lcd.print ("                    ");                                    // send text to LCD display. 
  delay(10);                                                             // pauses the program for the amount of time (in milliseconds).
  Serial.print("totaalOmw : ");                                          // print to serial monitor.
  Serial.println(numberOfRevolutions);                                   // print to serial monitor.
}                                                                        // End of subRoutine "totaalOmw".



void stilGevlucht()                                                      // subRoutine "gevlucht staat stil".
{
  Serial.println("stilGevlucht");                                        // print to serial monitor.
  digitalWrite(LED_Still, HIGH);                                         // turn bleu LED on.
  lcd.setCursor(0, 0);                                                   // put the cursor on position 1, line 1.
  lcd.print("        ");                                                 // send 8 spaces to LCD display for empty space.
  lcd.setCursor(0, 0);                                                   // put the cursor on position 1, line 1.
  lcd.print(numberOfRevolutions);                                        // send text to LCD display.
  lcd.setCursor(7, 0);                                                   // put the cursor on position 8, line 1.
  lcd.print(" omw. in ");                                                // send text to LCD display.
  lcd.setCursor(16, 0);                                                  // put the cursor on position 17, line 1.
  lcd.print(jaartal);                                                    // send text to LCD display.
  lcd.setCursor(0, 1);                                                   // put the cursor on position 1, line 2.
  lcd.print ("De wieken staan stil");                                    // send text to LCD display.
  lcd.setCursor(0, 2);                                                   // put the cursor on position 1, line 3.
  lcd.print ("                    ");                                    // send text to LCD display. 
  lcd.setCursor(0, 3);                                                   // put the cursor on position 1, line 3.
  lcd.print ("                    ");                                    // send text to LCD display. 
  lcd.setCursor(2, 3);                                                   // put the cursor on position 3, line 4, align the text with the first number (2),
                                                                         // de tekst (molennaam) kun je uitlijnen met het eerste cijfer (2).
  lcd.write(1);                                                          // draw character from memory position 1.
  lcd.print(" de Heimolen ");                                            // send text to LCD display. (adjust to own mill name),
                                                                         // verzend de tekst (aanpassen aan eigen molennaam).
  lcd.write(1);                                                          // draw character from memory position 1.
 // delay(10);                                                           // pauses the program for the amount of time (in milliseconds).   
}                                                                        // End of subRoutine "gevlucht staat stil".



void bijwerk()                                                           // Start of subroutine "bijwerken".
{
   Serial.println("bijwerk");                                            // print to serial monitor. 
   EEPROM.update(76, revolutionsSpurwheel);                              // update Eeprom address.
   EEPROM.update(86, jaartal);                                           // update Eeprom address.
   Serial.print ("Opslaan aantal omwentelingen : ");                     // print to serial monitor.
   Serial.println (revolutionsSpurwheel / 1.9189);                       // print to serial monitor.
   Serial.print ("Ruwe waarde : ");                                      // print to serial monitor.
   Serial.println (revolutionsSpurwheel);                                // print to serial monitor.
   bijwerkTijd = millis();                                               // set variable 'bijwerkTijd' to time now
 //  delay (10);                                                         // pauses the program for the amount of time (in milliseconds).
}                                                                        // End of subroutine "bijwerken".



void resetTotaalOmw()                                                    // Start of subroutine "Reset Totaal Aantal Omwentelingen".
{
  Serial.println("resetTotaalOmw");                                      // print to serial monitor. 
  jaartal = jaartal +1;                                                  // adds one to date.
  revolutionsSpurwheel = 1;                                              // set revolutionsSpurwheel to zero.
  EEPROM.put(86, jaartal);                                               // set date in EEprom.
  EEPROM.put(76, revolutionsSpurwheel);                                  // update rotations pro year to EEprom address.
  digitalWrite(LED_Still, LOW);                                          // turn bleu LED off.
  delay(200);                                                            // pauses the program for the amount of time (in milliseconds). 
  digitalWrite(LED_Forward, HIGH);                                       // turn green LED on.
  delay(200);                                                            // pauses the program for the amount of time (in milliseconds).
  digitalWrite(LED_Forward, LOW);                                        // turn green LED off.
  delay(40);                                                             // pauses the program for the amount of time (in milliseconds).
  digitalWrite(LED_Still, HIGH);                                         // turn bleu LED on.
  delay(200);                                                            // pauses the program for the amount of time (in milliseconds).
  digitalWrite(LED_Still, LOW);                                          // turn bleu LED off.
  delay(40);                                                             // pauses the program for the amount of time (in milliseconds).
  digitalWrite(LED_red, HIGH);                                           // turn red LED on.
  delay(400);                                                            // pauses the program for the amount of time (in milliseconds).
  digitalWrite(LED_red, LOW);                                            // turn red LED on.
  delay(40);                                                             // pauses the program for the amount of time (in milliseconds). 
  digitalWrite(LED_Still, HIGH);                                         // turn bleu LED on.
  delay(200);                                                            // pauses the program for the amount of time (in milliseconds).
  digitalWrite(LED_Still, LOW);                                          // turn bleu LED off.
  delay(40);                                                             // pauses the program for the amount of time (in milliseconds). 
  digitalWrite(LED_Forward, HIGH);                                       // turn green LED on.
  delay(200);                                                            // pauses the program for the amount of time (in milliseconds).
  digitalWrite(LED_Forward, LOW);                                        // turn green LED off.
  Serial.println ("reset Omwentelingen en verhoog jaartal");             // print to serial monitor.   
  Serial.println (jaartal);                                              // print to serial monitor.
  Serial.println (revolutionsSpurwheel);                                 // print to serial monitor.
  // delay (10);                                                         // pauses the program for the amount of time (in milliseconds).
}                                                                        // End of subroutine "Reset Totaal Aantal Omwentelingen".



void weetZekerDisplay()
{
  Serial.println("weetZekerDisplay");                                    // print to serial monitor.
      lcd.clear();
      lcd.setCursor(0, 0);                                               // put the cursor on position 1, line 1.
      lcd.print("Weet u dit zeker?");                                    // print to display
      lcd.setCursor(0, 1);                                               // put the cursor on position 1, line 2.
      lcd.print("Dan binnen 2 seconde");                                 // print to display
      lcd.setCursor(0, 2);                                               // put the cursor on position 1, line 3.
      lcd.print("magneet nogmaals");                                     // print to display
      lcd.setCursor(0, 3);                                               // put the cursor on position 1, line 1.
      lcd.print("erbij houden");                                         // print to display
      delay (1000);                                                      // delay
      for (int i = 0; i <= 10; i++) {                                    // 10 times blinking
      digitalWrite(LED_Still, LOW);                                      // turn blue LED off.
      Serial.println("knipper");                                         // print to serial monitor.
      delay(80);                                                         // delay blink off.
      (buttonSureState) = digitalRead(reedSchakReset);                   // check if the reed switch B is activated.
       if (buttonSureState != buttonSureStateOld)                        // check if current Sure en previous Sure aren't the same.
         {
         if (buttonSureState == HIGH)                                    // check if buttonSureState is low.
           {
           resetTotaalOmw();                                             // jump to subRoutine "reset totaal aantal omwentelingen per jaar". 
           break;                                                        // break after magnet the second time.
           }
         }
         buttonSureStateOld = buttonSureState;                           // old = new.
       digitalWrite(LED_Still, HIGH);                                    // turn blue LED on.
       delay(120); 
      }
      wiekSnelheid();
      totaalOmw();       
}     



void setup()                                                             // the setup routine runs once when you start the Arduino.
{
  lcd.init();                                                            // initialize the LCD display.
  lcd.backlight();                                                       // put the backlight on.
  lcd.createChar(1, mill);                                               // create character in memorycell 1.
  Serial.begin(9600);                                                    // initialize serial communication at 9600 bits per second.
  pinMode(reedSchakA, INPUT);                                            // initialize digital pin 2 as input.
  pinMode(reedSchakReset, INPUT);                                        // initialize digital pin 4 as input.
  pinMode(LED_red, OUTPUT);                                              // initialize digital pin 8 as output.
  pinMode(LED_Forward, OUTPUT);                                          // initialize digital pin 9 as output.
  pinMode(LED_Still, OUTPUT);                                            // initialize digital pin 10 as output.
  rotationTimeAOld = millis();                                           // set previous time forward.
  EEPROM.get(76, revolutionsSpurwheel);                                  // read revolutionsSpurwheel from EEprom.
  EEPROM.get(86, jaartal);                                               // read date from EEprom.
//  jaartal = 2019;                                                        // de strepen voor deze regel weghalen en voor de volgende regel zetten om jaar terug naar 2019 te stellen
  Serial.println (revolutionsSpurwheel);                                 // print to serial monitor.
  Serial.println (jaartal);                                              // print to serial monitor. 
}                                                                        // End of subRoutine "setup".



void loop()                                                              // the loop routine is running all the time. 
{
  (buttonAState) = digitalRead(reedSchakA);                              // check if the reed switch A is activated.
  if (buttonAState != buttonAStateOld)                                   // check if current time en previous time aren't the same.
    {
    if (buttonAState == HIGH)                                            // check if buttonAState is low.
      {
      rotationTimeA = millis();                                          // current time fot rotation-time.
      wiekSnelheid();                                                    // jump to subRoutine "wiekSnelheid bepalen".
      totaalOmw();                                                       // jump to subRoutine "totaal aantal omwentelingen per jaar".
      revolutionsSpurwheel = revolutionsSpurwheel + 1;                   // counter for rotations spurwheel.
      }
    }
  buttonAStateOld = buttonAState;                                        // previous forward status is equal to forward status.
 
  if (millis() - rotationTimeA == 8000)                                  // check whether if the sails stand still.
    {
    stilGevlucht();                                                      // jump to subRoutine "gevlucht staat stil".
    }

  if (millis() - bijwerkTijd > 60000)                                    // check if 15 minutes (900.000 ms) has been passed. (for testing 1 minute)
    {
    bijwerk();                                                           // jump to subRoutine "bijwerk" to update the memory.
    }

  (buttonResetState) = digitalRead(reedSchakReset);                      // check if the reed switch B is activated.
  if (buttonResetState != buttonResetStateOld)                           // check if current reset en previous reset aren't the same.
    {
    if (buttonResetState == HIGH)                                        // check if buttonResetState is low.
      {
      weetZekerDisplay();                                                // jump to subRoutine "weetZekerDisplay.
      }
    } 
    buttonResetStateOld = buttonResetState;                              // old = new.
}                                                                        // End of subRoutine "loop".
Laatst gewijzigd door RonalT op 27 Jan 2020, 01:07, in totaal 2 keer gewijzigd.

Advertisement

Berichten: 45
Geregistreerd: 08 Jan 2020, 17:23

Re: Teller voor een windmolen

Berichtdoor RonalT » 27 Jan 2020, 00:54

Ik zie dat de code een beetje verschoven is. Als die // staan boven elkaar.
p.s. ik zie wel eens sketches die er gekleurd uit zien en daardoor duidelijker. Geen idee hoe ik dat maak...

Berichten: 4064
Geregistreerd: 16 Okt 2013, 14:31
Woonplaats: s hertogenbosch

Re: Teller voor een windmolen

Berichtdoor shooter » 27 Jan 2020, 11:12

welkom op het forum uiteraard.
allereerst de kleuren komen vaak van een externe editor zoals npp (newspad plus plus) of een andere editor.
er is ook een webeditor op arduino.cc die geeft ook kleuren.
Ik zou de variabelen beter namen geven zoals pinschakelaar, pinrodeled, etc.
het rare inspringen van // kun je voorkomen door elk commentaar op een nieuwe regel te beginnen, daar wordt je programma wel wat langer door, maar het komt door de verschillende letterbreedte, als je een courierlettertype gebruikt heb je er geen last van.
dan het aantal enden:
bereken dat gewoon en zet het in een float dus 71/37*4.

mechanische teller: is natuurlijk prima, en daar kun je dus ook gelijk een magneetje en je reedschakelaar aan vast zetten.
het detecteren van een puls kun je debounce voor gebruiken (kleine routine )
in de loop zet je op een plek dat currenttime = millis() neer. en die gebruik je dan verder dan staan in een cyclus de tijden goed.
omdat je i2c gebruikt zou een RTC een handige aanvulling zijn.
de tijd is dan veel beter en er zitten een paar geheugenplaatsen in die je dus kunt gebruiken om je teller in op te slaan bijvoorbeeld elke minuut of zo, dan blijft de teller staan als je de arduino uitzet.
(het verschil in adres is normaal en komt door het type IC en de addressering daarvan.
Persoonlijk zou ik ook een relaiskaart eraan zetten, zodat je met een lamp aan kunt geven of het allemaal draait of niet.
dan het gemiddelde, als je een paar tellers maakt zoals minuut, 5minuut,uur,dag,jaar.
en dan update met je klok, gaat.
als je dus twee pulsen hebt, kun je de tijd tussen beide pulsen gebruiken om de draaisnelheid te bepalen, dat is niet erg nauwkeurig maar wel een snel resultaat.
je programma ziet er prima uit hoor, ga zo verder.
paul deelen
shooter@home.nl

Berichten: 45
Geregistreerd: 08 Jan 2020, 17:23

Re: Teller voor een windmolen

Berichtdoor RonalT » 27 Jan 2020, 21:57

Bedankt voor je reactie, Paul.

Ik zie dat er inderdaad dikwijls dat soort variabelenamen gebruikt worden, maar ik heb juist deze variabelen gebruikt zodat het voor mij duidelijk is.
Het rare inspringen gebeurt hier op het forum, in IDE staat het juist mooi onder elkaar.
Dat 'float dus 71/37*4' zal ik eens bekijken, als het voor mij verbeterd ga ik het toepassen.
De mechanische teller zit bijna helemaal boven in de molen (3 zolders hoger) en draait met de as mee rond. Deze blijft gewoon tellen en de Arduino teller komt er bij. De magneet en reedschakelaar komen veel lager te zitten (maar 1 zolder hoger dan de werkplek). Als voordeel zie ik het (gemakkelijker af)lezen op de werkplek en voor bezoekers is het zichtbaar hoeveel omwentelingen we gemaakt hebben in het jaar en hoe snel de molen op dit moment draait.
Een soort van debounce gebruik ik volgens mij al. De magneet kan bij de reedschakelaar werd er als een malle geteld en dat is hiermee opgelost. Ook als de magneet stil boven de reedschakelaar blijft staan maar hij wordt maar eenmaal geteld.
Real Time Clock wil ik inderdaad gaan gebruiken om vast te leggen hoeveel we op welk moment hebben gedraaid. Maar die zit geïntegreerd in een SD-card writer/reader.
Relais kaart is niet nodig, in de kast komt een 3 kleuren-LED die groen knippert als er een puls binnenkomt en blauw kleurt als de wieken stil staan.
Het 'het gemiddelde, als je een paar tellers' moet ik nog eens bestuderen, dat is me nog onbekend.

Al met al ben ik zelf ook wel tevreden. Alleen de paar vragen die ik stelde in mijn eerste bericht storen me....

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

Re: Teller voor een windmolen

Berichtdoor Koepel » 28 Jan 2020, 02:05

Een sketch kan beter geen "magische getallen" hebben.
Je hebt nu in je sketch "2.084507043", maar als er per ongeluk een stuk pizza op je toetsenbord valt, dan kan er "2.0804507043" komen te staan. Dat verschil valt niet op.

De Arduino kan berekeningen doen en de compiler kan berekeningen doen. Maak daar gebruik van.
Bijvoorbeeld:
Code: Alles selecteren
const float revSpurwheel = 22.0;
float rev = revSpurwheel * 71.0 / 37.0 * 4.0;


Ik schrijf "4.0" en niet "4". Een "4" is voor de compiler een integer, en met "4.0" geef ik nog eens extra aan dat het een floating point getal voor een floating point berekening is.

Als je het aan stappen telt van een stappenmotor, dan is het logisch om 'long' of 'unsigned long' te gebruiken.
Voor een bepaalde verhouding en snelheid en omtrek is een 'float' handiger. Jij zit daar een beetje tussen in.

Dit is verwarrend:
Code: Alles selecteren
numberOfSails = 60000 / rotationSpeed * conversion;

'numberOfSails' is een 'int'.
'60000' is een integer, maar het past niet in een 'int'.
'rotationSpeed' is een 'int'.
'conversion' is een 'float'.
Hoe gaat de compiler dat berekenen ? Met integers of met float, of allebei. Het is beter als jij bepaalt wat er moet gebeuren. Ik zou deze berekening volledig in 'float' doen. Bij het afdrukken van een float kun je dat laten afronden op hele getallen met een Serial.println( x, 0)

Als je toch iets met 'pin' toevoegt, dan kun je er ook 'const' aan toevoegen.
cpp code
const int pinReedSchakA = 2;
const int pinReedSchakReset = 4;


Dit forum ken twee dingen om code netjes te zetten. Geen van beide is perfect.
Met de "Code" knop, tussen de tags: [ code ] en [ / code ]
Met "Select a Syntax" en dan "C++", dan krijg je de tags: [ code2 = cpp ] en [ / code2 ]

Dit:
Code: Alles selecteren
(buttonAState) = digitalRead(reedSchakA);

kun je beter zonder die haakjes doen:
Code: Alles selecteren
buttonAState = digitalRead(reedSchakA);


Ik kan de sketch niet voldoende doorgronden om te zien wat het lege display veroorzaakt en de teller die nog op nul staat.
Maar ik zie wel een flink aantal dingen die problemen kunnen opleveren.
Mijn eerste gedacht was: "als je iets op het scherm wilt zetten, dan zet je het op het scherm". Maar de delays kunnen dat verstoren.

Tijdens een delay kun je niet kijken of het reedcontact een puls krijgt. Om de hele sketch om te bouwen zodat er geen enkele delay meer is, is een flinke opgave. Ik zou in de code het meten en berekenen apart houden van het display updaten.

Berichten: 45
Geregistreerd: 08 Jan 2020, 17:23

Re: Teller voor een windmolen

Berichtdoor RonalT » 28 Jan 2020, 22:05

Koepel schreef:....knip....
Ik kan de sketch niet voldoende doorgronden om te zien wat het lege display veroorzaakt en de teller die nog op nul staat.
....


En dan ineens zie je het.
Ik was bezig met je opmerkingen en dan zie je ineens waarom het display leeg blijft na het opstarten.
In de loop wordt gewacht op een puls, daarna worden de subroutines wiekSnelheid() en totaalOmw() aangeroepen zodat de informatie op het display geschreven wordt. Maar tot die eerste puls gebeurt er niets.
Ik heb deze twee routines opgenomen in setup() zodat deze eenmaal worden uitgevoerd en het scherm niet leeg blijft.
Later heb ik de 2 subroutines vervangen door de subroutine stilGevlucht() omdat de molen altijd stilstaat tijdens het aanzetten van de elektra.
Nu wordt het display netjes geschreven.

Da's een probleem opgelost!

Nu de rest bestuderen....

Berichten: 45
Geregistreerd: 08 Jan 2020, 17:23

Re: Teller voor een windmolen

Berichtdoor RonalT » 29 Jan 2020, 00:41

Het "magische getal" is vervangen door

cpp code
float conversion = 60.0/(15.0*(71.0/37.0));


Eigenlijk is dit nog veel gemakkelijker, want als deze sketch op een andere molen gebruikt zou gaan worden hoeft men alleen de getallen 71.0 en 37.0 te vervangen. Dit zijn namelijk het aantal tanden van het bovenwiel en het rondsel in onze molen.


Nu moet ik nog zien te ontdekken hoe ik getallen groter dan 255 kan opslaan

Berichten: 45
Geregistreerd: 08 Jan 2020, 17:23

Re: Teller voor een windmolen

Berichtdoor RonalT » 30 Jan 2020, 00:06

Ook het opslaan is opgelost met een andere library.
Ik ben de sketch toch wat aan het verbouwen omdat ik over sommige delen niet tevreden ben. :roll:

Berichten: 45
Geregistreerd: 08 Jan 2020, 17:23

Re: Teller voor een windmolen

Berichtdoor RonalT » 30 Jan 2020, 01:18

Ik ben ook nog aan het kijken geweest naar deze opmerking...

Koepel schreef:....
Als je het aan stappen telt van een stappenmotor, dan is het logisch om 'long' of 'unsigned long' te gebruiken.
Voor een bepaalde verhouding en snelheid en omtrek is een 'float' handiger. Jij zit daar een beetje tussen in.

Dit is verwarrend:
Code: Alles selecteren
numberOfSails = 60000 / rotationSpeed * conversion;

'numberOfSails' is een 'int'.
'60000' is een integer, maar het past niet in een 'int'.
'rotationSpeed' is een 'int'.
'conversion' is een 'float'.
Hoe gaat de compiler dat berekenen ? Met integers of met float, of allebei. Het is beter als jij bepaalt wat er moet gebeuren. Ik zou deze berekening volledig in 'float' doen. Bij het afdrukken van een float kun je dat laten afronden op hele getallen met een Serial.println( x, 0)
.....


Ook dat is gelukt. Alle variabelen zijn float's geworden.
Via de serial monitor krijg ik de getallen tot 2 cijfers achter de komma te zien. Op het LCD display zonder decimalen.

Berichten: 4064
Geregistreerd: 16 Okt 2013, 14:31
Woonplaats: s hertogenbosch

Re: Teller voor een windmolen

Berichtdoor shooter » 30 Jan 2020, 10:06

Mooi werk man, er zit ook een stukje eeprom in een arduino
paul deelen
shooter@home.nl

Volgende

Terug naar Overige projecten

Wie is er online?

Gebruikers in dit forum: Geen geregistreerde gebruikers en 14 gasten