• 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
Problem z prostym programem
#1
int number;

void setup() {
Serial.begin(9600);
}

void loop() {
number = 0;
Serial.flush();

while(Serial.available() == 0){

}
while(Serial.available() > 0){
  number = Serial.read() - '0';     //odczytuje liczbę z bufora portu szeregowego
                                    //usuwa przesunięcie ASCII dla zera: '0'
}

Serial.print("Wpisana liczba: ");
Serial.println(number);
Serial.print(number);
Serial.print(" pomnożone przez dwa równa się ");
number = number * 2;
Serial.println(number);

delay(1000);
}


To wyświetla mi się po uruchomieniu programu i wpisaniu liczby 3.
Skąd bierze się to -38? Wyczytałem, że rejestrowane jest też wciśnięcie przycisku ENTER, ale jakim prawem odczytuje liczbę dwa razy?
Jak to naprawić?


Wpisana liczba: 3

3 pomnożone przez dwa równa się 6

Wpisana liczba: -38

-38 pomnożone przez dwa równa się -76
 
Odpowiedź
#2
(11-11-2025, 21:43)PATRO0902 napisał(a): int number;

void setup() {
Serial.begin(9600);
}

void loop() {
number = 0;
Serial.flush();

while(Serial.available() == 0){

}
while(Serial.available() > 0){
  number = Serial.read() - '0';     //odczytuje liczbę z bufora portu szeregowego
                                    //usuwa przesunięcie ASCII dla zera: '0'
}

Serial.print("Wpisana liczba: ");
Serial.println(number);
Serial.print(number);
Serial.print(" pomnożone przez dwa równa się ");
number = number * 2;
Serial.println(number);

delay(1000);
}


To wyświetla mi się po uruchomieniu programu i wpisaniu liczby 3.
Skąd bierze się to -38? Wyczytałem, że rejestrowane jest też wciśnięcie przycisku ENTER, ale jakim prawem odczytuje liczbę dwa razy?
Jak to naprawić?


Wpisana liczba: 3

3 pomnożone przez dwa równa się 6

Wpisana liczba: -38

-38 pomnożone przez dwa równa się -76

Bo funkcja loop(), jak to nawet wynika z nazwy, wywoływana jest ciągle, w zewnętrznej pętli. Program na takim procesorku w zasadzie się nie kończy - działa aż do wyłączenia zasilania. Dobrą praktyką jest pisanie wnętrza funkcji loop tak by wykonywała pojedynczy krok przetwarzania, nie umieszczanie całego przetwarzania w jednym przebiegu tej funkcji. Ale to trochę trudniejsze, trzeba opanować automaty stanów.
Pokazany program najpierw czeka na jakieś dane na serialu a potem czyta i ostatni znak zamienia na liczbę i wykonuje tą całą zabawe. Przy prędkości procka i seriala oznacza to praktycznie wczytanie jednego znaku - ale program natychmiast zaczyna od nowa.

Ta druga pętla jest nieużyteczna, chyba że ten serial nie jest fizycznym serialem a czyms co przesyła dane pakietami. 

Bardziej interesująco byłoby przerobić ten program by czytał liczbę składającą się z wielu znaków/cyfr a naciśniecie ENTER oznaczałoby polecenie wypisania wyniku.

Dla wyjaśnienia wyniku musisz wiedzieć że kod cyfry '0' to 48 a ENTER to 10 albo 13 w zależności od ustawień terminala. Jak widać u ciebie jest 10. 10-48 daje -38.
 
Odpowiedź
#3
(13-11-2025, 07:51)oscarX napisał(a):
(11-11-2025, 21:43)PATRO0902 napisał(a): int number;

void setup() {
Serial.begin(9600);
}

void loop() {
number = 0;
Serial.flush();

while(Serial.available() == 0){

}
while(Serial.available() > 0){
  number = Serial.read() - '0';     //odczytuje liczbę z bufora portu szeregowego
                                    //usuwa przesunięcie ASCII dla zera: '0'
}

Serial.print("Wpisana liczba: ");
Serial.println(number);
Serial.print(number);
Serial.print(" pomnożone przez dwa równa się ");
number = number * 2;
Serial.println(number);

delay(1000);
}


To wyświetla mi się po uruchomieniu programu i wpisaniu liczby 3.
Skąd bierze się to -38? Wyczytałem, że rejestrowane jest też wciśnięcie przycisku ENTER, ale jakim prawem odczytuje liczbę dwa razy?
Jak to naprawić?


Wpisana liczba: 3

3 pomnożone przez dwa równa się 6

Wpisana liczba: -38

-38 pomnożone przez dwa równa się -76

Bo funkcja loop(), jak to nawet wynika z nazwy, wywoływana jest ciągle, w zewnętrznej pętli. Program na takim procesorku w zasadzie się nie kończy - działa aż do wyłączenia zasilania. Dobrą praktyką jest pisanie wnętrza funkcji loop tak by wykonywała pojedynczy krok przetwarzania, nie umieszczanie całego przetwarzania w jednym przebiegu tej funkcji. Ale to trochę trudniejsze, trzeba opanować automaty stanów.
Pokazany program najpierw czeka na jakieś dane na serialu a potem czyta i ostatni znak zamienia na liczbę i wykonuje tą całą zabawe. Przy prędkości procka i seriala oznacza to praktycznie wczytanie jednego znaku - ale program natychmiast zaczyna od nowa.

Ta druga pętla jest nieużyteczna, chyba że ten serial nie jest fizycznym serialem a czyms co przesyła dane pakietami. 

Bardziej interesująco byłoby przerobić ten program by czytał liczbę składającą się z wielu znaków/cyfr a naciśniecie ENTER oznaczałoby polecenie wypisania wyniku.

Dla wyjaśnienia wyniku musisz wiedzieć że kod cyfry '0' to 48 a ENTER to 10 albo 13 w zależności od ustawień terminala. Jak widać u ciebie jest 10. 10-48 daje -38.
 
Odpowiedź
#4
Wiele razy tu pokazywałem przykład z SerialEvent, w wersji na łańcuchach char albo na stringach, jest też w przykładach. Wystarczy umówić się z użytkownikiem, że wysyłasz ciąg znaków zakończony ENTER lub znakiem nowyj linii - CR NL. Można potem to rozbudować o kontrolę, jakie znaki przylatują, by ignorować znaki spoza cyfr, liczby spoza zakresu, itp.
Wpisz w lupę SerialEvent.
Miło być decenianym https://buycoffee.to/kaczakat
 
Odpowiedź
  


Skocz do:


Przeglądający: 1 gości