trainee Maj 29, 2022 Udostępnij Maj 29, 2022 (edytowany) To żeby nie wprowadzać zbyt wielkich rewolucji do Twojego dotychczasowego zamysłu, to można tak: static bool insideUnsolicitedMessage = false; if (Serial.available() > 0) { char code = Serial.read(); if (insideUnsolicitedMessage) { if (code == '\r') insideUnsolicitedMessage = false; } else { if (code == '+') insideUnsolicitedMessage = true; else processCommand(code); } } By nie szaleć w głębokości zagnieżdżeń, proponuję zrobić funkcję void processCommand(char code), a w niej umieścić Twoje pierwotne warunki od sterowania. Działa to tak, że po wykryciu znaku plus kod będzie ignorował wszystkie kolejne znaki aż do wystąpienia znaku \r, tj. carriage return, co z dużym prawdopodobieństwem występuje na końcu komunikatu od Twojego modułu. PS W kwestii Twoich warunków możesz też rozważyć użycie switch, zamiast ciągów if-else. Jest to bardziej popularna konstrukcja dla porównań jednej zmiennej, np.: switch (code) { case 'F': front(); break; case 'L': left(); break; ... PPS To rozwiązanie powyżej nie jest w pełni szczelne jeżeli program startuje/restartuje niezależnie od zasilania modułu Bluetooth. Bo program może uruchomić się, gdy moduł jest w środku wysyłania komunikatu, np. zamiast "+PAIRABLE\r" otrzymać "RABLE\r". Jedną z możliwości lepszego radzenia sobie z takimi wypadkami, skoro mamy do czynienia z urządzeniem, którego protokół ma komendy oddzielane znakami nowego wiersza, jest używanie również nowego wiersza we własnych komendach, uczynienie ich dłuższymi i np. jak w AT zaczynające się od jakiegoś stałego ciągu, by uniknąć niejednoznaczności, np. "AT&FORWARD\r". Można też sprawdzić czy nie da się w ogóle pozbyć pierwotnego problemu czyli czy nie można przypadkiem w ogóle wyłączyć powiadomień z modułu. Edytowano Maj 29, 2022 przez trainee 1 Cytuj Link do komentarza Share on other sites More sharing options...
kiker212 Maj 29, 2022 Autor tematu Udostępnij Maj 29, 2022 (edytowany) Dobra już zrobiłem poprawny program i wszystko działa 🙂.Na module bluetooth użyłem state. Program wygląda tak. #include <avr/io.h> #define MOTOR1_PWM 6 //D6 #define MOTOR1_PWM_COR 0 #define MOTOR1_IN1 14 //A0 #define MOTOR1_IN2 15 //A1 #define MOTOR2_PWM 5 //D5 #define MOTOR2_PWM_COR 0 #define MOTOR2_IN1 16 //A2 #define MOTOR2_IN2 17 //A3 #define STATE_BT 4 //D4 #define diodaright 11 //D11 #define diodaleft 12 //D12 char lastCode = ' '; int isDisabled = 0; int pwmSpeed = 0; void setup() { Serial.begin(38400); TCCR0A = _BV(WGM01) | _BV(WGM00); TCCR0B = _BV(CS01) | _BV(CS00); OCR0A = 100; OCR0B = 100; pinMode(MOTOR1_PWM, OUTPUT); digitalWrite(MOTOR1_PWM, HIGH); pinMode(MOTOR1_IN1, OUTPUT); pinMode(MOTOR1_IN2, OUTPUT); pinMode(MOTOR2_PWM, OUTPUT); digitalWrite(MOTOR2_PWM, HIGH); pinMode(MOTOR2_IN1, OUTPUT); pinMode(MOTOR2_IN2, OUTPUT); pinMode(STATE_BT, INPUT); lightOff(); stop(); } void loop() { analogWrite(MOTOR1_PWM, pwmSpeed); analogWrite(MOTOR2_PWM, pwmSpeed); boolean btStatus = digitalRead(STATE_BT) == HIGH; if (Serial.available() > 0) { char code = Serial.read(); if(btStatus) { if (code == 'F') { front(); } else if (code == 'L') { left(); } else if (code == 'R') { right(); } else if (code == 'B') { back(); } else if (code == 'S') { stop(); } else if (code == '0') { setSpeed(0); } else if (code == '1') { setSpeed(1); } else if (code == '2') { setSpeed(2); } else if (code == '3') { setSpeed(3); } else if (code == '4') { setSpeed(4); } else if (code == '5') { setSpeed(5); } else if (code == '6') { setSpeed(6); } else if (code == '7') { setSpeed(7); } else if (code == '8') { setSpeed(8); } else if (code == '9') { setSpeed(9); } else if (code == 'q') { setSpeed(10); } else if (code == 'W') { lightOn(); } else if (code == 'w'){ lightOff(); } lastCode = code; Serial.print("LastCode: "); Serial.println(lastCode); } else { stop(); Serial.print("Bt disconnected"); } } if(!btStatus){ Serial.print("Bt disconnected"); } } void right() { Serial.println("left"); digitalWrite(MOTOR1_IN1, LOW); digitalWrite(MOTOR1_IN2, HIGH); digitalWrite(MOTOR2_IN1, HIGH); digitalWrite(MOTOR2_IN2, LOW); } void left() { Serial.println("righ"); digitalWrite(MOTOR2_IN1, LOW); digitalWrite(MOTOR2_IN2, HIGH); digitalWrite(MOTOR1_IN1, HIGH); digitalWrite(MOTOR1_IN2, LOW); } void back() { Serial.println("back"); digitalWrite(MOTOR1_IN1, HIGH); digitalWrite(MOTOR1_IN2, LOW); digitalWrite(MOTOR2_IN1, HIGH); digitalWrite(MOTOR2_IN2, LOW); } void front() { Serial.println("front"); digitalWrite(MOTOR2_IN1, LOW); digitalWrite(MOTOR2_IN2, HIGH); digitalWrite(MOTOR1_IN1, LOW); digitalWrite(MOTOR1_IN2, HIGH); } void stop() { //Serial.println("stop"); digitalWrite(MOTOR2_IN1, LOW); digitalWrite(MOTOR2_IN2, LOW); digitalWrite(MOTOR1_IN1, LOW); digitalWrite(MOTOR1_IN2, LOW); } void setSpeed(int speed) { pwmSpeed = 100 + speed * 15 ; } void lightOff() { light1(LOW); light2(LOW); } void lightOn() { light1(HIGH); light2(HIGH); } void light1(int status){ pinMode(diodaleft, OUTPUT); digitalWrite(diodaleft, status); } void light2(int status){ pinMode(diodaright, OUTPUT); digitalWrite(diodaright, status); } Dziękuję za pomoc 🙂 Edytowano Maj 29, 2022 przez kiker212 1 Cytuj Link do komentarza Share on other sites More sharing options...
farmaceuta Maj 29, 2022 Udostępnij Maj 29, 2022 O widzisz..o tym pinie wogole nie pomyslalem..😉 A ta linijka tak ma wygladac? btStatus = digitalRead(STATE_PIN) == HIGH; O ile w tym przypadku jest ok to kiedys w przyszlosci moze Ci taki zapis sprawic problem bo bedzie jakis stan odwrocony...wystarczy sam digital tutaj (jest czytelniej) Dobrze ze sie udalo wkoncu rozwiazac problem👍 Cytuj Link do komentarza Share on other sites More sharing options...
Pomocna odpowiedź
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!