Go Down

Topic: *SOLVED* Only every 2nd sms gets send (SM5100B) (Read 2466 times) previous topic - next topic

Stevanx

Sep 29, 2014, 03:49 pm Last Edit: Oct 02, 2014, 04:21 pm by Stevanx Reason: 1
Hello.

I am writing some code for an arduino mega with a SM5100B. Measuring some ADC and then send an sms.

The problem I have run into is that somehow it will only send an SMS every 2nd time and when it seems like it is "behind" the count (when it is at 3rd sms it sends sms number 2, when at 5th it sends sms nr 3 and so forth)

code for sending SMS
Code: [Select]

void sendSMS(char *phone, char *msg) {
       Serial1.print("AT+CMGS=");
Serial1.write(34);   // ASCII equivalent of "
Serial1.print(phone); // Use international format: 0045xxxxxxxx with ""
Serial1.write(34);   // ASCII equivalent of "
Serial1.write((byte)13);
Serial1.write((byte)10);
delay(250); // Give the module some thinking time
Serial1.print(msg); // The sms message in ""
delay(250);
Serial1.write((byte)26); // ASCII equivalent of Ctrl-Z, tell the GSM module we finished the message
Serial1.println()
}

I tried removing the last println, but then it just shifts when it sends (same behavior but it's the evens instead of the odds it sends)

Please help or ask if I need to post more information :)

Best regards

robtillaart

Do you check if there is a msg in progress?

posting the whole code is according to the guidelines "how to use the forum" ;)
Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

Stevanx

Code: [Select]
#include "HardwareSerial.h"
#include "string.h"
#include "Arduino.h"

#define numberOfPumps 1 // Number of pumps connected - Always start from pump 1 and increment.
#define cellphoneNumber "004560649717" // The phone to send sms to.

#define debugFlag 0 // This enables debug sms and serial data

#define relayPinStart 39 // Pin number of the digital pin right before first relay pin.
String inputString = "";         // a string to hold incoming data
boolean stringComplete = false;  // whether the string is complete
boolean moduleReady = false; // Is GSM module ready?
volatile unsigned int globalCounter = 0; // Global time counter.
volatile unsigned int nextPhase = 1; // Where in the startstop process are we.

// Function for sending SMS.
void sendSMS(char * phone, char * msg) {
// Serial1.println("AT+CMGF=1");  // This line is needed if GSM module is not configured to use text instead of PDU (can be saved to non volatile memory with AT&W command)
// delay(200);
Serial1.flush();
Serial1.print("AT+CMGS=");
Serial1.write(34);   // ASCII equivalent of "
Serial1.print(phone); // Use international format: 0045xxxxxxxx with ""
Serial1.write(34);   // ASCII equivalent of "
Serial1.write((byte)13);
Serial1.write((byte)10);
#if debugFlag == 1
Serial.print("AT+CMGS=");
Serial.write((byte)34);   // ASCII equivalent of "
Serial.print(phone); // Use international format: 0045xxxxxxxx with ""
Serial.write((byte)34);   // ASCII equivalent of "

Serial.write((byte)34);   // ASCII equivalent of "
Serial.print(phone); // Use international format: 0045xxxxxxxx with ""
Serial.write((byte)34);   // ASCII equivalent of "
Serial.println();
#endif
delay(250); // Give the module some thinking time
Serial1.print(msg); // The sms message in ""
Serial1.write((byte)26); // ASCII equivalent of Ctrl-Z, tell the GSM module we finished the message
delay(250);
Serial1.println();
}

// Initializing.
void setup() {
//Initialize serial ports for communication.
Serial.begin(9600);
Serial.println("Hello. Starting up microprocessor.");
delay(1000);
Serial1.begin(9600);
Serial.println("Starting SM5100B Communication!");

noInterrupts(); // Disallow interrupts

//Initialize interrupt for 1ms counter (timer 0 @ 1kHz)
TCCR0A = 0;// Set entire TCCR0A register to 0
TCCR0B = 0;// Same for TCCR0B
TCNT0  = 0;// Start counter value to 0
// set compare match register for 1kHz increments
OCR0A = 250;// = (16*10^6) / (1000*64) - 1 (must be <256) = 250,004
// turn on CTC mode
TCCR0A |= (1 << WGM01);
// Set CS01 and CS00 bits for 64 prescaler
TCCR0B |= (1 << CS01) | (1 << CS00);   
// enable timer compare interrupt
// TIMSK0 |= (1 << OCIE0A);

interrupts(); // Allow interrupts

pinMode(13, OUTPUT);
pinMode(40, OUTPUT);
pinMode(41, OUTPUT);
pinMode(42, OUTPUT);
pinMode(43, OUTPUT);
pinMode(44, OUTPUT);
}

// Dont do anything before GSM module is ready routine + Printing GSM module output to RS232 serial.
void GSMcheck() {
if ((stringComplete)) {
if (inputString == "+SIND: 1") {
Serial.println("SIM Found");
}

if (inputString == "+SIND: 11") {
Serial.println("Network found");
}

if (inputString == "+SIND: 4") {
Serial.println("AT module fully ready");
moduleReady = true;
#if debugFlag == 1
delay(100);
sendSMS(cellphoneNumber, "AT module ready. Starting start/stop test.");
#endif
delay(2500);
Serial.println("Starting timer...");
TIMSK0 |= (1 << OCIE0A); // Enable timer compare interrupt
}

Serial.println(inputString);
// Clear the string:
inputString = "";
stringComplete = false;
}
}

// LED blinking when GSM is ready and the timer/counter is running.
void TickTock() {
if (((globalCounter%2000) < 1000)  && (moduleReady == true)) {
digitalWrite(13, 1);
} else {
digitalWrite(13, 0);
}
}

// Call function to start/stop X pumps according to correct timing.
void StartStopPumps(int pumpCount) {
static uint32_t startStopCount = 1; // Start stop counter.
int analogBuffer;

if ((nextPhase == 1) && (moduleReady == true)) {
for (int x = 1; x <= pumpCount; x++) {
digitalWrite(relayPinStart+x, HIGH); // Start relay for pump.
Serial.print("Pump #"); // Info
Serial.print(x);
Serial.println(": ON"); // end of info
}
nextPhase = 10; // Change so we dont loop this.
}

if ((nextPhase == 2) && (moduleReady == true)) {
for (int x = 1; x <= pumpCount; x++) {
Serial.println("Measuring start current"); // Info
// Mål ADC --> Over X = OK Under X = FEJL
analogBuffer = analogRead(x-1);
if (analogBuffer < 120) {
char buffer[50];
sprintf(buffer, "Error on pump %i at run %i - No start current detected", x, startStopCount);
Serial.println(buffer);
delay(100);
sendSMS(cellphoneNumber, buffer);
}
}
nextPhase = 20; // Change so we dont loop this.
}

if ((nextPhase == 3) && (moduleReady == true)) {
for (int x = 1; x <= pumpCount; x++) {
Serial.println("Measuring running current."); // Info
// Mål ADC --> Over X = FEJL Under X = OK.
analogBuffer = analogRead(x-1);
if (analogBuffer > 120) {
char buffer[50];
sprintf(buffer, "Error on pump %i at run %i - Running current detected", x, startStopCount);
Serial.println(buffer);
delay(100);
sendSMS(cellphoneNumber, buffer);
}
}
nextPhase = 30; // Change so we dont loop this.
}

if ((nextPhase == 4) && (moduleReady == true)) {
for (int x = 1; x <= pumpCount; x++) {
digitalWrite(relayPinStart+x, LOW); // Stop relay for pump.
Serial.print("Pump #"); // Info
Serial.print(x);
Serial.println(": OFF"); // end of info
}
Serial.print("This was run nr: "); // Info.
Serial.println(startStopCount); // Info.
startStopCount++;
nextPhase = 40; // Change so we dont loop this.
}
}

void loop() {
GSMcheck();
TickTock();

StartStopPumps(numberOfPumps);
}

// This gets called when there is data on RS232 from PC.
void serialEvent()
{
static char incoming_char = 0;      // Will hold the incoming character from the Serial Port.
if(Serial.available() >0)
{
incoming_char=(char)Serial.read();  // Get the character coming from the terminal
Serial1.print(incoming_char);    // Send the character to the cellular module.
}
}

// This gets called when there is data on the UART from the GSM module.
void serialEvent1()
{
  while (Serial1.available()) {
    char inChar = (char)Serial1.read(); // Get the new byte.
    inputString += inChar; // Add it to the inputString.
   
if (inputString.length()>1 && inputString[inputString.length()-2]=='\r' && inputString[inputString.length()-1]=='\n') { // If the 2nd last char is \r and last is \n then string is done.
  inputString = inputString.substring(0,inputString.length()-2); // Remove the last two chars from the string (GSM module uses CR+NL(\r & \n) and it fucks everything up ^_^)
      stringComplete = true; // Set string complete flag so data can be parsed
    }
  }
}

// Interrupt routine for timer0 compare.
ISR(TIMER0_COMPA_vect) {
globalCounter++;
if (globalCounter == 50) { nextPhase = 2; } // Correct value = 50.
if (globalCounter == 700) { nextPhase = 3; } // Correct value = 700.
if (globalCounter == 4200) { nextPhase = 4; } // Correct value = 4200.
if (globalCounter == 45000) { nextPhase = 1; globalCounter = 0; } // Correct value = 45000.
}


This is the whole code.
I am unsure of how to check if there is a message in progress?

Stevanx

Ok.

So far it now works with using delay. What I found out is that timer 0 is used by arduino to make the delays fuction, so after i changed to use another timer (timer 2 as it was also 8 bit - and almost same setup).

Maybe i should make some kind of fuction which awaits the "> " instead of using delays.

Go Up