Skocz do zawartości

Sprawdzenie kodu - zapis do EEPROM


Waldy

Pomocna odpowiedź

Witam,chciałbym mieć możliwość zapisu do pamięci eeprom dwóch pozycji góra i dół(w programie H i L) i mam taką zagawostkę od czego uzależnić wartości H i L żeby później można było je odczytać(jako dwie inne wartości wysokości) i porównać w dalszych etapach. Czy jak np uwarunkuje je od odczytu z czujnika to nie zapisze wartości  H i L jako tej samej wysokości ?

Problem zaczyna się w  //ZAPIS USTAWIONEJ WYSOKOŚCI :

#include <EEPROM.h>
#include <Bounce2.h>

#define przycisk_zapisu_wysokosci 4          // przycisk zapisujący ustawioną wysokość do pamięci 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 8          // przycisk 
#define cewkag 10              //cewka rozdzielacza do góry
#define cewkad 9           //cewka rozdzielacza na dół

#define przycisk_gora_dol A4    // przycisk umożliwiający bezpośredni ruch do zapisanej wartości do góry albo w dół

Bounce debouncer1 = Bounce();
Bounce debouncer2 = Bounce();
Bounce debouncer3 = Bounce();
Bounce debouncer4 = Bounce();
Bounce debouncer5 = Bounce();
Bounce debouncer6 = Bounce();

int H;
int L;
 
void setup() { 
  
  pinMode(przycisk_zapisu_wysokosci,INPUT_PULLUP);
  pinMode(potencjometr,INPUT);
  pinMode(czujnik,INPUT);
  pinMode(przycisk,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_gora_dol,INPUT_PULLUP);

  
  digitalWrite(cewkag,LOW);          //domyślnie cewka wyłączona
  digitalWrite(cewkad,LOW);
  
  
  debouncer1.attach(przycisk);
  debouncer1.interval(30);

  debouncer2.attach(przycisk_zapisu_wysokosci);
  debouncer2.interval(30);
  
  debouncer3.attach(przycisk_do_gory);
  debouncer3.interval(40);
  
  debouncer4.attach(przycisk_na_dol);
  debouncer4.interval(40);

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

  debouncer6.attach(przycisk_gora_dol);
  debouncer6.interval(30);



  Serial.begin(9600);

  delay(100);
}


 void loop() {
   
 //debouncing przycisków :
  
  debouncer1.update();
  int stan1 = debouncer1.read();

  debouncer2.update();
  int stan2 = debouncer2.read();

  debouncer3.update();
  int stan3 = debouncer3.read();

  debouncer4.update();
  int stan4 = debouncer4.read();

  debouncer5.update();
  int stan5 = debouncer5.read();

  debouncer6.update();
  int stan6 = debouncer6.read();
  

  H = EEPROM.read(0);                //odczyt zapisanej wysokość góra
  L = EEPROM.read(1);                //odczyt zapisanej wysokość dół
  
 
  int pozycja = analogRead(czujnik)/4 ;         //odczyt pozycji czujnika 
  //pozycja = map(pozycja,0,400,0,1023)/4;      //przeskalowanie zakresu czujnika na odpowiedni zakres sterowania
  
  int sterowanie = analogRead(potencjometr)/4; //odczyt potencjometru do ustawiania pozycji 
    
  int hist = 3; //histereza 

  int8_t jazda;
  
  
 //USTAWIANIE WYSOKOŚCI DO ZAPISU

   

if (stan1 == LOW) {           //wcisnięty przycisk
   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 {                   // przycisk puszczony
   jazda = 0;            // nigdzie nie jedziemy
}
    


//ZAPIS USTAWIONEJ WYSOKOŚCI
  
  
  if(stan1 == LOW && stan2 == LOW){    // jeżeli stan2 == low zapis ustawionej wysokosci do pamięci
    digitalWrite(DZW,HIGH);
    if (pozycja > 127)  EEPROM.update(0,H);
    if (pozycja < 127) EEPROM.update(1,L); 
    }
  else digitalWrite(DZW,LOW);
  

Serial.println("wysokość dół ");
Serial.println(L);
Serial.println("wysokość góra ");
Serial.println(H);

 
  
 //BEZPOŚREDNI DOJAZD DO ZAPISANYCH WYSOKOŚCI ZA POMOCĄ PRZYCISKÓW

 if(stan6 == LOW) {
  
   if (stan3 == LOW) {     //wcisnięty przycisk w górę
   if (pozycja < H - hist) jazda = 1;  
   else if (pozycja > H + hist)  jazda = -1;
                                                                
   }
   
    if (stan4 == LOW ) {            //wcisnięty przycisk w dół  
    if(pozycja > L + hist ) jazda = -1;   
    else if(pozycja < L -hist) jazda = 1;
    
   } 
 }

  if (jazda > 0) {
     
   digitalWrite(cewkag,HIGH);
   digitalWrite(DG,HIGH);
   
   digitalWrite(cewkad,LOW);
   digitalWrite(DD,LOW);
}

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

Pozdrawiam Waldek.

Link do komentarza
Share on other sites

A co będzie, jeśli będziesz chciał zapisać wartości np. 130 i 220?

Ja bym to zrobił na zasadzie wciśnięcia jednocześnie dwóch przycisków: np. ZAPIS i GÓRA zapisują wartość H, ZAPIS i DOL wartość L. Można to jeszcze na piętnaście różnych sposobów zrobić, ale jeśli nie będziesz miał bezpośredniej kontroli nad tym co i gdzie zapisujesz, prędzej czy później się pomylisz.

Jeszcze drobiazg... w którym miejscu w programie zmienia się L i H? Bo z tego co widzę odczytujesz je z EEPROM-u nie wiadomo po co za każdym obrotem pętli, nigdy się te wartości nie zmieniają ale próbujesz je zapisywać...

I drugi drobiazg... czynności takie jak "zapisz do EEPROM-u" wyzwalaj poprzez zmianę stanu przycisku, a nie stan (np. debouncer.fell() albo debouncer.rose()), bo w przeciwnym razie czynność będzie si powtarzać cały czas dopóki nie puścisz klawisza - a nie o to Ci chyba chodziło.

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

@Waldy świetnie, że udało się rozwiązać problem 😉 Może wkleisz ostateczny kod? Na pewno ktoś jeszcze na tym skorzysta, a przy okazji sprawdzimy czy wszystko jest poprawnie zrobione 🙂

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

Faktycznie 😉  Kod jeszcze nie jest ostateczny - puki co jest nasiane 2/3 tego co chciałbym mieć ale to i tak już duży sukces. 

Proszę:

#include <EEPROM.h>
#include <Bounce2.h>

#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  7                    
#define przycisk_na_dol 6
#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 8          // przycisk 
#define cewkag 10              //cewka rozdzielacza do góry
#define cewkad 9           //cewka rozdzielacza na dół
#define przycisk_gora_dol 4    // przycisk umożliwiający bezpośredni ruch do zapisanej wartości do góry albo w dół



Bounce debouncer1 = Bounce();
Bounce debouncer2 = Bounce();
Bounce debouncer3 = Bounce();
Bounce debouncer4 = Bounce();
Bounce debouncer5 = Bounce();
Bounce debouncer6 = Bounce();
Bounce debouncer7 = Bounce();

int wartosc_gora;
int wartosc_dol;

int ledState = LOW;
bool stan3 = false;
bool stan4 = false;
 
void setup() { 
  
  pinMode(zapis_wysokosci_gora,INPUT_PULLUP);
  pinMode(zapis_wysokosci_dol,INPUT_PULLUP);
  pinMode(potencjometr,INPUT);
  pinMode(czujnik,INPUT);
  pinMode(przycisk,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_gora_dol,INPUT_PULLUP);

  
  digitalWrite(cewkag,LOW);          //domyślnie cewka wyłączona
  digitalWrite(cewkad,LOW);
  digitalWrite(DZW,ledState);
 

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

  debouncer2.attach(zapis_wysokosci_gora);
  debouncer2.interval(30);
  
  debouncer3.attach(przycisk_do_gory);
  debouncer3.interval(40);
  
  debouncer4.attach(przycisk_na_dol);
  debouncer4.interval(40);

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

  debouncer6.attach(przycisk_gora_dol);
  debouncer6.interval(30);

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


  Serial.begin(9600);

  

  delay(100);
}


 void loop() {
   
 //debouncing przycisków :
  
  debouncer1.update();
  int stan1 = debouncer1.read();

  debouncer2.update();
  
  debouncer3.update();
  //int stan3 = debouncer3.read();

  debouncer4.update();
  //int stan4 = debouncer4.read();

  debouncer5.update();
  int stan5 = debouncer5.read();

  debouncer6.update();
  int stan6 = debouncer6.read();

  debouncer7.update();

  
 
 
  int pozycja = analogRead(czujnik)/4 ;         //odczyt pozycji czujnika 
  //pozycja = map(pozycja,0,400,0,1023)/4;      //przeskalowanie zakresu czujnika na odpowiedni zakres sterowania
  
  int sterowanie = analogRead(potencjometr)/4; //odczyt potencjometru do ustawiania pozycji 
    
  int hist = 3; //histereza 

  int8_t jazda;
  
  
 //USTAWIANIE WYSOKOŚCI DO ZAPISU


if (stan1 == LOW) {           //wcisnięty przycisk
   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 {                   // przycisk puszczony
   jazda = 0;            // nigdzie nie jedziemy
}
    


//ZAPIS USTAWIONEJ WYSOKOŚCI
  
  
  if((stan1 == LOW) && (debouncer2.fell() )) {    //zapis górnej pozycji
                
      wartosc_gora = pozycja;
      EEPROM.update(0,wartosc_gora);
      ledState = !ledState;   
      digitalWrite(DZW,ledState); 
        
    } else
      digitalWrite(DZW,LOW);
    
  if((stan1 == LOW) && (debouncer7.fell() )) {    //zapis dolnej pozycji
    
    wartosc_dol = pozycja;
    EEPROM.update(1,wartosc_dol); 
    ledState = !ledState;   
    digitalWrite(DZW,ledState); 
      
    } else 
      digitalWrite(DZW,LOW);
    
  

Serial.println("wysokość dół: ");
Serial.println(wartosc_dol);
Serial.println("wysokość góra: ");
Serial.println(wartosc_gora);
Serial.println("pozycja czujnika: " );
Serial.println(pozycja);
  
  
 //BEZPOŚREDNI DOJAZD DO ZAPISANYCH WYSOKOŚCI ZA POMOCĄ PRZYCISKÓW

   if ((stan6 == LOW) && debouncer3.fell ()) {stan3 = !stan3;}                //po naciśnięciu dojazd do pozycji górnej 
  
   if (stan3 == true) {
   if (pozycja < wartosc_gora - hist) jazda = 1;  
   else if (pozycja > wartosc_gora + hist)  jazda = -1;  
   else jazda = 0;
   }    else stan3 == HIGH;                      
    
   
    if ((stan4 == LOW) && debouncer4.fell ()) { stan4 = !stan4;}               //po naciśnięciu dojazd do pozycji dolej 
    
    if (stan4 == true) {
    if (pozycja > wartosc_dol + hist ) jazda = -1;
    else if(pozycja < wartosc_dol -hist) jazda = 1;
    else jazda = 0;
    }   else stan4 == HIGH;
 
 

 //DROBNA REGULACJA USTAWIONEJ WYSOKOŚCI :

  if (jazda > 0) {
     
   digitalWrite(cewkag,HIGH);
   digitalWrite(DG,HIGH);
   
   digitalWrite(cewkad,LOW);
   digitalWrite(DD,LOW);
}

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

Zmieniłem wartości H na wartosc_gora i L na wartosc_dol  - myślę że tak jest czytelniej, obecnie walczę z przyciskami bezpośredniego dojazdu do zapisanej wysokości trochę nie działają tak jak bym chciał. Na tą chwilę po wciśnięciu przycisku i puszczeniu dojeżdża do zapamiętanej pozycji góra i dół ale tylko raz i później jakby blokował się program(nie mogę już nic wykonać) myślę że źle jest zdefiniowany else... nie wiem czy dobrze myślę ale przy takim założeniu jak mam i wykonaniu dojazdu do zapamiętanej pozycji trzeba zmienić mu stan z powrotem na wysoki ? Hmm taka myśl mnie naszła że chyba lepiej przypisać ten stan do przycisku po którym się on zmienia a nie do stanu bo to jakaś głupota teraz wyszła - przykład jak nie pisać kodu 😄 Pozdrawiam. 

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

Cześć,chciałbym uzyskać taki efekt taki że po chwilowym naciśnięciu przycisku "do góry" ramię jedzie do zapamiętanej pozycji zdefiniowanej jako wartosc_gora i analogicznie po chwilowym naciśnięciu przycisku na dół ramię zdąża do zapisanej pozycji wartosc_dol. Tak też się dzieje ramię ładnie zdąża do zadanej pozycji po naciśnięciu odpowiedniego przycisku ale tylko raz. ? Dlaczego tak się dzieje ? Może ja źle definiuje warunek po else jak już wykona się dojazd do zapamiętanej pozycji ? Próbowałem  za else przypisać do odpowiedniego stanu false, stan przeciwny do wystawionego po wykryciu zbocza,oraz sam stan; - nok. Może ja to źle rozumiem i chcę "na siłę" przywrócić stan pierwotny po zmianie którego następuje dojazd do pozycji góra bądź dół, a może całość trzeba jakoś inaczej napisać ? Poniżej wycinek kodu:

if ((stan6 == LOW) && (debouncer3.fell ()) ) stan3 = !stan3;   //po naciśnięciu dojazd do pozycji górnej                            //wybór trybu dojazdu               
   if (stan3 == true) {
   if (pozycja < wartosc_gora - hist) jazda = 1;  
   else if (pozycja > wartosc_gora + hist)  jazda = -1;  
   else jazda = 0;
   }   else stan3 = ???
    
   
    if ((stan6 == LOW) && (debouncer4.fell ()) ) stan4 = !stan4;      //po naciśnięciu dojazd do pozycji dolej 
    if (stan4 == true) {
    if (pozycja > wartosc_dol + hist ) jazda = -1;
    else if(pozycja < wartosc_dol -hist) jazda = 1;
    else jazda = 0;
    }   else stan4 = ???

Pozdrawiam Waldek

Link do komentarza
Share on other sites

Zacznij może od tego, że pozmieniasz nazwy zmiennych. Wybacz, ale "stan57" czy "debouncer17" Tobie może coś mówią, ale nie mnie i bez całości kodu ten fragment jest po prostu nieczytelny. Chciałbym pomóc, ale nie dajesz mi szans.

A przy okazji owszem, trzeba będzie napisać zupełnie inaczej, ale o tym pogadamy jak przestaniesz numerować stany.

Link do komentarza
Share on other sites

Ok,to na szybko objaśnienia tak żeby nie trzeba było przeszukiwać całego "kodu" :

stan6 - odczytanie stanu przycisku który wybiera tryb bezpośredniego dojazdu do zapamiętanej pozycji w pamięci eeprom( wartosc_dol i wartosc_gora ),

debouncer3.feel - zmiana stanu przycisku(przycisk_do_gory)  po którym ramię dojeżdża do zapamiętanej pozycji "wartosc_gora" ,

debouncer4.feel -zmiana stanu przycisku(przycisk_na_dol)  po którym ramię dojeżdża do zapamiętanej pozycji   "wartosc_dol" ,

stan3 i stan4 pierwotnie to :

bool stan3 = false;
bool stan4 = false;

I cały kod poniżej :

#include <EEPROM.h>
#include <Bounce2.h>

#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 8          // przycisk 
#define cewkag 10              //cewka rozdzielacza do góry
#define cewkad 9           //cewka rozdzielacza na dół
#define przycisk_gora_dol 4    // przycisk umożliwiający bezpośredni ruch do zapisanej wartości do góry albo w dół



Bounce debouncer1 = Bounce();
Bounce debouncer2 = Bounce();
Bounce debouncer3 = Bounce();
Bounce debouncer4 = Bounce();
Bounce debouncer5 = Bounce();
Bounce debouncer6 = Bounce();
Bounce debouncer7 = Bounce();

int wartosc_gora;
int wartosc_dol;

bool stan3 = false;
bool stan4 = false;
  


void setup() { 
  
  pinMode(zapis_wysokosci_gora,INPUT_PULLUP);
  pinMode(zapis_wysokosci_dol,INPUT_PULLUP);
  pinMode(potencjometr,INPUT);
  pinMode(czujnik,INPUT);
  pinMode(przycisk,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_gora_dol,INPUT_PULLUP);

  
  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ół
  
  debouncer1.attach(przycisk);
  debouncer1.interval(30);

  debouncer2.attach(zapis_wysokosci_gora);
  debouncer2.interval(30);
  
  debouncer3.attach(przycisk_do_gory);
  debouncer3.interval(40);
  
  debouncer4.attach(przycisk_na_dol);
  debouncer4.interval(40);

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

  debouncer6.attach(przycisk_gora_dol);
  debouncer6.interval(30);

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


  Serial.begin(9600);
  
  
  

  delay(100);
}


 void loop() {
   
 //debouncing przycisków :
  
  debouncer1.update();
  int stan1 = debouncer1.read();

  debouncer2.update();
  
  debouncer3.update();
  //int stan3 = debouncer3.read();

  debouncer4.update();
  //int stan4 = debouncer4.read();

  debouncer5.update();
  int stan5 = debouncer5.read();

  debouncer6.update();
  int stan6 = debouncer6.read();

  debouncer7.update();

  
 
 
  int pozycja = analogRead(czujnik)/4 ;         //odczyt pozycji czujnika 
  //pozycja = map(pozycja,0,400,0,1023)/4;      //przeskalowanie zakresu czujnika na odpowiedni zakres sterowania
  
  int sterowanie = analogRead(potencjometr)/4; //odczyt potencjometru do ustawiania pozycji 
    
  int hist = 3; //histereza 

  int8_t jazda;

  
  
 //USTAWIANIE WYSOKOŚCI DO ZAPISU


if (stan1 == LOW) {           //wcisnięty przycisk
   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 {                   // przycisk puszczony
   jazda = 0;            // nigdzie nie jedziemy
}
    


//ZAPIS USTAWIONEJ WYSOKOŚCI DO PAMIĘCI EEPROM:
  
  if((stan1 == LOW) && (debouncer2.fell() )) {    //zapis górnej pozycji
                
      wartosc_gora = pozycja;
      EEPROM.update(0,wartosc_gora);  
      digitalWrite(DZW,HIGH);
      digitalWrite(DG,HIGH);
      delay(1000); 
        
    } else
      digitalWrite(DZW,LOW);
      digitalWrite(DG,LOW);
    
  if((stan1 == LOW) && (debouncer7.fell() )) {    //zapis dolnej pozycji
    
    wartosc_dol = pozycja;
    EEPROM.update(1,wartosc_dol);   
    digitalWrite(DZW,HIGH); 
    digitalWrite(DD,HIGH);
    delay(1000);
      
    } else 
      digitalWrite(DZW,LOW);
      digitalWrite(DD,LOW);
    
  
  
 //BEZPOŚREDNI DOJAZD DO ZAPISANYCH WYSOKOŚCI ZA POMOCĄ PRZYCISKÓW

   if ((stan6 == LOW) && (debouncer3.fell ()) ) stan3 = !stan3;   //po naciśnięciu dojazd do pozycji górnej              
   if (stan3 == true) 
   if (pozycja < wartosc_gora - hist) jazda = 1;  
   else if (pozycja > wartosc_gora + hist)  jazda = -1;  
   else jazda = 0;
   }   else stan3 = ???
    
   
    if ((stan6 == LOW) && (debouncer4.fell ()) ) stan4 = !stan4;      //po naciśnięciu dojazd do pozycji dolej 
    if (stan4 == true) {
    if (pozycja > wartosc_dol + hist ) jazda = -1;
    else if(pozycja < wartosc_dol -hist) jazda = 1;
    else jazda = 0;
    }   else stan4 = ???
   
    
   

 //DROBNA REGULACJA USTAWIONEJ WYSOKOŚCI :

  if (jazda > 0) {
     
   digitalWrite(cewkag,HIGH);
   digitalWrite(DG,HIGH);
   
   digitalWrite(cewkad,LOW);
   digitalWrite(DD,LOW);
}

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

 

Link do komentarza
Share on other sites

Nie, nie o to chodzi.

Co to za zmienne "stan" w ogóle i do czego one są tam potrzebne? Wiem, że istnieje maszyna stanów ale tam jest jedna zmienna "stan" przyjmująca różne wartości, a nie siedemnaście stanów co ze sobą wojują. Tu brakuje tej jednej zmiennej.

Czy na swoim traktorze masz klawiaturę numeryczną z klawiszami od 1 do 7, czy może te klawisze się jakoś nazywają (np. "do góry")?

Program jest dalej nieczytelny, w kodzie masz zupę z instrukcji odpowiedzialnych za czytanie klawiszy, jeżdżenie i tak dalej. Na szczęście sterowanie cewkami masz w jednym miejscu.

Zrób sobie jakąś funkcję odpowiedzialną za odczyt polecenia z klawiatury. Zrób jakąś niewielką funkcję, w której zawrzesz wszystko co się wiąże z zapalaniem/gaszeniem led (a przede wszystkim wywal delay(1000) z programu bo jak człowiek na to patrzy to go ciarki przechodzą). Taki przykład (nie funkcji a jej wykorzystania):
 

int command = readKeyboard();
switch (command) {
	case EEPROM_WRITE_LOW:
    	wartosc_dol = pozycja;
    	EEPROM.update(ADDR_LOW,wartosc_dol);   
    	ledControl(LED_DZW | LED_DD);
    	break;

Program nie ma działać tak, że jeśli pali się leda to nie przyjmuje żadnych poleceń z klawiatury, prawda? A odliczanie czasu do zgaszenia ledy można sobie zrobić używając millis().

Niech globalna zmienna "stan" (jedna, możesz użyć zmiennej "jazda" bo aż się o to prosi) trzyma wartości typu "nigdzie nie jadę", "jadę do pozycji górnej", "jadę do pozycji dolnej", "jadę w górę", "jadę w dół". Niech program po odczycie z klawiatury ustawia tę wartość. Niech już po ustawieniu sprawdza, czy dalsza jazda jest konieczna (np. przy dojeździe do dołu czy osiągnięto zapisaną dolną pozycję, przy ręcznej jeżdzie do dołu czy nam się podnośnik nie skończył), i koryguje wartość tej zmiennej. Na końcu możesz na jej podstawie sterujesz cewkami. Po kolei, a nie wszystko na raz.

 

 

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

Hmm,stany to u mnie po prostu odczyty poszczególnych przycisków po debouncingu z wyjątkiem stanu3 i 4 który przypisałem tak bo pasował mi do kolejności debouncerów przycisków góra/dół - no faktycznie może jest to nieczytelne dla drugiej osoby/być może nawet bardzo(poprawię to). Szczerze mówiąc po przeczytaniu mam trochę mętlik w głowie no muszę sobie to na spokojnie przeanalizować.Może napiszę jaki ja miałem zamysł na strukturę(nie wiem czy to dobre słowo) kodu jako laik nie programista:

Mam cztery tryby każdy wyzwalany osobnym przyciskiem tak żeby nie było pomyłki co kiedy robimy i żeby nie zrobić czasem czegoś innego(tutaj używam przełącznika obrotowego 4 pozycyjnego) :

Pozycja1:  ustawienie żądanej wysokości + zapis do pamięci 

Pozycja2:  regulacja w małym stopniu ustawionej wysokości(na wypadek pływania ramienia)

Pozycja3:  możliwość bezpośredniego dojazdu do zapisanej wysokości, i np. tutaj mamy ((stan6 == LOW) && (debouncer3.fell ()) )  jeżeli wybrano pozycje 3(stan6 == LOW) i jeżeli wykryto naciśnięcie przycisku - jedziemy do danej pozycji.

Pozycja4:  sterowanie zewnętrzne

W zasadzie dlatego taka "zupa stanowa" jest...

Odnośnie tego delaya no to też zastanawiałem się nad millis() ale w zasadzie na moment zapisu ustawionej wysokości nie musi przyjmować innych poleceń  ->  Pozycja1 ustawienie wysokości i zapis(i tyle) może wydawać się to prymitywne ale to dość proste i eliminuje pomyłkę .

Być może się mylę, to proszę mnie poprawić i skorygować moje rozumowanie dlaczego jest złe 😉

Co do mojego traktorka to prezentuje się tak 😄

Silnik z przekładnią i patykiem jako ramię,przekaźniki jako rozdzielacz hydrauliczny i super pająk z przyciskami jako pseudo sterownik. 

 

foto.jpg

Link do komentarza
Share on other sites

52 minuty temu, Waldy napisał:

używam przełącznika obrotowego 4 pozycyjnego

I to całkowicie wszystko zmienia.

Po jakiego grzyba tam cztery jakieś stany? A nie może to być jedna uczciwa zmienna, nazwijmy ją "wajcha". Pozostawmy debouncery (bo nie przeszkadzają) i spróbujmy ustalić położenie wajchy. Pozwolę sobie jednak zmienić nazwy debouncerów na jakieś bardziej przyjazne. Fragment kodu:

// gdzieś na początku

enum {
  WAJCHA_USTAW = 1,
  WAJCHA_REGULACJA = 2,
  WAJCHA_DOJAZD = 4,
  WAJCHA_ZEWN = 8
  }; 

//a w funkcji realizującej odczyt z klawiatury:

wajcha = 0;
if (!poz1.read()) wajcha |= WAJCHA_USTAW;
if (!poz2.read()) wajcha |= WAJCHA_REGULACJA;
if (!poz3.read()) wajcha |= WAJCHA_DOJAZD;
if (!poz4.read()) wajcha |= WAJCHA_ZEWN;

// w tym miejscu w "wajcha" mamy albo pojedynczy bit odpowiadający
// stanowi przełącznika, albo nieinteresujący nas stan przejściowy
// Czyli obsługujemy interesujące nas stany:

switch (wajcha) {
  case WAJCHA_USTAW:
    // tu kod dla pierwszej pozycji
    break;
  case WAJCHA_REGULACJA:
    // tu kod dla pierwszej pozycji
    break;    
  case WAJCHA_DOJAZD:
    // tu kod dla pierwszej pozycji
    break;
  case WAJCHA_ZEWN:
    // tu kod dla pierwszej pozycji
    break;
}

// i nie ma żadnej zupy

Teraz spróbujmy zrealizować zapis do EEPROM-u, czyli kolejny fragment kodu:

case WAJCHA_USTAW:
    if (zapis_dol.fell()) return CMD_ZAPISZ_DOL;
    if (zapis_gora.fell()) return CMD_ZAPISZ_GORA;
    if (!jazda_dol.read()) return CMD_JAZDA_RECZNA_DOL;
    if (!jazda_gora.read()) return CMD_JAZDA_RECZNA_GORA;
    return 0;

i w ten sposób w pętli loop() mamy coś bardzo prostego:

switch(cmd) {
    case CMD_ZAPISZ_DOL:
    // kod zapisu do EEPROMU
    break;
    
    case CMD_ZAPISZ_GORA:
    // kod zapisu do EEPROMU
    break;
    
    // i tak dalej

Nie ma siedemnastu stanów (które w Twoim przypadku zresztą nie są żadnymi stanami, bo je ręcznie zmieniasz). Nie ma delajów po sekundzie. Nie ma zupy. Masz pełne rozdzielenie funkcji czytania klawiatury i jazdy. Uwierz mi - funkcję realizującą jazdę niewiele interesuje czy został przyciśnięty klawisz zielony czy czerwony, tylko czy ma jechać i dokąd. Funkcja realizująca czytanie klawiatury nie jest absolutnie zainteresowana jakimiś cewkami i innymi zaworami - ona wie tylko że jak użytkownik kazał jechać to ma zwrócić wynik "kazali jechać". Wszystko...

A teraz jak będziesz chciał dorobić zdalne sterowanie, ty wystarczy drobna zmiana w funkcji readKeyboard(), i to tylko w obrbie jednej gałęzi switcha... czyż to nie jest proste? 🙂

 

1 godzinę temu, Waldy napisał:

Co do mojego traktorka to prezentuje się tak

Owszem, na dzisiaj 🙂

 

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

Witam to znowu ja 😉

Teraz trochę coś z innej pułki nie chciałem spamować forum nowym wątkiem,chociaż wydaje się ciekawy  czyli coś o bezpieczeństwie a konkretnie software'owa krańcówka.

Chciałbym taką opcję mieć bo wiadomo różnie to bywa. Tutaj mam parę pytań:

- Czy jest możliwość realizacji takiej krańcówki omijając przerwanie i czy jest to "zgodne ze sztuką" . Mam tu na myśli to że przerwanie realizuje się "nadrzędnie" i czy jest możliwość wywołania przerwania  z poziomu programu np. jeżeli pozycja >= 0  to bach przerwanie w którym miga dioda dół i cewka dół jest wyłączona.

- Czy jak krańcówka była by zrealizowana jako zwykły warunek if w pętli loop jak by to się miało do momentu w którym zostaje osiągnięta  i przekroczona pozycja 0 (podczas np. regulacji pozycji) co zostanie wykonane najpierw; Czy warunek w którym reguluje pozycje i dajmy na to że przejdzie 0 (urywając potencjometr) i potem dopiero program dojdzie do linijki kodu w którym sprawdza pozycje dla krańcówki (zakładając że program wykonuje się linijka po linijce) 

Pytam dlatego że do ustawiania pozycji góra/dół używam potencjometru a jako czujnik położenia też jest potencjometr(wersja bieda edyszyn :D)  i zadana pozycja 0 pokryje się z pozycją 0 na czujniku i ramie się zatrzyma. Ale do drobnej regulacji ustawionej pozycji użyłem impulsatora przerabiając przykład z biblioteki tak aby uzyskać drobną regulację w postaci 4 kroków do góry i 4 na dół i właśnie w tym wypadku może pojawić się ryzyko że zejdzie się poniżej minimalnej pozycji czujnika,zresztą pewnie nie tylko w tym wypadku no ale wypadało by takie zabezpieczenie posiadać. 

Pozdrawiam i miłej niedzieli życzę 😉 

 

Link do komentarza
Share on other sites

28 minut temu, Waldy napisał:

Czy jest możliwość realizacji takiej krańcówki omijając przerwanie i czy jest to "zgodne ze sztuką" . Mam tu na myśli to że przerwanie realizuje się "nadrzędnie" i czy jest możliwość wywołania przerwania  z poziomu programu np. jeżeli pozycja >= 0  to bach przerwanie w którym miga dioda dół i cewka dół jest wyłączona.

Przetłumacz to na jakśs zrozumiały język - dlaczego chcesz przerywać program (tzn. wywołać ręcznie przerwanie) jeśli możesz po prostu nie wywoływać przerwania a zrobić coś?

Po co tam w ogóle jakieś przerwania? Co to przerwanie miałoby robić?

W ogóle co rozumiesz przez "software'ową krańcówkę"? Kiedy ma zadziałać? Dlaczego nie możesz po prostu w ostatnich linijkach przed przekazaniem sygnału do cewek sprawdzić, czy przypadkiem nie trzeba ich wyłączyć? Ot coś w stylu:

/// wyszło wcześniej nam że "jazda" jest "w górę"

if ((jazda == W_GORE && aktualna_pozycja >= MAKSYMALNA_POZYCJA) ||
    (jazda == W_DOL && aktualna_pozycja >= MINIMALNA_POZYCJA)) jazda = STOP;

No i przede wszystkim jeśli mówimy tu o bezpieczeństwie - dlaczego nie możesz tam wsadzić normalnej uczciwej krańcówki odcinającej po prostu prąd od cewki? Poleganie na software'owych rozwiązaniach nie jest szczególnie mądre - a w sytuacji kiedy nie jesteś super-znawcą tematu (konstrukcja mikrokontrolera, język programowania, algorytmy i takie tam różne wymyślne rzeczy typu "wiem kiedy zadziała if") jest po prostu niebezpieczne.

 

 

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.