Falsche Messwerte

Hallo, ich verwende einen Mega 2560 um über ein Controllerboard einen DC Motor zu steuern. Das läuft über Hardware Serial1 beim Mega. Gleichzeitig lese ich einen Messschieber aus. Ich möchte nun Statusmeldungen des Motorcontrollers und Messwerte des Messschiebers über USB (Serial) auf ein Terminal am PC ausgeben.
Im Grunde genommen klappt das, jedoch zeigt der Messschieber im seriellen Terminal sporadisch unsinnige/falsche Werte an, obwohl er nicht verstellt wird. Die Motorcontrollerwerte und Messdaten werden in der loop ausgelesen und mit Serial.print ausgegeben.
Das Terminal zeigt mir brav die Positionsdaten des Motorcontrollers an, jedoch sporadisch Falschwerte des Messmittels. Kürze ich nun den Sketch und lasse mir nur die Messdaten des Schiebers anzeigen, passen alle Werte. Leider unterstützt der Controller nur 9600 baud, sonst hätte ich da mal getestet.

Was kommt sich da in die Quere wenn beide Sachen laufen?

Hier schematisch der Sketch

........ blabla 

void setup(){

............ blabla

	Serial1.begin(9600);
	Serial.begin(9600); 
}

	  
void loop()
{
Position(100); // Motor positionieren über Serial1 auf 100
    
    while (pos < 100){

    Serial.println(pos);
      
    getData1();
}
	
Position(1); // Motor positionieren über Serial1 auf 1
    
    while (pos > 100)

        {
 
      Serial.println(pos);
      
      getData1();
	  }	  
	  
void getData1() // daten messschieber
{

    digitalWrite(req, HIGH); // generate set request

for(i = 0; i < 13; i++ ) {

k = 0;

for (j = 0; j < 4; j++) {

while( digitalRead(clk) == LOW) { // hold until clock is high

}

while( digitalRead(clk) == HIGH) { // hold until clock is low

}

bitWrite(k, j, (digitalRead(dat) & 0x1)); // read data bits, and reverse order )

}


mydata[i] = k;


}

// assemble measurement from bytes

char buf[7];
for(int lp=0;lp<6;lp++)

buf[lp]=mydata[lp+5]+'0';
buf[6]=0;


num=atol(buf);

int temp = mydata[4];
  
Serial.println(num);
}

ohne das jetzt genauer analysiert zu haben, denke ich, da sind wwhile Schleifen drin, die zu lange blockieren.

Wie groß sind denn die Sprünge? Ich nehme mal an die Messwerte werden Analog eingelesen? Da gibts immer kleine Spannungssprünge. Bau dir doch einfach einen kleinen Filter, der die Sprünge ausgleicht.

Ich habe es per map gemacht für meine Motoren.

val = map(input_a0, 0, 850, 0, 80);

Du musst dann selbst entscheiden wie stark du die Motoren steuern willst, ich nehme an, dass du das ganze per PWM steuerst. Einfach die Werte wieder mit zB. 10 multiplizieren und etwas herum spielen bis die Sprünge gering genug sind und es für deine Motoren passt.

Mir fehlt da ein digitalWrite(req,LOW) nach dem Auslesen. Wenn Du Dich da einmal mit den Bits verhedderst, wie willst Du Dich mit der Ausgabe wieder synchronisieren?

Moin zusammen, danke für eure Tipps,

vielleicht hab ich den Auslöser gefunden. Ich verwende zur Anzeige der Werte und zur Steuerung des Mega das Programm Megunolink Pro. Zum Testen habe ich den Sketch mal Stück für Stück heruntergekürzt, um eine Fehlerquelle ausmachen zu können.

Der Test ergab: In der Grundform, so wie in meinem Post beschrieben, läuft der Sketch einwandfrei und zeigt fortlaufend ausschließlich korrekte Werte an. Sobald ich jedoch die Steuerung mit MLP übernehme und mir die Daten dort anzeigen lasse, bekomme ich die Fehlwerte. Ich werde dem Entwickler von MLP mal das Problem schildern. Mal sehn, was er dazu meint.

dr_nobody:
... Ich werde dem Entwickler von MLP mal das Problem schildern. Mal sehn, was er dazu meint.

Super Idee!

Dafür bekommst Du einen Eimer Karma von mir :slight_smile:

Gruß

Gregor

Ich habe ein ähnliches Problem mit sporadisch falschen Messwerten. Die Messwerte kommen über eine RS232-Schnittstelle von einem Laserdistanzmodul rein.

Das Distanzmodul gibt jedoch alle Werte korrekt her, ich nutze das angesprochene Programm nicht.

int start = 47;
int fehler = 46;
int distanz1 = 45;
int distanz2 = 44;
int distanz3 = 43;
int distanz4 = 42;
int distanz5 = 41;
int distanz6 = 40;


char eingabe[12];

float arbeitswert;
float halteposition;

boolean Endposition = true;


void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  Serial2.begin(9600);
  Serial.println("Setup abgeschlossen!");
  //Serial2.println("DW");
  pinMode(start, OUTPUT);
  pinMode(fehler, OUTPUT);
  pinMode(distanz1, OUTPUT);
  pinMode(distanz2, OUTPUT);
  pinMode(distanz3, OUTPUT);
  pinMode(distanz4, OUTPUT);
  pinMode(distanz5, OUTPUT);
  pinMode(distanz6, OUTPUT);
}

boolean datenEinlesen() {
  static byte count = 0;
  char c;
  if (Serial.available() == 0) return false; // Falls nichts ankommt
  if (count == 0) memset(eingabe, 0, sizeof(eingabe)); // Puffer von eingabe leeren
  c = Serial.read();
  if (c == 13) // Wenn ein Zeilenumbruch erkannt wurde
  {
    eingabe[count] = '\0';
    count = 0;
    return true; // Zeilenumbruch(CR) erkannt = Eingabe vollständig
  }
  else if (c > 32 && count < sizeof(eingabe) - 1)
  {
    eingabe[count] = c;
    count++;
  }
  else; // Ignoriere alle anderen Steuerzeichen
  return false;
}


float messwertErfassen() {
  String inString;
  while (Serial2.available() > 0) { //Solange Daten kommuniziert werden, tue folgendes
    char inChar = Serial2.read();
    if (inChar != 13) {           //Falls kein Carriage return erscheint
      inString += (char)inChar;   //Addiere den char zum String
    } else {
      //Serial.print("Messung ergab: ");
      //Serial.print(inString);
      //Serial.println(" m");
      arbeitswert = inString.toFloat();
      //Serial.println(arbeitswert);
      return arbeitswert;
      inString = "";
    }
  }

}

void loop() {
  // put your main code here, to run repeatedly:

  if (datenEinlesen()) {
    if (strcmp(eingabe, "reset") == 0) {
      Serial2.println("LF");
      digitalWrite(start, LOW);
      digitalWrite(fehler, LOW);
      digitalWrite(distanz6, LOW);
      digitalWrite(distanz5, LOW);
      digitalWrite(distanz4, LOW);
      digitalWrite(distanz3, LOW);
      digitalWrite(distanz2, LOW);
      digitalWrite(distanz1, LOW);
      Endposition = true;
      Serial.println("RESET-----RESET-----RESET");
    } else if (strcmp(eingabe, "x") == 0) {
      Endposition = true;
      Serial.println("PC-Konnektivität hergestellt");
    } else if (strcmp(eingabe, "start") == 0) {
      Serial2.println("DW");
      Serial.println("Laser aktiv, warte auf Zielwert");
    } else {
      Endposition = false;
      digitalWrite(start, LOW);
      digitalWrite(fehler, LOW);
      digitalWrite(distanz6, LOW);
      digitalWrite(distanz5, LOW);
      digitalWrite(distanz4, LOW);
      digitalWrite(distanz3, LOW);
      digitalWrite(distanz2, LOW);
      digitalWrite(distanz1, LOW);
    }
  }


  if (Endposition == false) {
    halteposition = atof(eingabe);
    messwertErfassen();
    delay(100);
    Serial.print("Halteposition ist ");
    Serial.println(halteposition);
    Serial.print("Arbeitswert ist ");
    Serial.println(arbeitswert);

    float abstand1 = 2;   //15  verkleinert auf Raummaße
    float abstand2 = 1.5; //5
    float abstand3 = 1;
    float abstand4 = 0.5;
    float abstand5 = 0.2;
    float abstand6 = 0.1;
    //######################################################################################


    if (arbeitswert >= (halteposition + abstand2) and (arbeitswert <= halteposition + abstand1)) {
      digitalWrite(distanz1, HIGH);
      Serial.println("DISTANZ ZWISCHEN x+2 und x+1,5 METER");
    } else if (arbeitswert < (halteposition + abstand2) and (arbeitswert >= (halteposition + abstand3))) {
      digitalWrite(distanz2, HIGH);
      Serial.println("DISTANZ ZWISCHEN x+1,5 und x+1 METER");
    } else if (arbeitswert < (halteposition + abstand3) and (arbeitswert >= (halteposition + abstand4))) {
      digitalWrite(distanz3, HIGH);
      Serial.println("DISTANZ ZWISCHEN x+1 und x+0,5 METER");
    } else if (arbeitswert < (halteposition + abstand4) and (arbeitswert >= (halteposition + abstand5))) {
      digitalWrite(distanz4, HIGH);
      Serial.println("DISTANZ ZWISCHEN x+0,5 und x+0,2 METER");
    } else if (arbeitswert < (halteposition + abstand5) and (arbeitswert >= (halteposition + abstand6))) {
      digitalWrite(distanz5, HIGH);
      Serial.println("DISTANZ ZWISCHEN x+0,2 und x+0,1 METER");
    } else if (arbeitswert < (halteposition + abstand6)) {
      digitalWrite(distanz6, HIGH);
      Serial.println("DISTANZ UNTER x+0,1 METER");
    } else {

      digitalWrite(start, LOW);
      digitalWrite(fehler, LOW);
      digitalWrite(distanz6, LOW);
      digitalWrite(distanz5, LOW);
      digitalWrite(distanz4, LOW);
      digitalWrite(distanz3, LOW);
      digitalWrite(distanz2, LOW);
      digitalWrite(distanz1, LOW);

    }


    if (arbeitswert == halteposition) {
      digitalWrite(start, HIGH);
      Serial.println("Zug steht");
      messwertErfassen();
      Serial.print(arbeitswert);
      delay(50);
      if (arbeitswert == halteposition) {
        Serial.println(" m Abschlussposition");
        Endposition = true;
      }

    }

    if (arbeitswert >= 75 || arbeitswert <= 0) { //Entfernungsgrenzen
      Serial.println("Fehler");
      digitalWrite(fehler, HIGH);
      messwertErfassen();
      if (arbeitswert >= 75 || arbeitswert <= 0) {
        Endposition = true;
        Serial.write("RESET");
      }

      else {
        Serial.print(arbeitswert);
        Serial.println(" m ist der letzte Arbeitswert");

      }
    }
    //######################################################################################1
  }
}