kellyq Napisano Listopad 4, 2021 Udostępnij Napisano Listopad 4, 2021 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ć.
H1M4W4R1 Listopad 4, 2021 Udostępnij Listopad 4, 2021 (edytowany) Szklana kula do wróżenia jest droga, jak ją kupisz to za free Ci odpowiem. Jak chcesz oszczędzić wydatku wstaw kod Edytowano Listopad 4, 2021 przez H1M4W4R1 1
farmaceuta Listopad 4, 2021 Udostępnij Listopad 4, 2021 23 minuty temu, kellyq napisał: Używam biblioteki accelstepper ta biblioteka chyba nie dziala w "tle" wiec loop musi zasuwac jak najszybciej, choc moge sie mylic...reszta jak kolega @H1M4W4R1 pisze...
kellyq Listopad 5, 2021 Autor tematu Udostępnij Listopad 5, 2021 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...
pmochocki Listopad 5, 2021 Udostępnij Listopad 5, 2021 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
ethanak Listopad 5, 2021 Udostępnij Listopad 5, 2021 (edytowany) 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 Listopad 5, 2021 przez ethanak 1
farmaceuta Listopad 5, 2021 Udostępnij Listopad 5, 2021 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...
kellyq Listopad 5, 2021 Autor tematu Udostępnij Listopad 5, 2021 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; } } } } 1
_LM_ Listopad 5, 2021 Udostępnij Listopad 5, 2021 (edytowany) @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 Listopad 5, 2021 przez _LM_ 1
H1M4W4R1 Listopad 5, 2021 Udostępnij Listopad 5, 2021 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 1
farmaceuta Listopad 5, 2021 Udostępnij Listopad 5, 2021 (edytowany) 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 Listopad 5, 2021 przez farmaceuta
kellyq Listopad 5, 2021 Autor tematu Udostępnij Listopad 5, 2021 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.
pmochocki Listopad 5, 2021 Udostępnij Listopad 5, 2021 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.
kellyq Listopad 5, 2021 Autor tematu Udostępnij Listopad 5, 2021 próbowałem z akceleracją i nic to nie dało niestety
farmaceuta Listopad 5, 2021 Udostępnij Listopad 5, 2021 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
Pomocna odpowiedź
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ę »