• 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
TABLICA float =>int
#21
Zajrzałem w kod i swoją drogą jest do bani. Teoretycznie 16MHz taktowania oznacza, że wykonując w pętli loop 16 podstawowych poleceń trwających 1 cykl zegara pętla będzie się wykonywać 1mln razy/sekundę.
Po co mierzysz i przeliczasz ciśnienie w każdym obiegu pętli loop? Czy jakbyś zmierzył np. raz na 10s to coś przegapisz?
No albo inaczej, zmierz w 1s, w drugiej przelicz, w trzeciej wyświetl na oled i potem powtórz cykl.
Oczywiście nie osiągniesz mln obiegów pętli/s, ale żeby program był responsywny powinno być chociaż kilkaset, super jak parę tysięcy.
Miło być decenianym https://buycoffee.to/kaczakat
 
Odpowiedź
#22
Bardzo dziękuje właśnie takie odpowiedzi są cenne ja się staram uczyć i jak widać  błądze Smile ... właśnie  zauważyłem że po wpisaniu większego "Czasu do milis  " kod się wiesza a wykonanie wyświetlania 1 raz na 0,5h faktycznie wystarczy ... nie mówiąc o całej reszcie
 
Odpowiedź
#23
Głównie chodzi o to, że mierzenie ciśnienia/temperatury , wyświetlanie ekranu itp. operacje to są bardzo czasochłonne procesy, mogą trwać od kilku do kilkuset ms. Możesz sobie mierzyć czas trwania operacji (mniej więcej) używając funkcji micros(). Jedną taką operacją powodujesz, że funkcja do przycisków, starająca się oszacować jak długo w ciągu 30ms przycisk był wciśnięty i czy uznać to za wciśnięcie/puszczenie przycisku przestaje działać.
Miło być decenianym https://buycoffee.to/kaczakat
 
Odpowiedź
#24
ok a więc na przykładzie powiedzmy co 2sek pomiar (odświeżenie Temp. i Pres. ) i wyrzut na ekran
Przyciski w głównej pętli "latają" bez czasu
Powiedzmy co 3000 000 ms wyrzut do wykresu na ekran linii wyliczonej z odświeżonej ( Temp i Pres) co 2s

Co z przyciskami latają luzem w pętli głównej można by je " aktywować " co mniej niż 5 ms z powodu czasu
debouncerB.interval(5);
 
Odpowiedź
#25
Pokaż kod, tak by było wiadomo co masz na myśli. Nie wrzucaj linku do github tylko wklej tu jako kod - pełna edycja, ikona <>.
Przyciski, to czy tam wstawisz 5 czy 50 zależy jakiego sprzętu użyłeś. Powinieneś mieć kod tylko z przyciskiem danego typu i led, przyciskiem włączać i wyłączać led. Czas dobierasz tak, by wciśnięcie ni mniej ni więcej odpowiadało przeciętnemu wciśnięciu używanego typu buttona. Jeśli czas masz 5, a najkrótsza pętla trwa i tak 200 to nie wiesz czy 5 jest OK.
Miło być decenianym https://buycoffee.to/kaczakat
 
Odpowiedź
#26
Kod:
#include <SPI.h>
#include <Wire.h>
#include <Bounce2.h>
#include <Adafruit_GFX.h>
#include <Adafruit_BMP280.h>
#include <Adafruit_SSD1306.h>
#define ledPin6 6
#define ledPin7 7
#define BUTTON_PINA 2
#define BUTTON_PINB 3
Bounce debouncerA = Bounce();
Bounce debouncerB = Bounce();         // pdłaczenie bounce                    
//-------
unsigned long previousMillis  = 0;
unsigned long previousMillis1 = 0;    
unsigned long previousMillis2 = 0;  
//-------  
int  licznik ;                        //Zmiana podstawy cisnienia  (do testów)
int p1;float t; float p;              // T i P
int i=0;
int j;                                // ktory kolejny pomiar na  wyswietlaczu na  dole
int width =   2;                      // 2*60, 3*40 =120 szeokosc lini 1 pomiaru ekran - ilosc  probek  mieszczaca sie   na ekranie
int ProbkiINT[60] ={};                // tablica probek            - ilosc  probek  mieszczaca sie   na ekranie
int Probki =  60;                     // ilosc probek  zwiazek  z tablicami  
int Czas_Probkowania = 100 ;          // mnożnik do milis
//-------
Adafruit_BMP280 bmp;                  
#define OLED_RESET 4
Adafruit_SSD1306 display(OLED_RESET);
//++++++++++++++++++++++++++++++++++++++++++++++
void setup() {
 Serial.begin(9600);

 if (!bmp.begin(0x76))                    //Adres czujnika ,czy jest
 {
   Serial.println(F("Check wiring!"));
   while (1);
 }
 
 pinMode(ledPin6,OUTPUT);
 pinMode(ledPin7,OUTPUT);
 pinMode(BUTTON_PINA,INPUT_PULLUP);
 pinMode(BUTTON_PINB,INPUT_PULLUP);
 debouncerA.attach(BUTTON_PINA);
 debouncerB.attach(BUTTON_PINB);
 debouncerA.interval(5);
 debouncerB.interval(5);
 display.begin(SSD1306_SWITCHCAPVCC, 0x3C);  // Przgotowanie wyswietlacza
 display.clearDisplay();
 display.display();
}
//++++++++++++++++++++++++++++++++++++++++++++++
void loop()
{
   unsigned long Millis1 = millis();                      
         if ( Millis1 - previousMillis1 >=  (5000))      //Wczytanie co 1s T/P
           {
 /* int  */    p1= ((bmp.readPressure()/100)+licznik);  
/*float */     p=  ((bmp.readPressure()/100)+licznik);  
               t=  (bmp.readTemperature());
           previousMillis1 = Millis1 ;
           }
//-------        
   unsigned long Millis2 = millis();                     //Print T/P
         if ( Millis2 - previousMillis2 >=  (10000))
           {
   mig(ledPin7);                                         //mignij przy wyswietleniu
            display.setTextColor(WHITE, BLACK);

           //  display.setCursor(10,36);  display.print(j);
           
             if ( p1> 1032 or p1 < 970) { display.fillRect(0,0, 120,64,BLACK); }  //czarny ekran if... z wartosciami
         
                  if ( p1>=1000)  //Jesli wieksze liczby T/P na  ekranie  na dole  
                              {
                                  if ( p1>=1000 and p1<=1002) { display.fillRect(0,0, 124,11,BLACK); }  //kasowanie resztek liczby po przeniesieniu
                                  display.setCursor(68,57);  display.print(p,1); display.print("hPa");
                                  display.setCursor(0,57);  display.print(t,1);  display.print("C");  
                              }
                              if ( p1<1000)  //Jesli mniejsze liczby T/P na  ekranie  na gorze  
                              {
                                  if ( p1<1000 and p1>=998  ) { display.fillRect(0,57, 124,11,BLACK); }  
                                  display.setCursor(68,0);  display.print(p,1); display.print(" hPa");
                                  display.setCursor(0,0);  display.print(t,1);  display.print("C");
                              }
                   display.display();     // Wyswietl na  ekran
           previousMillis2 = Millis2 ;
           }

//-------

 debouncerA.update();
 debouncerB.update();                           // przyciski - ,  +  do podsatawy

      int valueA = debouncerA.fell();    
      int valueB = debouncerB.fell();
            if ( valueA == LOW){
                 licznik --;
            }  
            if ( valueB == LOW) {
                 licznik ++;
               }

unsigned long Millis = millis();
   if ( Millis - previousMillis >=  (720000)) //  720000 pomiar co 12 min  60 pomiarów to 12h działka na ekranie to 1h
   {
   //  j++;                                   // ktory to pomiar
  mig(ledPin6);                               // mignij przy odczycie do tablicy                  
  WczytajTablicePrzesun( p1, ProbkiINT);  
  int w = - width ;                           // ustawia  początek startu wykresu
       for(int i=0;i<Probki;++i)              // wyswietla  tablice  do wykresu
      {                                       //wykres  ze skalowaniem w zaleznosci od  cisnienia 1hPa 2pix or 1pix                          
          w = w+width;                        //przesowanie  wykresu
        if ( p1>=985 and p1 <= 1016)          // 1016 to szczyt wyswietlacza  16*2 mnoznik pol wyswietlacza 1hPa to dwa pix
        {                                     // 3  tablice 3  czesci słupek czarny gorny linia  biala czarny dolny
            display.fillRect(w, 0    , (width),( (1016-ProbkiINT[i])*2),BLACK);     //*2 mnoznik splyca wykres  
            display.fillRect(w,((1016-ProbkiINT[i])*2), (width),1  ,WHITE);  
           display.fillRect(w,((1016-ProbkiINT[i]+ 1)*2) , (width)   , (64-((1016-ProbkiINT[i]+1)*2))   ,BLACK);  
        }
        if((p1>969 and p1<985 )or(p1>1016 and p1<1032))  //po wyjsciu z  zakresu 1pix  to 1hPa zmiana  wysokosci wykresu
        {
           display.fillRect(w, 0    , (width), (1032-ProbkiINT[i]),BLACK);      
           display.fillRect(w,(1032-ProbkiINT[i]), (width),1  ,WHITE);        // linia white  pomiaru szerokosc 2
           display.fillRect(w,(1032-ProbkiINT[i]+ 1) , (width)   , (64-(1032-ProbkiINT[i]+1))   ,BLACK);  
        }
        previousMillis = Millis ;
      }          
   }
//-------
grid();
//-------
}
//++++++++++++++++++++++++++++++++++++++++++++++
void grid ()                   //siatka na ekranie 12h
{
     for(i=0;i<=120;i=i+10)
   {        
     display.drawPixel(i,12,WHITE);
     display.drawPixel((i),32,WHITE);
     display.drawPixel(i,52,WHITE);
   }
}
//-------
void mig(int led)                // mig
{
     digitalWrite(led,HIGH);  
     unsigned long time_mig = millis();                
        while(millis() < time_mig + 25)
        {}                              
     digitalWrite(led,LOW);
}
void WczytajTablicePrzesun(int pressure,int P[] )
   {
     for(int i = (Probki-1); i > 0 ; i--)
      {
         P[i] = P[i-1];
      }
         P[0] =  pressure;
   }


A więc czyta p/t co 5s co 10s aktualizuje na  ekranie  p/t co 12 minut przebudowuje wykres 60 pomiarów  
na 12h przyciski cały czas luzem  w pętli loop pare  aspektów poprawiłem od  ostatniego kodu...

Najlepiej takie  kody ogląda się w  SUBLIME TEXT ... są czytelne na  stronie nie widać  nic gdyby chciał się ktoś  zagłębić

https://github.com/maniek3716/CODE/blob/master/Hpa_ver13   - tu jest link do KODU
 
Odpowiedź
#27
W ostatnich moich postach jest przykład użycia WDT, 3 dodatkowe linijki i program może działać nieco pewniej. W innych jest funkcja czas, nie musisz sprawdzać czy minęło 720tys ms, wystarczy wtedy odwołanie do minut/sekund. Liczby które są większe od int trzeba odpowiednio przedstawiać w programie, np. UL, L, 720000L.
Miło być decenianym https://buycoffee.to/kaczakat
 
Odpowiedź
#28
Pdepnę sie trochę co te UL i L oznaczają ? czy muszą być ? w przykładach ciagle jest własnie tak pisane wiec czym się różni int 2000 od 2000L i UL ?? wiem że to LONG i U LONG skoro funkcja Millis() zwaraca UL to po co używać L??
Arduino zostało wymyślone po to, by robić dobrze jedną prostą rzecz – migać diodą. 
 
Odpowiedź
#29
Kompilator lubi upraszczać, jest coś nazywane promocją do int i wyniki obliczeń mogą czasami być inne niż się spodziewamy. W millis też to występuje. Dlatego przestaje działać odmierzanie czasu po 50 dniach z millis, trzeba porównanie zapisać tak, by wynik był zawsze dodatni:

Kod:
if((uint32_t)(czasTeraz-czasPoprzedni)>=1000UL) //tan napisany warunek jest odporny na "klątwe 50 dni millis()"

Pomimo, że jest działanie na dwóch uint32_t wynik normalnie jest traktowany jako int, liczba ujemna i już nigdy warunek by się nie spełnił bez tego wymuszenia (uint32_t). Czy tu faktycznie UL jest potrzebny nie wiem, może wystarczy rzutowanie na uint32_t.
Miło być decenianym https://buycoffee.to/kaczakat
 
Odpowiedź
#30
#include <avr/wdt.h>
volatile int i=1;
void wdt_init()
{
  cli();
  wdt_reset();
  MCUSR &= ~(1<<WDRF);
  WDTCSR |= (1<<WDCE) | (1<<WDE);
  WDTCSR =  (1<<WDP0) | (1<<WDP3) | (1<<WDIE);
  sei();

}
void setup()
{
  Serial.begin(9600);
  wdt_init();
}
 
void loop()
{
  if (i>8 )  {i=0;} 
  Serial.print(i);
  JAK wartosc 8  coś tam coś tam  8*8 s  i w  kółko 

}

ISR(WDT_vect)
{
  i++;   
}


Bardzo potężne narzędzie "WDT" na biurku leży zegar RTC i czeka na swój czas :D

Co do ul i l w kodzie parę postów wyżej używałem mnożnik sekundowy razy milis, aby ułatwić zapis (ludzki)
zawsze kończyło się to w jeden sposób... Gleba bezpośrednio po wczytaniu programu.Ul i l pomagało, ale pomysł zarzuciłem (nieludzki zapis 750 000 wystarczył)

Tu panowie też mieli wątpliwości
https://forum.arduino.cc/index.php?topic=190752.0
 
Odpowiedź
  


Skocz do:


Przeglądający: 1 gości