Serielle Kommunikation @ Arduino UNO & VB.Net

Hallo Leute,

ich stehe im Moment ein wenig auf dem Schlauch. Vielleicht zum einen weil ich noch kaum Erfahrung mit dem Arduino habe aber sicherlich auch, weil ich noch nie über VB.Net auf den Arduino zugegriffen habe.

Was habe ich vor ...
Ich habe mir das ACS714 Stromsensor Breakout Board +- 5A gekauft und möchte über den Arduino an einem Gerät den Strom messen.

Den entsprechenden Code dafür habe ich gefunden ...

/*
  Computes the average of a sample of N readings at intervals
  of 1000/N ms from a ACS712 low current sensor connected to
  the analog input pin 0 on Arduino board and print them to the
  serial monitor.
  This sketch uses the the Chauvenet's statistical criterion
  for rejecting the bad readings.
*/

const int num_readings = 10;
// Chauvenet’s criterion for rejecting a reading
// http://people.ohio.edu/bayless/seniorlab/lecture1.ppt
// http://people.ohio.edu/bayless/seniorlab/chauvenet.pdf
// Consult the table of the pdf document to find the ratio
// of maximum acceptable deviation to precision index for
// this sampling.
const int mad = 2.24;
int readings[num_readings];
int index = 0;

void setup() {
  // sets the serial port to 9600
  Serial.begin(9600);
}

int average() {
  int total = 0;
  for(int i=0; i<num_readings; i++)
    total = total + readings[i];
  return total/num_readings;
}

float standard_deviation(int avg) {
  int total = 0;
  for(int i=0; i<num_readings; i++)
    total = total + pow((avg - readings[i]), 2);
  return sqrt(total/num_readings);
}

void loop() {
  // read analog input pin 0
  int reading = analogRead(0);
  readings[index] = reading;
  // incrementing the index
  index = index + 1;
  // if have already been done 10 readings...
  if (index >= num_readings) {
    // set the index to 0
    index = 0;
    // compute the average
    int avg = average();
    // compute the standard deviation
    float std = standard_deviation(avg);
    
    float madstd = mad * std;
    float lowlimit = avg - madstd;
    float highlimit = avg + madstd;
    
    int count = 0;
    int total = 0;
    for(int i=0; i<num_readings; i++) {
      // Check if the values of the readings are within the limits.
      if(readings[i] >= lowlimit && readings[i] <= highlimit) {
        total = total + readings[i];
        count = count + 1;
      }
    }
    // compute the new average
    int newaverage = total/count;
    // send it to the serial port (as ASCII digits)
    Serial.println(newaverage);
  }
  // wait 1000/num_readings ms for next reading
  //delay(int(1000/num_readings));
}

Der Serial Monitor liefert mir dann das folgende Ergebnis... soweit so gut!

512
512
510
511
511
512
511
511
511
511
511
512
510
.....

Nun möchte ich mit meiner VB.Net Anwendung über den Serialport genau diese Zahlen abgreifen und da hänge ich nun fest. Ich habe dazu schon einiges ausprobiert, aber leider ohne Erfolg!

Der Code zum lesen schaut bei mir wie folgt aus...

Dim sw As New Stopwatch
        Dim swms As Long = sw.ElapsedMilliseconds
        Dim wert As Integer = 0
        sw.Start()
        Dim port As New System.IO.Ports.SerialPort
        With port
            .PortName = "COM3"
            .BaudRate = 9600
            .Parity = IO.Ports.Parity.None
            .DataBits = 8
            .StopBits = IO.Ports.StopBits.One
            .Handshake = IO.Ports.Handshake.None
            .RtsEnable = True
            .DtrEnable = True
            .Encoding = System.Text.Encoding.ASCII
            .NewLine = vbCrLf
        End With

        port.Open()
        Do

            wert = port.ReadByte

            RichTextBox1.Invoke(Sub()
                                    RichTextBox1.AppendText(wert.ToString)
                                End Sub)

            Dim v As Integer = CInt(100 / 1023 * wert)
            BackgroundWorker1.ReportProgress(v)
            dt.Rows.Add(sw.ElapsedMilliseconds, wert)

            If BackgroundWorker1.CancellationPending Then
                BackgroundWorker1.ReportProgress(0)
                Exit Do
            End If
            wert = 0
        Loop
        port.Close()

das Ergebnis in der Richtextbox ist dann ...

494948131053494913105349501310534949131053494813105313105349491310534949131053494913105349481310534948131053495013105349491310534949131053494813105349481310534948131053494913105349501310534949131053494913105349491310534949131053494913105349491310534949131053494813105349491310534950131053494913105349...

Weiß einer wie man da weiter kommt? Besten Danke!

49 49 48 13 10
53 49 49 13 10
53 49 50 13 10
53 49 49 13 10
53 49 48 13 10
als ashii Kode interpretiert ist:
1 1 0 LF CR
5 1 1 LF CR
5 1 2 LF CR
5 1 1 LF CR
5 1 0 LF CR

Grüße Uwe

Hallo Uwe,

danke für deine Antwort :slight_smile:

Ja die Informationen konnte ich auch schon etwas interpretieren! Nur ist die Frage, muss ich das mühesam zusammenschustern muss oder ob ich das nicht durch eine richtige Einstellung des Serialports und wenigen Codeschnippsel so hinbekomme wie im Serial Monitor zu sehen ist.

Ich kenne VB.net nicht. VB muß die angekommenen Zahlen nicht als Zahlen sondern als Zeichen interpretieren.
Grüße Uwe

Du solltest den SerialEvent (System.IO.Ports.SerialDataReceivedEventArgs) verwenden, damit dein Programm Eventbasierend arbeitet.

Ich verwende:
Dim bufEing(SP1.ReadBufferSize) As Byte
SP1.Read(bufEing, 0, SP1.ReadBufferSize)
Diesen Buffer musst du mit chr() umwandeln und in einen String klopfen.

Das kannst du machen sobald sich Bytes im Puffer befinden:
SP1.ReadBufferSize

Ein Zeichen bekommst du mit:
CR = Chr(13)

Hallo mde110,

danke für die Antwort. Ich habe die Schnittstelle genauso angesprochen wie von dir geschrieben. Mir war das mit dem Buffer nicht so ganz klar gewesen doch nun funktioniert alles wie gewünscht .... ein ein wenig Codebereinigung und dann sollte das schon funktionieren :slight_smile:

  1. Problem... Arduino Uno vergisst sein Programm ... werde den aber zurück schicken :zipper_mouth_face:

desert-fox:
danke für die Antwort. Ich habe die Schnittstelle genauso angesprochen wie von dir geschrieben. Mir war das mit dem Buffer nicht so ganz klar gewesen doch nun funktioniert alles wie gewünscht .... ein ein wenig Codebereinigung und dann sollte das schon funktionieren :slight_smile:

Schön, das ist ja toll.
Mit VB scheinst du ja auch schon Ordentlich zu haben, wenn du das so Problemlos umsetzen konntest.

desert-fox:
2. Problem... Arduino Uno vergisst sein Programm ... werde den aber zurück schicken :zipper_mouth_face:

Das kann ich mir nicht erklären wie das passieren kann.
Wann vergisst er das genau?

Arduino mit Alzheimer: uC "vergisst" Code - Deutsch - Arduino Forum

Zurückschicken ist sicher eine gute Lösung. Ist es ein Orginal-Arduino?

Grüße Uwe

Gibt's da irgendwo eine Anleitung oder Ähnliches, wie ich eine Verbindung zwischen dem Arduino und VB.net herstellen kann? Oder hast du dir das selbst erarbeitet? Würde das auch gerne mal probieren :slight_smile:

Hallo zusammen,

ja ich arbeite schon länger mit VB.net und habe auch schon div. Applikationen umgesetzt. Wie gesagt, es lag eher an der RS232 und dem fehlenden Verständnis dafür :wink: Das ist ein originaler Arduino und er vergisst die Informationen ganz sporadisch. Abends och mit rumgespielt und am nächsten Morgen ist alles weg oder manchmal auch zwischendurch.

@Spexx: Es gibt Anleitungen im netz dazu. Nur wird diese nicht deine Aufgabe lösen :slight_smile: Die Erkentniss habe ich in diesem Projekt sehr häufig feststellen müssen :slight_smile:

Siehe z. B.http://competefornothing.com/?p=738

Ich werde mal den Thread für mein weiteres "Verständnisproblem" nutzen wenn das OK ist :slight_smile:

Ich habe von einem Hersteller eine Schnittstellendefinition gekommen wo folgende Informationen drinstehen:

  • Anfangsbyte (Byte 0)
  • Telegrammrumpf (Byte 1 - n)
  • Endbyte (Byte n + 1) Das Endbyte ist eine Checksumme die hier anscheinend nach einem speziellen Alog berechnet wird.

Zur Übertragung gibt er nun auch zwei Kommandazeilen an

02 hex 02 hex FN hex CS hex

Kann mir irgendeiner sagen wie man sowas interpretieren muss und wie nun die Übertragung stattfindet?

Technisch habe ich mir das so vorgestelltn, dass ich den Arduino über das normale USB-Interface ansteuern kann und die digitalPins 0 und 1 (Rx Tx) die Informationen dann an das Gerät ausgeben. Sobald ich nun den Arduino über VB ansteuer soll er nun den Befehl zurück an die RS232 schicken und dadurch soll nun das Gerät angesteuert werden.

Ein Auszug (aus dem Kontext gerissen) aus einer techn. Doku ist immer schwierig zu verstehen. Auf Anhieb kann ich nur vermuten. Hierzu wäre das ganze Dokument sicherlich besser.

Bei RS232 musst du daran denken, dass der Ardu 5V TTL hat und die Maschine evtl. +/-12V für die RS232 benötigt.

Ja, mehr orginal-Text wäre extrem hilfreich.
Für die TTL-RS232 Pegelumsetzung gibt es fertige ICs die auch die Spannung für die RS232 produzieren zB den MAX232

Grüße Uwe

Hallo zusammen,

mit dem Auszug aus einer technischen Dokumentation ist immer soeine Sache! Dessen bin ich mir bewust, doch ich kann hier leider nicht die vollständige Doku hochladen, da diese der Geheimhaltungserklärung unterliegt.

Du kannst mir evtl. per PN einen Screenshot der Seite schicken und mir die Typenbezeichnung der Maschine geben. XD
Anderenfalls musst du wohl damit alleine klar kommen. 8)

Für alle die sich auch dafür interessieren wie man die Kommunikation mit seinem Arduino aufbaut und Informationen ausgelesen bekommt.

Der Code in VB.Net ist recht einfach. Dazu muss für dieses Beispiel einfach eine Schaltfläche auf eine Form gezogen werden (bei mir heißt die Schaltflächte btnRS232Lesen) und in das Click-Event die folgenden Zeilen Code einfügen:

        Dim port As New System.IO.Ports.SerialPort
        With port
            .PortName = "COM3" 'Der Arduino ist bei mir am COM3-Port angeschlossen. Ggf. müsst ihr das bei euch Ändern!
            .BaudRate = 9600
            .ReadTimeout = 5000
        End With

        port.Open()
        port.Write("C")
        MessageBox.Show(port.ReadLine)
        port.Close()

Der passende Code für den Arduino schaut so aus ...

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

void loop() {
  //Wenn die Schnittstelle bereit ist...
  if (Serial.available() > 0)
  {
    int inByte = 0;
    //Lesen ob etwas angekommen ist
    inByte = Serial.read();

    if (inByte == 'C') //Wenn ein C gelesen wir, dann hau die Zeile raus :-)
    {
      Serial.println("Hallo aus dem Arduino :-)");
    }
  }
}

Das Ergebnis ...