INFO: Dieses Forum nutzt Cookies...
Cookies sind für den Betrieb des Forums unverzichtbar. Mit der Nutzung des Forums erklärst Du dich damit einverstanden, dass wir Cookies verwenden.

Es wird in jedem Fall ein Cookie gesetzt um diesen Hinweis nicht mehr zu erhalten. Desweiteren setzen wir Google Adsense und Google Analytics ein.

Antwort schreiben 
 
Themabewertung:
  • 0 Bewertungen - 0 im Durchschnitt
  • 1
  • 2
  • 3
  • 4
  • 5
Schrittmotorlibrary wechseln
28.05.2014, 00:51 (Dieser Beitrag wurde zuletzt bearbeitet: 28.05.2014 00:52 von flyingeagle.)
Beitrag #1
Schrittmotorlibrary wechseln
Hallo,

Ich habe folgendes Problem. Ich baue gerade für mein Teleskop ein Filterrad.
Mit diesem Filterrad ist es möglich mit der s/w CCD Kamera Farbaufnahmen zu machen.
In diesem Rad sind dazu 5 Filter angebracht. Zu jedem Filter ist ein Magnet zur Positionsermittlung vorhanden. Vier Filter mit Nördlicher Ausrichtung ,und zum Indexieren des Nullpunktes bzw. dem ersten Filter mit Südlicher Ausrichtung. Erfaßt werden sie über einen Hall Sensor. Zur Hardware habe ich einen Arduino Uno und einen baugleichen Adafruit Stepper/Servo Shield.
Gesteuert wird das ganze dann über ein Plugin für das Aufnahmeprogramm.
Ich habe schon die komplette Firmware für das Arduino und auch das Plugin, leider arbeitet die Firmware mit der Stepper Library. Und so wie es aussieht kann ich mit dem Motorshield nur die AFMotor Library nutzen. Leider bin ich beim Programmieren noch ein blutiger Anfänger, aber wenn ich jetzt anfange ein eigenes Programm samt Plugin zu schreiben vergehen wohl Jahre. Bin seit mittlerweile 2 Wochen durchgängig schon am Lernen, aber irgendwie stellen sich mir mehr fragen als ich Antworten bekomme.
Klar möchte ich nebenbei ein wenig Programmieren lernen, aber Ich würde gerne dieses Filterrad auch noch recht schnell fertigbekommen. Bin eigentlich mehr der Basteler als Programmierer Big Grin
Ich hoffe mir kann da jemand helfen.
Dabei noch ein Foto vom aktuellen Baustatus sowie der Originalcode

Viele Grüße

Micha


Angehängte Datei(en) Thumbnail(s)
   

.ino  Filterwheel.ino (Größe: 14,25 KB / Downloads: 142)
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
28.05.2014, 06:13
Beitrag #2
RE: Schrittmotorlibrary wechseln
Hallo Micha,

hast du mal einen Link zum Motorshield? Ist schon wichtig genau zu wissen was das für ein Teil ist.

Grüße Ricardo

Nüchtern betrachtet...ist besoffen besser Big Grin
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
28.05.2014, 07:33 (Dieser Beitrag wurde zuletzt bearbeitet: 28.05.2014 08:00 von flyingeagle.)
Beitrag #3
RE: Schrittmotorlibrary wechseln
http://www.adafruit.com/products/81

Es ist nicht von Adafruit , sondern von DK Electronics. Es sieht aber genauso aus und ist
eigentlich komplett Baugleich.
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
29.05.2014, 07:33 (Dieser Beitrag wurde zuletzt bearbeitet: 29.05.2014 07:35 von flyingeagle.)
Beitrag #4
RE: Schrittmotorlibrary wechseln
Also so wie es aussieht kann man diesen Shield wirklich nur über die AFMotor Library ansprechen, da er nicht wie üblich direkt über die Pins mit dem Motor kommuniziert wie es z.B. beim easydriver ist.
Da bleibt mir wohl nichts anderes übrig als einen anderen Motor Shield zu besorgen.

Den vorhandenen Sketch umzuprogrammieren ist ziemlich schwierig , da die beiden Library komplett verschieden sind.

Hab mir jetzt seit Tagen den Kopf zerbrochen, aber als Anfänger fällt mir keine Lösung mehr ein. Huh
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
29.05.2014, 09:30 (Dieser Beitrag wurde zuletzt bearbeitet: 29.05.2014 10:04 von rkuehle.)
Beitrag #5
RE: Schrittmotorlibrary wechseln
Hallo Micha,

ich habe den Code jetzt mal an die AF_Motor - Library angepasst.
AberExclamationExclamationExclamation
Ich weiß nicht ob der Code jetzt so arbeitet wie du es erwartest, da ich die entsprechende Hardware nicht habe. Zumindest aber geht er durch den Compiler.
Code:
/*
* Filterwheel
* Provides for control of a five position filter wheel.
*
* Copyright (C) 2014 Howard Dutton
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program.  If not, see <http://www.gnu.org/licenses/>.
*
*
*
* Revision History
*
* Date                Version           Comment
* 03-16-2014          1.0               Adaptation of Camera/Filterwheel driver to filterwheel only
* 05-26-2014          1.1               Added code at adjust the stepping granularity
*
* Author: Howard Dutton
* http://www.stellarjourney.com
*
*
*/

#include "stdio.h";
#include "EEPROM.h";
// *** #include <Stepper.h>
#include <AFMotor.h>

#define fullRotation 280            // enough slots to hold reading a bit more than once around the wheel (for finding index/calibration), keep under about 1000
#define stepGranularity 8           // number of half-steps per slot

boolean debug = false;
boolean override = false;
AF_Stepper myStepper(96,2);
// *** Stepper myStepper(96,2,3,4,5,true); // Note: the Stepper library in the Arduino enviroment needs to be replaced with a half-stepping version
                                    // this can be found at http://code.google.com/p/arduino/issues/detail?id=139 and might need to be modified
                                    // by replacing the line #include "WProgram.h" with #include "Arduino.h"

int hallAnalogPin        =1;        // analog in A1

int   filter_position    =0;        // filter position control
int   filters_to_pass    =0;        // number of filters to pass to arrive at the destination
int   filter_destination =0;        //
int   filter_offset      =0;        // moves +/- once we find the correct filter to center it
int   filter_hysteresis  =0;        // ignore this many readings when the filter wheel begins to rotate (prevents false counts)

boolean standardFilter   =false;    // keep track of filter wheel state
boolean indexFilter      =false;
int   Moving             =0;
int   calibrateFilters   =0;
boolean zeroFilters      =false;

int   G                  =512;      // for processing magnetic gauss readings
int   G1                 =512;      // for determination of filter positions
int   neutralG           =100;
int   southG             =75;
int   northG             =125;
int   thresholdGS;
int   thresholdGN;
byte  GA[fullRotation];            // holds a series of gauss readings for calibration of the filter wheel

char  inChar;
char  buffer[80];                  // storage for command
int   bufferPtr          =0;       // current location in buffer
char  buffer2[3];                  // two letter command code
char  buffer3[13];                 // numeric tail
boolean commandError;              // command status

void setup() // run once, when the sketch starts
{
  int l;
  
  // slow pwm down
  TCCR1B = TCCR1B & 0b11111000 | 0x01;  // clock divided by 1024

  // get the stepper ready
  myStepper.setSpeed(20);

  // make the ADC use our external voltage reference
  analogReference(EXTERNAL);
  
  // enable serial communications
  Serial.begin(9600);
  Serial.flush();

  // retrieve the last filter position
  filter_position=EEPROM.read(0);
  if (filter_position<0) filter_position=0;
  if (filter_position>4) filter_position=0;
  filter_destination=filter_position;
  filters_to_pass=0;

  // retrieve the filter offset position
  filter_offset=EEPROM.read(1)-10;
  if (filter_offset<-10) filter_offset=-10;
  if (filter_offset> 10) filter_offset= 10;

  // retrieve the last filter wheel calibration
  southG  =EEPROM_readInt(20);
  northG  =EEPROM_readInt(22);
  neutralG=EEPROM_readInt(24);

  // prepare the command buffers
  buffer[0]=0;
  buffer2[0]=0;
  buffer3[0]=0;
}

void loop()
{
  bool input_ready = false;
  int dummy;
  int State;
  int T;
  int i;
  int L;
  int tr_count_actual;
  char Temp[80];

  // build serial input:
  if (Serial.available() > 0) {
    
    // get incoming byte:
    inChar = Serial.read();
    
    // and build up a command
    buffer[bufferPtr]=toupper(inChar);
    bufferPtr++;
    buffer[bufferPtr]=(char)0;
    if (bufferPtr>78) { bufferPtr=78; }  // limit maximum command length to avoid overflow

    // process command
    if (inChar==(char)13) {
      buffer[bufferPtr-1]=0;             // erase the cr
      strncpy(buffer2,buffer,2);         // get the two letter command
      strncpy(buffer3,&buffer[2],12);    // get the optional numeric tail

      commandError=false;
      
      // ask for version
      if (strcmp(buffer2,"V?") == 0) {
        if (strlen(buffer3)==0) { Serial.println("On-Cue Filter Wheel V1.0"); } else commandError=true;
      } else

      // set current filter 1
      if (strcmp(buffer2,"F1") == 0) {
        if ((strlen(buffer3)==0) && (!Moving)) {
          if (filter_position!=0) { filters_to_pass=toPass(0,filter_position); filter_destination=0; filter_hysteresis=10; Moving=300; }
          Serial.println("Selecting Filter #1");
        } else commandError=true;
      } else
      // set current filter 2
      if (strcmp(buffer2,"F2") == 0) {
        if ((strlen(buffer3)==0) && (!Moving)) {
          if (filter_position!=1) { filters_to_pass=toPass(1,filter_position); filter_destination=1; filter_hysteresis=10; Moving=300; }
          Serial.println("Selecting Filter #2");
        } else commandError=true;
      } else
      // set current filter 3
      if (strcmp(buffer2,"F3") == 0) {
        if ((strlen(buffer3)==0) && (!Moving)) {
          if (filter_position!=2) { filters_to_pass=toPass(2,filter_position); filter_destination=2; filter_hysteresis=10; Moving=300; }
          Serial.println("Selecting Filter #3");
        } else commandError=true;
      } else
      // set current filter 4
      if (strcmp(buffer2,"F4") == 0) {
        if ((strlen(buffer3)==0) && (!Moving)) {
          if (filter_position!=3) { filters_to_pass=toPass(3,filter_position); filter_destination=3; filter_hysteresis=10; Moving=300; }
          Serial.println("Selecting Filter #4");
        } else commandError=true;
      } else
      // set current filter 5
      if (strcmp(buffer2,"F5") == 0) {
        if ((strlen(buffer3)==0) && (!Moving)) {
          if (filter_position!=4) { filters_to_pass=toPass(4,filter_position); filter_destination=4; filter_hysteresis=10; Moving=300; }
          Serial.println("Selecting Filter #5");
        } else commandError=true;
      } else
      // ask for current filter position
      if (strcmp(buffer2,"F?") == 0) {
        if (strlen(buffer3)==0) {
          if ((filter_position!=filter_destination) || (Moving)) {
            sprintf(Temp,"Filter: ?");
          } else {
            if (debug) {
              sprintf(Temp,"Filter: %d, Offset: %d, thresholdGN: %d, neutralG: %d, thresholdGS: %d", filter_position, filter_offset, thresholdGN, neutralG, thresholdGS);
            } else {
              int fp=filter_position+2;  if (fp>4) fp=fp-4;
              sprintf(Temp,"Filter: %d", fp);
            }
          }
          Serial.println(Temp);
        } else commandError=true;
      } else
      // ask to calibrate filter wheel
      if (strcmp(buffer2,"FC") == 0) {
        if ((strlen(buffer3)==0) && (!Moving)) { calibrateFilters=fullRotation; Moving=300; filter_hysteresis=0; Serial.println("Ok"); } else commandError=true;
      } else
      // ask to seek zero position on filter wheel
      if (strcmp(buffer2,"FZ") == 0) {
        if ((strlen(buffer3)==0) && (!Moving)) { zeroFilters=fullRotation; Moving=300; filter_hysteresis=6; Serial.println("Ok"); } else commandError=true;
      } else
      // tweek filter wheel +
      if (strcmp(buffer2,"F+") == 0) {
        if (strlen(buffer3)==0) {
          if (filter_offset<9) { filter_offset++; EEPROM.write(1,filter_offset+10); Serial.println("Filter Offset Adjusted +1"); } else commandError=true;
        } else commandError=true;
      } else
      // tweek filter wheel -
      if (strcmp(buffer2,"F-") == 0) {
        if (strlen(buffer3)==0) {
          if (filter_offset>-9) { filter_offset--; EEPROM.write(1,filter_offset+10); Serial.println("Filter Offset Adjusted -1"); } else commandError=true;
        } else commandError=true;
      } else

      // debug mode on
      if (strcmp(buffer2,"D+") == 0) {
        if (strlen(buffer3)==0) { debug=true; Serial.println("Debug mode on"); } else commandError=true;
      } else
      // debug mode off
      if (strcmp(buffer2,"D-") == 0) {
        if (strlen(buffer3)==0) { debug=false; Serial.println("Debug mode off"); } else commandError=true;
      } else {
        // command not recognized
        commandError=true;
        Serial.println("Error");
      }

      // clear the last command
      bufferPtr=0; buffer[bufferPtr]=0;  
    }
  }

  // Hall-effect filter wheel sensor
  // Some initial values observed were
  // SouthG   = 794
  // NeutralG = 635
  // NorthG   = 584
  G=analogRead(hallAnalogPin);
  thresholdGN=(neutralG-((neutralG-northG)/2)); // ex. 635-584 =  +51,  51/4  =  15, 635-15 = 620;
  thresholdGS=(neutralG-((neutralG-southG)/2)); // ex. 635-794 = -159, -159/4 = -40, 635+40 = 675;
  if ((G<thresholdGN) && (G1>=thresholdGN) && !filter_hysteresis) { indexFilter   =true; } else { indexFilter=false; }
  if ((G>thresholdGS) && (G1<=thresholdGS) && !filter_hysteresis) { standardFilter=true; } else { standardFilter=false; }
  G1=G;

  if (debug) {
    if (indexFilter)       { Serial.print("I="); Serial.println(G); }
    if (standardFilter)    { Serial.print("S="); Serial.println(G); }
    if (filter_hysteresis) { Serial.print("H="); Serial.println(G); }
  }

  if (filter_hysteresis>0) filter_hysteresis--;
  
  if (Moving) {
    // Three modes of operation, mode 1: filter positioning
    if ((!zeroFilters) && (!calibrateFilters)) {
      // Standard or index filter found
      if (standardFilter || indexFilter) {
        if (filters_to_pass>0) filters_to_pass--;
      }
      // Move filter to the new position
      if (filters_to_pass>0) {
        if (Moving>0) Moving--;
       // ***      
        myStepper.step(stepGranularity,FORWARD,SINGLE);
      } else {
        if (filter_position!=filter_destination) {
          filter_position=filter_destination;
          EEPROM.write(0,filter_position);
        }
        // ***
        myStepper.step(filter_offset*stepGranularity,FORWARD,SINGLE);
        filter_hysteresis=false;
        Moving    =false;
      }
    }
  
    // Three modes of operation, mode 2: homing
    if ((zeroFilters) && (!calibrateFilters)) {
      // Index filter found
      if (indexFilter) {
        filter_position=0; filter_destination=0;
        EEPROM.write(0,filter_position);
        // ***
        myStepper.step(filter_offset*stepGranularity,FORWARD,SINGLE);
        Moving=false;
      } else {
        // move filter to a new position
        if (zeroFilters>0) zeroFilters--;
        if (Moving>0) Moving--;
        // ***
        myStepper.step(stepGranularity,FORWARD,SINGLE);
      }
    }
  
    // Three modes of operation, mode 3: calibration
    if ((!zeroFilters) && (calibrateFilters)) {
      if (calibrateFilters>2) {
        // save a series of readings from all around the wheel
        if (calibrateFilters>1) calibrateFilters--;
        if (Moving>0) Moving--;
        // ***
        myStepper.step(stepGranularity,FORWARD,SINGLE);
        GA[calibrateFilters]=(G>>2);
      } else {
        // sort the list of readings, ascending
        int l;
        int m;
        for (l=1; l<fullRotation-1; l++) {
          for (m=1; m<fullRotation-1; m++) {
            if (GA[l]>GA[m]) { G=GA[l]; GA[l]=GA[m]; GA[m]=G; }
          }
        }
        
        // take an average of readings from the lowest, middle, and highest
        southG  =((GA[2]+GA[3]+GA[4])/3)<<2;
        neutralG=((GA[fullRotation/2-1]+GA[fullRotation/2]+GA[fullRotation/2+1])/3)<<2;
        northG  =((GA[fullRotation-3]+GA[fullRotation-4]+GA[fullRotation-5])/3)<<2;

        if (debug) {
          Serial.println("Cal complete:");
          for (l=1; l<fullRotation-1; l++) { Serial.println(GA[l]<<2); }
          Serial.println("");
          sprintf(Temp,"Sav: SouthG=%d  NeutralG=%d  NorthG=%d",southG,neutralG,northG);
          Serial.println(Temp);
        }
        
        // and save them for later
        EEPROM_writeInt(20,southG);
        EEPROM_writeInt(22,northG);
        EEPROM_writeInt(24,neutralG);
        
        calibrateFilters=false;
        Moving          =false;
      }
    }
  } else {
    filter_hysteresis=false;
    zeroFilters     =false;
    Moving          =false;
    calibrateFilters=false;
    filters_to_pass=0;
  }
}

// get the numeric tail of the command
boolean intTail2(int *val,int *dec, int low, int high) {
  int l;
  int i;
  int hasDecimal;
  boolean isNumeric;
  long temp;

  l = strlen(buffer3);
  if (l>0) {
    // check to make sure we have a number
    isNumeric=true; for (i=0; i++; i<l) { if (((buffer3[i]<'0') || (buffer3[i]>'9')) && (buffer3[i]!='.')) { isNumeric=false; } }

    // check that only one digit is after the decimal point, if any decimal point is found
    hasDecimal=0; for (i=0; i++; i<l) { if (buffer3[i]=='.') { hasDecimal++; } }
    if (hasDecimal>1) { isNumeric=false; }
    if ((hasDecimal==1) && (buffer3[l-2]!='.')) { isNumeric=false; }

    // record and strip the decimal if present
    *dec=0;
    if (hasDecimal) { *dec=(int)buffer[l-1]-48; buffer[l-2]=0; }
    
    // convert to an integer
    *val=0;
    if (isNumeric) {
      temp=atoi(buffer3);
      if ((temp>=low) and (temp<=high)) { *val=temp; return true; } else return false;
    } else return false;
    
  } else return false;
}

// calculate how many filters to pass from current position
int toPass(int filterDestination, int filterPosition) {
  int l;
  l=filterDestination-filterPosition;
// if (l<0) l=4+l;  // for a 4-position wheel
  if (l<0) l=5+l;
  return l;
}

// write int numbers into EEPROM
void EEPROM_writeInt(int i,int l) {
  byte *lPtr;
  lPtr = (byte*)&l;
  EEPROM.write(i+0,*lPtr); lPtr++;
  EEPROM.write(i+1,*lPtr);
}

// read int numbers from EEPROM
int EEPROM_readInt(int i) {
  int l;
  byte *lPtr;
  lPtr = (byte*)&l;
  *lPtr=EEPROM.read(i+0); lPtr++;
  *lPtr=EEPROM.read(i+1);
  return l;
}
Alle von mir angepassten Stellen findest du über // ***
Du mußt folgende Dinge prüfen:
- den Motorblockanschluß bei der Initialisierung von myStepper
- die Directions und den Modus bei den step Aufrufen

Hope it helps!

Grüße Ricardo

Nüchtern betrachtet...ist besoffen besser Big Grin
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
29.05.2014, 10:11 (Dieser Beitrag wurde zuletzt bearbeitet: 29.05.2014 10:12 von flyingeagle.)
Beitrag #6
RE: Schrittmotorlibrary wechseln
Guten Morgen und Danke schonmal,

also der Motor läuft zumindestens schonmal mit dem Sketch. Jetziges problem ist das er bei den Magneten nicht stoppt.
Sensor habe ich überprüft... Läuft.
Aber wir kommen der Sache schon näher.
Kann im Moment leider nicht sehen wo das schon wieder dran liegt...

Gruß

Micha
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
30.05.2014, 15:21
Beitrag #7
RE: Schrittmotorlibrary wechseln
Hallo Micha,

das kann eigentlich nur an den step- Aufrufen liegen. Die haben ja mehrere Parameter. Da ich nicht wirklich in der Codelogik stecke, hier ein Link der die Parameter nochmal erklärt: https://learn.adafruit.com/afmotor-libra...pper-class
Du wirst wohl die verschiedenen Parameter testen müssen.

Grüße Ricardo

Nüchtern betrachtet...ist besoffen besser Big Grin
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
Antwort schreiben 


Gehe zu:


Benutzer, die gerade dieses Thema anschauen: 1 Gast/Gäste