HC-SR04 und Schrittmotor Verbinden

Ich versuche für ein Schulprojekt den Haft- und den Gleitreibungskoeffizienten mithilfe der Simulation einer schiefen Ebene zu berechnen. Ein Schrittmotor zieht eine Rampe über einen Seilzug hoch. Auf der Rampe befindet sich ein Objekt, das ab einem bestimmten Winkel von der Rampe abrutscht. Das Abrutschen soll mit einem Ultraschallabstandssensor (HC-SR04) aufgefangen werden. An dem Punkt an dem das Objekt abrutscht, soll sich der Schrittmotor aufhören zu drehen und mithilfe eines 3-Achsen Beschleunigungssensors soll der aktuelle Winkel der Rampe für die Berechnung des Haftreibungskoeffizienten ausgegeben werden. Für die Berechnung des Gleitreibungskoeffizienten soll der Ultraschallsensor auch den Weg des Objekts auffangen, um die Beschleunigung zu berechnen. Derzeit scheitert es jedoch daran den Schrittmotor den mein Projektpartner programmiert hat mit dem Ultraschallsensor zu verbinden. Der Schrittmotor soll aufhören sich zu drehen wenn das Objekt auf der Rampe sich bewegt.

Code für den Schrittmotor:

#include <Arduino.h>
#include <Stepper.h>

const int stepsPerRevolution = 200;

#define pwmA 3
#define pwmB 11
#define brakeA 9
#define brakeB 8
#define dirA 12
#define dirB 13


#define PIN_TRIGGER 7
#define PIN_ECHO    6
#define PIN_PIEZO   5

int off = 0;
int up = 1;
int down = 2;
int motorState;

// Initialize the stepper library on the motor shield:
Stepper myStepper = Stepper(stepsPerRevolution, dirA, dirB);
char buffer[10];

void setup() 
{
  // Set the PWM and brake pins so that the direction pins can be used to control the motor:
  pinMode(pwmA, OUTPUT);
  pinMode(pwmB, OUTPUT);
  pinMode(brakeA, OUTPUT);
  pinMode(brakeB, OUTPUT);

  digitalWrite(pwmA, HIGH);
  digitalWrite(pwmB, HIGH);
  digitalWrite(brakeA, LOW);
  digitalWrite(brakeB, LOW);

  Serial.begin(9600);
    pinMode(PIN_TRIGGER, OUTPUT);
    pinMode(PIN_ECHO, INPUT);
    for (byte pin=2; pin<=10; pin++) 
   {
        pinMode(pin, OUTPUT);
    }

  // Set the motor speed (RPMs):
  myStepper.setSpeed(25);

  Serial.begin(9600);

}


void loop() 
{
  byte command;

  // check if data has been sent from the computer:
  if (Serial.available()) 
  {
    //read the most recent byte (which will be from 0 to 255):
    command = Serial.read();
    sprintf(buffer, "c: %c", command);
    Serial.println(buffer);
  }

  if(command == 'o')
  {
    motorState = 0;
  }
  else if(command == 'u')
  {
    motorState = 1;
  }
  else if(command == 'd')
  {
    motorState = 2;
  }

  if(motorState == 1)
  {
    Serial.println(motorState);
    myStepper.step(-500);
    delay(20);
  } 
  
  else if(motorState == 2)
  {
    Serial.println(motorState);
    myStepper.step(500); 
    delay(20);
  }

}

Code für den Ultraschallabstandssensor (HC-SR04)

#include <Arduino.h>
#define PIN_TRIGGER 12
#define PIN_ECHO    13

const int SENSOR_MAX_RANGE = 3000; // in mm
unsigned long duration;
unsigned int distance;
unsigned int oldDistance = distance;

void setup()
{
  Serial.begin(9600);
  pinMode(PIN_TRIGGER, OUTPUT);
  pinMode(PIN_ECHO, INPUT);
}

void loop()
{
  digitalWrite(PIN_TRIGGER, LOW);
  delayMicroseconds(2);

  digitalWrite(PIN_TRIGGER, HIGH);
  delayMicroseconds(10);

  duration = pulseIn(PIN_ECHO, HIGH);
  distance = duration/5.8;

  if (distance > oldDistance+3)
  {
    Serial.println("Objekt rutscht!");
  } 
  else
  {
    Serial.println("Distance to object: " + String(distance) + "mm");
  }

  oldDistance = distance;
  delay(500);
}

Skizze des Prototyps:

Du willst Pins sparen??

Grüße Uwe

Hallo Lauritz,

willkommen im Arduino-Forum.
Als Anfänger macht es sich gut zunächst mal einige grundlegende Dinge zu lernen die beim Programmieren wichtig sind. Und ein paar Dinge die beim Fragen in einem Forum wichtig sind.

Aus deinem Code kann man schlussfolgern, dass du vergleichsweise wenig weißt.
Das ist vollkommen Ok. Jeder hat mal bei Null angefangen.

Deine Formulierung

Ja irgendwie muss da eine "Verbindung" hergestellt werden. Aber was das genau sein soll geht aus dieser Formulierung nicht hervor.

Der Schrittmotor zieht also die Rampe selbst hoch?
Wahrscheinlich nicht. wahrscheinlich wird ein "Objekt" die Rampe hochgezogen.
Was ist das für ein Objekt???

Das klingt jetzt widersprüchlich
erst soll der Schrittmotor etwas eine Rampe hochziehen = das Objekt bewegen und sobald der Ultraschallsensor eine Bewegung erkennt soll der Schrittmotor angehalten werden.

Diese Beschreibung ist einfach zu unpräzise als das man dir wirklich helfen könnte.
Aus der Tatsache, dass du jetzt 24 Stunden lang nur eine Antwort bekommen hast, kannst du schlussfolgern, dass niemand Lust hatte auf so eine allgemeingehaltene Frage ohne detaillierte Projektbeschreibung zu antworten.

Den Code hast du dir garantiert irgendwo ergoogelt. Wenn jemand diese Codezeilen selbst programmieren kann, dann macht er keine Doppelzuweisung von IO-pins.

Also wenn du eine detaillierte Beschreibung deines Projektes postest, dann kann man dir helfen.
Ohne diese Beschreibung müsste man jetzt 10 völlig verschiedene Programme erstellen um alle Eventualitäten abzudecken. Das macht keiner !

Du musst die präzise Beschreibung anliefern.

vgs

Danke, habe meinen Beitrag überarbeitet.

Ok ich beschreibe noch einmal mit meinen Worten was ich verstanden habe:

Der Schrittmotor erhöht langsam den Winkel der Rampe so lange bis das Objekt auf der Rampe anfängt zu rutschen = Hangabtriebskraft wird größer als die Haftreibungskraft.

Der Ultraschallsensor misst den Abstand Sensor-Objekt.
Das Abrutschen wird detektiert, dadurch dass sich der gemessene Abstand ab beginnendem Abrutschen vergrößert.

Aus dem Winkel bei dem das Abrutschen beginnt kann man dann den Haftreibungskoeffizienten berechnen.

Ist das so richtig?
vgs

Das Grundprinzip wird mit dem Ultraschallsensor funktionieren.

Es wird interessant sein die Performance dieses Messsystems auszutesten.
Zwischen antriggern des Ultraschallssensors und dem Aussenden des Ultraschallimpulses und dem Umschalten auf Empfang des Echos vergeht eine gewisse Zeit.

Darüber hinaus sollte ein bisschen gewartet werden bis man den nächsten Impuls aussendet, damit sich das Echo des ersten Impulses nicht mit Echo des zweiten Impulses überlagert. Die Echos des ersten Impulses sollten abgeklungen sein bis man den zweiten Impuls aussendet.
Dazu muss man auch abwarten bis die Echos aus größerer Entfernung abgeklungen sind oder
sehr sorgfältig dafür sorgen, das alle Oberflächen Ultraschall stark abdämpfen, ausser der Oberfläche des Objektes auf der Rampe.

Als Alternative könnte man einen sogenannten ToF (Time of Flight) Sensor zur Abstandsmessung nehmen. Aber auch da muss man sich im Datenblatt anschauen wie schnell kann der Sensor aufeinanderfolgend Messwerte anliefern.

Das Programm zum Ansteuern des Schrittmotors macht gerade mal drehe den Schrittmotor bei Eingang eines Befehls über die serielle Schnittstelle.

Das ganze ist ein sehr gutes Projekt. Inklusive dass es auf zwei Partner aufgeteilt ist.
Ihr könnt als Partner lernen, dass man bei so einem technischen Projekt sehr präzise besprechen und dann schriftlich festlegen was sind die Leistungen die Partner A erbringen muss, was sind die Leistungen die Partner B erbringen muss.

Zwischen Schrittmotor drehen und Ultraschallsensor detektiert Start der Bewegung muss ein Signalaustausch stattfinden. Dieser Signalaustausch ist nicht festgelegt. Weil ihr wahrscheinlich nicht besprochen habt wie die Schnittstelle für diesen Signalaustausch aussehen soll.

Wahrscheinlich habt ihr nur besprochen "Du machst den Schrittmotor - ich den Ultraschall"
Ende der Besprechung.

An die Definition hat sich der Schrittmotorpartner gehalten. Aber weil diese Definition so unpräzise ist, hat jetzt der Ultraschall-Partner die ganze Arbeit an der Backe.
Auch die Arbeit das Schrittmotorprogramm zu weiterzuentwickeln, dass die Programmlogik überhaupt in der Lage auf "Zuruf" den Schrittmotor anzuhalten.

vgs

Wie soll die Schnittstelle denn aussehen?

Die Frage verstehe ich nicht. Das ist zu ungenau gefragt.
Du solltest dir angewöhnen alle Details explizit beim Namen zu nennen.

Welche Schnittstelle?
WER sind die beiden Partner die da über die Schnittstelle WAS kommunizieren?

Tut mir leid, wie schaffe ich es, dass sich der Schrittmotor aufhört zu drehen wenn der Ultraschallabstandssensor eine Bewegung entdeckt?

Hallo Lauritz,

lies mal bitte sofort die private Message die ich dir geschrieben habe

So jetzt weiter im Programm:

Du konntest es nicht wissen aber du hast dir ein Projekt ausgesucht, dass wegen dem blockierenden Charakter sowohl der Standard stepper.h-library als auch dem blockierenden Charakter der Standard Ultraschall-Messung ganz schön anspruchsvoll ist.

Es gibt ein "Programm-Modul" zur Schrittmotoransteuerung dass nicht-blockierend arbeitet.
Man nennt diese Programm-Module "Bibliotheken (Programm-Bibliotheken) in englisch
library. Diese Library heißt MobaTools
Die kann man über den Library-Manager installieren.

Die Schrittmotor-Steuerbefehle der MobaTools heißen etwas anders als die der stepper.h-library

In den MobaTools kann man einen Befehl absetzen "Schrittmotor dreh dich" und dann werden die einzelnen Schrittimpulse "im Hintergrund" quasi als Nebentätigkeit erzeugt und dein Programm kann "quasi parallel" den Ultraschall-Sensor auslesen.
Möglicherweise brauchst du für den Ultraschall-Sensor auch eine nicht-blockierende library

vgs

Wie schon im Parallel-Thread "Schrittmotor mit HC-SR04 verbinden" erwähnt, kannst du es ja auch langsam nacheinander machen:

  1. Testen ob das Objekt sich bewegt hat.
  2. Etwas steiler stellen
  3. Warten
  4. Wieder von vorn (1.) ...
    Ob du die blockierenden Zeiten von 1. und 2. bei 3. berücksichtigst, ist eigentlich egal.
1 Like

Ja, genau. Schön der Reihe nach. Und ich glaube ich würde da auf eine Lib. für den Schrittmotor verzichten. Den Motor zwei Schritte machen lassen, dann wieder US Messung, wenn fertig wieder zwei Schritte, u.s.w. Da lohnt sich ja die Lib. gar nicht. Wenn ich das so mache, brauche ich den Motor auch nicht stoppen, weil er gar nicht läuft, wenn ich messe.

1 Like

Das finde ich eine sehr gute Lösung.

Danke! Wäre es auch möglich, dass man dem Motor sagt: "Fahr auf 20°."? Also das der Beschleunigungssensor dem Motor mitteilt wann er aufhören soll die Steigung der Rampe zu erhöhen? Weil der Winkel in der Berechnung der Reibungskoeffizienten eine große Rolle spielt.

Der Motor versteht den Wert 20° natürlich nicht. Selbst die Moba-Tools wären da überfordert. Theoretisch könnte vielleicht der Arduino das ausrechnen, besser wäre es, das mit dem Beschleunigungs- (= Winkel-) Sensor zu messen, bzw. aus den Messwerten auszurechnen (atan) .
Wenn du ungeduldig bist und den Anfang schneller durchlaufen willst, kannst du meinen Schritt 3 ja gerne komplizierter machen:

  1. Steilheit messen, in Grad umrechnen und anzeigen. Wenn es schon "ziemlich steil" ist, etwas warten, sonst weiter bei 2. und den Punkt 1 (US-Messung) überspringen.

:slight_smile:

Der Sensor "sagt" dem Motor gar nichts.
Du kannst im Sketch programmieren daß der Motor sich solange angesteuert wird bis der 3-Achsen Beschleunigungssensors 20° "liest".
Grüße Uwe

Ich habe mal einen Kreuztisch mit Schrittmotoren umgebaut. Damit war es dann so, dass der Schrittmotor, um den Tisch 100mm zu fahren 80.000 Schritte machen mußte. Wenn du da die Schritte pro mm berechnest, sieht du wie genau du theoretisch damit arbeiten kannst. Aber natürlich nicht mit so einer Seilwinde. Die macht jede Präzision unmöglich. Da bleibt nur fahren, messen, fahren messen, u.s.w.

Meine Arbeit mit dem Beschleunigungssensor ist schon sehr lange her. Ich weiß im Moment nicht, wie lange es dauert, bis man ein Balastbares Messergebnis vom Beschleunigungssensor hat. :thinking:

Ist hauptsächlich eine Frage des Filters, meines Wissens nach.

... kommt es hauptsächlich darauf an, die auftretenden Probleme zu zeigen. Wenn möglich, natürlich auch mit Lösung.