Skocz do zawartości

Funkcja "Serial.parseInt()" wystawia 0


NeghMC

Pomocna odpowiedź

Witam, napisałem sobie taki kod używający serwomechanizmu:

#include <Servo.h>

Servo servo;
long pozycja = 15;


void setup() {
Serial.begin(9600);
servo.attach(9);
}

void loop() {
if (Serial.available()) {
pozycja = Serial.parseInt();
}
if ((pozycja >= 15) && (pozycja <= 180))
servo.write(pozycja);
else
Serial.println("zla komenda");
}

Problem jest z funkcją Serial.parseInt(), po odczytaniu wartości typu int wystawia ona na port znak "0", co powoduje wyświetlanie się masowej ilości komunikatów "zla komenda".

Trochę czasu poświęciłem na znalezienie przyczyny i nie udało mi się tego zrobić. Ma ktoś pomysł co co się dzieje?

PS. najmniejsza pozycja nie wynosi 0 ponieważ mój silnik jest trochę wadliwy i przy takim ułożeniu zacina się.

Dziękuje z góry za odpowiedzi 🙂

PS2. czy dałoby się używać cyfry typu int a nie typu long?

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

Przeczytałem, ale rozumiem tyle że ta funkcja przysyła zero tylko gdy nie znajdzie żadnej liczby. Nadal nie rozumiem czemu wo znalezieniu jakiejś liczby, funkcja jakimś magicznym trafem odpala się po raz drugi i wysyła 0 za port. Jeśli wiesz dla czego to proszę, wytłumacz mi.

Link do komentarza
Share on other sites

Nie "jakimś magicznym trafem", tylko ty ją uruchamiasz za każdym wywołaniem funkcji "loop()", gdy tylko jest w buforze portu szeregowego cokolwiek, niezależnie od tego co to jest i ile tego jest.

Link do komentarza
Share on other sites

Dzień dobry.

Mam pewien probvlem z prawidłowym działaniem funkcji Serial.parseInt().

Potrzebuję wczytać z portu sześć liczb int (0-255)wpisanych w linię wejścia monitora portu szeregowego.

Napisałem taki kod:

//.......................................
void loop() {
  // put your main code here, to run repeatedly:
  //Wprowadzanie wartości kolorów z klawiatury
  int r1 = -1;
  int g1 = -1;
  int b1 = -1;
  int r2 = -1;
  int g2 = -1;
  int b2 = -1;

  Serial.println("Wprowadź 6 wartości kolorów (0-255) rozdzielonych spacjami np: 0 12 254 16 128 56 ");
  Serial.setTimeout(600000); //Czeka 10 minut na wprowadzone liczby
  while (r1 < 0 || g1 < 0 || b1 < 0 || r2 < 0 || g2 < 0 || b2 < 0 || r1 > 255 || g1 > 255 || b1 > 255 || r2 > 255 || g2 > 255 || b2 > 255)
  {
    r1 = Serial.parseInt();
    g1 = Serial.parseInt();
    b1 = Serial.parseInt();
    r2 = Serial.parseInt();
    b2 = Serial.parseInt();
    g2 = Serial.parseInt();
  }
  
Serial.println("Wprowadzono: ");
 wydruk(r1, g1, b1, r2, g2, b2);
Serial.println("Wyświetlam wprowadzone kolory ");
  //Wyświetlenie kolorów na RGB Led
  analogWrite(RGB_R1, r1);
  analogWrite(RGB_G1, g1);
  analogWrite(RGB_B1, b1);
  analogWrite(RGB_R2, r2);
  analogWrite(RGB_G2, g2);
  analogWrite(RGB_B2, b2);

}//END of loop

Niestety nie zawsze wszystkie liczby są prawidłowo odczytane z portu. Potrafią być pominięte i zostają w buforze.

Przy kolejnym odczycie to co zostało w buforze jest odczytywane jako pierwsze liczby.

Dobrze by było opróżnić bufor przed kolejnym odczytem.

Jest funkcja Serial.flush(), ale z tego co czytam w opisie to służy do opróżniania bufora wyjściowego a nie wyjściowego.

Jakiś pomysł na prawidłowy, kompletny odczyt i opróżnienie bufora gdyby coś pozostało ?

 

Link do komentarza
Share on other sites

Wygląda na to że sobie poradziłem.

Doiero to dobrze działa.

Nie wystarczało czyszczenie bufora po odczycie danych. Trzeba było go wyczyścić też przed.

//Program Dobieranie kolorów RGB//
//Wprowadzamy z monitora portu szeregowego wartości RGB (0-255) dla dwóch Ledów RGB
#define VER "Dobieranie kolorów ver 2021/03/02"
//Podłączenia. Ledy muszą być podłączone do portów PWM czyli 3, 5, 6, 9, 10 lub 11
#define RGB_R1 3
#define RGB_G1 5
#define RGB_B1 6
#define RGB_R2 9
#define RGB_G2 10
#define RGB_B2 11

//Formatowany wydruk na serial monitor
void wydruk(int va1, int va2, int va3, int va4, int va5, int va6)
{
  char bufor[80];
  sprintf(bufor, "r1= %3d g1= %3d b1= %3d * r2= %3d g2= %3d b2= %3d", va1, va2, va3, va4, va5, va6);
  Serial.println(bufor);
}

//*********************************SETUP***********************************
void setup() {
  // put your setup code here, to run once:
  Serial.begin(115200);
  Serial.println(VER);
}

//*********************************LOOP************************************
void loop() {
  // put your main code here, to run repeatedly:
  //Wprowadzanie wartości kolorów z klawiatury
  int r1 = -1;
  int g1 = -1;
  int b1 = -1;
  int r2 = -1;
  int g2 = -1;
  int b2 = -1;

  Serial.println("Wprowadź 6 wartości kolorów (0-255) rozdzielonych spacjami np: 0 12 254 16 128 56 ");
  Serial.setTimeout(6000000); //Czeka 100 minut na wprowadzone liczb
 //opróżnienie bufora wejściowego na wypadek, gdyby coś zostało z poprzedniego czytania.
 while (Serial.available() > 0) char x = Serial.read();
  while (r1 < 0 || g1 < 0 || b1 < 0 || r2 < 0 || g2 < 0 || b2 < 0 || r1 > 255 || g1 > 255 || b1 > 255 || r2 > 255 || g2 > 255 || b2 > 255)
  {
    r1 = -1;
    g1 = -1;
    b1 = -1;
    r2 = -1;
    g2 = -1;
    b2 = -1;
    r1 = Serial.parseInt();
    g1 = Serial.parseInt();
    b1 = Serial.parseInt();
    r2 = Serial.parseInt();
    g2 = Serial.parseInt();
    b2 = Serial.parseInt();
  }
  //opróżnienie bufora wejściowego na wypadek, gdyby coś zostało
  while (Serial.available() > 0) char x = Serial.read();

  Serial.println("Wprowadzono: ");
  wydruk(r1, g1, b1, r2, g2, b2);
  Serial.println("Wyświetlam wprowadzone kolory ");
  //Wyświetlenie kolorów na RGB Led
  analogWrite(RGB_R1, r1);
  analogWrite(RGB_G1, g1);
  analogWrite(RGB_B1, b1);
  analogWrite(RGB_R2, r2);
  analogWrite(RGB_G2, g2);
  analogWrite(RGB_B2, b2);

}//END of loop

Problem pojawiał się zwłaszcza gdy za dużo liczb zostało wpisanych lub za mało.

Teraz jak jest za dużo, to wczytuje pierwszych sześć, a jak za mało lub nie mieszczące się w zakresie, to nic nie wczytuje. Tak miało to działać.

 

Link do komentarza
Share on other sites

Dołącz do dyskusji, napisz odpowiedź!

Jeśli masz już konto to zaloguj się teraz, aby opublikować wiadomość jako Ty. Możesz też napisać teraz i zarejestrować się później.
Uwaga: wgrywanie zdjęć i załączników dostępne jest po zalogowaniu!

Anonim
Dołącz do dyskusji! Kliknij i zacznij pisać...

×   Wklejony jako tekst z formatowaniem.   Przywróć formatowanie

  Dozwolonych jest tylko 75 emoji.

×   Twój link będzie automatycznie osadzony.   Wyświetlać jako link

×   Twoja poprzednia zawartość została przywrócona.   Wyczyść edytor

×   Nie możesz wkleić zdjęć bezpośrednio. Prześlij lub wstaw obrazy z adresu URL.

×
×
  • 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.