Daten von LabVIEW empfangen

Hallo Leute,

ich möchte über einen Arduino Mega einen Motor steuern. Dazu muss ich dem Arduino mit LabVIEW Daten für Geschwindigkeit (G), Schrittanzahl (S) und Drehrichtung (R) vorgeben und anschießend den Motor mittels digitalen Pin starten.

Zur Zeit versuche ich die Kommunikation zum Laufen zu bringen. Für eine Einzelne LED mit einem Einzelnen Wert ist das auch kein Problem. Jetzt will ich aber gern dem Arduino einen String per Serieller Schnittstelle schicken “G123”, “S500” und “R1” . Der erste Buchstabe soll die Variable angeben die geändert werden soll und die Zahl danach den Wert dieser Variable.

Zum Testen würde es mir reichen, wenn ich die externe LED und die On Board LED blinken lassen kann.
Dazu hätte ich gern, dass wenn ich A5 (LED 1 blinkt 5 mal) B15 (LED 2 binkt 15 mal).

Das ganze muss ich wahrscheinlich über eine Case Struktur aufbauen. Nur wie bekomme ich dann am besten die empfangenen Zahlen/ASCII-Zeichen als den Wert den ich gesendet habe?

Hier der Code mit dem ich die Kommunikation allgemein getestet habe.

#include <Wire.h>
#include <SPI.h>
#include <Servo.h>
#include "LabVIEWInterface.h" 

/*********************************************************************************
 **  setup()
 **
 **  Initialize the Arduino and setup serial communication.
 **
 **  Input:  None
 **  Output: None
 *********************************************************************************/

 int incomingByte = 0;
 
void setup()
{  
   // >>>> Setup Motor <<<<
  Serial.begin(9600);
  pinMode(40, OUTPUT);
  digitalWrite(40,LOW);
  // Initialize Serial Port With The Default Baud Rate
  syncLV();

  // Place your custom setup code here
  
}


/*********************************************************************************
 **  loop()
 **
 **  The main loop.  This loop runs continuously on the Arduino.  It 
 **  receives and processes serial commands from LabVIEW.
 **
 **  Input:  None
 **  Output: None
 *********************************************************************************/
void loop()
{   
  // Check for commands from LabVIEW and process them.   
 
  checkForCommand();
  // Place your custom loop code here (this may slow down communication with LabVIEW)
  if (Serial.available() > 0) {
                // read the incoming byte:
                incomingByte = Serial.read();
if (incomingByte == 97){  // LED Anschalten, wenn 'a' gesendet
  digitalWrite(40,HIGH);
}
else if(incomingByte == 98){  // LED ausschalten, wenn 'b' gesendet
  digitalWrite(40,LOW);
}
        }
        
       
  
  
  
  if(acqMode==1)
  {
    sampleContinously();
  }

}

Ich kenne die LabView-Sachen nicht aber schau Dir mal strtok an.

Für eine RGB-LED habe ich mal das hier geschrieben.

Gruß Tommy

Tommy56:
Ich kenne die LabView-Sachen nicht aber schau Dir mal strtok an.

Dazu muss er aber erst mal den String vernünftig in ein char Array einlesen. Am besten wie üblich mit einem LF abgeschlossen. Nach dem Einlesen kann man dann Parsen

Richtig. Das kann er sich aus dem verlinkten Beispiel raus suchen.

Gruß Tommy

Hallo,

sieh dir mal das Beispiel unter Beispiel / communication / serial Event an. da werden Zeichen eingelesen als String bis LF (enter Taste )

Den String kannst Du dann auswerten.

Rentner:
sieh dir mal das Beispiel unter Beispiel / communication / serial Event an. da werden Zeichen eingelesen als String bis LF (enter Taste )

Nein. Bitte nicht. Das verwendet ein String Objekt. Ein char Array kann man viel, viel einfacher auswerten

Vielen Dank Tommy, das sieht nach genau dem aus was ich benötige.
Dann werde ich mich damit mal auseinander setzten.

Gruß
Dave

Also ich habe das jetzt mit dem Code hinbekommen, vorerst zwei LEDs zu steuern.
Aber mir ging es ja auch nur um die Serielle Kommunikation, also danke nochmal an Tommy!! :smiley:

Jetzt würde ich gern den Kompletten Code nachvollziehen.
Probleme habe ich bei der “auswerten” Funktion.
Ich verstehe folgende Code-Schnipsel nicht:

char *ptr, *p, *savePtr, saveP; || was machen die"" bei den Variablen

ptr = strtok_r(inStr, delim, &savePtr); || In delim stehen meine “,” richtig? Und für was steht das &savePtr

Hier mein Code:

#define LED1 13
#define LED2 40

const byte IN_LEN = 20; // Puffergroesse Eingabe

boolean status = false; // Fehlerstatus true = ok, false = Error
boolean fertig = false; // Eingabe beendet
char inputChar;  // Zeichen zum Einlesen
char inStr[IN_LEN];  // Lesepuffer
int velocity = 0;
int steps = 0;
int rotation = 0;



void setup() {
  Serial.begin(9600);
  // Warten bis Serial bereit
  while (!Serial);
  Serial.println("Start");
  pinMode(LED1, OUTPUT);
  pinMode(LED2, OUTPUT);
  digitalWrite(LED1, LOW);
  digitalWrite(LED2, LOW);

  inStr[0] = '\0';  // Puffer auf leer initialisieren

}

void loop() {
  if (Serial.available() > 0)
    if (fertig = einlesen()) {
      // ganze Zeile eingelesen
      status = auswerten();
    }

  switch (velocity) {
    case 123:
      digitalWrite(LED1, HIGH);
      break;

    case 321:
      digitalWrite(LED1, LOW);
      break;
  }

    switch (steps) {
    case 456:
      digitalWrite(LED2, HIGH);
      break;

    case 654:
      digitalWrite(LED2, LOW);
      break;
  }

    switch (rotation) {
    case 789:
      digitalWrite(LED1, HIGH);
      digitalWrite(LED2, HIGH);
      break;

    case 987:
      digitalWrite(LED1, LOW);
      digitalWrite(LED2, LOW);
      break;
  }

}


boolean einlesen() {
  static byte i = 0; // Positionsindex in inStr
  // wenn es schon eine vollstaendige Eingabe gab -> zuruecksetzen
  if (fertig) {
    fertig = false;  // neuer Anfang
    inStr[0] = '\0'; // Puffer initialisieren
    i = 0; // Positiojnsindex auf Anfang
  }
  inputChar = Serial.read();
  // Wenn nicht Zeilenende und nicht Puffer voll
  if (inputChar != '#' && i < IN_LEN - 1) {
    // Zeichen in inStr schreiben
    inStr[i] = inputChar;
    inStr[++i] = '\0'; // Abschluss dahinter schreiben, um evtl. Debugausgaben richtig anzuzeigen
    return false;
  }
  return true;
}


// true = es gab mindestens einen richtigen Wert, false = kein gueltiger Wert
boolean auswerten() {
  char *ptr, *p, *savePtr, *saveP;
  const char delim[] = ",";
  char first;
  boolean status = false;
  int wert;
  // inStr zerlegen an ,
  // strtok ist nicht wiedereintrittsfähig,
  // deshalb strtok_r nehmen, um auch den Doppelpunkt auszuwerten zu koennen
  ptr = strtok_r(inStr, delim, &savePtr);
  while (ptr != NULL) {

    first = ptr[0];
    wert = atoi(ptr + 1);

    switch (first) {
      case 'v':   velocity = wert;
        status = true;
        break;
      case 's':   steps = wert;
        status = true;
        break;
      case 'r':   rotation = wert;
        status = true;
        break;
    }
/*
    Serial.print("Motorkennwert: ");
    Serial.print(first);
    Serial.print(" = ");
    Serial.println(wert);
    Serial.println();
    */

    // naechster Token. NULL, wenn nichts gefunden
    ptr = strtok_r(NULL, delim, &savePtr);
  }
/*
  Serial.print("Geschwindigkeit = ");
  Serial.println(velocity);
  Serial.print("Schritte = ");
  Serial.println(steps);
  Serial.print("Drehrichtung = ");
  Serial.println(rotation);
*/

  Serial.print("Werte: ");
  Serial.print(velocity);
  Serial.print(", ");
  Serial.print(steps);
  Serial.print(", ");
  Serial.println(rotation);

  return status;
}

Gruß
Dave

Mach Dich mal über Pointer/Zeiger kundig und schaue in die Deklaration von strtok_r.

Gruß Tommy

DaDaVee:
Jetzt würde ich gern den Kompletten Code nachvollziehen.

Dazu würde ich die Warnungen in den Voreinstellungen der IDE einschalten.

In dieser Zeile sind *p und *saveP unbenutzt:

char *ptr, *p, *savePtr, *saveP;

Zeiger: in der fünften Parklücke steht mein Auto.
Wert: mein Auto ist ein roter Käfer.