0

Hello I'm working on this mini project. This project works this way, Whenever someone type wrong password, LCD will display "Access Denied" and send an alert to SMS using GSM module. I used 2 Arduinos for this project, The 1st Arduino is powered up by my laptop this is where the signal pins are connected the RX/TX of GSM is connected in (pin 10 and 11) respectively and the LCD is in pin (2-9) and Servo to (A4) . The second Arduino I used is powered up with a charger and used it for GSM power source it function well as it blinks every 2 sec. I'm really wondering why my servo is shaking whenever I add the SIM900.begin(9600); at the setup in Arduino IDE?

This is the code

#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();
}

//take care of some special events
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();
  // Give module time to send SMS
  delay(5000); 
}
1

Servo.h use interrupts to generate the control signal. However, SoftwareSerial really messes interrupts up.

You can't use SoftwareSerial with anything that relies on interrupts for timing, like Servo.h.

Solutions:

  1. Use a better Arduino with an unused hardware UART
  2. Use an external hardware PWM controller to drive the servos
  3. Use the internal hardware PWM (you'd need to find a library to do this) to drive the servos.
  • You can't use SoftwareSerial with anything that uses Timer1. You can use all the other interrupts that you want. – Delta_G Jan 27 at 17:50
  • Is there any library available for gsm that won't messes interrupts? or can you suggest a best article for the internal hardware PWM ? – Chard Jan 27 at 17:54
  • @Delta_G SoftwareSerial disables interrupts when sending. It also blocks all interrupts while receiving. You can't sensibly use SoftwareSerial with any timer interrupts and have it do anything reliable. – Majenko Jan 27 at 17:56
  • @Chard You may get better luck with AltSoftSerial. I did see a hardware PWM library around once, but I can't recall where. Ask Google - she knows. – Majenko Jan 27 at 17:57
  • I tried to replace SoftwareSerial to AltSoftSerial but stil the servo is shaking. – Chard Jan 27 at 18:58
0

Both SoftwareSerial and Servo are trying to use the same hardware timer, Timer1. There are other servo libraries like ServoTimer2 that will allow you to use SoftwareSerial and there are other soft serial libraries that will allow you to use Servo. It is a pretty common topic that comes up a lot. If you search a little bit you should find several solutions.

  • I used the #include"ServoTimer2.h" and remove the #include<Servo.h>. but the servo is still shaking. – Chard Jan 27 at 18:20
  • SoftwareSerial does not use a timer. It uses PCINT to trigger reception, and both reception and transmission of data use a "tuned delay" based on _delay_loop_2 which is a hard blocking loop written in assembly (in delay_basic.h). – Majenko Jan 28 at 15:59

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.