serial connection to c168i

Hi all. I have read and found several examples where people have sent sms messages from a c168i, here is just one example:

My own code makes the arduino act as a temperature sensor and send a texts at a regular interval or when the temperature gets too low. The code works for the most part, but sometimes ends up sending the texts too often and with the exact same temperature reading. I suspect that there is some serial communication problem that just accumulates until it gets to the point where the phone is not put into the correct mode or something weird. Would anyone mind giving this a look over and checking whether I am doing something wrong?

Thanks

//TMP36 Pin Variables
int sensorPin = 0; //the analog pin the TMP36's Vout (sense)

long interval = 20000; //how often to check
long day = 1200000;
float low_temp = 71;

long time = 0;
float tempF = 0;

void setup(){
  

}

void loop(){
  CheckTemp();

    if (tempF < low_temp){
        SendText(tempF);
        time = time-16000+interval;
    }
    else if(time == day){
        SendText(tempF);
        time = 0;
    }
    else{
        time = time + interval;
    }
    delay(interval);
    //SendText(tempF); 
}


void CheckTemp(){
  int reading = analogRead(sensorPin);  
  float voltage = reading * 5.0;
  voltage /= 1024.0; 
  tempF = ((voltage - 0.5) * 900.0 / 5.0) + 32;  
}


void SendText(float msg) {
  Serial.begin(4800); // Open serial connection at baud rate of 4800
  delay(2000);

  Serial.println("AT"); // Sends AT command to wake up cell phone
  delay(2000);

  Serial.println("AT+CMGF=1"); // Puts phone into SMS mode
  delay(2000); // Wait a second

  Serial.println("AT+CMGW=\"+15555555555\""); // Creates new message to number
  delay(2000);

  Serial.println("The temperature is"); // Message contents
  Serial.println(msg);
  delay(2000);

  Serial.write(26);
  delay(2000);

  Serial.println("AT+CMSS=1"); // Sends message at index of 1
  delay(2000);

  Serial.println("AT+CMGD=1"); // Deletes message at index of 1
  delay(2000);
  Serial.end();
  
}
        time = time + interval;

Adding times is not a good idea. Overflow is not handled properly with addition.

    delay(interval);

If you are going to use the dreaded delay(), why bother with relative times, anyway.

  Serial.begin(4800); // Open serial connection at baud rate of 4800

This belongs in setup(). You don't need to do this every time you want to send a text message.

  delay(2000); // Wait a second

Can't count, huh?

  Serial.end();

You don't ever need to do this.

Every AT command elicits a response. Why do you not read the responses?

PaulS:

        time = time + interval;

Adding times is not a good idea. Overflow is not handled properly with addition.

    delay(interval);

If you are going to use the dreaded delay(), why bother with relative times, anyway.

I initially tried to not use the "dreaded delay". You may be correct, and this could be part of my problem. I will try and revert back to code that does not use the delay.

PaulS:

  Serial.begin(4800); // Open serial connection at baud rate of 4800

This belongs in setup(). You don't need to do this every time you want to send a text message.

  Serial.end();

You don't ever need to do this.

I did have this in the "setup", but I moved it into the loop because I was afraid that there was some sort of connection issue between my code and the phone (over time). I will move it back.

PaulS:

  delay(2000); // Wait a second

Can't count, huh?

I can't tell you how hard this made my laugh! :slight_smile: Initially, it was 1000, but I did end up changing it.

PaulS:
Every AT command elicits a response. Why do you not read the responses?

I suppose I could, I am not sure where I would store them? How could I read these?

I suppose I could, I am not sure where I would store them? How could I read these?

You read them using Serial.available() to determine if there is anything to read, and Serial.read() to read the reply, one character at a time.

Now, perhaps you see why connecting the c168i to the hardware serial port was not a good idea. Now, you have nowhere to send the debug/reply data.

OK I have re-written the code. How does this look?

long prev1 = 0;
long prev2 = 0;
int sensorPin = 0; //the analog pin the TMP36's Vout (sense)
float current_tempF = 0;
long check_interval = 3000;
long text_interval = 120000;

void setup() {
  Serial.begin(4800);
}

void loop() {
    long now = millis();

  do {
    now = millis();
    
    //check if temperature is low
    if( now - prev2 > (check_interval) ){
      CheckTemp();
      if( current_tempF < 60 ){
        SendText(current_tempF);
      }
      prev2 = millis();
    }
    //send the daily text message
    if( now - prev1 > (text_interval) ) {
      CheckTemp();
      SendText(current_tempF);
      prev1 = millis();
    }

  } while( true );
}

void CheckTemp(){
  int reading = analogRead(sensorPin);  
  float voltage = reading * 5.0;
  voltage /= 1024.0; 
  current_tempF = ((voltage - 0.5) * 900.0 / 5.0) + 32;  
}

void SendText(float msg) {
  pinMode(13, OUTPUT); // Initialize pin 13 as digital out (LED)

  Serial.println("AT"); // Sends AT command to wake up cell phone
  delay(1000);

  Serial.println("AT+CMGF=1"); // Puts phone into SMS mode
  delay(1000); // Wait a second

  Serial.println("AT+CMGW=\"+17084979117\""); // Creates new message to number
  delay(1000);

  Serial.print("The temperature is:"); // Message contents
  Serial.println(msg);
  delay(1000);

  Serial.write(26);
  delay(1000);

  Serial.println("AT+CMSS=1"); // Sends message at index of 1
  delay(1000);

  Serial.println("AT+CMGD=1"); // Deletes message at index of 1
}

After testing, there is still something wrong with the text messages. They appear in the outbox, and the content looks good, however, there is a red circle with a slash though it when I look at the list of messages sitting in the outbox and they do not always get sent.

Does this make any sense?

EDIT: REMOVED, BAD POST

I am trying to listen to the phones serial response.

That's not all that you are trying to do. Ditch the rest of the crap until you know that you can get the phone's response.

Where in that code do you try to read a response? It's all talk, talk, talk. No listen anywhere.

I appologize, I made a mistake and posted the incorrect code. I have removed it to hopefully avoid confusion.

Here is my code that I used to try and listen:

EDIT: UPDATED CODE TO BELOW:

long prev1 = 0;

#include <SoftwareSerial.h>
SoftwareSerial mySerial(2,3); // RX, TX

void setup(){
  Serial.begin(9600);
  mySerial.begin(4800);
}

void loop() {
      long now = millis();

  do {
    now = millis();
    
    if( now - prev1 > (3000) ){
      SendText();

      prev1 = millis();
    }

  } while( true );
}

void SendText() {
  mySerial.println("AT+SWRESET");
  Serial.write(mySerial.read());
  delay(500);
  
  mySerial.println("AT"); // Sends AT command to wake up cell phone
  Serial.write(mySerial.read());
  delay(500);

  mySerial.println("AT+CMGF=1"); // Puts phone into SMS mode
  Serial.write(mySerial.read());
  delay(1000); // Wait a second

  mySerial.println("AT+CMGW=\"+17084979117\""); // Creates new message to number
  Serial.write(mySerial.read());
  delay(1000);

  mySerial.print("The temperature is:"); // Message contents
  mySerial.println("80");
  Serial.write(mySerial.read());
  delay(1000);

  mySerial.write(26);
  Serial.write(mySerial.read());
  delay(1000);

  mySerial.println("AT+CMSS=1"); // Sends message at index of 1
  Serial.write(mySerial.read());
  delay(1000);

  mySerial.println("AT+CMGD=1"); // Deletes message at index of 1
  Serial.write(mySerial.read());
  Serial.println('X');
}

UPDATE:
I switched the serial port used to communicate with the phone to the softserial (2,3), and was able to get some response from my phone. Here is what I get when I run the code used in the previous post:

ÿÿÿÿÿÿÿÿX
ÿÿÿÿÿÿÿÿX
ÿÿÿÿÿÿÿÿX
ÿÿÿÿÿÿÿÿX
ÿÿÿÿÿÿÿÿX
ÿÿÿÿÿÿÿÿX
ÿÿÿÿÿÿÿÿX
ÿÿÿÿÿÿÿÿX
ÿÿÿÿÿÿÿÿX
ÿÿÿÿÿÿÿÿX
ÿÿÿÿÿÿÿÿX
ÿÿÿÿÿÿÿÿX
ÿÿÿÿÿÿÿÿX

my serial monitor is set to 9600, does anyone know what this means?

Seems like this is the serials version of -1 (255)? Anyone know how I can use that?

  do {
    now = millis();
    
    if( now - prev1 > (3000) ){
      SendText();

      prev1 = millis();
    }

  } while( true );

Why are you using a do/while construct?

Why are you looping inside loop at all?

my serial monitor is set to 9600, does anyone know what this means?

Yes. It means that you didn't bother calling the available() method to see if there was anything to read before you tried to (and failed) to read. The funny y/-1 is the result of reading when there is nothing to read.

Since you never get any response, I would not be convinced that the phone is working/wired correctly.

So forget about the do loop, I just copied that from my other code.

The serial connection is hooked up correctly, because the phone does compose the text message, just doesnt always send. Is there any other way I can troubleshoot this?