Skocz do zawartości

Serwo pierwsze kroki


PanMajster

Pomocna odpowiedź

(edytowany)

@farmaceuta
Dotarło jedno serwo 80kg kupione w Polsce czekam jeszcze na dwa te z oznaczeniem 160kg.

Wygląda naprawdę solidnie ale testow jeszcze żadnych nie zrobilem po za podłączeniem serwa i przetestowaniem czy działa.

Mam tu kilka pytań.

Zasilam je przez zasilacz impulsowy 12v 8,3A i przetwornice step down. Dokładnie to coś takiego:
https://allegro.pl/oferta/zasilacz-przetwornica-dc-dc-step-down-300w-10678363862.

Po pierwsze serwo w oczekiwaniu mi drga nie wiem jakiś 1 stopień w ta i z powrotem , nieregularnie.

W programie ustawiłem wartość początkową i końcową na 10stopni i 100 stopni zeby serwo nie oczekiwało na skrajnej pozycji. Nic to nie zmienia.

Do tego nawet przy tych drganiach  z ustawionego napiecia 7,8 potrafi na ułamek sekundy spaść do 7,6V

Przy normalnym ruchu serwa roznice juz sa wiekszę z 7,8 spada do nawet 7,14V po czym przy zatrzymaniu potrafi na ułamek sekundy pokazać 8,22V i wraca na ustawione 7,8V.

Tu mam dodatkowe pytanie czy przetwornica która ogranicza napiecie z 12v na 7,8V ogranicza tez natężenie? W przetwornicy mam je rozkręcone na maxa.

Przy serwie przed samym zasilaniem dodałem kondensator elektrolityczny 1000uF i ceramiczny 100nF.. Czy one sa czy nie ma, nie widzę żadnej różnicy. Sam sygnał z arduino idzie przez rezystory 200 OHM.

Masz jakiś pomysł co jeszcze mógł bym zrobić?

 

Jak dojda serwa 160kg to podłączę je bezposrednio pod zasilacz bo sa na 12V. Wydaje mi sie ze słabym punktem układu jest przetwornica ale tego serwa nie mam jak sprawdzić bez niej.

 

EDIT:
Zapomniałem dopisać że serwo drga dopiero jak podłączyłem je do mojego całego układu z rozbudowanym kodem i wszystkimi czujnikami. Jak testowałem ja na oddzielnej płytce stykowej z programem tylko do serwa to nic takiego nie miało miejsca. Mówię o drganiach a nie skokach napięcia 

Edytowano przez PanMajster
Link do komentarza
Share on other sites

(edytowany)
2 godziny temu, PanMajster napisał:

Zasilam je przez zasilacz impulsowy 12v 8,3A i przetwornice step down. Dokładnie to coś takiego:
https://allegro.pl/oferta/zasilacz-przetwornica-dc-dc-step-down-300w-10678363862.

@PanMajster , z ciekawości dla kolegi pytam, co masz napisane na elementach przykręconych do radiatorów?

//

Ok, prawdopodobnie znalazwszy: https://sklep.msalamon.pl/produkt/przetwornica-dc-dc-step-down-300w-xl4016/

XL4016E1 jest dosyć wolna, a spadki napięcia przy obciążeniu są normalne. Poszukałbym dobrej przetwornicy synchronicznej (mają lepszą stabilność pod obciążeniem). Poza tym zasilacz impulsowy to też przetwornica.

A gdyby w przyszłości zainteresowało cię testowanie słabszych zasilaczy i przetwornic DC, to są np. sztuczne obciążenia, które możesz dodatkowo programować (link, link) do zmiennego poboru prądu, itd. Używam DL24P w "rozsądnych" ~100W (180W jest już raczej próbą przypalenia chińskiego mosfetu przy tym chłodzeniu).

Edytowano przez orb777
  • Lubię! 2
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

(edytowany)

@orb777 Ok czyli diagnoza że to prawdopodobnie ta przetwornica chyba jest słuszna. Myślałem że bardziej spadki mogą dotyczyć step-up a step down ma raczej zapas mocy. 

1 godzinę temu, orb777 napisał:

A gdyby w przyszłości zainteresowało cię testowanie słabszych zasilaczy i przetwornic DC, to są np. sztuczne obciążenia,

O super. Myślę że w przyszłości skorzystam , dobrze wiedzieć że coś takiego istnieje 🙂

Edytowano przez PanMajster
Link do komentarza
Share on other sites

10 minut temu, PanMajster napisał:

Ok czyli diagnoza że to prawdopodobnie ta przetwornica chyba jest słuszna.

Chyba tak. Nie mam XL4016E1, ale amatorsko testowałem np. XL4015E1 (180 KHz) i zachowuje się tak jak opisałeś, co dobrze widać na oscyloskopie. Silnik w serwie jest zmiennym obciążeniem, więc taka przetwornica być może "trochę nie nadąża". W synchronicznej przez cały czas masz praktycznie CC i CV, chociaż wspominam tu o małej SY8205 do 5A (taką m.in. sprawdzałem).

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

@PanMajster co do drgania serwa to normalna sprawa, taki urok serw modelarskich, choć to loteria, niektóre drgają inne nie...najczęściej ten problem dotyczy chyba serw cyfrowych z tego co pamiętam...wklej oba kody żeby można było porównać co się zmieniło 

Link do komentarza
Share on other sites

(edytowany)

@farmaceuta No właśnie zmieniło sie bardzo dużo. 

 

Tu kod do sterowania serwa poprzez wpisanie ustawienia pozycji

#include <Servo.h> //Biblioteka serwa 

Servo serwomechanizm;  //Obiekt odwołania do serwa 
int start = 0; // pozycha startowa
String odebranapozycja=""; //dane wprowadzone przez UART
int stopnie;
boolean wpisane=false;

void setup() 
{ 
 serwomechanizm.attach(9);  //Serwomechanizm podłączony do pinu 9 
 Serial.begin(9600); // start łąćża
 serwomechanizm.write(start); // ustawienie serwa w pozycje startowej
} 

void loop() 
{
 if (wpisane==false) { // sprawdzenie bool
 Serial.println("Wpisz polozenie serwaa 0-180");
   wpisane=true;
 }

if(Serial.available() > 0) {  // jeżeli wpisano tekst
odebranapozycja = Serial.readStringUntil('\n'); // odczytuje dane ze string do konca linijki
stopnie=odebranapozycja.toInt(); // wpisujemy liczbe wpisana w string do stopni

 delay(100); // opóźnienie do lepszej obserwacji

if (stopnie<=180 && stopnie>=0){// sprawdzamy czy uzytkownik wpisal liczbe w zakresie 0-180
     delay(100); // opóźnienie do lepszej obserwacji
     serwomechanizm.write(stopnie); //serwo ustawia sie w wpisana pozycje
    // progtam wysyla napis wpisane stopnie + położenie}
 Serial.println(" Wpisane stopnie");
     Serial.println(stopnie);
     delay(100);

}else{ // w innym przypadku
     Serial.println("wpisano złą wartość"); // program pisze do nas wpisano złą wartość
      Serial.println("Prawidłowa wartość 0-180");
     delay(100);
   }
 
}  }

    

tutaj kod do którego podłączyłem serwo

#include <OneWire.h> // biblioteka do czujnika tempaeratury cyfrowego
#include <DallasTemperature.h> // biblioteka do czujnika tempaeratury cyfrowego
#include <LiquidCrystal_I2C.h> // biblioteka do wyswietlacza LCD
#include "HX711.h" // biblioteka do WAGI
#define DATA_PIN 2 // definicja pinu 2 jako DANE
#define CLOCK_PIN 3 // definicja pinu 3 jako CLK
#include <Servo.h> //Biblioteka serwa 

HX711 scale; // Tworzymy obiekt scale typu HX711 dla wagi
LiquidCrystal_I2C lcd1(0x27, 16, 2); // Adres I2C ekranu (0x27), ilość kolumn (16) i wierszy (2)
LiquidCrystal_I2C lcd2(0x26, 16, 2); // Adres I2C ekranu (0x26), ilość kolumn (16) i wierszy (2)
OneWire oneWire(A3); //Podłączenie do A3 (Pin A3 do srodkowej nozki czujnika temperatury)
DallasTemperature sensors(&oneWire); //Przekazanie informacji do biblioteki
DeviceAddress termometrZewnetrzny = { 0x28, 0x77, 0x21, 0x12, 0x0, 0x0, 0x0, 0x9 }; // adres czujnika
DeviceAddress termometrZewnetrzny2 = { 0x28, 0x42, 0xA0, 0x10, 0x0, 0x0, 0x0, 0xE }; // adres czujnika 2
Servo serwomechanizm;  //Obiekt odwołania do serwa 

// deklaracje dla wentylatorów
const int wentylator = 7; // Pin sterujący MOSFET-em nr 1 i zarazem wentylatorem nr 1
const int wentylator2 = 8; // Pin sterujący MOSFET-em nr 2 i zarazem wentylatorem nr 2
const int temp_wlacz = 25; // Temperatura włączenia wentylatora nr 1
const int temp_wylacz = 22; // Temperatura wyłączenia wentylatora nr 1 (histereza by wentylator nie włączał i wyłączał sie bez przerwy)
const int temp_wlacz2 = 25; // Temperatura włączenia wentylatora 2
const int temp_wylacz2 = 22; // Temperatura wyłączenia wentylatora 2 (histereza by wentylator nie włączał i wyłączał sie bez przerwy)
// deklaracje dla WAGI
const int iloscOdczytow = 5; // Ilość odczytów WAGI do uśrednienia w wadze
const float wspolczynnikSkali  = -0.00000862; // <--- Wklej tutaj *obliczoną* wartość! ( roznica odczytu waga z obciazeniem - waga pusta) ( waga obciazenia podzielna przez wynik)
long wartoscTara = 85058; // <--- Wklej tutaj *obliczoną* wartość!( odczyt wagi pustej surowe dane)
//WAGA opóźnienia w millis
unsigned long ostatniOdczytCzasu = 0; // Zmienna do przechowywania czasu ostatniego odczytu
const long interwal = 50; // Interwał między odczytami (100ms) WAGI
const int przyciskTarowania = 4; // Pin 4 jako przycisk do tarowania wagi
//Zmienne millis w pętli loop
unsigned long poprzedniCzasPetliLoop = 0;
const long interwalPetliLoop = 100; // Interwał pętli głównej (200ms)
int start = 20; // pozycha startowa serwa
int stopnie = 120; // ruch serwa w prawo
int stopnie2 = 20; // ruch serwa w lewo
const int GUZIKSTART = 10; // Pin 10 jako przycisk do startu serw
float zmiennaWaga; // Deklaracja zmiennej zmiennaWaga ( aktualna waga)
unsigned long poprzedniCzasOdczytuTemperatury = 0; // zmienna do przechowywania czasu odczytu temperatury
const long interwalOdczytuTemperatury = 1500; // Odczyt co 1,5 sekundy

void setup(void) {
  Serial.begin(9600); // start połączenia z komputerem
  pinMode(przyciskTarowania, INPUT_PULLUP); // Ustawiamy pin jako wejście z wbudowanym rezystorem pull-up
  sensors.begin(); //Inicjalizacja czujnikow
  Wire.begin(); // Inicjalizacja magistrali I2C ( CZY TO POTRZEBNE??)
  scale.begin(DATA_PIN, CLOCK_PIN); //Inicjalizujemy HX711
  pinMode(wentylator, OUTPUT); // Wentylator (pin 7) jako wyjscie
  pinMode(wentylator2, OUTPUT); // Wentylator2 (pin 8) jako wyjscie
  digitalWrite(wentylator, LOW); // Początkowo wentylator wyłączony
  digitalWrite(wentylator2, LOW); // Początkowo wentylator wyłączony
  lcd1.init(); // Inicjalizacja ekranu 1
  lcd1.backlight(); // Włączenie podświetlenia ekranu 1
  lcd2.init(); // Inicjalizacja ekranu 2
  lcd2.backlight(); // Włączenie podświetlenia ekranu 2
  serwomechanizm.attach(9);  //Serwomechanizm podłączony do pinu 9 
  serwomechanizm.write(start); // ustawienie serwa w pozycje startowej
  pinMode(GUZIKSTART, INPUT_PULLUP); // Ustawiamy pin START jako guzik
  tarujWage(); // Tarowanie wagi po uruchomieniu
}

void loop(void) {
// Debouncing przycisku
  static unsigned long poprzedniCzasPrzycisku = 0; //zapisanie czasu poprzedniego uzycia przycisku
  const unsigned long interwalDebouncingu = 50; // czas miedzy kolejnymi nacisnieciami
  unsigned long aktualnyCzas = millis(); 

  if (millis() - poprzedniCzasPrzycisku > interwalDebouncingu) { // sprawdzenie odstepu czasu przy nacisnieciu przycisku
    if (digitalRead(przyciskTarowania) == LOW) { //jezeli guzik wcisniety to:
      tarujWage(); //Wywołujemy funkcję tarującą wagę
      poprzedniCzasPrzycisku = millis(); // zmieniamy milis dla nastepnej petli
    }
  }
    if (aktualnyCzas - poprzedniCzasPetliLoop >= interwalPetliLoop) {  // Sprawdzamy, czy minął interwał dla pętli głównej
    poprzedniCzasPetliLoop = aktualnyCzas; // Aktualizujemy aktualny czas dla nastepnej pętli

   if (millis() - poprzedniCzasOdczytuTemperatury >= interwalOdczytuTemperatury) {
  poprzedniCzasOdczytuTemperatury = millis();
  termometr(); // Wywołanie funkcji  od pomiarów temperatury bez argumentu
    }
  waga1(); // Wywołanie funkcji od wagi nr 1 bez argumentu
  STARTNABIJANIA(); // wywołanie funkcji start nabijania (serwa)
}
}

// FUNKCJA OBSLUGUJACA WAGE NR 1
void waga1() {
    
     
    if (scale.is_ready()) { // Sprawdzamy, czy HX711 jest gotowy do odczytu
    unsigned long aktualnyOdczytCzasu = millis(); // Pobieramy aktualny czas
     if (aktualnyOdczytCzasu - ostatniOdczytCzasu >= interwal) { // jeżeli minął interwał lub wiecej to:
      ostatniOdczytCzasu = aktualnyOdczytCzasu; // Aktualizujemy czas ostatniego odczytu dla nastepnej pętli
    long sum = 0; // Suma odczytów.
    for (int i = 0; i < iloscOdczytow; i++) { // odczytujemy odczyty az do wartości iloscOdczytow czyli 10.
      sum += scale.read(); // dodaj do sum odczyt z HX711 i zapisz w SUM
    }
    long srednia = sum / iloscOdczytow; //Obliczamy średnią.
    zmiennaWaga = (srednia - wartoscTara) * wspolczynnikSkali; //równanie kalibracji ( do uzupełnienia na poczatku kodu)
   
    // Narazie mam jedna wage wiec waga jest wyswietlana 2 raz ( naszykowane pod podpiecie drugiej wagi)
  lcd2.setCursor(0, 0); // Ustawienie kursora na początku pierwszego wiersza
  lcd2.print("WAGA1 "); //wyswietlenie tekstu
  lcd2.print(zmiennaWaga); // Wyświetlenie aktualnej wagi z tensometru
  lcd2.setCursor(0, 1); // Ustawienie kursora na początku pierwszego wiersza
  lcd2.print("WAGA2 "); //wyswietlenie tekstu
  lcd2.print(zmiennaWaga); // Wyświetlenie aktualnej wagi z tensometru

//Wyświetlamy wagę w porcie szeregowym
    Serial.print("Waga: ");
    Serial.print(zmiennaWaga);
    Serial.println(" kg");
  } else {
    Serial.println("HX711 kalibruje.."); //Komunikat, gdy HX711 nie jest gotowy.
  }
}}

// FUNKCJA TAROWANIA WAGI
void tarujWage() {
  wartoscTara = scale.read(); // Odczytujemy aktualny odczyt z wagi i zapisujemy jako waga tara
  Serial.print("Waga została wytarowana. Nowa waga tara: "); // Wyświetlenie tekstu
  Serial.println(wartoscTara);
}

// FUNKCJA TERMOMETR nr 1 i nr 2
void termometr() { // Funkcja obsługująca włączanie i wyłączenie wentylatora po zczytaniu temperatury
  sensors.requestTemperatures(); //Pobranie temperatury czujnika
  float temp = sensors.getTempC(termometrZewnetrzny); // Odczyt temperatury wewnątrz funkcji
   float temp2 = sensors.getTempC(termometrZewnetrzny2); // Odczyt temperatury wewnątrz funkcji
// wyswietlanie temperatury na LCD
  lcd1.setCursor(0, 0); // Ustawienie kursora na początku pierwszego wiersza
  lcd1.print("Temp1 ");// Wyświetlenie tekstu
  lcd1.print(sensors.getTempC(termometrZewnetrzny)); // Wyświetlenie temperatury z termometrZewnetrzny
  lcd1.setCursor(0, 1); // Ustawienie kursora na początku pierwszego wiersza
  lcd1.print("Temp2 ");// Wyświetlenie tekstu
  lcd1.print(sensors.getTempC(termometrZewnetrzny2)); // Wyświetlenie temperatury z termometrZewnetrzny2
// wyswietlanie temperatury w porcie szeregowym
  Serial.print("Aktualna temperatura: "); // Piszemy do portu szeregowego "Aktualna temperatura: "
  Serial.println(sensors.getTempC(termometrZewnetrzny)); // Wyświetlenie temperatury w porcie szeregowym pobranej z czujnika
  Serial.print("Aktualna temperatura2: "); // Piszemy do portu szeregowego "Aktualna temperatura: "
  Serial.println(sensors.getTempC(termometrZewnetrzny2)); // Wyświetlenie temperatury w porcie szeregowym pobranej z czujnika

  if (temp >= temp_wlacz) { // jeżeli temperatura jest wieksza od ustawionej to:
    digitalWrite(wentylator, HIGH); //Włącz wentylator
  } else if (temp <= temp_wylacz) { // jeżeli temperatura jest mniejsza od ustawionej to: ( ustawić Histereze)
    digitalWrite(wentylator, LOW); //Wyłącz wentylator
  }
  if (temp2 >= temp_wlacz2) { // jeżeli temperatura jest wieksza od ustawionej to:
    digitalWrite(wentylator2, HIGH); //Włącz wentylator2
  } else if (temp2 <= temp_wylacz2) { // jeżeli temperatura jest mniejsza od ustawionej to: ( ustawić Histereze)
    digitalWrite(wentylator2, LOW); //Wyłącz wentylator2
  }}
  
  void STARTNABIJANIA() { // Funkcja obsługująca uruchomienie SERW
if (digitalRead(GUZIKSTART) == LOW && (zmiennaWaga <= 2.0)) { //jezeli guzik start jest wcisniety i jednoczesnie waga pokazuje ponizej 2kg
    serwomechanizm.write(stopnie); // serwo ustawia sie w pozycji 1
} else if (zmiennaWaga >= 2.0) { //jezeli przycisk nie jest wcisniety a waga jest powyżej 2kg
    serwomechanizm.write(stopnie2); // serwo ustawia sie w pozycji 2
} 
  }

 

Edytowano przez PanMajster
Link do komentarza
Share on other sites

Dla ciekawych . Udało mi sie usunąć drgania serw. Poniżej wrzucam aktualny kod. Jest jeszcze parę poprawek do wprowadzenia ale 90% zrobione.

#include <OneWire.h> // biblioteka do czujnika tempaeratury cyfrowego
#include <DallasTemperature.h> // biblioteka do czujnika tempaeratury cyfrowego
#include <LiquidCrystal_I2C.h> // biblioteka do wyswietlacza LCD
#include "HX711.h" // biblioteka do WAGI
#include <Servo.h> //Biblioteka serwa
#include <Wire.h>

#define WERSJA_TESTOWA 0 //(gdy 0 nie wysyla na port szeregow)
#define STOP 19 //  definicja pinu STOP dla przerwania
#define DATA_PIN 2 // definicja pinu 2 jako DANE (WAGA)
#define CLOCK_PIN 3 // definicja pinu 3 jako CLK (WAGA)
#define DATA_PIN2 50 // definicja pinu 50 jako DANE (WAGA2)
#define CLOCK_PIN2 52 // definicja pinu 52 jako CLK (WAGA2)

HX711 scale; // Tworzymy obiekt scale typu HX711 dla wagi
HX711 scale2; // Tworzymy obiekt scale typu HX711 dla wagi2
LiquidCrystal_I2C lcd1(0x27, 16, 2); // Adres I2C ekranu (0x27), ilość kolumn (16) i wierszy (2)
LiquidCrystal_I2C lcd2(0x26, 16, 2); // Adres I2C ekranu2 (0x26), ilość kolumn (16) i wierszy (2)
OneWire oneWire(A3); //Podłączenie do A3 (Pin A3 do srodkowej nozki czujnika temperatury)
DallasTemperature sensors(&oneWire); //Przekazanie informacji do biblioteki
DeviceAddress termometrZewnetrzny = { 0x28, 0x77, 0x21, 0x12, 0x0, 0x0, 0x0, 0x9 }; // adres czujnika
DeviceAddress termometrZewnetrzny2 = { 0x28, 0x42, 0xA0, 0x10, 0x0, 0x0, 0x0, 0xE }; // adres czujnika 2
Servo serwomechanizm;  //Obiekt odwołania do serwa
Servo serwomechanizm2;  //Obiekt odwołania do serwa 2
Servo serwomechanizm3;  //Obiekt odwołania do serwa 3
Servo serwomechanizm4;  //Obiekt odwołania do serwa 4


// deklaracje dla wentylatorów
const int wentylator = 7; // Pin sterujący MOSFET-em nr 1 i zarazem wentylatorem nr 1
const int wentylator2 = 6; // Pin sterujący MOSFET-em nr 2 i zarazem wentylatorem nr 2

//deklaracje dla czujników temperatury
float temp_wlacz = 26.0; // Temperatura włączenia wentylatora nr 1
float temp_wylacz = 22.0; // Temperatura wyłączenia wentylatora nr 1 (histereza by wentylator nie włączał i wyłączał sie bez przerwy)
float temp_wlacz2 = 26.0; // Temperatura włączenia wentylatora 2
float temp_wylacz2 = 22.0; // Temperatura wyłączenia wentylatora 2 (histereza by wentylator nie włączał i wyłączał sie bez przerwy)
float temp1 = 0.0; // Początkowa wartość temperatury
float temp2 = 0.0; // Początkowa wartość temperatury2
float ostatniaPoprawnaTemp1 = 0.0; // Ostatnia poprawna wartość temp1
float ostatniaPoprawnaTemp2 = 0.0; // Ostatnia poprawna wartość temp2
unsigned long poprzedniCzasOdczytuTemperatury = 0; // zmienna do przechowywania czasu odczytu temperatury
const long interwalOdczytuTemperatury = 1500; // Odczyt co 1,5 sekundy

// deklaracje dla WAGI
const int iloscOdczytow = 3; // Ilość odczytów WAGI do uśrednienia w wadze
const float wspolczynnikSkali  = -0.00000862; // <--- Wklej tutaj *obliczoną* wartość! ( roznica odczytu waga z obciazeniem - waga pusta) ( waga obciazenia podzielna przez wynik)
const float wspolczynnikSkali2  = -0.00000862; // <--- Wklej tutaj *obliczoną* wartość! ( roznica odczytu waga z obciazeniem - waga pusta) ( waga obciazenia podzielna przez wynik)
long wartoscTara = 85058; // <--- Wklej tutaj *obliczoną* wartość!( odczyt wagi pustej surowe dane)
long wartoscTara2 = 85058; // <--- Wklej tutaj *obliczoną* wartość!( odczyt wagi pustej surowe dane)
const int przyciskTarowania = 4; // Pin 4 jako przycisk do tarowania wagi
const int przyciskTarowania2 = 48; // Pin 48 jako przycisk do tarowania wagi2
float zmiennaWaga; // Deklaracja zmiennej zmiennaWaga ( aktualna waga)
float zmiennaWaga2; // Deklaracja zmiennej zmiennaWaga2 ( aktualna waga)
float granicaWagi = 2.0; // Początkowa wartość graniczna wagi
const int PRZYCISK_ZWIEKSZ = 11; // Pin dla przycisku zwiększającego wartość graniczna wagi
const int PRZYCISK_ZMNIEJSZ = 12; // Pin dla przycisku zmniejszającego wartość graniczna wagi

// WAGA opóźnienia w millis
unsigned long ostatniOdczytCzasu1 = 0; // Zmienna do przechowywania czasu ostatniego odczytu dla wagi 1
unsigned long ostatniOdczytCzasu2 = 0; // Zmienna do przechowywania czasu ostatniego odczytu dla wagi 2
const long interwal = 100; // Interwał między odczytami (100ms) WAGI

//Opóźnienia millis w pętli loop
unsigned long poprzedniCzasPetliLoop = 0;
const long interwalPetliLoop = 60; // Interwał pętli głównej (60ms)

// Servo
int start = 0; // pozycha startowa serwa
int stopnie110 = 110; // ruch serwa w prawo o 90 st
int stopnie20 = 20; // ruch serwa w lewo o 90 st
int stopnie0 = 0; // pozycja startowa malego serwa
int stopnie180 = 173; // pozycja koncowa malego serwa
const int GUZIKSTART1 = 10; // Pin 10 jako przycisk do startu serw 1
const int GUZIKSTOP1 = 53; // Pin 53 jako przycisk do stopu serw 1
const int GUZIKSTART2 = 39; // Pin 43 jako przycisk do startu serw 2
const int GUZIKSTOP2 = 42; // Pin 42 jako przycisk do stopu serw 2
int pozycjaSerwo1 = start; //pozycja startowa serwa 1
int pozycjaSerwo2 = start; //pozycja startowa serwa 2
int pozycjaSerwo3 = start; //pozycja startowa serwa 3
int pozycjaSerwo4 = start; //pozycja startowa serwa 4
unsigned long czasOstatniegoRuchu1 = 0; // Czas ostatniego ruchu Serwo1
unsigned long czasOstatniegoRuchu2 = 0; // Czas ostatniego ruchu Serwo2
unsigned long czasOstatniegoRuchu3 = 0; // Czas ostatniego ruchu Serwo3
unsigned long czasOstatniegoRuchu4 = 0; // Czas ostatniego ruchu Serwo4
bool serwo1Aktywne = false; // Czy Serwo1 czeka na ruch
bool serwo2Aktywne = false; // Czy Serwo2 czeka na ruch
bool serwo3Aktywne = false; // Czy Serwo3 czeka na ruch
bool serwo4Aktywne = false; // Czy Serwo4 czeka na ruch
const unsigned long czasRuchu = 600; // Czas na ruch w ms (600 ms)

// Debouncing przycisku tarowania
static unsigned long poprzedniCzasPrzycisku1 = 0; //zapisanie czasu poprzedniego uzycia przycisku1
static unsigned long poprzedniCzasPrzycisku2 = 0; //zapisanie czasu poprzedniego uzycia przycisku2
const unsigned long interwalDebouncingu = 50; // czas miedzy kolejnymi nacisnieciami (tara i wartosc graniczna)
unsigned long aktualnyCzas;

// Deklaracje funkcji przed ich użyciem
void wyswietlDaneNaLCD(float temp1, float temp2, float waga1, float waga2);
void tarujWage(bool autoTarowanie = false, unsigned long aktualnyCzas = 0);
void tarujWage2(bool autoTarowanie = false, unsigned long aktualnyCzas = 0);
void waga1(unsigned long aktualnyCzas);
void waga2(unsigned long aktualnyCzas);
void zmienGraniceWagi(unsigned long aktualnyCzas);
void termometr(unsigned long aktualnyCzas);
void sterujWentylatorem(float temp1, float temp2);
void STARTNABIJANIA1(unsigned long aktualnyCzas);
void STARTNABIJANIA2(unsigned long aktualnyCzas);
void STOPNABIJANIA1(unsigned long aktualnyCzas);
void STOPNABIJANIA2(unsigned long aktualnyCzas);
void STOP_przerwanie();
void debugPrint(unsigned long aktualnyCzas);
void sterujSerwem(Servo& serwo, int pin, int& pozycja, unsigned long& czasRuchu, bool& aktywne, int nowaPozycja, unsigned long aktualnyCzas);


// ZMIENNA WYSWIETLACZY LCD
void wyswietlDaneNaLCD(float temp1, float temp2, float waga1, float waga2) {
  // Ekran 1 (temperatury)
// wyswietlanie temperatury na LCD
  lcd1.setCursor(0, 0); // Ustawienie kursora na początku pierwszego wiersza
  if (temp1 == -127.0 || temp1 == 85.0) { //sprawdzanie poparawnosci odczytu
    lcd1.print("Temp1 ERROR "); // Wyświetlenie tekstu błędu
  } else {
    lcd1.print("Temp1 "); // Wyświetlenie tekstu
    lcd1.print(temp1, 1); // Wyświetlenie temperatury z termometrZewnetrzny
    lcd1.print("  "); // ususwanie za dlugiego tekstu
  }
lcd1.setCursor(0, 1); // Ustawienie kursora na początku pierwszego wiersza
  if (temp2 == -127.0 || temp2 == 85.0) { //sprawdzanie poparawnosci odczytu
    lcd1.print("Temp2 ERROR ");
  } else {
    lcd1.print("Temp2 "); // Wyświetlenie tekstu
    lcd1.print(temp2, 1); // Wyświetlenie temperatury z termometrZewnetrzny2
    lcd1.print("  "); // ususwanie za dlugiego tekstu
  }
  // LCD od wagi wystwietlanie z dwóch czujników + CEL

  lcd2.setCursor(0, 0); //Ustawienie kursora na początku pierwszego wiersza
  lcd2.print("L "); //wyswietlenie tekstu
  lcd2.print(waga1, 2); //Wyświetlenie aktualnej wagi z tensometru
  lcd2.print("  "); //ususwanie za dlugiego tekstu
  lcd2.setCursor(9, 0); //Ustawienie kursora na początku pierwszego wiersza
  lcd2.print("P "); //wyswietlenie tekstu
  lcd2.print(waga2, 2); //Wyświetlenie aktualnej wagi z tensometru
  lcd2.print("  "); //ususwanie za dlugiego tekstu
  lcd2.setCursor(0, 1);
  lcd2.print("CEL: "); // Wyświetl granicę wagi
  lcd2.print(granicaWagi, 2);
  lcd2.print(" kg ");
}


void setup(void) {
  Serial.begin(9600); // start połączenia z komputerem
  pinMode(przyciskTarowania, INPUT_PULLUP); // Ustawiamy pin jako wejście z wbudowanym rezystorem pull-up
  pinMode(przyciskTarowania2, INPUT_PULLUP); // Ustawiamy pin jako wejście z wbudowanym rezystorem pull-up
  pinMode(PRZYCISK_ZWIEKSZ, INPUT_PULLUP); // Przycisk zwiększający wartosc graniczną wagi
  pinMode(PRZYCISK_ZMNIEJSZ, INPUT_PULLUP); // Przycisk zmniejszający wartosc graniczną wagi
  sensors.begin(); //Inicjalizacja czujnikow
  Wire.begin();
  scale.begin(DATA_PIN, CLOCK_PIN); //Inicjalizujemy HX711
  scale2.begin(DATA_PIN2, CLOCK_PIN2); //Inicjalizujemy drugi HX711
  delay(1000); //czas na stabilizację HX711
  tarujWage(true);  // Automatyczne Tarowanie wagi 1
  tarujWage2(true); // Automatyczne Tarowanie wagi 2
  pinMode(wentylator, OUTPUT); // Wentylator (pin 7) jako wyjscie
  pinMode(wentylator2, OUTPUT); // Wentylator2 (pin 6) jako wyjscie
  digitalWrite(wentylator, LOW); // Początkowo wentylator wyłączony
  digitalWrite(wentylator2, LOW); // Początkowo wentylator wyłączony
  lcd1.init(); // Inicjalizacja ekranu 1
  lcd1.backlight(); // Włączenie podświetlenia ekranu 1
  lcd2.init(); // Inicjalizacja ekranu 2
  lcd2.backlight(); // Włączenie podświetlenia ekranu 2
  pinMode(GUZIKSTART1, INPUT_PULLUP); // Ustawiamy pin START jako guzik
  pinMode(GUZIKSTOP1, INPUT_PULLUP); // Ustawiamy pin STOP jako guzik
  pinMode(GUZIKSTART2, INPUT_PULLUP); // Ustawiamy pin START2 jako guzik
  pinMode(GUZIKSTOP2, INPUT_PULLUP); // Ustawiamy pin STOP2 jako guzik
  pinMode(STOP, INPUT_PULLUP); // Dodano konfigurację pinu STOP
  serwomechanizm.attach(9); //Podłączenie serwa pod pin 9
  serwomechanizm.write(start); // ustawienie pozycji startowej
  serwomechanizm.detach(); // odłączenie serwa
  serwomechanizm2.attach(30); //Podłączenie serwa pod pin 30
  serwomechanizm2.write(start); // ustawienie pozycji startowej
  serwomechanizm2.detach(); // odłączenie serwa
  serwomechanizm3.attach(31); //Podłączenie serwa pod pin 31
  serwomechanizm3.write(start); // ustawienie pozycji startowej
  serwomechanizm3.detach(); // odłączenie serwa
  serwomechanizm4.attach(33); //Podłączenie serwa pod pin 33
  serwomechanizm4.write(start); // ustawienie pozycji startowej
  serwomechanizm4.detach(); // odłączenie serwa
  attachInterrupt(digitalPinToInterrupt(STOP), STOP_przerwanie, FALLING); // Przerwanie reagujące na zbocze spadające
}

void loop(void) {
    unsigned long aktualnyCzas = millis(); // Aktualizacja w każdej literacji pętli
    if (aktualnyCzas - poprzedniCzasPetliLoop >= interwalPetliLoop) {  // Sprawdzamy, czy minął interwał dla pętli głównej
    poprzedniCzasPetliLoop = aktualnyCzas; // Aktualizujemy aktualny czas dla nastepnej pętli

   if (aktualnyCzas - poprzedniCzasOdczytuTemperatury >= interwalOdczytuTemperatury) {
  poprzedniCzasOdczytuTemperatury = aktualnyCzas;
  termometr(aktualnyCzas); // Wywołanie funkcji  od pomiarów temperatury
    }
  tarujWage(false, aktualnyCzas); //Wywołujemy funkcję tarującą wagę
  tarujWage2(false, aktualnyCzas); //Wywołujemy funkcję tarującą wagę2
  waga1(aktualnyCzas); // Wywołanie funkcji od wagi nr 1 bez argumentu
  waga2(aktualnyCzas); // Wywołanie funkcji od wagi nr 2 bez argumentu
  STARTNABIJANIA1(aktualnyCzas); // wywołanie funkcji start nabijania (serwa)
  STARTNABIJANIA2(aktualnyCzas); // wywołanie funkcji start nabijania (serwa2)
  zmienGraniceWagi(aktualnyCzas); // Funkcja do zmiany wagi
  wyswietlDaneNaLCD(temp1, temp2, zmiennaWaga, zmiennaWaga2); // wyswietlanie danych na LCD
  STOPNABIJANIA1(aktualnyCzas); // wywołanie funkcji stop nabijania (serwa)
  STOPNABIJANIA2(aktualnyCzas); // wywołanie funkcji stop nabijania (serwa2)
  debugPrint(aktualnyCzas); // wywołanie funkcji testowej
 
 // Wyłączanie serw po upływie czasu ruchu
    if (serwo1Aktywne && (aktualnyCzas - czasOstatniegoRuchu1 >= czasRuchu)) {
      serwomechanizm.detach();
      serwo1Aktywne = false;
    }
    if (serwo2Aktywne && (aktualnyCzas - czasOstatniegoRuchu2 >= czasRuchu)) {
      serwomechanizm2.detach();
      serwo2Aktywne = false;
    }
    if (serwo3Aktywne && (aktualnyCzas - czasOstatniegoRuchu3 >= czasRuchu)) {
      serwomechanizm3.detach();
      serwo3Aktywne = false;
    }
    if (serwo4Aktywne && (aktualnyCzas - czasOstatniegoRuchu4 >= czasRuchu)) {
      serwomechanizm4.detach();
      serwo4Aktywne = false;
    }
  }
}


// FUNKCJA OBSLUGUJACA WAGE NR 1
void waga1(unsigned long aktualnyCzas) {
    if (scale.is_ready()) { // Sprawdzamy, czy HX711 jest gotowy do odczytu

     if (aktualnyCzas - ostatniOdczytCzasu1 >= interwal) { // jeżeli minął interwał lub wiecej to:
      ostatniOdczytCzasu1 = aktualnyCzas; // Aktualizujemy czas ostatniego odczytu dla nastepnej pętli
    long sum = 0; // Suma odczytów.
    for (int i = 0; i < iloscOdczytow; i++) { // odczytujemy odczyty az do wartości iloscOdczytow.
      sum += scale.read(); // dodaj do sum odczyt z HX711 i zapisz w SUM
    }
    long srednia = sum / iloscOdczytow; //Obliczamy średnią.
    zmiennaWaga = (srednia - wartoscTara) * wspolczynnikSkali; //równanie kalibracji ( do uzupełnienia na poczatku kodu)

  }}}

   // FUNKCJA OBSLUGUJACA WAGE NR 2
void waga2(unsigned long aktualnyCzas) {
    if (scale2.is_ready()) { // Sprawdzamy, czy HX711 jest gotowy do odczytu
     if (aktualnyCzas - ostatniOdczytCzasu2 >= interwal) { // jeżeli minął interwał lub wiecej to:
      ostatniOdczytCzasu2 = aktualnyCzas; // Aktualizujemy czas ostatniego odczytu dla nastepnej pętli
    long sum = 0; // Suma odczytów.
    for (int i = 0; i < iloscOdczytow; i++) { // odczytujemy odczyty az do wartości iloscOdczytow
      sum += scale2.read(); // dodaj do sum odczyt z HX711 i zapisz w SUM
    }
    long srednia = sum / iloscOdczytow; //Obliczamy średnią.
    zmiennaWaga2 = (srednia - wartoscTara2) * wspolczynnikSkali2; //równanie kalibracji ( do uzupełnienia na poczatku kodu)
  }}}

void zmienGraniceWagi(unsigned long aktualnyCzas) {
  static unsigned long poprzedniCzasZwieksz = 0; // Czas ostatniego naciśnięcia przycisku zwiększającego
  static unsigned long poprzedniCzasZmniejsz = 0; // Czas ostatniego naciśnięcia przycisku zmniejszającego
 

  // Zwiększanie wartości granicy wagi
  if (digitalRead(PRZYCISK_ZWIEKSZ) == LOW && (aktualnyCzas - poprzedniCzasZwieksz > interwalDebouncingu)) {
    granicaWagi += 0.02; // Zwiększ o 0.02 kg
    poprzedniCzasZwieksz = aktualnyCzas;
 }
  // Zmniejszanie wartości granicy wagi
  if (digitalRead(PRZYCISK_ZMNIEJSZ) == LOW && (aktualnyCzas - poprzedniCzasZmniejsz > interwalDebouncingu)) {
    granicaWagi -= 0.02; // Zmniejsz o 0.02 kg
    poprzedniCzasZmniejsz = aktualnyCzas;
}}

// FUNKCJA TAROWANIA WAGI
void tarujWage(bool autoTarowanie, unsigned long aktualnyCzas = 0) {
 if (autoTarowanie || (aktualnyCzas - poprzedniCzasPrzycisku1 > interwalDebouncingu && digitalRead(przyciskTarowania) == LOW)) { // sprawdzenie odstepu czasu przy nacisnieciu przycisku
     wartoscTara = scale.read(); // Odczytujemy aktualny odczyt z wagi i zapisujemy jako waga tara
     if (!autoTarowanie) {
    poprzedniCzasPrzycisku1 = aktualnyCzas; // zmieniamy milis dla nastepnej petli tylko przy recznym tarowaniu
}}}
// FUNKCJA TAROWANIA WAGI2
void tarujWage2(bool autoTarowanie, unsigned long aktualnyCzas = 0) {
if (autoTarowanie || (aktualnyCzas - poprzedniCzasPrzycisku2 > interwalDebouncingu && digitalRead(przyciskTarowania2) == LOW)) {
    wartoscTara2 = scale2.read(); // sprawdzenie odstepu czasu przy nacisnieciu przycisku
     if (!autoTarowanie) {
    poprzedniCzasPrzycisku2 = aktualnyCzas; // zmieniamy milis dla nastepnej petli
}}}

// FUNKCJA TERMOMETR nr 1 i nr 2
void termometr(unsigned long aktualnyCzas) { // Funkcja obsługująca włączanie i wyłączenie wentylatora po zczytaniu temperatury
  sensors.requestTemperatures(); //Pobranie temperatury czujnika
  // czujnik temperatury nr 1
  float nowaTemp1 = sensors.getTempC(termometrZewnetrzny);
  if (nowaTemp1 != -127.0 && nowaTemp1 != 85.0) { // Sprawdzamy, czy odczyt nie jest błędny
    temp1 = nowaTemp1; // Aktualizujemy temp1 tylko jeśli odczyt jest poprawny
    ostatniaPoprawnaTemp1 = temp1; // Zapisujemy poprawną wartość
  } else {
    temp1 = ostatniaPoprawnaTemp1; // W przypadku błędu używamy ostatniej poprawnej wartości
  }
  // czujnik temperatury nr 2
  float nowaTemp2 = sensors.getTempC(termometrZewnetrzny2);
  if (nowaTemp2 != -127.0 && nowaTemp2 != 85.0) { // Sprawdzamy, czy odczyt nie jest błędny
    temp2 = nowaTemp2; // Aktualizujemy temp2 tylko jeśli odczyt jest poprawny
    ostatniaPoprawnaTemp2 = temp2; // Zapisujemy poprawną wartość
  } else {
    temp2 = ostatniaPoprawnaTemp2; // W przypadku błędu używamy ostatniej poprawnej wartości
  }
  // Wywołanie funkcji sterującej wentylatorami
  sterujWentylatorem(temp1, temp2);
   
}

// FUNKCJA WENTYLATOR nr 1 i nr 2
void sterujWentylatorem(float temp1, float temp2) {
  if (temp1 >= temp_wlacz) { // jeżeli temperatura jest wieksza od ustawionej to:
    digitalWrite(wentylator, HIGH); //Włącz wentylator
  } else if (temp1 <= temp_wylacz) { // jeżeli temperatura jest mniejsza od ustawionej to: ( ustawić Histereze)
    digitalWrite(wentylator, LOW); //Wyłącz wentylator
  }
  if (temp2 >= temp_wlacz2) { // jeżeli temperatura jest wieksza od ustawionej to:
    digitalWrite(wentylator2, HIGH); //Włącz wentylator2
  } else if (temp2 <= temp_wylacz2) { // jeżeli temperatura jest mniejsza od ustawionej to: ( ustawić Histereze)
    digitalWrite(wentylator2, LOW); //Wyłącz wentylator2
  }}
 
void STARTNABIJANIA1(unsigned long aktualnyCzas) { // funkcja uruchamiajaca serwo 1 i 2
  int nowaPozycja1, nowaPozycja2;
  if (digitalRead(GUZIKSTART1) == LOW && (zmiennaWaga <= granicaWagi)) { //jezeli guzik jest wcisniety a waga jest ponizej wyznaczonej w granica wagi
    nowaPozycja1 = stopnie180; // 173°
    nowaPozycja2 = stopnie110; // 110°
  } else if (zmiennaWaga >= granicaWagi) {
    nowaPozycja1 = stopnie0;   // 0°
    nowaPozycja2 = stopnie20;  // 20°
  } else {
    return; // Brak zmiany
  }
 
  sterujSerwem(serwomechanizm, 9, pozycjaSerwo1, czasOstatniegoRuchu1, serwo1Aktywne, nowaPozycja1, aktualnyCzas);
sterujSerwem(serwomechanizm2, 30, pozycjaSerwo2, czasOstatniegoRuchu2, serwo2Aktywne, nowaPozycja2, aktualnyCzas);
}
 
void STARTNABIJANIA2(unsigned long aktualnyCzas) { // funkcja uruchamiajaca serwo 3 i 4
  int nowaPozycja3, nowaPozycja4;
  if (digitalRead(GUZIKSTART2) == LOW && (zmiennaWaga2 <= granicaWagi)) { //jezeli guzik jest wcisniety a waga jest ponizej wyznaczonej w granica wagi
    nowaPozycja3 = stopnie110; // 110°
    nowaPozycja4 = stopnie180; // 173°
  } else if (zmiennaWaga2 >= granicaWagi) {
    nowaPozycja3 = stopnie20;  // 20°
    nowaPozycja4 = stopnie0;   // 0°
  } else {
    return; // Brak zmiany
  }
 sterujSerwem(serwomechanizm3, 31, pozycjaSerwo3, czasOstatniegoRuchu3, serwo3Aktywne, nowaPozycja3, aktualnyCzas);
    sterujSerwem(serwomechanizm4, 33, pozycjaSerwo4, czasOstatniegoRuchu4, serwo4Aktywne, nowaPozycja4, aktualnyCzas);
}

void STOPNABIJANIA1(unsigned long aktualnyCzas) {
    if (digitalRead(GUZIKSTOP1) == HIGH) {
        sterujSerwem(serwomechanizm, 9, pozycjaSerwo1, czasOstatniegoRuchu1, serwo1Aktywne, stopnie0, aktualnyCzas);
        sterujSerwem(serwomechanizm2, 30, pozycjaSerwo2, czasOstatniegoRuchu2, serwo2Aktywne, stopnie20, aktualnyCzas);
    }
}

void STOPNABIJANIA2(unsigned long aktualnyCzas) {
    if (digitalRead(GUZIKSTOP2) == HIGH) {
        sterujSerwem(serwomechanizm3, 31, pozycjaSerwo3, czasOstatniegoRuchu3, serwo3Aktywne, stopnie20, aktualnyCzas);
        sterujSerwem(serwomechanizm4, 33, pozycjaSerwo4, czasOstatniegoRuchu4, serwo4Aktywne, stopnie0, aktualnyCzas);
    }
}

void STOP_przerwanie() { // Funkcja zatrzymania cofa serwa do pozycji startowej
    unsigned long teraz = millis();
    sterujSerwem(serwomechanizm, 9, pozycjaSerwo1, czasOstatniegoRuchu1, serwo1Aktywne, stopnie0, teraz);
    sterujSerwem(serwomechanizm2, 30, pozycjaSerwo2, czasOstatniegoRuchu2, serwo2Aktywne, stopnie20, teraz);
    sterujSerwem(serwomechanizm3, 31, pozycjaSerwo3, czasOstatniegoRuchu3, serwo3Aktywne, stopnie20, teraz);
    sterujSerwem(serwomechanizm4, 33, pozycjaSerwo4, czasOstatniegoRuchu4, serwo4Aktywne, stopnie0, teraz);
}


void sterujSerwem(Servo& serwo, int pin, int& pozycja, unsigned long& czasRuchu, bool& aktywne, int nowaPozycja, unsigned long aktualnyCzas) {
    if (nowaPozycja != pozycja) {
        serwo.attach(pin);
        serwo.write(nowaPozycja);
        pozycja = nowaPozycja;
        czasRuchu = aktualnyCzas;
        aktywne = true;
    }
}

void debugPrint(unsigned long aktualnyCzas) {
    if (!WERSJA_TESTOWA) return; // Wychodzimy, jeśli tryb testowy jest wyłączony

    // Wagi
    Serial.print("Waga: ");
    Serial.print(zmiennaWaga);
    Serial.println(" kg");

    Serial.print("Waga2: ");
    Serial.print(zmiennaWaga2);
    Serial.println(" kg");

    // Granica wagi
    Serial.print("Granica wagi: ");
    Serial.println(granicaWagi);

    // Tarowanie (tylko jeśli się zmieniło – wymaga flagi)
    static long ostatniaWartoscTara = wartoscTara;
    static long ostatniaWartoscTara2 = wartoscTara2;
    if (wartoscTara != ostatniaWartoscTara) {
        Serial.print("Waga została wytarowana. Nowa waga tara: ");
        Serial.println(wartoscTara);
        ostatniaWartoscTara = wartoscTara;
    }
    if (wartoscTara2 != ostatniaWartoscTara2) {
        Serial.print("Waga2 została wytarowana. Nowa waga tara: ");
        Serial.println(wartoscTara2);
        ostatniaWartoscTara2 = wartoscTara2;
    }

    // Temperatury
    if (temp1 == -127.0 || temp1 == 85.0) {
        Serial.println("ERROR 1 ");
    } else {
        Serial.print("Aktualna temperatura: ");
        Serial.println(temp1);
    }
    if (temp2 == -127.0 || temp2 == 85.0) {
        Serial.println("ERROR 2 ");
    } else {
        Serial.print("Aktualna temperatura2: ");
        Serial.println(temp2);
    }

    // Pozycje serw
    Serial.print("STARTNABIJANIA1: Serwo1=");
    Serial.print(pozycjaSerwo1);
    Serial.print("°, Serwo2=");
    Serial.println(pozycjaSerwo2);

    Serial.print("STARTNABIJANIA2: Serwo3=");
    Serial.print(pozycjaSerwo3);
    Serial.print("°, Serwo4=");
    Serial.println(pozycjaSerwo4);

    Serial.println("---"); // Separator dla czytelności
}

Do tego przetestowałem serwo pod obciążeniem na ramieniu 10 cm wiec dość duże.
Cieżar 5kg bez problemu podnosi. 10kg podnosi ale juz dosc ciezko w koncowej fazie ruchu. Nie dociaga jak chce sie przesunac serwo o rowne 90stopni. Trzeba ruszyc np o 110 stopni wtedy dociagnie do 90 stopni. Ogólnie działa jak na razie bardzo fajnie. Postaram sie jutro wrzucić filmy o ile uda mi sie je jakos zmiejszyc do 50 mb.

Link do komentarza
Share on other sites

(edytowany)

@PanMajster bo to z tymi serwami jest jeszcze tak że serwo cyfrowe zazwyczaj drgają...analogowe z reguły już nie ...testowałeś serwo o jakim ciągu? Te 150kg?

Edytowano przez farmaceuta
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.