Probleme mit Baud Rate und LTE Modul

Hallo Gemeinde

Ich habe ein Projekt mit einem LTE-Modul (SIM7600) am Laufen. Das Problem ist, dass das Modul per default auf 115200 Baud eingestellt ist. Diese Rate ist für meinen Code aber zu schnell, d.h. Zeichen (z.B. von einem SMS) werden nicht richtig gelesen. Mit 9600 funktioniert der Code einwandfrei. Nur kann ich die Baudrate leider nicht permanent ändern. Deshalb muss ich sie beim Powerup per AT-Command (AT+IPR=) ändern. Doch leider will das nicht funktionieren, der Code bleibt im Setup hängen. Hat jemand eine Idee?

/*
  Project: Interfacing SIM7600 GSM Module with Maker UNO
  Item used:
  - Maker UNO https://www.cytron.io/p-maker-uno
  - SIM7600 https://www.cytron.io/p-4g-3g-2g-gsm-gprs-gnss-hat-for-raspberry-pi
*/

#include <SoftwareSerial.h>
#include "Adafruit_FONA.h"

#define BUTTON  2
#define BUZZER  8
#define LED13   13

#define GSM_RX  8
#define GSM_TX  7
#define GSM_PWR 5
#define GSM_RST 20 // Dummy
//#define GSM_BAUD  9600

char replybuffer[255];

SoftwareSerial SIM7600SS = SoftwareSerial(GSM_TX, GSM_RX);
SoftwareSerial *SIM7600Serial = &SIM7600SS;

Adafruit_FONA SIM7600 = Adafruit_FONA(GSM_RST);



uint8_t readline(char *buff, uint8_t maxbuff, uint16_t timeout = 0);
char SIM7600InBuffer[64]; // For notifications from the FONA
char callerIDbuffer[32]; // We'll store the SMS sender number in here
char SMSbuffer[32]; // We'll store the SMS content in here
uint16_t SMSLength;
String SMSString = "";
boolean buttonEnable = false;

void setup()
{
  pinMode(BUTTON, INPUT_PULLUP);
  pinMode(BUZZER, OUTPUT);
  pinMode(LED13, OUTPUT);

  pinMode(GSM_PWR, OUTPUT);
  delay(1000);
  pinMode(GSM_PWR, INPUT_PULLUP);

  Serial.begin(115200);
  Serial.println("Interfacing SIM7600 GSM Module with Maker UNO");
  Serial.println("Initializing... (May take a minute)");

  playStartMelody();
  delay(15000);

  //SIM7600.write("AT+IPR=9600");


  // Make it slow so its easy to read!
  SIM7600Serial->begin(115200);
  delay(1000);
  SIM7600.write("AT+IPR=9600");
  delay(1000);
  SIM7600Serial->end();
  delay(1000);
  SIM7600Serial->begin(9600);


  if (!SIM7600.begin(*SIM7600Serial)) {
    Serial.println("Couldn't find SIM7600");
    playErrorMelody();
    while (1);
  }
  Serial.println(F("SIM7600 is OK"));

  // Print SIM card IMEI number.
  char imei[16] = {0}; // MUST use a 16 character buffer for IMEI!
  uint8_t imeiLen = SIM7600.getIMEI(imei);
  if (imeiLen > 0) {
    Serial.print("SIM card IMEI: "); Serial.println(imei);
  }

  SIM7600Serial->print("AT+CNMI=2,1\r\n");  // Set up the SIM800L to send a +CMTI notification when an SMS is received

  playReadyMelody();
  Serial.println("GSM is ready!");

  delay(1000);



  delay(1000);
}

void loop()
{
  char* bufPtr = SIM7600InBuffer; // Handy buffer pointer

  if (SIM7600.available()) { // Any data available from the SIM800L
    int slot = 2; // This will be the slot number of the SMS
    int charCount = 0;

    // Read the notification into fonaInBuffer
    do {
      *bufPtr = SIM7600.read();
      Serial.write(*bufPtr);
      delay(1);
    } while ((*bufPtr++ != '\n') && (SIM7600.available()) && (++charCount < (sizeof(SIM7600InBuffer) - 1)));

    // Add a terminal NULL to the notification string
    *bufPtr = 0;

    // Scan the notification string for an SMS received notification.
    // If it's an SMS message, we'll get the slot number in 'slot'
    if (1 == sscanf(SIM7600InBuffer, "+CMTI: \"SM\",%d", &slot)) {
      playSmsMelody();
      Serial.print("slot: "); Serial.println(slot);

      // Retrieve SMS sender address/phone number.
      if (!SIM7600.getSMSSender(slot, callerIDbuffer, 31)) {
        Serial.println("Didn't find SMS message in slot!");
      }
      Serial.print("FROM: "); Serial.println(callerIDbuffer);

      if (!SIM7600.readSMS(slot, SMSbuffer, 250, &SMSLength)) { // pass in buffer and max len!
        Serial.println("Failed!");
      }
      else {
        SMSString = String(SMSbuffer);
        Serial.print("SMS: "); Serial.println(SMSString);
      }

      // Compare SMS string
      if (SMSString == "ENABLE BUTTON") {
        Serial.print("Button is enable.");
        buttonEnable = true;
        delay(100);
        // Send SMS for status
        if (!SIM7600.sendSMS("+41787978606", "Button is enable.")) {  // callerIDbuffer ersetzt durch Nummer
          Serial.println("Failed");
        }
        else {
          Serial.println(F("Sent!"));
        }
      }
      else if (SMSString == "LED13 ON") {
        Serial.print("Setting LED 13 to on.");
        digitalWrite(LED13, HIGH);
        delay(100);
        // Send SMS for status
        if (!SIM7600.sendSMS(callerIDbuffer, "Setting LED to on.")) {
          Serial.println("Failed");
        }
        else {
          Serial.println(F("Sent!"));
        }
      }
      else if (SMSString == "LED13 OFF") {
        Serial.print("Setting LED 13 to off.");
        digitalWrite(LED13, LOW);
        delay(100);
        // Send SMS for status
        if (!SIM7600.sendSMS(callerIDbuffer, "Setting LED to off.")) {
          Serial.println("Failed");
        }
        else {
          Serial.println(F("Sent!"));
        }
      }
      else {
        Serial.print("Invalid command.");
        playErrorMelody();
      }

      // Delete the original msg after it is processed
      // otherwise, we will fill up all the slots
      // and then we won't be able to receive SMS anymore
      while (1) {
        boolean deleteSMSDone = SIM7600.deleteSMS(slot);
        if (deleteSMSDone == true) {
          Serial.println("OK!");
          break;
        }
        else {
          Serial.println("Couldn't delete, try again.");
        }
      }
    }
  }

  if (digitalRead(BUTTON) == LOW && buttonEnable == true) {
    buttonEnable = false;
    playButtonMelody();

    // Send SMS for status
    if (!SIM7600.sendSMS(callerIDbuffer, "Button is pressed!")) {
      Serial.println("Failed");
    }
    else {
      Serial.println(F("Sent!"));
    }
  }
}

void playTone(int *melody, int *melodyDur, int notesLength)
{
  for (int i = 0; i < notesLength; i++) {
    int noteDuration = 1000 / melodyDur[i];
    tone(BUZZER, melody[i], noteDuration);
    delay(noteDuration);
    noTone(BUZZER);
  }
}

Muss am Ende des Befehls \r\n oder \n gesendet werden?

  SIM7600.write("AT+IPR=9600\n");

Ja Du hast Recht! Aber leider hängt er immer noch. Es kommt immer:
Interfacing SIM7600 GSM Module with Maker UNO
Initializing... (May take a minute)
Interfacing SIM7600 GSM Module with Maker UNO
Initializing... (May take a minute)
Interfacing SIM7600 GSM Module with Maker UNO
Initializing... (May take a minute)

Es scheint, dass Ihr Arduino dauerhaft neu startet!...

Können Sie klären, wie die Module verbunden und mit Strom versorgt sind?
Warum machen Sie das?

  pinMode(GSM_PWR, OUTPUT);
  pinMode(GSM_PWR, INPUT_PULLUP);

Ist es ein OUTPUT oder ein INPUT_PULLUP?

Hallo,
das sehe ich anders. Die Ausgabe auf dem Monitor kann doch nur vom loop kommen. Dort wird als erstes die Schnittstellle des Moduls ausgelesen. Und man kann es lesen. Damit sieht das für mich so als als habe die Umschaltung auf 9600 geklappt.

ich vermute auch das neu gebootet wird. Du könntest ja mal noch ein paar serielle Ausgaben auf den Monitor bringen, z.B
start Setup
boudrate geändert
Setup ende
start loop

Sorry es war @laurin_e gemeint.

Verwende einen Controller, der eine weitere Hardware Serielle zur Verfügung stellt.
SoftwareSerial ist bei 115200 nicht sehr sicher in der Übertragung.

Ja, aber nur das Senden eines AT-Befehls, ohne dass sonst etwas passiert, um die Baudrate zu ändern, funktioniert problemlos.

t#include <SoftwareSerial.h>
#define GSM_RX  8
#define GSM_TX  7
SoftwareSerial SIM7600SS = SoftwareSerial(GSM_TX, GSM_RX);

void setup() {
  Serial.begin(115200);
  SIM7600SS.begin(115200);
  SIM7600SS.write("AT+IPR=9600\n");
  SIM7600SS.end();
  delay(1000);
  SIM7600SS.begin(9600);
  ...

Ja, ok...das mag sein.
Nur mit einem Controller der auf 115200 richtig und fehlerfrei arbeitet, spart sich @laurin_e das Umschalten.

Ja, wenn es einen "physischen" UART haben kann, wäre das besser.

Mein Code ist jetzt identisch mit dem Post # 7

  // Make it slow so its easy to read!
  SIM7600Serial->begin(115200);
  SIM7600.write("AT+IPR=9600\n");
  SIM7600Serial->end();
  delay(1000);
  SIM7600Serial->begin(9600);

doch auf dem Serial Monitor kommt immer nur:
Interfacing SIM7600 GSM Module with Maker UNO
Initializing... (May take a minute)
Interfacing SIM7600 GSM Module with Maker UNO
Initializing... (May take a minute)
Interfacing SIM7600 GSM Module with Maker UNO
Initializing... (May take a minute)
Interfacing SIM7600 GSM Module with Maker UNO
Initializing... (May take a minute)

Wieso das? Der müsste doch weitergehen und später in die Loop?? Ich bin fast sicher, dass der crasht und jesdesmal neu bootet, sonst würde er das oben ja nicht ständig printen..

Wie versorgst Du das GSM-Modul und welchen Arduino benutzt Du?

Gruß Tommy

Per externem Schaltnetzteil über die Fremdspannungsbuchse mit 12VDC. Unter dem Modul ist ein Arduino Uno.

Du solltest jetzt herausfinden, an welcher Stelle er neu started.
Baue doch noch ein Paar serielle Ausgaben ein.
Hat das GSM eine eigene Spannungsversorgung?
Oder bekommt er die vom Uno ?

ok, bin dran. Er bekommt die Speisung vom Uno

Dann ist da dein Problem.
Der Spannungsregler des Uno schafft das nicht. Teste mal mit 7Volt, dann wird der Regler nicht überlastet.

Ich glaubs nicht, jetzt mit den Serial.prints dazwischen bootet er. Ist wohl mal wieder ein delay-Problem :see_no_evil:

Ganz sicher nicht.

Ich habe was gelesen, das dass Modul im peak bis zu 2A Strom zieht, damit ist dein Regler auf dem Uno hoffnungslos überfordert. Du solltest das Modul an eine eigene Stromversorgung anschließen.

1 Like

Stimmt, das gilt für alle GSM-Shields. Zusätzlich noch einen 1000yF Elko an die Versorgung hängen und die Probleme sind weg.

1 Like

Ok, werde nachher die 5V am SIM7600 auf dem Oszi anschauen