• Witaj na Forum Arduino Polska! Zapraszamy do rejestracji!
  • Znajdziesz tutaj wiele informacji na temat hardware / software.
Witaj! Logowanie Rejestracja


Ocena wątku:
  • 0 głosów - średnia: 0
  • 1
  • 2
  • 3
  • 4
  • 5
Warunek - wyhamowanie przed osiągnęciem zadanej pozycji
#1
Witam,proszę o pomoc w ułożeniu warunku w programie bądź o rady/sugestie jak to najlepiej wykonać.
Celem jest wstawienie do programu warunku który będzie odpowiedzialny za "płynne wyhamowanie cewki zaworu hydraulicznego" przed osiągnięciem zadanej wysokości tak aby nie było natychmiastowego zatrzymania co mogło by spowodować nieprzewidziane uszkodzenia mechaniczne. Przykład:

- Znam aktualną pozycję ,ustawiam pozycję zadaną która jest np. większa od aktualnej i rozpoczyna się ruch
(pozycja aktualna dąży do zadanej - tutaj wszystko odbywa się po odczycie wartości potencjometru który pełni
rolę "ekonomicznego encodera"). I tutaj najważniejsze co chcę uzyskać że jeżeli aktualna pozycja będzie zbliżać
się do zadanej to rozpocznie się zmniejszenie wypełnienia przez co "cewka a w zasadzie to czym steruje" zacznie zwalniać aż osiągnie zadaną pozycje i się zatrzyma. Puki co cewka a w zasadzie tranzystor sterowany jest 0/1 ale chcę to przerobić na pwm.

I tutaj mój tok myślenia w przypadku kiedy rozpoczyna się praca w górę czyli aktualna pozycja jest mniejsza
od zadanej pozycji:

(zadana_ pozycja - aktualna_pozycja) = Y;

x = (Y<= 30);

//rozpoczyna się hamowanie, 30 to luźno przyjęta wartość po prostu chcę mieć
jakąś stałą od której mogę uzależnić rozpoczęcie hamowania zarówno podczas dojazdu do zadanej pozycji góra jak i dół.

pwm = map(x,30,0, 255,0);    //tutaj chciałem wykorzystać przyjętą wartość do przeskalowania na odpowiednio zmniejszające się wypełnienie:

analogWrite(cewka,pwm);      // i bach pwm na tranzystor sterujący cewką

edit, wyżej wypisane dane nie pokrywają się z zmiennymi w kodzie programu - jest to po prostu przykład.

ALE nie wiem jak to wkomponować do wysterowanej już cewki  bo przecież ma hamować dopiero "chwilę" przed
osiągnięciem pozycji.

Dlatego zwracam się z prośba o wsparcie w temacie bo może ja po prostu przyjąłem zły tok myślenia i można to w zupełnie inny sposób ułożyć.

Kod programu puki co jest dużo "ifów" planuje to przerobić pewne rzeczy na switch-case, po za tym jest tu dużo innych rzeczy ale nas interesuje w zasadzie warunek dla zmiennej "jazda" - jest na samym dole:
Kod:
#include <EEPROM.h>
#include <Bounce2.h>


int MAKSYMALNA_POZYCJA = 90;
int MINIMALNA_POZYCJA = 3;

#define zapis_wysokosci_gora A4          // zapis górnej wysokosci do eeprom   
#define zapis_wysokosci_dol A5          //zapis dolnej wysokosci do eeprom                           
#define przycisk_do_gory  6                   
#define przycisk_na_dol 7
#define DZW  11                                   // dioda zapisu wysokości
#define przycisk_regulacji 5           //przycisk umozliwiający regulację zapisanej wysokości
#define potencjometr A1        // potencjometr ustawiający pozycję do zapisu
#define czujnik A2            // potencjometr -czujnik
#define DG 12                  // dioda do góry
#define DD 13                 // dioda na dół
#define przycisk_ustawienia 8          // przycisk
#define cewkag 10              //cewka rozdzielacza do góry
#define cewkad 9           //cewka rozdzielacza na dół
#define przycisk_dojazdu 4    // przycisk umożliwiający bezpośredni ruch do zapisanej wartości do góry albo w dół
#define sterowanie_zew A3
#define regulacja A0     // drobna regulacja ustawionej wysokośći



Bounce pozycja1 = Bounce();       // pozycja przełącznika 1
Bounce pozycja2 = Bounce();       // pozycja przełacznika 2
Bounce pozycja3 = Bounce();       // pozycja przełącznika 3
Bounce pozycja4 = Bounce();       // pozycja przełącznika 4
Bounce zapis_pozycji_gora = Bounce();
Bounce zapis_pozycji_dol = Bounce();
Bounce do_gory = Bounce();
Bounce na_dol = Bounce();

int wartosc_gora;
int wartosc_dol;

bool gora = false;
bool dol = false;

unsigned long aktualnyCzas =0;
unsigned long zapamietanyCzas =0;

void setup() {


  pinMode(zapis_wysokosci_gora,INPUT_PULLUP);
  pinMode(zapis_wysokosci_dol,INPUT_PULLUP);
  pinMode(potencjometr,INPUT);
  pinMode(czujnik,INPUT);
  pinMode(przycisk_ustawienia,INPUT_PULLUP);
  pinMode(DG,OUTPUT);
  pinMode(DD,OUTPUT);
  pinMode(DZW,OUTPUT);
  pinMode(cewkag,OUTPUT);
  pinMode(cewkad,OUTPUT);
  pinMode(przycisk_do_gory,INPUT_PULLUP);
  pinMode(przycisk_na_dol,INPUT_PULLUP);
  pinMode(przycisk_regulacji,INPUT_PULLUP);
  pinMode(przycisk_dojazdu,INPUT_PULLUP);
  pinMode(sterowanie_zew,INPUT_PULLUP);
  pinMode(regulacja,INPUT);
 

  Serial.begin(9600);
 
  digitalWrite(cewkag,LOW);          //domyślnie cewka wyłączona
  digitalWrite(cewkad,LOW);
  digitalWrite(DZW,LOW);


  wartosc_gora = EEPROM.read(0);                //odczyt zapisanej wysokość góra
  wartosc_dol  = EEPROM.read(1);                //odczyt zapisanej wysokość dół

 
// DEBOUNCING PRZYCISKÓW I PRZEŁĄCZNIKA:

  pozycja1.attach(przycisk_ustawienia);
  pozycja1.interval(30);

  pozycja2.attach(przycisk_regulacji);
  pozycja2.interval(30);

  pozycja3.attach(przycisk_dojazdu);
  pozycja3.interval(30);

  pozycja4.attach(sterowanie_zew);
  pozycja4.interval(30);

  zapis_pozycji_gora.attach(zapis_wysokosci_gora);
  zapis_pozycji_gora.interval(30);
 
  do_gory.attach(przycisk_do_gory);
  do_gory.interval(40);
 
  na_dol.attach(przycisk_na_dol);
  na_dol.interval(40);

  zapis_pozycji_dol.attach(zapis_wysokosci_dol);
  zapis_pozycji_dol.interval(30);

  

  delay(100);
}


void loop() {

  aktualnyCzas = millis();

  pozycja1.update();
  int poz1 = pozycja1.read();

  pozycja2.update();
  int poz2 = pozycja2.read();

  pozycja3.update();
  int poz3 = pozycja3.read();

  pozycja4.update();
  int poz4 = pozycja4.read();

  zapis_pozycji_gora.update();
 
  zapis_pozycji_dol.update();

  na_dol.update();
 
  do_gory.update();

 

  int pozycja = analogRead(czujnik)/4 ;       //odczyt pozycji czujnika
 
  int sterowanie = analogRead(potencjometr)/4;   //odczyt potencjometru do ustawiania pozycji
   
  int8_t jazda;
 
  const int hist = 2  ;

  int regulacja_ustawionej_wysokosci = analogRead(regulacja)/4;

  int value_dol = map(regulacja_ustawionej_wysokosci,125,80,0,2);
  int value_gora  = map(regulacja_ustawionej_wysokosci,130,175,0,2);

 
  Serial.println("regulacja ");
  Serial.print(regulacja_ustawionej_wysokosci);

  //USTAWIENIE POZYCJI DO ZAPISU:

  if(poz1 == LOW) {
                           
     if (pozycja < sterowanie - hist ) jazda = 1;        // jazda do góry  
     else if (pozycja > sterowanie + hist ) jazda = -1;  //jazda  w dół
     else jazda = 0;                                    // stop
   } else jazda = 0;

//ZAPIS USTAWIONEJ WYSOKOŚCI DO EEPROM:
        
  if((poz1== LOW) && (zapis_pozycji_gora.fell()) ) {
   
    wartosc_gora = pozycja;
    EEPROM.update(0,wartosc_gora);
    digitalWrite(DZW,HIGH);
    digitalWrite(DG,HIGH);
    delay(1000);
  } else
    digitalWrite(DZW,LOW);
    digitalWrite(DG,LOW);
 
if((poz1 == LOW) &&(zapis_pozycji_dol.fell()) ) {

   wartosc_dol = pozycja;
   EEPROM.update(1,wartosc_dol);
   digitalWrite(DZW,HIGH);
   digitalWrite(DD,HIGH);
   delay(1000);
} else
   digitalWrite(DZW,LOW);
   digitalWrite(DD,LOW);

//REGULACJA USTAWIONEJ WYSOKOŚCI DÓŁ:

   if(poz2 == LOW) {
       
     if(pozycja > wartosc_dol - value_dol ) jazda =-1;
     else if (pozycja < wartosc_dol + value_gora ) jazda =1;
     else jazda =0;    
   }

  

//DOJAZD DO ZAPISANYCH WYSOKOSCI W PAMIĘCI:

  if((poz3 == LOW)&& do_gory.fell()) gora=!gora; {
   if(gora == true){
   if (pozycja < wartosc_gora - hist ) jazda = 1; 
   else if (pozycja > wartosc_gora + hist )  jazda = -1; 
   else { jazda = 0;
      gora=!gora;  }
}
  }
    if((poz3 == LOW) && na_dol.fell()) dol=!dol; {
    if(dol == true) {
    if (pozycja > wartosc_dol + hist) jazda = -1;
    else if(pozycja < wartosc_dol - hist ) jazda = 1;
    else  { jazda = 0;
            dol=!dol; }            
  
  }
    }

  
// STEROWANIE ZEWNĘTRZNE:
  if(poz4 == LOW)  {
  jazda=0;
  digitalWrite(DZW,LOW);
  if(aktualnyCzas - zapamietanyCzas >=1000UL) {
    zapamietanyCzas = aktualnyCzas;
  digitalWrite(DZW,HIGH);
    }
  }
  

 
//WARUNKI DLA ZMIENNEJ JAZDA:

  if (jazda > 0) {
    
   digitalWrite(cewkag,HIGH);
   digitalWrite(DG,HIGH);
  
   digitalWrite(cewkad,LOW);
   digitalWrite(DD,LOW);
    
  if(pozycja >= MAKSYMALNA_POZYCJA) {
   digitalWrite(cewkag,LOW);
   digitalWrite(DG,LOW);
  if(aktualnyCzas - zapamietanyCzas >=500UL) {
    zapamietanyCzas = aktualnyCzas;
    digitalWrite(DG,HIGH);
  }
}

}

   else if (jazda < 0) {
   digitalWrite(cewkag,LOW);
   digitalWrite(DG,LOW);
  
   digitalWrite(cewkad,HIGH);
   digitalWrite(DD,HIGH);

   if(pozycja <= MINIMALNA_POZYCJA){
     digitalWrite(cewkad,LOW);
     digitalWrite(DD,LOW);
  if(aktualnyCzas - zapamietanyCzas >=500UL) {
    zapamietanyCzas = aktualnyCzas;
    digitalWrite(DD,HIGH);
  }
}
}
   
   else {
   digitalWrite(cewkag,LOW);
   digitalWrite(DG,LOW);
  
   digitalWrite(cewkad,LOW);
   digitalWrite(DD,LOW);
}
   
}
 
Odpowiedź
#2
Do takich celów używa się czujników liniowych, lub chociaż dwóch czujników określających minimum dwie pozycje pozycję.. Bo chcesz opierać się na czasie a skąd wiesz że siłownik zawsze w takim samym czasie się posuwał? jak on będzie zmienny zależny od obciążenia i od temp oleju.....

Po drugie to co chcesz zrobić już dawno zrobiono za epoki kamienia łupanego, nazywa się to akumulator ciśnienia....
Arduino zostało wymyślone po to, by robić dobrze jedną prostą rzecz – migać diodą. 
 
Odpowiedź
#3
(19-02-2021, 18:01)Jarewa0606 napisał(a): Do takich celów używa się czujników liniowych, lub chociaż dwóch czujników określających minimum dwie pozycje pozycję..  Bo chcesz opierać się na czasie a skąd wiesz że siłownik zawsze w takim samym czasie się posuwał?  jak on będzie zmienny zależny od obciążenia i od temp oleju.....

Po drugie to co chcesz zrobić już dawno zrobiono za epoki kamienia łupanego, nazywa się to akumulator ciśnienia....
Nie opieram się "na czasie" tylko na podstawie odczytu ADC z potencjometru.
Czas jest tylko używany do tak jakby "krańcówek"
 
Odpowiedź
#4
A sory nie doczytałem... Skoro znasz pozycje wystarczy przerzut ADC do PWM tylko musisz określić punkt początkowy i punkt końcowy hamowania...

ADC= readanalog(pin); // odczyt pozycji
if(ostatni_ADC - ADC >0 ){ // pozycja UP
poprzedni_ADC= ADC; // przypisz teraźniejszą wartość ADC
ADC=constrain(ADC, punkt początkowyUP, punkt koncowyUP); // ograniczaj odczyt do zadanych
pwm = map(ADC, punkt_początkowyUP, punkt_koncowyUP, 255,0);
analogWrite(cewka,pwm);
}else{
if(ostatni_ADC -ADC <0 ){ // pozycj DOWN
poprzedni_ADC= ADC; // przypisz teraźniejszą wartość ADC
ADC=constrain(ADC, punkt początkowyDOWN, punkt koncowyDOWN); // ograniczaj odczyt do zadanych
pwm = map(ADC, punkt_początkowyDOWN, punkt_koncowyDOWN, 255,0);
analogWrite(cewka,pwm);
}else{
poprzedni_ADC= ADC; // przypisz teraźniejszą wartość ADC
// tu można wyłączyć zawór bo siłownik stoi w miejscu......
}
}
Arduino zostało wymyślone po to, by robić dobrze jedną prostą rzecz – migać diodą. 
 
Odpowiedź
#5
Dzięki za propozycje, niedługo będę próbował to "wdrożyć w życie" jak co to będę jeszcze pytał. 
Wytłumacz proszę jeszcze mi co to jest constrain bo szczerze mówiąc nie spotkałem się jeszcze z takim czymś.
 
Odpowiedź
#6
Ogranicza liczbę do interesujących nas parametrów, po to żeby funkcja map nie szwankowała...

Czyli jeżeli z ADC interesuje nas przedział 700-800 to ta funkcja ogranicza do tych liczb jeżli będzie poniżej 700 to przyjmie 700 a powyżej 800 to przyjmuje zawsze 800. , po to żeby w funkcji map jak masz określoną minimalną i maksymalną wartość zmiennej nie podawać poniżej i powyżej bo będzie problematyczne...
Arduino zostało wymyślone po to, by robić dobrze jedną prostą rzecz – migać diodą. 
 
Odpowiedź
  


Skocz do:


Przeglądający: 1 gości