static volatile bool flag = 0;
void setup() {
pinMode(2, INPUT_PULLUP);
Serial.begin(57600); //This pipes to the serial monitor
while (!Serial);
Serial1.begin(57600); //This is the UART, pipes to sensors attached to board
while (!Serial1);
Serial1.setTimeout(10000);
attachInterrupt(1, fall, FALLING );
}
void loop() {
while ( Serial.available() ) {
char ch = Serial.read();
if (ch == 'S' && 'M' == Serial.peek()) {
char tmp[10] = {0};
tmp[0] = ch;
Serial.readBytes(tmp + 1, 2);
if (!strcmp(tmp, "SMS")) {
while (Serial.available()) Serial.read();
send_sms();
}
else Serial1.write(tmp);
}
else Serial1.write(ch);
}
while ( Serial1.available() ) {
Serial.write( Serial1.read() );
}
if (flag) {
flag = 0;
Serial1.println("ATH");
delay(1000);
//send_sms();
attachInterrupt(1, fall, FALLING );
}
}
void config () {
Serial1.println("AT");
while (!Serial1.find("OK"));
Serial.println("OK");
Serial1.println("AT+CMGF=1");
while (!Serial1.find("OK"));
Serial.println("CMGF=1");
Serial1.println("AT+CSCS=\"GSM\"");
while (!Serial1.find("OK"));
Serial.println("GSM");
}
void send_sms() {
config();
char message[40] = {0}; uint8_t i = 0; char c;
Serial1.println("AT+cusd=0,\"*444#\"");
Serial.println("send");
delay(2000);
while (!Serial1.find("+CUSD:"));
while (Serial1.available()) Serial.write(Serial1.read());
Serial.println("end");
}
void fall() {
detachInterrupt(1);
flag = 1;
Serial.println("lowlevel");
}
board is micro/leonardo (2 serial)
so when I send from PC to modem SMS command send_sms() is calling and
despite the fact that I put these two lines delay(2000); while (!Serial1.find("+CUSD:"));
special for print "end" after all serial stream (when stream is terminated/no incoming bytes)
but as you can see on the output
CMGF=1
GSM
send
end
Abonement: 1155 min v seti, 75 min vne seti i 1001.92MB deistvitelinye do kontsa meseatsa
Info
Loialinosti
Moi nomer
",15
OK
"end" is printing before USSD command was executed
How to print "end" after all stream ?
This does not read input 'until there is no more'. It only reads input until the buffer is empty. If there is any gap in the input the buffer may empty before more data arrives.
You could use a timeout:
unsigned long startTimer = millis();
while (millis() - startTimer <= 5000) // Allow 5 seconds for input
{
if (Serial1.available())
{
startTimer = millis(); // re-start the timeout
Serial.write(Serial1.read());
}
}
That will accept input until it has been 5 seconds since the last character received.
you are right. was written quickly just to verify serial stream. but. at this moment issue not in this line. commands from PC(Serial) were sending successfully.
will try this tomorrow ... just want to add small notes , line
while (!Serial1.find("+CUSD:"));
is working as expected. find is waiting 10 sec (Serial1.setTimeout(10000); ) for "+CUSD:". and after ~2..4 sec this target is coming ... and +CUSD text is excluding from Output. but! somehow , line
Serial.println("end"); which is after find, is executing before find. How ?!
while (!Serial1.find("+CUSD:"));
At this point the ':' of "+CUSD:" has just been taken out of the buffer. At 57600 baud, it will be about 174 microseconds (2777 instruction cycles) until the next character arrives.
The buffer is empty so this loop does nothing:
while (Serial1.available())
Serial.write(Serial1.read());
This line puts "end\n" in the Serial output buffer. Serial.println("end");
send_sms() now returns.
Now we are back in loop() and start repeating:
while ( Serial1.available() ) {
Serial.write( Serial1.read() );
}
That will (eventually) show everything that arrived after "end\n" was put in the output buffer.
after some tests I figured out that "delay" in the input string can be in any place... so might be exist only one solution to resolve this issue.. using timeout as you suggested or write my own timeRead function like in the Stream class