Macroschlitten

Crystal Clear action run.png
Macroschlitten

Status: stable

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

Stepper läuft mit 12V

Hier ist der Ardunio-Code:

Hier ist der Processing-Code:

  1import processing.serial.*;
  2
  3Serial myPort;
  4PFont font;
  5
  6String Schritte = "333";
  7int msgQueue[]; //the message queue
  8boolean msgLock; //message lock, active until last message is confirmed
  9int lstMsg; //last message sent
 10int schritt = 125;
 11
 12void setup(){
 13  size(400, 300);
 14  background(0);
 15  font = createFont("Verdana", 14);
 16  
 17  msgQueue = new int[0];
 18  
 19  
 20  println(Serial.list());
 21 myPort = new Serial(this, Serial.list()[Serial.list().length - 1], 9600); //the highest connected COM port is always my Arduino
 22  //myPort.buffer(4); //buffer 4 bytes of data before calling serialEvent()
 23  myPort.bufferUntil('\n');
 24
 25}
 26
 27void draw(){
 28  background(0);
 29  textFont(font, 14);
 30  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);
 31  text("Schritte: " + schritt, 25, 230);
 32  parseQueue();
 33}
 34
 35void keyPressed(){
 36  if(int(key) == 50){// Taste 2 DOWN
 37    queueMessage(2); //
 38    //Schritte = Integer.toString(schritt);
 39    queueMessage(schritt);
 40  }
 41    if(int(key) == 56){// Taste 8 UP
 42    queueMessage(1); // 
 43    //Schritte = Integer.toString(schritt);
 44     queueMessage(schritt);
 45  }
 46    if(int(key) == 51){// Taste 3 Schritt verkleinern
 47    schritt = schritt - 5;
 48  }
 49    if(int(key) == 57){// Taste 9 Schritt erhöhen
 50    schritt = schritt + 5;
 51  }
 52    if(int(key) == 55){ //Taste 7 Grosser Schritt UP
 53    queueMessage(1); // 
 54    queueMessage(600);
 55  }
 56    if(int(key) == 49){ //Taste 1 Grosser Schritt DOWN
 57    queueMessage(2); // 
 58    queueMessage(600);
 59  }
 60}
 61
 62/* serialEvent(Serial myPort)
 63 * called when the amount of bytes specified in myPort.buffer()
 64 * have been transmitted, converts serial message to integer,
 65 * then sets this value in the chair object
 66 */
 67void serialEvent(Serial myPort){
 68  if(myPort.available() > 0){
 69    
 70    String message = myPort.readString(); //read serial buffer
 71    int msg = int(message); //convert message to integer
 72    println(msgQueue.length);
 73    myPort.clear(); //clear whatever might be left in the serial buffer
 74    //msgLock = false;
 75     if(msg == 0){
 76      println("Anweisung durchgeführt");
 77      msgLock = false;
 78    }
 79  }
 80}
 81
 82private void writeSerial(int msg){
 83  if(myPort.available() > 0) myPort.clear(); //empty serial buffer before sending
 84  myPort.write(msg);
 85}
 86
 87public void queueMessage(int msg){
 88  msgQueue = append(msgQueue, msg);
 89}
 90
 91private void parseQueue(){
 92  
 93    if(msgQueue.length > 0 && !msgLock) {
 94      msgLock = true; //lock queue, preventing new messages from being sent
 95      lstMsg = msgQueue[0]; //queue the first message on the stack
 96      writeSerial(lstMsg); // sende richtungsbefehl
 97      println("writing Richtung: " + lstMsg);
 98            
 99      msgQueue = subset(msgQueue, 1); // letzten befehl löschen
100      
101      lstMsg = msgQueue[0]; //queue the first message on the stack
102      Schritte = Integer.toString(lstMsg);
103      myPort.clear();
104      myPort.write(Schritte);// sende Schrittzahl
105      println("writing Schritte: " + lstMsg);
106      
107      msgQueue = subset(msgQueue, 1); // letzten befehl löschen
108    }
109
110}


Knitty: passap Firmware

//////////////////////////////////////////////////////////////////////////////
// Knitty Project
//
// Author: ptflea, schinken
//

//Servo
#include <Servo.h> 

Servo servoColour12;  // create servo object to control a servo 
Servo servoColour34;

#define INT_ENCODER 0
#define INT_IFDR    1

//////////////////////////////////////////////////////////////////////////////
// General purpose definitions

#define PIN_IFDR      3         // Green
#define PIN_CSENSE    2         // Yellow
#define PIN_CREF      4         // White
#define PIN_NEEDLE_RTL    5         // Blue,  Pattern RTL
#define PIN_NEEDLE_LTR    6         // ,  Pattern LTR
#define PIN_BUTTON_1  7         // Button_1 (activate colour change)
#define BUTTONDELAY   20        // delay for Button_1 
// PIN 8 and 9 are for the color change servos
#define PIN_Eyelet_1  10        // Eyelet_1 status
#define Eyelet_1_DELAY   100
#define PIN_Eyelet_2  11        // Eyelet_2 status
#define PIN_Eyelet_3  12        // Eyelet_3 status
#define PIN_Eyelet_4  13        // Eyelet_4 status


long buttonLastChecked = 0; // variable to limit the button getting checked every cycle
int button_1_State = 0;     // status of button_1
int button_1_Hold = 0; // toggle state of Button_1

long eyelet_1_LastChecked = 0;
int eyelet_1_State = 0;
int eyelet_1_Hold = 0;

#define DIRECTION_UNKNOWN       0
#define DIRECTION_LEFT_RIGHT   -1
#define DIRECTION_RIGHT_LEFT    1

char currentDirection = DIRECTION_UNKNOWN;
char lastDirection = DIRECTION_UNKNOWN;

signed int currentCursorPosition = 0;
signed int lastCursorPosition = 0;
signed int leftEndCursorPosition = 0;
unsigned int currentPatternIndex = 0;
signed int firstNeedle = 0;
signed int offsetCarriage_RTL = 52;
signed int offsetCarriage_LTR = 46;


volatile unsigned char knitPattern[255] = {
  0};
bool isKnitting = false;

//////////////////////////////////////////////////////////////////////////////
// Knitty Serial Protocol

// Receive commands
#define COM_CMD_PATTERN      'P'
#define COM_CMD_PATTERN_END  'E'
#define COM_CMD_CURSOR       'C'
#define COM_CMD_IFDR         'I'
#define COM_CMD_RESPONSE     'R'
#define COM_CMD_DIRECTION    'D'
#define COM_CMD_DEBUG        'V'
#define COM_CMD_NEW_PATTERN  'N'
#define COM_CMD_FIRST_NEEDLE 'F'  //first needle of pattern from right
#define COM_CMD_SEPERATOR    ':'

#define COM_CMD_SERVO        'S'

#define COM_CMD_PLOAD_END    '\n'

// Parser states
#define COM_PARSE_CMD      0x01
#define COM_PARSE_SEP      0x02
#define COM_PARSE_PLOAD    0x03


unsigned char parserState = COM_PARSE_CMD;

unsigned char parserReceivedCommand = 0;
String parserReceivedPayload = "";

unsigned char patternLength = 0;

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

  // Button Input
  pinMode(PIN_BUTTON_1, INPUT);

  //Eylet Input
  pinMode(PIN_Eyelet_1, INPUT);


  // Setup PHOTO SENSOR pin change interrupt
  pinMode(PIN_CSENSE, INPUT);
  pinMode(PIN_CREF, INPUT);
  attachInterrupt(INT_ENCODER, interruptPinChangeEncoder, CHANGE);

  // Setup IFDR pin change interrupt
  pinMode(PIN_IFDR, INPUT);
  attachInterrupt(INT_IFDR, interruptPinChangeIfdr, FALLING);

  // Setup Needles
  pinMode(PIN_NEEDLE_RTL, OUTPUT);
  digitalWrite(PIN_NEEDLE_RTL, HIGH);
  pinMode(PIN_NEEDLE_LTR, OUTPUT);
  digitalWrite(PIN_NEEDLE_LTR, HIGH);

}

void executeCommand(unsigned char cmd, String payload) {

  switch(cmd) {
  case COM_CMD_PATTERN:

    patternLength = payload.length();
    for(unsigned char i = 0; i < patternLength; i++) {
      knitPattern[i] = (payload.charAt(i) == '1')? 1 : 0;
    }

    break;

  case COM_CMD_CURSOR:
    currentCursorPosition = payload.toInt();
    break;

  case COM_CMD_FIRST_NEEDLE:
    firstNeedle = payload.toInt()*2-2;
    break;

  case COM_CMD_SERVO:

    switch(payload.toInt()) {
    case 0: //no colour selected
      servoColour12.write(90);
      servoColour34.write(90);
      break;
    case 1: //Color 1
      servoColour12.write(70);    
      servoColour34.write(90);
      break;    
    case 2: //Color 2
      servoColour12.write(115);
      servoColour34.write(90);
      break; 
    case 3: //Color 3
      servoColour12.write(90);    
      servoColour34.write(70);
      break;    
    case 4: //Color 4
      servoColour12.write(90);
      servoColour34.write(115);
      break; 
    case 5: //Servo off
      servoColour12.detach();
      servoColour34.detach();
      break; 
    case 6: //Servo on
      servoColour12.attach(8);
      servoColour34.attach(9);
      break; 
    }

    break;


  }
}

void sendCommand(unsigned char cmd, String payload) {
  Serial.write(cmd);
  Serial.write(COM_CMD_SEPERATOR);
  Serial.print(payload);
  Serial.write("\n");
}

void parserSerialStream() {

  if (Serial.available() == 0) {
    return;
  }

  char buffer = Serial.read();

  switch(parserState) {

  case COM_PARSE_CMD:
    parserState = COM_PARSE_SEP;
    parserReceivedCommand = buffer;
    parserReceivedPayload = "";
    break;

  case COM_PARSE_SEP:

    // We're awaiting a seperator here, if not, back to cmd
    if(buffer == COM_CMD_SEPERATOR) {
      parserState = COM_PARSE_PLOAD;
      break;
    }

    parserState = COM_PARSE_CMD;
    break;

  case COM_PARSE_PLOAD:

    if(buffer == COM_CMD_PLOAD_END) {

      executeCommand(parserReceivedCommand, parserReceivedPayload);
      parserState = COM_PARSE_CMD;

      sendCommand(COM_CMD_RESPONSE, "OK");
      break;
    }

    parserReceivedPayload += buffer;
    break;
  }
}

void loop() {
  parserSerialStream();

  //check if button for colour change ist activated and send response to processing
  button_1_State = digitalRead(PIN_BUTTON_1);

  if( buttonLastChecked == 0 ) // see if this is the first time checking the buttons
    buttonLastChecked = millis()+BUTTONDELAY;  // force a check this cycle
  if( millis() - buttonLastChecked > BUTTONDELAY ) { // make sure a reasonable delay passed
    if (button_1_State == HIGH) {    
      if (button_1_Hold == HIGH) { 
        // Send   
        sendCommand(COM_CMD_RESPONSE, "ON"); 
        button_1_Hold = LOW;
      }
    }
    else {
      if (button_1_Hold == LOW) { 
        // Send   
        sendCommand(COM_CMD_RESPONSE, "OFF"); 
        button_1_Hold = HIGH;
      }
    }
    buttonLastChecked = millis(); // reset the lastChecked value
  }



  //check Eyelets
  eyelet_1_State = digitalRead(PIN_Eyelet_1);

  if( eyelet_1_LastChecked == 0 ) // see if this is the first time checking the buttons
    eyelet_1_LastChecked = millis()+Eyelet_1_DELAY;  // force a check this cycle
  if( millis() - eyelet_1_LastChecked > Eyelet_1_DELAY ) { // make sure a reasonable delay passed
    if (eyelet_1_State == HIGH) {    
      if (eyelet_1_Hold == HIGH) { 
        // Send   
        sendCommand(COM_CMD_RESPONSE, "Eyelet 1 OUT"); 
        eyelet_1_Hold = LOW;
      }
    }
    else {
      if (eyelet_1_Hold == LOW) { 
        // Send   
        sendCommand(COM_CMD_RESPONSE, "Eyelet 1 IN"); 
        eyelet_1_Hold = HIGH;
      }
    }
    eyelet_1_LastChecked = millis(); // reset the lastChecked value
  }
}




void setNeedleByCursor(char cursorPosition) {

  // Just to be sure that we never exceed the pattern
  if(cursorPosition > patternLength-1 || cursorPosition < 0) {
    return;
  }

  if(currentDirection == DIRECTION_LEFT_RIGHT) {
    setNeedle_LTR(knitPattern[cursorPosition]);
  } 
  else if(currentDirection == DIRECTION_RIGHT_LEFT) {
    setNeedle_RTL(knitPattern[patternLength-cursorPosition-1]);
  }
}



void setNeedle_RTL(char state) {
  //change state because the E6000 sets needle by 0
  if(state==1){
    state = 0;
  }
  else
  {
    state = 1;
  }
  digitalWrite(PIN_NEEDLE_RTL, state);
}

void setNeedle_LTR(char state) {
  //change state because the E6000 sets needle by 0
  if(state==1){
    state = 0;
  }
  else
  {
    state = 1;
  }
  digitalWrite(PIN_NEEDLE_LTR, state);
}


void interruptPinChangeEncoder() {

  char currentPinChangeValue = digitalRead(PIN_CSENSE);
  char currentPinChangeOppositeValue = digitalRead(PIN_CREF);

  // Determine direction
  if(currentPinChangeValue == currentPinChangeOppositeValue) {
    currentDirection = DIRECTION_LEFT_RIGHT;
  } 
  else {
    currentDirection = DIRECTION_RIGHT_LEFT;
  }

  // RTL = 1, LTR = -1
  currentCursorPosition += currentDirection; 

  //store last position
  lastCursorPosition = currentCursorPosition;


  //debug cursorposition
  //sendCommand(COM_CMD_RESPONSE, String(currentCursorPosition));

  // Check if we're in range of our needles
  if((currentDirection == DIRECTION_RIGHT_LEFT && currentCursorPosition > offsetCarriage_RTL + firstNeedle) ||
    (currentDirection == DIRECTION_LEFT_RIGHT && currentCursorPosition - offsetCarriage_LTR  <= patternLength + firstNeedle)) {

    if(currentPatternIndex > patternLength) {

      setNeedle_RTL(0);
      setNeedle_LTR(0);
      currentPatternIndex = 0;
      isKnitting = false;

      sendCommand(COM_CMD_PATTERN_END, "1");


    } 
    else {

      if(isKnitting == true) {
        // React on FALLING Edge 
        if(currentPinChangeValue == 1)  {
          setNeedleByCursor(currentPatternIndex);
          currentPatternIndex++;
        }
      }

    }
  }

  if(lastDirection != currentDirection) {
    lastDirection = currentDirection;
    currentPatternIndex = 0;
    isKnitting = true;
    if(currentDirection == DIRECTION_RIGHT_LEFT) {
      sendCommand(COM_CMD_DIRECTION, "RTL");
    } 
    else {
      sendCommand(COM_CMD_DIRECTION, "LTR");
    }
  }
}

// We only use the IFDR to determine if we can send the pattern
// for the next line.
void interruptPinChangeIfdr() {
  if(isKnitting == false) {
    sendCommand(COM_CMD_IFDR, "1");
  }
}