Hi I am building a pet feeder using Arduino Uno and GSM module. The other components that I use are LM35, Servo motor, motor driver shield and DC fan, Ultrasonic sensor and vibration motor. The servo motor will rotate based on timer(millis function) and GSM. While most of the components are working well, I am having trouble with the receiving part of the GSM. So here is my code
#include <Servo.h>
#include <SoftwareSerial.h>
SoftwareSerial mySerial(9, 10);
#define PIN_SERVO 11
#define pwm 3
#define pwm2 5
Servo feedServo;
//unsigned long feedIntervalFullMsec = 28800000; // 8 hours
unsigned long feedIntervalMiniMsec = 600000; // 10 minutes
int middle;
int sample = 5;
long cm;
float median, w;
float reading[5];
const int inPin = 0;
const int trigger=6;
const int echo=7;
float distance;
float feedlevel;
float currentlevel;
float feederlevel;
float celsius;
int rotation = 4;
int reset = 2;
int beefy = 12;
int feedRate = 103; // 90+23
int feedReversal = 77; // 90-23
int n = 0;
boolean triggerMeal = false;
unsigned long nextFullFeedTime = 60000; // 1 minute
char inchar; // Will hold the incoming character from the GSM shield
void setup()
{
Serial.begin(9600);
mySerial.begin(9600);
pinMode(rotation, OUTPUT);
pinMode(reset, OUTPUT);
pinMode(beefy, OUTPUT);
delay(20000);
mySerial.print("AT+CNMI=2,2,0,0,0\r"); // blurt out contents of new SMS upon receipt to the GSM shield's serial out
Serial.println("Ready...");
}
void loop()
{
unsigned long timeNow = millis();
int value = analogRead(inPin);
float millivolts = (value / 1024.0) * 5000;
celsius = millivolts / 10;
Serial.println(celsius);
if(celsius < 24)
{
analogWrite(pwm, 0);
digitalWrite(rotation, HIGH);
digitalWrite(reset, HIGH);
//fanOn();
}
else if(celsius >= 26 && celsius < 29)
{
analogWrite(pwm, 120);
digitalWrite(rotation, HIGH);
digitalWrite(reset, HIGH);
digitalWrite(beefy, HIGH);
fanOn();
}
else if(celsius > 29)
{
analogWrite(pwm, 240);
digitalWrite(rotation, HIGH);
digitalWrite(reset, HIGH);
digitalWrite(beefy, HIGH);
}
if(mySerial.available() >0)
{
inchar=mySerial.read();
if (inchar=='F')
{
if (mySerial.find("eed"))
{
nextFullFeedTime = timeNow + feedIntervalMiniMsec;
triggerMeal = true;
delay(100);
}
}
else if (inchar == 'S')
{
if (mySerial.find("tatus"))
{
feederstatus();
delay(100);
}
}
mySerial.println("AT+CMGD=1,4"); // delete all SMS
}
// if we met the feed time...
if ((long)(timeNow - nextFullFeedTime) >= 0)
{
nextFullFeedTime = timeNow + feedIntervalMiniMsec;
triggerMeal = true;
}
// trigger a feeding (turn servo and vibration motor)
// since nothing else should run during feeding, delay() is fine
if (triggerMeal)
{
analogWrite(pwm, 0);
feedServo.attach(PIN_SERVO);
ultrasonic();
delay(3000);
currentlevel = distance;
feedlevel = currentlevel + 4;
do
{
analogWrite(pwm2, 230);
feedServo.write(feedReversal);
delay(900);
feedServo.write(feedRate);
delay(300);
feedServo.write(feedReversal);
delay(200);
ultrasonic();
} while ( distance <= feedlevel);
analogWrite(pwm2,0);
feedServo.detach();
triggerMeal = false;
feederReply();
}
}
void ultrasonic()
{
for (int k=0; k< sample; k++)
{
// Trigger US-100 to start measurement
// Set up trigger
digitalWrite(trigger,LOW);
delayMicroseconds(5);
// Start Measurement
digitalWrite(trigger,HIGH);
delayMicroseconds(10);
digitalWrite(trigger,LOW);
reading[k]=pulseIn(echo,HIGH);
reading[k] = reading[k]*0.01657;
Serial.print(reading[k]);
Serial.println(", ");
// Acquire and convert to mtrs
// distance=pulseIn(echo,HIGH);
// distance=distance*0.01657;
// send result to UART
// Serial.println(distance);
// delay(50);
}
medianfilter();
}
void medianfilter()
{
//sort the value of array
for (int i=0; i< sample-1; i++)
{
for (int j=i+1; j< sample; j++)
{
if (reading[i] > reading[j])
{
w = reading[i];
reading[i] = reading[j];
reading[j] = w;
}
}
}
//find the middle value of the sample
median = reading[2]; //since median of 5 is 3.
distance = median;
Serial.print("Distance is ");
Serial.println(distance);
}
void feederstatus()
{
ultrasonic();
feederlevel = ((15 - distance) / 15)*100;
mySerial.print("AT+CMGF=1\r"); // set SMS mode to text
//delay(1000);
mySerial.println("AT+CMGS=\"+639771003540\"\r"); // Insert number with country code here
delay(1000);
mySerial.println("The feeder level is "); // Message that will send
mySerial.println(feederlevel);
mySerial.println("%. \n");
mySerial.println("The temperature is ");
mySerial.println(celsius);
mySerial.println("C. \n");
delay(100);
mySerial.println((char)26);
delay(1000);
}
void feederReply()
{
mySerial.print("AT+CMGF=1\r"); // set SMS mode to text
//delay(1000);
mySerial.println("AT+CMGS=\"+639771003540\"\r"); // Insert number with country code here
delay(1000);
mySerial.println("Your Pet has been feed."); // Message that will send
delay(100);
mySerial.println((char)26);
delay(1000);
}
void fanOn()
{
mySerial.print("AT+CMGF=1\r"); // set SMS mode to text
//delay(1000);
mySerial.println("AT+CMGS=\"+639771003540\"\r"); // Insert number with country code here
delay(1000);
mySerial.println("The fan has been turned ON."); // Message that will send
delay(100);
mySerial.println((char)26);
delay(1000);
}
Basically, the gsm should only read two SMS messages, "Feed" and "Status". The problem is the "feed" part, it should turn the servo motor on but it does not work when I send the sms message on my phone. However, the "status" part works fine and sends the user the sensor values. In addition, the "status" triggers the servo motor which I did not programmed it to do. Can anyone help me with this dilemma?
here is my circuit diagram
