settings.RMN contains a string of 00000000 (which would be replaced with a valid mobile number)
If I debug by sending the strings to the serial terminal I get what appears to be the same result of:
AT+CMGS="00000000"
for both variations which is what I would expect to get - but obviously there is a difference I cant see, because the first one works and the second doesn't.
Would it be because the first example the number string is treated differently to the second example? Hence the second example becomes an invalid AT command?
Once I finish editing all the garbage out of the code on the other computer I'll post the lot....standby
//==============================================
// Send SMS
//==============================================
void SMSsend(){
GSMSerial.println("AT+CMGF=1");
Serial.println("AT+CMGF=1");
delay(1000);
GSMSerial.println("AT+CSCA=\"+61418706700\"");
Serial.println("AT+CSCA=\"+61418706700\"");
delay(1000);
GSMSerial.println("AT+CMGS=\"00000000\"");
// GSMSerial.print("AT+CMGS=\"");
// GSMSerial.print(settings.RMN);
// GSMSerial.println("\"");
delay(2000);
GSMSerial.println(settings.SiteName);
GSMSerial.println("This is the message body");
GSMSerial.write(26);
Serial.println("AT+CMGS=\"00000000\"");
// Serial.print("AT+CMGS=\"");
// Serial.print(settings.RMN);
// Serial.println("\"");
delay(2000);
Serial.println(settings.SiteName);
Serial.println("This is the message body");
Serial.write(26);
}
//**********************************************
//===================================================================
// RTC & Time Sync
//===================================================================
void SyncTime(){
sendATcommand(AT_CCLK, "+CCLK: ", 500); //Read the RTC from the GSM/3G Module
char* valPos = ATcomResp + 19; //Find the HOURS position in the response string
TimeHours = atoi(valPos); //Read HOURS Value
TimeMinutes = atoi(valPos + 3); //Find and read the MINUTES value
TimeSeconds = atoi(valPos + 3); //Find and read the SECONDS value
setTime(TimeHours,TimeMinutes,TimeSeconds,0,0,0); //Set the clock from the RTC values
} //
//===============================================================
// GSM/3G Module AT Command send routine #1
//===============================================================
int8_t sendATcommand(char* ATcomBuf, char* expected_answer1,
unsigned int timeout)
{
uint8_t x=0, answer=0;
unsigned long previous; //char response[100];
memset(ATcomResp, EOS, 100); // Initialize the string
delay(100);
while( GSMSerial.available() > 0) GSMSerial.read(); // Clean the input buffer
GSMSerial.println(ATcomBuf); // Send the AT command
x = 0;
previous = millis();
do{ // this loop waits for the answer
if(GSMSerial.available() != 0){
ATcomResp[x] = GSMSerial.read();
x++;
if (strstr(ATcomResp, expected_answer1) != NULL){ // check if the desired answer is in the response of the module
answer = 1;
}
}
}
while((answer == 0) && ((millis() - previous) < timeout)); // Waits for the answer with time out
return answer;
}
//==============================================================
// GSM/3G Power On Command
//==============================================================
void GSM_power_on(){
Serial.println(F("3G : Module Powering Up")); // DEBUG : Power on message
uint8_t answer=0; //
answer = sendATcommand("AT", "OK", 2000); // Checks if the module is started
if (answer == 0){ // If no reply from module, turn module ON
digitalWrite(powerGSMPin,HIGH); // Power on "pulse" to the module
delay(400); //
digitalWrite(powerGSMPin,LOW); //
delay(6000); //
while(answer == 0){ // Waits for an answer from the module.....
answer = sendATcommand("AT", OK, 2000); // Checks if the module is started
Serial.println(F("Wait...")); // DEBUG : wait message
} //
} //
}
void ATResponseOK(){
strcpy_P(ATcomResp, PSTR("OK"));
}
I think I may be getting a clearer idea as to why it doesnt work after studying the received SMS
When I use the first option (which works) I seem to have some extra line breaks in the message after the SITENAME.
So I wonder if I am getting an extra line break (or two) after the number stored in (settings.RMN) which is causing the command to fail.
ie I would expect the received message to be:
SITENAME
This is the message body
But I am getting:
SITENAME
This is the Message body
Now to work out why that is happening and how I can change my config .txt file and the way its being read to overcome that....
Here is a sample of the config.txt file stored on the SD Card for reference:
// CONFIGURATION FILE - DO NOT DELETE
// TEMP TRIGGER POINT
TTP = 1
// SITE NAME
SiteName = TESTSITE
// RECIPIENT MOBILE NUMBER
RMN = 00000000
//SYSTEM PIN
SYSPIN = 1234
I thing you're looking at your problem in the right place. There must be something wrong with the content RNM.
Be aware that the serial monitor the Arduino enviroment is using will not display all control code correctly. Try to use an other terminal program for further debugging.
But remember to turn it off when uploading programs as 2 programs can not access the COM interace at the same time
Just used a different term program and there it was - a nice CR at the end of the RMN value when using the 2nd code version
Now how to remove it?
Can i somehow limit the string to 10 digits effectively dropping the CR?
Or is the way I'm reading the string including the CR in the value and I could do it differently? Use a different char to show the end of the valid data in the config file?
I was looking at that section wondering if it was including the stray CR - of course it was as each line would be ended with a CR LF and I was ending on the LF so the CR would be included in my string
Hadn't got as far as working out how to stop the CR being included.
Modified my code with your suggestion and now the CR is gone and the strings are correctly being passed to the SIMCOM module and SMS's now work with the parameters sourced from the SD CARD
Was good to learn the serial terminal issue too and I'll be sure to use a different one now so I dont get caught with that next time
I have the above working quite nicely with the temperature alarm trigger point being an integer read from the config file.
Now I want the trigger temperature to be specified to one decimal place.
ie in the config file on the SD card:
TTP = 10.5
instead of the current:
TTP = 10
So I have changed:
TTP to a float instead of int
and changed atoi to atof
I thought that would then read in the value for TTP as 10.5
But it shows it as 105............what have I done wrong (apart from everything....)
Here is the section that reads the data from the SD for the variable TTP as it stands now:
As far as I understand it, it reads all the chars after the "TTP" "=" and whitespace until the CRLF - which means the buffer should contain "10.5" (without quotes) - but it seems to hold "105" (without quotes) - why did it lose the decimal?
if(description == "TTP") {
value = "";
while(character != '\n' && character != '\r'){
if(isdigit(character)) {
value.concat(character);
} else if(character != '\n' && character != '\r'){
valid = false; // Use of invalid values
}
character = myFile.read();
};
if (valid = true) {
char charBuf[value.length()+1]; // Convert string to array of chars
value.toCharArray(charBuf,value.length()+1);
settings.TTP = atof(charBuf); // Convert chars to float
} else {
settings.TTP = 0; // revert to default value for invalid entry in settings
}
For the time being I have just added the the following to get the correct value - is this a valid fix???
PaulS - FULL code was posted previously and has been updated..............I felt there no need to waste numerous posts to repost the code all over again when the changes I made where clearly stated above.
If by your cryptic comment above you are saying that line should be:
if (valid == true) {
or maybe
if (valid) {
well they both stop the program from working.....
Currently the code as previously posted correctly assigns a value to TTP if the value is present in the config.txt file, or assigns a value of 0 to TTP if the value is missing from the config.txt file.
I'm unsure as to why that has anything to do with my missing decimal point, so I'll just stick with my /10 option as that means you don't have to help me anymore.
As the double equals things has caught me out before (many times - bangs head on table!)
So i will re-phrase my previous statement:
if (valid = true) {
produces the correct results with the value from TTP being retrieved from the SD Card if its present or returns the "default" value of "0" if its not present.
If i change the code to what it SHOULD read:
if (valid == true) {
then it always returns the default value of "0" no matter what, ignoring the TTP value on the SD Card.
This is why I am stumped on this - when the code is OBVIOUSLY WRONG it works how I want it to, when its CORRECTED it fails to produce what is expected.
In reply to your other questions about the content of those two variables:
value = 105
charBuf = 105
So it seems whilst value is a string it doesn't seem to contain the decimal place which means its not correctly reading it from the card for some reason.
as a test I forced value to what I expected it to be by inserting this after the loop:
value = ("10.5");
I then get the expected result in charBuf and the atof function works with settings.TTP also holding 10.5, so its back to how the routine is reading the SD card and why its dropping the decimal out of the string.
I freely admit I don't fully grasp how its reading the card so I'll study those few lines a bit harder to see if I can work out whats wrong - as that's how you learn this stuff!
then it always returns the default value of "0" no matter what, ignoring the TTP value on the SD Card.
I'd question exactly what value is in valid.
Apparently, valid does NOT ever contain true, until you assign it the value of true in the incorrect if statement. Without having the SD card in hand, I'd have to guess that there is not a '\n' to define the end of the record, thus valid is not being set to true, thus the proper if test never evaluates to true.