This tutorial allows the user to move a servo sending text messages with the mobile phone. Depending on the number received by the module, the servo is placed in one position or another corresponding to the indicated degrees.
Ingredients:
Preparation Time: 30 minutes
Buy nowThis project can be developed with Arduino or Intel Galileo. It is also compatible with Raspberry Pi using the Raspberry Pi to Arduino shields connection bridge.
For further information about the GPRS+GPS (SIM908) Shield, consult the main tutorial.
Connect the GPRS antenna to the shield and then, connect the shield to the Arduino or to Raspberry Pi connection bridge. Connect servo in the breadboard as you can see in the next diagram.
Connect two wires, red and black, to the two long rows on the side of the breadboard to provide access to 3.3 volt supply and ground. Servo has 3 wires with different colors. Connect Black/Brown wire to GND, Red wire to 3.3 volt and the remaining wire, Yellow/Orange, to pin 9 of Arduino. Pin 9 has PWM control so you can move your servo from 0 to 180 degrees.
Arduino:
/* * GPRS+GPS Quadband Module (SIM908) * * Copyright (C) Libelium Comunicaciones Distribuidas S.L. * http://www.libelium.com * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * a * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see http://www.gnu.org/licenses/. * * Version: 1.0 * Design: David GascĂłn * Implementation: Victor Boria */ #include <Servo.h> //Include the servo-motor library //Enter here you data const char pin_number[] = "****"; // Write the pin number of the SIM card Servo myServo; // Create a servo object int angle; // Variable to hold the angle for the servo motor int8_t answer; int onModulePin = 2; char aux_string[50]; unsigned long previous; int count; void setup() { myServo.attach(9); // Attaches the servo on pin 9 to the servo object myServo.write(90); // Set the servo in the center position pinMode(onModulePin, OUTPUT); Serial.begin(115200); Serial.println("Starting..."); power_on(); // Powering the module delay(3000); //sets the PIN code sprintf(aux_string, "AT+CPIN=%s", pin_number); sendATcommand(aux_string, "OK", 2000); delay(3000); Serial.println("Connecting to the network..."); while ( (sendATcommand("AT+CREG?", "+CREG: 0,1", 500) || sendATcommand("AT+CREG?", "+CREG: 0,5", 500)) == 0 ); Serial.print("Setting SMS mode..."); sendATcommand("AT+CMGF=1", "OK", 1000); // sets the SMS mode to text sendATcommand("AT+CPMS=\"SM\",\"SM\",\"SM\"", "OK", 1000); // selects the memory sendATcommand("AT+CNMI=2,1,0,0", "OK", 1000); // Sets mode to wait for an incoming SMS Serial.println("Waiting incoming SMS"); } void loop() { answer = sendATcommand("", "+CMTI: ", 1000); //Detect incomming SMS if (answer == 1) { count = 0; previous = millis(); do { while (((millis() - previous) < 1000) && (Serial.available() == 0)) { // Condition to avoid an overflow if ( millis() < previous) previous = millis(); } // Condition to avoid an overflow if ( millis() < previous) previous = millis(); //Search a "," in the command received } while (((millis() - previous) < 1000) && (Serial.read() != ',')); previous = millis(); do { while (((millis() - previous) < 1000) && (Serial.available() == 0)) { // Condition to avoid an overflow if ( millis() < previous) previous = millis(); } aux_string[count] = Serial.read(); count++; // Condition to avoid an overflow if ( millis() < previous) previous = millis(); } while ((aux_string[count - 1] != '\r') && ((millis() - previous) < 1000) && (count < 30)); aux_string[count - 1] = '\0'; count = atoi(aux_string); Serial.print(F("SMS index: ")); Serial.println(count, DEC); Serial.println(aux_string); if (count != 0) { //Check the comunication with the module sendATcommand("AT", "OK", 1000); //Read the received SMS snprintf(aux_string, sizeof(aux_string), "AT+CMGR=%d", count); answer = sendATcommand(aux_string, "+CMGR:", 1000); if (answer == 1) { previous = millis(); do { while (((millis() - previous) < 1000) && (Serial.available() == 0)) { // Condition to avoid an overflow if ( millis() < previous) previous = millis(); } // Condition to avoid an overflow if ( millis() < previous) previous = millis(); } while (((millis() - previous) < 1000) && (Serial.read() != '\n')); count = 0; previous = millis(); do { while (((millis() - previous) < 1000) && (Serial.available() == 0)) { // Condition to avoid an overflow if ( millis() < previous) previous = millis(); } aux_string[count] = Serial.read(); count++; // Condition to avoid an overflow if ( millis() < previous) previous = millis(); } while ((strstr(aux_string, "OK") == NULL) && ((millis() - previous) < 1000) && (count < 30)); aux_string[count - 1] = '\0'; Serial.print("Received SMS: "); Serial.println(aux_string); //Conversion de string a int angle = atoi(aux_string); //The servo turn the angle read in the SMS myServo.write(angle); } } } } void power_on() { uint8_t answer = 0; // checks if the module is started answer = sendATcommand("AT", "OK", 2000); if (answer == 0) { // power on pulse digitalWrite(onModulePin, HIGH); delay(3000); digitalWrite(onModulePin, LOW); // waits for an answer from the module while (answer == 0) { // Send AT every two seconds and wait for the answer answer = sendATcommand("AT", "OK", 2000); } } } int8_t sendATcommand(char * ATcommand, char * expected_answer, unsigned int timeout) { uint8_t x = 0, answer = 0; char response[100]; unsigned long previous; memset(response, '\0', 100); // Initialice the string delay(100); while ( Serial.available() > 0) Serial.read(); // Clean the input buffer if (ATcommand[0] != '\0') { Serial.println(ATcommand); // Send the AT command } x = 0; previous = millis(); // this loop waits for the answer do { // if there are data in the UART input buffer, reads it and checks for the asnwer if (Serial.available() != 0) { response[x] = Serial.read(); x++; // check if the desired answer is in the response of the module if (strstr(response, expected_answer) != NULL) { answer = 1; } } // Waits for the asnwer with time out } while ((answer == 0) && ((millis() - previous) < timeout)); return answer; }
Raspberry Pi:
/* * GPRS+GPS Quadband Module (SIM908) * * Copyright (C) Libelium Comunicaciones Distribuidas S.L. * http://www.libelium.com * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * a * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see http://www.gnu.org/licenses/. * * Version: 1.0 * Design: David GascĂłn * Implementation: Marcos MartĂnez */ //Include arduPi library #include "arduPi.h" int8_t sendATcommand(const char* ATcommand, const char* expected_answer, unsigned int timeout); void power_on(); void servoWrite(int servo, int angle); int servo = 9; int angle; unsigned int us; //Enter here you data const char pin_number[] = "****"; // Write the pin number of the SIM card int8_t answer; int onModulePin = 2; char aux_string[50]; unsigned long previous; int count; void setup() { pinMode(onModulePin, OUTPUT); pinMode(servo, OUTPUT); Serial.begin(115200); printf("Starting...\n"); power_on(); // Powering the module delay(3000); //sets the PIN code sprintf(aux_string, "AT+CPIN=%s", pin_number); sendATcommand(aux_string, "OK", 2000); delay(3000); printf("Connecting to the network...\n"); while ( (sendATcommand("AT+CREG?", "+CREG: 0,1", 500) || sendATcommand("AT+CREG?", "+CREG: 0,5", 500)) == 0 ); printf("Setting SMS mode...\n"); sendATcommand("AT+CMGF=1", "OK", 1000); // sets the SMS mode to text sendATcommand("AT+CPMS=\"SM\",\"SM\",\"SM\"", "OK", 1000); // selects the memory sendATcommand("AT+CNMI=2,1,0,0", "OK", 1000); // Sets mode to wait for an incoming SMS printf("Waiting incoming SMS\n"); } void loop() { answer = sendATcommand("", "+CMTI: ", 1000); //Detect incomming SMS if (answer == 1) { count = 0; previous = millis(); do { while (((millis() - previous) < 1000) && (Serial.available() == 0)) { // Condition to avoid an overflow if ( millis() < previous) previous = millis(); } // Condition to avoid an overflow if ( millis() < previous) previous = millis(); //Search a "," in the command received } while (((millis() - previous) < 1000) && (Serial.read() != ',')); previous = millis(); do { while (((millis() - previous) < 1000) && (Serial.available() == 0)) { // Condition to avoid an overflow if ( millis() < previous) previous = millis(); } aux_string[count] = Serial.read(); count++; // Condition to avoid an overflow if ( millis() < previous) previous = millis(); } while ((aux_string[count - 1] != '\r') && ((millis() - previous) < 1000) && (count < 30)); aux_string[count - 1] = '\0'; count = atoi(aux_string); printf("SMS index: %i %s\n",count,aux_string); if (count != 0) { //Check the comunication with the module sendATcommand("AT", "OK", 1000); //Read the received SMS snprintf(aux_string, sizeof(aux_string), "AT+CMGR=%d", count); answer = sendATcommand(aux_string, "+CMGR:", 1000); if (answer == 1) { previous = millis(); do { while (((millis() - previous) < 1000) && (Serial.available() == 0)) { // Condition to avoid an overflow if ( millis() < previous) previous = millis(); } // Condition to avoid an overflow if ( millis() < previous) previous = millis(); } while (((millis() - previous) < 1000) && (Serial.read() != '\n')); count = 0; previous = millis(); do { while (((millis() - previous) < 1000) && (Serial.available() == 0)) { // Condition to avoid an overflow if ( millis() < previous) previous = millis(); } aux_string[count] = Serial.read(); count++; // Condition to avoid an overflow if ( millis() < previous) previous = millis(); } while ((strstr(aux_string, "OK") == NULL) && ((millis() - previous) < 1000) && (count < 30)); aux_string[count - 1] = '\0'; printf("Received SMS: %s\n",aux_string); //Conversion de string a float angle = atof(aux_string); //The servo turn the angle read in the SMS servoWrite(servo,angle); } } } } void power_on() { uint8_t answer = 0; // checks if the module is started answer = sendATcommand("AT", "OK", 2000); if (answer == 0) { // power on pulse digitalWrite(onModulePin, HIGH); delay(3000); digitalWrite(onModulePin, LOW); // waits for an answer from the module while (answer == 0) { // Send AT every two seconds and wait for the answer answer = sendATcommand("AT", "OK", 2000); } } } int8_t sendATcommand(const char* ATcommand, const char* expected_answer, unsigned int timeout){ uint8_t x=0, answer=0; char response[100]; unsigned long previous; memset(response, '\0', 100); // Initialize the string delay(100); while( Serial.available() > 0) Serial.read(); // Clean the input buffer Serial.println(ATcommand); // Send the AT command x = 0; previous = millis(); // this loop waits for the answer do{ if(Serial.available() != 0){ // if there are data in the UART input buffer, reads it and checks for the asnwer response[x] = Serial.read(); printf("%c",response[x]); x++; // check if the desired answer is in the response of the module if (strstr(response, expected_answer) != NULL) { printf("\n"); answer = 1; } } } // Waits for the asnwer with time out while((answer == 0) && ((millis() - previous) < timeout)); return answer; } void servoWrite(int servo, int angle) { for(int i=0; i<20; i++){ us = (angle*11) + 450; // Convert angle to microseconds digitalWrite(servo, HIGH); delayMicroseconds(us); digitalWrite(servo, LOW); delay(50); // Refresh cycle of servo } } int main (){ setup(); while(1){ loop(); } return (0); }
Intel Galileo:
/* * GPRS+GPS Quadband Module (SIM908) * * Copyright (C) Libelium Comunicaciones Distribuidas S.L. * http://www.libelium.com * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * a * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see http://www.gnu.org/licenses/. * * Version: 1.0 * Design: David GascĂłn * Implementation: Jorge Casanova, Luis MartĂn */ #include <Servo.h> //Include the servo-motor library //Enter here you data const char pin_number[] = "****"; // Write the pin number of the SIM card Servo myServo; // Create a servo object int angle; // Variable to hold the angle for the servo motor int8_t answer; int onModulePin = 2; char aux_string[50]; unsigned long previous; int count; void setup() { myServo.attach(9); // Attaches the servo on pin 9 to the servo object myServo.write(90); // Set the servo in the center position pinMode(onModulePin, OUTPUT); Serial.begin(115200); Serial1.begin(115200); Serial.println("Starting..."); power_on(); // Powering the module delay(3000); //sets the PIN code sprintf(aux_string, "AT+CPIN=%s", pin_number); sendATcommand(aux_string, "OK", 2000); delay(3000); Serial.println("Connecting to the network..."); while ( (sendATcommand("AT+CREG?", "+CREG: 0,1", 500) || sendATcommand("AT+CREG?", "+CREG: 0,5", 500)) == 0 ); Serial.print("Setting SMS mode..."); sendATcommand("AT+CMGF=1", "OK", 1000); // sets the SMS mode to text sendATcommand("AT+CPMS=\"SM\",\"SM\",\"SM\"", "OK", 1000); // selects the memory sendATcommand("AT+CNMI=2,1,0,0", "OK", 1000); // Sets mode to wait for an incoming SMS Serial.println("Waiting incoming SMS"); } void loop() { answer = sendATcommand("", "+CMTI: ", 1000); //Detect incomming SMS if (answer == 1) { count = 0; previous = millis(); do { while (((millis() - previous) < 1000) && (Serial1.available() == 0)) { // Condition to avoid an overflow if ( millis() < previous) previous = millis(); } // Condition to avoid an overflow if ( millis() < previous) previous = millis(); //Search a "," in the command received } while (((millis() - previous) < 1000) && (Serial1.read() != ',')); previous = millis(); do { while (((millis() - previous) < 1000) && (Serial1.available() == 0)) { // Condition to avoid an overflow if ( millis() < previous) previous = millis(); } aux_string[count] = Serial1.read(); count++; // Condition to avoid an overflow if ( millis() < previous) previous = millis(); } while ((aux_string[count - 1] != '\r') && ((millis() - previous) < 1000) && (count < 30)); aux_string[count - 1] = '\0'; count = atoi(aux_string); Serial.print("SMS index: "); Serial.println(count, DEC); Serial.println(aux_string); if (count != 0) { //Check the comunication with the module sendATcommand("AT", "OK", 1000); //Read the received SMS snprintf(aux_string, sizeof(aux_string), "AT+CMGR=%d", count); answer = sendATcommand(aux_string, "+CMGR:", 1000); if (answer == 1) { previous = millis(); do { while (((millis() - previous) < 1000) && (Serial1.available() == 0)) { // Condition to avoid an overflow if ( millis() < previous) previous = millis(); } // Condition to avoid an overflow if ( millis() < previous) previous = millis(); } while (((millis() - previous) < 1000) && (Serial1.read() != '\n')); count = 0; previous = millis(); do { while (((millis() - previous) < 1000) && (Serial1.available() == 0)) { // Condition to avoid an overflow if ( millis() < previous) previous = millis(); } aux_string[count] = Serial1.read(); count++; // Condition to avoid an overflow if ( millis() < previous) previous = millis(); } while ((strstr(aux_string, "OK") == NULL) && ((millis() - previous) < 1000) && (count < 30)); aux_string[count - 1] = '\0'; Serial.print("Received SMS: "); Serial.println(aux_string); //Conversion de string a int angle = atoi(aux_string); //The servo turn the angle read in the SMS myServo.write(angle); } } } } void power_on() { uint8_t answer = 0; // checks if the module is started answer = sendATcommand("AT", "OK", 2000); if (answer == 0) { // power on pulse digitalWrite(onModulePin, HIGH); delay(3000); digitalWrite(onModulePin, LOW); // waits for an answer from the module while (answer == 0) { // Send AT every two seconds and wait for the answer answer = sendATcommand("AT", "OK", 2000); } } } int8_t sendATcommand(char * ATcommand, char * expected_answer, unsigned int timeout) { uint8_t x = 0, answer = 0; char response[100]; unsigned long previous; memset(response, '\0', 100); // Initialice the string delay(100); while ( Serial1.available() > 0) Serial1.read(); // Clean the input buffer if (ATcommand[0] != '\0') { Serial1.println(ATcommand); // Send the AT command } x = 0; previous = millis(); // this loop waits for the answer do { // if there are data in the UART input buffer, reads it and checks for the asnwer if (Serial1.available() != 0) { response[x] = Serial1.read(); x++; // check if the desired answer is in the response of the module if (strstr(response, expected_answer) != NULL) { answer = 1; } } // Waits for the asnwer with time out } while ((answer == 0) && ((millis() - previous) < timeout)); return answer; }
If you are interested in Internet of Things (IoT) or M2M projects check our open source sensor platform Waspmote which counts with more than 100 sensors available to use 'off the shelf', a complete API with hundreds of ready to use codes and a low consumption mode of just 0.7µA to ensure years of battery life.
Know more at:
Get the Starter Kits at:
Cooking Hacks makes electronics affordable, easy to learn and fun.
The e-commerce for worldwide community of developers, designers, inventors and makers who love creating electronics with sensors, robotics, Arduino and Raspberry Pi.
Cooking Hacks is a brand by Libelium.