Skip to content

simonrettmann/Projektseite

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 

Repository files navigation

Der arduinogesteuerte Gaskocher - Projektseite

Ein Projekt von David Borgmann und Simon Rettmann

Stormarnschule Ahrensburg
Informatik, Bl
Schuljahr 2021/22, 1. Halbjahr


Animation



Navigation

1. Grundlagen

2. Das Projekt

3. Reflexion


Für dieses Halbjahresprojekt im Rahmen des Informatikunterricht schlossen sich David Borgmann und Simon Rettmann zu einem Team zusammen. Als gute Freunde bildeten sie ein gut funktionierendes Team aus Entwicklern, die das Projekt unbedingt nach vorne bringen wollten. Beide besaßen aufgrund einer Teilnahme am Enrichement-Kurs "Das Programmieren von Microcontrollern" schon ein paar Arduinovorkenntnisse. Beigeistert ist die Gruppe vor allem von Physical Computing Projekten, weil es ermöglicht, Hardware und Software zu vereinen. Somit kann im Kopf und Computer etwas gesteuert und erschaffen werden, was in der realen Welt tatsächlich funktioniert. Diese Art von Projekten fasziniert die beiden. Bei dem arduinogesteuertem Gaskocher handelt es sich um ein Physical Computing Projekt. Das bedeutet, dass Anwendungen der Informatik in Wechselwirkung mit der Umwelt stehen. Dazu ist sowohl Hardware, welche mit der physischen Umwelt im Kontakt steht, als auch Software, welche die Hardware interaktiv mit „Leben“ füllt, nötig. Arduino bietet bei diesem Projekt die Plattform, welche die Umsetztung des Projektes ermöglicht. Arduino ist eine aus Soft- und Hardware bestehende open-source Physical Computing-Plattform. Das Herzstück der Hardware ist dabei der Micro-Controller, in diesem Fall der Arduino UNO R3. Bei dem UNO handelt es sich um das Standard-Modell des Repertoires. Dieser ist günstig und für viele Projekte im Bezug auf Rechenleistung, Speicher und Anschlussmöglichkeiten völlig ausreichend. Programmiert wird der Microcontroller mithilfe der integrierten Entwicklungsumgebung. Es handelt sich um eine plattformübergreifende Anwendung. Die Programmiersprache beinhaltet Elemente aus C, C++ und AVR-Assembler und der Code lässt sich von einem Computer mithilfe eines USB-Anschlusses auf den UNO übertragen. Zur präzisen Umsetzung und ansprechenden Dokumentation wurde eine Vielzahl von verschiedenen Programmen benutzt und dessen Handhabung erlernt.
  • Arduino IDE
  • Der Arduino stellt das Herzstück des Projektes dar. In der Entwicklungsoberfläche wurde das Programm geschrieben und auf den Arduino Uno gespielt.
    Entwicklungsoberfläche von Arduino Entwicklungsoberfläche - Website von Arduino
  • GitHub
  • GitHub ist eine Software zur Versionsverwaltung von Software. Für dieses Projekt wurde GitHub für die Dokumentation genutzt, um Stundenprotokolle, eine Art Tagebuch für jede Stunde, und eine Projektseite, eine Zusammenfassung des Halbjahresprojektes, zu erstellen.
    Oberfläche von GitHub GitHub - Website von GitHub
  • fritzing
  • Fritzing wurde genutzt, um die für die Hardware erforderlichen Steckverbindungen und eingesetzten Geräte, zu digitalisieren.
    Oberfläche von fritzing fritzing - Website von fritzing
  • TinkerCAD
  • TinkerCAD ist eine Software, mit der 3-D Objekte modelliert werden können. Für das Projekt war es wichtig, eine Steckverbindung zwischen Gaskocher und Schrittmotor herzustellen. Ein dementsprechendes 3-D Modell wurde erstellt und als .stl Datei exportiert.
    Oberfläche von TinkerCAD Obefläche von TinkerCAD - Oberfläche von TinkerCAD
  • Cura
  • Die mit TinkerCAD erstellte .stl Datei kann mit Hilfe der Software Cura in einen .gcode umgewandelt werden. Dieser Dateityp ist mit 3-D Druckern kompatibel. So wurde das auf TinkerCAD erstellte Modell - nach Anpassung der Druckeinstellungen - gedruckt.
    Oberfläche von Cura Oberfläche von Cura - Website von Cura
Damit diese Vielzahl von Programmen auch sinnvoll eingesetzt werden konnte, begann die Gruppe immer zuerst mit der Einarbeitung in das jeweilige Programm. Dafür wurden unterschiedliche Quellen und Arten genutzt. Als besonders hilfreich haben sich YouTube-Tutorials für eine grobe Übersicht und Foreneintrage für die Beantwortung konkreter Fragen herausgestellt. Hierbei waren die am meisten verwendeten Quellen:

Die Entwickler des Projektes, David und Simon, sind begeisterte Outdoor-Fans. Beispiele sind eine Woche "Wildcampen" in Schweden während der Sommerferien und eine Studienfahrt, in der eine Woche auf der Mecklenburger-Seenplatte Kanu gefahren wurde. Neben der Natur begeistert allerdings auch das Kochen die beiden. Bei der Nahrungszubereitung gab es bei diesen beiden Urlauben Probleme: Mal ist der Gaskocher zu heiß - der Reis angebrannt, mal das Wasser zu kalt - die Nudeln werden einfach nicht gar. Als in der Einführung zum Informatikunterricht die Möglichkeit eines "Physical-Computing"-Projekts genannt wurde und zuerst einige Ideen diskutiert wurden, entschieden sich die beiden schnell für einen aurdionogesteuerten Gaskocher. Die Idee für das Projekt war geboren. Ziel war es, einen Gaskocher so steuern zu können, dass eine vorher eingestellte Temperatur erreicht und selbstständig gehalten werden kann.

Die Erfindung zielt insofern in eine Marktlücke, als es diese Art und Weise des Kochens noch nicht gibt. Beim Backofen stellt man eine bestimmte Temperatur ein, die erreicht werden soll. Der Backofen gibt ein Feedback, sobald die vorher eingestellte Temperatur erreicht ist. Beim Kochen auf Herdplatten gibt es diese Einstellung hingegen noch nicht. Herdplatten werden in verschiedenen Stufen mit unterschiedlicher Leistung eingestellt. Welche Temperatur die Herdplatte oder der zubereitete Topfinhalt gerade hat, kann nicht transparent für den Benutzer eingesehen werden. Lediglich durch das Verhalten des jeweiligen Inhalts kann eine Schätzung der Temperatur vorgenommen werden. so ist es natürlich bekannt, dass Wasser bei 100 °C zu sieden beginnt. Ob der Inhalt jedoch 70 oder 80 bzw. 110 oder 120 °C hat, kann nicht unterschieden werden. Bei einem Gaskocher, insbesondere einem Campinggaskocher, wird dieses Problem weiter verstärkt. Die Einstellung des Gasflusses geschieht stufenlos. Der Benutzer kann so nur aufgrund der Größe der Gasflamme beurteilen, ob der Topf bald heißer oder kälter sein wird. Da die Temperatur beim Backen von Kuchen und Keksen von einer größerer Bedeutung als beim Kochen ist, gab es in dieser Branche bereits einen Wechsel hin zu temperaturregulierten Öfen. Beim Kochen fehlt diese Veränderung, obwohl es auch dort für den Benutzer deutlich transparenter wäre und einige Gerichte eine präzise Einstellung erfordern. Beispiele für Gerichte, bei denen es auf eine genaue Temperierung ankommt, sind die Herstellung von Karamell, das Schmelzen von Schokolade oder das Sous vide garen von Steaks. Daher kannn man dieses Informatikprojekt als einen ersten Schritt in die Richtung einer "Revolution des Kochens" bezeichnen, mit der dem Benutzer ein besseres Kocherlebnis geboten werden soll.

Der Entwicklungsprozess startete am 3.8.2021, der ersten Informatikstunde mit einer Brainstormingphase und dem Aufgreifen der Idee des arduinogesteuerten Gaskochers. Es folgte ein viermonatiger Entwicklungsprozess, in dem eine Software geschrieben wurde, die ein Thermometer auslesen kann, einen über ein rotary encoder eingestellten Wert mit dem gemessenen Wert ins Verhältnis setzt und auf dieser Grundlage einen Schrittmotor anspricht. Außerdem wurde die Hardware so entwickelt, dass ein Gaskocher an eine Gasflasche angeschlossen wird und ein Schrittmotor über eine Halterung an das Ventil der Gasflasche montiert ist und dieses öffnen kann. Ein Topf wurde so präpariert, dass ein Thermometer, wasserdicht verpackt, durch ein Loch im Deckel mit dem Wasser in Berührung kommt und die Temperatur misst.
Um den zeitlichen Ablauf des Entwicklungsprozesses graphisch anschaulich und transparent darzustellen, wurde eine Zeitleiste erstellt.

zeitlicher Ablauf des Entwicklungsprozesses zeitlicher Ablauf
Die Aufgabe der Software ist es, unter Berücksichtigung der eingestellten Zieltemperatur die gemessene Temperatur in einen Öffnungsgrad des Ventils zu übertragen. Dazu werden verschiedene Werte erhoben, welche tatsächlich durch die physische Umwelt oder den Benutzer des Produktes verändert werden:
  • Die Zieltemperatur wird durch den rotary encoder definiert. Dabei handelt es sich um eine Integer-Variable (int) mit dem Namen „eingestellteTemp“. Gespeichert werden die ganzzahligen Werte vom encoder als Temperatur in °C. Zur Programmierung des rotary encoders ist eine spezielle Art der Programmierung nötig, welche eine Besonderheit des Programms darstellt. Die Problematik ist, dass der rotary encoder selbst nicht speichert, in welcher Position er sich befindet oder welcher Wert äquivalent zu der momentanen Stellung ist. Es werden lediglich Stromimpulse bei jedem Schritt abgegeben. Doch können die Signale im Loop-Abschnitt des Programms nur dann ausgelesen werden, wenn ein entsprechender Abschnitt zur Zeit der Signalübertragung durchgeführt wird. Wird gerade ein anderer Befehl, wie z.B. ein „delay“, ausgeführt, kann der Stromimpuls nicht verarbeitet werden. Um einen präzise funktionierenden encoder zu programmieren, ist es nötig, dass alle gesendeten Daten vom Programm bearbeitet werden. Gelöst wurde diese Herausforderung mit einer Interrupt-Routine. Es handelt es sich um einen gesonderten Programmteil, welcher durch einen festgelegten Auslöser jederzeit gestartet und durchgeführt werden kann. Nach der Unterbrechung wird die Hauptschleife an der Stelle der Unterbrechungen fortgesetzt. Bei der Programmierung konnte sich die Bauweise des rotary encoders zu Nutze gemacht werden. Bei jedem Schritt liegt für einen kurzen Abschnitt keine Spannung am Clock-Pin des Encoders an. Sobald also der Zustand „LOW” am PinA anliegt, wird um einen Schritt gedreht. Dies wird als Auslöser der ISR (= Interrupt-Service-Routine) festgelegt. Je nach der Drehrichtung folgt nun entweder ein „LOW” Signal des Datenpins (PinB) oder es wird kein weiterer Impuls übermittelt. Das Programm überprüft diese Bedingungen. Somit kann ermittelt werden, ob die „eingestellteTemp“ um den Schrittwert „rotarySchrittwert“ erhöht oder verringert werden soll. Die größte Herausforderung war es, „bouncing“ in den Griff zu bekommen. Fehlerhafte Signale, die durch unsaubere Kontaktschließung bei der Hardware entstehen, sorgen beim rotary encoder für den Anschein, dass der Encoder um bis zu mehrere hundert Schritte gedreht wurde. Die Lösung dieses Problems hat der Gruppe einige kurze Nächte beschert. Verhindern ließ sich dieses Phänomen schlussendlich, indem der Zeitabstand zwischen den Signalen überprüft wird. Sind seit dem vorherigen Signal weniger als 5ms vergangen, handelt es sich um einen „Bounce“. Das Signal wird folglich ignoriert.
Ausschnitt des Codes
//erster wichtiger Codeausschnitt
void setup() {
  attachInterrupt(digitalPinToInterrupt(PinA), isr, LOW);  //die Interupt-Routine "ISR" wird dann ausgelöst, wenn der PinA = LOW ist
}

void isr ()  {
  static unsigned long lastInterruptTime = 0;
  unsigned long interruptTime = millis();          //es wird gespeichert, zu welchem Zeitpunkt der Interrupt kommt

  
  if (interruptTime - lastInterruptTime > 5) {     //wenn der Interupt schneller als 5 ms nach dem vorherigen Interrupt kommt, wird dieser ignoriert. Dadurch wird "Bouncing" verhindert.
    if (digitalRead(PinB) == LOW)
    {
      eingestellteTemp-= rotarySchrittwert ;       //wenn nach PinA= LOW PinB=Low folgt, soll die eingestellte Temperatur um den Schrittwert vergrößert werden 
    }
    else {
      eingestellteTemp+= rotarySchrittwert ;       //anderenfalls soll die eingestellte Temperatur um den Schrittwert zunehmen

    eingestellteTemp = min(300, max(0, eingestellteTemp));    //die Temperatur, welche eingestellt werden kann, ist zwischen 0° und 300° begrenzt 


  }
  lastInterruptTime = interruptTime;                          //der Zeitpunkt des aktuellen Interrupts wird als Zeitpunkt des vergangenen Interruptes deffiniert
} 
  • Der Schrittwert „rotarySchrittwert“ kann zwei Zustände annehmen. Wenn der encoder gedrückt wird, also „HIGH“ am „PinSW“ anliegt, dann ist der Schrittwert als 1 °C pro Schritt definiert, anderenfalls beträgt der Schrittwert 5 °C pro Schritt. So kann der Benutzer zwischen einer schnelleren oder präziseren Eingabe der Zieltemperatur wechseln und dies flexibel an seine Bedürfnisse anpassen, je nachdem ob der rotary encoder eingedrückt oder lediglich gedreht wird.
Auschnitt des Codes
int rotarySchrittwert = 5; 

void loop() {
  if ((!digitalRead(PinSW))) {        //wenn der Knopf des Encoders gedrückt wird (Strom am PinSW anliegt), ist der Schrittwert = 1
    rotarySchrittwert = 1;
  }
  else{                               //andernfalls beträgt der Schrittwert = 5
    rotarySchrittwert = 5;
  }
}
  • Die gemessene Temperatur des Thermoelements wird „tatTemp“ genannt. Es handelt sich um eine „Float“-Variable, welche die Temperatur auf zwei Nachkommastellen genau speichert. Es wird etwa zwei- bis dreimal pro Sekunde, zu Beginn jeder Loop, gemessen, wie die aktuelle Temperatur in °C innerhalb des Topfes ist. Die Programmierung funktioniert über eine library, welche speziell für das Driverboard des Elements programmiert wurde.

Diese Parameter alleine reichen aber nicht aus, um den Kocher zu betreiben. Es müssen Konstanten sowie Rechenvariablen bekannt sein:

  • Die „tempDifferenz“ stellt als "Float"-Varibale die Differenz zwischen der gemessenen Temperatur und der eingestellten Temperatur dar.
  • Die spezifischen Parameter des Schrittmotors und die Eigenschaft des Ventils sind nötig, um zu errechnen, wie viele Schritte der Motor machen muss, um das Ventil um 1% zu öffnen.
Grundsätzlich werden Variablen und Konstanten vor dem Setup-Teil des Programms definiert. So werden als erstes die benötigten Bibliotheken eingebunden und dann die Pins für den Schrittmotor, den rotary encoder, das I2C-LCD und das Thermoelement festgelegt. Die Zuweisung der Pins erleichtert später den Überblick. Auch die vorher erwähnten Konstanten und Variablen werden definiert. Anschließend müssen sowohl der Schrittmotor und das LCD, als auch das Thermomodul als Objekte initialisiert werden. Folglich kann nun mit den jeweiligen Bibliotheken gearbeitet werden, in welche die Parameter der spezifischen Objekte eingespeist wurden.
Der Setup-Teil des Programms wird nur einmal ausgeführt. In diesem Teil wird als erstes die serielle Kommunikation gestartet. Der Arduino kann mit dem Computer seriell kommunizieren, um Daten auszutauschen. In unserem Fall dient der serielle Monitor des Computers später als Kontrollbildschirm. Außerdem wird das LC-Display gestartet und die Arbeitseinstellung des Schrittmotors definiert. Die ISR wird im Setup dem oben beschriebenen Auslöser zugeordnet. Sobald das Setup erfolgreich ausgeführt wurde, übermittelt der Arduino das Signal „Start“, welches nun im seriellen Monitor erscheint.
Der sich endlos wiederholende Loop des Programms beginnt mit der Auslesung des Thermoelements. Der gemessene Wert wird in die Variable „tatTemp“ überführt. Es folgt eine serielle Übermittlung aller interessanten Variablen an den seriellen Monitor. Nun erfüllt der Kontrollmonitor seine Funktion. Damit auch bei dem Endprodukt überprüft werden kann, wie die gemessene oder eingestellte Temperatur des Kochers ist, werden diese beiden Werte im nächsten Teil über das LC-Display ausgegeben. Eine Schwierigkeit war zunächst, dass die mit jedem Loop neu hinzugefügten Schriftzeichen die alten Zeichen überschrieben haben, ohne diese gänzlich zu entfernen. Deshalb müssen vor jeder Änderung der Anzeige zunächst alle Zeichen für ein Frame entfernt werden, bevor die neuen Zeichen auf dem LCD erscheinen. Der Nebeneffekt dieser Darstellung ist jedoch ein für den Benutzer wahrnehmbares Flackern des Displays.
Ausschnitt des Codes
	
void loop() {
    float tatTemp = thermo.readCelsius();               //das Thermomenter wird ausgelesen und der Wert als Variable überführt
         delay(300);
  
 Serial.print("Eingestellte Temperatur: ");          
  Serial.println(eingestellteTemp);
         Serial.println(" ");
         
  Serial.print("Gemessene Temperatur in C: ");
  Serial.println(tatTemp);
         Serial.println(" ");
         
  Serial.print("Temperaturdifferenz:");
  Serial.println(tempDifferenz);
         Serial.println(" ");
         
  Serial.print("Ventilöffnung in Prozent: ");
  Serial.println(pVentil);
         Serial.println(" ");

  Serial.println("------------------------------------");  //dient der Übersicht im seriellen Monitor

  lcd.clear();                         //leert das LCD, damit neue und alte Werte sich nicht überlagern
  lcd.setCursor(0, 0);                 //das LCD soll die gemessene Temperatur und die eingestellte Temperatur darstellen: 
  lcd.print("ein.Temp: ");
    lcd.print(eingestellteTemp);
    lcd.setCursor(15, 0);
    lcd.print("C");
  lcd.setCursor(0, 1);
  lcd.print("akt.Temp: ");
    lcd.print(tatTemp);
    lcd.setCursor(15, 1);
    lcd.print("C");

}
	

Nach der Aktualisierung der verschiedenen Anzeigen wird mit dem Herzstück des Codes fortgefahren. In dem Abschnitt findet die Verrechnung der eingestellten Parameter statt. Dazu wird die Temperaturdifferenz „tempDifferenz“ gebildet. Die nötige Position des Steppers setzt sich aus der nötigen Öffnung des Ventils in Prozent, multipliziert mit der Schrittanzahl, welche für 1% Öffnung nötig ist, zusammen. Daraus folgt eine Position in Schritten, welche später von dem Schrittmotor angefahren wird.

Nun wird mit einer mathematischen Funktion ermittelt, wie groß die Öffnung des Ventils in % entsprechend der Temperaturdifferenz sein muss. Der f(x)-Wert der Funktion steht für die Ventilöffnung in Prozent und ist eine „Float“-Variable mit dem Namen „pVentil“. Der x-Wert der Funktion ist die Temperaturdifferenz „tempDifferenz“. Jeder Temperaturdifferenz soll eine Ventilöffnung in Prozent zugeordnet werden. Grundsätzlich muss folgender Zusammenhang gelten: Je größer die Temperaturdifferenz, desto großer die prozentuale Ventilöffnung. Ein einfacher linearer Zusammenhang eignet sich aber nicht, da so lange wie möglich viel Hitze erzeugt werden soll, damit sich der Topf schnell aufheizen kann. Das Projekt soll den Kochprozess vereinfachen und nicht unnötig in die Länge ziehen. Jedoch ist es ebenso wichtig, dass bei geringer Temperaturdifferenz die Flamme zunehmend kleiner wird, um das exakte Erreichen der Zieltemperatur zu gewährleisten. Folglich scheint es sinnvoll, eine Funktion zu nehmen, welche eine logistische Kurve aufweist. Die Entscheidung fiel nach vielen Versuchen mit unterschiedlichen Funktionen auf folgende Funktion: f(x)= 80/(1+1,15^(-x+35))+0,3

Graph der Funktion Bild der Funktion

Im Bereich geringer Temperaturdifferenzen nährt sich die Flamme der geringsten Intensität an. Bei steigender Differenz steigt die Funktion jedoch stark, sodass viel Hitze erzeugt wird und die Zieltemperatur schnell erreicht werden kann. Bei besonders hohen Differenzen wiederum nährt sich die Funktion einem Grenzwert von etwa 80% Ventilöffnung an. Beim Testen ist klar geworden, dass eine Ventilöffnung von 100% unbrauchbar ist, da bei dieser großen Gasmenge viele hohe Flammen am Topf vorbeischlagen. Die Funktion verfügt somit über einen Wertebereich für die Ventilöffnung von 0,3% bis 80% Öffnung. Deshalb geht die Flamme nie gänzlich aus, sie wird aber auch nie so groß, dass die Benutzerfreundlichkeit oder Sicherheit gefährdet wird.
Zuletzt wird die errechnete Schrittstellung des Schrittmotors angefahren. Die Programmierung des Motors gestaltet sich dank der verwendeten Bibliothek simpel. Als erstes wird ein Ziel in Schritten festgelegt, welches angefahren werden soll. Anschließend wird der Befehl erteilt, dass der Motor dieses Ziel anfahren soll. Während der Bewegung des Schrittmotors wird der Code angehalten. Unter anderem aus diesem Grund ist die Verwendung der „ISR“ unumgänglich. Nach dem Erreichen des festgelegten Ziels werden alle für den Motor relevanten Pins deaktiviert. Der Vorteil davon ist eine Energieersparnis, da kein Strom fließen kann. Folglich erhitzt der Schrittmotor nicht so stark, sodass ein Dauerbetrieb ohne Sorge möglich ist.
Ausschnitt des Codes
	
void loop() {
  tempDifferenz = eingestellteTemp - tatTemp;               //Differenz aus eingestellter Temperatur und gemessener Temperatur wird gebildet und als int Variable gespeichert

  stepperPosition = pVentil * schritteproprozent;           //die Position des Steppers ist das Produkt der gewünschten Ventilstellung und der Anzahl der Schritte, welche für 1% benötigt werden

                                                             
  pVentil= 80/(1+ pow(1.15, -tempDifferenz + 35)) +0.3;     //mathematische Funktion, welche die Temperaturdifferenz in eine Ventilstellung umsetzt
  pVentil = min(100, max(0, pVentil));                      //der Wertebereich der Ventilöffnung wir zwischen 0% und 100% begrenzt

  stepperPosition = min(7168, max(0, stepperPosition));     //um sicherzugehen, dass der Motor nicht zu weit dreht und die Hardware beschädigt wird, wird auch die maximale Drehung begrenzt
  
//dieser Programmabschnitt aktualisert die Position des Schrittmotors:
stepper1.moveTo(stepperPosition);                     
stepper1.runToPosition();          //leider wird der Code an diese Stelle pausiert; der Schrittmotor sollte also möglichst schnell drehen
stepper1.disableOutputs();         //die Pins für den Schrittmotor werden deaktiviert. Somit wird Strom gespart und eine Überhitzung des Motors verhindert

}
	

Die Hardware ist erforderlich, damit die entwickelte Software auch in der Realität getestet werden kann und der "physical" Teil des physical computing Projekts umgesetzt werden kann.

  • Das Herzstück der Software ist natürlich der Gaskocher, der bei Amazon bestellt wurde. Kauflink von Amazon Über eine passende Gasflasche wird der Kocher mit Gas versorgt. Der Gasfluss kann manuell mit einem Drehregler eingestellt werden.
Bild des Gaskochers Bild des Gaskochers Bild des Gaskochers
  • Ebenfalls essenziell für das Projekt ist ein arduinofähiges Thermometer. Die Wahl fiel auf das MAX6675. Kauflink von Amazon Dieses Thermometer zeichnet sich durch einen hohen Toleranzbereich aus, was für die Arbeit mit Feuer sehr wichtig ist. Zunächst stand der genaue Einsatzbereich des Thermometers noch nicht fest und über eine Anwendung im Flammenbereich wurde gesprochen. Letztendlich entschied sich die Gruppe dafür, das Thermometer in den Deckel zu integrieren und so die Temperatur des Topfinhaltes zu ermitteln. Bei dieser Idee, die für den Nutzer die transparenteste Darstellung bietet, ergaben sich allerdings zwei Probleme. Erstens ist der gemessene Wert etwas verzögert, da das Wasser sich nur träge erwärmt und die Restwärme des Topfbodens und der Gasflamme nicht berücksichtigt wird. Zweitens ist das Thermometer selbst nicht wasserdicht, sodass es abgedichtet werden musste. Dafür wurde das Thermometer in eine Kupferröhre gelegt und mit Gummidichtungen abgedichtet. Außerdem wurde das Thermometer in den Topfdeckel integriert, damit der Topf frei beweglich bleibt und nur der Deckel fest mit dem Versuchsaufbau verbunden ist. Durch diese Befestigung, die ebenfalls mit einer Gummidichtung verschlossen wurde, konnte ein Messfehler durch vorbeischlagende Flammen und die Erhitzung des Topfmaterials verhindert werden.
Bilder des Thermometers

Produktfoto von Amazon Foto von Amazon abgedichtetes Thermometer von der Seite Thermometer von der Seite abgedichtetes Thermometer von oben Thermometer von oben in den Deckel integriertes Thermometer intergriertes Thermometer

  • Die Steuerung der Gasmenge, die verbrannt wird, wurde durch einen Schrittmotor übernommen. Der Motor sollte über eine Verbindung den Gasregler des Kochers greifen und diesen drehen, damit mehr oder weniger Gas fließen kann. Die Wahl fiel auf den "STEPPER MOTOR PM GEARED UNI 12" Link zum Motor Durch ein 3D gedrucktes Verbindungsstück wurde eine Verbindung von Schrittmotor zu Gasregler hergestellt. Das Verbindungsstück wurde mit TinkerCAD erstellt, nachdem mit einer Schieblehre alle wichtigen Maße erhoben worden waren und dann mit einem 3D Drucker gedruckt. Nach mehreren Fehlversuchen ist ein Teil entstanden, das sowohl auf den Schrittmotor als auch auf den Gasregler gesteckt werden konnte und auch bei Belastung nicht durchdrehte. Damit der Schrittmotor Kraft gegen das Ventil aufbringen kann, musste sichergestellt werden, dass der Motor sich nicht mitdreht, sondern mit statischen Teilen verbunden ist. Zu diesem Zweck wurde eine Plattform aus dünnem Blech auf das Ventil gebaut und mit einer Steckverbindung sicher verankert. Anschließend wurde eine Verlängerung aus Winkeln gebaut und sowohl an dem Schrittmotor als auch an dem Blech befestigt. Der Schrittmotor war nun fest verankert, sodass er Kraft auf das Ventil aufbringen kann, um es zu öffnen oder zu schließen. Durch die Winkelverlängerung wurde auch eine Flexibilität der Halterung erreicht. Diese Beweglichkeit führte zu zwei wichtigen Vorteilen: Erstens wurde die Ausrichtung erleichtert und zweitens kann somit auch die Vor- und Zurückbewegung des Gasgewindes ausgeglichen werden.
Bilder des Schrittmotors

Produktbild von digikey Produktbild Bild des 3D-Verbindungsstückes Verbindungsstück Bild der Winkelverbindung zum Schrittmotor Winkelverbindung Blechplattform auf dem Ventil der Gasflasche Plattform

  • Als Gefäß entschied sich die Gruppe für einen alten Kochtopf. Dieser war bereits im Besitz einer befreundeten Familie und war daher leicht zu beschaffen. Da in mehreren Versuchsreihen auffiel, dass sich der Inhalt des Topfes selbst bei sehr niedriger Flamme weiter erhitzte, stellte die Gruppe fest, dass der Topf so gut isoliert war, dass nicht genug Wärme an die Umwelt abgegeben wird. Da die Flamme nicht weiter reduziert werden konnte, musste die Abgabe an die Umwelt erhöht werden. Es stellte sich als sinnvoll heraus, den Deckel nur halb auf den Topf zu setzen, sobald die Temperatur erreicht wurde. Außerdem wurden durch Bohrungen in den Deckel Löcher geschaffen, durch die der heiße Wasserdampf entweichen konnte.
Bilder vom Topf Bild des Topfes Bild vom Topf Bild des durchlöcherten Deckels von unten Bild von unten
  • Zur besseren Bedienbarkeit entschied sich die Gruppe für die Verwendung eines rotary encoders. Über diesen wird die Temperatur eingestellt. Konkret wurde der rotary encoder KY-040 verwendet. Kauflink zum Produkt Für diesen Prototyp wurde noch kein Handknauf verwendet. Ziel ist es aber, für die nächste Abgabe den encoder in eine Box einzuarbeiten und die Bedienung über einen Handknauf zu erleichtern. Ähnlich verhält es sich mit dem verwendeten LC-Display. Es wurde das HD44780 1602 LCD verwendet. Kauflink zum Produkt Das Display sorgt für eine angenehme Benutzung, da sowohl die gemessene Temperatur als auch die eingestellte Temperatur angezeigt werden. So ist ein Computer mit einem seriellen Monitor nicht mehr erforderlich. Auch das Display wurde für den Prototyp nicht verändert, soll aber beim fertigen Produkt in die Box mit eingearbeitet werden.
    Im Lieferumfang des Produktes war ein zusätzliches Modul enthalten, welches an das Display gelötet wird und mit diesem eine Einheit bildet. Es handelt sich um ein Modul, welches eine serielle Kommunikation mit dem LCD ermöglicht. Durch den I2C-Datenbus wird dank entsprechender Bibliothek die Programmierung der Einheit sehr simpel. Der massive Vorteil ist, dass der Bus nur 2 Pins für die Kommunikation benötigt. Es werden also viele Pins am Arduino gespart, ohne welche die restlichen Module nicht angeschlossen werden könnten.
Bilder der Produkte Produktbild von az-delivery Bild des LC-Displaysy
Der viermonatige Entwicklungsprozess mit vielen Testungen und Lösungen von Problemen hat letzendlich zu einem funktionierenden Prototyp geführt.
Video eines erfolgreichen Experiments - novum hotplate
fertiger Code
	
/*
*/
// in diesem Abschnitt werden die benötigten Bibliotheken eingebunden:
#include <LiquidCrystal_I2C.h>                         //ermöglicht eine einfache Komunikation mit dem LC-Display mit nur 2 Datenpins; Quelle: https://github.com/fdebrabander/Arduino-LiquidCrystal-I2C-library                                                                                                                      
#include <Wire.h>                                      //wird für die I2C-LCD Bibliothek zusätzliche für die Kommunikation benötigt benötigt; Quelle: Vorinstallierte Arduino-Bibliothek
#include <AccelStepper.h>                              //ermöglicht einfache Programmierung des Schrittmotors; Quelle: Arduino-Biliotheken-Verzeichnis
#include "max6675.h"                                   //ist für die Auslese des Thermosensors zuständig; Quelle: Arduino-Biliotheken-Verzeichnis von Adafruit

//in diesem Abschnitt werden alle benötigten Variablen und Konstanten definiert:
  //zunächst werden die Pin-Belegung:
const int PinA = 2;   //CLK: Clock-Pin für den Rotary-Encoder
const int PinB = 3;   //DT:  Daten-Output-Pin des Rotary-Encoder
const int PinSW = 8;  //SW:  Knopf-Pin des Rotary-Encoder

const int soPin = 4;  //SO: Serieller Output-Pin für das Thermoelement
const int csPin = 5;  //CS: Chip-Select-Pin für das Thermoelement
const int sckPin = 6; //SCK: Serieller Clock-Pin für das Thermoelement

#define motorPin1 9   //Die 4 benötigten Pins für den Schrittmotor werden festgelegt 
#define motorPin2 10
#define motorPin3 11
#define motorPin4 12

  //außerdem werden verschiedene Variablen für die Programmierung benötigt:
float tatTemp;                                //Variable für die gemessene Temperatur in Grad Celsius (float: mit 2 Nachkommastellen)
int lastCount = 0;                            //speichert den letzten Wert des rotary encoders
volatile int eingestellteTemp = 0;            //eingestellte Temperatur: wird durch die ISR (Interrupt Service Routine) aktualisiert
float pVentil = 0;                            //Ventilstellung in Prozent (100% entspricht vollständiger Öffnung)
int stepperPosition = 0;                      //Position des Schrittmotors in Schritten (4096 Schritte = 360°)
float tempDifferenz;                          //Differenz zwischen eingestellter Temperatur und gemessener Temperatrur  
const float schritteproprozent = 71.68;       //71.68 Schritte des Schrittmotors entpricht 1° Ventilöffnung 
int rotarySchrittwert = 5;                    //Wertigkeit jedes am Rotaryencoder eingestellten Schrittes

#define HALFSTEP 8                            //der Schrittmotor soll im Halfstep-Modus betrieben

AccelStepper stepper1(HALFSTEP, motorPin1, motorPin3, motorPin2, motorPin4);    //das Objekt "stepper1" wird initialisiert
LiquidCrystal_I2C lcd(0x3F, 16, 2);                                             //das Objekt "lcd" wird initialisiert
MAX6675 thermo(sckPin, csPin, soPin);                                           //das Objekt "thermo" wird initialisiert


//Der folgende Programmteil wird nur einmal abgerufen:
void setup()       
{
  Serial.begin(9600);    //die serielle Kommunikation wird gestartet
    delay(1000);         //Zeit, damit sich die Sensoren kalibrieren können 
  lcd.begin();           //das LC-Display wird gestartet  
  lcd.backlight();       //die Hintergrundbeleuchtung des LCDs wird aktiviert 
  
  stepper1.setCurrentPosition(0);     //die aktuelle Position des Schrittmotors wird = 0 gesetzt
  stepper1.setMaxSpeed(1000.0);       //die maximale Geschwindigkeit des Steppers wird auf 1000 Schritte pro Sekunde gesetzt 
  stepper1.setAcceleration(1000.0);   //die Beschleunigung des Steppers wird auf 1000 Schritte pro Sekunde^2 gesetzt 
  stepper1.setSpeed(1000);            //die Geschwindigkeit des Steppers wird auf 1000 Schritte pro Sekunde festgelegt 

  pinMode(PinA, INPUT);               //PinA und PinB sind INPUTs, um die Signale des Rotary-Encoders zu lesen
  pinMode(PinB, INPUT);
  pinMode(PinSW, INPUT_PULLUP);       //der SW-Pin ist potentailfrei; es wird ein Widerstand benötigt, dafür wird der im Arduino verbaute Pullup-Widerstand verwendet

  attachInterrupt(digitalPinToInterrupt(PinA), isr, LOW);  //die Interupt-Routine "ISR" wird dann ausgelöst, wenn der PinA = LOW ist
  
  Serial.println("Start");  //das Setup ist ausgeführt; im seriellen Monitor wir das mit "Start" signalisiert
} 

//Der folgende Programmteil wird bei Vollendung wiederholt
void loop()
{
  float tatTemp = thermo.readCelsius();               //das Thermomenter wird ausgelesen und der Wert als Variable überführt
         delay(300);

//der serielle Monitor dient unserem Projekt als Kontrollbildschirm, deshalb werden alle wichtigen Werte abgebildet: 
  Serial.print("Eingestellte Temperatur: ");          
  Serial.println(eingestellteTemp);
         Serial.println(" ");
         
  Serial.print("Gemessene Temperatur in C: ");
  Serial.println(tatTemp);
         Serial.println(" ");
         
  Serial.print("Temperaturdifferenz:");
  Serial.println(tempDifferenz);
         Serial.println(" ");
         
  Serial.print("Ventilöffnung in Prozent: ");
  Serial.println(pVentil);
         Serial.println(" ");

  Serial.println("------------------------------------");  //dient der Übersicht im seriellen Monitor

  lcd.clear();                         //leert das LCD, damit neue und alte Werte sich nicht überlagern
  lcd.setCursor(0, 0);                 //das LCD soll die gemessene Temperatur und die eingstellte Temperatur darstellen: 
  lcd.print("ein.Temp: ");
    lcd.print(eingestellteTemp);
    lcd.setCursor(15, 0);
    lcd.print("C");
  lcd.setCursor(0, 1);
  lcd.print("akt.Temp: ");
    lcd.print(tatTemp);
    lcd.setCursor(15, 1);
    lcd.print("C");
  
delay(100);                           //0,1 Sekunden Pause, damit die Sensoren neue Werte bilden können
  
  if ((!digitalRead(PinSW))) {        //wenn der Knopf des Encoders gedrückt wird (Strom am PinSW anliegt), ist der Schrittwert = 1
    rotarySchrittwert = 1;
  }
  else{                               //andernfalls beträgt der Schrittwert = 5
    rotarySchrittwert = 5;
  }
  
   
  //wenn der folgende Programmteil aktiviert wird, kann bestimmt werden, ob der Wert des Encoders momentan verringert oder vergrößert wird
 /* if (eingestellteTemp != lastCount) {
      Serial.println("Eingestellte Temperatur: ");
      Serial.print(eingestellteTemp > lastCount ? "Up  :" : "Down:");
      Serial.println(eingestellteTemp);
      
      lastCount = eingestellteTemp ;
  }
 */

  tempDifferenz = eingestellteTemp - tatTemp;               //Differenz aus eingestellter Temperatur und gemessener Temperatur wird gebildet und als int Variable gespeichert

  stepperPosition = pVentil * schritteproprozent;           //die Position des Steppers ist das Produkt der gewünschten Ventilstellung und der Anzahl der Schritte, welche für 1% benötigt werden

                                                             
  pVentil= 80/(1+ pow(1.15, -tempDifferenz + 35)) +0.3;     //mathematische Funktion, welche die Temperaturdifferenz in eine Ventilstellung umsetzt
  pVentil = min(100, max(0, pVentil));                      //der Wertebereich der Ventilöffnung wir zwischen 0% und 100% begrenzt

  stepperPosition = min(7168, max(0, stepperPosition));     //um sicherzugehen, dass der Motor nicht zu weit dreht und die Hardware beschädigt, wird auch die maximale Drehung begrenzt
  
//dieser Programmabschnitt aktuallisert die Position des Schrittmotors:
stepper1.moveTo(stepperPosition);                     
stepper1.runToPosition();          //leider wird der Code an diese Stelle pausiert; der Schrittmotor sollte also möglichst schnell drehen
stepper1.disableOutputs();         //die Pins für den Schrittmotor werden deaktiviert. Somit wird Strom gespart und eine Überhitzung des Motors verhindert
  
}

//der folgende Programmteil ist die Interrupt-Service-Routine
void isr ()  {
  static unsigned long lastInterruptTime = 0;
  unsigned long interruptTime = millis();

  //wenn der Interupt schneller als 5 ms nach dem vorherigen Interrupt kommt, wird dieser ignoriert. Dadurch wird "Bounce" verhindert.
  //Bounces sind Signale, welche beim Herstellen eines mechanischen Kontaktes entstehen. Der Kontakt "flimmert". Wenn das nicht berücksichtigt wird, entstehen mehrere kurze Signale, auch wenn nur ein Schritt gedreht wurde
  if (interruptTime - lastInterruptTime > 5) {
    if (digitalRead(PinB) == LOW)
    {
      eingestellteTemp-= rotarySchrittwert ; 
    }
    else {
      eingestellteTemp+= rotarySchrittwert ; 
    }

    eingestellteTemp = min(300, max(0, eingestellteTemp));    //die Temperatur, welche eingestellt werden kann, ist zwischen 0° und 300° begrenzt 


  }
  lastInterruptTime = interruptTime;                          //es wird gespeichert, wann der letzte Interupt war
} 
Bilder der Verbindung vom Schrittmotor zum Gasregler Bild der Verbindung von oben Bild der Verbindung von oben #1 Bild der Verbindung von oben #2 Bild der Verbindung von oben #2 Bild der Verbindung von der Seite Bild der Verbindung von der Seite
Bild der Verbindung vom Ventil der Gasflasche zur Befestigung des Schrittmotors Verbindung vom Ventil der Gasflasche zur Befestigung des Schrittmotors Bild der Verbindung Gasflasche - Befestigung
Bild des Gaskochers Bild des Gaskochers Bild des Gaskochers
Bilder des Topfes mit integriertem Thermometer Bild des geschlossenen Topfes von oben Bild des Topfes von oben geschlossener Topf von der Seite Bild des Topfes von der Seite Bild des integrierten Thermometers von unten Bild des Thermometers von unten
Bilder des Netzteils Netzteil von vorne Netzteil Bild der Klemmverbindung Klemmverbindung
Bilder des LC-Displays ausgeschaltet LC-DisplayDisplay off eingeschaltetes LC-DisplayDisplay on
Steckverbindungen digitalisierter Schaltplan von fritzing digitaler Schaltplan Steckverbindung des Schrittmotors Steckverbindung des Schrittmotors Steckverbindung des rotary encoders Steckverbindung rotary encoder Steckverbindung des Thermometers Steckverbindung Thermometer Übersicht der Steckverbindungen Übersicht Steckverbindung

Der arduinogesteuerte Gaskocher - aus einer spontanen Idee ist Wirklichkeit geworden. Grundsätzlich lässt sich festhalten, dass die Gruppe mit dem Prototyp und der graphischen Darstellung des Projektes sehr zufrieden ist. Auch wenn der Entwicklungsprozess mit hohem zeitlichen Aufwand, einigen sehr kurzen Nächten und manchmal auch Flucherei verbunden war, überwog dauerhaft der Wille, das Projekt nach vorne zu bringen und die eigenen Kenntnisse zu erweitern.
Durch diese Projektarbeit gewonnen beide Gruppenmitglieder große Einblicke in das Programmieren von Microcontrollern und die Darstellung von Informationen mit HTML. Wie in dem Punkt "verwendete Programme" dargestellt, wurden auf dem Weg des Projekts aber auch viele andere Fähigkeiten hinzugewonnen. Beispielhaft dafür ist das Erstellen und Drucken von 3D-Modellen oder die Erstellung von YouTube-Videos. Für diese Möglichkeit ist die Gruppe sehr dankbar. Hierin besteht auch ein großer Vorteil bei physical computing Projekten, da Arbeiten auf ganz unterschiedlichen Ebenen erledigt werden müssen. Dadurch werden Projekte natürlich schnell anspruchsvoll, aber eben auch sehr vielseitig.
Die zurückliegende Gruppenarbeit wurde anhand von verschieden Kriterien beurteilt und reflektiert.

  • Die Planung des Projektes verlief unkompliziert. Während der gesamten Projektphase war die Stimmung innerhalb der Gruppe gut und die Arbeitsphasen produktiv. An Absprachen wurde sich gehalten und die Bereitschaft, auch außerschulisch das Projekt voranzubringen war vorhanden.
  • Mit der geleisteten Arbeit ist die Gruppe zufrieden, obwohl nicht alle Ziele umgesetzt werden konnten. Aufgrund von zeitlichen Schwierigkeiten wurden, anders als eingangs geplant, die Steckverbindungen nicht gelötet und auch keine Transportbox gebaut. Die Gruppe entschied sich dafür, die hardwaretechnische Umsetzung für den Prototyp in den Hintergrund zu stellen und die Software in den Vordergrund zu rücken. Wichtig bei der Hardware war nun, dass diese funktional war, damit Testungen erfolgen können. Durch das Projekt lernte die Gruppe auch, dass es zwar wichtig ist, sich Ziele zu setzen, allerdigns auch adaptiv und flexibel sich auf äußere Umstände anpassen zu können
Nach der Reflexion des Projektes war für die Gruppe schnell klar, dass die Zusammenarbeit auch für das kommende Halbjahr weitergeführt werden soll. Es ist wichtig, dass ein gutes Klima in der Gruppe herrscht und dass sich die Mitglieder aufeinander verlassen können. Während der finalen Phase des Projektes hat sich ebenfalls abgezeichnet, dass die Gruppe das Projekt des arduinogesteuerten Gaskochers weiterführen möchte. Im Hinterkopf stehen dort auch Ideen wie die Teilnahme am Wettbewerb Jugend forscht. Der entstandene Prototyp hat gezeigt, wie viel innerhalb von vier Monaten möglich ist und dass dieses physical computing Projekt die Gruppe begeistert. Damit aus dem Protoyp ein fertiges Produkt wird, sollen in der nächsten Arbeitsphase einige Änderungen vorgenommen werden. Die Brainstormingpahse dieses neuen Abschnittes startete bereits. Abschließend lässt sich dieser Unterichtsabschnitt als erfolgreich bewerten, weil viel dazu gelernt wurde, es viel Spaß bereitet hat und ein funktionaler Protoyp entstanden ist, der die Grundlage für die weitere Entwicklung darstellt.

Beim Brainstormingprozess kamen folgende Ideen auf:

  • Handysteuerung der Temperatur
  • Programmierbarkeit eines Kochprogramms mit zeitlicher Komponente
  • ordentliches Kabelmanagement mit Verlötung und Aufbewahrung
  • akustisches oder optisches Signal beim Erreichen der Zieltemperatur
  • weitere Optimierung der Funktion zur Ermittlung des Öffnungsgrads
  • eigenständige Entzündung des Gaskochers
  • Menu für das LC-Display

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published