Teleskop-fokuserare via Arduino, Nu fungerar knapparna!

PIC, AVR, Arduino, Raspberry Pi, Basic Stamp, PLC mm.
Användarvisningsbild
PHermansson
EF Sponsor
Inlägg: 4340
Blev medlem: 22 december 2004, 00:46:38
Ort: Särestad Grästorp
Kontakt:

Re: Teleskop-fokuserare via Arduino, manuell styrning behövs

Inlägg av PHermansson »

-Du ska/kan inte ha flera setup eller loop. Kod som ska köras konstant i en loop ska in i den befintliga loop(), det som ska köras en gång vid uppstart ska in i befintlig setup().
-För knappar finns kod att kolla på i Examples, kan också vara värt att titta på biblioteket Bounce.
-Ett annat sätt att kommantera ut är // som kommenterar ut en enskild rad. Ex:

Kod: Markera allt

/*
Attiny reads temperature sensor DS18B20.
Output value is printed to (software) serial port.

Arduino Duemilanove is used as programmer according to http://hlt.media.mit.edu/?p=1695.

C Patrik Hermansson 2013
GPL v2
*/

#include <OneWire.h>
// From the Tiny core.
#include <TinyDebugSerial.h>
Corpze
Inlägg: 256
Blev medlem: 29 januari 2013, 17:31:27

Re: Teleskop-fokuserare via Arduino, manuell styrning behövs

Inlägg av Corpze »

Tackar för alla star, nästan så man skäms för att posta här då det verkar som att ni besitter så stor kunskap om kodning, hursomhelst så har jag klurat lite på egen kammare nu och vad jag tror lagt #define och void setup på rätt ställe, när jag kompilerade sketchen så klagade den inte iaf.

Men en sak som jag inte förstår är hur jag skall utforma void-kommandona så de faktiskt driver motor fram och tillbaka, när jag skrev in bad som är mitt första försök till void-kod så fick jag dessa varningar, vad jag förstår så har det att göra med klammrarna? Jag har markerat det jag skrivit i med EGEN KOD

MVH

Kod: Markera allt



#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))

EGEN KOD #define BUTTONIN_PIN 5
EGEN KOD #define BUTTONOUT_PIN 6

// 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

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)



EGEN KOD:

  pinMode(BUTTONIN_PIN, INPUT);
  digitalWrite(BUTTONIN_PIN, HIGH); // connect internal pull-up
  pinMode(BUTTONOUT_PIN, INPUT);
  digitalWrite(BUTTONOUT_PIN, HIGH);


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
  }


}

//***************************************************
//*****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;
}

EGEN KOD

  if (BUTTONIN_PIN = LOW);
  void FocusINFun (void)  
  }
  
  { if (BUTTONOUT_PIN = LOW);
  void FocusOUTFun (void)

}

//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 
Senast redigerad av Corpze 31 januari 2013, 20:07:05, redigerad totalt 2 gånger.
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Re: Teleskop-fokuserare via Arduino, manuell styrning behövs

Inlägg av sodjan »

Gjorde du en "Förhandsgranska" ?
Blev det då rött hos dig ?
BB-koder fungerar inte inom code-taggar...
Corpze
Inlägg: 256
Blev medlem: 29 januari 2013, 17:31:27

Re: Teleskop-fokuserare via Arduino, manuell styrning behövs

Inlägg av Corpze »

Gjorde du en "Förhandsgranska" ?
Blev det då rött hos dig ?
BB-koder fungerar inte inom code-taggar...

-Ja
-Nej
-Uppenbarligen inte!
Användarvisningsbild
mri
Inlägg: 1165
Blev medlem: 15 mars 2007, 13:20:50
Ort: Jakobstad, Finland
Kontakt:

Re: Teleskop-fokuserare via Arduino, manuell styrning behövs

Inlägg av mri »

Ser ut som du kopierat/flyttat in fuktionen loop() innuti funktionen setup(). Sånt går inte i "C".

Strukturen borde vara nåt i stil med:

void setup()
{

// en massa kod

}

void loop()
{

// en massa kod

}

Man måste hålla reda på start och slutklamrarna.
Corpze
Inlägg: 256
Blev medlem: 29 januari 2013, 17:31:27

Re: Teleskop-fokuserare via Arduino, manuell styrning behövs

Inlägg av Corpze »

Sådär, nu börjar det lossna lite iaf, jag har gjort en egen kod för att få igång motorn med två knappar, det funkade prima så jag provade att lyfta in den koden i den stora "SGL"-koden, och nu har jag även börjat förstå klamrarna!

Men när jag "uploadat" min egenmoddade kod rör sigmotorn 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

Kod: Markera allt

#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
Corpze
Inlägg: 256
Blev medlem: 29 januari 2013, 17:31:27

Re: Teleskop-fokuserare via Arduino, manuell styrning behövs

Inlägg av 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;

Kod: Markera allt

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;

Kod: Markera allt

#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


Corpze
Inlägg: 256
Blev medlem: 29 januari 2013, 17:31:27

Re: Teleskop-fokuserare via Arduino, konflikt med EEprom-str

Inlägg av Corpze »

Nu har jag fått ordning på koden, eftersom EEprom har en begränsad livslängd så undvek jag att rensa minnet för att inte "parked" läget skulle initieras, såhär blev det iaf;

Kod: Markera allt

#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

// 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

//IN

delayMicroseconds(200);
val = digitalRead(buttonIN);
  if (val == LOW)
  {
    digitalWrite(powerPin, HIGH);
    digitalWrite(dirPin, HIGH);
    while (val == LOW) {
      digitalWrite(stepperPin, HIGH);
      delayMicroseconds(300);
      digitalWrite(stepperPin, LOW);
      delayMicroseconds(300);
      val = digitalRead(buttonIN);
    }
    powerMillis = millis();
  }
  
//OUT

delayMicroseconds(200);
  val = digitalRead(buttonOUT);
  if (val == LOW)
  {
    digitalWrite(powerPin, HIGH);
    digitalWrite(dirPin, LOW);
    while (val == LOW) {
      digitalWrite(stepperPin, HIGH);
      delayMicroseconds(300);
      digitalWrite(stepperPin, LOW);
      delayMicroseconds(300);
      val = digitalRead(buttonOUT);
    }
    powerMillis = millis();
  }
 // 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


Skriv svar