Ich schreibe einen C-Code für den Batterieempfang mit dem GSM-Modem SIM 800E. Ich verwende AtMega16 uC. Hier habe ich AT-Befehle verwendet, um Batterieinformationen zu erhalten.
void uart_send(unsigned char ch) //Function to send via UART
{
while(!(UCSRA &(1<<UDRE)));
UDR=ch;
}
void bat() //Function to get battery info and send SMS via UART
{
int x;
char battery[16];
UCSRB &= ~(1<<UDRIE);
writecommand("AT+CBC"); //AT command to get battery status(My program stuck here)
for(int x = 0;x<20;x++) //Reading 20 characters by the response of AT+CBS
{
while(!(UCSRA & (1<<RXC)));
battery[x] = UDR;
}
UCSRB |= (1<<RXCIE);
for(int x=1;x<20;x++) //sending 20 characters to UART
{
uart_send(*battery);
}
}
int main()
{
DDRB=0xff; //PORT as output port for LCD
uart_init(); //initializing UART
_delay_ms(1000);
writecommand("AT");
writecommand("AT+CMGF=1"); //setting GSM to Text Mode
writecommand("AT+CNMI=2,0,2,0,0");
while(1)
{
bat();
transmit("AT+CMGS=\"+9195xxxxxxxx\"\r"); //Sending SMS with values in UART buffer
_delay_ms(10);
uart_send(26); // command to send SMS
}
Wenn ich den Code ausführe, bleibt er in der bat()-Funktion (bei "AT+CBC") hängen, er zeigt die Batterieinformationen auf dem LCD und dem Terminal an, sendet sie aber nicht per SMS und das Programm fährt nicht fort. Bitte schlagen Sie mir vor, wie ich die Informationen per SMS erhalten kann.
Bearbeiten
Zu Kommentaren von Loongcat
Ich erhalte 20 Zeichen nach dem Komman "AT+CBC", dann sollte es das erhalten. das ist die Schleifefor(int x = 0;x<20;x++)
1) AT+CMGS muss vor dem SMS-Text stehen (platzieren Sie bat() nach transmit())
2) Sie erkennen das Ende der Antwort auf den AT + CBC-Befehl nicht, das ist ein schlechter Weg. Sie müssen Symbole erhalten, bis Sie "OK" erhalten
AT+CMGS
dann AT+CBC
wird das Senden der Nachricht möglicherweise wegen des neuen AT-Befehls unterbrochen.Ich sehe folgende Probleme in deinem Code:
bat()
Funktion speichern Sie die Batterieinformationen in einem lokalen String ( char battery[16];
)
for(int x = 0;x<20;x++)
) darin. Wenn Sie 20 Zeichen erwarten, sollten Sie ein Array mit einer Größe von 20 + 1 verwenden , plus eins für das abschließende Nullzeichen: \0
.uart_send
Funktion erwartet unsigned char
als Parameter, also ist dieser Aufruf falsch: uart_send(*battery);
es sollte seinuart_send(battery[x]);
Im aktuellen Zustand Ihres Programms wird es kein Problem geben, da Sie diesen String in der bat()
Funktion übertragen, aber Sie sollten ihn nach dem AT+CMGS
Befehl übertragen, wo dieser String nicht verfügbar ist.
bat()
Wenn Sie die Funktion einfach nach dem aufrufen AT+CMGS
, wird es Probleme geben, da der AT+CBC
Befehl an das Modul gesendet wird, das darauf antwortet. Ich denke, es wird die Ausführung des AT+CMGS
Befehls unterbrechen.
Daher schlage ich vor, dass Sie die Batterieinformationen zuerst in einer Variablen speichern, die nicht verloren geht, und sie dann zur richtigen Zeit senden. Eine korrekte Nachrichten-Sendesequenz sollte etwa so aussehen:
AT+CMGS="+9195xxxxxxxx"
Befehl.>
, das bedeutet, dass das Modul die Telefonnummer verarbeitet hat und nun bereit ist, den SMS-Text zu empfangen, [Batterieinfo].>
Zeichen erhalten haben, können Sie die Batterieinformationen an das Modul senden.<CTRL>-<Z>
Zeichen 0x26
in ASCII.+CMGS: 62
Bence Kaulics
Ravi Kumar