Skocz do zawartości

Zakłócenia przy komunikacji BT


Bachu

Pomocna odpowiedź

Witam!

Ostatnio męczę się z problemem przy przesyłaniu wartości za pomocą dwóch modułów BT HC-05 ZS-040. Stworzyłem dwie konfiguracje, gdzie moduł MASTER jest zasilony ze sterownika i z osobnego zasilania.  Najlepiej będzie, jak pokaże jak to działa na filmie. Większy ekran będzie monitorem odbioru, a mniejszy monitorem wysyłu.

Ustawienia modułów

Podłączony do rękawicy(Master):

ROLE = 1
CMODE=1
BAUD RATE = 9600,0,0

Podłączony do płytki stykowej(Slave):

ROLE=0
CMODE=0
BAUD RATE=9600,0,0

Schemat pierwszej konfiguracji:

tak.thumb.png.66b4554179970328290df1f9af153305.png

Rezystor R5 - 1k Ohm
Rezystor R4 - 2k Ohm
Rezystory R1, R2 i R3 mają po 820k Ohm

Nagranie z odczytami:

 

Program odbioru:

#include<Servo.h>
#include<Wire.h>
#include<Adafruit_PWMServoDriver.h>

Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver();



const byte numChars = 32;
char receivedChars[numChars];
char tempChars[numChars];    

uint8_t servonum = 1;
uint8_t servonum2 = 2;
uint8_t servonum3 = 3;

int motorOut, staryx, odczytx;
int odczyt0;
int odczyt = 0;
int odczyt2 = 0;
int odczyt4 = 0;
int odczyt5 = 0;
int stary;
String all, value1, value2, value3, value4, value5;
boolean noweDane = false;

//============

void setup() {
    Serial.begin(9600);
    pwm.begin();
    pwm.setPWMFreq(50);
    yield();
}
    
 void proba(int odczytx, int staryx, int motorOut)
  {
   if (odczytx < staryx) {
  for(int i=staryx;i>odczytx;i--)
   {
    Serial.println(i);
    pwm.setPWM(motorOut, 0, i);
    delay(1);
   }

  }
    else if (odczytx > staryx) { 
      for(int i=staryx;i<odczytx;i++)
   {
    Serial.println(i);
    pwm.setPWM(motorOut, 0, i);
    delay(1);
   }
 }
}


//============

void loop() {
    recvWithStartEndMarkers();
    if (noweDane == true) {
        strcpy(tempChars, receivedChars);
            
        parseData();
        showParsedData();
        noweDane = false;
    }
}

    


//============

void recvWithStartEndMarkers() {
    static boolean recvInProgress = false;
    static byte ndx = 0;
    char startMarker = '<';
    char endMarker = '>';
    char rc;

    while (Serial.available() > 0 && noweDane == false) {
        rc = Serial.read();

        if (recvInProgress == true) {
            if (rc != endMarker) {
                receivedChars[ndx] = rc;
                ndx++;
                if (ndx >= numChars) {
                    ndx = numChars - 1;
                }
            }
            else {
                receivedChars[ndx] = '\0'; 
                recvInProgress = false;
                ndx = 0;
                noweDane = true;
            }
        }

        else if (rc == startMarker) {
            recvInProgress = true;
        }
    }
}

//============

void parseData() {      

    char * strtokIndx; 

    strtokIndx = strtok(tempChars,",");     
    odczyt0 = atoi(strtokIndx);
 
    strtokIndx = strtok(NULL, ","); 
    odczyt = atoi(strtokIndx);     

    strtokIndx = strtok(NULL, ",");
    odczyt2 = atoi(strtokIndx);  

   strtokIndx = strtok(NULL, ",");
    odczyt4 = atoi(strtokIndx); 
      
   strtokIndx = strtok(NULL, ",");
    odczyt5 = atoi(strtokIndx); 
}

//============

void showParsedData() {
  value1 = String(odczyt0/ 1, DEC);
  value2 = String(odczyt / 1, DEC);
  value3 = String(odczyt2 / 1, DEC);
  value4 = String(odczyt4 / 1, DEC);
  value5 = String(odczyt5 / 1, DEC);  

  all = "<" + value1 + "," + value2 + "," + value3 + "," + value4 + "," + value5 + ">";

  Serial.println(all);
}

Jak widać na filmie, przy podłączonym module odczyty z czujników ugięcia co jakiś czas samoistnie się zmieniają. Przy module BT odłączonym od zasilania ten problem nie występuje.

                                                                                                                                       Konfiguracja z osobnym zasilaniem

Schemat:

osobnezasilanie.thumb.png.17cdebc9ade5ed27f481492cef10e565.png

Tutaj moduł został zasilony osobno z zestawu baterii o łącznym napięciu 6V. (Na tym schemacie także znajdują się czujniki ugięcia)

Nagranie z odczytami:

Tutaj jak widać odczyty nie zmieniają się samoistnie, lecz w trakcie transmisji, moduły "gubią" dane. Program odbioru jak i wysyłu przy pierwszej i drugiej konfiguracji jest taki sam.

Schemat podłączenia drugiego modułu (SLAVE):

nie.thumb.png.ca2402825d4916e339d77c360f2f5db6.png

Czy jest możliwość wyeliminowania tych zakłóceń przy wysyle z modułem zasilonym z płytki? Będę bardzo wdzięczny za jakiekolwiek rady. Pozdrawiam!

Link do komentarza
Share on other sites

Zbyt wiele tu pisać, na początek nie można używać tego samego UART do połączenia z BT i monitorowania UNO, UART jest interfejsem 1:1. W UNO można go używać tylko wtedy gdy nie używasz USB. Jak potrzebujesz użyć dwóch UART to co najmniej Arduino Leonardo/MICRO, do PC łączy się przez USB wbudowane w Atmegę - Serial, a TX/RX na płytce to Serial1 i nim komunikujesz się z BT. Prędkość ustaw na max ile się da, by procesor miał czas na inne rzeczy w loop. Nie pokazujesz programu nadawczego, a on może być ważniejszy tutaj. Każdą transmisję zacznij od kolejnego numeru porządkowego, możesz skopiować sobie wtedy dwa teksty i je porównać, tak to nie wiesz która linijka wysłana odpowiada odebranej. Oczekujesz że ktoś przeanalizuje te fruwające liczby na ekranie? Przechodzisz test Turinga?

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

String all;
String value1, value2, value3, value4, value5;
int pierwszy_pomiar0, pierwszy_pomiar1, pierwszy_pomiar2;
int minim0 = 650;
int minim1 = 650;
int minim2 = 650;
int poprzedni_odczyt0, poprzedni_odczyt1, poprzedni_odczyt2;
int stary0, stary1, stary2;
int wynik0, wynik1, wynik2, wynik3, wynik4;


void setup() {
  Serial.begin(9600);
  
 for (int i=0; i <= 10; i++)
  {
    Serial.println("setup");
    pierwszy_pomiar0 = analogRead(A0);
    pierwszy_pomiar0 = map(pierwszy_pomiar0, 40, 115, 0, 180);
    pierwszy_pomiar0 = map(pierwszy_pomiar0, 0, 180, 650, 2350);
    pierwszy_pomiar0 = int(float(pierwszy_pomiar0) / 1000000 * 50 * 4096); 

 if (pierwszy_pomiar0 < minim0)     
      {
        minim0=pierwszy_pomiar0;     
      }

    pierwszy_pomiar1 = analogRead(A1);
    pierwszy_pomiar1 = map(pierwszy_pomiar1, 30, 75, 0, 180);
    pierwszy_pomiar1 = map(pierwszy_pomiar1, 0, 180, 650, 2350);
    pierwszy_pomiar1 = int(float(pierwszy_pomiar1) / 1000000 * 50 * 4096); 

 if (pierwszy_pomiar1 < minim1)     
      {
        minim1=pierwszy_pomiar1;     
      }

    pierwszy_pomiar2 = analogRead(A2);
    pierwszy_pomiar2 = map(pierwszy_pomiar2, 40, 110, 180, 0);
    pierwszy_pomiar2 = map(pierwszy_pomiar2, 180, 0, 2350, 650);
    pierwszy_pomiar2 = int(float(pierwszy_pomiar2) / 1000000 * 50 * 4096); 

 if (pierwszy_pomiar2 < minim2)     
      {
        minim2=pierwszy_pomiar2;     
      }

 delay(20);
  }
   poprzedni_odczyt0 = minim0;
   poprzedni_odczyt1 = minim1;
   poprzedni_odczyt2 = minim2;

}

void loop() {
   pierwszy_pomiar0 = analogRead(A0);
   pierwszy_pomiar0 = map(pierwszy_pomiar0, 40, 115, 0, 180);
   pierwszy_pomiar0 = map(pierwszy_pomiar0, 0, 180, 650, 2350);
   pierwszy_pomiar0 = int(float(pierwszy_pomiar0) / 1000000 * 50 * 4096); 

  stary0 = abs(pierwszy_pomiar0 - poprzedni_odczyt0);

if (stary0 > 10 && stary0 < 100) {
  wynik0 = pierwszy_pomiar0;
  poprzedni_odczyt0 = pierwszy_pomiar0;
}
else {
  wynik0 = poprzedni_odczyt0;
} 

   pierwszy_pomiar1 = analogRead(A1);
   pierwszy_pomiar1 = map(pierwszy_pomiar1, 30, 75, 0, 180);
   pierwszy_pomiar1 = map(pierwszy_pomiar1, 0, 180, 650, 2350);
   pierwszy_pomiar1 = int(float(pierwszy_pomiar1) / 1000000 * 50 * 4096); 

  stary1 = abs(pierwszy_pomiar1 - poprzedni_odczyt1);

if (stary1 > 15 && stary1 < 100) {
  wynik1 = pierwszy_pomiar1;
  poprzedni_odczyt1 = pierwszy_pomiar1;
}
else {
  wynik1 = poprzedni_odczyt1;
} 

   pierwszy_pomiar2 = analogRead(A2);
   pierwszy_pomiar2 = map(pierwszy_pomiar2, 40, 110, 180, 0);
   pierwszy_pomiar2 = map(pierwszy_pomiar2, 180, 0, 2350, 650);
   pierwszy_pomiar2 = int(float(pierwszy_pomiar2) / 1000000 * 50 * 4096); 


  
  stary2 = abs(pierwszy_pomiar2 - poprzedni_odczyt2);

if (stary2 > 10 && stary2 < 100) {
  wynik2 = pierwszy_pomiar2;
  poprzedni_odczyt2 = pierwszy_pomiar2;
}
else {
  wynik2 = poprzedni_odczyt2;
} 

 
  value1 = String(wynik0/ 1, DEC);
  value2 = String(wynik1 / 1, DEC);
  value3 = String(wynik2 / 1, DEC);
  value4 = String(wynik3 / 1, DEC);
  value5 = String(wynik4 / 1, DEC);
  

  all = "<" + value1 + "," + value2 + "," + value3 + "," + value4 + "," + value5 + ">";

  Serial.println(all);
  
  delay(100);
}

Tak wygląda kod wysyłu. 
Nie ma potrzeby analizowania każdej linijki. Chodziło mi o to, by pokazać, że gdy BT master nie jest zasilone ze sterownika, to odczyty nie zmieniają się i są stałe. Gdy moduł zasilam ze sterownika, odczyty nagle zaczynają się same z siebie zmieniać (Nie jakoś znacznie, bo o max. 20 jednostek w skali 0-600, ale jednak jest to lekko uciążliwe).  Czy wina tutaj może leżeć po stronie źle zlutowanej płytki, bądź źle zaprojektowanego układu? 

Link do komentarza
Share on other sites

Kod nadawczy był potrzebny by się upewnić, że odbiornik ma czas na przeanalizowanie wysyłanych danych, delay(100) od biedy może być, zmierz się z resztą tego co napisałem wcześniej, to jest wystarczające by działało nieprawidłowo.

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

Działa. :)

Ostatecznie pomogło zmiane na 36400 bodów, zasilenie modułu z osobnego zasilania i połączenie masy zasilania z masą sterownika.

Dzięki za pomoc! 

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

@Bachu, dziękuję za podzielenie się rozwiązaniem! Na pewno pomoże to w przyszłości jakiejś innej osobie, która trafi tu podczas szukania rozwiązania swojego problemu. W takiej sytuacji nie ma nic bardziej irytującego od znalezienia tematu, w którym autor na końcu publikuje informację "Już działa" i nie dzieli się konkretnymi wskazówkami 🙂

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

Napisał przecież na końcu ' połączenie masy zasilania z masą sterownika ' 🙂

Edytowano przez Treker
Poprawiłem formatowanie.
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.