Arduino Projektarbeit Strom Simulation

Moin Moin,
Im Zuge einer Projektarbeit um ein "Smarthome"-Puppenhaus zu erstellen,
wollte ich einen Stromzähler programmieren welcher einen Wert zwischen 4-6 Ampere pendeln lässt, um das ein bzw ausschalten von Geräten in diesen Raum zu simulieren. Dieser soll dann auf ein LCD dargestellt werden. Nun ist das Problem, dass ich 8 Räume Simulieren möchte und den Strom je nach zugeschalteten Räumen Addieren will um einen Gesamtstromwert auf dem LCD anzuzeigen. Jedoch bekomme ich bzw. weiß nicht wie ich den Stromwert simulieren kann.
Kann mir da jemand helfen? Grüße.

jedem Raum (Relais) einen "Stromwert" zuweisen und am Ende einfach jene zusammenzählen bei denen das Relais eingeschaltet ist (du kannst mit digitalRead auch abfragen ob ein OUTPUT ein oder aus ist).

stell mal rein was du hast, vieleicht erbarmt sich wer.

//GESAMTSTROMVERBRAUCH
int Raum1 = 2;
int Raum2 = 3;
int Raum3 = 4;
int Raum4 = 5;
int Raum5 = 6;
int Raum6 = 7;
int Raum7 = 8;
int Raum8 = 9;


void setup() {
 Serial.begin(9600);
 //-----------------------------------------
pinMode(2, INPUT); // Input des Status eines Raumes
pinMode(3,INPUT);  // Input des Status eines Raumes
pinMode(4,INPUT);  // Input des Status eines Raumes
pinMode(5,INPUT);  // Input des Status eines Raumes
pinMode(6,INPUT);  // Input des Status eines Raumes
pinMode(7,INPUT);  // Input des Status eines Raumes
pinMode(8,INPUT);  // Input des Status eines Raumes
pinMode(9,INPUT);  // Input des Status eines Raumes
float  Strom1 =0;
float  Strom2 =0;
float  Strom3 =0;
float  Strom4 =0;
float  Strom5 =0;
float  Strom6 =0;
float  Strom7 =0;
float  Strom8 =0;
float Gesamtstrom =Strom1+Strom2+Strom3+Strom4+Strom5+Strom6+Strom7+Strom8;
   Serial.print(Gesamtstrom);
   Serial.print("Ampere");
   delay(20);
//-----------------------------------------
}

void loop()

 {
   while (digitalRead(2)==1){
   float  Strom1 =5;
   delay(200);
   //-----------------------------------------
         Strom1 ++;
         delay(200);
    //-----------------------------------------
         Strom1 ++;
         delay(200);
    //-----------------------------------------
         Strom1--;
         delay(200);
    //-----------------------------------------
   delay(1000);
   }
    while (digitalRead(3)==1){
   float  Strom2 =6;
   delay(200);
   //-----------------------------------------
         Strom2 ++;
         delay(200);
    //-----------------------------------------
         Strom2 ++;
         delay(200);
    //-----------------------------------------
         Strom2--;
         delay(200);
    //-----------------------------------------
   delay(1000);
   }
    while (digitalRead(4)==1){
   float  Strom3 =4;
   delay(200);
   //-----------------------------------------
         Strom3 ++;
         delay(200);
    //-----------------------------------------
         Strom3 ++;
         delay(200);
    //-----------------------------------------
         Strom3--;
         delay(200);
    //-----------------------------------------
   delay(1000);
   }
    while (digitalRead(5)==1){
   float  Strom4 =4;
   delay(200);
   //-----------------------------------------
         Strom4 ++;
         delay(200);
    //-----------------------------------------
         Strom4 ++;
         delay(200);
    //-----------------------------------------
         Strom4--;
         delay(200);
    //-----------------------------------------
   delay(1000);
   }
    while (digitalRead(6)==1){
   float  Strom5 =3;
   delay(200);
   //-----------------------------------------
         Strom5 ++;
         delay(200);
    //-----------------------------------------
         Strom5 ++;
         delay(200);
    //-----------------------------------------
         Strom5--;
         delay(200);
    //-----------------------------------------
   delay(1000);
   }
    while (digitalRead(7)==1){
   float  Strom6 =4;
   delay(200);
   //-----------------------------------------
         Strom6 ++;
         delay(200);
    //-----------------------------------------
         Strom6 ++;
         delay(200);
    //-----------------------------------------
         Strom6--;
         delay(200);
    //-----------------------------------------
   delay(1000);
   }
   while (digitalRead(8)==1){
   float  Strom7 =4;
   delay(200);
   //-----------------------------------------
         Strom7 ++;
         delay(200);
    //-----------------------------------------
         Strom7 ++;
         delay(200);
    //-----------------------------------------
         Strom7 --;
         delay(200);
    //-----------------------------------------
   delay(1000);
   }
   while (digitalRead(9)==1){
   float  Strom8 =2;
   delay(200);
   //-----------------------------------------
         Strom8 ++;
         delay(200);
    //-----------------------------------------
         Strom8 ++;
         delay(200);
    //-----------------------------------------
         Strom8--;
         delay(200);
    //-----------------------------------------
   delay(1000);
   }   
}

Moin,
A) Was sind Codetags?
B) Genau
C) Die 200er sowie 1000er Delays sollten dazu dienen, dass der Wert des jeweiligen Stromwertes nicht all zu sprunghaft sich ändert. Bin leider noch nicht ganz vertraut programmiere erst an Arduinos seit dem Projekt.

Dein Sketch besteht zum größten Teil aus Wiederholungen. Du könntest es stark durch die Verwendung von Arrays vereinfachen. Statt Raum1…Raum8 hättest du das Array Raum[8]. Der Vorteil ist, dass du mit Zählschleifen darauf zugreifen kannst. i=4; Raum[i-1]; gibt den Wert des 4. Raums. Schaue dir auch for-Schleifen an.

https://www.arduino.cc/reference/en/language/variables/data-types/array/

https://www.arduino.cc/reference/en/language/structure/control-structure/for/

Die Delays wären ein weiterer kritischer Punkt, da sie den Kontroller blockieren und er in der Zeit nicht auf Schalterbewegungen reagieren kann. Ich denke, schaue dir aber erst mal die Arrays und For-Schleifen an.

Code-Tags:

...Sketch...

Schaltfläche oben </>

bitte lies How to use this forum - please read.

eckig klammer auf code eckige Klammer zu

Sketch reinkopieren

eckige Klammer auf /code eckige Klammer zu

ich würde erst mal das Gedöns weglassen und die prinzipielle Logik so machen:

//GESAMTSTROMVERBRAUCH
// kompilierbare Version 4 ;-/

const int Raum1 = 2;
const int Raum2 = 3;
const int Raum3 = 4;
const int Raum4 = 5;
const int Raum5 = 6;
const int Raum6 = 7;
const int Raum7 = 8;
const int Raum8 = 9;

  const float  Strom1 = 5;
  const float  Strom2 = 6;
  const float  Strom3 = 4;
  const float  Strom4 = 4;
  const float  Strom5 = 3;
  const  float  Strom6 = 4;
  const  float  Strom7 = 4;
  const  float  Strom8 = 2;

  float Gesamtstrom = 0;

void setup() {
  Serial.begin(9600);
  //-----------------------------------------
  pinMode(Raum1, INPUT); // Input des Status eines Raumes
  pinMode(Raum2, INPUT); // Input des Status eines Raumes
  pinMode(Raum3, INPUT); // Input des Status eines Raumes
  pinMode(Raum4, INPUT); // Input des Status eines Raumes
  pinMode(Raum5, INPUT); // Input des Status eines Raumes
  pinMode(Raum6, INPUT); // Input des Status eines Raumes
  pinMode(Raum7, INPUT); // Input des Status eines Raumes
  pinMode(Raum8, INPUT); // Input des Status eines Raumes

  Serial.print(F("Arbeit/Energie"));
  delay(20);
  //-----------------------------------------
}

void loop()
{

  if (digitalRead(Raum1)) {Gesamtstrom += Strom1;}
  if (digitalRead(Raum2)) {Gesamtstrom += Strom2;}
  if (digitalRead(Raum3)) {Gesamtstrom += Strom3;}
  if (digitalRead(Raum4)) {Gesamtstrom += Strom4;}
  if (digitalRead(Raum5)) {Gesamtstrom += Strom5;}  
  if (digitalRead(Raum6)) {Gesamtstrom += Strom6;}
  if (digitalRead(Raum7)) {Gesamtstrom += Strom7;}

  Serial.print (Gesamtstrom);
}

wenn man eine Zeitkompenente will, wirds bei 8 Kanälen umfangreich, da würde ich dann in objektorientierter Programmierung weitermachen.

wollte ich einen Stromzähler programmieren welcher einen Wert zwischen 4-6 Ampere

Das ist ein Widerspruch.
Stromzähler messen in Wh oder kWh, von mir aus auch noch in Ah, aber nicht nicht in nackten Ampere
Da solltest du dir schon, mit dir selber, einig werden.

Dein Skript beinhaltet viele durch gezählte Dinge...
Es ist immer unglücklich, Bezeichner durchzunummerieren.

Es bieten sich Arrays an.
Oder, wenn man härter drauf ist, auch Listen/Bäume

MFriedrichsen:
einen Wert zwischen 4-6 Ampere pendeln lassen , um das ein bzw ausschalten von Geräten in diesen Raum zu simulieren. Dieser soll dann auf ein LCD dargestellt werden. Nun ist das Problem, dass ich 8 Räume Simulieren möchte und den Strom je nach zugeschalteten Räumen Addieren will um einen Gesamtstromwert auf dem LCD anzuzeigen.

Von einer "Stromzähler" - Funktion (also dem zeitlichen Integral in der Einheit Ah oder kWh) kann ich in der Aufgabenbeschreibung nichts erkennen.

Für zufällige Änderungen bietet sich die random Funktion an. (Achtung: ganzzahlige Parameter und Ergebnisse)

Wenn Du dir Werte simulieren willst gibts dazu die dollsten Möglichkeiten, hängt von Deiner Phantasie ab, man kann auch so dreiecks Kurven bilden wie du das gemacht hast.

Grundwert +Zufallswert
Gurundwert+Sinuswert bei dem Sinus kann man dann die Amplitude und Frequenz zufällig ändern und / oder in bestimmten Zeitabständen. Damit ergeben sich zufällige Kurven die sich nicht plötzlich ändern.

Wenn Du anschliessend die Summe bilden willst gehhört das ins Loop, was soll das im Setup. Ansonsten wurde ja bereits darauf hingewiesen das delay denkbar schlecht für die Anwendung ist.

noiasca:
wenn man eine Zeitkompenente will, wirds bei 8 Kanälen umfangreich, da würde ich dann in objektorientierter Programmierung weitermachen.

Lustige Idee, das in OOP zu machen, aber mein Entprellansatz, basierend auf combies Vorschlag, läßt sich dazu umbauen:

// Quelle der Bibliothek: https://github.com/duinoWitchery/hd44780
#include <Wire.h>
#include <hd44780.h> // include hd44780 library header file
#include <hd44780ioClass/hd44780_I2Cexp.h> // i/o expander/backpack class
hd44780_I2Cexp lcd; // auto detect backpack and pin mappings

#define LCD_COLS 20
#define LCD_ROWS 4

const unsigned long debounceDelay = 50, messIntervall = 1000;
unsigned long jetzt;                     // Variable für den aktuellen Zeitpunkt
unsigned long messMillis;
float verbrauch;
uint16_t gesamtleistung, vorherGesamtleistung;

struct Verbraucher {                          // Struktur mit Konstanten, Variablen und Methoden
  Verbraucher(const byte pin, const uint16_t leistung): pin(pin), leistung(leistung), aktZustand(0), altZustand(0), vorhin(0) {}

  void init()
  {
    pinMode(pin, INPUT_PULLUP);
    aktZustand = !digitalRead(pin);
    altZustand = aktZustand;
  }
  void run()
  {
    aktualisieren();                        // Verbraucherzustände aktualisieren
    if (zustand())                          // Verbraucher aktiv
    {
      gesamtleistung += leistung;
    }
  }

  void aktualisieren()
  {
    altZustand = aktZustand;
    if (jetzt - vorhin >= debounceDelay)    // Entprellen
    {
      aktZustand = !digitalRead(pin);
      if (altZustand != aktZustand)
      {
        vorhin = jetzt;
      }
    }
  }
  /* nicht benutzt
    bool steigend()                           // steigende Signalflanke
    {
      if (!altZustand && aktZustand)
      {
        return true;
      }
      return false;
    }
  */
  bool zustand()
  {
    return aktZustand;
  }
  /* nicht benutzt
    bool fallend()
    {
      if (altZustand && !aktZustand)
      {
        return true;
      }
      return false;
    }
  */
  const byte pin;
  const uint16_t leistung;
  bool aktZustand;
  bool altZustand;
  unsigned long vorhin;
};

Verbraucher verbraucher[] {
  // Arduino-Pin, Leistung in Watt
  {2, 7},
  {3, 9},
  {4, 15},
  {5, 15},
  {6, 9},
  {7, 7},
  {8, 3840}  // maximal mögliche Leistung bei 16 A pro Verbraucher
};

void setup() {
  lcd.begin(LCD_COLS, LCD_ROWS);
  lcd.print("Smarthome-Puppenhaus");
    lcd.setCursor (0, 1);
    lcd.print("Leistung: ");
    lcd.setCursor (0, 2);
    lcd.print("   Strom: ");
    lcd.setCursor (0, 3);
    lcd.print(" Energie: ");
  for (Verbraucher &v : verbraucher) v.init();
}

void loop() {
  jetzt = millis();
  vorherGesamtleistung = gesamtleistung;
  gesamtleistung = 0;
  for (Verbraucher &v : verbraucher) v.run();
  if (jetzt - messMillis >= messIntervall)
  {
    messMillis = jetzt;
    verbrauch += gesamtleistung / 3600.0;  // 3600 Messungen pro Stunde
    lcd.setCursor (10, 3);
    lcd.print("          ");
    lcd.setCursor (10, 3);
    if (verbrauch < 1000)
    {
      lcd.print(verbrauch, 3);
      lcd.print(" Wh");
    } else {
      lcd.print(verbrauch / 1000, 2);
      lcd.print(" kWh");
    }
  }
  if (vorherGesamtleistung != gesamtleistung)
  {
    lcd.setCursor (10, 1);
    lcd.print("          ");
    lcd.setCursor (10, 1);
    lcd.print(gesamtleistung);
    lcd.print(" W");
    lcd.setCursor (10, 2);
    lcd.print("          ");
    lcd.setCursor (10, 2);
    lcd.print(gesamtleistung / 240.0, 3);
    lcd.print(" A");
  }
}

Da könntest Du eine Zeitkomponente einbauen, wobei ein LED-Leuchtmittel eher uninteressant sein dürfte. Aber ich stelle mir eine Waschmaschine vor, wo der Motor in Intervallen dreht, manchmal die Heizung dazukommt, dann der Schleudergang aktiv wird.

Hi

So ein Pumpenhaus hatte ich auch mal in den Händen (zum restaurieren (2014) Baujahr ca. 1980).
Der Besucher könnte sich beliebige Geräte einschalten und bekam die Summe
der aktuellen Energiemenge in einem 7 Segment Display angezeigt.

Nach einer Wartezeit wurden alle aktiven Geräte automatisch wieder gelöscht.
Mit der Anwahl der Räume wurde ein Relais aktiviert um die jeweilige Szene zu beleuchten (nun mit LED)
die Relaiskontakte werden dann in der SW abgefragt und der Momentanwert berechnet.

Vielleicht ist es eine Anregung für dich

// Darstellung Summenverbrauch Schaukasten
// 10 Eingänge und Ausgabe Summe an 7 Segment
// Ansteuerung Szenelampen über Koppelrelais
// Arduino Franzis Verlag = Duemilanov

// Pin 0, 1 reserviert für serielle Schnittstelle - darf kein Eingang sein solange serial Monitor verwendet wird
// Pin 10, 11, 12, reserviert für SPI - darf kein Eingang sein
// Pin 13 reserviert für Kontroll LED on Board
// Pull down Widerstände nicht vergessen

#include "LedControl.h"  // Bibliothek für MAX7219 einbinden

// Festlegung I/O Pinzuordnung
const int Lampe = 2;    // Szene Stehlampe
const int Buegel = 3;   // Szene Bügeleisen
const int Staub = 4;    // Szene Staubsauger
const int Herd = 5;     // Szene Elektroherd
const int Wasch = 6;    // Szene Waschmaschine
const int Kuehl = 7;    // Szene Kühlschrank
const int Wasser = 8;   // Szene Warmwasserspeicher
const int Ferns = 9;    // Szene Fernseher
const int Kontroll = 13;    // Kontroll LED für Testzwecke - nicht verwendet

LedControl lc=LedControl(10,11,12,1); // Pin 10 to Data In, 11 to Clk, 12 to LOAD Anzahl Module = 1
// Pin 10 Data In = Draht gelb MAX 7219 Pin 1
// Pin 11 Clock In = Draht weiß MAX 7219 Pin 13
// Pin 12 Load = Draht grün MAX 7219 Pin 12
// rot + grau = +5V
// blau + schwarz = Masse

// Eingänge Hardware abfragen
int LampeState = 0;         // Status Eingang abfragen
int BuegelState = 0;         // Status Eingang abfragen
int StaubState = 0;         // Status Eingang abfragen
int HerdState = 0;         // Status Eingang abfragen
int WaschState = 0;         // Status Eingang abfragen
int KuehlState = 0;         // Status Eingang abfragen
int WasserState = 0;         // Status Eingang abfragen
int FernsState = 0;         // Status Eingang abfragen
int TiefkState = 0;         // Status Eingang abfragen
int SpuelState = 0;         // Status Eingang abfragen
int Tiefk = A0;             // kein Pin mehr frei muss über Analogeingang gemacht werden 
                            // Pull down R 10kOhm an A0 nicht vergessen
int Spuel = A1;              // kein Pin mehr frei muss über Analogeingang gemacht werden
                            // Pull down R 10kOhm an A1 nicht vergessen

// Variblen für 7 Segment Anzeige

int Einer = 0;              // Digit 0 am MAX7219 = Pin 2
int Zehner = 0;             // Digit 1 am MAX7219 = Pin 11
int Hundert = 0;            // Digit 2 am MAX7219 = Pin 11  Tausenderstelle braucht keiner
long Wartezeit = 0;         // für externen Hardwarereset
int Wertalt = 0;            // vor neuer Abfrage Wert retten

                            
                            
// Variablen für Zuweisung Verbrauchswert

int WertLampe =  0;  //Monatsverbrauch Fenster Lampe 27kWh
int WertBuegel =  0;  //Monatsverbrauch Fenster Bügeleisen 9kWh
int WertStaub =  0;  //Monatsverbrauch Fenster Staubsauger 15kWh
int WertHerd =  0;  //Monatsverbrauch Fenster Herd 120kWh
int WertWasch =  0;  //Monatsverbrauch Fenster Waschmaschine ??kWh
int WertKuehl =  0;  //Monatsverbrauch Fenster Kühlschrank 18kWh
int WertWasser =  0;  //Monatsverbrauch Fenster Warmwasserspeicher 150kWh
int WertFerns =  0;  //Monatsverbrauch Fenster Fernseher 30kWh
int WertTiefk =  0;  //Monatsverbrauch Fenster Kühltruhe 45kWh
int WertSpuel =  0;  //Monatsverbrauch Fenster Geschirrspueler 90kWh

int WertAlle = 0;  //Monatsverbrauch aller aktiven Fenster 

void setup() {
   // initialize the pushbutton pin as an input:
  pinMode(Lampe, INPUT); 
  pinMode(Buegel, INPUT);
  pinMode(Staub, INPUT);
  pinMode(Herd, INPUT);
  pinMode(Wasch, INPUT);
  pinMode(Kuehl, INPUT);
  pinMode(Wasser, INPUT);
  pinMode(Ferns, INPUT);
  // pinMode(Tiefk, INPUT); muss dann über Analog gemacht werden
  // pinMode(Spuel, INPUT); muss dann über Analog gemacht werden
   
  // initialize serial communication at 9600 bits per second:
  Serial.begin(9600); // - nur bei der Inbetriebnahme für Monitor nötig
  // initialize MAX7219
  lc.shutdown(0,false);  // Display freigeben
  lc.setIntensity(0,10);  // 0 min, 15 max
  lc.clearDisplay(0);  // Display Register zurücksetzten
  
  // automatischer Reset Board - Watchdog
  // Analog A2 wird als binär Ausgang verwendet
  
  pinMode(A2, OUTPUT);    // kein Binaerausgang mehr frei für Hardwarereset
  
}

void loop(){
  
  Wertalt = WertAlle;    // Wert retten
  
  // read the state of the pushbutton value:
  LampeState = digitalRead(Lampe);
  BuegelState = digitalRead(Buegel);
  StaubState = digitalRead(Staub);
  HerdState = digitalRead(Herd);
  WaschState = digitalRead(Wasch);
  KuehlState = digitalRead(Kuehl);
  WasserState = digitalRead(Wasser);
  FernsState = digitalRead(Ferns);
  TiefkState = analogRead(Tiefk);      // anlog Eingang weil kein Pin mehr frei 0-1023 Digits
  SpuelState = analogRead(Spuel);      // anlog Eingang weil kein Pin mehr frei 0-1023 Digits
  
  // check if the pushbutton is pressed.
  // if it is, the buttonState is HIGH:
  if (LampeState == HIGH) {     
    WertLampe = 27;
      } 
  else {
    WertLampe = 0;
      }
  
  if (BuegelState == HIGH) {     
    WertBuegel = 9;
  } 
  else {
    WertBuegel = 0;
  }
   
  if (StaubState == HIGH) {     
    WertStaub = 15;
  } 
  else {
    WertStaub = 0;
  } 
  
  if (HerdState == HIGH) {     
    WertHerd = 120;
  } 
  else {
    WertHerd = 0;
  }
  
  if (WaschState == HIGH) {     
    WertWasch = 45;     
  } 
  else {
    WertWasch = 0;
  }
  
  if (KuehlState == HIGH) {     
    WertKuehl = 18;
  } 
  else {
    WertKuehl = 0;
  }
  
  if (WasserState == HIGH) {     
    WertWasser = 150;
  } 
  else {
    WertWasser = 0;
  }
  
  if (FernsState == HIGH) {     
    WertFerns = 30;
  } 
  else {
    WertFerns = 0;
  }
  // die letzten 2 sind die Analogeingänge
  // alles über 2,5Volt gilt als ein
  
  if (TiefkState > 500) {     
    WertTiefk = 45;    
  } 
  else {
    WertTiefk = 0;
  }
  
  if (SpuelState > 500) {     
    WertSpuel = 90;      
  } 
  else {
    WertSpuel = 0;
  }
  WertAlle = WertLampe + WertBuegel + WertStaub + WertHerd + WertWasch + WertKuehl + WertWasser + WertFerns + WertTiefk +  WertSpuel;
 Serial.println("WertAlle...");
 Serial.println(WertAlle);
 
  
  Einer = WertAlle%10;          //WertAlle zerlegen
  Zehner = (WertAlle/10)%10;    //WertAlle zerlegen
  Hundert = (WertAlle/100)%10;  //WertAlle zerlegen
  
  lc.setDigit(0,0,Einer,false);      // Stelle 0 ganz rechts
  lc.setDigit(0,1,Zehner,false);
  lc.setDigit(0,2,Hundert,false);
  
   
  delay (200); // wichtig für Zeitberechnung Reset
   
   if (WertAlle == Wertalt) {     
    Serial.println("keine Aenderung....");
    Wartezeit = Wartezeit + 1;      // wenn keine Änderung 0,2 Sekundenschritte zaehlen
    Serial.println(".......Wartezeit");
    Serial.println(Wartezeit);
  } 
  else {
    Serial.println("da wurde was gedrueckt");
    Wartezeit = 0;      // Wartezeit löschen weil wer aktiv ist
    Serial.println(".......Wartezeit");
    Serial.println(Wartezeit);
  }
  
  if (Wartezeit > 18000) {     // Wartezeit ist xx mal 0,2 sec 1 Stunde = 3600 Sekunden = 18000 Wartezeit Variabe Type long !
    digitalWrite (A2, HIGH);      // externes Resetrelais auslösen
  } 
  else {                    // Arduino startet sowieso neu
      }
  
}

Mit Werte pendeln kann ich nicht dienen, alles statisch.