Skocz do zawartości

Problem z wypisywanie w porcie USART


n1k0

Pomocna odpowiedź

Cześć,

Rozpocząłem zabawę z Arduino (Swoją drogą na zestawie z Botlandu i z kursami z forbota 😉 ).

Jestem na etapie zabawy z portem szeregowym USART. Tworzę miernik z "Kurs Arduino – #4 – Przetwornik ADC". Chcę wypisywać wartość z przetwornika analogowego ale z dopiskiem "Wartość wynosi"...

Czy jest w stanie ktoś mi doradzić gdzie jest błąd i wytłumaczyć dlaczego on występuje?

Pozdrawiam i z góry dziękuję za pomoc

  float wartosc=0; //Stworzenie zmiennej "wartosc"
  int sygnal=0; //Stworzenie zmiennej "sygnal"
void setup() 
{
  Serial.begin(9600); //Komunikacja z USART
  Serial.println('\n');
}

void loop() 
{
  sygnal = analogRead(A4); //Przypisanie zmiennej "wartosc" do portu A5
  wartosc =  sygnal * (5.0/1024.0);
  Serial.println("Napięcie wynosi" + wartosc); //Wypisanie w USART wartości z A5
  delay(1000); //Spowolnienie wypisywania żeby Arduino pi***ca nie dostało
}

image.thumb.png.aee4dd5dbdc4a1c0101038a711960acf.png

Link do komentarza
Share on other sites

@n1k0 cześć, to co robisz nie jest prostą operacją, bo dodajesz 2 zupełnie różne wartości. W C++ to co robisz to skorzystanie z przeciążonego operatora dodawania czyli użycie takiej jakby funkcji która bierze 2 takie same argumenty i dodaje je i zwraca ten sam typ.

Po lewej jest typ const char* lub const char[N] czyli wskaźnik na tablicę iluś znaków char. Po prawej masz liczbę float. Żeby zrobićdodawanie (czyli fachowo konkatanację napisów) musisz zamienić float na napis funkcją np to_string() i dodanie. Użyje to jednak obiektu String który zazwyczaj używa stertę czyli pamięć której programista embedded niezabardzo chce używać.

Tu najlepiej jak dasz pierwszy napis w jednym Serial.print, a wartość w Serial.println.

Masz też wiele innych opcji do wyboru, jedna to skorzystanie z dodatkowego bufora wypisywania w postaci statycznej tablicy iluś znaków z zapasem i do niej pisanie funkcją std::sprintf() z biblioteki <cstdio> albo std::snprintf() dla bezpieczeństwa. Wynik tego możesz w jednym rzucie dać do Serial.println(). Na pewno pojawi się problem polskich znaków, do tego masz "widechar" i odpowiedniki tych funkcji.

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

51 minut temu, Gieneq napisał:

@n1k0 cześć, to co robisz nie jest prostą operacją, bo dodajesz 2 zupełnie różne wartości. W C++ to co robisz to skorzystanie z przeciążonego operatora dodawania czyli użycie takiej jakby funkcji która bierze 2 takie same argumenty i dodaje je i zwraca ten sam typ.

Po lewej jest typ const char* lub const char[N] czyli wskaźnik na tablicę iluś znaków char. Po prawej masz liczbę float. Żeby zrobićdodawanie (czyli fachowo konkatanację napisów) musisz zamienić float na napis funkcją np to_string() i dodanie. Użyje to jednak obiektu String który zazwyczaj używa stertę czyli pamięć której programista embedded niezabardzo chce używać.

Tu najlepiej jak dasz pierwszy napis w jednym Serial.print, a wartość w Serial.println.

Masz też wiele innych opcji do wyboru, jedna to skorzystanie z dodatkowego bufora wypisywania w postaci statycznej tablicy iluś znaków z zapasem i do niej pisanie funkcją std::sprintf() z biblioteki <cstdio> albo std::snprintf() dla bezpieczeństwa. Wynik tego możesz w jednym rzucie dać do Serial.println(). Na pewno pojawi się problem polskich znaków, do tego masz "widechar" i odpowiedniki tych funkcji.

Ok, rozumiem, dziękuję bardzo za pomoc ❤️ 

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

1 godzinę temu, Gieneq napisał:

Tu najlepiej jak dasz pierwszy napis w jednym Serial.print, a wartość w Serial.println.

Popieram. I będzie to znacznie szybsze niż konkatenacja 😉 Nawet w GameDev'ie staraliśmy się unikać sterty (nie zawsze się dało), bo jest tragicznie wolna. Na szczęście Java ma aż 32kB stosu, co nawet przy kwiatkach kompilatora Unity było okej 😄

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

Jeszcze pytanko jedno, co jeśli bym chciał to zrobić tak jak się to robi w C?

Serial.println( ”Napiecie wynosi  %f” , wartosc);

Wbiłem to do tinkercad'a i nie działa. Z tego co mnie uczono C++ jest wstecznie kompatybilny z C. Kwestia tego że to co jest arduino to jest przerobiony C++ czy też problem tego że tutaj jest Serial.println zamiast printf?

float wartosc=0; //Stworzenie zmiennej "wartosc"
  int sygnal=0; //Stworzenie zmiennej "sygnal"
void setup() 
{
  Serial.begin(9600); //Komunikacja z USART
  Serial.println('\n');
}

void loop() 
{
  sygnal = analogRead(A4); //Przypisanie zmiennej "wartosc" do portu A5
  wartosc =  sygnal * (5.0/1024.0);
  Serial.println("Napięcie wynosi %f", wartosc); 
  delay(1000);
}

 

Link do komentarza
Share on other sites

1 minutę temu, n1k0 napisał:

Wbiłem to do tinkercad'a i nie działa. Z tego co mnie uczono C++ jest wstecznie kompatybilny z C. Kwestia tego że to co jest arduino to jest przerobiony C++ czy też problem tego że tutaj jest Serial.println zamiast printf?

Serial.println to funkcja klasy Serial, która jest elementem frameworka/API Arduino, a nie C++. Dlatego nie działa.

Musisz użyć funkcji sprintf, a jej "wynik" dać do Serial.println.

  • Pomogłeś! 1
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.