I have stumbled across various solutions for the interface and sketch code for an Arduino using Siemens TC35i, but I can't seem to find anything that works.
I am wondering if anyone has a basic sketch out there that can send an SMS text message from the Arduino using what I believe is AT commands.
Also seperate to this I can't make out why a supply of 2A is required, I connected a 300mA supply @ 8v and when powered up, I can ring the number on the sim card inserted to the Siemens TC35i and get a ringing noise on my mobile phone. So surely the power supply can handle sending a SMS text message.
Current code:
#include <SoftwareSerial.h>
char gsm_char=0; //Stores character from the gsmSerial
SoftwareSerial gsmSerial(0,1); //Creates a software serial port. (rx,tx)
void setup()
{
//Initialize serial ports for communication.
Serial.begin(9600);
gsmSerial.begin(9600);
Serial.println("Starting TC35 and debug Communication...");
}
void loop() {
//If a character comes in from the cellular module...
if(gsmSerial.available() > 0){
gsm_char=gsmSerial.read(); //Store the char in gsm_char.
Serial.print(gsm_char); //Print it to debug serial
}
//Read serial input
if(Serial.available() > 0){
gsm_char=Serial.read(); //Store char in gsm_char (Not really from the gsm, just saving some memory)
delay(2000);
//Evaluate input.
if(gsm_char=='t'){
gsmSerial.print("AT\r"); //Send test connection response should be OK
} else if(gsm_char=='g'){
gsmSerial.print("AT+CMGF=1\r"); //Set text mode.
} else if(gsm_char=='s'){
//Send sms!
gsmSerial.print("AT+CMGS=+44XXXXXXXXXX"); //AT command to send SMS
delay(100);
gsmSerial.print("Hello World"); //Print the message
delay(10);
gsmSerial.print("\x1A"); //Send it ascii SUB
}
}
}
If you are sure the gsm module is working and you don't get any response try sending AT commands with println() instead of print(). The modem expect's CR and LF characters at the end of each AT command;
I had quite some problems with a TC35 board (note not the TC35i) in combination with the AT+CMGF=1\r command.
It turned out that depending on the delay ofter this command, an SMS was send (or not). The worst thing was that the required amount of delay was depending on the length of the SMS message.
Hello folks
I'm using this modem a while ago.I had made a small .h file with some functions to deal with it.
In future I will create a library but for now I'm out of time.
If you want to use it all you have to do is include this file and then call the functions in the main program.
The file is away of be perfect, like I said it not finished and should contain some bugs
To use the functions here is an example for those don't understand how to use it:
Wowzers Hugo Just D/L the header file and had a brief read of it. It looks very impressive and seems to cover most of the basic functions you would like to use a TC35i (using AT command set).
Correct me if I am wrong, but you can read a sms message with this and it extracts the data into an array? This is exactly the purpose I got my TC35i modem for, since when it recieves a message saying "heating on", I want my Arduino Uno to in turn bring in a relay which will drive my heating.
I'll have further look into the .h file, but it all looks very good so far, and neatly presented.
Correct me if I am wrong, but you can read a sms message with this and it extracts the data into an array? This is exactly the purpose I got my TC35i modem for, since when it recieves a message saying "heating on", I want my Arduino Uno to in turn bring in a relay which will drive my heating.
Yes it can handle sms
*senderID = get_SMS_ID_Sender();//The function get_SMS_ID_Sender() will return a pointer that points to a variable containing the number of the sms sender
*messageBody = get_corpo_sms(); //this function return a pointer that points to a variable cointaining a string
The code is not prepared to use a softserial unfortunately, so you need to use a UART Port.
I will try to implement that later.
Thanks for your feedback
If you have any trouble just ask
/*
Arduino 1.0.1
This sketch reads TC35 SMS to control items
connected to the Arduino.
The readTC35 and readkeyboard functions are from
Process incoming serial data without blocking by Nick Gammon
http://gammon.com.au/serial
The rest of the sketch is by me
Run this sketch and enter the folowing AT commands
in the Serial Monitor to set user profile
you only need to do this once.
AT+CMGF=1 for txt mode
AT+CNMI=2,1,0,0,1 message indication
AT^SMGO=1 SMS full indication
AT&W store to memory
To check what you have entered
AT&V display current configuration
*/
#include <SoftwareSerial.h>
SoftwareSerial gsmSerial(2,3);
//-------- TC35 GSM ---------------
int SMS_location_number;
const unsigned int MAX_INPUT = 165; // 160 characters for SMS plus a few extra
static unsigned int input_pos = 0;
void setup() {
Serial.begin(9600);
gsmSerial.begin(9600);
//--- turn on TC35 ---
// wire pin 8 Arduino to IGT pin on TC35
// it grounds IGN pin for 100 ms
// this is the same as pressing the button
// on the TC35 to start it up
pinMode(8, INPUT);
digitalWrite(8, LOW);
pinMode(8, OUTPUT);
delay(100);
pinMode(8, INPUT);
}//------ End setup -------
void loop() {
readTC35();
readKeyboard();
}//------ End loop --------
//---------------------------- Read TC35 ------------------------------------
// Read data from the TC35, When a linefeed is read the data is processed
void readTC35(){
static char input_line [MAX_INPUT];
//static unsigned int input_pos = 0;
if (gsmSerial.available () > 0)
{
while (gsmSerial.available () > 0) {
char inByte = gsmSerial.read ();
switch (inByte)
{
case '\n': // end of text
input_line [input_pos] = 0; // terminating null byte
// terminator reached! process input_line here ...
process_data (input_line);
// reset buffer for next time
input_pos = 0;
break;
case '\r': // discard carriage return
break;
default:
// keep adding if not full ... allow for terminating null byte
if (input_pos < (MAX_INPUT - 1))
input_line [input_pos++] = inByte;
break;
} // end of switch
} // end of while incoming data
} // end of if incoming data
} // end of readTC35
//---------------------------- Read Keyboard --------------------------------
void readKeyboard(){
static char input_line [MAX_INPUT];
//static unsigned int input_pos = 0;
if (Serial.available () > 0)
{
while (Serial.available () > 0) {
char inByte = Serial.read ();
switch (inByte)
{
case '\n': // end of text
input_line [input_pos] = 0; // terminating null byte
// terminator reached! process input_line here ...
// if its an AT command, send it to TC35 without processing
// ---------------- a --------------------- A -------------------- t -------------------- T --
if(input_line[0] == 97 || input_line[0] == 65 && input_line[1] == 116 || input_line[1] == 84){
gsmSerial.println(input_line);
}
else{
process_data (input_line);
}
// reset buffer for next time
input_pos = 0;
break;
case '\r': // discard carriage return
break;
default:
// keep adding if not full ... allow for terminating null byte
if (input_pos < (MAX_INPUT - 1))
input_line [input_pos++] = inByte;
break;
} // end of switch
} // end of while incoming data
} // end of if incoming data
} // end of readKeyboard
//---------------------------- process_data --------------------------------
void process_data (char * data){
// display the data
Serial.println (data);
if(strstr(data, "??")){ // If data contains ?? display the menu
Serial.print("\r\n Keyboard Help Menu\r\n ?? This Menu\r\n readsms List the SMS messages\r\n smsgone Delete all SMS messages\r\n");
}
if(strstr(data, "+CMGR:") && strstr(data, "+448080808080")){
// Reads the +CMGR line to check if SMS is from a known Phone number
// This if statement could cover the whole of the process_data function
// then only known a phone number could control the Arduoino
}
if(strstr(data, "readsms")){ // If data contains readsms
gsmSerial.println("AT+CMGL=\"ALL\""); // Read all SMS on the SIM
}
if(strstr(data, "smsgone")){
delete_All_SMS();
}
if(strstr(data, "^SMGO: 2")){ // SIM card FULL
delete_All_SMS(); // delete all SMS
}
if(strstr(data, "+CMTI:")){ // An SMS has arrived
char* copy = data + 12; // Read from position 12 until a non ASCII number to get the SMS location
SMS_location_number = (byte) atoi(copy); // Convert the ASCII number to an int
gsmSerial.print("AT+CMGR=");
gsmSerial.println(SMS_location_number); // Print the SMS in Serial Monitor
} // this SMS data will go through this process_data function again
// any true if statements will execute
if(strstr(data, "Heating on")){ // If data contains Heating on
Serial.println("Heating is switched ON"); // Control your syuff here
//delete_one_SMS(); // delete the SMS if you want
}
if(strstr(data, "Heating off")){
Serial.println("Heating is switched OFF");
//delete_one_SMS();
}
if(strstr(data, "Lights on")){
Serial.println("Lights are ON");
//delete_one_SMS();
}
if(strstr(data, "Lights off")){
Serial.println("Lights are OFF");
//delete_one_SMS();
}
} //--------------------------- end of process_data ---------------------------
void delete_one_SMS(){
Serial.print("deleting SMS ");
Serial.println(SMS_location_number);
gsmSerial.print("AT+CMGD=");
gsmSerial.println(SMS_location_number);
}
void delete_All_SMS(){
for(int i = 1; i <= 20; i++) {
gsmSerial.print("AT+CMGD=");
gsmSerial.println(i);
Serial.print("deleting SMS ");
Serial.println(i);
delay(500);
}
}
Looks like my weekend is sorted, I have pretty much a small snipet of code running at the moment, that can do the following;
Send SMS
Read SMS
My task was to read the sms then store into an array of some sort, then learn how to parse out the actual message content recieved.
Next step would be to make it automatically get the new message and do the same with the data. Followed by the deletion of that message making it available for the next command.
I noted the code was for TC35 not TC35i, but that neither here nor there as AT commands and functionality are pretty much all the same from various modems including phones.
Hugo and LJRob, thanks a bunch and shall keep you posted on how the project goes.
Hopefully I will eventually be able to post a YouTube video on the working solution......fingers crossed
Regards
Dan
P.S both examples and coding is well written, and well documented. Makes it great for understanding the functionality.
All is going quite well at the moment during a debug stage and understanding of the code.
As I progress I have been editing it slightly to meet the demand and eliminate code that isn't required.
As it stands I can send an sms, heating on/off, lights on/off, and create actions based on this (currently LED change state). I added a feature so that when the heating/lighting changes state it replies with a message for example, "Heating is now on" to let the user (myself) know that it has been actioned. At a later date this will be done by a fail safe connection from a relay, so unless the relay is energised the light can't be on.
Added a general status function in which acts on the command status, and then produces "Heating ON, Lighting OFF" for example.
Going to start having a look at ripping apart a smoke alarm for fire detection, get a PIR for house alarm etc.
Would you be able to post up your code for receiving SMSs messages?
I am working on a project where, when a smoke detector is activated, it sends an RF signal to my Arduino which then calls or texts (or both) my phone. It is working great but I want to be able to send an SMS containing a phone number to Arduino which then becomes the default number that is called when the smoke detector is triggered. In summary I am having no joy receiving SMSs!
I found this for anyone that was looking to use the siemens mc35i gsm modem for controlling your house heat remotely. I'm sure you can change the code for other uses.
Arduino based House Heater Controler with SMS User Interface in the Instructables web site.
Good afternokn guys.
Long overdue latest update. I am having great success the tc35i using the above code + some tweeks. However I'm rather stuck in tackling a problem with this code. When I attach my other functions temperate reading, setting and LCD updates, because of the delays used it misses the incoming message signal.
Is there any way to attach an interrupt with the serial? Or am I looking down the wrong path.
I basically need the program to constantly monitor temperature readings and display them on the LCD. But in doing this the software misses the moment the serial recieves the new message command.
Any help is much appreciated guys, if you need any further information or my latest could just let me know.
When I attach my other functions temperate reading, setting and LCD updates, because of the delays used it misses the incoming message signal.
It should not be missed since it will stay in serial port buffer waiting to be read.You must insure you are "looking" in your loop if there is something to read (if (Serial.available()) and if there is something read it to prevent Serial buffer overflow.
Thank you for the prompt response Hugo.
From my understanding/small experience so far, if the programming is calculating something in a loop. The serial.available misses the transmission as it isn't being called for looked at whilst in a processing loop. Does the serialevent function manage to capture serial data received whilst processing something else?
In a nutshell I need to capture serial command (+CMTI) sent by the GSM modem which alerts a received SMS. The code earlier in this thread works as a live serial stream, but not whilst processing something.
Kind regards Dan.
P.s would you like to see the full latest code I have so far?
Does the serialevent function manage to capture serial data received whilst processing something else?
Yes.The serial interface still received data while the cpu is doing another things, and will put the incoming bytes in a Serial buffer to be read in a near future.This buffer has a limit and if you don't read it, it will overflow and you loose data.
P.s would you like to see the full latest code I have so far?