Skocz do zawartości

Sterowanie silnikiem krokowym


kellyq

Pomocna odpowiedź

Upraszczając, kod działa w ten sposób że sprawdzam jaka waga jest na czujniku tensometrycznym i do tej wagi dostosowuje prędkość silnika krokowego. Kiedy waga dojdzie do zadanej silnik krokowy zatrzymuje się. Poza tym w kodzie jest jeszcze obsługa menu wielopoziomowego. Używam biblioteki accelstepper i dużego silnika krokowego 8Nm. Problem tkwi w tym że prawdopodobnie pętla loop jest za długa i nie zoptymalizowana pod silnik krokowy. Objawy to to że silnik cyka zamias kręcić z odpowiednią prędkością. Czy jest ktoś może obeznany z tą biblioteką i podpowie co by można było poradzić na to. 

Wcześniej moim kodem obsługiwałem silnik 3f z falownikiem. Teraz przy maszynie mam krokowca bo trzy fazowy silnik to była by przesada, maszyna sporo mniejsza od poprzedniej. Ostatnią deską ratunku jest konwerter 0-10v na częstotliwość ale chciałem tego uniknąć i w kodzie jakoś to zaprogramować.

Link do komentarza
Share on other sites

Szklana kula do wróżenia jest droga, jak ją kupisz to za free Ci odpowiem. Jak chcesz oszczędzić wydatku wstaw kod 😉 

Edytowano przez H1M4W4R1
  • Nie zgadzam się! 1
Link do komentarza
Share on other sites

No właśnie pętla loop trochę zamula, nie chciałbym kodu wstawiać bo trochę się nad nim namordowałem, prawa autorskie, rodo itd 😜. A jakie mi jeszcze pozostają opcje do wysterowania krokowca w mojej sytuacji? A może wziąć jakiś atiny i nim wysterować krokowca osobno, tylko znowu nie wiem jak skomunikować ich nawzajem hmmmm...

Link do komentarza
Share on other sites

Zarejestruj się lub zaloguj, aby ukryć tę reklamę.
Zarejestruj się lub zaloguj, aby ukryć tę reklamę.

jlcpcb.jpg

jlcpcb.jpg

Produkcja i montaż PCB - wybierz sprawdzone PCBWay!
   • Darmowe płytki dla studentów i projektów non-profit
   • Tylko 5$ za 10 prototypów PCB w 24 godziny
   • Usługa projektowania PCB na zlecenie
   • Montaż PCB od 30$ + bezpłatna dostawa i szablony
   • Darmowe narzędzie do podglądu plików Gerber
Zobacz również » Film z fabryki PCBWay

6 minut temu, kellyq napisał:

A może wziąć jakiś atiny i nim wysterować krokowca osobno, tylko znowu nie wiem jak skomunikować ich nawzajem hmmmm...

UART, SPI, I2C, itd... rozumiem, że ten szeroki wybór sprawia, że nie wiesz co wybrać...

9 minut temu, kellyq napisał:

nie chciałbym kodu wstawiać bo trochę się nad nim namordowałem, prawa autorskie, rodo itd 😜

No jak pomysł i algorytm, aż tak fajny to patent 😛  

Link do komentarza
Share on other sites

1) Uprościłeś sprawę za bardzo - co prawda umieściłeś post w dziale "Arduino i ESP" ale nie napisałeś czy to Arduino czy ESP.

2) Jeśli ESP32 to sprawa jest trywialna - odpalasz task na rdzeniu 0 i niech zajmuje się tylko obsługą tej nieszczęsnej biblioteki

3) Jeśli to Arduino to wywalić bibliotekę, napisać własny kod i użyć przerwania zegarowego (biblioteka TimerInterrupt czy jakoś tak) - chociaż być może uda się sterowanie accelstepperem z przerwania.

4) przy okazji: AccelStepper jest na GPL, ale to już Twój problem. Wiesz - ktoś się nad tym namordował, prawa autorskie, licencja...

Edytowano przez ethanak
  • Lubię! 1
Link do komentarza
Share on other sites

46 minut temu, kellyq napisał:

nie chciałbym kodu wstawiać bo trochę się nad nim namordowałem, prawa autorskie, rodo itd 😜

Panie...przeciez nie zdradzales do jakiej maszyny ten kod...dla nas to tylko kod ktory kreci silnikiem w zaleznosci od czujnika...

Hmmm...jedyne rady w takiej sytuacji to

50 minut temu, kellyq napisał:

No właśnie pętla loop trochę zamula

To trzeba zrobic tak zeby nie zamulala...jak masz delaye to je wywal i wstaw millis()

 

52 minuty temu, kellyq napisał:

A jakie mi jeszcze pozostają opcje do wysterowania krokowca w mojej sytuacji?

Rozne...mozesz wystartowac silnik na przerwaniach/timerach i problem z wolnym loop znika

 

54 minuty temu, kellyq napisał:

A może wziąć jakiś atiny i nim wysterować krokowca osobno, tylko znowu nie wiem jak skomunikować ich nawzajem hmmmm...

Ma to sens i jednoczesnie jest bez sensu bo nie wiemy na ile obciazony jest glowny procek i nie wiadomo czy dodatkowy uklad jest potrzebny...

Link do komentarza
Share on other sites

Dobra wstawiam kod ale ostrzegam że jest długi, działam na atmega 328p czyli to co w arduino ale na swojej płytce. W sterowaniu falownikiem sprawdza się elegancko.

#include <AccelStepper.h>
#include <Wire.h> 
#include <LiquidCrystal_I2C.h>
#include <EEPROM.h>
#include "HX711.h"
#define up 7
#define down 6
#define set 9
#define back 8
#define wyjscieFalownik 10              //główny wyjscieFalownik
#define wyjsciePrzekaznik 16            //główny przekażnik od zamykania kosza
#define przyciskKiprowanie 17           //przycisk kiprowania
#define PUL 4
#define DIR 5

                                       
#define a 2                                        //nieużywane piny
#define b 3   
#define e 11
#define f 12
#define g 13  
      

  AccelStepper stepper(1,4,5); // (mode, pul, dir)

  HX711 scale(A0, A1);
  LiquidCrystal_I2C lcd(0x27,16,2); 
  byte kostka[] = {
  B11111,
  B11111,
  B11111,
  B11111,
  B11111,
  B11111,
  B11111,
  B11111
};
            
  unsigned long czas = 0;

  float zadanaWaga = EEPROM.get(0, zadanaWaga);
  float przekaznik = EEPROM.get(4, przekaznik);
  float wspKalibracji = EEPROM.get(8, wspKalibracji);
  float progI = EEPROM.get(12, progI);
  float progII = EEPROM.get(16, progII);
  float predkosc1 = EEPROM.get(20, predkosc1);
  float predkosc2 = EEPROM.get(24, predkosc2);
  float predkosc3 = EEPROM.get(28, predkosc3);
  float wzorzec = EEPROM.get(32, wzorzec);
  float liczMiejsc = EEPROM.get(36, liczMiejsc);
  float probkowanie = EEPROM.get(40, probkowanie);
  float przekaznikStan = EEPROM.get(44, przekaznikStan);
  float autotarowanie = EEPROM.get(48, autotarowanie);
  float podswietlenie = EEPROM.get(52, podswietlenie);
  float ujemnaWaga = EEPROM.get(56, ujemnaWaga);
  int rozmiarBufora = EEPROM.read(60); 
  float filter = EEPROM.get(64, filter);         //od 1 najsłabsze działanie do 0 najsilniejsze
  
  const int wagaArrayCount = 50;      
  float wagaArray[wagaArrayCount];              
  float wagaSum;   
  float Array[1]; //0 to nowy odczyt
  float zero = 0.00000;
  int counter = 0;                            //zmienna ile  zliczono paczek
  boolean nawazone_1kg = 0;                 //zmienna przechowuje stan kiedy naważono 1kg
  boolean pierwszy_rozruch = 0;             //pierwszy rozruch
  unsigned long oldTime = 0;
  unsigned long oldTime2 = 0;
  int screen = 0;
                      
  
void setup() {
  pinMode(up, INPUT);
  pinMode(down, INPUT);
  pinMode(set, INPUT);
  pinMode(back, INPUT);
  pinMode(wyjscieFalownik, OUTPUT);
  pinMode(wyjsciePrzekaznik, OUTPUT);
  pinMode(przyciskKiprowanie, INPUT);
  pinMode(PUL, OUTPUT);
  pinMode(DIR, OUTPUT);
  
  pinMode(a, OUTPUT);
  pinMode(b, OUTPUT);
  pinMode(e, OUTPUT);
  pinMode(f, OUTPUT);
  pinMode(g, OUTPUT);
  digitalWrite(a, LOW);
  digitalWrite(b, LOW);
  digitalWrite(e, LOW);
  digitalWrite(f, LOW);
  digitalWrite(g, LOW);
  
  if(EEPROM.read(999)!=222){     //zapis standardowych ustawień
    EEPROM.write(999, 222);      // zapis kontrolnej liczby żeby nie nadpisywać za każdym wgraniem szkicu
    EEPROM.put(0, 1.0);        //zadana waga  15kg
    EEPROM.put(4, 1.4);           //przekaznik 1,4sekundy
    EEPROM.put(8, -121.8);        //wspKalibracji  -121,8
    EEPROM.put(12, 70.0);         //prog 1 70%
    EEPROM.put(16, 90.0);         //prog 2 90%
    EEPROM.put(20, 244.0);        //predkość 1 6000=max
    EEPROM.put(24, 125.0);        //predkosc 2 
    EEPROM.put(28, 60.0);         //predkosc 3
    EEPROM.put(32, 0.02);         //wzorzec 1kg
    EEPROM.put(36, 3);            //liczba miejsc po przecinku
    EEPROM.put(40, 10.0);         //próbkowanie
    EEPROM.put(44, 0.0);          //odwrocenie dzialania przekaznika
    EEPROM.put(48, 1.0);          //autotarowanie po każdym wysypaniu z kosza wagowego
    EEPROM.put(52, 1.0);          //podswietlenie
    EEPROM.put(56, 0.0);          //waga nie ujemna
    EEPROM.write(60, 10);         //rozmiar tablicy do wagi
    EEPROM.put(64, 0.2);          //filter
  }
//  if(przekaznikStan==0){
//    digitalWrite(wyjsciePrzekaznik, HIGH);  //przekażnik rozwarty
//  }else if(przekaznikStan==1){
//    digitalWrite(wyjsciePrzekaznik, LOW);  //przekażnik rozwarty
//  }

  stepper.setMaxSpeed(10000);
  //stepper.setAcceleration(2000);
    
  //wyskalowanie po uruchomieniu
  scale.read();
  scale.read_average(10);
  scale.get_value(100);
  scale.get_units(10);
  scale.set_scale(wspKalibracji);    
  scale.tare();
  delay(100);
  
  lcd.init();                       
  if(podswietlenie==1){
    lcd.backlight();
  }else if(podswietlenie==0){
    lcd.noBacklight();
  }
  lcd.createChar(0, kostka);
  lcd.setCursor(0,0);
  lcd.print("  Uruchamiam...");
  
  for (int i = 0; i < 16; i++){         //animacja początkowa
    lcd.setCursor(i,1);
    lcd.write(byte(0));
    delay(80);                       //odstęp pomiędzy animacją kwadracików
  }




}
  volatile byte levelMarker = 0;            //poziom menu
  volatile byte positionMarker = 0;         //strzałka
  volatile byte menuMarker = 0;             //strzałka    
  volatile byte optionMarker = 0;           //która opcja z menu
  String myMenu[] = {
    "ZADANA WAGA",
    "PRZEKAZNIK",
    "KALIBRACJA",
    "WSP. KALIBRACJI",
    "PROG I",
    "PROG II",
    "WZORZEC",
    "PROBKOWANIE",
    "LICZ MSC PO PRZ",
    "PREDKOSC I",
    "PREDKOSC II",
    "PREDKOSC III",
    "STAN PRZEKAZNIK",
    "AUTOTAROWANIE",
    "PODSWIETLENIE",
    "UJEMNA WAGA",
    "ROZMIAR BUFORA",
    "FILTER"
  };
  
void tarowanie(void){
//  scale.read();
//  scale.read_average(10);
//  scale.get_value(100);
//  scale.get_units(10);
  scale.set_scale(wspKalibracji);    
  scale.tare();
  delay(100);
  for (int i=wagaArrayCount-1; i>-1; i--){        //zerowanie tablicy
   wagaArray[i] = 0.00;
  }
  Array[0]=0.00;
}

void printValue(float value, int button){
  delay(200);
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print(value);
  button = 0;
}
void kalibruj(){
  lcd.clear();
  delay(1000);
  lcd.setCursor(0,0);
  lcd.print("KALIBRACJA START");
  lcd.print("oproznij wage");
  delay(1000);
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("OPROZNIJ WAGE");
  while(digitalRead(set) == 1){
    lcd.setCursor(0,1);
    lcd.print("NACISNIJ SET");
  }
  delay(200);    //debounce
  scale.set_scale();
  scale.tare();
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("UMIESC WZORZEC");
  lcd.setCursor(0,1);
  lcd.print("NACISNIJ SET");
  while(digitalRead(set) == 1){   
  }
  delay(200);    //debounce
  float waga_kal = scale.get_units(100);
  wspKalibracji = waga_kal/(wzorzec*1000); 
  EEPROM.put(8, wspKalibracji);
  scale.set_scale(wspKalibracji);
  scale.tare();
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("SKALIBROWANO");
  lcd.setCursor(0,1);
  lcd.print("I ZAPISANO :-)");
  delay(2000);
  
  levelMarker=1;
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print(">"+myMenu[menuMarker]);
  lcd.setCursor(0,1);
  lcd.print(" "+myMenu[menuMarker+1]);   
}
void clearLCDLine(int line)
  {               
        lcd.setCursor(0,line);
        for(int n = 0; n < 16; n++){
          lcd.print(" ");
        }
  }

int buttonKrotki = 0;
int buttonDlugi = 0;
unsigned long czasWcisku = 0;
int ktoryBtnWcisniety = 0;
 
void loop() {
  
  int button=0;
  if(digitalRead(up) == 0) {
    button = 1;
    ktoryBtnWcisniety = 1;
    if(czasWcisku == 0)
      czasWcisku = millis();
  }
  if(digitalRead(down) == 0) {
    button = 2;
    ktoryBtnWcisniety = 2;
    if(czasWcisku == 0)
      czasWcisku = millis();
  }
  if(digitalRead(set) == 0) button = 3;
  if(digitalRead(back) == 0) button = 4;
  
  if(ktoryBtnWcisniety == 1 && (millis() - czasWcisku > 200)) 
    buttonDlugi = 1;
  else if(ktoryBtnWcisniety == 2 && (millis() - czasWcisku > 200))  
    buttonDlugi = 2;
  

  if(digitalRead(up) == 1 && ktoryBtnWcisniety == 1) {
    if((millis() - czasWcisku < 200) && buttonDlugi == 0)
      buttonKrotki = 1;
      
    ktoryBtnWcisniety = 0;
    buttonDlugi = 0;
    czasWcisku = 0;
  }

  if(digitalRead(down) == 1 && ktoryBtnWcisniety == 2) {
    if((millis() - czasWcisku < 200) && buttonDlugi == 0)
      buttonKrotki = 2;
      
    ktoryBtnWcisniety = 0;
    buttonDlugi = 0;
    czasWcisku = 0;
  }


  if (levelMarker==0){
    if (nawazone_1kg == 1) {
//      if(przekaznikStan==0){
//        digitalWrite(wyjsciePrzekaznik, LOW);        //wysypanie z wagi
//        delay(przekaznik * 1000);
//        digitalWrite(wyjsciePrzekaznik, HIGH);         //powrot na pozycje pierwotna
//        delay(1000);  
//      }else if(przekaznikStan==1){
//        digitalWrite(wyjsciePrzekaznik, HIGH);        //wysypanie z wagi
//        delay(przekaznik * 1000);
//        digitalWrite(wyjsciePrzekaznik, LOW);         //powrot na pozycje pierwotna
//        delay(500);
//      }
      nawazone_1kg = 0;
      counter = counter + 1;                         //zlicza naważone paczki 
      
      for (int i=wagaArrayCount-1; i>-1; i--){        //zerowanie tablicy
      wagaArray[i] = 0.00;
      }
        
      if(autotarowanie==1)tarowanie();                           
      }

    float waga = scale.get_units(probkowanie);                  //zlicza wage
      
    unsigned long czasTeraz = millis();
    float wydajnosc =((counter*zadanaWaga) / czasTeraz )*3600000   ;

    for (int i=rozmiarBufora-1; i>0; i--){
      wagaArray[i] = wagaArray[i-1];
    }
    wagaArray[0] = waga;

    wagaSum = 0;
    for (int i=0; i<rozmiarBufora; i++)wagaSum += wagaArray[i];
    wagaSum /= rozmiarBufora;

    float wagaToDisplay = filter*wagaSum+(1-filter)*Array[0];
    Array[0]= wagaSum;
    

  if(screen ==0){
    if(millis()-oldTime > 100){         //wyswietlanie co 100ms
      clearLCDLine(0);
      clearLCDLine(1);
      lcd.setCursor(0,0);
      if(ujemnaWaga==1){
        lcd.print(wagaToDisplay*0.001, liczMiejsc);
        lcd.print(" KG"); 
      }else if(ujemnaWaga==0){
        if(wagaToDisplay*0.001>=0){
          lcd.print(wagaToDisplay*0.001, liczMiejsc);
          lcd.print(" KG"); 
        }else if(wagaToDisplay*0.001<0){
          lcd.print(zero, liczMiejsc);
          lcd.print(" KG"); 
        }
      }
      oldTime = millis(); 
    } 
  }else if(screen==1){
    if(millis()-oldTime2 > 1000){        //wyświetlanie co 2 sekunde
          lcd.clear();
          lcd.setCursor(0,0);
          lcd.print(round(wydajnosc));
          lcd.print(" KG/H");
          lcd.setCursor(0,1);
          lcd.print(counter);
          lcd.print(" SZTUK SUM");
          oldTime2 = millis();
        }
  }
    
    
    
    if (wagaToDisplay < ((zadanaWaga*1000) * (progI*0.01))) {    //waga poniżej 70%
      //analogWrite(wyjscieFalownik, predkosc1);
        stepper.setSpeed(predkosc1);
        stepper.runSpeed();



    }
    if (wagaToDisplay > ((zadanaWaga*1000) * (progI*0.01)) && wagaToDisplay < ((zadanaWaga*1000) * (progII*0.01))) {   // 70-90%
      //analogWrite(wyjscieFalownik, predkosc2);
        stepper.setSpeed(predkosc2);
        stepper.runSpeed();
    }
    if (wagaToDisplay > ((zadanaWaga*1000) * (progII*0.01)) && wagaToDisplay < (zadanaWaga*1000)) {
      //analogWrite(wyjscieFalownik, predkosc3);
        stepper.setSpeed(predkosc3);
        stepper.runSpeed();
    }
    if (wagaToDisplay >= (zadanaWaga*1000)) {
      //analogWrite(wyjscieFalownik, 0);
        stepper.setSpeed(0);
        stepper.runSpeed();

      while (1) {
        if (digitalRead(przyciskKiprowanie) == LOW) {
        goto skip_1;
        }
      }
skip_1:
      nawazone_1kg = 1;
    } 
  }
  
  if(levelMarker==0){
    switch(button){                     //wejście do menu
      case 1:
        if(screen<1)screen++;
        break;
      case 2:
        if(screen>0)screen--;
        break;
      case 3:
        levelMarker = 1;
        button=0;
        delay(300);
        lcd.clear();
        lcd.setCursor(0,0);
        lcd.print(">"+myMenu[menuMarker]);
        lcd.setCursor(0,1);
        lcd.print(" "+myMenu[menuMarker+1]);    
      break;
      case 4:
        if(screen==0)tarowanie();
        if(screen==1)counter=0;
        button=0;
       
     
     }
  }
  
  if(levelMarker==1){
    switch(button){
      case 1:                       //nacisniecie góra w menu głównym
        if(positionMarker == 1) {
          delay(300);
          lcd.clear();
          positionMarker--;
          lcd.setCursor(0,0);
          lcd.print(">"+myMenu[menuMarker]);
          lcd.setCursor(0,1);
          lcd.print(" "+myMenu[menuMarker+1]); 
        } else if(positionMarker == 0 && menuMarker > 0) {
          delay(300);
          lcd.clear();
          menuMarker--;
          lcd.setCursor(0,0);
          lcd.print(">"+myMenu[menuMarker]);
          lcd.setCursor(0,1);
          lcd.print(" "+myMenu[menuMarker+1]); 
        }
        break;
        
      case 2:         //nacisniecie dół w menu głównym
        if(positionMarker == 0) {
          delay(300);
          lcd.clear();
          positionMarker++;
          lcd.setCursor(0,0);
          lcd.print(" "+myMenu[menuMarker]);
          lcd.setCursor(0,1);
          lcd.print(">"+myMenu[menuMarker+1]); 
        } else if(positionMarker == 1 && menuMarker < 16) {     //tu zmienić dodając podmenu
          delay(300);
          lcd.clear();
          menuMarker++;
          lcd.setCursor(0,0);
          lcd.print(" "+myMenu[menuMarker]);
          lcd.setCursor(0,1);
          lcd.print(">"+myMenu[menuMarker+1]); 
        }
        break;
      case 3:               //nacisniecie set w menu głównym
        levelMarker++;
        if(positionMarker == 0 && menuMarker == 0) {
            //zadana waga 
            printValue(zadanaWaga, button);
            lcd.print(" KG");
            optionMarker = 0;
        } else if(positionMarker == 0 && menuMarker == 1 ||
          positionMarker == 1 && menuMarker == 0) {
            //przekaźnik
            printValue(przekaznik, button);
            lcd.print(" SEK.");
            lcd.setCursor(0,1);
            lcd.print("CZAS OTWARCIA");
            optionMarker = 1;
        } else if(positionMarker == 0 && menuMarker == 2 ||
          positionMarker == 1 && menuMarker == 1){
            //kalibracja
            button = 0;
            optionMarker = 2;
        } else if(positionMarker == 0 && menuMarker == 3 ||
          positionMarker == 1 && menuMarker == 2){
            //wsp skali
            printValue(wspKalibracji, button);
            optionMarker = 3;
        } else if(positionMarker == 0 && menuMarker == 4 ||
          positionMarker == 1 && menuMarker == 3){
            //prog 1
            printValue(progI, button);
            lcd.print(" %");
            optionMarker = 4;
        } else if(positionMarker == 0 && menuMarker == 5 ||
          positionMarker == 1 && menuMarker == 4){
            //prog 2
            printValue(progII, button);
            lcd.print(" %");
            optionMarker = 5;
        } else if(positionMarker == 0 && menuMarker == 6 ||
          positionMarker == 1 && menuMarker == 5){
            //wzorzec
            printValue(wzorzec, button);
            lcd.print(" KG");
            optionMarker = 6;
        } else if(positionMarker == 0 && menuMarker == 7 ||
          positionMarker == 1 && menuMarker == 6){
            //probkowanie
            printValue(probkowanie, button);
            optionMarker = 7;
            lcd.setCursor(0,1);
            lcd.print("WIECEJ=WOLNIEJ");
        } else if(positionMarker == 0 && menuMarker == 8 ||
          positionMarker == 1 && menuMarker == 7){
            //liczba miejsc op przec
            printValue(liczMiejsc, button);
            optionMarker = 8;
        } else if(positionMarker == 0 && menuMarker == 9 ||
          positionMarker == 1 && menuMarker == 8){
            //PREDKOSC 1
            printValue(predkosc1, button);
            lcd.setCursor(0,1);
            lcd.print("6000 = MAX");
            optionMarker = 9;
        } else if(positionMarker == 0 && menuMarker == 10 ||
          positionMarker == 1 && menuMarker == 9){
            //PREDKOSC 2
            printValue(predkosc2, button);
            lcd.setCursor(0,1);
            lcd.print("6000 = MAX");
            optionMarker = 10;
        } else if(positionMarker == 0 && menuMarker == 11 ||
          positionMarker == 1 && menuMarker == 10){
            //PREDKOSC 3
            printValue(predkosc3, button);
            lcd.setCursor(0,1);
            lcd.print("6000 = MAX");
            optionMarker = 11;
        } else if(positionMarker == 0 && menuMarker == 12 ||
          positionMarker == 1 && menuMarker == 11){
            //przekaznik stan
            printValue(przekaznikStan, button);
            lcd.setCursor(0,1);
            lcd.print("0=NO, 1=NC");
            optionMarker = 12;
        } else if(positionMarker == 0 && menuMarker == 13 ||
          positionMarker == 1 && menuMarker == 12){
            //autotarowanie
            printValue(autotarowanie, button);
            lcd.setCursor(0,1);
            lcd.print("O-off 1-on");
            optionMarker = 13;
        } else if(positionMarker == 0 && menuMarker == 14 ||
          positionMarker == 1 && menuMarker == 13){
            //podswietlenie
            printValue(podswietlenie, button);
            lcd.setCursor(0,1);
            lcd.print("O-off 1-on");
            optionMarker = 14;
        } else if(positionMarker == 0 && menuMarker == 15 ||
          positionMarker == 1 && menuMarker == 14){
            //ujemna waga
            printValue(ujemnaWaga, button);
            lcd.setCursor(0,1);
            lcd.print("1 = dozwolone");
            optionMarker = 15;
        } else if(positionMarker == 0 && menuMarker == 16 ||
          positionMarker == 1 && menuMarker == 15){
            //rozmiar tablicy
            printValue(rozmiarBufora, button);
            lcd.setCursor(0,1);
            lcd.print("MIN 1, MAX ");
            lcd.setCursor(12,1);
            lcd.print(wagaArrayCount);
            optionMarker = 16;
        }else if(positionMarker == 0 && menuMarker == 17 ||
          positionMarker == 1 && menuMarker == 16){
            //filter
            printValue(filter, button);
            lcd.setCursor(0,1);
            lcd.print("MIN 0, MAX 1");
            optionMarker = 17;
        }
        break;
      case 4:
        delay(300);
        lcd.clear();
        levelMarker = 0;
        screen = 0;
    } 
  }

  if(levelMarker == 2) {
    if(button == 4) {
      levelMarker = 1;
      button=0;
      delay(300);
      lcd.clear();
      if(positionMarker == 0) {
        lcd.setCursor(0,0);
        lcd.print(">"+myMenu[menuMarker]);
        lcd.setCursor(0,1);
        lcd.print(" "+myMenu[menuMarker+1]);
      } else {
        lcd.setCursor(0,0);
        lcd.print(" "+myMenu[menuMarker]);
        lcd.setCursor(0,1);
        lcd.print(">"+myMenu[menuMarker+1]);
      }
    }
    
    switch(optionMarker) {
      case 0: //zadana waga
        if(buttonKrotki == 1) {
          zadanaWaga=zadanaWaga+0.01;
          printValue(zadanaWaga, button);
          lcd.print(" KG");
          buttonKrotki = 0;
        } 
        else if(buttonDlugi == 1) {
          zadanaWaga++;
          printValue(zadanaWaga, button);
          lcd.print(" KG");
         } 
        else if(buttonKrotki == 2) {
          if(zadanaWaga>0.01)zadanaWaga=zadanaWaga-0.01;
          printValue(zadanaWaga, button);
          lcd.print(" KG"); 
          buttonKrotki = 0;
        } 
        else if(buttonDlugi == 2) {
          if(zadanaWaga>0)zadanaWaga--; 
          printValue(zadanaWaga, button);
          lcd.print(" KG");
        } else if(button == 3) {
          EEPROM.put(0, zadanaWaga);
          button = 0;
        }
        break;
      case 1: //przekaźnik
        switch(button) {
            case 1:
              przekaznik+=0.01;
              printValue(przekaznik, button);
              lcd.print(" SEK.");
              lcd.setCursor(0,1);
              lcd.print("CZAS OTWARCIA");
              break;
            case 2: 
              if(przekaznik>0)przekaznik-=0.01;
              printValue(przekaznik, button);
              lcd.print(" SEK.");
              lcd.setCursor(0,1);
              lcd.print("CZAS OTWARCIA");
              break;
            case 3:   //zapisanie do epromu
              EEPROM.put(4, przekaznik);
              button = 0;
          }
        break;
       case 2: //kalibracja
        switch(button) {
            case 1:
              
              button = 0;
              break;
            case 2: 
              
              button = 0;
              break;
            case 3: //zapisanie do epromu
              kalibruj();
              button = 0;
          }
        break;
       case 3: //wspKalibracji
        if(buttonKrotki == 1) {
          wspKalibracji=wspKalibracji+0.01;
          printValue(wspKalibracji, button);
          buttonKrotki = 0;
        } 
        else if(buttonDlugi == 1) {
          wspKalibracji++;
          printValue(wspKalibracji, button);
         } 
        else if(buttonKrotki == 2) {
          wspKalibracji=wspKalibracji-0.01;
          printValue(wspKalibracji, button);
          buttonKrotki = 0;
        } 
        else if(buttonDlugi == 2) {
          wspKalibracji--; 
          printValue(wspKalibracji, button);
        } else if(button == 3) {
          EEPROM.put(8, wspKalibracji);
          button = 0;
        }
//        switch(button) {
//            case 1:
//              wspKalibracji++;
//              printValue(wspKalibracji, button);
//              break;
//            case 2: 
//              wspKalibracji--;
//              printValue(wspKalibracji, button);
//              break;
//            case 3:     //zapisanie do epromu
//              EEPROM.put(8, wspKalibracji);
//              button = 0;
//          }
        break;
       case 4: //prog 1
        switch(button) {
            case 1:
              if(progI<100)progI++;
              printValue(progI, button);
              lcd.print(" %");
              break;
            case 2: 
              if(progI>0)progI--;
              printValue(progI, button);
              lcd.print(" %");
              break;
            case 3:   //zapisanie do epromu
              EEPROM.put(12, progI);
              button = 0;
          }
        break;
       case 5: //prog 2
        switch(button) {
            case 1:
              if(progI<100)progII++;
              printValue(progII, button);
              lcd.print(" %");
              break;
            case 2: 
              if(progI>0)progII--;
              printValue(progII, button);
              lcd.print(" %");
              break;
            case 3:   //zapisanie do epromu
              EEPROM.put(16, progII);
              button = 0;
          }
        break;
       case 6: //wzorzec
        if(buttonKrotki == 1) {
          wzorzec=wzorzec+0.01;
          printValue(wzorzec, button);
          lcd.print(" KG");
          buttonKrotki = 0;
        } 
        else if(buttonDlugi == 1) {
          wzorzec++; 
          printValue(wzorzec, button);
          lcd.print(" KG");
         } 
        else if(buttonKrotki == 2) {
          if(wzorzec>0.01)wzorzec=wzorzec-0.01;
          printValue(wzorzec, button);
          lcd.print(" KG");  
          buttonKrotki = 0;
        } 
        else if(buttonDlugi == 2) {
          if(wzorzec>1)wzorzec--; 
          printValue(wzorzec, button);
          lcd.print(" KG");
        }
        else if(button == 3) {   //zapisanie do epromu
              EEPROM.put(32, wzorzec);
              button = 0;
          }
        break;
       case 7: //probkowanie
        switch(button) {
            case 1:
              probkowanie++;
              printValue(probkowanie, button);
              break;
            case 2: 
              if(probkowanie>1)probkowanie--;
              printValue(probkowanie, button);
              break;
            case 3:   //zapisanie do epromu
              EEPROM.put(40, probkowanie);
              button = 0;
          }
        break;
       case 8: //licZba miejsc po przecinku
        switch(button) {
            case 1:
              if(liczMiejsc<5)liczMiejsc++;
              printValue(liczMiejsc, button);
              break;
            case 2: 
              if(liczMiejsc>0)liczMiejsc--;
              printValue(liczMiejsc, button);
              break;
            case 3:   //zapisanie do epromu
              EEPROM.put(36, liczMiejsc);
              button = 0;
          }
        break;
       case 9: //predkosc 1
        switch(button) {
            case 1:
              if(predkosc1<6000)predkosc1=predkosc1+100;
              printValue(predkosc1, button);
              lcd.setCursor(0,1);
              lcd.print("6000 = MAX");
              break;
            case 2: 
              if(predkosc1>0)predkosc1=predkosc1-100;
              printValue(predkosc1, button);
              lcd.setCursor(0,1);
              lcd.print("6000 = MAX");
              break;
            case 3:   //zapisanie do epromu
              EEPROM.put(20, predkosc1);
              button = 0;
          }
        break;
       case 10: //predkosc 2
        switch(button) {
            case 1:
              if(predkosc2<6000)predkosc2=predkosc2+100;
              printValue(predkosc2, button);
              lcd.setCursor(0,1);
              lcd.print("6000 = MAX");
              break;
            case 2: 
              if(predkosc2>0)predkosc2=predkosc2-100;
              printValue(predkosc2, button);
              lcd.setCursor(0,1);
              lcd.print("6000 = MAX");
              break;
            case 3:   //zapisanie do epromu
              EEPROM.put(24, predkosc2);
              button = 0;
          }
        break;
       case 11: //predkosc 3
        switch(button) {
            case 1:
              if(predkosc3<6000)predkosc3=predkosc3+100;
              printValue(predkosc3, button);
              lcd.setCursor(0,1);
              lcd.print("6000 = MAX");
              break;
            case 2: 
              if(predkosc3>0)predkosc3=predkosc3-100;
              printValue(predkosc3, button);
              lcd.setCursor(0,1);
              lcd.print("6000 = MAX");
              break;
            case 3:   //zapisanie do epromu
              EEPROM.put(28, predkosc3);
              button = 0;
          }
        break;
       case 12: //stan przekaznik
        switch(button) {
            case 1:
              if(przekaznikStan<1)przekaznikStan++;
              printValue(przekaznikStan, button);
              lcd.setCursor(0,1);
              lcd.print("0=NO, 1=NC"); 
              break;
            case 2: 
              if(przekaznikStan>0)przekaznikStan--;
              printValue(przekaznikStan, button);
              lcd.setCursor(0,1);
              lcd.print("0=NO, 1=NC"); 
              break;
            case 3:   //zapisanie do epromu
              EEPROM.put(44, przekaznikStan);
              if(przekaznikStan==0){
                digitalWrite(wyjsciePrzekaznik, HIGH);
              }else if(przekaznikStan==1){
                digitalWrite(wyjsciePrzekaznik, LOW);
              }
              button = 0;
          }
          break;
        case 13: //autotarowanie
        switch(button) {
            case 1:
              if(autotarowanie<1)autotarowanie++;
              printValue(autotarowanie, button);
              lcd.setCursor(0,1);
              lcd.print("O-off 1-on"); 
              break;
            case 2: 
              if(autotarowanie>0)autotarowanie--;
              printValue(autotarowanie, button);
              lcd.setCursor(0,1);
              lcd.print("O-off 1-on");
              break;
            case 3:   //zapisanie do epromu
              EEPROM.put(48, autotarowanie);
              button = 0;
              break;
          }
          break;
         case 14: //podswietlenie
        switch(button) {
            case 1:
              if(podswietlenie<1)podswietlenie++;
              printValue(podswietlenie, button);
              lcd.setCursor(0,1);
              lcd.print("O-off 1-on"); 
              break;
            case 2: 
              if(podswietlenie>0)podswietlenie--;
              printValue(podswietlenie, button);
              lcd.setCursor(0,1);
              lcd.print("O-off 1-on");
              break;
            case 3:   //zapisanie do epromu
              EEPROM.put(52, podswietlenie);
              button = 0;
              break;
          }
          break;
          case 15: //waga ujemna
          switch(button) {
            case 1:
              if(ujemnaWaga<1)ujemnaWaga++;
              printValue(ujemnaWaga, button);
              lcd.setCursor(0,1);
              lcd.print("1 = dozwolone"); 
              break;
            case 2: 
              if(ujemnaWaga>0)ujemnaWaga--;
              printValue(ujemnaWaga, button);
              lcd.setCursor(0,1);
              lcd.print("1 = dozwolone");
              break;
            case 3:   //zapisanie do epromu
              EEPROM.put(56, ujemnaWaga);
              button = 0;
              break;
          }
          break;
          case 16: //rozmiar tablicy
          switch(button) {
            case 1:
              if(rozmiarBufora<wagaArrayCount+1)rozmiarBufora++;
              printValue(rozmiarBufora, button);
              lcd.setCursor(0,1);
              lcd.print("MIN 1, MAX ");
              lcd.setCursor(12,1);
              lcd.print(wagaArrayCount);
              break;
            case 2: 
              if(rozmiarBufora>1)rozmiarBufora--;
              printValue(rozmiarBufora, button);
              lcd.setCursor(0,1);
              lcd.print("MIN 1, MAX ");
              lcd.setCursor(12,1);
              lcd.print(wagaArrayCount);
              break;
            case 3:   //zapisanie do epromu
              EEPROM.write(60, rozmiarBufora);
              button = 0;
              break;
          }
          break;
          case 17: //filter
          switch(button) {
            case 1:
              if(filter<1)filter+=0.01;
              printValue(filter, button);
              lcd.setCursor(0,1);
              lcd.print("MIN 0, MAX 1");
              break;
            case 2: 
              if(filter>0)filter-=0.01;
              printValue(filter, button);
              lcd.setCursor(0,1);
              lcd.print("MIN 0, MAX 1");
              break;
            case 3:   //zapisanie do epromu
              EEPROM.put(64, filter);
              button = 0;
              break;
          }
     
    }
  }
}

 

  • Lubię! 1
Link do komentarza
Share on other sites

@kellyq Na twoim miejscu rozdzieliłbym program na pliki. Osobno menu, osobno funkcje wagi, osobno funkcje sterowania ssilnikiem. Tego kodu nie jest aż tyle żeby nie mogło się to płynnie wykonywać. Delaye należy zastąpić millisami, wypisywanie na LCD i UART buforować i wysyłać tylko wtedy kiedy jest to potrzebne. Typy float też nie są optymalne ale na tym etapie bym pozostawił. No tę drabinkę if -ów caseów też można lepiej napisać, ale wpierw podział kodu na mniejsze kawałki.

Edytowano przez _LM_
  • Lubię! 1
Link do komentarza
Share on other sites

Patrząc na kod widzę, że nie ma tam ustawionej akceleracji. W przypadku silnika krokowego nie może on "wskoczyć" na wysokie obroty np. 2000 RPM (przykład dla klasycznego silnika od drukarek 3D). Musi się "rozpędzić", bo inaczej będzie cykać (przynajmniej tak było w przypadku moich silników). Oczywiście dla małych wartości da radę, aczkolwiek dla większych już potrzebna jest akceleracja. Dlatego też istnieje biblioteka AccelStepper 😉 

Jeżeli tworzysz obiekt AccelStepper to akceleracja jest ustawiona na "0", co oznacza nieskończoność, czyli tak jakbyś po prostu wysyłał sygnał PWM na pin PULSE. Jeżeli sygnał będzie miał za dużą częstotliwość to silnik nie ruszy. Oddzielną kwestią jest to, czy silnik dostaje odpowiednio dużo prądu ze sterownika 😉 

  • Pomogłeś! 1
Link do komentarza
Share on other sites

Wszystko jak powiedzial kolega @_LM_ ...rowniez tak jak gada kolega @H1M4W4R1 , jesli za wysokie obroty wrzucisz to sie nie zsynchronizuje, choc tu bedzie widac odrazu ze silnik dostal telepawki lub stoi w miejscu...prad tez bardzo wazny jesli chodzi o obroty...

Jak nie chcesz bardzo modyfikowac kodu to timery zostaja...jest tu kilka tematow w ktorych znajdziesz gotowe przyklady ktore bez problemu wykorzystasz...to chyba najkrotsza droga (nie znaczy najlepsza)

Tutaj znajdziesz gotowe przyklady...

Edytowano przez farmaceuta
Link do komentarza
Share on other sites

Mam jednak mieszane uczucia związane z poprawianiem tego kodu, zajmie mi to pewnie w ciul czasu. A jakbym poszedł łatwiejszą drogą i np. użył drugiego mikrokontrolera do sterowania tylko silnikiem z komunikacją po uart? Czy może inny rodzaj komunikacji byłby lepszy w tym wypadku? Liczę na prostotę i łatwość implementacji.

Link do komentarza
Share on other sites

6 minut temu, kellyq napisał:

Mam jednak mieszane uczucia związane z poprawianiem tego kodu, zajmie mi to pewnie w ciul czasu. A jakbym poszedł łatwiejszą drogą i np. użył drugiego mikrokontrolera do sterowania tylko silnikiem

Ale to już wiesz, że problem jest z ilością rzeczy w pętli głównej, a nie z akceleracją o której pisali koledzy?

Uporządkowanie tego kodu i dodanie komentarzy na pewno mu nie zaszkodzi. Zawsze możesz dodać drugi mikrokontroler.

Link do komentarza
Share on other sites

16 minut temu, kellyq napisał:

 Liczę na prostotę i łatwość implementacji.

Nie bede sie upieral ktore rozwiazanie lepsze, ale jesli chcesz powyzszego to ten timer Cie ratuje...w w kodzie praktycznie zero zmian a jedynie dodac pare linijek...ustawiasz timer na jakis staly interval np. 100us co da 10000 przerwan (ewentualnych krokow) a to juz 50 obrotow na sekunde przy silniku 1.8°(nieosiagalne)...piszesz jakas prosta funkcje w ktorej bedziesz obliczal ilosc krokow/predkosc na sekunde, w przerwaniu odliczasz to co ci wyszlo i podajesz krok...nie bylo by to super dokladne (stracona reszta po przecinku) ale skuteczne...tez duzo zalezy od tego jak ten silnik jest poruszany..w sensie z jaka dokladnoscia

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.