DYI motorfokuserare

Här kan du skriva om dina teleskopbygge och andra byggprojekt (som observatorium mm) med beskrivningar, ritningar och bilder.
User avatar
HanssonJ
Posts: 178
Joined: 2011-11-18 22:12:45
spamtest: JA
Location: Kristinelund utanför Björköby mellan Vetlanda och Nässjö
Contact:

Re: DYI motorfokuserare

Post by HanssonJ »

Hej - har inte hunnit testa så mycket än (molnen ligger täta över Smålandska Höglandet). Ingen tempstyrning än. Hittade två siter som har lite matnyttigt vad gäller att styra med knappar

http://www.cloudynights.com/item.php?item_id=2784
http://www.scopefocus.info/home

Tänkte bygga färdigt allt i julhelgen.

Mvh

Jörgen
---------------------------------------------------------------------
Celestron C8-SGT (XLT) med CG-5 Montering
Celestrons Reducer/Corrector f/6.3
Sky-Watcher Shorttube 70/500 med ALCCD5 för guidning
Canon EOS 400D, 650D
Corpze
Posts: 1012
Joined: 2012-03-01 04:00:53
spamtest: JA
Location: Arvika

Re: DYI motorfokuserare

Post by Corpze »

Nu har jag också beställt kort och motor, fästet har jag redan gjort till min Meade 102mm APO men jag har ännu inte funnit kuggremshjul och rem, Jag måste ha tag i ett kugg med en delning på 1.5mm och med profilen SN tror jag, för att det ska passa med orginal 1:10 ratten på fokuseraren, org.ratten är 30mm och jag hade tänkt mig 15mm på motoraxeln, då får jag 2:1 till finjusteringen och ett steg på motorn blir då 0.005mm vilket är mer än nog :)
Om någon vet var man får tag på sådana kugg och remmar får ni gärna hojta till!

MVH
bild.JPG
bild.JPG (417.68 KiB) Viewed 6173 times
TS N-AG10
Celestron C9.25" XLT
Meade 102mm APO
Astro Systeme Austria (ASA) DDM85
NEQ6 Pro Synscan
Atik 460 EX
SX Filterwheel LRGB Ha O3 S2

http://www.facebook.com/exophotograph" onclick="window.open(this.href);return false;
KennethB
Posts: 72
Joined: 2011-04-27 17:56:36
spamtest: JA

Re: DYI motorfokuserare

Post by KennethB »

Hej, jag blev också inspirerad av motorfokuserarbygget på SGL. Köpte ett arduino nano och en easydriver. Stegmotorn fick jag av en bekant. Nu har jag i alla fall fått ihop nånting. Jag hittade nån typ av vinkeljärn, troligtvis tillhörande en IKEA-säng. Skruvhålen för dessa var perfekt lokaliserade för att passa tillbehörshålen på min C9,25. För tillfället består själva remmen mellan stegmotorn och fokuseraren av en hårsnodd :-) Tro det eller ej, fokuseraren rör på sig. Denna del skall dock ses över, men rent principiellt så fungerar lösningen.

/Kenneth
Attachments
Fokuserare.jpg
Fokuserare.jpg (9.71 KiB) Viewed 6119 times
Corpze
Posts: 1012
Joined: 2012-03-01 04:00:53
spamtest: JA
Location: Arvika

Re: DYI motorfokuserare

Post by Corpze »

Kul att fler hakar på trenden :) har beställt temp/hygrosensor samt en LCD-shield, denna; http://dx.com/p/lcd-keypad-shield-for-a ... 602-118059 men jag vet inte den "släpper igenom" nog med utgångar för at få den vanliga fokuserarutgången att fungera, jag hade en tanke om att läsa ut temp/luftfuktighet samt antalet steps på displayen samt kunna styra fokus manuellt ute i fält utan dator :/
TS N-AG10
Celestron C9.25" XLT
Meade 102mm APO
Astro Systeme Austria (ASA) DDM85
NEQ6 Pro Synscan
Atik 460 EX
SX Filterwheel LRGB Ha O3 S2

http://www.facebook.com/exophotograph" onclick="window.open(this.href);return false;
Corpze
Posts: 1012
Joined: 2012-03-01 04:00:53
spamtest: JA
Location: Arvika

Re: DYI motorfokuserare

Post by Corpze »

Nu har jag lyckats löda ihop alla komponenter och laddat in koden i Arduinon och lyckats köra den lite fram och tillbaka i FocusMax, men hur kalibrerar man motorn, så att 0 är längst inkörd drawtube? sedan så står det Focuser step size 100 i SGLAscomFocusControl Setup, men är det inte 200 på denna motorn? jag kan iaf inte ändra så värdet sparas, inte heller kan jag ändra focuser speed :/

Med den utväxlingen jag har kommer jag få ca 500.000 steg, och att stega sig fram i 10.000 intervaller känns väldigt drygt, kan man ändra det på nåt vis?

Såhär blev det tillslut iaf;
bild 1.JPG
bild 1.JPG (672.64 KiB) Viewed 6064 times
bild 2.JPG
bild 2.JPG (336.22 KiB) Viewed 6064 times
TS N-AG10
Celestron C9.25" XLT
Meade 102mm APO
Astro Systeme Austria (ASA) DDM85
NEQ6 Pro Synscan
Atik 460 EX
SX Filterwheel LRGB Ha O3 S2

http://www.facebook.com/exophotograph" onclick="window.open(this.href);return false;
Corpze
Posts: 1012
Joined: 2012-03-01 04:00:53
spamtest: JA
Location: Arvika

Re: DYI motorfokuserare

Post by Corpze »

Hoppas att någon är bättre än mig på att koda C, men jag försöker modda dit två knappar, en för in och en för ut, har lyckats modda dit min egen kod så att knapparna funkar tillsammans med orginalkoden från SGL, men motorn rör sig extremt sakta, precis som att det är nån annan kod som "håller i" motorn eller om det är någon konstig inställning med motorhastigheten... vad kan det vara? Har två olika "int" för samma pin, nämligen "stepperpin" och "steppin" som båda är utgång 3 till easydrivern, kan det vara orsaken?

Markerade min egen kod som // MY OWN BUTTONCODE

MVH Daniel

Code: Select all

#include <SPI.h>
//START OF FOCUS CONTROL INITIALISE
// include the library code:
#include <EEPROM.h>
#include <eepromRW.h>
#include <HalfStepper.h>
#include <AFMotor.h>
AF_Stepper motor(200, 2); // steps per rev and the connection of the stepper to AFmotor shield (2nd chip M3/M4)

#define MAX_COMMAND_LEN             (5)
#define MAX_PARAMETER_LEN           (6)
#define COMMAND_TABLE_SIZE          (11)
#define TO_UPPER(x) (((x >= 'a') && (x <= 'z')) ? ((x) - ('a' - 'A')) : (x))

// initialize the library with the numbers of the interface pins
int dirPin = 2; // Easy Driver Direction Output Pin
int stepperPin = 3; // EasyDriver Stepper Step Output Pin
int powerPin = 4; //Sets the output used to power the Driver board
unsigned long powerMillis = 0; // used to remember when EasyDriver power was enabled
int motorSteps =3200; //number if steps for the motor to turn 1 revolution

// MY OWN BUTTONCODE
int steppin = 3;
int buttonIN = 5;
int buttonOUT = 6;
int val = 0;
// END OF MY OWN BUTTONCODE

volatile long NoOfSteps = 1000; //required number of steps to make
volatile long Position = 0; //used to keep track of the current motorposition
volatile long MaxStep = 200000; //define maximum no. of steps, max travel
volatile int SPEED = 500;
volatile byte MotorType = 0; // Motortypes, default is 0, Stepper motor, 1=Servo, 2=DC motor                           
volatile int BoardType = 0; // Boardtypes, default is 0, EasyDriver, 1=L293 chip, 2=LadyAda AFmotor board                           

boolean Direction = true;//True is one way false is other.Change to false if motor is moving in the wrong direction
boolean IsMoving = false;
boolean Absolute = true;
volatile long MaxIncrement=16384;//not yet used
HalfStepper myHalfStepper = HalfStepper(960, 9, 10, 11, 12);
//END OF FOCUS CONTROL INITIALISE

//Serial comms setup
char incomingByte = 0; // serial in data byte
byte serialValue = 0;
boolean usingSerial = true; // set to false to have the buttons control everything
char gCommandBuffer[MAX_COMMAND_LEN + 1];
char gParamBuffer[MAX_PARAMETER_LEN + 1];
long gParamValue;
volatile boolean UPDATE = true;

struct config_t //Memory Structure for Parking, Unparking the Focuser and other config settings 
{
    long parkposition;
    boolean parked;
    boolean stepperdirection;
    long controlboardtype;
} configuration;


typedef struct {
  char const    *name;
  void          (*function)(void);
} 
command_t;

//Set up a command table. when the command "IN" is sent from the PC and this table points it to the subroutine to run
command_t const gCommandTable[COMMAND_TABLE_SIZE] = {
  {
    "IN1",     FocusINFun,  }
  ,
  {
    "OUT",    FocusOUTFun,   }
  ,
  {
    "STP",  FocusSTEPSFun,   }
  ,
  {
    "SPD",  FocusSPEEDFun,   }
  ,
  {
    "LMT",  FocusSLimitFun,   }
  ,
  {
    "POS",    FocusSPositionFun,   }
  ,  
  {
    "MDE",   FocusSModeFun,   }
  ,
  {
    "TYP",   FocusSTypeFun,   }
  ,  
  {
    "PRK",   ParkFocuserFun,   }
  ,  
  {
    "BRD",   FocusBoardTypeFun,   }
  ,  
  {
    NULL,      NULL   }
};

//Serial Comms setup end

void setup() {

  EEPROM_readAnything(0, configuration); //PARKING:- Read the Position and Parked info
    if (configuration.parked == true) { //If the Focuser was Parked then load the Position information
     Position = configuration.parkposition; //Load the Position information
     Direction = configuration.stepperdirection;
     BoardType = configuration.controlboardtype;
  }

  pinMode(dirPin, OUTPUT); //Initialise Easydriver output
  pinMode(stepperPin, OUTPUT); //Initialise easy driver output
  //START OF FOCUS CONTROL SETUP
   //END OF FOCUS CONTROL SETUP
  Serial.begin(19200);// start the serial
  myHalfStepper.setSpeed(SPEED);
  NoOfSteps=1000;
  pinMode(13,OUTPUT); 
  pinMode(powerPin,OUTPUT); //Easydriver Sleep mode or power off
  digitalWrite(powerPin, LOW); //Easydriver Pwer off (Low = powered down)

  // MY OWN BUTTONCODE
  pinMode(dirPin, OUTPUT);
  pinMode(steppin, OUTPUT);
  pinMode(buttonIN, INPUT_PULLUP);
  pinMode(buttonOUT, INPUT_PULLUP);
  // END OF MY OWN BUTTONCODE

}

void loop() {

  int bCommandReady = false;

  //FocuserControl Power off command
  if (millis() > (powerMillis + 20000)) // check if power has been on for more than 20 seconds
  {
      digitalWrite(powerPin, LOW); // if yes, then disable power
  }

  //If There is information in the Serial buffer read it in and start the Build command subroutine
  if (usingSerial && Serial.available() >= 1) {
    // read the incoming byte:
    incomingByte = Serial.read();
    delay(5);
    if (incomingByte == '#') {
    /* Build a new command. */
    bCommandReady = cliBuildCommand(incomingByte);
    }
  }
  else
  {
    incomingByte=0;
    //Serial.flush();
  }

  //If there is a command in the buffer then run the process command subroutine
  if (bCommandReady == true) {
    bCommandReady = false; // reset the command ready flag
    cliProcessCommand(); // run the command
  }
if ((Position != configuration.parkposition)) {
  configuration.parked = 0;
  EEPROM_writeAnything(0, configuration);
}
  if (UPDATE){
    UPDATE=false;
    SerialDATAFun();  // Used to send the current state of the focuser to the PC over serial comms
  }

  //MY OWN BUTTONCODE
  val = digitalRead(buttonIN);
  if (val == LOW)
  {
   

    digitalWrite(dirPin, HIGH);   
   
      digitalWrite(steppin, LOW);  
      digitalWrite(steppin, HIGH);
      delayMicroseconds(0);
    } 
    
  val = digitalRead(buttonOUT);
  if (val == LOW)
  {
    digitalWrite(dirPin, LOW);   
   
      digitalWrite(steppin, HIGH);  
      digitalWrite(steppin, LOW);
      delayMicroseconds(0);
    }
    // END OF MY OWN BUTTONCODE

}

//***************************************************
//*****Start of User defined Functions **************
//***************************************************

//START OF FOCUS CONTROL FUNCTIONS
void EasyDriverStep(boolean dir,long steps){
  digitalWrite(powerPin, HIGH); // enable power to the EasyDriver
  powerMillis = millis(); // remember when power was switched on
  delayMicroseconds(10); // wait a bit after switching on power
  digitalWrite(dirPin,dir);
  delay(100);
  for(int i=0;i<steps;i++){
    digitalWrite(stepperPin, HIGH);
    delayMicroseconds(SPEED);
    digitalWrite(stepperPin, LOW);
    delayMicroseconds(SPEED);
  }
}

void ParkFocuserFun (void) {//Park the focuser by setting the Park bit to 1 and the current Focuser Position in Configuration

if (configuration.parked == false){
configuration.parkposition = Position;
configuration.stepperdirection = Direction;
configuration.parked = true;
configuration.controlboardtype = BoardType;

EEPROM_writeAnything(0, configuration);
}
  UPDATE=true; //Update even if the focuser was already parked
}

void FocusINFun (void) {//Move the Stepper IN.
  long Steps = 0;

  if (Absolute == false) {  //If not Absolute move the number of steps
    if ((Position-NoOfSteps)>=0) {
    switch (BoardType) {
    case 0:
      EasyDriverStep(Direction,NoOfSteps);
      break;
    case 1:
      digitalWrite(13,HIGH); myHalfStepper.step (NoOfSteps); digitalWrite(13,LOW); 
      break;
    case 2:
      motor.step(NoOfSteps, FORWARD, MICROSTEP); motor.release();
      break;
    default: 
      // if nothing else matches, do the default
      // default is optional
      break;
      }
       Position=Position-NoOfSteps;
      }
  }
  else if (NoOfSteps < MaxStep) //Absolute :- work out the number of steps to take based on current position
  {
    if (NoOfSteps<Position){

       Steps=(Position-NoOfSteps);
       switch (BoardType) {
        case 0:
         EasyDriverStep(Direction,Steps);
        break;
        case 1:
         digitalWrite(13,HIGH); myHalfStepper.step (Steps); digitalWrite(13,LOW); 
        break;
        case 2:
         motor.step(Steps, FORWARD, MICROSTEP); motor.release();
        break;
        default: 
      // if nothing else matches, do the default
      // default is optional
      break;
      }
     Position=NoOfSteps;
    }
    else
    {
    Steps=(NoOfSteps-Position);
    switch (BoardType) {
        case 0:
         EasyDriverStep(!Direction,Steps);
        break;
        case 1:
         digitalWrite(13,HIGH); myHalfStepper.step (-Steps); digitalWrite(13,LOW); 
        break;
        case 2:
         motor.step(Steps, BACKWARD, MICROSTEP); motor.release();
        break;
        default:
        break; 
      }
    Position=NoOfSteps;  
    }
  }
  // set the update flag so that the new position is displayed
  IsMoving=true;
  UPDATE=true;
}

void FocusOUTFun (void) {//Move the Stepper OUT.
long Steps = 0;

  if (Absolute == false) {  //If not Absolute move the number of steps
    if ((Position+NoOfSteps)<=MaxStep) {
       switch (BoardType) {
        case 0:
         EasyDriverStep(!Direction,NoOfSteps);
        break;
        case 1:
         digitalWrite(13,HIGH); myHalfStepper.step (-NoOfSteps); digitalWrite(13,LOW); 
        break;
        case 2:
          motor.step(NoOfSteps, BACKWARD, MICROSTEP); motor.release();
        break;
        default: 
      // if nothing else matches, do the default
      // default is optional
       break;
      }
      Position=Position+NoOfSteps;
    }
  }
  else if (NoOfSteps < MaxStep) //Absolute :- work out the number of steps to take based on current position
  {
    if (NoOfSteps>Position){

    Steps=(NoOfSteps-Position);
    switch (BoardType) {
        case 0:
         EasyDriverStep(!Direction,Steps);
        break;
        case 1:
         digitalWrite(13,HIGH); myHalfStepper.step (-Steps); digitalWrite(13,LOW); 
        break;
        case 2:
          motor.step(Steps, BACKWARD, MICROSTEP); motor.release();
        break;
        default: 
      // if nothing else matches, do the default
      // default is optional
       break;
      }
    Position=NoOfSteps;
    }
    else
    {
    Steps=(Position-NoOfSteps);
    switch (BoardType) {
        case 0:
         EasyDriverStep(Direction,Steps);
        break;
        case 1:
         digitalWrite(13,HIGH); myHalfStepper.step (Steps); digitalWrite(13,LOW); 
        break;
        case 2:
         motor.step(Steps, FORWARD, MICROSTEP); motor.release();
        break;
        default: 
      // if nothing else matches, do the default
      // default is optional
       break;
      }
    Position=NoOfSteps;  
    }
  }
  // set the update flag so that the new position is displayed
  IsMoving=true;
  UPDATE=true;
}

void FocusSTEPSFun (void) {//Set the number of Steps.
  NoOfSteps = gParamValue;
  // set the update flag so that the new position is displayed
  UPDATE=true;
}

// function to set the RPM of the stepper motor
// user sends :speed:500:
void FocusSPEEDFun (void) {
  myHalfStepper.setSpeed(gParamValue); // Set the stepper objects speed.
  SPEED = gParamValue;
  UPDATE=true;
}

// Set max limit for focus travel, for absolute positioning focusers
void FocusSLimitFun (void) {
  MaxStep = gParamValue;
  UPDATE=true;
}

// set current focuser position, used for calibrating absolute positioning focusers
void FocusSPositionFun (void) {
  Position = gParamValue;
  UPDATE=true;
}

// set the focuser mode to relative 0 or absolute positioning 1
void FocusSModeFun (void) {
  switch (gParamValue){
  case 0:
    Absolute=false;
    //Serial.println("Relative Mode"); // debug only
    break;
  case 1:
    Absolute=true;
    //Serial.println("Absolute Mode"); // debug only
    break;
  default:
    //Serial.println("0 or 1 for relative or absolute, try again"); // debug only
    break;  
  }
  UPDATE=true;
}
// to add different motor types, stepper, servo or DC
void FocusSTypeFun(void){
  MotorType=gParamValue;
  UPDATE=true;
}

// to add different motor types, stepper, servo or DC
void FocusBoardTypeFun(void){
  BoardType=gParamValue;
  UPDATE=true;
}
//END OF FOCUS CONTROL FUNCTIONS

//Start of serial control functions

void SerialDATAFun (void) {//Update All information over comms if there has been any change in the state of the focuser
   Serial.print("#POS:");  
  Serial.print(Position);
  Serial.println(";");
  Serial.print("#STP:" );
  Serial.print(NoOfSteps);
  Serial.println(";");
  Serial.print("#MDE:");
  if (Absolute){
  Serial.print("1");
  }
  else{  
  Serial.print("0");
  }
  Serial.println(";");
  Serial.print("#LMT:");
  Serial.print(MaxStep);
  Serial.println(";");
   Serial.print("#SPD:");
if (SPEED==0){
  Serial.print(char(SPEED));
  }
  else{  
  Serial.print(SPEED);
  }
  Serial.println(";");
  if (IsMoving==true) {
    Serial.print("#MOV:");
    Serial.print("1");
    Serial.println(";");
    IsMoving=false;
  }
  Serial.print("#BRD:0");  
  Serial.print(BoardType);
  Serial.println(";");
  Serial.print("#PRK:");  
  if (configuration.parked == 1) Serial.print("01"); else Serial.print("00");
  Serial.println(";");
}


//Process Command. This searches the command table to see if the command exits if it does then the required subroutine is run
void cliProcessCommand(void)
{
  int bCommandFound = false;
  int idx;

  /* Convert the parameter to an integer value. 
   * If the parameter is emplty, gParamValue becomes 0. */
  gParamValue = strtol(gParamBuffer, NULL, 0);

  /* Search for the command in the command table until it is found or
   * the end of the table is reached. If the command is found, break
   * out of the loop. */
  for (idx = 0; gCommandTable[idx].name != NULL; idx++) {
    if (strcmp(gCommandTable[idx].name, gCommandBuffer) == 0) {
      bCommandFound = true;
      break;
    }
  }

  /* If the command was found, call the command function. Otherwise,
   * output an error message. */
  if (bCommandFound == true) {
    (*gCommandTable[idx].function)();
  }
}


//When data is in the Serial buffer this subroutine is run and the information put into a command buffer.
// The character : is used to define the end of a Command string and the start of the parameter string
// The character ; is used to define the end of the Parameter string
int cliBuildCommand(char nextChar) {
  static uint8_t idx = 0; //index for command buffer
  static uint8_t idx2 = 0; //index for parameter buffer
  int loopchk = 0;

  nextChar = Serial.read();
  do
  {

    gCommandBuffer[idx] = TO_UPPER(nextChar);
    idx++;
    nextChar = Serial.read();
    loopchk=loopchk+1;
  } 
  while ((nextChar != ':') && (loopchk < 100));

  loopchk=0;

  nextChar = Serial.read();

  do
  {

    gParamBuffer[idx2] = nextChar;
    idx2++;
    nextChar = Serial.read();
  } 
  while ((nextChar != ';')&& (idx2 < 100));



  gCommandBuffer[idx] = '\0';
  gParamBuffer[idx2] = '\0';
  idx = 0;
  idx2 = 0;

  return true;
}

//END of serial control functions
TS N-AG10
Celestron C9.25" XLT
Meade 102mm APO
Astro Systeme Austria (ASA) DDM85
NEQ6 Pro Synscan
Atik 460 EX
SX Filterwheel LRGB Ha O3 S2

http://www.facebook.com/exophotograph" onclick="window.open(this.href);return false;
Starsoft
Posts: 1501
Joined: 2007-09-20 14:21:00
Location: Gävle
Contact:

Re: DYI motorfokuserare

Post by Starsoft »

Har två olika "int" för samma pin, nämligen "stepperpin" och "steppin" som båda är utgång 3 till easydrivern, kan det vara orsaken?
Att göra så är onödigt men inte fel, "stepperpin" och "steppin" har båda värdet 3 vilket bara anger vilken utgång som avses nar man anropar digitalwrite(), har ingen funktion för övrigt.

Däremot kan det bli förvirring om utgången anropas från det befintliga programmet samtidigt som du trycker på en knapp, men om du inte samtidigt ger kommando från PC och trycker på en knapp så bör inte det bli något problem.

Nu finns inte huvudloopen med i den här koden men jag skulle tro att trögheten beror på att processorn inte är snabbare. Funktionen loop() anropas antagligen från huvudloopen och om en av dina knappar är intryckt så går motorn bara två steg vid varje anrop, och det finns antagligen så mycket irrelevant kod som ska exekveras i huvudloopen så att dina knappar kontrolleras för sällan.

Du kan prova att "kapa" huvudloopen när du trycker in en knapp.


if (digitalRead(buttonIN))
digitalWrite(dirPin, HIGH);

while (digitalRead(buttonIN)) {
digitalWrite(steppin, LOW);
delayMicroseconds(0);
digitalWrite(steppin, HIGH);
delayMicroseconds(0);
}

if (digitalRead(buttonOUT))
digitalWrite(dirPin, LOW);

while (digitalRead(buttonIN)) {
digitalWrite(steppin, HIGH);
delayMicroseconds(0);
digitalWrite(steppin, LOW);
delayMicroseconds(0);
}

Ett bättre sätt vore att använda 4 knappar, in snabbt, ut snabbt, in sakta och ut sakta. När en knapp är intryckt så simuleras ett PC-kommando och fokuseraren går ett visst antal steg, då behåller du den befintliga funktionaliteten med aktuell position även fast du trycker på dina knappar och knappkommandon kan inte komma i konflikt med PC kommandon.

Lycka till
Anders
Observatorium v2.0: http://www.hemlin.se/astroweb
Corpze
Posts: 1012
Joined: 2012-03-01 04:00:53
spamtest: JA
Location: Arvika

Re: DYI motorfokuserare

Post by Corpze »

Tackar för svar, det låter logiskt, jag kommer inte att köra pc OCH knapparna, utan använda antingen eller, ska prova koden så fort jag kan och återkomma med svar, är det själva "while" kommandot som gör att den antingen läser från pc eller mina knappar? Senare skall jag även koppla på lcd och försöka läsa ut aktuella steps också :-)
TS N-AG10
Celestron C9.25" XLT
Meade 102mm APO
Astro Systeme Austria (ASA) DDM85
NEQ6 Pro Synscan
Atik 460 EX
SX Filterwheel LRGB Ha O3 S2

http://www.facebook.com/exophotograph" onclick="window.open(this.href);return false;
Starsoft
Posts: 1501
Joined: 2007-09-20 14:21:00
Location: Gävle
Contact:

Re: DYI motorfokuserare

Post by Starsoft »

Hej

While { ... } satsen gör att så länge som knappen är intryckt så gör processorn inget annat än det som står inom while { } klammerna, (förutom avbrottstyrd hantering, om sådan finns). Då kommer pulserna att skickas ut med nästan högsta möjliga frekvens och nu kan det bli att dom i stället skickas så snabbt så att stegmotordrivern inte hinner med, så du kan nog behöva stoppa i något lämpligt värde i DelayMicroseconds() funktionerna för att få det att fungera.

Om du styr drivern direkt med knapparna på det här sättet så måste du skapa en egen positionsräknare får att kunna visa position.

Kul att se att det pågår kreativ DIY här på Astronet.

Anders
Observatorium v2.0: http://www.hemlin.se/astroweb
Corpze
Posts: 1012
Joined: 2012-03-01 04:00:53
spamtest: JA
Location: Arvika

Re: DYI motorfokuserare

Post by Corpze »

Om jag skriver en egen stegräknare och sätter även de i whiletaggar så "ska" inte "Ascom"-koden påverkas om jag förstått rätt?
TS N-AG10
Celestron C9.25" XLT
Meade 102mm APO
Astro Systeme Austria (ASA) DDM85
NEQ6 Pro Synscan
Atik 460 EX
SX Filterwheel LRGB Ha O3 S2

http://www.facebook.com/exophotograph" onclick="window.open(this.href);return false;
Corpze
Posts: 1012
Joined: 2012-03-01 04:00:53
spamtest: JA
Location: Arvika

Re: DYI motorfokuserare

Post by Corpze »

Nu har jag provat att dels mata in den koden du skrev, men även att bara infoga while-taggarna i den koden jag skrev men utan framgång, motorn går lika sakta ändå, men den går hela tiden som knappen är intryckt, och den fungerar både in och ut, men ett varv kanske tar en minut eller något sådant, dvs enormt långsamt... jag kanske inte lyckades foga in whiletaggarna rätt?

MVH
TS N-AG10
Celestron C9.25" XLT
Meade 102mm APO
Astro Systeme Austria (ASA) DDM85
NEQ6 Pro Synscan
Atik 460 EX
SX Filterwheel LRGB Ha O3 S2

http://www.facebook.com/exophotograph" onclick="window.open(this.href);return false;
Starsoft
Posts: 1501
Joined: 2007-09-20 14:21:00
Location: Gävle
Contact:

Re: DYI motorfokuserare

Post by Starsoft »

Med den utväxlingen jag har kommer jag få ca 500.000 steg
Läste detta tidigare i tråden, jag ser ingen växellåda på motorn så det verkar konstigt med så många steg.

Verkar klokt att få den att fungera rimligt med ASCOM innan du börja modifiera koden.

Anders
Observatorium v2.0: http://www.hemlin.se/astroweb
Corpze
Posts: 1012
Joined: 2012-03-01 04:00:53
spamtest: JA
Location: Arvika

Re: DYI motorfokuserare

Post by Corpze »

Utväxlingen är faktiskt ganska perfekt, lagom hastighet med styrningen via Ascom, som funkar perfekt, det är bara min egenmoddade kod som fungerar sådär :-P
TS N-AG10
Celestron C9.25" XLT
Meade 102mm APO
Astro Systeme Austria (ASA) DDM85
NEQ6 Pro Synscan
Atik 460 EX
SX Filterwheel LRGB Ha O3 S2

http://www.facebook.com/exophotograph" onclick="window.open(this.href);return false;
Corpze
Posts: 1012
Joined: 2012-03-01 04:00:53
spamtest: JA
Location: Arvika

Re: DYI motorfokuserare

Post by Corpze »

Nu har jag klurat lite ytterligare, jag har bytt namn på "int steppin till samma som orginalkoden, dvs stepperPin så att inte två olika int hänvisar till samma Pin, Men dett hjälpte dock inte, däremot så kom jag på att anledningen till att motorn verkar "låst" är att under void setup, och EEPROM så står det såhär;

Code: Select all

void setup() {

  EEPROM_readAnything(0, configuration); //PARKING:- Read the Position and Parked info
    if (configuration.parked == true) { //If the Focuser was Parked then load the Position information
Ändrar jag till (configuration.parked == false) så kan jag köra med knapparna i önskad hastighet, denna funktion skulle man (om jag förstår rätt) kunna "hoppa över" med while-kommando?

MVH Daniel


Hela koden;

Code: Select all

#include <SPI.h>
//START OF FOCUS CONTROL INITIALISE
// include the library code:
#include <EEPROM.h>
#include <eepromRW.h>
#include <HalfStepper.h>
#include <AFMotor.h>
AF_Stepper motor(200, 2); // steps per rev and the connection of the stepper to AFmotor shield (2nd chip M3/M4)

#define MAX_COMMAND_LEN             (5)
#define MAX_PARAMETER_LEN           (6)
#define COMMAND_TABLE_SIZE          (11)
#define TO_UPPER(x) (((x >= 'a') && (x <= 'z')) ? ((x) - ('a' - 'A')) : (x))

// initialize the library with the numbers of the interface pins
int dirPin = 2; // Easy Driver Direction Output Pin
int stepperPin = 3; // EasyDriver Stepper Step Output Pin
int powerPin = 4; //Sets the output used to power the Driver board
unsigned long powerMillis = 0; // used to remember when EasyDriver power was enabled
int motorSteps =200; //number if steps for the motor to turn 1 revolution                      altered from 3200 to 200

// MY OWN BUTTONCODE
int buttonIN = 5;
int buttonOUT = 6;
int val = 0;
// END OF MY OWN BUTTONCODE

volatile long NoOfSteps = 1000; //required number of steps to make
volatile long Position = 0; //used to keep track of the current motorposition
volatile long MaxStep = 200000; //define maximum no. of steps, max travel
volatile int SPEED = 500;
volatile byte MotorType = 0; // Motortypes, default is 0, Stepper motor, 1=Servo, 2=DC motor                           
volatile int BoardType = 0; // Boardtypes, default is 0, EasyDriver, 1=L293 chip, 2=LadyAda AFmotor board                           

boolean Direction = true;//True is one way false is other.Change to false if motor is moving in the wrong direction
boolean IsMoving = false;
boolean Absolute = true;
volatile long MaxIncrement=16384;//not yet used
HalfStepper myHalfStepper = HalfStepper(960, 9, 10, 11, 12);
//END OF FOCUS CONTROL INITIALISE

//Serial comms setup
char incomingByte = 0; // serial in data byte
byte serialValue = 0;
boolean usingSerial = true; // set to false to have the buttons control everything
char gCommandBuffer[MAX_COMMAND_LEN + 1];
char gParamBuffer[MAX_PARAMETER_LEN + 1];
long gParamValue;
volatile boolean UPDATE = true;

struct config_t //Memory Structure for Parking, Unparking the Focuser and other config settings 
{
    long parkposition;
    boolean parked;
    boolean stepperdirection;
    long controlboardtype;
} configuration;


typedef struct {
  char const    *name;
  void          (*function)(void);
} 
command_t;

//Set up a command table. when the command "IN" is sent from the PC and this table points it to the subroutine to run
command_t const gCommandTable[COMMAND_TABLE_SIZE] = {
  {
    "IN1",     FocusINFun,  }
  ,
  {
    "OUT",    FocusOUTFun,   }
  ,
  {
    "STP",  FocusSTEPSFun,   }
  ,
  {
    "SPD",  FocusSPEEDFun,   }
  ,
  {
    "LMT",  FocusSLimitFun,   }
  ,
  {
    "POS",    FocusSPositionFun,   }
  ,  
  {
    "MDE",   FocusSModeFun,   }
  ,
  {
    "TYP",   FocusSTypeFun,   }
  ,  
  {
    "PRK",   ParkFocuserFun,   }
  ,  
  {
    "BRD",   FocusBoardTypeFun,   }
  ,  
  {
    NULL,      NULL   }
};

//Serial Comms setup end

void setup() {

  EEPROM_readAnything(0, configuration); //PARKING:- Read the Position and Parked info
    if (configuration.parked == true) { //If the Focuser was Parked then load the Position information
     Position = configuration.parkposition; //Load the Position information
     Direction = configuration.stepperdirection;
     BoardType = configuration.controlboardtype;
  }

  pinMode(dirPin, OUTPUT); //Initialise Easydriver output
  pinMode(stepperPin, OUTPUT); //Initialise easy driver output
  //START OF FOCUS CONTROL SETUP
   //END OF FOCUS CONTROL SETUP
  Serial.begin(19200);// start the serial
  myHalfStepper.setSpeed(SPEED);
  NoOfSteps=1000;
  pinMode(13,OUTPUT); 
  pinMode(powerPin,OUTPUT); //Easydriver Sleepmode or power off
  digitalWrite(powerPin, LOW); //Easydriver Pwer off (Low = powered down)
  
  // MY OWN BUTTONCODE
  pinMode(dirPin, OUTPUT);
  pinMode(stepperPin, OUTPUT);
  pinMode(buttonIN, INPUT_PULLUP);
  pinMode(buttonOUT, INPUT_PULLUP);
  // END OF MY OWN BUTTONCODE
  
}

void loop() {
 
  int bCommandReady = false;
  
  //FocuserControl Power off command
  if (millis() > (powerMillis + 20000)) // check if power has been on for more than 20 seconds
  {
      digitalWrite(powerPin, LOW); // if yes, then disable power
  }
  
  //If There is information in the Serial buffer read it in and start the Build command subroutine
  if (usingSerial && Serial.available() >= 1) {
    // read the incoming byte:
    incomingByte = Serial.read();
    delay(5);
    if (incomingByte == '#') {
    /* Build a new command. */
    bCommandReady = cliBuildCommand(incomingByte);
    }
  }
  else
  {
    incomingByte=0;
    //Serial.flush();
  }

  //If there is a command in the buffer then run the process command subroutine
  if (bCommandReady == true) {
    bCommandReady = false; // reset the command ready flag
    cliProcessCommand(); // run the command
  }
 if ((Position != configuration.parkposition)) {
  configuration.parked = 0;
  EEPROM_writeAnything(0, configuration);
 }
  if (UPDATE){
    UPDATE=false;
    SerialDATAFun();  // Used to send the current state of the focuser to the PC over serial comms
  }
  
//MY OWN BUTTONCODE

  val = digitalRead(buttonIN);
  if (val == LOW)
  {
   

    digitalWrite(dirPin, HIGH);   
   
      digitalWrite(stepperPin, LOW);  
      digitalWrite(stepperPin, HIGH);
      delayMicroseconds(200);
    } 
    
  val = digitalRead(buttonOUT);
  if (val == LOW)
  {
    digitalWrite(dirPin, LOW);   
   
      digitalWrite(stepperPin, HIGH);  
      digitalWrite(stepperPin, LOW);
      delayMicroseconds(200);
    }
 // END OF MY OWN BUTTONCODE

}

//***************************************************
//*****Start of User defined Functions **************
//***************************************************

//START OF FOCUS CONTROL FUNCTIONS
void EasyDriverStep(boolean dir,long steps){
  digitalWrite(powerPin, HIGH); // enable power to the EasyDriver
  powerMillis = millis(); // remember when power was switched on
  delayMicroseconds(10); // wait a bit after switching on power
  digitalWrite(dirPin,dir);
  delay(100);
  for(int i=0;i<steps;i++){
    digitalWrite(stepperPin, HIGH);
    delayMicroseconds(SPEED);
    digitalWrite(stepperPin, LOW);
    delayMicroseconds(SPEED);
  }
}

void ParkFocuserFun (void) {//Park the focuser by setting the Park bit to 1 and the current Focuser Position in Configuration

 if (configuration.parked == false){
 configuration.parkposition = Position;
 configuration.stepperdirection = Direction;
 configuration.parked = true;
 configuration.controlboardtype = BoardType;
 
 EEPROM_writeAnything(0, configuration);
 }
  UPDATE=true; //Update even if the focuser was already parked
}

void FocusINFun (void) {//Move the Stepper IN.
  long Steps = 0;

  if (Absolute == false) {  //If not Absolute move the number of steps
    if ((Position-NoOfSteps)>=0) {
    switch (BoardType) {
    case 0:
      EasyDriverStep(Direction,NoOfSteps);
      break;
    case 1:
      digitalWrite(13,HIGH); myHalfStepper.step (NoOfSteps); digitalWrite(13,LOW); 
      break;
    case 2:
      motor.step(NoOfSteps, FORWARD, MICROSTEP); motor.release();
      break;
    default: 
      // if nothing else matches, do the default
      // default is optional
      break;
      }
       Position=Position-NoOfSteps;
      }
  }
  else if (NoOfSteps < MaxStep) //Absolute :- work out the number of steps to take based on current position
  {
    if (NoOfSteps<Position){
    
       Steps=(Position-NoOfSteps);
       switch (BoardType) {
        case 0:
         EasyDriverStep(Direction,Steps);
        break;
        case 1:
         digitalWrite(13,HIGH); myHalfStepper.step (Steps); digitalWrite(13,LOW); 
        break;
        case 2:
         motor.step(Steps, FORWARD, MICROSTEP); motor.release();
        break;
        default: 
      // if nothing else matches, do the default
      // default is optional
      break;
      }
     Position=NoOfSteps;
    }
    else
    {
    Steps=(NoOfSteps-Position);
    switch (BoardType) {
        case 0:
         EasyDriverStep(!Direction,Steps);
        break;
        case 1:
         digitalWrite(13,HIGH); myHalfStepper.step (-Steps); digitalWrite(13,LOW); 
        break;
        case 2:
         motor.step(Steps, BACKWARD, MICROSTEP); motor.release();
        break;
        default:
        break; 
      }
    Position=NoOfSteps;  
    }
  }
  // set the update flag so that the new position is displayed
  IsMoving=true;
  UPDATE=true;
}

void FocusOUTFun (void) {//Move the Stepper OUT.
 long Steps = 0;

  if (Absolute == false) {  //If not Absolute move the number of steps
    if ((Position+NoOfSteps)<=MaxStep) {
       switch (BoardType) {
        case 0:
         EasyDriverStep(!Direction,NoOfSteps);
        break;
        case 1:
         digitalWrite(13,HIGH); myHalfStepper.step (-NoOfSteps); digitalWrite(13,LOW); 
        break;
        case 2:
          motor.step(NoOfSteps, BACKWARD, MICROSTEP); motor.release();
        break;
        default: 
      // if nothing else matches, do the default
      // default is optional
       break;
      }
      Position=Position+NoOfSteps;
    }
  }
  else if (NoOfSteps < MaxStep) //Absolute :- work out the number of steps to take based on current position
  {
    if (NoOfSteps>Position){
    
    Steps=(NoOfSteps-Position);
    switch (BoardType) {
        case 0:
         EasyDriverStep(!Direction,Steps);
        break;
        case 1:
         digitalWrite(13,HIGH); myHalfStepper.step (-Steps); digitalWrite(13,LOW); 
        break;
        case 2:
          motor.step(Steps, BACKWARD, MICROSTEP); motor.release();
        break;
        default: 
      // if nothing else matches, do the default
      // default is optional
       break;
      }
    Position=NoOfSteps;
    }
    else
    {
    Steps=(Position-NoOfSteps);
    switch (BoardType) {
        case 0:
         EasyDriverStep(Direction,Steps);
        break;
        case 1:
         digitalWrite(13,HIGH); myHalfStepper.step (Steps); digitalWrite(13,LOW); 
        break;
        case 2:
         motor.step(Steps, FORWARD, MICROSTEP); motor.release();
        break;
        default: 
      // if nothing else matches, do the default
      // default is optional
       break;
      }
    Position=NoOfSteps;  
    }
  }
  // set the update flag so that the new position is displayed
  IsMoving=true;
  UPDATE=true;
}

void FocusSTEPSFun (void) {//Set the number of Steps.
  NoOfSteps = gParamValue;
  // set the update flag so that the new position is displayed
  UPDATE=true;
}

// function to set the RPM of the stepper motor
// user sends :speed:500:
void FocusSPEEDFun (void) {
  myHalfStepper.setSpeed(gParamValue); // Set the stepper objects speed.
  SPEED = gParamValue;
  UPDATE=true;
}

// Set max limit for focus travel, for absolute positioning focusers
void FocusSLimitFun (void) {
  MaxStep = gParamValue;
  UPDATE=true;
}

// set current focuser position, used for calibrating absolute positioning focusers
void FocusSPositionFun (void) {
  Position = gParamValue;
  UPDATE=true;
}

// set the focuser mode to relative 0 or absolute positioning 1
void FocusSModeFun (void) {
  switch (gParamValue){
  case 0:
    Absolute=false;
    //Serial.println("Relative Mode"); // debug only
    break;
  case 1:
    Absolute=true;
    //Serial.println("Absolute Mode"); // debug only
    break;
  default:
    //Serial.println("0 or 1 for relative or absolute, try again"); // debug only
    break;  
  }
  UPDATE=true;
}
// to add different motor types, stepper, servo or DC
void FocusSTypeFun(void){
  MotorType=gParamValue;
  UPDATE=true;
}

// to add different motor types, stepper, servo or DC
void FocusBoardTypeFun(void){
  BoardType=gParamValue;
  UPDATE=true;
}
//END OF FOCUS CONTROL FUNCTIONS

//Start of serial control functions

void SerialDATAFun (void) {//Update All information over comms if there has been any change in the state of the focuser
   Serial.print("#POS:");  
  Serial.print(Position);
  Serial.println(";");
  Serial.print("#STP:" );
  Serial.print(NoOfSteps);
  Serial.println(";");
  Serial.print("#MDE:");
  if (Absolute){
  Serial.print("1");
  }
  else{  
  Serial.print("0");
  }
  Serial.println(";");
  Serial.print("#LMT:");
  Serial.print(MaxStep);
  Serial.println(";");
   Serial.print("#SPD:");
 if (SPEED==0){
  Serial.print(char(SPEED));
  }
  else{  
  Serial.print(SPEED);
  }
  Serial.println(";");
  if (IsMoving==true) {
    Serial.print("#MOV:");
    Serial.print("1");
    Serial.println(";");
    IsMoving=false;
  }
  Serial.print("#BRD:0");  
  Serial.print(BoardType);
  Serial.println(";");
  Serial.print("#PRK:");  
  if (configuration.parked == 1) Serial.print("01"); else Serial.print("00");
  Serial.println(";");
}


//Process Command. This searches the command table to see if the command exits if it does then the required subroutine is run
void cliProcessCommand(void)
{
  int bCommandFound = false;
  int idx;

  /* Convert the parameter to an integer value. 
   * If the parameter is emplty, gParamValue becomes 0. */
  gParamValue = strtol(gParamBuffer, NULL, 0);

  /* Search for the command in the command table until it is found or
   * the end of the table is reached. If the command is found, break
   * out of the loop. */
  for (idx = 0; gCommandTable[idx].name != NULL; idx++) {
    if (strcmp(gCommandTable[idx].name, gCommandBuffer) == 0) {
      bCommandFound = true;
      break;
    }
  }

  /* If the command was found, call the command function. Otherwise,
   * output an error message. */
  if (bCommandFound == true) {
    (*gCommandTable[idx].function)();
  }
}


//When data is in the Serial buffer this subroutine is run and the information put into a command buffer.
// The character : is used to define the end of a Command string and the start of the parameter string
// The character ; is used to define the end of the Parameter string
int cliBuildCommand(char nextChar) {
  static uint8_t idx = 0; //index for command buffer
  static uint8_t idx2 = 0; //index for parameter buffer
  int loopchk = 0;

  nextChar = Serial.read();
  do
  {

    gCommandBuffer[idx] = TO_UPPER(nextChar);
    idx++;
    nextChar = Serial.read();
    loopchk=loopchk+1;
  } 
  while ((nextChar != ':') && (loopchk < 100));

  loopchk=0;

  nextChar = Serial.read();

  do
  {

    gParamBuffer[idx2] = nextChar;
    idx2++;
    nextChar = Serial.read();
  } 
  while ((nextChar != ';')&& (idx2 < 100));



  gCommandBuffer[idx] = '\0';
  gParamBuffer[idx2] = '\0';
  idx = 0;
  idx2 = 0;

  return true;
}

//END of serial control functions


TS N-AG10
Celestron C9.25" XLT
Meade 102mm APO
Astro Systeme Austria (ASA) DDM85
NEQ6 Pro Synscan
Atik 460 EX
SX Filterwheel LRGB Ha O3 S2

http://www.facebook.com/exophotograph" onclick="window.open(this.href);return false;
Starsoft
Posts: 1501
Joined: 2007-09-20 14:21:00
Location: Gävle
Contact:

Re: DYI motorfokuserare

Post by Starsoft »

Hej

Nu kanske det klarnar lite...
EEPROM_readAnything(0, configuration); //PARKING:- Read the Position and Parked info
Här läser programmet information, typ av drivkrets, konfigurering och position som (ev) sparades när fokuseraren parkerades, från det permanenta minnet.
if (configuration.parked == true) { //If the Focuser was Parked then load the Position information
Här görs en kontroll om någon konfigurering har sparats, (configuration.parked == true) är ett villkor som blir sant om det fanns sparad konfigurering. Om det villkoret är sant så utförs koden som följer (som inte syns i tråden). Om du byter utrycket till (configuration.parked == false) så kommer den följande koden att utföras om ingen konfigurering har sparats.

Det verkar väl då som att anledningen till att det inte fungerar med dina knappar är att drivkretsen till stegmotorn inte blir rätt konfigurerad när programmet söker konfigurering, när du får det att fungera genom att ändra villkoret så att koden utförs även utan att det finns någon konfigurering så tyder det väl på att någon del av den följande koden måste utföras för att drivkretsen ska initieras på ett riktigt sätt.

Så det kanske inte är något problem med hanteringen av dina knappar.

Vore intressant att se koden som kommer efter villkoret.

Anders
Observatorium v2.0: http://www.hemlin.se/astroweb