Avaleht
uus teema   vasta Tarkvara »  Programmeerimine »  Abi freespinki liigutava Arduino programmiga märgi kõik teemad loetuks
märgi mitteloetuks
vaata eelmist teemat :: vaata järgmist teemat
Hinnavaatlus :: Foorum :: Uudised :: Ärifoorumid :: HV F1 ennustusvõistlus :: Pangalink :: Telekavad :: HV toote otsing
autor
sõnum Saada viide sõbrale. Teata moderaatorile
otsing:  
Terror
HV veteran
Terror

liitunud: 08.11.2001




sõnum 18.09.2017 07:39:54 Abi freespinki liigutava Arduino programmiga vasta tsitaadiga

Mõned kuud tagasi sai soetatud üks mittekomplektne nõuka aegne freespink millel puudus elektroonika ning muud nipet näpet.
Praeguseks siis elektroonika osa niikaugel, et saab juba häda pärast midagi freesida. X,Y,Z telje liigutamine toimub läbi samm-mootori. Eripära seisneb selles, et kõiki telgi liigutatakse läbi ühe mootori. Ülekandes on 3 elektromagnetit mille lülitamisel haagitakse vastava telje vedu taha.
Telgede liigutamine toimub läbi joystiku ning liikumise kiirus läbi poteka.
Arduino koodiga aga hetkel väike probleem. Liikumine ei ole sujuv, seda on hästi näha just aeglasel kiirusel. Alloleval videol kiire ülevaade asjast.
https://www.youtube.com/watch?v=UqEGLz3RFcE&feature=youtu.be
Kuula ka mootori häält. Ossi väljundist on näha, et väljundpulsside sagedus varieerub, kuigi peaks olema konstantne. Üks teine probleem mis antud videol ei kajastu on see, et kokku on potekast võimalik valida ~4-5 erinevat kiirust. St kiiruste valik ei ole sujuv, potekat keerates on tegemist justkui 4 pos lülitiga kus kiirus hüppab ühel hetkel ühelt kiiruselt teisele.

Mootor: https://www.aliexpress.com/item/Top-Quality-ACT-Stepper-Motor-Driver-DM860-80V-7-8A-256Microsteps-for-Nema34-Stepper-Motor-CNC/32610782356.html?spm=a2g0s.9042311.0.0.kTCy7D
Driver: https://www.aliexpress.com/item/Top-Quality-ACT-Stepper-Motor-Driver-DM860-80V-7-8A-256Microsteps-for-Nema34-Stepper-Motor-CNC/32610782356.html?spm=a2g0s.9042311.0.0.kTCy7D
Arduino Mega kloon: https://www.aliexpress.com/item/1pcs-Mega-2560-R3-CH340G-ATmega2560-16AU-MicroUSB-Compatible-for-Arduino-Mega-2560-With-Bootloader-hei/32688365177.html?spm=2114.13010708.0.0.b3UEuo

Mõned fotod hetke seisust: https://imgur.com/a/eZdpV
Arduino kood:

#include <AccelStepper.h>

// Define the stepper and the pins it will use
AccelStepper stepper1(AccelStepper::DRIVER, 9, 8);

// Define 6 input pins for axis movements
#define  X_CW  2
#define  X_CCW  1
#define  Y_CW  4
#define  Y_CCW  3
#define  Z_CW  5
#define  Z_CCW  6

// Electromagnetic clutch. If output is low axis won't move.
#define X_coil 10
#define Y_coil 11
#define Z_coil 12

// Define limit switches

#define  X_CW_limit  40
#define  X_CCW_limit  41
#define  Y_CW_limit  42
#define  Y_CCW_limit  43
#define  Z_CW_limit  44
#define  Z_CCW_limit  45

// Define our analog pot input pin
#define  SPEED_PIN 0

// Define our maximum and minimum speed in steps per second (scale pot to these)
#define  MAX_SPEED 4000
#define  MIN_SPEED 0

void setup() {
  // The only AccelStepper value we have to set here is the max speeed, which is higher than we'll ever go
  stepper1.setMaxSpeed(10000.0);
 
  // Set up the button inputs, with pullups
  pinMode(X_CW, INPUT_PULLUP);
  pinMode(X_CCW, INPUT_PULLUP);
  pinMode(Y_CW, INPUT_PULLUP);
  pinMode(Y_CCW, INPUT_PULLUP);
  pinMode(Z_CW, INPUT_PULLUP);
  pinMode(Z_CCW, INPUT_PULLUP);

  // Set up limit switches, with pullups
  pinMode(X_CW_limit, INPUT_PULLUP);
  pinMode(X_CCW_limit, INPUT_PULLUP);
  pinMode(Y_CW_limit, INPUT_PULLUP);
  pinMode(Y_CCW_limit, INPUT_PULLUP);
  pinMode(Z_CW_limit, INPUT_PULLUP);
  pinMode(Z_CCW_limit, INPUT_PULLUP);
 
  //Define 3 electromagnetic clutches as outputs
  pinMode(X_coil, OUTPUT);
  pinMode(Y_coil, OUTPUT);
  pinMode(Z_coil, OUTPUT);

}

void loop() {
  static float current_speed = 0.0;         // Holds current motor speed in steps/second
  static int analog_read_counter = 1000;    // Counts down to 0 to fire analog read
  static char sign = 0;                     // Holds -1, 1 or 0 to turn the motor on/off and control direction
  static int analog_value = 0;              // Holds raw analog value.


// check if switches are not pushed and turn off motor and coils
   
  if (digitalRead(X_CW) == 1) {
    sign = 0;
    digitalWrite(X_coil, HIGH);
  }
    if (digitalRead(X_CCW) == 1) {
    sign = 0;
    digitalWrite(X_coil, HIGH);
  }
   if (digitalRead(Y_CW) == 1) {
    sign = 0;
    digitalWrite(Y_coil, HIGH);
  }
    if (digitalRead(Y_CCW) == 1) {
    sign = 0;
    digitalWrite(Y_coil, HIGH);
  }
    if (digitalRead(Z_CW) == 1) {
    sign = 0;
    digitalWrite(Z_coil, HIGH);
  }
    if (digitalRead(Z_CCW) == 1) {
    sign = 0;
    digitalWrite(Z_coil, HIGH);
  }
 

  // If a switch is pushed, set the sign value appropriately

  if (digitalRead(X_CW) == 0) {
    if(!digitalRead(X_CW_limit)){}
    else {
      sign = 1;
      digitalWrite(X_coil, LOW);
      }
  }
  if (digitalRead(X_CCW) == 0) {
    if(!digitalRead(X_CCW_limit)){}
    else {
      sign = -1;
      digitalWrite(X_coil, LOW);
      }
  }
   if (digitalRead(Y_CW) == 0) {
    if(!digitalRead(Y_CW_limit)){}
    else {
      sign = 1;
      digitalWrite(Y_coil, LOW);
      }
  }
   if (digitalRead(Y_CCW) == 0) {
    if(!digitalRead(Y_CCW_limit)){}
    else {
      sign = -1;
      digitalWrite(Y_coil, LOW);
      }
  }
   if (digitalRead(Z_CW) == 0) {
    if(!digitalRead(Z_CW_limit)){}
    else {
      sign = 1;
      digitalWrite(Z_coil, LOW);
    }
  }
   if (digitalRead(Z_CCW) == 0) {
    if(!digitalRead(Z_CCW_limit)){}
    else {
      sign = -1;
      digitalWrite(Z_coil, LOW);
      }
  }


   


  // We only want to read the pot every so often (because it takes a long time we don't
  // want to do it every time through the main loop). 
  if (analog_read_counter > 0) {
    analog_read_counter--;
  }
  else {
    analog_read_counter = 3000;
    // Now read the pot (from 0 to 1023)
    analog_value = analogRead(SPEED_PIN);
    // Give the stepper a chance to step if it needs to
    stepper1.runSpeed();
    //  And scale the pot's value from min to max speeds
    current_speed = ((analog_value/1023.0) * (MAX_SPEED - MIN_SPEED)) + MIN_SPEED;
    if (current_speed < 10){
      current_speed = 0;
    }
    current_speed = current_speed * sign;
   
    // Update the stepper to run at this new speed
    stepper1.setSpeed(current_speed);
  }

  // This will run the stepper at a constant speed
  stepper1.runSpeed();
}

Kood on enamasti copy paste teiste inimeste neti avarustest leitud koodist, kuna ma ise progemises ei hiilga. Oleks tore, kui keegi saaks koodi optimeerimisel ning nende bugide välja juurimisel abiks olla.

_________________
Väiksemagabariidilised trei, frees ning keevitustööd. PS.
Kommentaarid: 100 loe/lisa Kasutajad arvavad:  :: 1 :: 2 :: 91
tagasi üles
vaata kasutaja infot saada privaatsõnum
Ohohh
Kreisi kasutaja
Ohohh

liitunud: 13.09.2003




sõnum 18.09.2017 21:01:14 vasta tsitaadiga

Kas ma saan õigesti aru, et X_CW ja X_CCW on üksteist välistavad?

Mulle praegu paistab, et loop'i alguses sa ALATI lülitad kõigepealt coili välja, kuna üks neist kahest tingimusest on igal juhul tõene, kuna kang ei saa olla korraga paremas ja vasakus servas üheaegselt.
 
  if (digitalRead(X_CW) == 1) {
    sign = 0;
    digitalWrite(X_coil, HIGH);
  }
  if (digitalRead(X_CCW) == 1) {
    sign = 0;
    digitalWrite(X_coil, HIGH);
  }

Tulemus on see, et kangi all hoides X_coil väljund ei ole mitte ühtlaselt peal vaid pulseerib kiiresti



Midagi sellist tundub loogilisem

  sign = 0;

  if (digitalRead(X_CW) == 0 && digitalRead(X_CW_limit) != 0) {
    sign = 1;
    digitalWrite(X_coil, LOW);
  } else if (digitalRead(X_CCW) == 0 && digitalRead(X_CCW_limit) != 0) {
    sign = -1;
    digitalWrite(X_coil, LOW);
  } else {
    digitalWrite(X_coil, HIGH);
  }

  if (digitalRead(Y_CW) == 0 && digitalRead(Y_CW_limit) != 0) {
    sign = 1;
    digitalWrite(Y_coil, LOW);
  } else if (digitalRead(Y_CCW) == 0 && digitalRead(Y_CCW_limit) != 0) {
    sign = -1;
    digitalWrite(Y_coil, LOW);
  } else {
    digitalWrite(Y_coil, HIGH);
  }

  if (digitalRead(Z_CW) == 0 && digitalRead(Z_CW_limit) != 0) {
    sign = 1;
    digitalWrite(Z_coil, LOW);
  } else if (digitalRead(Z_CCW) == 0 && digitalRead(Z_CCW_limit) != 0) {
    sign = -1;
    digitalWrite(Z_coil, LOW);
  } else {
    digitalWrite(Z_coil, HIGH);
  }





edit: panin kõik teljed


viimati muutis Ohohh 18.09.2017 21:24:02, muudetud 1 kord
Kommentaarid: 6 loe/lisa Kasutajad arvavad:  :: 0 :: 0 :: 6
tagasi üles
vaata kasutaja infot saada privaatsõnum
Terror
HV veteran
Terror

liitunud: 08.11.2001




sõnum 22.09.2017 18:52:10 vasta tsitaadiga

Liikumisega tundub nüüd korras olevat, kuid üritasin siin koodi edasi arendada ning jõin jällegi hätta.
Freespingil on hüdropump mis õlitab liikuvaid osasid. Kui X,Y või Z telge liigutada peaks pump tööle hakkama ning töötama veel 10 sek vms intervall.
Kui spindli mootor tööle panna peab pump samuti tööle hakkama ning lisaks lülitama veel sisse hüdroklapi.
Hetkel jääbki hüdropump mingil põhjusel sisse lülitatuks, kui masina sisse lülitan.

Lisaks ei toimi millegipärast ka see osa koodist (kui sisendit lülitan, siis väljund ei reageeri):

if (digitalRead(SpindleState == LOW)){
    digitalWrite(SpindleOilValvePin, LOW);
  }
  else {
    digitalWrite(SpindleOilValvePin, HIGH);
  }


Kogu kood:


#include <AnalogSmooth.h>

#include <AccelStepper.h>

// Define the stepper and the pins it will use
AccelStepper stepper1(AccelStepper::DRIVER, 9, 8);

AnalogSmooth as = AnalogSmooth();

//Define input for spindle motor state so that we know if spindle is running or not
const int SpindleState = 17;

//Define outputs for hydraulic system. Pump and electric valves
const int HydroPumpPin =  14; //Starts hydraulic pump
const int SpindleOilValvePin = 15; //when spindle is running valve must be set LOW and pump must also work
const int AxisOilValvePin = 16; // oil for ways, must occasionally be turned on for 2 sek (pump running). <-ei ole veel kasutuses.

// Define 6 input pins for axis movements
const int  X_CW = 2;
const int  X_CCW = 1;
const int  Y_CW = 4;
const int  Y_CCW = 3;
const int  Z_CW = 5;
const int  Z_CCW = 6;

// Electromagnetic clutch. If output is high axis won't move.
const int X_coil = 10;
const int Y_coil = 11;
const int Z_coil = 12;

// Define limit switches

const int  X_CW_limit = 40;
const int  X_CCW_limit = 41;
const int  Y_CW_limit = 42;
const int  Y_CCW_limit = 43;
const int  Z_CW_limit = 44;
const int  Z_CCW_limit = 45;

// Define our analog pot input pin
const int  SPEED_PIN = 0;

// Define our maximum and minimum speed in steps per second (scale pot to these)
const int  MAX_SPEED = 5000;
const int  MIN_SPEED = 0;

boolean HydroState = HIGH; //current state of the Hydraulic pump 

unsigned long timeOfLastPumpEvent = 0;//the last time the Pump was running

int intervalON = 15000;//how long we want the pump to stay on

void setup() {
  // The only AccelStepper value we have to set here is the max speeed, which is higher than we'll ever go
  stepper1.setMaxSpeed(5000.0);
  //stepper1.setAcceleration(1000);

// Serial.begin(9600);
 
  pinMode(HydroPumpPin, OUTPUT);
  pinMode(SpindleOilValvePin, OUTPUT);
  pinMode(AxisOilValvePin, OUTPUT);
  pinMode(SpindleState, INPUT_PULLUP);

  digitalWrite(HydroPumpPin, HIGH);
 
  // Set up the button inputs, with pullups
  pinMode(X_CW, INPUT_PULLUP);
  pinMode(X_CCW, INPUT_PULLUP);
  pinMode(Y_CW, INPUT_PULLUP);
  pinMode(Y_CCW, INPUT_PULLUP);
  pinMode(Z_CW, INPUT_PULLUP);
  pinMode(Z_CCW, INPUT_PULLUP);

  // Set up limit switches, with pullups
  pinMode(X_CW_limit, INPUT_PULLUP);
  pinMode(X_CCW_limit, INPUT_PULLUP);
  pinMode(Y_CW_limit, INPUT_PULLUP);
  pinMode(Y_CCW_limit, INPUT_PULLUP);
  pinMode(Z_CW_limit, INPUT_PULLUP);
  pinMode(Z_CCW_limit, INPUT_PULLUP);
 
  //Define 3 electromagnetic clutches as outputs
  pinMode(X_coil, OUTPUT);
  pinMode(Y_coil, OUTPUT);
  pinMode(Z_coil, OUTPUT);

}

void loop() {
 
  static float current_speed = 0.0;         // Holds current motor speed in steps/second
  static int analog_read_counter = 1000;    // Counts down to 0 to fire analog read
  static char sign = 0;                     // Holds -1, 1 or 0 to turn the motor on/off and control direction
  static int analog_value = 0;              // Holds raw analog value.
 
  unsigned long currentMillis = millis();
 
// check joystick and end switches position and start stepper + engage electric clutch
sign = 0;

  if (digitalRead(X_CW) == 0 && digitalRead(X_CW_limit) != 0) {
    sign = 1;
    digitalWrite(X_coil, LOW);
    timeOfLastPumpEvent = currentMillis;
  }
  else if (digitalRead(X_CCW) == 0 && digitalRead(X_CCW_limit) != 0) {
    sign = -1;
    digitalWrite(X_coil, LOW);
    timeOfLastPumpEvent = currentMillis;
  }
  else {
    digitalWrite(X_coil, HIGH);
  }

  if (digitalRead(Y_CW) == 0 && digitalRead(Y_CW_limit) != 0) {
    sign = 1;
    digitalWrite(Y_coil, LOW);
    timeOfLastPumpEvent = currentMillis;
  }
  else if (digitalRead(Y_CCW) == 0 && digitalRead(Y_CCW_limit) != 0) {
    sign = -1;
    digitalWrite(Y_coil, LOW);
    timeOfLastPumpEvent = currentMillis;
  }
  else {
    digitalWrite(Y_coil, HIGH);
  }

  if (digitalRead(Z_CW) == 0 && digitalRead(Z_CW_limit) != 0) {
    sign = 1;
    digitalWrite(Z_coil, LOW);
    timeOfLastPumpEvent = currentMillis;
  }
  else if (digitalRead(Z_CCW) == 0 && digitalRead(Z_CCW_limit) != 0) {
    sign = -1;
    digitalWrite(Z_coil, LOW);
    timeOfLastPumpEvent = currentMillis;
  }
  else {
    digitalWrite(Z_coil, HIGH);
  }

  if (HydroState == HIGH){ //if the Pump is already off
    if (currentMillis - timeOfLastPumpEvent < intervalON || digitalRead(SpindleState == LOW)){//and enough time has passed
      digitalWrite(HydroPumpPin, LOW);//turn it on
      HydroState = LOW;//store its current state
      //timeOfLastPumpEvent = currentMillis;//update the time of this new event
    }
  }
  else {//if the Pump is already on
    if (currentMillis - timeOfLastPumpEvent > intervalON && digitalRead(SpindleState == HIGH)){
      digitalWrite(HydroPumpPin, HIGH); //turn pump off
      HydroState = HIGH; //hydrostate off
      //timeOfLastPumpEvent = currentMillis;
    }
  }
 
  if (digitalRead(SpindleState == LOW)){
    digitalWrite(SpindleOilValvePin, LOW);
  }
  else {
    digitalWrite(SpindleOilValvePin, HIGH);
  }


  // We only want to read the pot every so often (because it takes a long time we don't
  // want to do it every time through the main loop). 
  if (analog_read_counter > 0) {
    analog_read_counter--;
  }
  else {
    analog_read_counter = 200;
    // Now read the pot (from 0 to 1023)
    analog_value = analogRead(SPEED_PIN);
    float analogSmooth = as.smooth(analog_value);
    // Give the stepper a chance to step if it needs to
    //stepper1.runSpeed();
    //  And scale the pot's value from min to max speeds
    current_speed = ((analogSmooth/1023.0) * (MAX_SPEED - MIN_SPEED)) + MIN_SPEED;
    if (current_speed < 10){
      current_speed = 0;
      }
    current_speed = current_speed * sign;
   
    // Update the stepper to run at this new speed
    stepper1.setSpeed(current_speed);
  }

  // This will run the stepper at a constant speed
  stepper1.runSpeed();
// Serial.println(current_speed);
}


_________________
Väiksemagabariidilised trei, frees ning keevitustööd. PS.
Kommentaarid: 100 loe/lisa Kasutajad arvavad:  :: 1 :: 2 :: 91
tagasi üles
vaata kasutaja infot saada privaatsõnum
Ohohh
Kreisi kasutaja
Ohohh

liitunud: 13.09.2003




sõnum 22.09.2017 21:01:34 vasta tsitaadiga

digitalRead'idel on sulud valesti:
digitalRead(SpindleState == LOW) -> digitalRead(SpindleState) == LOW
digitalRead(SpindleState == HIGH) -> digitalRead(SpindleState) == HIGH
digitalRead(SpindleState == LOW) -> digitalRead(SpindleState) == LOW
Hetkel toimivad need kõik kui digitalRead(0)


Lisaks oleks hea mõte nendel pikkadel if'idel rohkem sulge kasutada, et kompilaator tehete järjekorrast kindlasti nii aru saaks nagu mõtled. Ehk siis näiteks nii:
if (((currentMillis - timeOfLastPumpEvent) < intervalON) || digitalRead(SpindleState) == LOW)



Ma pumba loogikasse praegu väga ei süvenenud. Esialgu võiks proovida parandatud digitalRead'idega.
Kommentaarid: 6 loe/lisa Kasutajad arvavad:  :: 0 :: 0 :: 6
tagasi üles
vaata kasutaja infot saada privaatsõnum
Terror
HV veteran
Terror

liitunud: 08.11.2001




sõnum 01.11.2017 19:52:30 vasta tsitaadiga

Vahepeal on paar asja kätte saadud valmis tehtud mis võimaldavad pingi juhtosa varsti lõplikult kokku panna.
https://imgur.com/BNGnr2b - puutetundlik LCD mis näitab pöördeid, laua liikumise kiirust, freesi lõikekiirust m/min, palju üks freesi tera materjali lõikab. Freesi läbimõõt ning lõiketerade arv on sisestavav läbi LCD
https://imgur.com/mjoM0Xp - juhtpaneel siis selline.
Koodi olen ka vahepeal veidi jõudumööda juurde kirjutanud ning pmst üks keerulisem osa on veel jäänud eeldusel, et servo juhtimine praeguse lisatud koodiga normaalselt toimib. Kui mingi osa koodist võtab liiga kaua aega hakkab servo hakkima, kuna arduino ei suuda stabiilselt kontrollerisse juhtpulsse saata.
Keerulisem osa koodist minu jaoks on servo juhtimine läbi enkoodri kui ka läbi joystiku. Enkoodriga saaks juhtida asja ainult siis, kui joystick pole hetkel aktiveeritud.
Enkoodri osa püüan midagi siit maha kirjutada: https://suleymancanan.wordpress.com/2015/03/16/stepper-motor-control-using-cnc-handle-dial-with-arduino/#more-585

Üks asi mis veel silma kriibib on koodi ülesehitus. Ilmselt saaks palju parema lahenduse asjale, kui asjad eraldi funktsioonidesse kirjtuada ning neid siis loopis välja kutsuda?
enda oskuste juures ei oska seda aga paraku kuidagi realiseerida.

Kood hetkel selline:

#include <AnalogSmooth.h>

#include <AccelStepper.h>

#include <RotaryEncoder.h>

int oldvalue;

volatile byte half_revolutions;

unsigned int rpm;
unsigned long timeold;



const int  SPEED_PIN = A0;  //Table Pot speed

const int EndoderMultiPin = A1;
const int EncoderAxisPin = A2;

RotaryEncoder encoder(A8, A9);  //rotary encoder sisendsignaali pinid

// Define the stepper and the pins it will use
AccelStepper stepper1(AccelStepper::DRIVER, 9, 8);  //pin 8, 9

AnalogSmooth as = AnalogSmooth();

const byte interruptPin = 2;  // spindli RPM signaali sisend pin

//Define input for spindle motor state so that we know if spindle is running or not
const int SpindleState = 22; //23

//Define outputs for hydraulic system. Pump and electric valves
const int HydroPumpPin =  23; //24 Starts hydraulic pump
const int SpindleOilValvePin = 24; // 25 when spindle is running valve must be set LOW and pump must also work
const int AxisOilValvePin = 25; // 26 oil for ways, must occasionally be turned on for 2 sek (pump running).

// Define 6 input pins for axis movements
const int  X_CW = 2; //27
const int  X_CCW = 1; //28
const int  Y_CW = 4; //29
const int  Y_CCW = 3; //29
const int  Z_CW = 5; //30
const int  Z_CCW = 6; //31

// Electromagnetic clutch. If output is high axis won't move.
const int X_coil = 10; //32
const int Y_coil = 11; //33
const int Z_coil = 12; //34

// Define limit switches

const int  X_CW_limit = 40; //35
const int  X_CCW_limit = 41; //36
const int  Y_CW_limit = 42; //37
const int  Y_CCW_limit = 43; //38
const int  Z_CW_limit = 44; //39
const int  Z_CCW_limit = 45; //40

//
const int  kiirendus = 41; //41




// Define our maximum and minimum speed in steps per second (scale pot to these)
const int  MAX_SPEED = 5000;
const int  MIN_SPEED = 0;

boolean HydroState = 0; //current state of the Hydraulic pump 0=OFF

unsigned long timeOfLastPumpEvent = 0;//the last time the Pump was running

const int intervalON = 5000;//how long we want the pump to stay on

int multiplier_value = 0;
int selected_axis = 0;
long virtualpos = 0L;

void setup() {
 
  stepper1.setMaxSpeed(5000.0);
  //stepper1.setAcceleration(1000);

  Serial1.begin(115200); //nextion display
  Serial.begin(115200); //debug via usb
 
  attachInterrupt(digitalPinToInterrupt(interruptPin), rpm_fun, RISING); //interrupt spindli RPM lugemiseks
  half_revolutions = 0;
  rpm = 0;
  timeold = 0;

  PCICR |= (1 << PCIE2);    // This enables Pin Change Interrupt 1 that covers the Analog input pins or Port C. - muudetud
  PCMSK2 |= (1 << PCINT16) | (1 << PCINT17);  // This enables the interrupt for pin 2 and 3 of Port C. - muudetud

 
  pinMode(HydroPumpPin, OUTPUT);
  pinMode(SpindleOilValvePin, OUTPUT);
  pinMode(AxisOilValvePin, OUTPUT);
  pinMode(SpindleState, INPUT_PULLUP);

  digitalWrite(HydroPumpPin, HIGH);
 
  // Set up the button inputs, with pullups
  pinMode(X_CW, INPUT_PULLUP);
  pinMode(X_CCW, INPUT_PULLUP);
  pinMode(Y_CW, INPUT_PULLUP);
  pinMode(Y_CCW, INPUT_PULLUP);
  pinMode(Z_CW, INPUT_PULLUP);
  pinMode(Z_CCW, INPUT_PULLUP);

  // Set up limit switches, with pullups
  pinMode(X_CW_limit, INPUT_PULLUP);
  pinMode(X_CCW_limit, INPUT_PULLUP);
  pinMode(Y_CW_limit, INPUT_PULLUP);
  pinMode(Y_CCW_limit, INPUT_PULLUP);
  pinMode(Z_CW_limit, INPUT_PULLUP);
  pinMode(Z_CCW_limit, INPUT_PULLUP);
 
  pinMode(kiirendus, INPUT_PULLUP); // seda nuppu all hoides ning joystikust liigutades liigub laud max kiirusega
 
  //Define 3 electromagnetic clutches as outputs
  pinMode(X_coil, OUTPUT);
  pinMode(Y_coil, OUTPUT);
  pinMode(Z_coil, OUTPUT);

}

ISR(PCINT2_vect) {
  encoder.tick(); // just call tick() to check the state.
}

void loop() {
 
  static float current_speed = 0.0;         // Holds current motor speed in steps/second
  static int analog_read_counter = 1000;    // Counts down to 0 to fire analog read
  static char sign = 0;                     // Holds -1, 1 or 0 to turn the motor on/off and control direction
  static int analog_value = 0;              // Holds raw analog value.
 
  unsigned long currentMillis = millis();
 
//siit hakkab enkoodri koodi osa

  int newPos = encoder.getPosition();



  if (newPos!=oldvalue) {
   
    oldvalue=newPos;
     
    if (digitalRead(X_CW) == 1 && digitalRead(X_CCW) == 1 && digitalRead(Y_CW) == 1 && digitalRead(Y_CCW) == 1 && digitalRead(Z_CW) == 1 && digitalRead(Z_CCW) == 1){
      //kui joystikut ei ole aktiveeritud töötab enkooder
      // if multiplier_value on kuni 1000 on kordaja 1, kui jääb vahemikku 1001-3000 on kordaja 10, kui on üle 3000 on kordaja 100
      // virtualpos = newpos * multiplier + virtualpos; // <-???
      //stepper.moveTo(virtualpos);
     
      // kuidagi peaks selle stepper pos pidevalt nulliks muutma? ka joystiku liigutamise koodi osas, kuna muidu joystikuga liigutad mootorit näit 90834 pulssi (positsioon),
      // ning enkoodriga ühe kliki tehes üritab sõita teab kuhu, kuna viimane enkoodri pos võis olla 12331.
      // stepper.setCurrentPosition(0);

   
    Serial1.print("n1.val=");
    Serial1.print(newPos);
    Serial1.write(0xff);
    Serial1.write(0xff);
    Serial1.write(0xff);
     }
   
    /*
    lisada kood enkoodri liigutuse järgi servo liigutamiseks.
    Enkoodriga saab servot liigutada, kui joysticku kangi ei ole parasjagu aktiivne.
    Enkoodri skaala nupp valib 1x, 10x või 100x multiplikatsiooni. Vastavalt mis sisendi pin on aktiivne.
    Enkoodri telje valiku nupp valib mis telge parasjagu liigutatakse. OFF, Z, X, Y.
    */
} //enkoodi koodi osa lõpp

  if ((millis()-timeold)>1500 || half_revolutions >=10) { // Spindli pöörded LCD displayle
     //Update RPM every 10 counts, increase this for better RPM resolution,
     //decrease for faster update
     rpm = 30*1000/(millis() - timeold)*half_revolutions;
     timeold = millis();
     half_revolutions = 0;
    //Serial.println(rpm,DEC);
    Serial1.print("n0.val=");
    Serial1.print(rpm);
    Serial1.write(0xff);
    Serial1.write(0xff);
    Serial1.write(0xff);
  }
 
// check joystick and end switches position and start stepper + engage electric clutch
sign = 0;

  if (digitalRead(X_CW) == 0 && digitalRead(X_CW_limit) != 0) {
    sign = 1;
    digitalWrite(X_coil, LOW);
    timeOfLastPumpEvent = currentMillis;
  }
  else if (digitalRead(X_CCW) == 0 && digitalRead(X_CCW_limit) != 0) {
    sign = -1;
    digitalWrite(X_coil, LOW);
    timeOfLastPumpEvent = currentMillis;
  }
  else {
    digitalWrite(X_coil, HIGH);
  }

  if (digitalRead(Y_CW) == 0 && digitalRead(Y_CW_limit) != 0) {
    sign = 1;
    digitalWrite(Y_coil, LOW);
    timeOfLastPumpEvent = currentMillis;
  }
  else if (digitalRead(Y_CCW) == 0 && digitalRead(Y_CCW_limit) != 0) {
    sign = -1;
    digitalWrite(Y_coil, LOW);
    timeOfLastPumpEvent = currentMillis;
  }
  else {
    digitalWrite(Y_coil, HIGH);
  }

  if (digitalRead(Z_CW) == 0 && digitalRead(Z_CW_limit) != 0) {
    sign = 1;
    digitalWrite(Z_coil, LOW);
    timeOfLastPumpEvent = currentMillis;
  }
  else if (digitalRead(Z_CCW) == 0 && digitalRead(Z_CCW_limit) != 0) {
    sign = -1;
    digitalWrite(Z_coil, LOW);
    timeOfLastPumpEvent = currentMillis;
  }
  else {
    digitalWrite(Z_coil, HIGH);
  }

  if (HydroState == 0 && ((currentMillis - timeOfLastPumpEvent) < intervalON) || digitalRead(SpindleState) == LOW){//and enough time has passed
      digitalWrite(HydroPumpPin, LOW);//turn it on
      HydroState = 1;//store its current state
      //timeOfLastPumpEvent = currentMillis;//update the time of this new event
  }
 
  else if (((currentMillis - timeOfLastPumpEvent) > intervalON) && digitalRead(SpindleState) == HIGH){
      digitalWrite(HydroPumpPin, HIGH); //turn pump off
      HydroState = 0; //hydrostate off
      //timeOfLastPumpEvent = currentMillis;
    }
 
 
  if (digitalRead(SpindleState) == 1){
    digitalWrite(SpindleOilValvePin, HIGH);
  }
  else {
    digitalWrite(SpindleOilValvePin, LOW);
  }


  // We only want to read the pot every so often (because it takes a long time we don't
  // want to do it every time through the main loop). 
  if (analog_read_counter > 0) {
    analog_read_counter--;
  }
  else {
    analog_read_counter = 2000;
    // Now read the pot (from 0 to 1023)
    analog_value = analogRead(SPEED_PIN);
   
    multiplier_value = analogRead(EndoderMultiPin);
    selected_axis = analogRead(EncoderAxisPin);
    float analogSmooth = as.smooth(analog_value);
    // Give the stepper a chance to step if it needs to
    //stepper1.runSpeed();
    //  And scale the pot's value from min to max speeds
    current_speed = ((analogSmooth/1023.0) * (MAX_SPEED - MIN_SPEED)) + MIN_SPEED;
    if (current_speed < 10){
      current_speed = 0;
      }
    if(digitalRead(kiirendus) == 0){
      current_speed = MAX_SPEED;
    } 
   
    Serial1.print("n1.val=");
    Serial1.print((current_speed / 10 * 0.02 * 60), 0); // pulses per second / microstep divider * one step is 0.02mm * 60 to conv to minutes = mm/min
    Serial1.write(0xff);
    Serial1.write(0xff);
    Serial1.write(0xff);
    Serial.print(current_speed, 0);
    Serial.println();
    current_speed = current_speed * sign;
   
    // Update the stepper to run at this new speed
    stepper1.setSpeed(current_speed);

  }

  // This will run the stepper at a constant speed
  stepper1.runSpeed();
// Serial.println(current_speed);
}

void rpm_fun()
{
   half_revolutions++;
   //Each rotation, this interrupt function is run twice
}

_________________
Väiksemagabariidilised trei, frees ning keevitustööd. PS.
Kommentaarid: 100 loe/lisa Kasutajad arvavad:  :: 1 :: 2 :: 91
tagasi üles
vaata kasutaja infot saada privaatsõnum
Ohohh
Kreisi kasutaja
Ohohh

liitunud: 13.09.2003




sõnum 02.11.2017 19:54:45 vasta tsitaadiga

Äkki saad stepper1.runSpeed()'i panna timeri interrupti, et seda jooksutataks kindla intervalliga sõltumata ülejäänud koodist.
Siis muidugi peaks kiiruse muutuse ajaks igaks juhuks interruptid ära keelama, et runSpeed() poole muutmise pealt käima ei läheks:
noInterrupts();
stepper1.setSpeed(current_speed);
interrupts();


Kui ma ise teeks, siis ma jagaks koodi loogiliste komponentide kaupa eraldi klassideks (eraldi cpp ja h failid).
Näiteks eraldi klass joistick'u jaoks.
Kogu mootori liikumise ja liigumise piiramise loogika (limit switchid ja liikuma panevad coilid) võiks olla omaette klass.

Siis saaks main loopis olla midagi taolist

    frees.moveX(joistick.getX())
    frees.moveY(joistick.getY())
    frees.moveZ(joistick.getZ())

kus getX() tagastab joistiku suuna (-1 0 või 1) ja moveX sisemiselt lülitab sisse coilX'i ning deaktiveerib coilX'i, kui limit switch aktiveerub.


Nüüd on ka lihtsam tulevikus täiendada, kui mingi muu moodul peab freesi kontrollima. Umbes nii:

  if (joistick.isActive()) {
    frees.moveX(joistick.getX())
    frees.moveY(joistick.getY())
    frees.moveZ(joistick.getZ())
  } else {
    frees.moveX(encoderController.getX())
    frees.moveY(encoderController.getY())
    frees.moveZ(encoderController.getZ())
  }
Kommentaarid: 6 loe/lisa Kasutajad arvavad:  :: 0 :: 0 :: 6
tagasi üles
vaata kasutaja infot saada privaatsõnum
näita postitusi alates eelmisest:   
uus teema   vasta Tarkvara »  Programmeerimine »  Abi freespinki liigutava Arduino programmiga
[vaata eelmist teemat] [vaata järgmist teemat]
 lisa lemmikuks
näita foorumit:  
 ignoreeri teemat 
sa ei või postitada uusi teemasid siia foorumisse
sa ei või vastata selle foorumi teemadele
sa ei või muuta oma postitusi selles foorumis
sa ei või kustutada oma postitusi selles foorumis
sa ei või vastata küsitlustele selles foorumis
sa ei saa lisada manuseid selles foorumis
sa võid manuseid alla laadida selles foorumis



Hinnavaatlus ei vastuta foorumis tehtud postituste eest.