In een vorige blog heb ik uitgelegd hoe je met mijn eCurtains project je gordijnen automatisch kunt bedienen. Ik maakte hierbij gebruik van een 28BYJ-48 stappen motor met een ULN motor driver. Dit werkt prima, maar de stappen motor is wel wat langzaam. Ik ben daarom wat verder gaan rondkijken en een goed alternatief is in dat geval een Nema17 stappen motor. Deze kost wel wat meer, maar is dan ook een stuk sneller en robuuster. In deze blog beschrijf ik hoe je een Nema17 stappen motor kunt aansturen en hoe je deze integreert in eCurtains.
Benodigheden
Je kunt de Nema17 stappen motor met diverse drivers aansturen. Ik heb gekozen voor de A4988.
1 x Breadboard 400
1 x NodeMcu ESP8266 (CH340/CP2102)
1 x MB102 Breadboard Power Supply Module 3.3V 5V
1 x Nema 17 42mm 12V Hybrid Two Phase Stepper Motor
1 x Nema 17 Mounting L Bracket 42
1 x SYB-170 Mini Breadboard
1 x A4988 DRV8825 Stepper Motor Driver
1 x DC12V Plug Adapter Connector Male
1 x 100uF 25V Nichichon Low Impedance Long Life Aluminum Electrolytic capacitor (10 stuks)
1 x Waterproof ABS Plastic Electronic Enclosure Project Box Case Black 125 x 80 x 32 mm
1 x VOLTCRAFT ESPS-1500 Stekkernetvoeding, instelbaar (Euro 9,91)
Zie ook de volgende link met meer informatie en technische details.
Aansluiten
Het aansluiten is heel eenvoudig als je de pin-aansluitingen van je ESP8266 module en A4988 motor driver weet:
Plaats je ESP8266 en A4988 stepper motor driver op je breadboard en sluit deze als volgt aan op je NEMA17 stappen motor.
Als de ingangstoestand van de RESET pin een logisch laag is, worden alle STEP-ingangen genegeerd. Door de SLEEP pin laag te zetten schakel je de driver uit (waardoor je de temperatuur van je stappen motor laag kunt houden).
Als je alles hebt aangesloten dan ziet dit er als volgt uit:
Programmeren
Ik verwijs voor het opzetten van de programmeer omgeving naar mijn vorige blog. Het aansturen van de stappen motor gaat heel eenvoudig met het volgende stukje code:
// For ESP8266 #include// ESP8266 WiFi #include // ESP8266 Web Server #include // EEPROM #include // Serial Peripheral Interrface #include // File system // For Steppermotor #include // // Steppermotor settings // #define STEPS_PER_REVOLUTION 200 // Steps per Revolution #define MOTOR_MAX_SPEED 300.0 // Maximum speed of motor #define MOTOR_ACCELERATION 100.0 // Acceleration of motor #define MOTOR_PIN_DIRECTION D1 // Direction pin on A4988 Driver => GPIO16 #define MOTOR_PIN_STEPS D2 // Steps pin on A4988 Driver => GPIO5 #define MOTOR_PIN_SLEEP D5 // Sleep pin on A4988 Driver => GPIO14 #define MOTOR_PIN_RESET D6 // Reset pin on A4988 Driver => GPIO12 // Initialize for using AccelStepper with NEMA17 with A4988 driver AccelStepper Stepper( AccelStepper::DRIVER, MOTOR_PIN_STEPS, MOTOR_PIN_DIRECTION ); // Set 'reset' pin to HIGH pinMode( MOTOR_PIN_RESET, OUTPUT); digitalWrite( MOTOR_PIN_RESET, HIGH ); // ----------------------------------------------------------------------------------------- // setup // Default setup() method called once by Arduino // ----------------------------------------------------------------------------------------- void setup() { // Setup serial port for your Serial Monitor Serial.begin( 115200 ); // Move motor 3 rotations move_motor ( 3.0 ); // Wait 1 second delay (1000); // Move motor 3 rotations back move_motor ( -3.0 ); } void move_motor (float no_rotations) { // Set maximum of motor speed Stepper.setMaxSpeed ( MOTOR_MAX_SPEED ); // Set acceleration8 Stepper.setAcceleration ( MOTOR_ACCELERATION ); // Set 'sleep' pin to HIGH again pinMode( MOTOR_PIN_SLEEP, OUTPUT); digitalWrite( MOTOR_PIN_SLEEP, HIGH ); // Give stepper instruction to move motor Stepper.move( no_rotations * STEPS_PER_REVOLUTION); } // ----------------------------------------------------------------------------------------- // loop () // Here you find the main code which is run repeatedly // ----------------------------------------------------------------------------------------- void loop() { // Handle Client server.handleClient(); // Control movement of motor Stepper.run(); // If motor it not running then disable motor pin outputs if ( Stepper.isRunning() == 0) { // Set 'sleep' pin to LOW again pinMode( MOTOR_PIN_SLEEP, OUTPUT); digitalWrite( MOTOR_PIN_SLEEP, LOW ); } }
Zoals je in bovenstaande code-snippet ziet zijn er eigenlijk maar 2 dingen anders vergeleken met de code voor de 28BYJ-48 stappen motor met een ULN driver:
- Voor NEMA17 gebruik je 200 stappen/omwenteling i.p.v. 2048
- Voor NEMA17 is de initialisatie van de AccelStepper library anders
Gebruik in eCurtains
Ik heb ondertussen vanaf eCurtain V1.02 de code aangepast zodat je kunt instellen welke stappen motor/driver je gebruikt. Gemakkelijker kan het dus niet voor jou.
Op dit moment gaat het bedienen van de gordijnen met de snelheid zoals in onderstaande filmpje:
Laat je even in de reacties weten of het jou ook is gelukt om je Nema17 stappen motor te bedienen?
Beste Henri, dank voor het delen van dit project !! Ik ga het gebruiken, maar dan voor mijn rolgordijnen, dus, wat ik denk, met hier en daar wat aanpassingen 😉 …Nogmaals dank !!!
Top Sjerrel. Ik denk dat het voor rolgordijnen wat gemakkelijker is. Succes met je project.
Leuk project, ga ik straks na m’n verbouwing ook proberen. Wat ik me wel af vroeg, zijn de gordijnen ook nog handmatig te bedienen, en weet het programma dan de stand van de gordijnen daarna nog ?
Je kunt met deze oplossing de gordijnen niet handmatig meer bedienen, daar je dan je referentie kwijt bent en het systeem dus niet weet in welke stand de gordijnen dan staan. Ik heb zelf een 3 button knop naast de gordijnen geplaats (open, stop, dicht). Op deze manier kun je de gordijnen precies in die stand zetten als je wilt, maar dan automatisch.
Dat vermoedde ik al. Op zich geen probleem en de knop naast het gordijn zorgt er voor dat toch iedereen hem kan bedienen. Lijkt me een leuk projectje dus ik ga er mee aan de slag.
Ik ga de onderdelen bestellen en zal binnenkort ook maar eens een kleine bijdrage doen naar jouw kant want dat scheelt mij een hoop regels code schrijven :-).
Nog een klein vraagje, ik bekeek het resultaat van jouw aansluiting en die kon ik bijna helemaal volgens. Het was me alleen niet helemaal duidelijk hoe de power supply module van stroom voorzien wordt. Die kabeltjes kon ik net niet helemaal volgen. Ik vermoed dat ze naar de female connector gaan en dat je op die manier de motorpower supply en de power supply module met de zelfde adapter van stoom voorziet. Klopt die aanname?
Die aanname klopt Lucas.
Hallo, ik heb het projectje gedaan en de stappenmotor werkt! Maar een vraagje, heb je de fouten er bewust ingezet?
Welke fouten Joop?
Hallo Henri, bij move -100 is de punt comma vergeten en g_AccelStepper deze vaiable bestaat niet. Moet volgens mij gewoon “Stepper” zijn dit werkt in ieder geval. Groeten Joop Maat ander vraagje hoe kan ik de positie bepalen als ik b.v. een noodstop knopje indruk? Kan met een lus maar dan werk volgens mij de acceleratie niet meer.
Je hebt helemaal gelijk Joop. Ik heb de fouten nu verbeterd. In mijn originele code staat het correct, maar bij het overzetten naar de blog is het ergens fout gegaan denk. Bedankt dat je mij hierop hebt gewezen!
Met betrekking tot je ‘noodstop’ vraag. Ik mijn code houd ik de actuele en vorige positie altijd bij in globale variabelen.
// Initialize current position in internal administration of AccelStepper Library
// This way you can determine the current position when 'stop' is pressed
Stepper.setCurrentPosition ( 0 );
Als je dus op [Stop] drukt dan wordt dit netjes in de interne administratie bijgehouden:
// -----------------------------------------------------------------------------------------
// handle_stop_motor
// Stop motor movement
// -----------------------------------------------------------------------------------------
void handle_stop_motor()
{
// Stop any possible motor movement
Stepper.stop();
// Calculate positions moved
float positions_moved = (Stepper.currentPosition() / (g_data.steps_per_revolution * 1.0));
// Check if motor even moved
if ( fabs(positions_moved) > g_epsilon )
{
g_data.position_current = g_data.position_current_previous + positions_moved;
EEPROM.put( g_start_eeprom_address, g_data);
EEPROM.commit();
}
Stepper.setCurrentPosition ( 0 );
}
Henri, ik heb het antwoord op mijn vraag gevonden moet zijn Stepper.currentPosition()