Macroschlitten

Version vom 18. Januar 2014, 16:33 Uhr von Ptflea (Diskussion | Beiträge) (Die Seite wurde neu angelegt: „{{Infobox Projekt |name = Macroschlitten |kategorie = Hardware |status = stable |autor = ptflea |beschreibung = |image …“)
(Unterschied) ← Nächstältere Version | Aktuelle Version (Unterschied) | Nächstjüngere Version → (Unterschied)
Macroschlitten

Status: stable

Beschreibung
Autor: ptflea
Version 0.5
PayPal Spenden für Macroschlitten

Stepper läuft mit 12V

Hier ist der Ardunio-Code:

#include <AFMotor.h>
#include <AccelStepper.h>

// Connect a stepper motor with 48 steps per revolution (7.5 degree)
// to motor port #2 (M3 and M4)
int incomingByte;  
char Data[8];
int i;
unsigned long Zeit;
int bewegung;
int schritte;

int motorStepsPerRev = 200;
float currentMaxSpeed = 1200.0;
float currentAcceleration = 300.0;
const int stepType = INTERLEAVE;

AF_Stepper motor1(motorStepsPerRev, 2);
AF_Stepper motor2(motorStepsPerRev, 1);


void forwarda() {  
  motor1.onestep(FORWARD, stepType);
}
void backwarda() {  
  motor1.onestep(BACKWARD, stepType);
}

AccelStepper accelA(forwarda, backwarda);


void forwardb() {  
  motor2.onestep(FORWARD, stepType);
}
void backwardb() {  
  motor2.onestep(BACKWARD, stepType);
}

AccelStepper accelB(forwardb, backwardb);

int range_in;
int byte_in[2];         // variable to store the VALID data from the port
char nextMsg;


void setup(){
 
  motor1.setSpeed(50);  // in rpm 
  motor2.setSpeed(50);  // in rpm
  
  //Accelstepper Setup
  accelA.setMaxSpeed(currentMaxSpeed);
  accelA.setAcceleration(currentAcceleration);  
  accelB.setMaxSpeed(currentMaxSpeed);
  accelB.setAcceleration(currentAcceleration);
  
  accelA.setMinPulseWidth(10);
  accelB.setMinPulseWidth(10);
  
  
  Serial.begin(9600);
  digitalWrite(13, HIGH); //turn on LED to indicate program has started
}

void loop(){
  

   do {
     // Wenn Daten verfügbar Zeichen in Data schreiben bis 4 Zeichen erreicht oder 0,5 Sekunden Warten nach dem ersten übertragenen byte
     if (Serial.available()) {
	if (i == 0)
            {
              bewegung = Serial.read();
            }
            else
            {
             Data[i-1] = Serial.read();
         }
	 i++;
	 }    
     if(i<1)Zeit = millis();
     } while (i<4&&(millis()-Zeit) < 500); //nach i< kommt die Anzahl der Zeichen
    // Serial.flush(); //empty serial buffer
       // Abschließende Null für gültigen String
     Data[i-1] = 0;    
    
     schritte = atof(Data);  // Wert von String zu Zahl wandeln wenn gewünscht
     i=0;
     decodeMessage(bewegung, schritte); 
     
}

void decodeMessage(int msg, int range){
  int faktor = 5;
  //check command type and command value
  if(bitRead(msg, 0) == 1){
    //Bit 1 = High   DOWN (1)
   // motor1.step(faktor, FORWARD, INTERLEAVE); 
    	accelA.move(-range);
	accelA.runToPosition();
  }
  if(bitRead(msg, 1) == 1){
    //Bit 2 = High   UP (2)
    //motor1.step(faktor, BACKWARD, INTERLEAVE); 
	accelA.move(range);
	accelA.runToPosition(); 
  }
  if(bitRead(msg, 2) == 1){
    //Bit 3 = High   LEFT (4)
    motor1.step(faktor, FORWARD, INTERLEAVE); 
  }
  if(bitRead(msg, 3) == 1){
    //Bit 4 = High   RIGHT (8)
    motor1.step(faktor, BACKWARD, INTERLEAVE); 

  }
  if((msg & 15) == 0){
    //Bit 1-4 = Low
    //sendMsg(000); //send a message back for testing purposes
  }
  sendMsg(msg, range);
}



void sendMsg(int msg, int range){
  /* Processing uses Serial.buffer(4) to read the messages it receives,
   * meaning that messages of 4 bytes long should be sent.
   * Arduino sends integers as Strings, so to ensure 4 characters are sent
   * for each message, I check the size of the integer to send and add zeroes
   * as needed (zeroes ensure that the received message can easily be cast
   * to an integer by Processing, which would not be the case with other, non-numerical, characters)
   */
  //if(Serial.available() > 0) Serial.flush();
//  if(msg < 1000) Serial.print(0);
//  if(msg < 100) Serial.print(0);
//  if(msg < 10) Serial.print(0);
  //delay(1000); 
  
  Serial.print(range); //...send a confirmation
  Serial.println(msg);
 
}


Hier ist der Processing-Code:

import processing.serial.*;

Serial myPort;
PFont font;

String Schritte = "333";
int msgQueue[]; //the message queue
boolean msgLock; //message lock, active until last message is confirmed
int lstMsg; //last message sent
int schritt = 125;

void setup(){
  size(400, 300);
  background(0);
  font = createFont("Verdana", 14);
  
  msgQueue = new int[0];
  
  
  println(Serial.list());
 myPort = new Serial(this, Serial.list()[Serial.list().length - 1], 9600); //the highest connected COM port is always my Arduino
  //myPort.buffer(4); //buffer 4 bytes of data before calling serialEvent()
  myPort.bufferUntil('\n');

}

void draw(){
  background(0);
  textFont(font, 14);
  text("Taste 8: vorwärts\nTaste 7: weit vorwärts\n\nTaste 2: zurück\nTaste 1: weit zurück\n\n9 -> Schritt erhöhen\n3 -> Schritt verkleinern", 25, 25);
  text("Schritte: " + schritt, 25, 230);
  parseQueue();
}

void keyPressed(){
  if(int(key) == 50){// Taste 2 DOWN
    queueMessage(2); //
    //Schritte = Integer.toString(schritt);
    queueMessage(schritt);
  }
    if(int(key) == 56){// Taste 8 UP
    queueMessage(1); // 
    //Schritte = Integer.toString(schritt);
     queueMessage(schritt);
  }
    if(int(key) == 51){// Taste 3 Schritt verkleinern
    schritt = schritt - 5;
  }
    if(int(key) == 57){// Taste 9 Schritt erhöhen
    schritt = schritt + 5;
  }
    if(int(key) == 55){ //Taste 7 Grosser Schritt UP
    queueMessage(1); // 
    queueMessage(600);
  }
    if(int(key) == 49){ //Taste 1 Grosser Schritt DOWN
    queueMessage(2); // 
    queueMessage(600);
  }
}

/* serialEvent(Serial myPort)
 * called when the amount of bytes specified in myPort.buffer()
 * have been transmitted, converts serial message to integer,
 * then sets this value in the chair object
 */
void serialEvent(Serial myPort){
  if(myPort.available() > 0){
    
    String message = myPort.readString(); //read serial buffer
    int msg = int(message); //convert message to integer
    println(msgQueue.length);
    myPort.clear(); //clear whatever might be left in the serial buffer
    //msgLock = false;
     if(msg == 0){
      println("Anweisung durchgeführt");
      msgLock = false;
    }
  }
}

private void writeSerial(int msg){
  if(myPort.available() > 0) myPort.clear(); //empty serial buffer before sending
  myPort.write(msg);
}

public void queueMessage(int msg){
  msgQueue = append(msgQueue, msg);
}

private void parseQueue(){
  
    if(msgQueue.length > 0 && !msgLock) {
      msgLock = true; //lock queue, preventing new messages from being sent
      lstMsg = msgQueue[0]; //queue the first message on the stack
      writeSerial(lstMsg); // sende richtungsbefehl
      println("writing Richtung: " + lstMsg);
            
      msgQueue = subset(msgQueue, 1); // letzten befehl löschen
      
      lstMsg = msgQueue[0]; //queue the first message on the stack
      Schritte = Integer.toString(lstMsg);
      myPort.clear();
      myPort.write(Schritte);// sende Schrittzahl
      println("writing Schritte: " + lstMsg);
      
      msgQueue = subset(msgQueue, 1); // letzten befehl löschen
    }

}