INFO: Dieses Forum nutzt Cookies...
Cookies sind für den Betrieb des Forums unverzichtbar. Mit der Nutzung des Forums erklärst Du dich damit einverstanden, dass wir Cookies verwenden.

Es wird in jedem Fall ein Cookie gesetzt um diesen Hinweis nicht mehr zu erhalten. Desweiteren setzen wir Google Adsense und Google Analytics ein.

Antwort schreiben 
 
Themabewertung:
  • 0 Bewertungen - 0 im Durchschnitt
  • 1
  • 2
  • 3
  • 4
  • 5
Stromgenerator
28.12.2018, 14:09
Beitrag #1
Stromgenerator
Hallo Zusammen,
heute möchte ich meine ersten Gehversuche zur Diskussion stellen.
Was kann ich besser machen?
Es geht um einen StromGenerator der gestartet und gestoppt werden soll.
Der Code ist bis jetzt nur teilweise fertig, es fehlen noch der Stopp und einiges an Störmeldungen und mehrere Startversuche sowie ein automatischer Start/Stop.

Code:
//Eingänge
int start_key = 11; //Start Taster
int stop_key = 12; //Stop Taster
int generatorRun = 10; //Generator liefert Strom

//Ausgänge
int start_relais = 6; //Start Magnet
int stop_relais = 7; //Stop Magnet

//Variablen
int startBit =LOW;
unsigned long startTime=0; //Startzeit speichern
int startStatus =LOW; //Hilfsvariable
const int startZeit = 5000; //Generator Anlasserzeit

void setup() {
    pinMode(start_key, INPUT);
    pinMode(stop_key, INPUT);
    pinMode(generatorRun, INPUT);
    pinMode(start_relais, OUTPUT);
    pinMode(stop_relais, OUTPUT);
    
}
void loop() {
    if (digitalRead (start_key) == HIGH){    //StartTaster gedrückt
        startBit= HIGH;
    }
    if (startBit == HIGH){
        starten(); //Gehe zu starten
    }
}

void starten(){
    if (startStatus == LOW){
        startTime = millis();
        digitalWrite(start_relais, HIGH);
        startStatus = HIGH;
    }
    else
        if ((millis() - startTime >= startZeit) || digitalRead (generatorRun)){
            digitalWrite(start_relais, LOW);
            startStatus = LOW;
            startBit = LOW;
            startTime = 0;
    }
}
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
28.12.2018, 15:37
Beitrag #2
RE: Stromgenerator
Hi,
da ich beruflich u.a. SPS programmiere, empfehle ich dir, sog. Statemaschines zu erlernen.
Wenn du die einmal drauf hast, ist es deutlich leichter, sog. Echtzeitanwendungen "parallel" zu bedienen/steuern.

Ein direkter Hinweis:
Du fragst deine Schalter ab, aber wie sieht es mit dem Entprellen aus ?
Sobald du später die Abfrage auf aus vom gleichen Schalter machst, hast du ggf. viele an/Aus-Durchläufe die du nicht möchtest.

ggf. kann ich hier mal ein paar Zeilen meiner Dosierstation einstellen, fast komplett als Statemaschine geschrieben.

Viel Spaß
Shrimps


(28.12.2018 14:09)uweausbaden schrieb:  Hallo Zusammen,
heute möchte ich meine ersten Gehversuche zur Diskussion stellen.
Was kann ich besser machen?
Es geht um einen StromGenerator der gestartet und gestoppt werden soll.
Der Code ist bis jetzt nur teilweise fertig, es fehlen noch der Stopp und einiges an Störmeldungen und mehrere Startversuche sowie ein automatischer Start/Stop.

Code:
//Eingänge
int start_key = 11; //Start Taster
int stop_key = 12; //Stop Taster
int generatorRun = 10; //Generator liefert Strom

//Ausgänge
int start_relais = 6; //Start Magnet
int stop_relais = 7; //Stop Magnet

//Variablen
int startBit =LOW;
unsigned long startTime=0; //Startzeit speichern
int startStatus =LOW; //Hilfsvariable
const int startZeit = 5000; //Generator Anlasserzeit

void setup() {
    pinMode(start_key, INPUT);
    pinMode(stop_key, INPUT);
    pinMode(generatorRun, INPUT);
    pinMode(start_relais, OUTPUT);
    pinMode(stop_relais, OUTPUT);
    
}
void loop() {
    if (digitalRead (start_key) == HIGH){    //StartTaster gedrückt
        startBit= HIGH;
    }
    if (startBit == HIGH){
        starten(); //Gehe zu starten
    }
}

void starten(){
    if (startStatus == LOW){
        startTime = millis();
        digitalWrite(start_relais, HIGH);
        startStatus = HIGH;
    }
    else
        if ((millis() - startTime >= startZeit) || digitalRead (generatorRun)){
            digitalWrite(start_relais, LOW);
            startStatus = LOW;
            startBit = LOW;
            startTime = 0;
    }
}
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
28.12.2018, 17:31
Beitrag #3
RE: Stromgenerator
Hallo shrimps,
vielen Dank für Deine Anregung.
Versuche gerade mich in statemachines schlau zu machen.
Das Grundprinzip ist mir klar geworden, aber was mir fehlt sind praktische Beispiele.

Grüße Uwe
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
29.12.2018, 08:02
Beitrag #4
RE: Stromgenerator
Hallo Uwe,
anbei zwei Ausschnitte aus meiner Abfüllstation.
Im Hauptteil, die einzige Datei mit Endung .ino, ist lediglich der Rumpf aller Abläufe drin und alle benötigten Module habe ich via include ausgelagert.
Macht alles übersichtlicher und wartbarer.
Leider habe ich die volle Schrittkettenprogrammierung wegen diverser Zeitverzögerungen nicht überall sauber durchgehalten.

Aber anhand des Basismoduls und des Abfüllmoduls kannst du schon mals viel Lesen...

Viel Spaß
Hardy

Mainprogramm:
Code:
/*
* Modul:
* HH, 03.11.18
* Hardware:
* esp32 wroom dev-board china
*/
// #include "i2c.h"
// #define ESP32

// Später für Onlineupdate
const byte FW_VERSION = 101;

// Das HD44780 LCD mit 4x20 Zeichen und I2C
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x3f,20,4);  // set the LCD address to 0x27 for a 20 chars and 4 line display

// Das wiegemodul von Olav Kallhovd sept2017
// das einzige, was vernünfig arbeitet
#include <HX711_ADC.h>
const byte hx711_data_pin  = 18;
const byte hx711_clock_pin = 19;
HX711_ADC LoadCell(hx711_data_pin, hx711_clock_pin);

// Horter & Kalb I2c-Karten mit negativer Logik, plusschaltend !
#include "PCF8574.h"
// I2C Eingangskarte, negative Logik !
PCF8574 PCF_INPUT(0x3c);
// I2C Ausgangskarte, negative Logik !
PCF8574 PCF_OUTPUT(0x27);

// Kleine Helfer aus der IEC-SPS-Welt
#include "plclib.h"
// Wir reservieren 4 Tasten zum Überwachen
R_TRIG rtrig_Tasten[4];
F_TRIG ftrig_Tasten[4];

// Unsere benötigten Vars
#include "variablen.h"

// Flash-Speicher
#include <Preferences.h>
// Alles was wir dauerhaft speichern wollen
#include "nvram.h"

#include <ArduinoSort.h>
#include "lcd.h"
#include "tools.h"
#include "Horter_Kalb_IO.h"
#include "holeTasten.h"
#include "waage.h"
#include "einstellungen_details.h"
#include "einstellungen.h"
#include "abfuellen.h"


void setup() {

  Serial.begin(115200);
  Serial.println("Modul startet...");

  Serial.print("NVRAM Size:");
  Serial.println(sizeof(NVRAM));
  

  // sets the pins as outputs:
  pinMode(EN_motor1_links_GPIO, OUTPUT);
  pinMode(EN_motor1_rechts_GPIO, OUTPUT);
  pinMode(PWM_motor1_GPIO, OUTPUT);
  // configure PWM functionalitites
  ledcSetup(PWM_channel, NVRAM.pwm.frequency, PWM_resolution);
  // attach the channel to the GPIO to be controlled
  ledcAttachPin(PWM_motor1_GPIO, PWM_channel);

  digitalWrite(EN_motor1_links_GPIO , HIGH);
  digitalWrite(EN_motor1_rechts_GPIO, HIGH);

  lcd_init();

  Memory(1);                    // Wir lesen alle Daten

  lcd.setCursor(0,0);
  lcd.print("Init: Input");
  PCF_INPUT_Init();
  
  lcd.setCursor(0,1);
  lcd.print("Init: Output");
  PCF_OUTPUT_Init();


  lcd.setCursor(0,2);
  lcd.print("Init: Waage");
  waage_init();

  // demo
  delay(2000);
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("Dosierstation");
  lcd.setCursor(0,1);
  lcd.print("(c) HH");
  lcd.setCursor(0,2);
  delay(3000);  
  // lcd.print("Waage aktiv");
  // lcd.setCursor(0,1);
  // lcd.print(cLeerzeile);
  
}

// the loop function runs over and over again forever
void loop() {

  if (blinker1(250)) bBlinker1 = ! bBlinker1;

  if (ticker4(100)) holeTasten();


// _eAnlagenmodus eAnlagenmodus = eAnlage_Init;
  switch (eAnlagenmodus) {
    case eAnlage_Init:
    // keine Ahnung ob vorher irgendwas getan werden muss
    eAnlagenmodus = eAnlage_Automatik;
    break;

    case eAnlage_Automatik:
      abfuellen();
    break;


    case eAnlage_Einstellungen:
      einstellungen();
    break;


    default:
      // if nothing else matches, do the default
      // default is optional
      break;
  }

  if (Led_Timer(10)) Tasten_Led_Aktualisieren();


} // void loop()

Nun ein Teil: die Steuerung der Dosierung
Hier habe ich bewusst sehr viele Einzelschritte eingebaut, damit das LCD nicht flackert, sondern einmal die Infos bekommt und dann erst im weiteren Schritt die permanenten Schleifen laufen...


Code:
void show_debugdata() {
  Serial.print("Gewicht ist:");
  Serial.print(Gewicht_ist);
  Serial.print(" / Gewicht Soll:");
  Serial.println(NVRAM.waage.gewicht_soll);
}


/*
   HH, 02.12.2018, Mobil
   Modul zum abfüllen der Flaschen
   Logik:
    Es werden alle Modi initialisiert,
    die Motoren ausgemacht.
    Die Waage wird leer auf tara gesetzt
    Die LEDs werden alle ausgeschaltet, nur ROT ist an
    Ab jetzt:
    ROT > GRÜN = Start
    ROT > GELB = ungültig
    ROT > BLAU = Pumpe einschalten, so lange BLAU gedrückt, dann wieder auf ROT
    BLAU > ROT = Standard
    GRÜN > GELB = Halt : not implemented
    GRÜN > ROT = STOP (Nothalt) = Standard

*/

void abfuellen() {
  static uint16_t iStep = 0;  // Schrittkette
  char lcd_buffer[10];        // Für formatierte Ausgabe

  Gewicht_ist = waage();      // Gewicht immer auslesen

  // Alle 1/2s Gewict anzeigen
  if (ticker1(500)) {
    lcd.setCursor(0, 3);
    sprintf(lcd_buffer, "%5i", Gewicht_ist);
    lcd.print(lcd_buffer);
  }

  // ROT = Notstop
  if (Tasten[ROT].hold and iStep != 10) {
    Tasten[ROT].hold = false;
    iStep = 0;
  }


  // Unsere Schrittkette
  switch (iStep) {
    case 0:
      // Motoren etc aus !
      // Beide pins aus: Motor steht !
      // Sicherheitshalber den PWM auf 0, dies ist der EN des Motors

      digitalWrite(EN_motor1_links_GPIO , STOP);
      digitalWrite(EN_motor1_rechts_GPIO, STOP);
      ledcWrite(PWM_channel, 0);
      resetTasten();
      Takt(1, true);
      LoadCell.tare(); // Tara setzen !
      iStep = 5;
      break;

    case 5:
      lcd.clear();
      lcd.setCursor(0, 0);
      lcd.print("Automatik");
      lcd.setCursor(15, 0);
      lcd.print(NVRAM.waage.gewicht_erkennen);
      lcd.setCursor(0, 1);
      lcd.print("Warte auf Start");
      lcd.setCursor(0, 2);
      lcd.print("Zielgewicht:");
      lcd.setCursor(13, 2);
      lcd.print(NVRAM.waage.gewicht_soll);
      Tasten[ROT].ledon = true;
      iStep = 10;
      break;

    case 10:
      // Installatiosmenü: ROT und GELB lange festhalten !
      if (Tasten[ROT].hold and Tasten[ROT].count > 20 and Tasten[GELB].hold and Tasten[GELB].count > 20) {
        Tasten[ROT].hold = false;
        Tasten[GELB].hold = false;
        Tasten[ROT].ledon = false;
        eAnlagenmodus = eAnlage_Einstellungen;
        iStep = 0;
      }

      // Start der Abfüllung mit Grün
      if (Tasten[GRUEN].hold) {
        Tasten[GRUEN].hold = false;
        iStep += 10;
      }

      // Manuell Pumpe AN/AUS mit Blau
      if (Tasten[BLAU].hold) {
        Tasten[BLAU].hold = false;
        Tasten[ROT].ledon = false;
        Tasten[BLAU].ledon = true;
        iStep = 10000;
      }
      break;

    // Start der Standardabfüllung
    case 20:
      lcd.setCursor(0, 1);
      lcd.print(cLeerzeile);
      lcd.setCursor(0, 1);
      lcd.print("Setze Tara");
      lcd.setCursor(0, 2);
      lcd.print("Zielgewicht:");
      lcd.setCursor(13, 2);
      lcd.print(NVRAM.waage.gewicht_soll);
      Tasten[ROT].ledon = false;
      Tasten[GRUEN].ledon = true;
      LoadCell.tare(); // Tara setzen !
      iStep += 10;
      break;

    case 30: // Tara abwarten
      // Geht nicht weil wir in der Task zu schnell sind: Waage = 50ms
      // if (LoadCell.getTareStatus() == true) iStep = 1000;
      if (Takt(200)) {
        Takt(1, true);
        iStep += 10;
      }
      break;

    case 40: // Vorbereitung: Standardflasche messen.
      lcd.setCursor(0, 1);
      lcd.print(cLeerzeile);
      lcd.setCursor(0, 1);
      lcd.print("Bitte Leergut");
      Tasten[GRUEN].ledblink = true;
      iStep += 10;
      break;

    case 50:  // Warten auf Taste mit Leergut/ GRÜN
      if (Tasten[GRUEN].hold) {
        Tasten[GRUEN].hold = false;
        Tasten[GRUEN].ledblink = false;
        iStep += 10;
      }
      break;

    case 60: // Info
      lcd.setCursor(0, 1);
      lcd.print(cLeerzeile);
      lcd.setCursor(0, 1);
      lcd.print("Tara speichern");
      iStep += 10;
      break;

    case 70: // Tara speichern
      Gewicht_tara = Gewicht_ist;               // Tara speichern
      Gewicht_automatik = Gewicht_tara * 0.7;   // Ca-Gewicht für Automatik
      if (Takt(2000)) {
        Takt(1, true);
        iStep += 10;
      }
      break;

    case 80: // Hinweis: Flasche runter
      lcd.setCursor(0, 1);
      lcd.print(cLeerzeile);
      lcd.setCursor(0, 1);
      lcd.print("Leergut entnehmen");
      iStep += 10;
      break;

    case 90:  // Warten auf Taste
      Tasten[GRUEN].ledblink = true;
      if (Tasten[GRUEN].hold) {
        Tasten[GRUEN].hold = false;
        Tasten[GRUEN].ledblink = false;
        iStep += 10;
      }
      break;

    case 100: // Neues Tara setzen
      LoadCell.tare(); // Tara setzen !
      iStep += 10;
      break;

    case 110: // Tara abwarten
      if (Takt(500)) {
        Takt(1, true);
        iStep = 1000;
      }
      break;

    //********************************************************************

    case 1000:  // Standardschleife
      lcd.clear();
      lcd.setCursor(0, 0);
      lcd.print("Prozess laeuft !!!");
      lcd.setCursor(0, 1);
      lcd.print("Leere Flasche bitte");
      lcd.setCursor(0, 2);
      lcd.print("Zielgewicht:");
      lcd.setCursor(13, 2);
      lcd.print(NVRAM.waage.gewicht_soll);

      Tasten[GRUEN].ledblink = true;
      iStep += 100;

      break;

    case 1100:  // Tastenanfrage oder via Gewichtserkennung
      if (Tasten[GRUEN].hold) {
        Tasten[GRUEN].hold = false;
        Tasten[GRUEN].ledblink = false;
        iStep += 100;
      }
      // Automatik, wenn nach 5s gewicht erkannt, dann los
      if (NVRAM.waage.gewicht_erkennen and (Gewicht_ist > Gewicht_automatik)) {
        if (Takt(5000)) {
          Takt(1, true);
          Tasten[GRUEN].ledblink = false;
          iStep += 100;
        }
      }
      break;

    case 1200: // Tara info
      lcd.setCursor(0, 1);
      lcd.print(cLeerzeile);
      lcd.setCursor(0, 1);
      lcd.print("Tara setzen");
      iStep += 100;
      break;

    case 1300: // Tara setzen !
      LoadCell.tare();
      iStep += 100;
      break;

    case 1400:
      if (Takt(500)) {
        Takt(1, true);
        iStep += 100;
      }
      break;

    case 1500: // Pumpeninfo
      lcd.setCursor(0, 1);
      lcd.print(cLeerzeile);
      lcd.setCursor(0, 1);
      lcd.print("Pumpe AN !");
      iStep += 100;
      break;

    case 1600:  // full process
      digitalWrite(EN_motor1_links_GPIO , START);
      digitalWrite(EN_motor1_rechts_GPIO, STOP);
      PWM_duty = 255;
      ledcWrite(PWM_channel, PWM_duty);                // Max Speed
      iStep += 100;
      break;

    case 1700:  // !! Action:Laufen lassen bis Gewicht erreicht !!

      // Ist das erreichte Gewicht über der ersten Schwelle, dann langsamer
      if (Gewicht_ist >= (NVRAM.waage.gewicht_soll - NVRAM.pwm.half_weight)) PWM_duty = NVRAM.pwm.half_duty;
      // Ist das erreichte Gewicht über der zweiten Schwelle, dann ganz langsam
      if (Gewicht_ist >= (NVRAM.waage.gewicht_soll - NVRAM.pwm.slow_weight)) PWM_duty = NVRAM.pwm.slow_duty;
      ledcWrite(PWM_channel, PWM_duty);

      // Haben wir unser Gewicht erreicht ?
      if (Gewicht_ist >= NVRAM.waage.gewicht_soll) {
        digitalWrite(EN_motor1_links_GPIO , STOP);
        digitalWrite(EN_motor1_rechts_GPIO, STOP);
        iStep += 100;
      }
      break;

    case 1800: // s warten, damit Motor nicht sofort rückwärts fährt
      if (Takt(1000)) {
        Takt(1, true);
        iStep += 100;
      }
      break;

    case 1900: // nun 1s rückwärts
      digitalWrite(EN_motor1_links_GPIO , STOP);
      digitalWrite(EN_motor1_rechts_GPIO, START);
      ledcWrite(PWM_channel, 255);
      if (Takt(1000)) {
        digitalWrite(EN_motor1_links_GPIO , STOP);
        digitalWrite(EN_motor1_rechts_GPIO, STOP);
        ledcWrite(PWM_channel, 0);
        Takt(1, true);
        iStep = 5000;
      }
      break;

    //********************************************************************

    case 5000:  // Info Voll !
      lcd.setCursor(0, 1);
      lcd.print(cLeerzeile);
      lcd.setCursor(0, 1);
      lcd.print("Flasche voll");
      Tasten[GRUEN].ledblink = true;
      iStep += 100;
      break;

    case 5100: // Grüne Taste zum weitermachen oder Autogewicht
      if (Tasten[GRUEN].hold) {
        Tasten[GRUEN].hold = false;
        Tasten[GRUEN].ledblink = false;
        iStep += 100;
      }
      if (NVRAM.waage.gewicht_erkennen and (Gewicht_ist < (Gewicht_automatik * -1))) {
        if (Takt(5000)) {
          Takt(1, true);
          Tasten[GRUEN].ledblink = false;
          iStep += 100;
        }
      }
      break;

    case 5200: // Tara setzen
      LoadCell.tare(); // Tara setzen !
      iStep += 100;
      break;

    case 5300:
      if (Takt(500)) {
        Takt(1, true);
        iStep = 1000;
      }
      break;

    //********************************************************************

    case 10000: // Sonderfall Reinigung durch BLAUE-Taste
      lcd.clear();
      lcd.setCursor(0, 0);
      lcd.print("Reinigung");
      lcd.setCursor(0, 1);
      lcd.print("BLAU(halten) = Pumpe AN");
      lcd.setCursor(0, 2);
      lcd.print("ROT = Exit");
      iStep += 100;
      break;

    case 10100: // Blau: Motor an/aus
      ledcWrite(PWM_channel, 0);
      digitalWrite(EN_motor1_links_GPIO, START);
      digitalWrite(EN_motor1_rechts_GPIO, STOP);
      Tasten[BLAU].ledblink = false;
      iStep += 100;
      break;

    case 10200: // Tastenabfrage, mit ROT oben vor Switch kommt man raus !
      if (Tasten[BLAU].hold and Tasten[BLAU].count > 10) {
        ledcWrite(PWM_channel, 255);
        Tasten[BLAU].ledblink = true;
      }
      else {
        ledcWrite(PWM_channel, 0);
        Tasten[BLAU].ledblink = false;
      }
      break;


[/php]    default:  // Ohje
      break;
  }
}

Nun noch die Tools, damit du siehst, wie ich die Timer aufgebaut habe...
Sicherlich wird der eine oder andere sagen, das dies auch mit Klassen geht...
Aber für mich war CutnPaste simpler...
Wichtig ist nur, das man den gleichen Timer nicht an mehereren aktiven Stellen einsetzt, das gäbe Chaos...
Die Tasten- und LED-Ansteuerung lasse ich erstmal aussen vor...
Da ich dort mit Triggern und STructures arbeite, sollten wir dies später besprechen...

Code:
// An optimized version of Bubble Sort
void bubbleSort(int32_t arr[])
{
  // #define swap(a, b) { int16_t t = a; a = b; b = t; }
   int32_t tmp;
   int i, j;
   int32_t elements;
   elements = sizeof(arr)/sizeof(arr[0]);
   bool swapped;
  
   for (i = 0; i < elements-1; i++)
   {
     swapped = false;
     for (j = 0; j < elements-i-1; j++)
     {
        if (arr[j] > arr[j+1])
        {
           //swap(&arr[j], &arr[j+1]);
           tmp      = arr[j];
           arr[j]   = arr[j+1];
           arr[j+1] = tmp;;
           swapped  = true;
        }
     }
  
     // IF no two elements were swapped by inner loop, then break
     if (swapped == false)
        break;
   }
}




void sort(int32_t a[]) {
  int size,i,j;
  int32_t t;
  size = sizeof(a)/sizeof(a[0]);
    for(i=0; i<(size-1); i++) {
        for(j=0; j<(size-(i+1)); j++) {
                if(a[j] > a[j+1]) {
                    t = a[j];
                    a[j] = a[j+1];
                    a[j+1] = t;
                }
        }
    }
}



byte zweihoch7(byte exponent)
{  
    byte result = 1;
    byte i;
    exponent = constrain(exponent, 0, 7);
    for (i=1; i<=exponent; i++) result = result*2;
    return result;
}


byte holeAnlagenModus(){
  /*
* Hier die beiden Tasten des Drehwahlschalters auswerten
* 0 = Install, 1 = auto, 2 = manuell
*/
  byte modus =1;

  return modus;
}

// Zentraler Blinker

boolean blinker1(long interval){
  static int oldValue;
  int value=millis() % interval;
  boolean q= value < oldValue;
  oldValue=value;
  return q;
}


boolean Led_Timer(long interval){
  static int oldValue;
  int value=millis() % interval;
  boolean q= value < oldValue;
  oldValue=value;
  return q;
}

// TON mit Millisekunden
boolean Takt(long interval, boolean reset = false){
  static int oldValue;
  int value;
  boolean q;
  
  if (reset){
    oldValue = 0;
  }
  else {
    value=millis() % interval;
    q= value < oldValue;
    oldValue=value;
  }  
  return q;
}





// TON mit Millisekunden
boolean ticker1(long interval){
  static int oldValue;
  int value=millis() % interval;
  boolean q= value < oldValue;
  oldValue=value;
  return q;
}

boolean ticker2(long interval){
  static int oldValue;
  int value=millis() % interval;
  boolean q= value < oldValue;
  oldValue=value;
  return q;
}

boolean ticker3(long interval){
  static int oldValue;
  int value=millis() % interval;
  boolean q= value < oldValue;
  oldValue=value;
  return q;
}

boolean ticker4(long interval){
  static int oldValue;
  int value=millis() % interval;
  boolean q= value < oldValue;
  oldValue=value;
  return q;
}


void BlinkInternalLed(){
#define DEF_BUILDIN_LED 2
  static unsigned long Zeitscheibe = 0;
  static boolean init = false;
  static boolean toggle;

  if (init == false) {
    init = true;
    pinMode(DEF_BUILDIN_LED, OUTPUT);
  }

  if (millis()- Zeitscheibe > 1000){    // Zeitscheibe wird alle 500ms aufgerufen
     Zeitscheibe  = millis();
     toggle = ! toggle;
     digitalWrite(DEF_BUILDIN_LED, toggle);
  }// end Zeitscheibe
}
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
29.12.2018, 12:06
Beitrag #5
RE: Stromgenerator
uhi das ist jetzt geballte Information, fühle mich fast schon erschlagen.
Wie schon gesagt, ich bin blutiger Anfänger und arbeite mich an meinem Projekt langsam vorwärts.
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
29.12.2018, 12:49 (Dieser Beitrag wurde zuletzt bearbeitet: 29.12.2018 13:00 von Tommy56.)
Beitrag #6
RE: Stromgenerator
(29.12.2018 12:06)uweausbaden schrieb:  Wie schon gesagt, ich bin blutiger Anfänger
Je öfter Du das betonst, um so länger wird meist der Zustand anhalten. Wink

Zerlege Dein Problem in Teilprobleme (was Du schon teilweise gemacht hast) und löse diese erst mal einzeln. Da stellt sich schneller ein Erfolgserlebnis ein.

Zu Zustandsautomaten (state machine) schau Dir mal diese Abhandlung an.

Alle ganzzahligen Variablen vom Typ int zeigt meist, dass man noch nicht darüber nachgedacht hat.
Ein Pin kann z.B. nicht negativ werden und auch nicht größer als 255, also genügt da der Typ byte. Microcontroler haben wenig RAM, da sollte man sich gleich am Anfang ans Sparen gewöhnen.
Statusvariable sollte man gleich als bool deklarieren, da hat der Compiler mehr Möglichkeiten Fehler zu erkennen.
Bit im Variablennamen (startBit) sollte man nur verwenden, wenn man das einzelne Bit eines Bytes meint, ansonsten verwirrt das nur.

Gruß Tommy

"Wer den schnellen Erfolg sucht, sollte nicht programmieren, sondern Holz hacken." (Quelle unbekannt)
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
03.01.2019, 15:56
Beitrag #7
RE: Stromgenerator
Vielen Dank für die Kritik, hilft sie doch besser zu werden.
Hier ein neuer Versuch, da kann man bestimmt noch viel verbessern!
Von der Anforderung fehlt noch das Stoppen und der Vollautomatische Start auf Anforderung.
Bin gespannt was Ihr meint und nur nicht zu knapp mit Kritik und Vorschlägen umgehen.
Code:
//Eingänge
int genStart = 11; //Start Taster
int genStop = 12; //Stop Taster
int genRun = 10; //Generator liefert Strom

//Ausgänge
int start_relais = 6; //Start Magnet
int stop_relais = 7; //Stop Magnet

//Variablen
bool startSignal =LOW;
bool stopByte =LOW;
byte startVersuch = 1;
bool startStatus =LOW; //Hilfsvariable
unsigned long startTimestore=0; //Startzeit speichern
unsigned long startWartezeit=0; //StartWartezeit speichern
const int startZeit = 3000; //Generator Anlasserzeit
const int warteZeit = 5000; //Wartezeit zwischen den Startversuchen

void setup() {
    pinMode(genStart, INPUT);
    pinMode(genStop, INPUT);
    pinMode(genRun, INPUT);
    pinMode(start_relais, OUTPUT);
    pinMode(stop_relais, OUTPUT);
    
}
void loop() {
    eingang();
    verarbeiten();
}

void eingang(){
    
    if (digitalRead (genStart) && !digitalRead (genRun)) {    startSignal=HIGH;}    //StartTaster gedrückt
    
    stopByte = digitalRead(genStop);    //StopTaster gedrückt
    if (stopByte){    startVersuch = 1;} //Startphase zurücksetzen
}

void verarbeiten(){
    if (digitalRead(genRun)) {    //Generator läuft, Startphase qutieren
        digitalWrite(start_relais, LOW);
        startSignal = LOW;
        startVersuch = 1;
        startStatus = LOW;
    }
    
    if (startSignal){    // 3 Startversuche
        switch (startVersuch){
            case 1:
                starten(); //Generator starten
                break;
            case 2:
                if (millis() - startWartezeit >= warteZeit){    starten();} //Generator starten                
                break;
            case 3:
                if (millis() - startWartezeit >= warteZeit){    starten();} //Generator starten                
                break;
            default:
                startSignal = 0; //Störung! muss mit Stopp Quitiert werden
        }        
    }
}

void starten(){
    if (startStatus == LOW){
        startTimestore = millis();
        digitalWrite(start_relais, HIGH); //Anlasser wird betätigt
        startStatus = HIGH;
    }
    else
        if ((millis() - startTimestore >= startZeit) || digitalRead (genRun)){
            digitalWrite(start_relais, LOW);
            startStatus = LOW;
            startTimestore = 0;
            if (!digitalRead(genRun)){    startVersuch = ++startVersuch;} //Start fehlgeschlagen, Startversuche zählen
            startWartezeit = millis(); //Wartezeit bis zum nächsten Startversuch
    }
    
    
}
[/
code]
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
03.01.2019, 17:45 (Dieser Beitrag wurde zuletzt bearbeitet: 03.01.2019 17:47 von Tommy56.)
Beitrag #8
RE: Stromgenerator
In der if - Bedingung || digitalRead(genRun) und im Bedingungsrumpf die gleiche Bedingung negiert abgefragt, kommt mir sehr merkwürdig vor.
Einige Pins sind immer noch int.

Gruß Tommy

"Wer den schnellen Erfolg sucht, sollte nicht programmieren, sondern Holz hacken." (Quelle unbekannt)
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
Antwort schreiben 


Gehe zu:


Benutzer, die gerade dieses Thema anschauen: 2 Gast/Gäste