• 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
Czar "0" z przodu...
#1
Moi drodzy,
mam średnia wiedze na temat programowania, ale napisałem juz kilka programów nawet działających, ale prostacko...

chciałem zrobić tak, żeby monitor wyświetlał w przypadku mniejszej liczby od 10 "0" z przodu, ale mi nie wychodzi to...

Monito r ma podawać np czas działania programu w zapisie podobnym: 01:15 min 

Załozyłem, że będzie zmienna char 2liczby[2] i że jak będzie liczba <10 to 2liczby[0] = "0", a 2liczby[1] wartość tej liczby...

Napisałem taki kod (jeden z wariantów, ale żaden nie zadziałała:

Kod:
//Monitor
char rzad16a[16];
char rzad16b[16];
char pole3[4];
char pole2[2];

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
}

void pole2w1(float zmienna){ //2 liczby do wyświetlenia (tylko dodatnie)
    char zero = "0";
   
  if(zmienna<=9){
      pole2[0] = zero;  
      pole2[1] = zmienna;
  }else{
      dtostrf(zmienna, 2, 0, pole2);
        } 
     
  //strcpy(pole2, wynik);
  //return wynik;
  }


void loop() {
  // put your main code here, to run repeatedly:
    float temperatura1 = 31.2;
    pole2w1(temperatura1);
    //Serial.print("1: ");
    Serial.print(pole2[0]);
    //Serial.print("\t 2: ");
    Serial.print("\t");
    Serial.print(pole2[1]);
    Serial.print("\n");
}

Kompilator twierdzi, że błedem jest zapis: char zero = "0"; Why? Gdy napiszę: pole2[0] = "0"; - to to samo, że to bład?

Dlaczego? Co mam robić, aby było dobrze?

A! Monitor mam 16x2 dlatego takie założyłem dwie tablice.

Tak samo nie rozumiem, czemy nie da dary zapisać: dtostrf(zmienna, 2, 0, pole2[1]); ? Taki ze mnie słabiak...

Pomocy!
Nie chcę wiecznie pisac prymitywnie, jak do tej pory, a pomocy w tutorialach szukałem bezowocnie...

Dzieku za wszwelkie podpowiedzi Smile
Pozdrawiam


Spróbowałem zrobić z tego funkcję, która zwraca tablice 2 elementową char... też kompliator uznał, że błędem jest końcowy zapis: return "tablica"...  - nie można zwracać tablicy?


Teraz błędy są takie: 
warning: invalid conversion from 'char' to 'char*' [-fpermissive]

          strcat(tmptxt1, tmptxt2);
i
note:  initializing argument 1 of 'char* strcat(char*, const char*)'

extern char *strcat(char *, const char *);


Natomiast taki zapis: tmptxt2[0] = 0; kompilator toleruje, a przwcie z to jest tablica char!!!! Why?
 
Odpowiedź
#2
Nie wiem co kombinujesz bo dla mnie to trochę nieczytelne co kombinujesz.

Ale:

char zero = "0"; - jest błędem powinno być char zero = 0; bo chcesz definiować trzy znaki w jednym "" to się liczy jako znaki.
Arduino zostało wymyślone po to, by robić dobrze jedną prostą rzecz – migać diodą. 
 
Odpowiedź
#3
(09-02-2023, 20:07)Jarewa0606 napisał(a): Nie wiem co kombinujesz bo dla mnie to trochę nieczytelne co kombinujesz.

Ale:

char zero = "0";  - jest błędem powinno być char zero = 0;  bo chcesz definiować trzy znaki w jednym "" to się liczy jako znaki.

Dzięki. Jednak jak wpisze się 0 (gołe) to nic nie wyswieltla, a ja chciałem wyśfietlać 0... w tym miejscu (bo zdaje sie znak \0 - to znak końca?)


I tak, jak zrobię tak:

Kod:
    if(pole3[0]==0){wpis = 0;}else{wpis=pole3[0];}
    Serial.print(wpis);
wyśfietla pustkę, zero wyświetla tylko gdy tak napiszę:

Kod:
    if(pole3[0]==0){wpis = 0;}else{wpis=pole3[0];}
    Serial.print("0");
Niepraktyczność polega na tym, że jak mam w tekście (tablicy) spację lub 0 to wtedy także tam gdzie spacja jest - wpisze 0?
 
Odpowiedź
#4
(09-02-2023, 20:07)Jarewa0606 napisał(a): Nie wiem co kombinujesz bo dla mnie to trochę nieczytelne co kombinujesz.

Ale:

char zero = "0";  - jest błędem powinno być char zero = 0;  bo chcesz definiować trzy znaki w jednym "" to się liczy jako znaki.

Kombinuję zapis: 01:51 / 2h
 
Odpowiedź
#5
No toś chłopie sobie życie skomplikował...

Na początek problem z char zero = "0"
Deklarujesz char, a przypisujesz mu stringa.
Albo robisz char *zero = "0" i wtedy masz tzw. C string, czyli po prostu tablicę, albo piszesz char zero = '0' i przypisujesz zmiennej typu char pojedynczy znak.
" " oznacza stringa (char array), a ' ' pojedynczy znak.


Cytat:Tak samo nie rozumiem, czemy nie da dary zapisać: dtostrf(zmienna, 2, 0, pole2[1]); ? Taki ze mnie słabiak...
Zmienną o minimalnej szerokości 2 pól, o 0 pól po przecinku pakujesz do pole2[1], które jest pojedynczym znakiem. Czyli dwa pola pakujesz w jedno z uporem maniaka i kompilator robi fakap.



Cytat:warning: invalid conversion from 'char' to 'char*' [-fpermissive]
Tu podobnie - używasz char (pojedynczego znaku), a funkcja przyjmuje char*, czyli tablicę znaków, a właściwie wskaźnik do pierwszego elementu tablicy. Funkcja, której użyłeś char *strcat (char* strTo, const char* strFrom) przyjmuje C stringi jako parametry.


Rozwiązanie Twojego problemu może okazać się dobrze użyte polecenie sprintf.
Jak tego dokonać? Przeanalizuj sobie kod poniżej i poczytaj o znakach formatu typu %d, %f, %s itd.
Kod:
int main()
{
    char array[11]; // tablica długości potrzebnej do zmieszczenia wszystkich znaków (plus 1 na '\0')
    int godziny = 7;
    int minuty = 12; // zmienne
    sprintf(array, "%02d:%02d / %ch", godziny, minuty, '2'); // wpisanie ciągu znaków zgodnie z formatem w cudzysłowie
    printf("%s", array); // wyświetlenie tablicy (dla Arduino może być Serial.println(array))
    return 0;
}
 
Odpowiedź
#6
Można sobie użyć gotowej funkcji sprintf, np. taki kod:
Kod:
//sprintf - formatowanie do bufora  http://mikrokontrolery.blogspot.com/2011/02/printf-instrukcja-rodzina.html
/*
*  flash/RAM
* Sprintf 3646/223 - + 1300flash i bufor
kolejna linijka z Sprintf 3708/223
Skrótem 2340/201
Pelny z F 2460/199
Pelny bez F 2390/203

*
*/
uint32_t czasTeraz,czasPoprzedni,tik=10; //tik musi byc mniejszy niz 1000 i dzilic 1000ms na rowne czesci
uint8_t nTik,sekundy,minuty,godziny,dni; //liczniki tikow, sekund, itd.
bool fnTik,fsekundy,fminuty,fgodziny,fdni; //flagi zdarzen nowy tik, nowa sekunda,minuta, godzina, dzien
char napis[10];
void setup() {
  // put your setup code here, to run once:
Serial.begin(115200);
pinMode(LED_BUILTIN,OUTPUT);

}

void loop() {
  // put your main code here, to run repeatedly:
czas();






if(fsekundy) {
sprintf(napis,"%03d:%02d:%02d",godziny,minuty,sekundy);
Serial.println(napis);


}

if(fnTik&&! (nTik%20)) digitalWrite(LED_BUILTIN,! digitalRead(LED_BUILTIN));//gdy nowy tik i co 20 tikow
}


void czas()
{
  czasTeraz=millis();
fnTik=fsekundy=fminuty=fgodziny=fdni=0;
if((uint32_t)(czasTeraz-czasPoprzedni)>=tik) //tan napisany warunek jest odporny na "klątwe 50 dni millis()"
{
  czasPoprzedni=czasTeraz;
  fnTik=1;
  nTik++;
  if(nTik>=(1000/tik))
  {
    nTik=0;
    sekundy++;
    fsekundy=1;
     if (sekundy>=60)
    {
      sekundy=0;
      minuty++;
      fminuty=1;
      if (minuty>=60)
      {
        minuty=0;
        godziny++;
        fgodziny=1;
        if (godziny>=24)
        {
          godziny=0;
          fdni=1;
          dni++;
   
        }
      }
    }
  }
}
}
W efekcie daje wydruk co 1s:
000:00:01
000:00:02
000:00:03
itd.
Miło być decenianym https://buycoffee.to/kaczakat
 
Odpowiedź
#7
(09-02-2023, 21:56)MadMrQ napisał(a): No toś chłopie sobie życie skomplikował...

Na początek problem z char zero = "0"
Deklarujesz char, a przypisujesz mu stringa.
Albo robisz char *zero = "0" i wtedy masz tzw. C string, czyli po prostu tablicę, albo piszesz char zero = '0' i przypisujesz zmiennej typu char pojedynczy znak.
" " oznacza stringa (char array), a ' ' pojedynczy znak.


Cytat:Tak samo nie rozumiem, czemy nie da dary zapisać: dtostrf(zmienna, 2, 0, pole2[1]); ? Taki ze mnie słabiak...
Zmienną o minimalnej szerokości 2 pól, o 0 pól po przecinku pakujesz do pole2[1], które jest pojedynczym znakiem. Czyli dwa pola pakujesz w jedno z uporem maniaka i kompilator robi fakap.



Cytat:warning: invalid conversion from 'char' to 'char*' [-fpermissive]
Tu podobnie - używasz char (pojedynczego znaku), a funkcja przyjmuje char*, czyli tablicę znaków, a właściwie wskaźnik do pierwszego elementu tablicy. Funkcja, której użyłeś char *strcat (char* strTo, const char* strFrom) przyjmuje C stringi jako parametry.


Rozwiązanie Twojego problemu może okazać się dobrze użyte polecenie sprintf.
Jak tego dokonać? Przeanalizuj sobie kod poniżej i poczytaj o znakach formatu typu %d, %f, %s itd.
Kod:
int main()
{
    char array[11]; // tablica długości potrzebnej do zmieszczenia wszystkich znaków (plus 1 na '\0')
    int godziny = 7;
    int minuty = 12; // zmienne
    sprintf(array, "%02d:%02d / %ch", godziny, minuty, '2'); // wpisanie ciągu znaków zgodnie z formatem w cudzysłowie
    printf("%s", array); // wyświetlenie tablicy (dla Arduino może być Serial.println(array))
    return 0;
}

Bardzo, bardzo dziekuję Smile Jak dla mnie genialne Smile Super.
 
Odpowiedź
#8
(09-02-2023, 21:58)kaczakat napisał(a): Można sobie użyć gotowej funkcji sprintf, np. taki kod:
Kod:
//sprintf - formatowanie do bufora  http://mikrokontrolery.blogspot.com/2011/02/printf-instrukcja-rodzina.html
/*
*  flash/RAM
* Sprintf 3646/223 - + 1300flash i bufor
kolejna linijka z Sprintf 3708/223
Skrótem 2340/201
Pelny z F 2460/199
Pelny bez F 2390/203

*
*/
uint32_t czasTeraz,czasPoprzedni,tik=10; //tik musi byc mniejszy niz 1000 i dzilic 1000ms na rowne czesci
uint8_t nTik,sekundy,minuty,godziny,dni; //liczniki tikow, sekund, itd.
bool fnTik,fsekundy,fminuty,fgodziny,fdni; //flagi zdarzen nowy tik, nowa sekunda,minuta, godzina, dzien
char napis[10];
void setup() {
  // put your setup code here, to run once:
Serial.begin(115200);
pinMode(LED_BUILTIN,OUTPUT);

}

void loop() {
  // put your main code here, to run repeatedly:
czas();






if(fsekundy) {
sprintf(napis,"%03d:%02d:%02d",godziny,minuty,sekundy);
Serial.println(napis);


}

if(fnTik&&! (nTik%20)) digitalWrite(LED_BUILTIN,! digitalRead(LED_BUILTIN));//gdy nowy tik i co 20 tikow
}


void czas()
{
  czasTeraz=millis();
fnTik=fsekundy=fminuty=fgodziny=fdni=0;
if((uint32_t)(czasTeraz-czasPoprzedni)>=tik) //tan napisany warunek jest odporny na "klątwe 50 dni millis()"
{
  czasPoprzedni=czasTeraz;
  fnTik=1;
  nTik++;
  if(nTik>=(1000/tik))
  {
    nTik=0;
    sekundy++;
    fsekundy=1;
     if (sekundy>=60)
    {
      sekundy=0;
      minuty++;
      fminuty=1;
      if (minuty>=60)
      {
        minuty=0;
        godziny++;
        fgodziny=1;
        if (godziny>=24)
        {
          godziny=0;
          fdni=1;
          dni++;
   
        }
      }
    }
  }
}
}
W efekcie daje wydruk co 1s:
000:00:01
000:00:02
000:00:03
itd.



Bardzo, bardzo dziekuję. Jeszcze u mnie
nie zadziałało, ale pracuje nad tym Smile
 
Odpowiedź
#9
Mam jeszcze pytanie...
chciałem napisać mijający czas procentowo, na przykładzie niżej:
      int czas_pozostaly_proc = (klepsydra_sek/sekundy_ustaw)*100;
      co jest de facto:
int czas_pozostaly_proc  = (100/3600)*100;

i obie operacje daja mi wynik 0... why????

ktoś wie?

jak zostawię: 100/3600 i zrobię ze zmiennej "czas_pozostaly_proc" double, to mam: 0.00 nie rozumiem...

kombinuję z typami danych, ale nie wychodzi... za duży jest dzielnik?

Jak sie domyslacie:
klepsydra_sek - narasta
a sekundy_ustaw - jest stała po ustawieniu...


hm... tylko raz wyświetliło prawidłowy wynik, jak było 100% gdzieś zaokrągla?
 
Odpowiedź
#10
int czas_pozostaly_proc = (klepsydra_sek/sekundy_ustaw)*100;
co jest de facto:
int czas_pozostaly_proc = (100/3600)*100;


Pewnie klepsydra_sek i sekundy_ustaw to zmienne całkowite, wiec masz źle i nawet ustawienie

float czas_pozostaly_proc = (klepsydra_sek/sekundy_ustaw)*100;

Nic nie zmieni bo przy obliczeniu nie wie że wynik jest float. I będzie liczył liczby całkowite gdzie:

100/3600 = 0 a 0*100 = 0.

Musisz mu to wskazać zrub rzutowanie

float czas_pozostaly_proc = (float(klepsydra_sek/sekundy_ustaw)*100);
Arduino zostało wymyślone po to, by robić dobrze jedną prostą rzecz – migać diodą. 
 
Odpowiedź
  


Skocz do:


Przeglądający: 1 gości