Frontend für 6 Analogwerte



Arduino sendet Daten an den Computer.
Der gibt sie in einem sogenannten "Frontend" aus, das in C# geschrieben ist.
Das Wort "Frontend" beschreibt den Teil eines Computerprogrammes, den der Nutzer "vor der Nase" hat.


Wozu ist das nützlich?

Wenn Dein Arduino Daten (z. B. Umweltdaten, wie Temperatur, Luftfeuchtigkeit, Helligkeit usw.) mittels Sensoren erfasst, können die ...

... in einem auf dem Computer laufenden Programm grafisch oder als Zahlen dargestellt werden,

... auf dem Computer in einer Datei abgespeichert werden, z. B. um später darauf zugreifen zu können,

... auf dem Computer in einer Datenbank abgespeichert werden, z. B. um sie im Netz anderen Nutzern zur Verfügung zu stellen.



Dieses Frontend ist unser Ziel:

        frontend


In unserem Fall sollen die sechs Werte der Analogeingänge des Arduino-Boards seriell in das Frontend gesendet und dort dem Benutzer sichtbar gemacht werden.

Du könntest sechs Spannungen an die Analogeingänge legen.
Oder die Analogeingänge einfach unbeschaltet lassen: sie werden dann Störfelder aus der Umgebung "einfangen", was uns in diesem Fall gerade eben nicht stört, da dadurch immer sechs mittlere Analogwerte "gesehen" werden.



1. Schritt


Arduino holt sich von seinen sechs Analogeingängen die Werte (jeweils möglich: 0...1023) und sendet diese in einem String verpackt über die serielle Schnittstelle.


Hier der Code, den Du so in Deinen Arduino schieben kannst:

int Wert0, Wert1, Wert2, Wert3, Wert4, Wert5; 

void setup() {
    Serial.begin(9600);
}
 
void loop() {
  
  Wert0 = analogRead(A0);
  Wert1 = analogRead(A1);
  Wert2 = analogRead(A2);
  Wert3 = analogRead(A3);
  Wert4 = analogRead(A4);
  Wert5 = analogRead(A5);
 
  String myString = "@"
    + String(Wert0) + ";"
    + String(Wert1) + ";"
    + String(Wert2) + ";"
    + String(Wert4) + ";"
    + String(Wert4) + ";"
    + String(Wert5)
    + "#";
 
  Serial.println(myString);
  Serial.flush();
  delay(1000);
  
}
 

Das ergibt dann Strings, die ungefähr so aussehen: @317;299;300;314;320;250#
Vorn ist ein @-Symbol und hinten ein #-Symbol.
Die 6 Werte sind durch Semikolons getrennt.




2. Schritt: das Frontend

Es hat folgende Funktionen:

frontend

  • Zuerst müssen wir dem Frontend sagen, an welchem Port unser Arduino hängt (links oben im Bild).

  • Dann werden die vom Arduino als String gesendeten Daten sekündlich in einer Listbox aufgelistet (links unten im Bild).

  • Letztendlich werden die 6 Werte in Bargraphdisplays dargestellt (rechts im Bild).

Das fertige Frontend kannst Du hier downloaden.


Versuche es selbst!

Das Frontend wurde von mir unter Windows 8.1 in C# mit Hilfe der kostenlosen IDE "Microsoft Visual Studio Express" (bekommst Du hier) geschrieben.


Wenn Du es selber versuchen willst, kannst Du wie folgt vorgehen:

  • Starte Visual Studio!

  • Lege ein Windows-Forms-Projekt in der Sprache C# an!

  • Platziere aus dem Werkzeugkasten Labels, ein NumericUpDown, einen Button, eine ListBox und 6 Progressbars auf dem Form!

  • Gib dem Button den Namen "btnConnect" und den Text "connect"!

  • Gib den Labels rechts neben den ProgressBars die Namen "lblA0" bis "lblA5"!

  • Doppelklicke im Werkzeugkasten auf SerialPort und auf Timer!
    Damit werden zwei Objekte davon in einem Bereich unter dem Form sichtbar.
    (Die sind zur Laufzeit des Programmes nicht mehr zu sehen.)

  • Doppelklicke im Form auf den Button "btnConnect": Du gelangst in die Methode (in anderen Programmiersprachen auch "Funktion" genannt), die dann ausgeführt wird, wenn zur Laufzeit der Button betätigt wird. Füge in diese Methode folgenden Quelltext ein:

     private void btnConnect_Click(object sender, EventArgs e) {

            label1.Enabled = false;
            numericUpDown1.Enabled = false;
            btnConnect.Enabled = false;

            serialPort1.PortName = "COM" + numericUpDown1.Value.ToString();
            serialPort1.BaudRate = 9600;
            serialPort1.DtrEnable = true;
            serialPort1.Open();
            connected = true;
     }

  • Wir benötigen 2 globale Variablen, die wir über alle Methoden schreiben:

            String newLine = "";
            Boolean connected = false;

  • Doppeklicke auf das Symbol "serielPort1". Du gelangst in die Methode, die dann ausgeführt wird, wenn Daten über den seriellen Port ankommen. Füge in diese Methode folgenden Quelltext ein:
        public void serialPort1_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {

            newLine = serialPort1.ReadLine();
        }

  • Doppelklicke auf das Symbol "timer1". Du gelangst in die Methode, die dann ausgeführt wird, wenn zur Laufzeit der Timer sagt "jetzt". Füge in diese Methode folgenden Quelltext ein:

     private void timer1_Tick(object sender, EventArgs e) {
            if ((connected == true) && (newLine != "")) showValues(newLine);
     }

  • Doppelklicke auf das Form. Du gelangst in die Methode, die dann ausgeführt wird, wenn das Form geladen (gestartet) wird. Füge in diese Methode folgenden Quelltext ein, um den Timer zu konditionieren:

            private void Form1_Load(object sender, EventArgs e) {
                timer1.Interval = 1000;
                timer1.Enabled = true;
            }



  • Zur Darstellung der Werte in Listbox und Progressbars, habe ich eine eigene Methode "showValues" geschrieben, die in der timer1_Tick-Methode jede Sekunde aufgerufen wird:

public void showValues(String s) {

          //zeige in Listbox
            listBox1.Items.Add(s);

          //Müll enfernen
            s = s.Replace("null", "");

            s = s.Replace(" ", "");
            s = s.Replace("\n", "");
            s = s.Replace("\r", "");

            s = s.Replace("@", "");
            s = s.Replace("#", "");


          //zeige die 6 Werte in Labels
            String[] einzelwert = s.Split(';');

            lblA0.Text = einzelwert[0];
            lblA1.Text = einzelwert[1];
            lblA2.Text = einzelwert[2];
            lblA3.Text = einzelwert[3];
            lblA4.Text = einzelwert[4];
            lblA5.Text = einzelwert[5];


          //zeige die 6 Werte in 6 Progressbars
            progressBar1.Value = Convert.ToInt32(einzelwert[0]);
            progressBar2.Value = Convert.ToInt32(einzelwert[1]);
            progressBar3.Value = Convert.ToInt32(einzelwert[2]);
            progressBar4.Value = Convert.ToInt32(einzelwert[3]);
            progressBar5.Value = Convert.ToInt32(einzelwert[4]);
            progressBar6.Value = Convert.ToInt32(einzelwert[5]);
}




Hier das komplette Programm:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO.Ports;

namespace ArduinoEmpfaengtSerielleDaten {
    public partial class Form1 : Form {

        String newLine = "";
        Boolean connected = false;

        public Form1() {
            InitializeComponent();
            numericUpDown1.Value = 3;
        }

        private void Form1_Load(object sender, EventArgs e) {
            listBox1.Items.Add(newLine);
            timer1.Interval = 1000;
            timer1.Enabled = true;
        }

        private void btnConnect_Click(object sender, EventArgs e) {
            label1.Enabled = false;
            numericUpDown1.Enabled = false;
            btnConnect.Enabled = false;

            serialPort1.PortName = "COM" + numericUpDown1.Value.ToString();
            serialPort1.BaudRate = 9600;
            serialPort1.DtrEnable = true;
            serialPort1.Open();
            connected = true;
        }

        public void serialPort1_DataReceived(object sender, SerialDataReceivedEventArgs e) {
            newLine = serialPort1.ReadLine();
        }


        public void showValues(String s) {

            //zeige in Listbox
            listBox1.Items.Add(s);
          
            //Müll enfernen

            s = s.Replace("null", "");
            s = s.Replace(" ", "");
            s = s.Replace("\n", "");
            s = s.Replace("\r", "");
            s = s.Replace("@", "");
            s = s.Replace("#", "");


            //zeige die 6 Werte in Labels
            String[] einzelwert = s.Split(';');
            lblA0.Text = einzelwert[0];
            lblA1.Text = einzelwert[1];
            lblA2.Text = einzelwert[2];
            lblA3.Text = einzelwert[3];
            lblA4.Text = einzelwert[4];
            lblA5.Text = einzelwert[5];


            //zeige die 6 Werte in 6 Progressbars
            progressBar1.Value = Convert.ToInt32(einzelwert[0]);
            progressBar2.Value = Convert.ToInt32(einzelwert[1]);
            progressBar3.Value = Convert.ToInt32(einzelwert[2]);
            progressBar4.Value = Convert.ToInt32(einzelwert[3]);
            progressBar5.Value = Convert.ToInt32(einzelwert[4]);
            progressBar6.Value = Convert.ToInt32(einzelwert[5]);


        }

        private void timer1_Tick(object sender, EventArgs e) {
            if ((connected == true) && (newLine != ""))
                showValues(newLine);
        }

    }
}


Natürlich kann man so ein Frontend auch in JAVA oder Visual Basic schreiben. Die Vorgehensweise ist trotzdem sehr ähnlich. Und das Programm im Arduino dasselbe.