Skocz do zawartości

Arduino - Ramka z własnymi zmiennymi


Pomocna odpowiedź

Napisano

Witam

Mam dość prosty problem ale myślę że ktoś mi pomoże.

Stworzyłem program w MIT app Inventor który wysyła mi na bluetooth zmienne z poszczególnymi danymi. Składa się standardowo z bitu startu, stopu a pomiędzy nimi danymi. Dam przykład:

23-start

0-led 1 OFF

1-led 2 ON

145- wartość ADC (od 0 do 255)

27-stop

Te cyfry na UART lecą w kółko i zmieniają stan gdy za pomocą programu bluetooth zmieniam wartości.

Jak wygląda sytuacja gdy trzeba zdefiniować w arduino które znaki oznaczają konkretne dane które potem trzeba przełożyć na np zapalnie diody itp. ?

Nijak nie wygląda. Odbierasz bajty, sprawdzasz w tych bajtach interesujące cię bity, ewentualnie składasz z nich inne typy w miarę potrzeb. Polecam jakąś książkę o programowaniu w C, powinno mocno pomóc.

Przeszukałem wiele poradników, toturiale na yt i nigdzie nie znalazłem tego. Znam teorie ale nie wiem jak w najprostszy sposób napisać kod który by rozróżniał kolejność tych liczb i wiedział co każda z nich oznacza.

Nie rozumiem nz czym polega problem "rozróżniania kolejności". Przecież dane odbierasz w tej samej kolejności, w jakiej zostały nadane, nie ma tu nic do rozróżniania. I chyba musisz doczytać czym się różni bajt od bitu.

Może pokaż nam swój kod i przykładowe działanie obecnie - zastanowimy się co jest źle.

Wiem że to troche komplikuje.

Problem wyszedł z tego że chciałem sterować serwem. Proste zadanie, wpisuje wartość z UART jako wychylenie. Gorzej gdy chce sterować czymś jeszcze lub kilkoma serwami, wtedy program musi rozróżniać która wartość jest od czego. Chodzi tylko o definiowanie by wiedział która wartość z tej kolejnosci co oznacza

Jeszcze w kodzie nic nie uwzględniłem

int bt;

void setup() {                

 pinMode(8, OUTPUT); 
 pinMode(9,OUTPUT);  
 pinMode(10,OUTPUT); 

 Serial.begin(9600);

}

void loop() {
 if(Serial.available() > 0){     
     bt = Serial.read();}

Serial.println(bt);

 if (bt == 'R') { 
     digitalWrite(10, HIGH);
     digitalWrite(9, LOW);
     digitalWrite(8, LOW);} 
   else if (bt == 'G') {
     digitalWrite(10,LOW);
     digitalWrite(9, HIGH);
     digitalWrite(8, LOW);}
   else if (bt == 'B') {
     digitalWrite(10, LOW); 
     digitalWrite(9, LOW);
     digitalWrite(8, HIGH);}
   else if (bt == '0') {
     digitalWrite(10,LOW);
     digitalWrite(9, LOW);
     digitalWrite(8, LOW);}

 delay(200);              
}

W MIT app inventor pokaze tylko bloki ukazujące co już mam jeśli chodzi o kod. STerowanie diodami mam narazie osobno ale gdy ogarne te ramki zmienie sposob ich działania

mniej więcej chodzi mi o coś takiego https://www.elektroda.pl/rtvforum/topic3364914.html

Nadal nie rozumiem z czym masz problem, ale spróbujmy łopatologicznie:

1. czytasz z seriala bajty aż znajdziesz początek ramki,
2. teraz kolejno czytasz wartości dla jednego leda, drugiego, wartości ADC, etc.

3. czytasz ostatni bajt i upewniasz się, że jest to koniec ramki — jak nie, to wyrzucasz całość i zaczynasz od nowa od 1.

4. używasz tych wczytanych wartości do czegokolwiek tam potrzebujesz,
5. przechodzisz do 1.

Rozumiem teorie, tylko nie wiem jak to zapisać kodem. Potrzebowałbym jakiś przykładowy w prostej formie.Chyba że sa jakieś gotowe sketche

krzywy187, spróbuj w takim razie dojść do tego po kolei. W tej chwili, jeśli dobrze rozumiem, wysyłasz ciągi takich liczb:

23

0

1

145

27

Każda jest w osobnej linii i przychodzi osobno, tak? To jest trochę mało wygodne rozwiązanie, bo nigdy nie wiesz, co jest czym (zgubisz jedną liczbę i całość będzie już przesunięta). Spróbuj wysyłać sobie informację np. tak:

23,0,1,145,27

Niech każda wysłana "linia" zawiera wszystkich informacje rozdzielone przecinkiem. Wtedy wystarczy kilka operacji na odebranych danych i będziesz mógł wyciągnąć poszczególne liczby. Dzięki przecinkowi będziesz wiedział, że "to koniec pierwszej wartości i po przecinku zaczyna się druga".

Dziękuję za odpowiedź. A gdyby tak przed każdą dać jeszcze literę ? Na uart będzie to pewnie widoczne w ascii. Ogólnie mam taki pomysł :

 value = Serial.read()

if (value=='A')
{
servo();
}
if (value=='B')
{
led();
}

Pisze z głowy więc wybaczcie za błędy.

krzywy187, możesz i przed każdą wartością dodać inna literę. Jednak i tak program w obecnej formie nie zadziała. Musisz najpierw z każdego odebranego ciągu danych pobierać pierwszy znak i dopiero na jego podstawie wykonywać dalsze operacje. Jest to do zrobienia - próbuj 😉

  • Pomogłeś! 1
Każda jest w osobnej linii i przychodzi osobno, tak? To jest trochę mało wygodne rozwiązanie, bo nigdy nie wiesz, co jest czym (zgubisz jedną liczbę i całość będzie już przesunięta). Spróbuj wysyłać sobie informację np. tak:

Nie sądzę, żeby one były w osobnych liniach. Kolega pisał o bitach, więc zgaduję, że to są kolejne bajty, a nie napisy. Swoją drogą, jedyne co w praktyce zmienia twoje rozwiązanie, to zmiana znaków startu/stopu ramki na "\n".

Jak narazie mam tyle działającego kodu, pod jedno serwo. Średnio rozumiem końcówkę.

#include <Servo.h>
Servo servomotor;

char c;
String status;


void setup() {

servomotor.attach(11);
servomotor.write(90);

Serial.begin(9600);
}

void loop() {

Serial.println(c);

 if (Serial.available())
 {
   c = Serial.read();

   if (c == 'A')
   {
     servo();
   }
}
 }
 void servo()
{
 delay(30);
 while (Serial.available())
 {
   char c = Serial.read();
   status += c;
 }
 if (status.length() > 0)
 {
   servomotor.write(status.toInt());
   status = "";
 }
}

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