Сервомотор и модуль Bluetooth блокируют друг друга

Для небольшого проекта я намерен подключить цифровой датчик температуры (KY-028), модуль Bluetooth (HC-05) и сервомотор (SG90). Проблема в том, что, кажется, я не могу подключить модуль Bluetooth и сервомотор одновременно. Модуль Bluetooth вместе с датчиком температуры работает нормально. Серво с датчиком, опять же, все в порядке. Но , похоже, эти двое не согласны друг с другом: как только я загружаю код на плате (Arduino UNO), сервопривод начинает вибрировать (даже не вращаясь), хотя я убедился, что ни одна команда, которая просит его сделать это, не достигнута. Также при этом светодиод модуля Bluetooth выключен и не распознается другими устройствами.

Когда я загружаю программу на борту, я отсоединить RX и TX пины модуль Bluetooth с контактов 0 & 1 на плате, (в противном случае я получаю ошибки и программа не загружается - если нужно, я буду вам коды ошибок, как я вам и редактирования поста), но после загрузки, сервопривод начинает вести себя странно, как описано выше. Как я читал в другой статье (если мне удастся найти ссылку снова, я опубликую ее здесь), она может вести себя так, потому что во всей моей схеме есть несвязанные контакты (что верно, но в противном случае я не могу подключить модуль Bluetooth). Как я мог соединить их обоих на одной плате?

Я тестировал код слои, они действуют так, как они должны, я попытался переключение вывода так, что я почти ничего не по ошибке, так как я полный новичок (например, я пытался ставить сигнальный провод сервопривод с обеих ШИМ и ШИМ не поддерживающих контактов, пробовали подключить модуль Bluetooth и сервопривод для разных оснований и т. д.) но без успеха.

Любая помощь будет очень признательна. Если понадобится макет моей схемы, я постараюсь сделать его в симуляторе. Большое спасибо!

Обновление

Вот код:

#include <Servo.h>
#include <SoftwareSerial.h>

int txPin = 1;
int rxPin = 0;
int digitalPin = 7; // KY-028 цифровой интерфейс
int analogPin = A2; // KY-028 аналоговый интерфейс
int angle = 0;
int temp;
bool incTemp = false, decTemp = false;

Servo servo;
SoftwareSerial BT(txPin,rxPin);

void setup() {
  pinMode(digitalPin, INPUT);
  pinMode(analogPin, INPUT);
  
  servo.attach(11);
  delay(100);

  BT.begin(9600);
  Serial.begin(9600);
}

void loop() {
  temp = analogRead(analogPin);
  Serial.println(temp); 

  if (BT.available())
  {
    char bytesToSend[2];
    bytesToSend[0] = 101;
    bytesToSend[1] = temp;
    bytesToSend[2] = 110;
    BT.println(bytesToSend);
  }

  if(incTemp)
  {
    servo.write(90);
    delay(100);
    servo.write(135);
    delay(100);
    servo.write(180);
    delay(100);
    servo.write(135);
    delay(100);
  }
  else if(decTemp)
  {
    servo.write(90);
    delay(100);
    servo.write(45);
    delay(100);
    servo.write(0);
    delay(100);
    servo.write(45);
    delay(100);
  }

  delay(2000);
}

Для переменных incTemp и decTemp я буду использовать прерывание, чтобы определить, когда Bluetooth-устройство посылает команду для активации сервомотора. Но пока, как видно, блоки, которые просят сервопривод вращаться, не могут быть достигнуты. Для макета я постараюсь найти симулятор, который предоставляет компоненты, которые я использую, и я вернусь с дизайном.

Позже отредактируйте, следуя совету Майенко

Вот текущий рабочий код. Ответ с полной реализацией придет, когда проект будет завершен.

#include <Servo.h>

int txPin = 1;
int rxPin = 0;
int digitalPin = 7; // KY-028 цифровой интерфейс
int analogPin = A2; // KY-028 аналоговый интерфейс
int angle = 0;
int temp;
bool incTemp = false, decTemp = false;

Servo servo;

void setup() {
  pinMode(digitalPin, INPUT);
  pinMode(analogPin, INPUT);

  Serial.begin(9600);
}

void loop() {
  temp = analogRead(analogPin);
  Serial.print("T");
  Serial.print(temp); 
  Serial.println();

  if(incTemp)
  {
    servo.attach(11);
    delay(100);
    
    servo.write(90);
    delay(100);
    servo.write(135);
    delay(100);
    servo.write(180);
    delay(100);
    servo.write(135);
    delay(100);

    servo.detach();
    delay(100);
  }
  else if(decTemp)
  {
    servo.attach(11);
    delay(100);
    
    servo.write(90);
    delay(100);
    servo.write(45);
    delay(100);
    servo.write(0);
    delay(100);
    servo.write(45);
    delay(100);

    servo.detach();
    delay(100);
  }

  delay(2000);
}

, 👍0

Обсуждение

Пожалуйста, покажите свой код и проводку., @Majenko

@Majenko Я предоставил код. Но для симулятора я не совсем уверен, что использовать. Ни Tinkercad, ни Fritzing не предоставляют всех компонентов, которые я использую..., @Gabriel Stancu

Может быть, это: https://arduinoprosto.ru/q/57584/does-softwareserial-and-the-servo-library-produce-interrupt-conflicts, @ocrdu

У меня было предчувствие,что я могу увидеть это: "SoftwareSerial BT(txPin, rxPin); ... НИКОГДА не используйте SoftwareSerial на контактах 0/1, так как они являются АППАРАТНЫМ UART. Вы используете правильные контакты, но НЕ используете SoftwareSerial. Используйте Серийный номер"., @Majenko

@Majenko Каким-то образом это работает, но я не совсем уверен, как связь Bluetooth покрывается последовательным интерфейсом. Я отредактировал пост с помощью текущего рабочего кода (я также прикрепляю сервопривод только тогда, когда это необходимо, и отсоединяю его после этого). Есть ли у вас какая-нибудь ссылка, по которой я мог бы лучше понять, почему последовательный интерфейс на самом деле отправляет данные по Bluetooth? Когда весь проект будет завершен, я в конце концов опубликую ответ с полностью работающим кодом., @Gabriel Stancu

Последовательный порт передает данные по контактам 0 и 1. Эти контакты *также* подключены непосредственно к микросхеме интерфейса USB. Именно поэтому вам также нужно отключить Bluetooth, чтобы загрузить свой код., @Majenko


1 ответ


Лучший ответ:

1

Итак, я увлекся своими экзаменами и забыл вернуться с обновлением и решением. Короче говоря, я добавил новый источник питания в схему, и я включаю сервопривод только тогда, когда нужно повернуть, а затем снова выключаю его. Код можно увидеть ниже:

#include <Servo.h>
#include <SoftwareSerial.h>

int rxPin = 2;
int txPin = 3;
int digitalPin = 7; // KY-028 цифровой интерфейс
int analogPin = A2; // KY-028 аналоговый интерфейс
int servoPin = 11;

int angle = 0;
int temp;

const int minTemp = 150;
const int maxTemp = 350;
const int minAngle = 0;
const int maxAngle = 180;
const char sendDataPackageStartByte = 'T';
const int receiveDataPackageStartByteVal = 83; //"S"
const int receiveDataPackageEndByteVal = 13; 
const int communicationDelay = 1000;
const int servoDelay = 100;

SoftwareSerial BT(rxPin,txPin);

Servo servo;
void setup() {
  pinMode(digitalPin, INPUT);
  pinMode(analogPin, INPUT);

  Serial.begin(9600);
  BT.begin(9600);
}

void loop() {
  if(BT.available() <= 0)
  {
    temp = analogRead(analogPin);
    BT.print(sendDataPackageStartByte);
    BT.print(temp/100);
    BT.print(temp/10%10);
    BT.print(temp%10); 
    BT.println();
    delay(communicationDelay);
  }
  else 
  {
    readData();
  }
}

void readData()
{
  if (BT.available())
  {       
    char temp[3];
    while(BT.available() > 0)
    {
      char crtByte = BT.read();
      if (crtByte == receiveDataPackageStartByteVal) 
      {
        temp[0] = BT.read();
        temp[1] = BT.read();
        temp[2] = BT.read();

        if(BT.read() != receiveDataPackageEndByteVal)
        {
          return;
        }
    
        break;
      } 
    }

    int desiredTemp = atoi(temp);
    int desiredAngle = map(desiredTemp, minTemp, maxTemp, minAngle, maxAngle);
    printDataToSerial(desiredTemp, desiredAngle);   

    turnServo(desiredAngle); //attach servo, write value, dettach
  }
}

void printDataToSerial(int desiredTemp, int desiredAngle)
{
  Serial.println("Желаемая температура:");
  Serial.println(desiredTemp);

  Serial.println("Нужный угол:");
  Serial.println(desiredAngle);
}

void turnServo(int angle)
{
  servo.attach(servoPin);
  delay(servoDelay);
  servo.write(angle);
  delay(servoDelay);
  servo.detach();
  delay(servoDelay);
}

Кроме того, здесь будет макет моей конечной схемы:

circuit

В основном то, что я хотел достичь, было отправкой и отображением текущей температуры с устройства Arduino на устройство Android, а затем позволить пользователю регулировать температуру, имитируя это с помощью сервопривода, управляемого по Bluetooth. Для тех, кто заинтересован в Android-части, а также (и весь проект на самом деле), вот ссылка на репозиторий проекта на GitHub. Android-часть написана на C# в Xamarin Android framework. Я надеюсь, что это поможет кому-нибудь приземлиться здесь, удачи! :D

,