Сервопривод начинает трястись, когда я добавляю SIM900.begin(19200);

Здравствуйте, я работаю над этим мини-проектом. Этот проект работает следующим образом. Всякий раз, когда кто-то вводит неправильный пароль, на ЖК-дисплее отображается «Отказано в доступе» и отправляется оповещение по SMS с использованием модуля GSM. Я использовал 2 Arduino для этого проекта. 1-й Arduino питается от моего ноутбука, здесь подключены сигнальные контакты, к которым подключены RX / TX GSM (контакты 10 и 11) соответственно, а ЖК-дисплей подключен к контакту (2- 9) и Сервопривод к (A4) . Второй Arduino, который я использовал, питался от зарядного устройства и использовал его в качестве источника питания GSM, он хорошо работает, так как мигает каждые 2 секунды. Мне действительно интересно, почему мой сервопривод трясется всякий раз, когда я добавляю SIM900.begin(9600); при настройке в Arduino IDE?

Это код

#include <Keypad.h>
#include <Password.h>
#include <Servo.h>
#include <Wire.h> 
#include <LiquidCrystal_I2C.h>

#include <SoftwareSerial.h>
SoftwareSerial SIM900(10, 11); 

LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE); 
Password password = Password( "9999" );
Servo myservo;

const byte ROWS = 4; 
const byte COLS = 4; 

char keys[ROWS][COLS] = {
    {'1','2','3','A'},
    {'4','5','6','B'},
    {'7','8','9','C'},
    {'*','0','#','D'}
};

byte rowPins[ROWS] = {3, 4, 5, 6}; 
byte colPins[COLS] = {7, 8, 9, 10}; 

Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );
int pos = 0;

void setup(){

  Serial.begin(9600);
  SIM900.begin(9600);

  myservo.attach(13); 
  lcd.begin(16, 2);
  lcd.print("Arduino Password");  
  lcd.setCursor ( 0, 1 );       
  lcd.print (" Door  Lock ");
  delay ( 2000 );
  setup1();

}
void setup1(){

  lcd.clear();
  lcd.home();
  lcd.print("Enter your code:");
  keypad.addEventListener(keypadEvent); 
}

void loop(){
  keypad.getKey();
}

//заботимся о некоторых особых событиях
void keypadEvent(KeypadEvent eKey){
  switch (keypad.getState()){
    case PRESSED:
        Serial.println(eKey);
        switch (eKey){
          case '4': checkPassword(); break;  
          case '2': password.reset(); break;
          case '8': lock(); break;
          default: password.append(eKey);
     }
  }
}

void checkPassword(){
  if (password.evaluate()){
    lcd.clear();
    lcd.print("Access granted");
    delay(1000);
    unlock();
  }else{
    lcd.clear();
    lcd.print("Access denied");
    delay(2000);
    sendSMS();
    delay(1000);


  }
  password.reset();
  delay(1000);
  setup1();
}

void unlock(){
  lcd.clear();
  lcd.print("Unlocking...");
  delay(2000);
  pos = 90;
  myservo.write(pos);
  lcd.clear();
  lcd.print("Unlocked! Press");
  lcd.setCursor(0, 1);
  lcd.print("* to lock!");
  delay(1000);
}

void lock(){
  lcd.clear();
  lcd.print("Locking...");
  delay(1000);
  pos = 0;
  myservo.write(pos);
  setup1();
}
void sendSMS() {

  SIM900.print("AT+CNMI=2,2,0,0,0\r");
  delay(100);
  SIM900.print("AT+CMGF=1\r"); 
  delay(100);
  SIM900.println("AT + CMGS = \"+6XXXXXXXXXX\""); 
  delay(100);
  SIM900.println("Wrong password Typed"); 
  delay(100);
  SIM900.println((char)26); 
  delay(100);
  SIM900.println();
  // Даем модулю время на отправку СМС
  delay(5000); 
}

, 👍0


2 ответа


1

Servo.h использует прерывания для генерации управляющего сигнала. Однако SoftwareSerial действительно портит прерывания.

Вы не можете использовать SoftwareSerial с чем-либо, что зависит от прерываний для синхронизации, например Servo.h.

Решения:

  1. Используйте лучшую версию Arduino с неиспользуемым аппаратным UART
  2. Используйте внешний аппаратный ШИМ-контроллер для управления сервоприводами.
  3. Используйте внутреннюю аппаратную ШИМ (для этого вам потребуется найти библиотеку) для управления сервоприводами.
,

Вы не можете использовать SoftwareSerial с чем-либо, использующим Timer1. Вы можете использовать любые другие прерывания, какие захотите., @Delta_G

Есть ли какая-нибудь библиотека для GSM, которая не портит прерывания? или можете ли вы предложить лучшую статью о внутреннем аппаратном ШИМ?, @Chard

@Delta_G SoftwareSerial отключает прерывания при отправке. Он также блокирует все прерывания во время приема. Вы не можете разумно использовать SoftwareSerial с *любыми* прерываниями по таймеру и заставить его делать что-то надежное., @Majenko

@Chard Возможно, вам повезет с AltSoftSerial. Однажды я видел аппаратную библиотеку ШИМ, но не могу вспомнить, где. Спросите у Гугла - она знает., @Majenko

Я попытался заменить SoftwareSerial на AltSoftSerial, но сервопривод все равно трясется., @Chard

Кстати, я использую Arduino Uno., @Chard

@Chard Тогда приобретите более подходящую плату или внешний модуль сервопривода ШИМ., @Majenko

То есть на Arduino Uno невозможно реализовать этот проект? почему? это из-за контактов прерывания?, @Chard

Это возможно – просто это непросто. Вам необходимо хорошее понимание основного оборудования. Проблема, с которой вы столкнулись, заключается в нехватке подходящих аппаратных ресурсов, поэтому вам придется использовать программную эмуляцию («Bit Banging»), чтобы обойти ее. И это не очень хорошо работает, когда вы пытаетесь делать и другие вещи., @Majenko


-1

И SoftwareSerial, и Servo пытаются использовать один и тот же аппаратный таймер Timer1. Существуют другие библиотеки сервоприводов, такие как ServoTimer2, которые позволят вам использовать SoftwareSerial, и есть другие программные последовательные библиотеки, которые позволят вам использовать Servo. Это довольно распространенная тема, которая часто всплывает. Если вы немного поискате, вы должны найти несколько решений.

,

Я использовал #include"ServoTimer2.h" и удалил #include<Servo.h>. но сервопривод все еще трясется., @Chard

SoftwareSerial *не* использует таймер. Он использует PCINT для запуска приема, и как прием, так и передача данных используют «настроенную задержку», основанную на _delay_loop_2, который представляет собой цикл жесткой блокировки, написанный на ассемблере (в файле Delay_basic.h)., @Majenko