Geschwindigkeit einstellen / Poti ersetzen

Hallo zusammen, guten Abend,
könnt ihr mir nochmal bitte beim modifizieren von meinem Script helfen?

Momentan kann ich die Geschwindigkeit vom Motor mit einem Potentiometer "regeln/einstellen". Ich brauche aber nur zwei Geschwindigkeiten. Der Motor dreht die ganze Zeit mit der Höchstgeschwindigkeit und nur ab und an drehe ich den Motor mit dem Potentiometer langsamer.

Gerne würde ich das Potentiometer durch einen Schalter oder ähnlichem ersetzen mit der Funktion: beim Schalter drücken reduziert sich die Geschwindeigkeit auf eine definierbare Geschwindigkeit und beim loslassen wird wieder die Höchstgeschwindigkeit X erreicht.
Also nur während ich den Schalter drücke ist die Geschwindigkeit reduziert. Keine feste Zeitspanne sondern nur bei Betätigung.

Ich habe folgendes Script im Einsatz:

// Defin pins
 
int reverseSwitch = 2;  // Push button for reverse
int driverPUL = 7;    // PUL- pin
int driverDIR = 6;    // DIR- pin
int spd = A0;     // Potentiometer
 
// Variables
 
int pd = 500;       // Pulse Delay period
boolean setdir = LOW; // Set Direction
 
void setup() { 
  pinMode (driverPUL, OUTPUT);
  pinMode (driverDIR, OUTPUT);
  pinMode (reverseSwitch, INPUT_PULLUP);  
} 
void loop() { 
    pd = map((analogRead(spd)),500,1023,500,3);
    if (digitalRead(reverseSwitch)) setdir=0; else setdir=1;
    digitalWrite(driverDIR,setdir);
    digitalWrite(driverPUL,HIGH);
    delayMicroseconds(pd);
    digitalWrite(driverPUL,LOW);
    delayMicroseconds(pd); 
}

A0 wäre dann der neue Schalter, der dann die Geschwindigkeit bei Betätigung reduzieren soll.

Vielen Dank vorab für eure Hilfe.

Dein Code ist sehr seltsam. Anscheinend steuert zuletzt delayMicroseconds(pd) den Motor. Dann kannst Du ja pd zuvor ändern wenn der Schalter gedrückt ist.

Auch ich frage mich, wie Du angesichts der ziemlich simplen Aufgabe zu so einem Programm kommst. Zeichne einen PAP. Von da bis zum fertigen Programm ist es nicht weit.

Gruß

Gregor

Ja das Programm wird so benötigt, da noch ein Fußschalter verwendet wird.
Ich weiß aber absolut nicht wie ich die Geschwindigkeit mit dem Schalter reduzieren kann.

Muss ich nur eine weitere Bedingung einfügen? -> if (digitalRead(spd)) map(x,x,x,x);

// Defin pins

int reverseSwitch = 2;  // Push button for reverse
int driverPUL = 7;    // PUL- pin
int driverDIR = 6;    // DIR- pin
int spd = A0;     // Potentiometer

// Variables 

int pd = 500;       // Pulse Delay period

boolean setdir = LOW; // Set Direction 

void setup() {

  pinMode (driverPUL, OUTPUT);
  pinMode (driverDIR, OUTPUT);
  pinMode (reverseSwitch, INPUT_PULLUP); 
}
void loop() {
    pd = map((analogRead(spd)),500,1023,500,3);
    if (digitalRead(spd)) map(x,x,x,x);

    if (digitalRead(reverseSwitch)) setdir=0; else setdir=1;
    digitalWrite(driverDIR,setdir);
    digitalWrite(driverPUL,HIGH);
    delayMicroseconds(pd);
    digitalWrite(driverPUL,LOW);
    delayMicroseconds(pd);
}

Eher etwa so:

if (digitalRead(spd)) pd=higSpeed; else pd=lowSpeed;

Wobei Du dann highSpeed und lowSpeed noch vorher definieren musst.
Das analogRead kann dann ganz weg ( es sei denn, Du willst eine der beiden Geschwindigkeiten doch über das Poti vorgeben ),

Hallo Franz-Peter,

schön von dir zu hören. Ich hoffe es geht dir gut. Danke für deine Antwort.

Ist die Anpassung so korrekt? (bei X trage ich dann die jeweiligen Werte ein)

void loop() {
   pd =highspeed map(x,x,x,x);
  pd = lowspeed map(x,x,x,x);
   if (digitalRead(spd)) pd=highSpeed; else pd=lowSpeed;

Hallo Linda,
das map brauchst Du doch nur beim analogRead(), um die gelesenen Werte auf den gewünschten pd-Bereich umzusetzen. Ohne analogRead brauchst Du auch kein map, sondern kannst die Werte für pd direkt vorgeben.
Also z.B.

const int highSpeed = 10
const int lowSpeed = 500;

Die beiden Zeilen gehören dann noch vor das setup(). Welche Werte Du da einsetzen musst, musst Du ausprobieren.

P.S. Ich glaube, es wäre besser gewesen, die Frage im Ursprungsthread zu stellen. Dann hätte man auch gleich gesehen, dass es sich um eine Schrittmotor handelt. So ist das etwas aus dem Zusammenhang gerissen.

Danke dir Franz-Peter, es funktioniert richtig gut.
Weitere Nachfragen landen zukünftig im Ursprungsthread

Super, dass es jetzt funktioniert und danke für die Rückmeldung.

Hallo Franz-Peter, ich grüße dich.
Ich hoffe du kannst das Sommerwetter genießen und bist bei bester Gesundheit.

Ich bin mal wieder was am tüfteln und brauche deine Umsetzungsideen :slight_smile: wie schon so oft :smiley:

Der o.g. Sketch ist klasse, danke dir. Ich hoffe es ist ok für dich, wenn ich zu dem Script jetzt hier die Nachfrage stelle.

"Wir", eher gesagt du, hast es ja geschafft, dass ich nun zwei "feste" Geschwindigkeiten zur Verfügung habe und diese mit einem Schalter manuell steuern kann.

Die Praxis ist so, dass ich, wenn der Motor langsamer drehen soll, den Schalter betätige, der Motor langsamer dreht und wenn ich den Schalter loslasse, der Motor wieder schneller dreht.

Jetzt überlege ich, wie man diesen Schalter durch einen Sensor oder ähnliches ersetzen könnte und diese Funktion dann in das Script einzubauen.

Bei mir betreibe ich mit einem Schrittmotor ja eine "kleine Seilwinde". Also der Motor dreht waagerecht ein Seil auf und ab (Miniaturland).
Und beim Aufrollen drücke ich immer den Schalter zum langsamer drehen, damit der Motor ein etwas höheres Drehmoment hat.

Ich habe schon überlegt, wie ich diesen manuellen Schalter ersetzen könnte:
ich gehe davon aus, dass wenn das Seil aufgerollt wird und der Motor etwas mehr arbeiten muss, da am Ende des Seils ein Gewicht angeknotet ist, diese "Mehrleistung" anhand von einer Volt-, Ampere- oder sonstigen Zahl zu sehen sein muss oder?
Kann man diese Zahl auslesen und dann das Script anpassen, wenn z.B ausgelesener Wert größer als X, dass dann der Motor langsam dreht?

Denkst du es gibt solche Werte, die sich unter Last erhöhen und die man auslesen kann oder hast du eine andere Idee?

Ich freue mich auf deine Rückmeldung.

Hallo,
d.h er soll bei einer bestimmten Drehrichtung langsamer laufen ?

dann benutze doch einfach 4 Geschwindigkeits-Sollwerte
rechts_langsam
links_langsam
rechts_schnell
links_schnell

Dann kannst Du z.B mittels if ... eine der 4 auswählen was / wann immer Du willst.
Heinz

Ja, ist machbar. Man misst dafür den Strom, den der Motor aufnimmt. Problem ist nur, dass dann wenn du aufgrund des hören Strom´s (Höhere Last) die Spannung (somit Drehzahl des Motors) runterdrehst, auch der Strom wieder sinkt. Dann sagt also deine Strommessung fälschlicherweis, dass die Last wieder geringer ist. Also gibt die Automatik wieder Gas, der Strom steigt wieder, (weil ja die Last immer noch dran hängt)....... und alles beginnt wieder von vorne.

Franz

PS: Du könntest die Seilspannung überwachen. Wenn das Seil stärker gespannt wird, wird die Spannung, somit auch die Drehzahl, verkleinert. Die höheren Seilspannung bleibt dabei erhalten. Also eine Mechanik die den Knopf drückt :slightly_smiling_face:

Bei einem Schrittmotor ist das nicht so einfach wie bei einem DC-Motor. Die Werte im Stillstand und unter Belastung schwanken da deutlich weniger. Hast Du eine Multimeter? Dann köntest Du mal messen inwieweit sich der Strom aus dem Netzteil unter Belastung ändert.
Ist es denn tatsächlich so, dass der Motor die Last mit der höheren Geschwindigkeit nicht schafft? Wenn ich mich an deinen alten Thread erinnere, hatten wir dir ja schonmal vorgeschlagen einen Sketch mit Anfahr und Bremsrampe zu verwenden. Evtl. ist das auch der Grund. Schrittmotore sind ohne Beschleunigungsrampe nicht sehr kräftig beim Start mit höheren Geschwindigkeiten.

Hallo und guten Abend in die Runde :slight_smile:

Danke für euren Input.
Ich habe mir heute ein Multimeter ausgeliehen und etwas festegestellt, was ein guter Lösungsansatz sein kann:

ich habe die Spannung von der Stromquelle gemessen und folgende Werte festgestellt:
Motor ohne Drehbewegung: 23,53 V
Motor dreht, Geschwindigkeit hoch: 23,58 V
Motor dreht, Geschwindigkeit hoch & "Last zu ziehen": 23,45 V und fallend

Jetzt meine Idee:
ich würde jetzt gernen einen Spannungssensor einbauen und die Spannung messen. Wenn die Spannung unter Wert X fällt (z.B. 23,45 ) dann soll der Motor von Geschwindigkeit "High-Speed" auf "Low-Speed" schalten.

Könnt ihr mir dabei bitte helfen :slight_smile: ich habe auch schon mit der Veränderung des Scriptes angefangen. Dazu habe ich etwas im Netz gefunden und versucht einzubauen.
Die selbst eingefügten Zeilen habe ich versucht für euch fett zu markieren bzw diese sind wohl mit so Sternchen versehene.

Es fehlt jetzt "nur" noch eine weitere If-Verknüpfung wenn Wert2=X dann LowSpeed oder?

int reverseSwitch = 2;  // Push button for reverse
int driverPUL = 7;    // PUL- pin   
int driverDIR = 6;    // DIR- pin   
int spd = A0;     // Speed-Schalter

**int wert1;**
**float wert2;**
      
// Variables    
const uint32_t stepMax = 162000;  
uint32_t stepCount = 0;   
      
int pd = 500;       // Pulse Delay period
const int highSpeed = 60;   
const int lowSpeed = 275;   
boolean setdir = LOW; // Set Direction
      
void doOneStep () {     
  digitalWrite(driverPUL, HIGH);  
  delayMicroseconds(pd);  
  digitalWrite(driverPUL, LOW);   
  delayMicroseconds(pd);  
}       
      
void setup() {    
      
  pinMode (driverPUL, OUTPUT);  
  pinMode (driverDIR, OUTPUT);  
  pinMode (reverseSwitch, INPUT_PULLUP);
  pinMode (spd, INPUT_PULLUP);  

  **Serial.begin(9600); //serielle Verbindung starten**
}       
void loop() {  

   **float temp;**
**wert1=analogRead(1); //Spannungswert am analogen Eingang 1 auslesen**
**temp=wert1/4.092; //Wert mathematisch umwandeln um den Spannungswert in Volt zu erhalten**
**wert1=(int)temp;**
**wert2=((wert1%100)/10.0);**
**Serial.println(wert2); //Endgültigen Spannungswert im seriellen Monitor anzeigen**
**delay(1000); //Eine Sekunde warten**
    
  if ( setdir ==1 && digitalRead(spd)) pd = highSpeed; else pd = lowSpeed;        <- hier muss noch eine weitere If-Formulierung rein, oder?
  if (digitalRead(reverseSwitch)) setdir = 0; else setdir = 1;
  digitalWrite(driverDIR, setdir);
   if ( setdir ==0)  pd = highSpeed; 
      
  if ( setdir ==1 && stepCount <= stepMax ) {
    // Endpunkt beim Vorwärtsdrehen noch nicht erreicht -> 1 Step ausführen
    stepCount++;    
    doOneStep();    
  }       
      
  if ( setdir ==0 && stepCount > 0 ) {
    // Endpunkt beim Rückwärtsdrehen noch nicht erreicht -> 1 Step ausführen
    stepCount--;    
    doOneStep();    
  }       
}

Ich freue mich über eure Nachrichten.

Ohhh, ich habe überlesen dass du einen Schrittmotor für die Seilwinde benutzt. OK, das ist das mit der Strommessung eher nicht so toll. Aber ich habe ja eh was anderes vorgeschlagen. Die Last am Seil messen. Also eine Umlenkrolle z.B. an der man dann den erhöten Zug durch das Mehrgewicht bekommt, und damit einen Kontakt schaltet.

Franz

Mit einer Spannungsmessung wirst Du nicht weit kommen. Dein Netzteil dürfte ja ein geregeltes Netzteil sein, dass versucht die Spannung möglichst konstant zu halte. Die von dir gemessenen Werte sind viel zu nah beieinander, als dass man das vernünftig auswerten könnte. Wenn überhaupt kann es evtl. über eine Strommessung gehen. Aber bei einem Schrittmotor sind auch da die Werte sicher recht nah beieinander.

Entweder du machst es - wie von Franz vorgeschlagen - über eine Zugkraftmessung.

Oder Du entschließt dich doch mit Beschleunigungsrampen zu arbeiten. Das ist bei einem Stepper schon wichtig und wurde dir ja auch schon vorgeschlagen:

Alles andere ist rumdoktorn an Symptomen, statt die Ursache in Angriff zu nehmen.

P.S. Wenn Du partout nicht umstellen willst: Hängt es nicht von der Drehrichtung ab, ob der Motor mehr oder weniger Kraft aufbringen muss? dann könntest Du die Geschwindigkeit ja auch einfach von der Drehrichtung abhängig machen.

Ganz meine Meinung :slightly_smiling_face:

Hallo Franz54, danke für deine Umsetzungsidee mit der Umlenkrolle.

Ich habe gerade etwas rumprobiert aber ich weiß nicht genau wie du es meinst. Kannst du mir es mal erklären?
Ich habe also eine Welle, die das Seil aufrollt. Das Seil soll vorher über eine Umlenkrolle geführt werden, oder? Umlenkrolle habe ich. Desweiteren habe ich einen Micro NO-Schalter. Aber wo soll ich den Schalter "anbauen".
Könntest du mir das mal aufzeichnen?

auch habe ich mich heute mit dem Spannungssensor beschäftigt. Ihr sagt ja, dass ich diesen sehr wahrscheinlich nicht für mein Vorhaben verwenden kann, da die Messzahlen zunah beieinader sind.

Ich finde aber generell die Möglichkeiten mit Sensoren etwas auszulesen und dann anhand von den Werten die oder jene Funktion auszuführen mega interessant.

Somit habe ich versucht einen Spannungssensor "einzubauen" , die Werte am seriellen Moitor zu sehen und dann etwas aus den Werten zu machen.

So weit so gut: Sensor funktioniert und die Werte kann man einsehen. Das ganze sonstige Script funktioniert aber nicht mehr :smiley: Ich dachte mir nur Oh man, Mädchen :smiley:

Hier ist das Script:

 #define SENSOR A1   
int reverseSwitch = 2;  // Push button for reverse
int driverPUL = 7;    // PUL- pin   
int driverDIR = 6;    // DIR- pin   
int spd = A0;     // Speed-Schalter

const float R1 = 30000.0f; // Der Widerstand R1 hat eine größe von 30 kOhm
const float R2 = 7500.0f; //  Der Widerstand R2 hat eine größe von 7,5 kOhm
const float MAX_VIN = 5.0f;
      
// Variables    
const uint32_t stepMax = 222000;  
uint32_t stepCount = 0;   
      
int pd = 500;       // Pulse Delay period
const int highSpeed = 100;   
const int lowSpeed = 300;   
boolean setdir = LOW; // Set Direction
      
void doOneStep () {     
  digitalWrite(driverPUL, HIGH);  
  delayMicroseconds(pd);  
  digitalWrite(driverPUL, LOW);   
  delayMicroseconds(pd);  
}       
      
void setup() {    
      
  pinMode (driverPUL, OUTPUT);  
  pinMode (driverDIR, OUTPUT);  
  pinMode (reverseSwitch, INPUT_PULLUP);
  pinMode (spd, INPUT_PULLUP);  

  Serial.begin(9600);
   pinMode(SENSOR, INPUT);
}       
void loop() { 

     float vout = (analogRead(SENSOR) * MAX_VIN) / 1024.0f;
  float vin = vout / (R2/(R1+R2)); 
   
Serial.println(vin);

  delay(500);


if ( setdir =1 && vin > 23.80) pd = highSpeed; else pd = lowSpeed;      
if (digitalRead(reverseSwitch)) setdir = 0; else setdir = 1;
digitalWrite(driverDIR, setdir);
if ( setdir =0)  pd = highSpeed;
      
  if ( setdir ==1 && stepCount <= stepMax ) {
    // Endpunkt beim Vorwärtsdrehen noch nicht erreicht -> 1 Step ausführen
    stepCount++;    
    doOneStep();    
  }       
      
  if ( setdir ==0 && stepCount > 0 ) {
    // Endpunkt beim Rückwärtsdrehen noch nicht erreicht -> 1 Step ausführen
    stepCount--;    
    doOneStep();    
  } 

 
}

Mache ich hier grundsätzliche Fehler?


Die Last wird am Lasthaken angehängt. Das Seil wird stärker gespannt, dadurch wird die Umlenkrolle etwas nach oben gezogen, und der Zugkontakt spricht an. Ist die Last weg, hängt das Seil wieder weiter durch, die Umlenkrolle geht runter, der Kontakt öffnet wieder.

1 Like