• 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
Zliczanie impulsów prosty przykład
#11
Coś mi na esp32 przerywania nie wychodzą.  Bo głównym problemem jest to ze pętla tylko raz ma się wykonać i dać wynik. Wiec włączanie wyłączanie nie mogę jakoś ogarnąć. A z drugiej strony i tak bym musiał zamrozić procesor bo pętla jak wyżej pisałem wykonuje się tylko raz. Wymysliłem tez taki kod to tylko przykład do mojego docelowego paragramu ważne jest tylko viod licznik() fakt że zamraża to procesor na 1s  ale mam jeszcze drugi przykład gdzie odczyt stanu pinu jest w "if" nie while wtedy procesor nie jest zamrożony .

Kod:
int pinLicznik = 34;
boolean stanPin = false;
int ostatni_stan_Pin = HIGH;
unsigned long Tims_ = millis();
unsigned long iloscImpulsow = 0;
boolean wynik = false;

void setup() {
 Serial.begin(9600);
 pinMode(pinLicznik, INPUT);
}

void loop() {
 licznik();

if (wynik== true){
 Serial.println(iloscImpulsow);
 
 wynik=false;
}
}

void licznik(){  
iloscImpulsow = 0;
Tims_=millis();

while (millis() - Tims_ <= 1000){
     
    int odczytPin = digitalRead(pinLicznik);
   
    if (odczytPin != ostatni_stan_Pin){
       
     
        if ( odczytPin ==  LOW && stanPin == true ){
             iloscImpulsow++;
             stanPin=false;
            }
        if ( odczytPin == HIGH && stanPin == false){
            stanPin= true;
           }
        }
         ostatni_stan_Pin=odczytPin;
   }
   
      wynik = true;
   
}

Działa w sumie poprawnie od 0 do 150kHz  czy to ma jakieś wady??
Arduino zostało wymyślone po to, by robić dobrze jedną prostą rzecz – migać diodą. 
 
Odpowiedź
#12
Nie bardzo wiem co tam masz do ogarnięcia z przerwaniami, wpisujesz w google i pojawiają się przykłady. W AVR trzeba pamiętać, że obsługą przerwania zajmuje się funkcja void, czyli procedura. W ESP32 pewnie jest tak samo.
Przykład jest np. tu: https://randomnerdtutorials.com/esp32-pi...ts-timers/
Twój kod nie ma wad jeśli jedyne co ma robić to zliczyć te impulsy, jeśli ma robić różne rzeczy w tym samym czasie (prawie) to po to właśnie wymyślono timery/millis i przerwania.
Miło być decenianym https://buycoffee.to/kaczakat
 
Odpowiedź
#13
A czy możesz luknąć na to czy są jakieś podstawowe błedy?

Kod:
unsigned int pinLicznik = 34;
unsigned long impulsy = 0;
unsigned long Tims_ =0 ;
volatile int read_data_ = 0;
volatile boolean on_data = true;
volatile unsigned long iloscImpulsow = 0;


void setup() {
 Serial.begin(9600);
 pinMode(pinLicznik, INPUT_PULLUP);
//  attachInterrupt(digitalPinToInterrupt(pinLicznik), licznik, FALLING);

}

void loop() {

if(on_data == true){
  attachInterrupt(digitalPinToInterrupt(pinLicznik), licznik, FALLING);
}
 if(read_data_== 1){
   Serial.println(iloscImpulsow);
   read_data_= 0;
 }
}

void licznik() {

if(millis()-Tims_< 1000){     // zliczanie impusow przez 1 sekunde
 impulsy++;
 }else{                      
   Tims_=millis();           // ponowne zliczanie impulsow przez 1 sekunde
   iloscImpulsow=impulsy;    // zapisanie licznik impulsow do bufora
   impulsy=0;                // zerowanie licznika by od nowa liczylo
   read_data_++;             // zmienna czy bufor ilosciImulsow jest wykorzystywany
 }
if(read_data_ >= 10){        // jezeli bufor ilosciImulsow jest nie wykorzystywany wylaczenie przerywania 10s czeka
  detachInterrupt(digitalPinToInterrupt(pinLicznik));
}
on_data = false;
}

Loop nie traktuj  jak typowego ardunio, to będzie zapytanie wyświetlacza o dane wykonuje się według timera  np co 1s lub 0,5s. 

W sumie tak zyskuje bo wtedy nie czeka na dane ale pierwszy zawsze bedzie pusty
Arduino zostało wymyślone po to, by robić dobrze jedną prostą rzecz – migać diodą. 
 
Odpowiedź
#14
Nie wiem co tam kombinujesz z tym LCD, taka idea, że masz coś odczytywać przez dłużej niż ms jest dla mnie dziwna i to  może słabo działać. Zawsze powinno się w takim miejscu zrobić jakieś odliczanie, że jak zapytasz a nie ma odpowiedzi przez wyznaczony czas to przerywasz. 
if(millis()-Tims_< 1000) tą linijkę też robię w jeden niezmienny sposób. Wszystko w kodzie domyślnie jest INT, inny INT w AVR inny w ESP, ale w każdym ze znakiem. Jest domyślna "promocja do int". I to może wywalić po jakimś czasie zliczanie. 

Kod:
uint32_t poprzedni; //jako zmienna globalna
{
uint32_t teraz=millis();//w bloku programu z warunkiem
if ((uint32_t) (poprzedni-teraz)>=1000UL) //rzutowanie na UL nie zatrzyma programu po przekreceniu licznika
{
poprzedni=teraz;
}
}
(poprzedni-teraz) - jeśli wynik tego zostanie potraktowany jako INT to program się sypnie i przez kolejne pętle już nic się nie wydarzy.Nie twierdzę, że Twój sposób jest zły, jest inny i nie chce mi się go analizować. Możesz sobie to sprawdzić zamiast millis przypisując zmienną inkrementowaną w każdym loop i szybko potwierdzić czy po przepełnieniu zmiennej 32bitowej program dalej będzie generował spełnienie ifa. 
Wygeneruj sobie sygnał drugim Arduino i zobacz czy to działa jak oczekujesz.
Miło być decenianym https://buycoffee.to/kaczakat
 
Odpowiedź
#15
Ja mam taki chiński mini generatorek impulsów Wink i sobie testuje. Zawsze to co robię testuję długo... Na razie mam w tym tylko problem ze zmienną "volatile boolean on_data = true;" gubi mi ją...
Arduino zostało wymyślone po to, by robić dobrze jedną prostą rzecz – migać diodą. 
 
Odpowiedź
#16
No to znakomicie.
Niestety dalej strasznie kombinujesz. Oczywiście nie musisz robić tak jak napisałem, ale w #8 opisałem jak ma wyglądać funkcja przerwania:

Kod:
void licznik() {
 impulsy++;
}
Wszystko inne: decyzja czy zacząć liczyć, kontrola czasu ile to już liczysz, informowanie innych części programu o tym że liczysz lub nie, decyzja by skończyć liczyć, odczytać zmienną i ją wyzerować to już nie w przerwaniu.
Jeśli wystarcza Ci zmienna 16 bit - czyli np. uint16_t to bierz 16bit, ulong jest 32bit, może w esp nie ma to dużego znaczenia, ale co do zasady zawsze najmniejsza możliwa, pisałeś o 500Hz, pomiar przez 100ms, czyli wystarczy uint8_t, 8 bitów. Przy pomiarze prze 1s już musi być 16bit, a jeśli częstotliwość większa od 64kHz to 32bity. Chodzi o to by czas w przerwaniu był możliwie krótki, wtedy nie musisz go wyłączać, nawet jak generujesz w pętli głównej komunikację softwarową to takie przerwanie zmieni długość impulsu o kilka us i w niczym nie będzie przeszkadzać.
Miło być decenianym https://buycoffee.to/kaczakat
 
Odpowiedź
#17
No może zbyt mocno komplikuje sobie życie, ale ta funkcja może być potrzebna tylko raz na miesiąc albo i rok Wink a może sie zdarzyć ze w jakimś okresie ciągle wiec myślałem po co ma liczyć jak nie będę tego przez bardzo długi okres wykorzystywał...

To mówisz że te liczenie najlepiej przenieś jak w #8 poście pisałeś??

Ja tak pytam bo nie umiem programowania "c" nic praktycznie nie umiem jedynie 30 lat temu jako nastolatek ugryzłem trochę bascom wiec cos tam jeszcze troszkę kumam.
Arduino zostało wymyślone po to, by robić dobrze jedną prostą rzecz – migać diodą. 
 
Odpowiedź
#18
(03-04-2019, 18:58)Jarewa0606 napisał(a): "c"  nic praktycznie nie umiem jedynie 30 lat temu jako nastolatek ugryzłem  trochę bascom wiec cos tam jeszcze troszkę kumam.
To napisz w Bascom. Niech jeden timer zlicza impulsy zewnętrzne, bramkuj go drugim, po odczycie kasuj i to wszystko.

PS
Czemu "bascom" a nie "Bascom", czemu "arduino" a nie "Arduino"?
 
Odpowiedź
#19
Mam jeszcze takie pytanie bo zrobiłem jak w tym #8 było mówione i jest ok ale dałem w swoim kodzie dwa przerywania i dwa zliczania o ile każde liczenie działa osobno z pomyłką zliczania czasami do "1" przy 1kHz ale jak naraz jest uruchomione obydwa przerywania to mi się rozjeżdża chyba millis bo pomyłka już sięga "20" przy 100Hz i tak pomyłka skacze.

Jak to jest w przypadku ESP32 czy przerywanie przerywa obydwa rdzenie? czy tylko jeden gdzie było włączone przerywanie? no i druga sprawa czy podłączenie do pinu jest obojętne aby obsługiwało przerywanie czy jednak są jakieś zastrzeżenia? (mam pod GPIO33 i GPIO34).
Arduino zostało wymyślone po to, by robić dobrze jedną prostą rzecz – migać diodą. 
 
Odpowiedź
#20
(16-04-2019, 18:59)Jarewa0606 napisał(a): Mam jeszcze takie pytanie bo zrobiłem jak w tym #8 było mówione i jest ok ale dałem w swoim kodzie dwa przerywania (...)
Pokaż kod.
 
Odpowiedź
  


Skocz do:


Przeglądający: 1 gości