Digitales Prototyping: Arduino 3 / 2021-07-19 / Matthias Edler-Golla, CC BY-SA 4.0



Hallo!


Themen heute

  • Servomotor
  • Schrittmotor

Google Dokument zum Code-Austausch

Code Exchange Document


Servo-Motor ansteuern

Verbindet den Motor – wie auf dem Foto unten gezeigt – mit Breadboard und Arduino. Verwendet dabei möglichst die gleichen Farben, damit Ihr den Motor richtig anschliessen könnt. Es kann sein, dass bei Eurem Motor die Farben anders sind…

Achtung

Die am Samstag installierten Libraries von Elegoo enthalten auch die Library Servo, die sich nicht mit der Default-Library von Arduino „verträgt“ – bitte löscht die von Elegoo eingefügte und startet Arduino neu.

Die Libraries findet Ihr hier:

  • Am Mac findet Ihr die Libraries bei Documents/Arduino/libraries
  • Am PC sind die Libraries hier zu finden: My Documents\Arduino\libraries\

Arduino

// http://www.oomlout.com/oom.php/products/ardx/circ-04

// Libary einfügen!
#include <Servo.h>

// create servo object to control a servo
// a maximum of eight servo objects can be created
Servo myservo;

int zeit = 1000; // wie lange soll der Arm in der Position stehen bleiben
int counter = 0; // der Servo soll nur eine bestimmte Anzahl machen und dann aufhören

void setup() {
  myservo.attach(9);  // attaches the servo on pin 9 to the servo object
}


void loop() {

  // der Servo soll nur eine bestimmte Anzahl machen und dann aufhören
  if (counter < 5) {

    // Mitte
    myservo.write(90); // Gradangabe! nur Werte zwischen 0 und 180 möglich!
    delay(zeit);

    myservo.write(0);
    delay(zeit);

    myservo.write(90);
    delay(zeit);

    myservo.write(180);
    delay(zeit);

    // Kurzschreibweise von counter = counter + 1;
    counter++;

  }

}

Übung 14: Scheibenwischer

Erweitert den Aufbau um einen Button und den dazugehörigen, richtigen Widerstand!

Erweitert den gerade gezeigten Servo-Motor-Code so, dass sich der Motor wie ein Scheibenwischer verhält und dreimal „die Scheibe wischt“, nachdem der Knopf gedrückt wurde.

Stellt sicher, dass Ihr den Knopf immer wieder betätigen könnt und der „Scheibenwischer“ jedesmal von neuen anfängt zu arbeiten!

Foto meines Aufbaus


Temperatur-Anzeige analog

Beachtet, wie ich im Arduino-Code einige Zeilen des Code als externe Funktionen ausgelagert habe – das macht den Code besser lesbar, oder?

Schaut Euch auch an, wie den externen Funktionen die Werte temperature übergeben werden!

Arduino

// Arduino Project Book, Seite 43ff
// http://www.oomlout.com/oom.php/products/ardx/circ-04

// ======== Servo-Sachen =============

// Libary einfügen!
#include <Servo.h>

// create servo object to control a servo
// a maximum of eight servo objects can be created
Servo myservo;

// ========= Temperatur-Sensor =========

#include <dht_nonblocking.h>
#define DHT_SENSOR_TYPE DHT_TYPE_11

static const int DHT_SENSOR_PIN = 2;
DHT_nonblocking dht_sensor( DHT_SENSOR_PIN, DHT_SENSOR_TYPE );

// ============ LED auf 13 ==========
int ledPin = 13;

// Grenzwert-Temperatur, wenn LED an/ausgehen soll
float grenzwert = 25.0;

void setup() {
  pinMode(ledPin, OUTPUT);
  myservo.attach(9);  // attaches the servo on pin 9 to the servo object
  Serial.begin(9600);
}

void loop() {
  float temperature;
  float humidity;

  /* Measure temperature and humidity.  If the functions returns
     true, then a measurement is available. */
  if ( measure_environment( &temperature, &humidity ) == true )
  {
    // in diesem Sketch werden nur die Temperatur-Werte verwendet!
    serielleAusgabe(temperature);
    ledAnAus(temperature);
    temperaturAnzeigeAnalog(temperature);
  }

  // externe Funktionen mit Übergabe des Temperatur-Wertes
  // mehr zu ext. Funktionen: https://canvas.instructure.com/courses/1054116/pages/arduino-coding-writing-functions-4-examples
}

// =========== externe Funktionen ============

void serielleAusgabe(float wert) {
  Serial.print( "T = " );
  Serial.print( wert, 1 );
  Serial.println( " deg. C" );
}

void ledAnAus(float wert) {
  // Wenn die Temperatur unter einen bestimmten Wert fällt, soll die LED angehen
  if (wert < grenzwert) {
    digitalWrite(ledPin, HIGH);
  } else {
    digitalWrite(ledPin, LOW);
  }
}

void temperaturAnzeigeAnalog(float wert) {
  // zur Sicherheit Limits eingebaut, damit der Servo nicht kaputt geht
  // wenn die Werte < 0 oder > 180 werden
  // deswegen werden nur Werte zwischen 0° und 60° zugelassen
  if (wert > 0 && wert < 45) {
    // Temperatur mit 4 multipliziert, damit man merkt, wenn sich die Temperatur ändern
    // z.b. wenn man mit der Hand an das Termometer fasst
    myservo.write(wert * 4);
  }
}

/*
   Poll for a measurement, keeping the state machine alive.  Returns
   true if a measurement is available.
*/
static bool measure_environment( float *temperature, float *humidity ) {
  static unsigned long measurement_timestamp = millis( );

  /* Measure once every second. */
  if ( millis( ) - measurement_timestamp > 1000ul )
  {
    if ( dht_sensor.measure( temperature, humidity ) == true )
    {
      measurement_timestamp = millis( );
      return ( true );
    }
  }

  return ( false );
}

Analoge Temperaturanzeige

hier eingeschränkt auf den Bereich von 0° bis 45° Celsius – also ein Zimmerthermometer…

Hinter der analogen Anzeige wäre dann der Servo-Motor verbaut…

Aufbau


Schrittmotor

Aufbau entsprechend des Elegoo-Tutorials

Typische Anwendungsgebiete sind Drucker, vor allem Matrixdrucker, oder der Antrieb des Schreib-/Lesekopfes in einem Diskettenlaufwerk. Aufgrund ihrer hohen Genauigkeit werden sie auch in computergesteuerten Werkzeugmaschinen zur Positionierung der Werkzeuge verwendet.

Schrittmotoren finden auch in 3D-Druckern ihren Einsatz – und werden dort oft von Arduinos angesteuert…

Arduino

//www.elegoo.com
//2018.10.25

/*
  Stepper Motor Control - one revolution

  This program drives a unipolar or bipolar stepper motor.
  The motor is attached to digital pins 8 - 11 of the Arduino.

  The motor should revolve one revolution in one direction, then
  one revolution in the other direction.

*/

#include <Stepper.h>

// typische Anzahl von Schritten für eine komplette Rotation (360°)
int stepsPerRevolution = 2048;

// Geschwindigkeit des Motors kann zwischen 0 und max. 17 rpm (Umdrehung pro Minute) sein
// mehr und der Motor „verschluckt“ Steps und wird ungenau…
int rolePerMinute = 15;

// initialize the stepper library on pins 8 through 11:
Stepper myStepper(stepsPerRevolution, 8, 10, 9, 11);

void setup() {
  // Geschwindigkeit des Motors festlegen
  myStepper.setSpeed(rolePerMinute);

  Serial.begin(9600);
}

void loop() {
  // Motor macht 2048 Steps im Uhrzeigersinn und somit eine volle Umdrehung
  Serial.println("clockwise");

  // Motor führt 2048 Stufen aus und macht somit eine vollständige Drehung
  myStepper.step(stepsPerRevolution);

  // kurze Pause danach
  delay(500);

  // Motor macht 2048 Steps gegen den Uhrzeigersinn und somit ebenfalls eine volle Umdrehung
  Serial.println("counterclockwise");

  // Motor macht nur eine halbe Umdrehung (1024 Schritte)
  myStepper.step(-stepsPerRevolution / 2);

  // kurze Pause danach
  delay(500);
}

Schrittmotor: Externe Funktionen

Externe Funktionen machen den Code einfacher lesbar und reduzieren so die Fehleranfälligkeit!

Schaut auch hier bei der Benamung der ext. Funktionen, dass diese möglichst selbsterklärend sind!

Arduino

// Libraries:
#include <Stepper.h>

// Buttons:
int Taster_links = 4;
int Taster_rechts = 2;

// Stepper_Setup
int SPU = 2048; //SPU=Steps Pro Umdrehung
Stepper Motor1(SPU, 8, 10, 9, 11);

void setup() {
  pinMode(Taster_links, INPUT);
  pinMode(Taster_rechts, INPUT);
}

void loop() {
  if (digitalRead(Taster_links) == HIGH) {
    // externe Funktion
    motorLinksrum();
  }
  if (digitalRead(Taster_rechts) == HIGH) {
    // externe Funktion
    motorRechtsrum();
  }
}

// ================ externe Funktionen ================

void motorLinksrum() {
  // schnell drehen
  Motor1.setSpeed(15);

  // 1024 Steps - halbe Umdrehung im Uhrzeigersinn
  Motor1.step(1024);
}

void motorRechtsrum() {
  // langsam drehen
  Motor1.setSpeed(5);

  // -512 Steps - viertel Umdrehung gegen Uhrzeigersinn
  Motor1.step(-512);
}

Modulo

Die Operation Modulo berechnet den Rest, wenn eine ganze Zahl durch eine andere geteilt wird. Dies ist nützlich, um eine Variable innerhalb eines bestimmten Bereichs zu halten.

Arduino

int x, y;

void setup() {
  x = 7 % 5;    // x enthält jetzt 2
  x = 9 % 5;    // x enthält jetzt 4
  x = 5 % 5;    // x enthält jetzt 0
  x = 4 % 5;    // x enthält jetzt 4

  y = 5 % 3;    // y enthält jetzt 2
  y = 8 % 3;    // y enthält jetzt 2
}

void loop() {}

Interrupts

Interrupts sind nützlich, um bestimmte Tasks in Microkontrollerprogrammen automatisch ablaufen zu lassen und können helfen, Timingprobleme zu lösen. Gute Beispiele dafür sind das Lesen eines Drehgebers sowie das Einlesen von Benutzereinaben.

Ihr könnt auf den Arduino Uno Boards nur die PINS 2 und 3 als Interrupt-Pins verwenden! Auf anderen Boards können auch andere PINS verwendet werden…

Arduino

// https://www.arduino.cc/reference/de/language/functions/external-interrupts/attachinterrupt/

// Setze den Pin für die LED auf 13
int ledPin = 13;

// Setze den Interruptpin auf 2
int interruptPin = 2;

// Definiere eine globale volatile Variable für den Status der LED
int state = LOW;

void setup() {
  // Lege den Pin für die LED als Outputpin fest
  pinMode(ledPin, OUTPUT);

  // Lege den Interruptpin als Inputpin mit Pullupwiderstand fest
  pinMode(interruptPin, INPUT_PULLUP);

  // Lege die ISR 'blink' auf den Interruptpin mit Modus 'CHANGE':
  // "Bei wechselnder Flanke auf dem Interruptpin" --> "Führe die ISR aus"
  attachInterrupt(digitalPinToInterrupt(interruptPin), ledBlink, CHANGE);

  Serial.begin(9600);
}

void loop() {
  // Schreibe den Status der LED auf den LED-Pin zurück:
  // "Schalte die LED an oder aus"
  digitalWrite(ledPin, state);

  Serial.print("state: ");
  Serial.println(state);
}

// externe Funktion, aufgerufen bei "attachInterrupt"
void ledBlink() {
  // Invertiere den Status: "Lass die LED blinken von HIGH auf LOW/ an auf aus"
  state = !state;
}

Bei dem oben gezeigten Beispiele könnte das Ein- und Ausschalten der LED sicherlich auch anders gelöst werden. Wichtiger werden die Interrupts, wenn Ihr z.B. einen Motor (unmittelbar) anhalten möchtet, während dieser läuft.


Leiterplatine statt Kabelsalat

Details aus der Bachelor-Arbeit von David Mitlewski


Übung 15: Uhren-Projekt David

Bitte baut die oben gezeigte Kombination schon mal auf!

  • ein Schrittmotor
  • ein Servomotor
  • drei Taster
  • die Widerstände bei den Tasters sind hier ebenfalls 1 KΩ

PDF Vorlage

Bitte ladet die von David erstellte PDF-Vorlage herunter und druckt diese aus


Übung 15a

Aufbau siehe Übung 15!

Baut mit dem Schrittmotor einen auf Knopfdruck startenden 1 Minuten-Timer


Übung 15b

Aufbau siehe Übung 15!

Die Lösung von Aufgabe 15a hat einen Nachteil: Der Arduino reagiert für die Dauer, die der Motor läuft auf keine weiteren Befehle.

  • Wie müsste man die Funktion umschreiben, so dass der Motor nach jedem einzelnen Schritt wieder ansprechbar wäre?
  • Wie kann jeder Motorschritt einzeln ausgeführt werden? (Nicht alle auf einmal, wie bei Aufgabe 15a)

Tipp : for - loop


Übung 15c

Aufbau siehe Übung 15!

Verändere die Timerfunktion (Übung 15b) so, dass der Timer nicht nur eine Umdrehung lange läuft sondern theoretisch unendlich lange.


Übung 15d

Aufbau siehe Übung 15!

Führt eine kurze Interruptfunktion ein, die die Motorfunktion durch Druck auf den mittleren Knopf stoppt.


Übung 15e

Aufbau siehe Übung 15!

Schreibt eine neue Funktion, die nach Stoppen des Timers (mittlerer Knopf) bei Knopfdruck der rechten Taste den Schrittmotor auf Null resetet.

Tipp:

Führt in die timer-Funktion eine Variable int s ein, die bei jedem Schritt eins mehr wird und so die Schritte zählt. Diese Schritte können nun wieder zurückgespult werden (Modulo hilfreich).


Übung 15f

Aufbau siehe Übung 15!

Zusatzaufgabe für die Schnellen:

Verändere die Resetfunktion: Lasst den Zeiger immer den kürzesten Weg zurück auf Null laufen.

Tipp:

Minusschritte sind gegen den Uhrzeigersinn.


Morgen: Eigenes Projekt

Arduino von Zach Hoeken

Bitte verwendet das bisher Erlernte, um ein eigenes, kleines Projekt mit Arduino zu erstellen!

vormittags

  • Erstellen eines eigenen Prototypen als Kombination aus Arduino und frei wählbaren Sensoren und Actoren

nachmittags ab 15:00

Bitte überlegt Euch bis morgen früh, was Ihr machen möchtet!


Danke

Alle Scripte durchsuchen

Weitere Vorträge: