Go Down

Topic: Projekt zur Ermittlung der Dauerbetriebseigenschaften unterschiedlicher Sensoren (Read 3046 times) previous topic - next topic

Hayley_Hay

Ich melde mich mal wieder hier mit einem kleinen Update:

Die Übertragung der Daten läuft jetzt stabil über den seriellen Monitor des RasPi, das Skript zur Erstellung der Datenbank funktioniert leider nicht zuverlässig. Trotzdem habe ich so schon einige Stunden an Datenaufzeichnung zusammenbekommen.

Die Steuerung mittels des einen Arduino läuft prinzipiell ebenfalls wie gewünscht (Abfahren des Programms Pumpen - Pause - Pumpen ... Belüften ). Allerdings bleibt es regelmäßig über Nacht stehen, scheinbar (bisher drei Mal) immer an der selben Stelle zum Ende des einen Pumpzyklus nach ca. 28 000 s Gesamtlaufzeit. Ich komme leider nicht dahinter, woran es liegen könnte, zumal ich frühere, einfachere Versionen bereits länger laufen lassen konnte, ohne dass es zu einem Abbruch kam. Blöderweise habe ich dafür keine ordentliche Versionierung.

Vielleicht kommt es irgendwo zu einem Überlauf oder dergleichen? Ich lasse mal den Code hier, vielleicht hat ja jemand eine Idee? Das Problem tritt natürlich nur im Modus 'Programm' auf.

Code: [Select]

#include<Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 16, 2);

// Belegung der Ein- und Ausgaenge, Relais und Switches, Zustandsvariablen

const byte RY_V1_pin = 3;  // Verdichter
byte RY_V1_state;

const byte RY_M1_pin = 5;  // Magnetventil 1
byte RY_M1_state;

const byte RY_M2_pin = 7;  // Magnetventil 2
byte RY_M2_state;

const byte RY_M3_pin = 9;  // Magnetventil 3
byte RY_M3_state;

const byte SW1_pin = 4;    // Schalter 1
bool SW1_status;
const byte SW2_pin = 6;    // Schalter 2
bool SW2_status;
const byte SW3_pin = 8;    // Schalter 3
bool SW3_status;

const byte trig_A = 2;
const byte trig_B = 13;

bool A_state;
bool B_state;


// Zeit
const unsigned int long pump_intervall = 315000;
const unsigned int long pause_intervall = 20000;
const unsigned int long air_intervall = 30000;

unsigned int long remaining_time;
unsigned int long elapsed_time;

unsigned int long Millis;
unsigned int long Intervall;

unsigned int long schreib_timestore;
const int long schreib_intervall = 1000;


void setup() {
  Wire.begin();
  Serial.begin(9600);

  pinMode(trig_A, OUTPUT);
  pinMode(trig_B, OUTPUT);

  pinMode(RY_M3_pin, OUTPUT);
  digitalWrite(RY_M3_pin, HIGH);

  pinMode(RY_M2_pin, OUTPUT);
  digitalWrite(RY_M2_pin, HIGH);

  pinMode(RY_M1_pin, OUTPUT);
  digitalWrite(RY_M1_pin, HIGH);

  pinMode(RY_V1_pin, OUTPUT);
  digitalWrite(RY_V1_pin, HIGH);

  pinMode(SW1_pin, INPUT);
  pinMode(SW2_pin, INPUT);
  pinMode(SW3_pin, INPUT);
  digitalWrite(SW1_pin, HIGH);
  digitalWrite(SW2_pin, HIGH);
  digitalWrite(SW3_pin, HIGH);

  lcd.init();
  lcd.clear();
  lcd.backlight();
  lcd.setCursor(0, 0);
  lcd.print("Pumpen/Belueften");
  lcd.setCursor(0, 1);
  lcd.print("Funktion waehlen");
}

void dig_Write() {
  digitalWrite(RY_V1_pin, RY_V1_state);
  digitalWrite(RY_M1_pin, RY_M1_state);
  digitalWrite(RY_M2_pin, RY_M2_state);
  digitalWrite(RY_M3_pin, RY_M3_state);
  digitalWrite(trig_A, A_state);
  digitalWrite(trig_B, B_state);
}

enum ZUSTAENDE {
  A_to_B, pause_1 , B_to_A, pause_2, pause_0, air
};

byte curr_state = pause_2;
byte next_state = A_to_B;
byte prev_state = B_to_A;

const int rounds = 2;
int count_rounds = 0;
int count_global = 0;

void A_B () {
  RY_V1_state = LOW;
  RY_M1_state = LOW;
  RY_M2_state = HIGH;
  RY_M3_state = HIGH;
  A_state = 1;
  B_state = 0;
  dig_Write();
  Millis = millis();
  curr_state = A_to_B;
  return;
}

void B_A () {
  RY_V1_state = LOW;
  RY_M1_state = HIGH;
  RY_M2_state = LOW;
  RY_M3_state = HIGH;
  A_state = 0;
  B_state = 1;
  dig_Write();
  Millis = millis();
  curr_state = B_to_A;
  return;
}

void Air () {
  RY_V1_state = LOW;
  RY_M1_state = HIGH;
  RY_M2_state = HIGH;
  RY_M3_state = LOW;
  A_state = 1;
  B_state = 1;
  dig_Write();
  Millis = millis();
  curr_state = air;
  return;
}

void pause () {
  RY_V1_state = HIGH;
  RY_M1_state = HIGH;
  RY_M2_state = HIGH;
  RY_M3_state = HIGH;
  curr_state = pause_0;
  A_state = 0;
  B_state = 0;
  dig_Write();
  Millis = millis();
  return;
}

void programm() {
  if (millis() - Millis >= Intervall) {
    switch (next_state) {

      case A_to_B:
        count_rounds++;
        count_global++;
        prev_state = curr_state;
        A_B();
        next_state = pause_1;
        Intervall = pump_intervall;
        break;

      case pause_1:
        pause();
        prev_state = curr_state;

        next_state = B_to_A;
        Intervall = pause_intervall;
        break;

      case B_to_A:
        prev_state = curr_state;
        B_A();
        next_state = pause_2;
        Intervall = pump_intervall;
        break;

      case pause_2:
        prev_state = curr_state;
        pause();
        if (count_rounds <= rounds)
        {
          next_state = A_to_B;
        }
        else {
          next_state = air;
        }
        Intervall = pause_intervall;
        break;

      case air:
        prev_state = curr_state;
        Intervall = air_intervall;
        Air();
        count_rounds = 0;
        next_state = pause_2;
    }
  }
}

unsigned int long switches_last_millis;
const unsigned int long switches_intervall = 50;

bool readingSwitches() {
  if(millis()- switches_last_millis < switches_intervall) return;
  switches_last_millis += switches_intervall;

  SW1_status = digitalRead(SW1_pin);
  SW2_status = digitalRead(SW2_pin);
  SW3_status = digitalRead(SW3_pin);
  return;
}

void schreiben() {
  if (millis() - schreib_timestore >= schreib_intervall) {
    schreib_timestore = millis();
    Serial.print(millis());
    Serial.print(",");
    Serial.print(curr_state);
    Serial.print(",");
    Serial.print(elapsed_time);
    Serial.print(",");
    Serial.print(RY_V1_state);
    Serial.print(",");
    Serial.print(RY_M1_state);
    Serial.print(",");
    Serial.print(RY_M2_state);
    Serial.print(",");
    Serial.print(RY_M3_state);
    Serial.println("");
  }
}

unsigned int display_last_millis;
const unsigned int display_intervall = 1000;

void Display() {
  if(millis()- display_last_millis < display_intervall) return;
  display_last_millis += display_intervall;

  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("Runde ");
  lcd.print(count_global);
  lcd.print(" ");
  if (curr_state == 4) {
    lcd.print("- Pause");
  }
  if (curr_state == 0) {
    lcd.print("- A->B");
  }
  if (curr_state == 2) {
    lcd.print("- B->A");
  }
  if (curr_state == 5) {
    lcd.print("- Air");
  }
  lcd.setCursor(0, 1);
  if (next_state == pause_1 || next_state == pause_2 || next_state == pause_0) {
    lcd.print("Pause in ");
  }
  if (next_state == A_to_B) {
    lcd.print("A->B in ");
  }
  if (next_state == B_to_A) {
    lcd.print("B->A in ");
  }
  if (next_state == air) {
    lcd.print("Air in ");
  }
  lcd.print(remaining_time);
  lcd.print(" s");
}


void loop() {
  schreiben();

  elapsed_time = (millis() - Millis) / 1000;
  remaining_time = Intervall / 1000 - elapsed_time;

  readingSwitches();

  if (SW1_status == HIGH && SW2_status == HIGH && SW3_status == HIGH) {  // Schalter 1+2+3
    programm();
  }

  if (SW1_status == HIGH && SW2_status == HIGH && SW3_status == LOW) {   // Schalter 1+2
    A_B();
  }

  if (SW1_status == HIGH && SW2_status == LOW && SW3_status == HIGH) {   // Schalter 1+3
    B_A();
  }

  if (SW1_status == HIGH && SW2_status == LOW && SW3_status == LOW) {    // Schalter 1
    Air();
  }

  if (SW1_status == LOW && SW2_status == LOW && SW3_status == LOW) { // kein Schalter
    pause();
    //}
  }
  if (SW1_status == LOW && SW2_status == LOW && SW3_status == HIGH) {
    pause();
  }

  if (SW1_status == LOW && SW2_status == HIGH && SW3_status == HIGH) {
    pause();
  }

  Display();
}



agmue

Code: [Select]
unsigned int display_last_millis;
const unsigned int display_intervall = 1000;

Wenn ich int im Zusammenhang mit millis() sehe, werde ich skeptisch.

Hayley_Hay

Code: [Select]
unsigned int display_last_millis;
const unsigned int display_intervall = 1000;

Wenn ich int im Zusammenhang mit millis() sehe, werde ich skeptisch.
Danke! Das stell ich mal ab und schau, was die Nacht bringt...

Rentner

Hallo,
kann mich da agmue nur anschliessen.
alle Variable die bei Berechnungen und abfragen  mit millis() benutzt werden solltest Du erst mal als

unsigned long Mllis // deklarieren

bei abfragen mit festen Werten im code den Wert mit UL kennzeichnen z.B


if millis()-Millis >=1000UL




Hayley_Hay

So, ich habe alle entsprechenden Variablen und Konstanten in unsigned long geändert - leider ist das Programm wieder stehen geblieben (dieses Mal nach 34000 s und mit dem Unterschied, dass nun wieder das Start-Display gezeigt wurde, wo vorher nur das "R" von Runde ... angezeigt wurde)  :(

Rentner

Hallo
34000s ist ja Mal gerade ein knapper halber Tag.
Da wirst du als nächstes ein paar Serielleptint Anweisungen einbauen müssen um die die Zeitvariablen und Statuswerte  ansehen zu können.

Ich denke mal Bein Eintritt und Austritt in deine Funktionen wäre eine gute Stelle

Anscheinend rennt das Programm durch ohne das eine swich Case ausgeführt wird .

Heinz

Hayley_Hay

Anscheinend rennt das Programm durch ohne das eine swich Case ausgeführt wird .
Wie meinst Du das? Kannst Du das etwas erläutern? Meinst Du, ein Case wird übersprungen?

Rentner

Hallo,

na ja , Du schreibst das Program bleibt stehen, daraus folgere ich das nichts mehr passiert , nichts mehr geschaltet wird an der Maschine. Was mich etwas wunder ist jetzt allerdings das in dem Fall ja eigendlich der aktuelle Zustand erhalten bleiben müsste. D.h irgendwas läüft immer weiter ohne das es mit dem nächsten Schritt abgeschaltet wird. Das wäre ja schlimm- Das Ding läuft dann ohne jede Kontrolle vor sich hin.  Oder ist das gerade immer ein Zustand in dem eh alles ausgeschaltet ist. ? Also passiert das immer nur am Ende eines Maschinenzyklus oder auch mitten drin. ?

die angegeben 28000 oder 34000s entnimmst Du den in der Funktion schreiben mit ausgegebenen millis() nehme ich mal an. ??

Eigendlich ist es ja so wenn das Startdisplay angezeigt wird ist das Programm ja anscheinend aus dem "Programm modus der "Automatik"  rausgefallen, ?? ich blicke da aber auch nicht so ganz durch was Dein programm da so macht und wann anzeigt. 


Dann hab ich noch mal eine Frage zur Hardware. Ich hab gesehen das die Schalter positiv schaltend abgefragt werden. Wie sind die Schalter beschaltet. Welche Widerstände (Pull-down) sind da mit verschaltet. ? Ist das ganze halbwegs sicher ? , oder ist dein eigendliches Problem ehr die EMV ?


wie Du siehst Fragen über Fragen

Gruß Heinz





postmaster-ino

Hi

Hatte hier ebenfalls sporadische Hänger - bei mir wurde aber von einer CAN-Nachricht (maximal 8 Byte lang) die Länge ermittelt und diese Anzahl an Bytes in den vorhandenen Puffer geschrieben.
Blöd, wenn vom CAN-Modul eine 12 Byte lange Nachricht angeboten wird ... (so richtig gefunden habe ich den Fehler nicht wirklich, tendiere auf Spannungseinbrüche, ausgebessert habe ich im Programm durch Begrenzen der Nachrichtenlänge und Kondensatoren in der Spannungsversorgung - ca. 24h bis jetzt fehlerfrei)

MfG

Hayley_Hay

Hallo noch mal!

Das Programm läuft jetzt seit einigen Tagen durch, nachdem ich beim letzten case (air) noch ein break; hinzugefügt habe.
 
Dann hab ich noch mal eine Frage zur Hardware. Ich hab gesehen das die Schalter positiv schaltend abgefragt werden. Wie sind die Schalter beschaltet. Welche Widerstände (Pull-down) sind da mit verschaltet. ? Ist das ganze halbwegs sicher ? , oder ist dein eigendliches Problem ehr die EMV ?
Ja, das stimmt. Das hab ich ganz am Anfang so gemacht ohne Nachzudenken, und aus Bequemlichkeit habe ich es so gelassen. Probleme mit der EMV sind inzwischen nur noch minimal, der Bildschirm des angeschlossenen RasPi geht kurz aus wenn ein Relais schaltet.

Also, vielen Dank wieder mal bis hier her!

Go Up