Sensordaten nur alle 10 sek im ser. Monitor

Hallo,

ich habe eine selbstgebaute Fräse (shapeoko2). Diese soll aber nicht fräsen sondern fotografieren. So weit ist alles fertig. Sie bewegt die y- und x-Achse wie ich es will, und der Sharp-Infrarotsensor kann die Z-Achse auf den gewünschten Abstand zum Objekt bringen. Nach dem Zusammenbasteln der Codes bekomme ich über den ser. Monitor nur noch alle 10 sek einen Wert.

Kann mir jemand sagen warum das so ist und wie ich es lösen kann? :confused:

Vielen Dank.

Hier der Code:

const int dirPin_X = 5;
const int stepperPin_X = 2;

const int dirPin_Y = 6;
const int stepperPin_Y = 3;

const int dirPin_Z = 7;
const int stepperPin_Z = 4;

const int sharpPin = A0;
int sharp_Messwert_volt = 0;
int Vorgabewert_mm = 90;

void setup(){
  Serial.begin (9600);
    
  pinMode(dirPin_X, OUTPUT);
  pinMode(stepperPin_X, OUTPUT);
  pinMode(dirPin_Y, OUTPUT);
  pinMode(stepperPin_Y, OUTPUT);
  pinMode(dirPin_Z, OUTPUT);
  pinMode(stepperPin_Z, OUTPUT);
  }

void step_1(boolean dir, int steps){
  digitalWrite(dirPin_X,dir);
  delay(50);
  for(int i=0;i<steps;i++){
    digitalWrite(stepperPin_X, HIGH);
    delayMicroseconds(600);
    digitalWrite(stepperPin_X, LOW);
    delayMicroseconds (600);
    }
}
void step_2(boolean dir, int steps){
  digitalWrite(dirPin_Y,dir);
  delay(50);
  for(int i=0;i<steps;i++){
    digitalWrite(stepperPin_Y, HIGH);
    delayMicroseconds(600);
    digitalWrite(stepperPin_Y, LOW);
    delayMicroseconds (600);
   }
}
void step_3(boolean dir, int steps){
  digitalWrite(dirPin_Z,dir);
  delay(50);
  for(int i=0;i<steps;i++){
    digitalWrite(stepperPin_Z, HIGH);
    delayMicroseconds(600);
    digitalWrite(stepperPin_Z, LOW);
    delayMicroseconds (600);
   }
}

void loop(){

  step_1(true,3000);
  delay(100);
  step_2(true,100);
  delay(100);
  step_1(false,3000);
  delay(100);
  step_2(true,100);
  delay(100);


  sharp_Messwert_volt = analogRead(sharpPin);
  Serial.print("Messwert: "); Serial.print(sharp_Messwert_volt); Serial.print(" ");
  int sharp_Messwert_mm = (207600 / (sharp_Messwert_volt-11))/10;

  sharp_Messwert_mm = constrain(sharp_Messwert_mm, 50, 130); 
  Serial.print("abs. Abstand: "); Serial.print(sharp_Messwert_mm); Serial.print("mm ");
  Serial.print("rel. Abstand: "); Serial.print(sharp_Messwert_mm - Vorgabewert_mm); Serial.println(" mm");
    
  if (sharp_Messwert_mm == 130)//umgerechneter Messwert ist gleich 130
  {step_3(true,0);}    
  else if (sharp_Messwert_mm == 50)//umgerechneter Messwert ist gleich 50
  {step_3(true,0);}    
  else if (sharp_Messwert_mm == 90)
  {step_3(true,0);}
  else if (sharp_Messwert_mm > 90) //umgerechneter Messwert ist größer als 90
  {step_3(true,51);}
  else if (sharp_Messwert_mm < 90) //umgerechneter Messwert ist kleiner als 90
  {step_3(false,51);} 
  delay (20);
  }

das liegt sehr wahrscheinlich an deinen zahlreichen delays in deinem Code. Die musst du durch millis (BlinkWithoutDelay) ersetzen.

Hallo,

beim drüber schauen sieht man das Dein Sketch fast nur aus festen delay Zeiten besteht. Diese summieren sich in den for Schleifen gnadenlos auf und ergeben die 10sek.. Du müßtest alle delays rauswerfen und durch millis() Abfragen ersetzen.

Lesestoff von mir zum Thema: Anleitung Endlicher Automat mit millis()

Hallo,

Vielen Dank für die Antworten und Entschuldigung dafür, das ich bis jetzt keine Rückmeldung gegeben habe. Tatsächlich ist millis() die Lösung. Aber der Übergang von delay auf millis() fällt mir echt schwer. :confused:

Ich habe mich erst einmal auf die Bewegung der Achsen konzentriert, den Sensor also vorläufig rausgeworfen.

// Achsen Belegung der Ausgänge
int dirPin_X = 5;
int stepperPin_X = 2;

int dirPin_Y = 6;
int stepperPin_Y = 3;

int dirPin_Z = 7;
int stepperPin_Z = 4;

// Bewegung der Achsen für 3 Sek
unsigned long  move_x = 3000;
unsigned long  move_y = 3000;
unsigned long  move_z = 3000;
long previousMillis = 0;

void setup(){
  Serial.begin (9600);
    
  pinMode(dirPin_X, OUTPUT);
  pinMode(stepperPin_X, OUTPUT);
  pinMode(dirPin_Y, OUTPUT);
  pinMode(stepperPin_Y, OUTPUT);
  pinMode(dirPin_Z, OUTPUT);
  pinMode(stepperPin_Z, OUTPUT);

  }

void loop(){
    unsigned long currentMillis = millis();

    if(currentMillis - previousMillis > move_x){
      previousMillis = currentMillis;
      digitalWrite(stepperPin_X, HIGH);
      digitalWrite(stepperPin_X, LOW);
      }
    else if (currentMillis - previousMillis > move_y){
      previousMillis = currentMillis;
      digitalWrite(stepperPin_Y, HIGH);
      digitalWrite(stepperPin_Y, LOW);
      }
    else if (currentMillis - previousMillis > move_z){
      previousMillis = currentMillis;
      digitalWrite(stepperPin_Z, HIGH);
      digitalWrite(stepperPin_Z, LOW);

    }
}

Es sollen sich die Achsen nacheinander für jeweils 3 Sekunden bewegen. Die Richtung stimmt: ich höre von den Motoren ein sehr leisesFiepen, das alle 3 Sekunden die Tonlage ändert. Die X-Achse zuckt etwas, mehr aber nicht. Kann jemand den Fehler sehen?

Vielen Dank Jan

MakroPix: Vielen Dank für die Antworten und Entschuldigung dafür, das ich bis jetzt keine Rückmeldung gegeben habe.

Besser spät, als nie :)

Ich denke, das ist etwas zu schnell für Deinen Motor. Versuch mal dies bei allen Achsen:

      digitalWrite(stepperPin_X, HIGH);
      delay(10);
      digitalWrite(stepperPin_X, LOW);
      delay(10);

Wenn sich die Achsen irgendwie drehen, sich meine Vermutung also bestätigt, geht es dann an die Details.

Hallo agmue,

es ändert sich nichts…Das Fiepen war schon vorher sehr leise. Die Motorimpulse sind zu spüren.

Viele Grüße
Jan

delay (100), (1000) und (1) ändert auch nichts.

void loop(){
    unsigned long currentMillis = millis();
 
    if(currentMillis - previousMillis > move_x){
      previousMillis = currentMillis;
      digitalWrite(stepperPin_X, HIGH);
      digitalWrite(stepperPin_X, LOW);
      }
    else if (currentMillis - previousMillis > move_y){
      previousMillis = currentMillis;
      digitalWrite(stepperPin_Y, HIGH);
      digitalWrite(stepperPin_Y, LOW);
      }
    else if (currentMillis - previousMillis > move_z){
      previousMillis = currentMillis;
      digitalWrite(stepperPin_Z, HIGH);
      digitalWrite(stepperPin_Z, LOW);

    }
}

Das wird so auch nicht funktionieren, in der Regel wird nur der erste Fall abgearbeitet.

void loop(){
 static uint32_t lastMillis = 0;
 uint32_t currentMillis = millis();
 unsigned long currentMillis = millis();
 static uint8_t step = 1; // einmal gesetzt
 
 
 if(currentMillis - lastMillis >= 3000 && step > 0){
 lastMillis = currentMillis;
 if(++step == 3) step = 0;
 }
 
 switch(step)
 {
 case 0:
 /* Wenn ein Taster gedrueckt wird, kann step auf 0 gesetzt werden zum erneuten Start */
 /* lastMillis = currentMillis; */
 break;
 
 case 1:
 digitalWrite(stepperPin_Y, 1);
 delaymicroseconds(600);
 digitalWrite(stepperPin_Y, 0);
 break;
 
 case 2:
 /* .. */
 }
}

MakroPix:
es ändert sich nichts…Das Fiepen war schon vorher sehr leise. Die Motorimpulse sind zu spüren.

Sorry, ich hatte übersehen, daß der Motor nur alle 3 Sekunden einen Schritt macht :frowning: Mit unsigned long move_x = 30; kommt Bewegung in den Motor, habe es probiert.

Das ist aber noch nicht, was Du möchtest.

Einmalig 3 Sekunden geht so:

void loop() {
  unsigned long currentMillis = millis();

  if (currentMillis - previousMillis <= move_x) {
    
    digitalWrite(stepperPin_X, HIGH);
    delayMicroseconds(600);
    digitalWrite(stepperPin_X, LOW);
    delayMicroseconds(600);
  }
}

Das Fiepen kommt vom Haltestrom, der durch den Stepper fließt.

@agmue,

die x-Achse läuft tatsächlich jetzt 3 Sekunden...sehr gut, danke. Die y-Achse und die z-Achse bleiben ruhig. Aber trotzdem.... endlich mal ne Bewegung.

Ich probiere jetzt mal den Vorschlag von sschultewolter.

Viele Grüße

@sschultewolter

Was passiert:
Die Y-Achse fährt 3 Sekunden ins Minus mit schöner Geschwindigkeit
Dann startet die X-Achse in Minus-Richtung mit derselben Geschwindigkeit aber ohne zu stoppen.

Allerdings sind uint8_t und uint32_t nicht farbig hinterlegt, also auch nicht aktiv(?). Ich habe uint8_t mit byte ersetzt. Ist das OK? Gibt es eine Alternative zu uint32_t?

#include <Arduino.h>
// Achsen Belegung der Ausgänge
int dirPin_X = 5;
int stepperPin_X = 2;

int dirPin_Y = 6;
int stepperPin_Y = 3;

int dirPin_Z = 7;
int stepperPin_Z = 4;

// Bewegung der Achsen für 3 Sek

void setup(){
  Serial.begin (9600);
    
  pinMode(dirPin_X, OUTPUT);
  pinMode(stepperPin_X, OUTPUT);
  pinMode(dirPin_Y, OUTPUT);
  pinMode(stepperPin_Y, OUTPUT);
  pinMode(dirPin_Z, OUTPUT);
  pinMode(stepperPin_Z, OUTPUT);

  }

void loop()
{
  static uint32_t lastMillis =0;  
  unsigned long currentMillis = millis();
  //uint32_t currentMillis = millis(); --> ergibt Fehlermeldung "redeclaration of 'uint32_t currentMillis"
  static byte_t step = 1; //einmal gesetzt//uint8_t mit byte ersetzten?
  
  
  if(currentMillis - lastMillis >= 3000 && step >0)
  if(++step ==3) step = 0;
  {
    switch (step)
    {
      case 0:
      digitalWrite(stepperPin_X, 1);
      delayMicroseconds(600);
      digitalWrite(stepperPin_X, 0);
      delayMicroseconds(600);
      break;
      
      case 1:
      digitalWrite(stepperPin_Y, 1);
      delayMicroseconds(600);
      digitalWrite(stepperPin_Y, 0);
      delayMicroseconds(600);
      break;
      
      case 2:
      digitalWrite(stepperPin_Z, 1);
      delayMicroseconds(600);
      digitalWrite(stepperPin_Z, 0);
      delayMicroseconds(600);
      break;
      }
   }
}

Gibt es eine Alternative zu uint32_t

unsigned long

nicht farbig hinterlegt, also auch nicht aktiv(?).

Die Farbgebung ist mehr oder weniger Spass, hat nicht viel zu sagen.

Nenn mal eine Variable 'status' ;)

Wenn du 'richtige' Programmierunterstützung mit Syntax-Highlighting willst, besorg dir Visual Studio und das VisualMicro Plugin.

Ist zwar nicht free (open source), aber gratis (Microsoft Community Edition und bei VisualMicro die Reklame ignorieren).

Sollte auch ohne VisualMicro im neuen Visual Studio (7) gehen.
Der Code sieht da dann in etwa so aus

/*Begining of Auto generated code by Atmel studio */
#include <Arduino.h>

/*End of auto generated code by Atmel studio */


//Beginning of Auto generated function prototypes by Atmel Studio
void setup();
void loop();
//End of Auto generated function prototypes by Atmel Studio
void setup() {
	// put your setup code here, to run once:
	pinMode(13, OUTPUT);
}

void loop() {
	// put your main code here, to run repeatedly:
	digitalWrite(13, 0);
	delay(500);
	digitalWrite(13, 1);
	delay(500);
}

Hab gerade nur keinen hier rumliegen um den Upload zu testen. Mit dem AVRISP mkii sollte es gehen, ob die onBoard Programmer unterstützt werden, weiß ich nicht.

Visual Studio gibts schon in Version 2015, Version 7 muss schon ziemlich alt sein.

Syntax Highlighting in sattem schwarz auf matt-weissem Grund sieht schon edel aus.

Sorry, ich meinte Atmel Studio 7! Das nutzt die 2015er Shell von Visual Studio.

Gerade dieser mattschwarze Hintergrund war ein Wechselgrund von Atmel Studio 6 auf 7. Habe ansonsten eigentlich auch nur mit Visual Studio 2015 zu tun, und es ist einfach deutlich angenehmer zu lesen.

Screenshot 2015-10-15 14.24.05.png

Hallo,

das hat echt lange gedauert bis es bei mir “klick” gemacht hat. Der folgende Code bewegt alle Achsen der Fräse ohne nennenswerte Delay-Blockaden. Mann kann die Geschwindigkeit, die Bewegungsrichtung und die Länge der einzelnen Bewegungen einstellen.
Der Code basiert auf dem “Endlichen Automaten” von Agmue und einigen guten Tips von sschultewolter. Vielen Dank dafür.

#include <Arduino.h>

int dirPin_X = 5;
int stepperPin_X = 2;

int dirPin_Y = 6;
int stepperPin_Y = 3;

int dirPin_Z = 7;
int stepperPin_Z = 4;

unsigned long move_x =1000;
unsigned long move_y =500;
unsigned long move_z =500;
unsigned long interval;

void setup()
{
  Serial.begin (9600);
  pinMode(dirPin_X, OUTPUT);
  pinMode(stepperPin_X, OUTPUT);
  pinMode(dirPin_Y, OUTPUT);
  pinMode(stepperPin_Y, OUTPUT);
  pinMode(dirPin_Z, OUTPUT);
  pinMode(stepperPin_Z, OUTPUT);
  }
  
void loop()
{     
  static unsigned long lastMillis = 0;
  unsigned long currentMillis = millis();
  static byte step = 0;
 
  if(currentMillis - lastMillis >= interval)
  {
    lastMillis = currentMillis;
      if (++step ==4) step =1;
    } 
    switch (step)
    {
      case 1:
      digitalWrite(dirPin_X, 1);
      digitalWrite(stepperPin_X, 1);
      delayMicroseconds(300);
      digitalWrite(stepperPin_X, 0);
      delayMicroseconds(300);
      interval = move_x;
      break;
            
      case 2:
      digitalWrite(dirPin_Y, 1);
      digitalWrite(stepperPin_Y, 1);
      delayMicroseconds(300);
      digitalWrite(stepperPin_Y, 0);
      delayMicroseconds(300);
      interval = move_y;      
      break;
      
      case 3:
      digitalWrite(dirPin_Z, 1);
      digitalWrite(stepperPin_Z, 1);
      delayMicroseconds(700);
      digitalWrite(stepperPin_Z, 0);
      delayMicroseconds(700);
      interval = move_z;
      break;
      }
   }

Als nächstes steht die Übernahme der Sensordaten und deren Kopplung an die Z-Achse an. Aber das wird ein neuer Thread.