Skocz do zawartości

Mały układ do sterowania prędkością obrotową silnika krokowego


Miodek

Pomocna odpowiedź

Witam,
moim celem jest zbudowanie prostego układu pozwalającego na regulację obrotów silnika krokowego z wykorzystaniem hardware:

http://elektromaniak.pl/funduino/44-nano-v30-r3-.html

http://botland.com.pl/silniki-krokowe/1473-silnik-krokowy-42bygh102u-200-krokow-obr-36v-12a.html

http://botland.com.pl/wyswietlacze-alfanumeryczne/224-wyswietlacz-lcd-2x16-znakow-niebieski.html

http://botland.com.pl/sterowniki-silnikow-krokowych/148-sterownik-silnika-krokowego-a4988-reprap-35v-2a-modul-pololu.html

Zasilacz 12V 29A - taki jak do listw ledowych, dużo mocy, używam go do zasilania drukarki 3D.

Docelowo obroty na minutę (RPM) mają być regulowane enkoderem (drgania styków już załatwione), jednak do testów chciałem aby wartość tę przesłać z konsoli arduino poprzez port szeregowy. Obsługa wyświetlacza bez problemu - dane wysyłane są poprawnie odczytywane.

Problemem jest sterowanie obrotami silnika. Silnik jest 6-cio przewodowy, przy czym wykorzystuję tylko 4 przewody, tak aby działał jako bipolarny. Prąd na sterowniku silnika ustawiony potencjometrem do wartości 1,2A. Sterownik zasilany razem z wyświetlaczem z arduino. Napięcie na silnik z osobnego zasilacza 12V. Sleep spięty zworką z resetem.

Problem jest taki, że silnik nie zachowuje się tak jak powinien. Obroty < 35/min silnik stoi. Powyżej tej wartości silnik się kręci, jednak zmian w prędkości obrotowej trudno zauważyć. Do pewnej wartości przyspiesza, później zwalnia - nie wygląda żeby kręcił się zbyt równo.

Zakomentowany kod służy do obsługi enkodera z przerwaniami i drganiami styków.

#include <LiquidCrystal.h>
#include <SPI.h>

//Inicjalizacja połączeń
LiquidCrystal lcd(12, 11, 5, 4, 7, 6);
//tworzymy pusty łańcuch znaków do którego będziemy w pętli
//dodawać po 1 odczytanym znaku z przesłanych danych
String odczyt_serial = "";
//zmienna pomocnicza za pomocą której będziemy sprawdzać
//czy można wyświtlić odczytane dane z serial monitora
boolean koniec_odczytu = false;

//const int encoderPinA = 2;    //interrupt 1
//const int encoderPinB = 3;    //interrupt 0
const int stepPin = 8;
const int dirPin = 9;

//static boolean rotating = false;
//boolean A_set = false;
//boolean B_set = false;

volatile int encoderValue = 60;
unsigned long previousMicros = 0;
const int stepsPerRevolution = 200;

#define MAX_RPM 200

void setup() 
{ 
 // Wybór rodzaju wyświetlacza  - 16x2
 lcd.begin(16, 2); 

 lcd.print("Wlacz serial monitor");

 //pinMode( SS, OUTPUT );
 //SPI.begin();
 /*
 pinMode(encoderPinA, INPUT_PULLUP);
 pinMode(encoderPinB, INPUT_PULLUP);
 attachInterrupt( 0, doEncoderA, CHANGE);
 attachInterrupt( 1, doEncoderB, CHANGE);
 */
 pinMode( dirPin, OUTPUT );
 pinMode( stepPin, OUTPUT );

 // initialize serial communication at 9600 bits per second:
 Serial.begin(9600);
 while (!Serial);
 Serial.println("Podaj predkosc obrotowa");  
}

void loop()
{ 
 //rotating = true;

 // sprawdzamy czy są nowe dane
 if (Serial.available() > 0)
 {
   //czyścimy lcd
   lcd.clear();
   //wykonujemy pętle do momentu w którym są dane
   while (Serial.available())
   {
     //do zmiennej znakowej znak, ładujemy w każdym obrocie pętli kolejny znak
     //przesłanego tekstu, zaznaczając poprzez (char), że chcemy otrzymywać znaki
     //w ramach eksperymentu proponuję usunąć (char) i zobaczyć co wtedy się nam
     //na wyjściu ukaże
     char znak = (char)Serial.read();
     //do wcześniej utworzzonej zmiennej łańcuchowej(tekstowej)
     //dodajemy kolejno po znaku
     if(znak != '\n')
       odczyt_serial += znak;
     //jeśli ostatni wczytany znak, jest znakiem końca linii
     //ustawiamy zmienną na wartość prawda, tak żeby móc wyświetlić
     //tekst na lcd w kolejnej instrukcji if
     if(znak == '\n')
     {
       koniec_odczytu = true;
     }
   }
   if(koniec_odczytu == true)
   {
     //wypisanie na serial monitorze tego
     //co przedchwilą wysłaliśmy
     Serial.print("otrzymalem: ");
     Serial.println(odczyt_serial.toInt());
     encoderValue = odczyt_serial.toInt();
     //wypisanie na ekranie LCD wpisanego tekstu
     lcd.print("Aktualna predkosc:");
     lcd.setCursor(0, 1);
     lcd.print(odczyt_serial); 
     //po wypisaniu ustawiamy zmienną znów na fałsz,
     //tak żeby instrukcje zawarte w tym ifie
     //nie zostały wykonane ponownie bez wczesniejszego
     //otrzymania danych
     koniec_odczytu = false;
     //wyczyszczenie łańcucha znaków by móc znów
     //do niego wpisywać kolejne dane
     odczyt_serial = "";
   }
 }
else  
 doStep();
}
/*
void doEncoderA(){
 // debounce
 if ( rotating ) delay (1);  // wait a little until the bouncing is done

 // Test transition, did things really change? 
 if( digitalRead(encoderPinA) != A_set ) {  // debounce once more
   A_set = !A_set;

   // adjust counter + if A leads B
   if ( A_set && !B_set ) 
     if( encoderValue > 0 )
       encoderValue -= 1;

   rotating = false;  // no more debouncing until loop() hits again
 }
}

// Interrupt on B changing state, same as A above
void doEncoderB(){
 if ( rotating ) delay (1);
 if( digitalRead(encoderPinB) != B_set ) {
   B_set = !B_set;
   //  adjust counter - 1 if B leads A
   if( B_set && !A_set ) 
     if( encoderValue < MAX_RPM ) 
       encoderValue += 1;

   rotating = false;
 }
}
*/
void doStep()
{
 unsigned long currentMicros = micros();
 unsigned long interval = 60L*1000000L / encoderValue / stepsPerRevolution ;//?

 if( currentMicros - previousMicros >= interval)
 {
   digitalWrite( stepPin, HIGH );
   delayMicroseconds(1000);
   digitalWrite( stepPin, LOW );
 }

 previousMicros = currentMicros;
}

Prawdopodobnie to coś niezwykle błachego, dlatego proszę o podpowiedź. Jestem zielony w elektronice DIY, lepiej radzę sobie w mechanice i programowaniu.

Link do komentarza
Share on other sites

Bądź aktywny - zaloguj się lub utwórz konto!

Tylko zarejestrowani użytkownicy mogą komentować zawartość tej strony

Utwórz konto w ~20 sekund!

Zarejestruj nowe konto, to proste!

Zarejestruj się »

Zaloguj się

Posiadasz własne konto? Użyj go!

Zaloguj się »
×
×
  • Utwórz nowe...

Ważne informacje

Ta strona używa ciasteczek (cookies), dzięki którym może działać lepiej. Więcej na ten temat znajdziesz w Polityce Prywatności.