Relais Ansteuerung Arduino Mega + Relaisboard + Visual Basic

Hallo zusammen,

eigentlich ganz simpel ich habe es teilweise schon geschafft mein Relaisboard über den Arduino und Visual Basic anzusteuern. Dh. ich habe 16 Taster in VB (8x An und 8 x Aus) mit denen ich die Relais eben an- und ausschalte.

Problem nun, ich komme nur bis Relais 5 An. Aus funktioniert nicht da ich die Ziffer 10 schlecht übertragen kann. Ich rede wohl noch etwas in rätseln deswegen hier der Code für Arduino und Visual Basic :

Arduino=

int relais1 = 2;
int relais2 = 3;
int relais3 = 4;
int relais4 = 5;
int relais5 = 6;
int relais6 = 7;
int relais7 = 8;
int relais8 = 9;


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

pinMode(relais1, OUTPUT); 
pinMode(relais2, OUTPUT); 
pinMode(relais3, OUTPUT); 
pinMode(relais4, OUTPUT); 
pinMode(relais5, OUTPUT); 
pinMode(relais6, OUTPUT); 
pinMode(relais7, OUTPUT); 
pinMode(relais8, OUTPUT); 

digitalWrite(relais1, HIGH);
digitalWrite(relais2, HIGH);
digitalWrite(relais3, HIGH);
digitalWrite(relais4, HIGH);
digitalWrite(relais5, HIGH);
digitalWrite(relais6, HIGH);
digitalWrite(relais7, HIGH);
digitalWrite(relais8, HIGH);

}


void loop(){
while (Serial.available() == 0); // do nothing if nothing sent
int val = Serial.read() - '0'; // deduct ascii value of '0' to find numeric value of sent number

if (val == 1) { 
Serial.println("Relais 1 ON");
digitalWrite(relais1, LOW); 
}
else if (val == 2) 
{
Serial.println("Relais 1 OFF");
digitalWrite(relais1, HIGH); 
}

else if (val == 3) 
{
Serial.println("Relais 2 ON");
digitalWrite(relais2, LOW); 
}

else if (val == 4) 
{
Serial.println("Relais 2 OFF");
digitalWrite(relais2, HIGH);
}

else if (val == 5) 
{
Serial.println("Relais 3 ON");
digitalWrite(relais3, LOW);
}

else if (val == 6) 
{
Serial.println("Relais 3 OFF");
digitalWrite(relais3, HIGH);
}

else if (val == 7) 
{
Serial.println("Relais 4 ON");
digitalWrite(relais4, LOW);
}

else if (val == 8) 
{
Serial.println("Relais 4 OFF");
digitalWrite(relais4, HIGH);
}

else if (val == 9) 
{
Serial.println("Relais 5 ON");
digitalWrite(relais5, LOW);
}

else if (val == 16) 
{
Serial.println("Relais 5 OFF");
digitalWrite(relais5, HIGH);
}


else // if not one of above command, do nothing
{
//val = val;
}
Serial.println(val);
Serial.flush(); // clear serial port
}

Visual Basic =

Imports System.IO
Imports System.IO.Ports
Imports System.Threading

Public Class Form1



    Dim Count As Integer = 0
    Dim var As Integer
    Dim wirkungsgrad As Double
    Dim dichte As Double
    Dim windgeschw As Double
    Dim durchmesser As Double
    Dim leistung As Double
    Dim leistungwind As Double

    Dim speichervar As Integer

    Private Sub TextBox6_KeyPress(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyPressEventArgs)
        If InStr("0123456789" & Chr(8), e.KeyChar) = False Then e.Handled = True
    End Sub
    Private Sub TextBox7_KeyPress(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyPressEventArgs)
        If InStr("0123456789" & Chr(8), e.KeyChar) = False Then e.Handled = True
    End Sub
    Private Sub TextBox8_KeyPress(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyPressEventArgs)
        If InStr("0123456789" & Chr(8), e.KeyChar) = False Then e.Handled = True
    End Sub




    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
      

        TextBox3.Text = "Bitte richtigen COM Port auswählen"
        Panel1.Visible = False

        Me.Size = New Size(500, 150)




    End Sub

   

    Private Sub Button3_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button3.Click
        End
    End Sub

   

    Private Sub Button4_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button4.Click

        SerialPort1.PortName = ComboBox1.Text
        SerialPort1.BaudRate = 9600
        SerialPort1.DataBits = 8
        SerialPort1.Parity = Parity.None
        SerialPort1.StopBits = StopBits.One
        SerialPort1.Handshake = Handshake.None
        SerialPort1.Encoding = System.Text.Encoding.Default
        SerialPort1.Open()
        speichervar = 1

        TextBox3.Text = "System READY"
        ComboBox1.Visible = False
        Button4.Visible = False
        Panel1.Visible = True
        Me.Size = New Size(500, 600)


    End Sub

    Private Sub Button5_Click_1(ByVal sender As System.Object, ByVal e As System.EventArgs)


        TextBox3.Text = "System READY"
        ComboBox1.Visible = False
        Button4.Visible = False

        speichervar = 0
        Panel1.Visible = True
        Me.Size = New Size(500, 600)

    End Sub

    Private Sub Button8_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button8.Click

        SerialPort1.Write("1")

    End Sub

    Private Sub Button9_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button9.Click

        SerialPort1.Write("2")

    End Sub

    
    Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
        SerialPort1.Write("3")
    End Sub


    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        SerialPort1.Write("4")
    End Sub


    Private Sub Button6_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button6.Click
        SerialPort1.Write("5")
    End Sub

    Private Sub Button5_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button5.Click
        SerialPort1.Write("6")
    End Sub

    Private Sub Button10_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button10.Click
        SerialPort1.Write("7")
    End Sub

    Private Sub Button7_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button7.Click
        SerialPort1.Write("8")
    End Sub

    Private Sub Button12_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button12.Click
        SerialPort1.Write("9")
    End Sub

    Private Sub Button11_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button11.Click
        SerialPort1.Write("10")
    End Sub
End Class

Meine Frage nun, welchen Weg muss ich wählen damit ich auf dieser Basis eine 10 erfolgreich zum Arduino schicken kann und er mir diese auch als eine 10 interpretiert. Stichwort ist hier ASCII aber ich habe keine Ahnung wo ich ansetzen muss.

Beste Grüße

Don

Dein Fehler liegt hier

int val = Serial.read() - '0'; // deduct ascii value of '0' to find numeric value of sent number

Entweder du ließt mit Serial.parseInt() ein, oder du musst deinen Wert akkrumilieren(?!).

Versuch es mal wie folgt.

    if (Serial.available())
    {
      char c = Serial.read();
      if (c >= '0' && c <= '9')
      {
        zahl = 10*zahl + ( c - '0' );
      }
      else if (c == '\r' || c == '\n')
      {
        printf("\n%i\t", zahl);
        zahl = 0;
      }
    }

hi,

oder Du machst weiter mit ASCII, da mußt Du dann damit arbeiten: 0123456789:;<=>?

gruß stefan

Oder du schickst gleich Zahlen von 0-255 und nicht Strings/chars

Danke wie immer für die schnellen Tips aber

@sschultewolter
leider funktioniert das nicht, ich habe jetzt die Zeilen mit deinem Code ausgetauscht und auch die variabeln ersetzt aber es tut sich rein garnichts

@serenifly
kannst du das etwas konkretisieren, wie mache ich das?

@Eisbaer
kannst du mir ein Beispiel nennen ?

Danke euch

moin

gucke dir mal das hier an..

der erklärt dir hier wie man das ganz einfach macht

trino

DonQuijote:
Problem nun, ich komme nur bis Relais 5 An. Aus funktioniert nicht da ich die Ziffer 10 schlecht übertragen kann. Ich rede wohl noch etwas in rätseln deswegen hier der Code für Arduino und Visual Basic :

Dir fehlen wesentliche Grundkenntnisse zum Programmieren von Arduino-Sketchen.

Zum Beispiel zum Verständnis der Variablentypen "char" (einzelnes Zeichen) und "String" (Zeichenkette aus vielen Zeichen).

In C/C++ stehen einzelne Zeichen (char) zwischen einzelnen Hochkommas und Strings zwischen mehreren Hochkommas.

Jedes einzelne Zeichen hat einen ASCII-Code. Mit der ASCII-Codierung scheinst Du auch auf Kriegsfuß zu stehen, der ASCII-Code von Ziffern ist nicht identisch mit dem numerischen Wert der Ziffer. ASCII-Codes sind bei der Verarbeitung von Zeichencodes aber wichtig, lerne ASCII-Code zu verstehen!

Und wenn ein Programm immer gleichartige Dinge tun soll, dann verwendet man Schleifen, z.B. for-Schleifen!

Wenn Du nun die Schaltinformation mit einem einzelnen "char" übertragen möchtest, kannst Du mit 10 verschiedenen Chars auch nur 10 verschiedene Informationen übertragen. Z.B. fünfmal EIN und fünfmal AUS, macht 10.

Mein Tipp: Es gibt zwar nur 10 Ziffern, aber das Alphabet hat 26 Buchstaben. Darüber gibt es Kleinbuchstaben und Großbuchstaben, also kannst Du mit einzelnen Buchstaben schon mal 26+26 Informationen übertragen. Z.B. 26 Einschaltinformationnen mit Großbuchstaben und 26 Kleinbuchstaben mit Ausschaltinformationen.

Schaue Dir bitte mal diesen Code an und versuche zu verstehen:

byte relais[]={2,3,4,5,6,7,8,9}; // Relais-Pins
int numRelais=sizeof(relais);

// Definieren, ob die Relais "active LOW" oder "active HIGH" schalten
#define EIN LOW    // in diesem Fall "aktive LOW"
#define AUS HIGH

void setup() {
  Serial.begin(9600);
  for (int i=0; i<numRelais; i++) 
  {
    digitalWrite(relais[i], AUS); // verhindert Relaisklappern beim Programmstart
    pinMode(relais[i], OUTPUT); 
  }
  Serial.println();
  Serial.println("Relais-Schaltdemo by 'jurs' for German Arduino Forum");
  Serial.print("Ausschalten mit Kleinbuchstaben a bis ");
  Serial.write('a'+numRelais-1);
  Serial.println();
  Serial.print("Einschalten mit Grossbuchstaben A bis ");
  Serial.write('A'+numRelais-1);
  Serial.println();
  Serial.println();
}

void printRelaisStatus()
// Aktuellen Schaltstatus aller Relais auf Serial ausgeben
{
  for (int i=0; i<numRelais; i++) 
  {
    if (digitalRead(relais[i])==EIN)
      Serial.print('1');
    else  
      Serial.print('0');
  }  
  Serial.println();
  Serial.println();
}


void loop(){
  char c= Serial.read();
  int num;
  if (c>='a' && c<'a'+numRelais)
  {
    num=c-'a';
    Serial.print(c);Serial.print(' ');
    Serial.print("Relais ");Serial.print(num+1);Serial.println(" OFF");
    digitalWrite(relais[num], AUS); 
    printRelaisStatus();
  }
  else if (c>='A' && c<'A'+numRelais)
  {
    num=c-'A';
    Serial.print(c);Serial.print(' ');
    Serial.print("Relais ");Serial.print(num+1);Serial.println(" ON");
    digitalWrite(relais[num], EIN); 
    printRelaisStatus();
  }
}

Übrigens: Dieses Programm kann praktisch unverändert zum Schalten von 1 bis 26 Relais verwendet werden, einfach indem man das Array "relais[]" mit einer anderen Pin-Zahl definiert. Alle Schleifen werden mit dem Schleifenzähler "numRelais" durchlaufen, so dass nirgends im Programm etwas mehr geändert werden muß, egal ob nun 4, 8, 16 Relais zu schalten sind, oder irgendeine andere Relaisanzahl zwischen 1 und 26.

hi,

@Eisbaer
kannst du mir ein Beispiel nennen ?

Du schickst keine zahlen, sondern ASCII-zeichen. von "0" -"9"ist da alles klar, aber danach darf keine "10" kommen, sondern das nächste ASCII-zeichen, und das ist ":" (schau einmal bei ASCII in wikipedia, dort ist eine tabelle).

also einfach statt "10" ein ":", statt "11" ein ";" usw. vom VB-programm senden.
ok, nicht elegant, aber funkt...

gruß stefan

Du kannst auch andere Zeichen verwenden zB Buchstaben.
mit "A" schaltest Du das erste Relais ein und mit "a" aus.
usw
Das ist zum lesen des Sketches/Programms etwas einfacher.

grüße Uwe

Hat ja der jurs schön erklärt mit dem Beispielcode.

skorpi08:
Hat ja der jurs schön erklärt mit dem Beispielcode.

Ups, Dann haben ich und Eisebaer das nicht gelesen.
Uwe

DonQuijote:
Danke wie immer für die schnellen Tips aber

@sschultewolter
leider funktioniert das nicht, ich habe jetzt die Zeilen mit deinem Code ausgetauscht und auch die variabeln ersetzt aber es tut sich rein garnichts

Hab das CodeSnippet scheinbar nicht ganz mitkopiert. Die Variable "zahl" muss als Global INT oder als static int deklariert sein. Sollte eigentlich gehen, habe es ebenfalls für ein C# GUI Programm im Einsatz, bei dem Slider abfrage.

Wobei ich muss sagen, Uwes Idee ist soo einfach, das man da teils schon garnicht mehr drauf kommt :wink:

Wobei ich muss sagen, Uwes Idee ist soo einfach, das man da teils schon garnicht mehr drauf kommt

Stimmt! Auch jurs kommt mit 1 Buchstabe aus.

Alternativ: Immer 2 Buchstaben je Befehl: eine Ziffer '1 .. 8' und ein '+' zum Einschalten , oder ein '-' zum Ausschalten. ( oder so )
Bei 9600 Bd dauert es übrigens eine ganze Millisekunde, bis der zweite Buchstabe da ist,
das ist ein Vorteil der 1 Buchstabe = 1 Befehl Methode.

Danke an euch allen, bin schon viel weiter und jeder einzelne Tip hat mir geholfen