execute action once when the criteria is met

So yes, hello everyone. I have stumpled upon a wall.
I'm making a small project using rasperry pi 2.
I'm trying it to send an SMS when relay have worked. With the code I got it does send sms, but it send them all the time, untill relay is released.
Can anyone help me get it send SMS when the signal changes? I know there is a command that reads digital input.

Here is the full code.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
//Include arduPi library
#include "arduPi.h"

int8_t sendATcommand(const char* ATcommand, const char* expected_answer, unsign$
void power_on();


//Enter here you data
const char pin_number[] = "0000";         // Write the pin number of the SIM ca$
const char phone_number[] = "26032324";  // Write here the number A to call
char sms_text1[] = "SMS1";
char sms_text2[] = "SMS2";
char sms_text3[] = "SMS3";

//Digital pin definitions
int onModulePin = 2;
int buttonA = 3;
int buttonB = 4;
int buttonC = 5;

int8_t answer;
char aux_string[30];


void setup() {
  pinMode(onModulePin, OUTPUT);
  pinMode(buttonA, INPUT);
  pinMode(buttonB, INPUT);
  pinMode(buttonC, INPUT);
  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");

  //Check network registration
  while ( (sendATcommand("AT+CREG?", "+CREG: 0,1", 1000) ||
             sendATcommand("AT+CREG?", "+CREG: 0,5", 1000)) == 0 );

  printf("Connected to the network!!\n");
  delay(1000);

  printf("Press a button to crap\n");
}

void loop() {
  //If button A is pressed send SMS1
  if (digitalRead(buttonA) == 1) {
    printf("Setting SMS mode...\n");
    sendATcommand("AT+CMGF=1", "OK", 1000);    // sets the SMS mode to text
    printf("Sending SMS\n");

    sprintf(aux_string,"AT+CMGS=\"%s\"", phone_number);
    answer = sendATcommand(aux_string, ">", 2000);    // send the SMS number
    if (answer == 1)
    {
        Serial.println(sms_text1);
        Serial.write(0x1A);
        answer = sendATcommand("", "OK", 20000);
        if (answer == 1)
        {
            printf("Sent \n");
        }
        else
        {
            printf("error \n");
        }
    }
    else
    {
        printf("error %o\n",answer);
    }
  }
  //If button B is pressed SEND SMS2
  if (digitalRead(buttonB) == 1) {
    printf("Setting SMS mode...\n");
    sendATcommand("AT+CMGF=1", "OK", 1000);    // sets the SMS mode to text
    printf("Sending SMS\n");

    sprintf(aux_string,"AT+CMGS=\"%s\"", phone_number);
    answer = sendATcommand(aux_string, ">", 2000);    // send the SMS number
    if (answer == 1)
    {
        Serial.println(sms_text2);
        Serial.write(0x1A);
        answer = sendATcommand("", "OK", 20000);
        if (answer == 1)
        {
            printf("Sent \n");
        }
        else
        {
            printf("error \n");
        }
    }
    else
    {
        printf("error %o\n",answer);
    }
  }
  //If button C is pressed SEND SMS3
  if (digitalRead(buttonC) == 1) {
    printf("Setting SMS mode...\n");
    sendATcommand("AT+CMGF=1", "OK", 1000);    // sets the SMS mode to text
    printf("Sending SMS\n");

    sprintf(aux_string,"AT+CMGS=\"%s\"", phone_number);
    answer = sendATcommand(aux_string, ">", 2000);    // send the SMS number
    if (answer == 1)
    {
        Serial.println(sms_text3);
        Serial.write(0x1A);
        answer = sendATcommand("", "OK", 20000);
        if (answer == 1)
        {
            printf("Sent \n");
        }
        else
        {
            printf("error \n");
        }
    }
        printf("error %o\n",answer);
    }
  }
}


/************************************************************************
 ****               Definition of functions                          ****
 ************************************************************************/

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 t$

    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 $
            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;
}

int main (){
    setup();
    while(1){
        loop();
    }
    return (0);
}



Basicly, I need it to send only one SMS, the code is sending multiple SMS untill the button (relay) is released.
Last edited on
One way to solve it is this:
1
2
3
4
5
6
7
8
9
void loop() {
  static bool A_is_pressed = false;
  bool A_was_pressed = A_is_pressed;
  A_is_pressed = (digitalRead(buttonA) == 1);

  //If button A is pressed send SMS1
  if ((!A_was_pressed) && A_is_pressed) {
...
}
I did they to use it, didn't help, it still sends loads of sms.
Code under, maybe someone can point to my fault.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
//Include arduPi library
#include "arduPi.h"

int8_t sendATcommand(const char* ATcommand, const char* expected_answer, unsigned int timeout);
void power_on();


//Enter here you data
const char pin_number[] = "0000";         // Write the pin number of the SIM ca$
const char phone_number[] = "29113038";   // Write here the number A to call
char sms_text1[] = "SMS1";
char sms_text2[] = "SMS2";
char sms_text3[] = "SMS3";
int A_is_pressed = 0;
int A_was_pressed = 0;
int B_is_pressed = 0;
int B_was_pressed = 0;
int C_is_pressed = 0;
int C_was_pressed = 0;

//Digital pin definitions
int onModulePin = 2;
int buttonA = 3;
int buttonB = 4;
int buttonC = 5;

int8_t answer;
char aux_string[30];


void setup() {
  pinMode(onModulePin, OUTPUT);
  pinMode(buttonA, INPUT);
  pinMode(buttonB, INPUT);
  pinMode(buttonC, INPUT);
  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");

  //Check network registration
  while ( (sendATcommand("AT+CREG?", "+CREG: 0,1", 1000) ||
             sendATcommand("AT+CREG?", "+CREG: 0,5", 1000)) == 0 );

  printf("Connected to the network!!\n");
  delay(1000);

  printf("Press a button to crap\n");
}

void loop() {
	static bool A_is_pressed = false;
	bool A_was_pressed = A_is_pressed;
	A_is_pressed = (digitalRead(buttonA) == 1);
	
  //If button A is pressed send SMS1
  if ((!A_was_pressed) && A_is_pressed) {
    printf("Setting SMS mode...\n");
    sendATcommand("AT+CMGF=1", "OK", 1000);    // sets the SMS mode to text
    printf("Sending SMS\n");

    sprintf(aux_string,"AT+CMGS=\"%s\"", phone_number);
    answer = sendATcommand(aux_string, ">", 2000);    // send the SMS number
    if (answer == 1)
    {
        Serial.println(sms_text1);
        Serial.write(0x1A);
        answer = sendATcommand("", "OK", 20000);
        if (answer == 1)
        {
            printf("Sent \n");
        }
        else
        {
            printf("error \n");
        }
    }
    else
    {
        printf("error %o\n",answer);
    }
  }
  	static bool B_is_pressed = false;
	bool B_was_pressed = B_is_pressed;
	B_is_pressed = (digitalRead(buttonB) == 1);
	
  //If buttonB is pressed send SMS2
  if ((!B_was_pressed) && B_is_pressed) {

    printf("Setting SMS mode...\n");
    sendATcommand("AT+CMGF=1", "OK", 1000);    // sets the SMS mode to text
    printf("Sending SMS\n");

    sprintf(aux_string,"AT+CMGS=\"%s\"", phone_number);
    answer = sendATcommand(aux_string, ">", 2000);    // send the SMS number
    if (answer == 1)
    {
        Serial.println(sms_text2);
        Serial.write(0x1A);
        answer = sendATcommand("", "OK", 20000);
        if (answer == 1)
        {
            printf("Sent \n");
        }
        else
        {
            printf("error \n");
        }
    }
    else
    {
        printf("error %o\n",answer);
    }
  }
  	static bool C_is_pressed = false;
	bool C_was_pressed = C_is_pressed;
	C_is_pressed = (digitalRead(buttonC) == 1);
	
  //If button C is pressed send SMS3
  if ((!C_was_pressed) && C_is_pressed) {

    printf("Setting SMS mode...\n");
    sendATcommand("AT+CMGF=1", "OK", 1000);    // sets the SMS mode to text
    printf("Sending SMS\n");

    sprintf(aux_string,"AT+CMGS=\"%s\"", phone_number);
    answer = sendATcommand(aux_string, ">", 2000);    // send the SMS number
    if (answer == 1)
    {
        Serial.println(sms_text3);
        Serial.write(0x1A);
        answer = sendATcommand("", "OK", 20000);
        if (answer == 1)
        {
            printf("Sent \n");
        }
        else
        {
            printf("error \n");
        }
    }
        printf("error %o\n",answer);
    }
  }



/************************************************************************
 ****               Definition of functions                          ****
 ************************************************************************/

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 $
            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;
}

int main (){
    setup();
    while(1){
        loop();
    }
    return (0);
}
It should work. I made a small test:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#include <iostream>
#include <stdlib.h>     /* srand, rand */
#include <time.h>       /* time */

using namespace std;

int main()
{
    srand (time(NULL));
    int change_count = 10;
    int value = (rand() % 10);
    for(int i=0;i<10000; ++i)
    {
        static bool is_pressed = false;
        bool was_pressed = is_pressed;
        if(change_count > 0)
            --change_count;
        else
        {
            change_count = 10;
            value = (rand() % 10);
        }
        is_pressed = (value == 5);
        cout << value << endl;

        if((!was_pressed) && (is_pressed))
            cout << "Press" << endl;
	}

	return 0;

}
"Press" is only triggered when there is a change to 5. Maybe something else is wrong?
Solved. Used it like
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
void loop() {
	//Read push on button A;
	A_is = digitalRead(buttonA);
	
	//compare A_was to A_is
	if (A_is != A_was){
		if(A_is ==1){
			
			printf("Setting SMS mode...\n");
			sendATcommand("AT+CMGF=1", "OK", 1000);    // sets the SMS mode to text
			printf("Sending SMS\n");

			sprintf(aux_string,"AT+CMGS=\"%s\"", phone_number);
			answer = sendATcommand(aux_string, ">", 2000);    // send the SMS number
			    if (answer == 1)
    {
        Serial.println(sms_text1);
        Serial.write(0x1A);
        answer = sendATcommand("", "OK", 20000);
        if (answer == 1)
        {
            printf("Sent \n");    
        }
        else
        {
            printf("error \n");
        }
    }
    else
    {
        printf("error %o\n",answer);
    }
		}
		else {
				if(A_is ==0){
			
			printf("Setting SMS mode...\n");
			sendATcommand("AT+CMGF=1", "OK", 1000);    // sets the SMS mode to text
			printf("Sending SMS\n");

			sprintf(aux_string,"AT+CMGS=\"%s\"", phone_number);
			answer = sendATcommand(aux_string, ">", 2000);    // send the SMS number
			    if (answer == 1)
    {
        Serial.println(sms_text2);
        Serial.write(0x1A);
        answer = sendATcommand("", "OK", 20000);
        if (answer == 1)
        {
            printf("Sent \n");    
        }
        else
        {
            printf("error \n");
        }
    }
	}
	}
	} 

	A_was = A_is;
	

}


Works like a charm.

Thanks for help
Topic archived. No new replies allowed.