HC-12 Funkmodul Reagiert nicht richtig auf AT Befehle

Hallo liebes Forum,

vor kurzem wollte ich mein HC-12 Funkmodul mit den AT Befehlen konfigurieren. Es wurde hier gekauft

Ich habe mich nach dieser Anleitung gerichtet, ich habe auf die Korekte belegung der Pins geachtet und SET mit GND verbunden.
Zur komunikation verwendete ich diesen Sketch:

#include <SoftwareSerial.h>
SoftwareSerial hc12(10,11);
void setup() {
  Serial.begin(9600);
  hc12.begin(9600);
  Serial.println("Let's start!");
}
void loop() { 
  if (hc12.available()) {
    Serial.write(hc12.read());
  }
  if (Serial.available()) {
    hc12.write(Serial.read());
  }
}

Um zu testen, ob sich das Modul im "AT" Modus befindet, tippte ich "AT" als Test Kommand ein und das Modul antwortete freundlicherweise mit "OK" und das wars. Das Modul reagiert auf keines der aufgelisteten "AT" Befehle:

AT+SLEEP
AT+V
AT+RX
AT+B1200

Und eigentlich allen anderen "AT" Befehlen auch. Verwende ich alle "AT" Befehle allerdings ohne, dass "+" Symbol antwortet das Modul NUR mit "OK" obwohl bei einem Befehl wie z.B. AT+FU1 als Antwort vom Modul OK+FU1 kommen sollte. dies ist nicht der Fall. Beim nächsten Reichweitentest und bei der Messung des Stromverbrauchs stellt sich heraus das das Modul die Einstellungen nicht übernommen hat.

AT-Befehle wie AT+DEFAULT oder die Abfrage der Firmwareversion funktionieren nicht. Wird der AT Befehl AT+V zur Abfrage der Firmware eingetippt ohne das "+" Zeichen antwortet das Modul mit „OK“, ohne die Firmwareversion zu zeigen.

Auf die korrekte Verdrahtung wurde geachtet, sonst würde das Modul nicht mit "OK" Kommunizieren können.

Hat jemand hier im Forum schonmal ähnliche Probleme gehabt? und wenn ja existiert dazu ein Lösungsweg?

ich habe auf zig verschiedenen Seiten recherchiert, aber die AT befehle scheinen wohl alle unabhängig von der Firmwareversion gleich zu sein.

Alternativ habe ich Für Windows das HC-12-config-master Tool gefunden, wofür man ein TTL USB Adapter benötigt, hat jemand mit so einem Tool Erfahrungen gehabt.

EDIT:
Es wurden auch viele andere Sketches zur Kommunikation des HC-12 verwendet.
Gibt es Arduino IDE Versionen die damit nicht kompatibel sind oder liegt das an der Version der SoftwareSerial Lib?
getestet wurde das mit einem Arduino UNO, NANO und einem MEGA.

Vielen dank im vorraus😁

Mit Freundlichen Grüßen,
Migel

Was genau möchtest du mit den AT-Befehlen erreichen ?

ich will den Funkmodus auf AT+FU2 einstellen zum Maximalen energiesparen sowie Sendeleistung auf AT+P4 einstellen um unter die erlaubten 10mW zu fallen und den Sender in den SLEEP Modus versetzen wenn das modul nichts sendet

Warum verwendest du nicht den Link dazu, den ich dir vor längerer Zeit schon mal gepostet habe ?

Das hatte ich total aus dem sinn, ich werde es damit auch nochmals probieren später. Dieser Link wurde mir auch ans Herz gelegt, den anderen Link hatte ich nciht mehr auf den Schirm, sorry

Ok, dein Link beinhaltet eine ergänzende Beschreibung. Der von mir gepostete zeigt die komfortable Nutzung der nötigen Befehle.

Ich hab mir die lib und das Tool für Arduino durchgelesen und ausgeführt.
Das Menü funktioniert.
ich konnte Funktion 1 und 3 ausführen. Das testen der µA mit dem Multimeter während ich Funktion 20 (den SLEEP Modus) teste fehlanzeige.
Auch hier kommt vom modul keine Bestätigung und informationen über die Firmware oder den Aktuellen einstellungen.
ich hab so langsam den verdacht das das Modul kein orgirinales ist.

AUSZUG:
Parametrierung 433 MHz HC-12 Modul
Version 1.0

Scanne Baudrate des HC-12 Moduls ...
Baudrate: 9600

Menu:
0 ... Zeige Menue
1 ... Teste Kommunikation
2 ... Zeige Baudrate
3 ... Zeige Kanal
4 ... Zeige Uebertragungsmodus
5 ... Zeige Sendeleistung
6 ... Zeige alle Parameter
9 ... Zeige Firmware Version
12 ... Aendere Baudrate
13 ... Aendere Kanal
14 ... Aendere Uebertragungsmodus
15 ... Aendere Sendeleistung
20 ... Teste Schlafmodus
96 ... Scanne Baudrate
97 ... Ruecksetzen auf Werkseinstellung
98 ... Einstellungen uebernehmen
99 ... Einstellungen uebernehmen und Programm beenden

Eingabe:
Eingabe: 1
Teste Kommunikation
OK

Eingabe: 2
Zeige Baudrate

Eingabe: 3
Zeige Kanal
OK+RC184

Eingabe: 4
Zeige Uebertragungsmodus

Eingabe: 5
Zeige Sendeleistung

Eingabe: 6
Zeige alle Parameter

Eingabe: 9
Zeige Firmware Version

Eingabe: 12
Aendere Baudrate
0 .. Abbruch
1 ..... 1200
2 ..... 2400
3 ..... 4800
4 ..... 9600
5 .... 19200
6 .... 38400
7 .... 57600
8 ... 115200
Eingabe: 1

Eingabe: 97
Ruecksetzen auf Werkseinstellung

Macht das bei jeder Einstellung ein Problem ?

Ich kann derartige Probleme bisher nicht bestätigen.
Schreibe doch mal deine kompletten Einstellungen. Ich versuche heute Abend das bei mir zu testen.

Ok, hat sich überschnitten.
Das sieht nicht gut aus. Das kann ich von meinen Modulen def. nicht berichten.
Ich werde aber später noch mal testen.

hast du deine Module im Funduino Shop gekauft und Sieht dein Modul von hinten auch so aus ?
ich kann mir nicht vorstellen das der Funduino Shop etwas komisches verkauft?


ich habe das Gegooglelt was auf der Rückseite steht, das einizge relevante Suchergebnis was mit dem Modul zusammen hängt ist die AliExpress Seite

Ja, es lässt sich nämlich überhaubt nichts einstellen

Eigendlich ist alles Standart, aktuelle einstellungen kann ich nicht einsehen. Was ich zu ändern versuche:
AT+FU2
AT+SLEEP
AT+P5

Nein, die habe ich schon vor einigen Jahren über ebay gekauft.
Ich poste später ein Foto von der Rückseite.

Machst du das?
" Zur Parametrierung muss das HC-12 Modul in den "AT command mode " gesetzt werden. Dazu wird der SET-Eingang des Moduls durch das Programm auf LOW gelegt`"
vor dem AT Kommando den Pin auf LOW setzen sonst kommt er nicht in Programmiermodus, da ich dein Modul nicht habe weis nicht ob nach senden und Bestätigung einmal der SET Pin auf HIGH gehen muss. so was habe auch schon gehabt.

Das macht der in der Anleitung zur verfügung gestellte Sketch sowie die Lib doch schon ? sonst würde das Pogramm Funktion 1 nicht mit OK antworten ? den kanal kann ich mir vom modul auch anzeigen laassen

Also was kostet dich wen du den Pin auf LOW setzt?
Eine Zeile dazu schreiben kostet nix, notfalls meckert die IDE was sollst

Weil das im Sketch bereits vorhanden ist:

digitalWrite(setPin, LOW); //SET-Modus starten

ich habe zusätzlich noch diese zwei zeilen hinzugefügt:

int pinNummer = 5; 

void loop() {
  digitalWrite(pinNummer, LOW); // Den Pin auf LOW setzen

Erst schreibst du es ist in der Lib jetzt zeigst du dass das ist außerhalb.
Ist aber OK, ich kann nur mutmaßen was du machst.

NEIN ich hab geschrieben das es im Sketch bereits vorhanden ist

EDIT:
DAS hier ist der Sketch, der verwendet wird für das menü mit den Funktionen zum Konfigurieren des Moduls:

//Parametrierung 433 MHz HC-12 Modul
//Code fuer Arduino
//Author Retian
//Version 1.0

//Prototypen
void zeigeMenue(void);
void aendereBaudrate(void);
void aendereKanal(void);
void aendereModus(void);
void aendereSendeleistg(void);
void warteAufAntwort(void);
void testeSchlafModus(void);
void scanBaudRate(void);

#define rxPin 3
#define txPin 4
#define setPin 5

#include <MySerialRead.h>
#include <SoftwareSerial.h>

MySerialRead SRead;
SoftwareSerial SWSerial(rxPin, txPin);

byte inByte;
char inChar;
byte readDelay = 200; //Verzoegerung vor Lesevorgang
long baudRate;
char atCommand[12];
char kanal[4];

void setup() {
  Serial.begin(115200);
  pinMode(setPin, OUTPUT);
  digitalWrite(setPin, LOW);
  //Nach Low-Setzen des SET-Pin mindestens 40 ms vor dem AT-Kommando warten
  delay(40);
  Serial.println(F("Parametrierung 433 MHz HC-12 Modul"));
  Serial.println(F("Version 1.0"));
  Serial.println();
  scanBaudRate();
  Serial.println();
  zeigeMenue();
}

void loop() {
  atCommand[0] = '\0'; //letztes AT-Kommando loeschen
  Serial.print(F("\nEingabe: "));
  if (SRead.readByte(&inByte, SERIAL_WAIT))
  {
    Serial.println(inByte);
    if (inByte == 0) zeigeMenue();
    else if (inByte == 1)
    {
      Serial.println(F("Teste Kommunikation"));
      strcpy(atCommand, "AT");
      SWSerial.write(atCommand);
      warteAufAntwort();
    }
    else if (inByte == 2)
    {
      Serial.println(F("Zeige Baudrate"));
      strcpy(atCommand, "AT+RB");
      SWSerial.write(atCommand);
      warteAufAntwort();
    }
    else if (inByte == 3)
    {
      Serial.println(F("Zeige Kanal"));
      strcpy(atCommand, "AT+RC");
      SWSerial.write(atCommand);
      warteAufAntwort();
    }
    else if (inByte == 4)
    {
      Serial.println(F("Zeige Uebertragungsmodus"));
      strcpy(atCommand, "AT+RF");
      SWSerial.write(atCommand);
      warteAufAntwort();
    }
    else if (inByte == 5)
    {
      Serial.println(F("Zeige Sendeleistung"));
      strcpy(atCommand, "AT+RP");
      SWSerial.write(atCommand);
      warteAufAntwort();
    }
    else if (inByte == 6)
    {
      Serial.println(F("Zeige alle Parameter"));
      strcpy(atCommand, "AT+RX");
      SWSerial.write(atCommand);
      warteAufAntwort();
    }
    else if (inByte == 9)
    {
      Serial.println(F("Zeige Firmware Version"));
      strcpy(atCommand, "AT+V");
      SWSerial.write(atCommand);
      warteAufAntwort();
    }
    else if (inByte == 12) aendereBaudrate();
    else if (inByte == 13) aendereKanal();
    else if (inByte == 14) aendereModus();
    else if (inByte == 15) aendereSendeleistg();
    else if (inByte == 20) testeSchlafModus();
    else if (inByte == 95)
    {
      Serial.print(F("Baudrate: "));
      Serial.println(baudRate);
    }
    else if (inByte == 96) scanBaudRate();
    else if (inByte == 97)
    {
      Serial.println(F("Ruecksetzen auf Werkseinstellung"));
      strcpy(atCommand, "AT+DEFAULT");
      SWSerial.write(atCommand);
      warteAufAntwort();
    }
    else if (inByte == 98)
    {
      Serial.println(F("Einstellungen uebernehmen!"));
      digitalWrite(setPin, HIGH); //SET-Modus beenden (HC-12 fuehrt Reset aus)
      Serial.println(F("Kontrolle des Ruhestromverbrauchs jetzt moeglich!"));
      Serial.println(F("Weiter mit beliebiger Zahl!"));
      if (SRead.readByte(&inByte, SERIAL_WAIT));
      digitalWrite(setPin, LOW); //SET-Modus starten
      delay(40);
      scanBaudRate();
    }
    else if (inByte == 99)
    {
      digitalWrite(setPin, HIGH);
      Serial.println(F("Programm beendet!"));
      Serial.println(F("Fuer weitere Parametrierung"));
      Serial.println(F("Programm neu starten"));
      while (1);
    }
    else Serial.println(F("Ungueltige Eingabe!"));
  }
}

void zeigeMenue()
{
  Serial.println(F("Menu:"));
  Serial.println(F(" 0 ... Zeige Menue"));
  Serial.println(F(" 1 ... Teste Kommunikation"));
  Serial.println(F(" 2 ... Zeige Baudrate"));
  Serial.println(F(" 3 ... Zeige Kanal"));
  Serial.println(F(" 4 ... Zeige Uebertragungsmodus"));
  Serial.println(F(" 5 ... Zeige Sendeleistung"));
  Serial.println(F(" 6 ... Zeige alle Parameter"));
  Serial.println(F(" 9 ... Zeige Firmware Version"));
  Serial.println(F("12 ... Aendere Baudrate"));
  Serial.println(F("13 ... Aendere Kanal"));
  Serial.println(F("14 ... Aendere Uebertragungsmodus"));
  Serial.println(F("15 ... Aendere Sendeleistung"));
  Serial.println(F("20 ... Teste Schlafmodus"));
  Serial.println(F("96 ... Scanne Baudrate"));
  Serial.println(F("97 ... Ruecksetzen auf Werkseinstellung"));
  Serial.println(F("98 ... Einstellungen uebernehmen"));
  Serial.println(F("99 ... Einstellungen uebernehmen und Programm beenden"));

}

void aendereBaudrate()
{
  bool baudRateGesperrt = false;
  long maxBaudRate = 115200;

  char modus[4];
  byte i = 0;
  char inStr[10];

  SWSerial.write("AT+RF");
  delay(readDelay);
  while (SWSerial.available())
  {
    inStr[i] = SWSerial.read();
    i++;
  }
  inStr[i] = '\0';

  strcpy(modus, "FU4");
  if (strstr(inStr, modus)) maxBaudRate = 1200;
  strcpy(modus, "FU2");
  if (strstr(inStr, modus)) maxBaudRate = 4800;

  Serial.println(F("Aendere Baudrate"));
  Serial.println(F(" 0 .. Abbruch"));
  Serial.println(F(" 1 ..... 1200"));
  Serial.println(F(" 2 ..... 2400"));
  Serial.println(F(" 3 ..... 4800"));
  Serial.println(F(" 4 ..... 9600"));
  Serial.println(F(" 5 .... 19200"));
  Serial.println(F(" 6 .... 38400"));
  Serial.println(F(" 7 .... 57600"));
  Serial.println(F(" 8 ... 115200"));
  Serial.print(F("Eingabe: "));
  if (SRead.readByte(&inByte, SERIAL_WAIT))
  {
    Serial.println(inByte);
    if (inByte > 0 && inByte < 9)
    {
      strcpy(atCommand, "AT+B");
      if (inByte == 1) strncat(atCommand, "1200", 4);
      else if (inByte == 2)
      {
        if (maxBaudRate > 2400) strncat(atCommand, "2400", 4);
        else baudRateGesperrt = true;
      }
      else if (inByte == 3)
      {
        if (maxBaudRate > 4800) strncat(atCommand, "4800", 4);
        else baudRateGesperrt = true;
      }
      else if (inByte == 4)
      {
        if (maxBaudRate > 9600) strncat(atCommand, "9600", 4);
        else baudRateGesperrt = true;
      }
      else if (inByte == 5)
      {
        if (maxBaudRate > 19200) strncat(atCommand, "19200", 5);
        else baudRateGesperrt = true;
      }
      else if (inByte == 6)
      {
        if (maxBaudRate > 38400) strncat(atCommand, "38400", 5);
        else baudRateGesperrt = true;
      }
      else if (inByte == 7)
      {
        if (maxBaudRate > 57600) strncat(atCommand, "57600", 5);
        else baudRateGesperrt = true;
      }
      else if (inByte == 8)
      {
        if (maxBaudRate >= 115200) strncat(atCommand, "115200", 6);
        else baudRateGesperrt = true;
      }
    }
    else if (inByte == 0)
    {
      Serial.println(F("Abbruch durch Benutzer!"));
      return;
    }
    else Serial.println(F("Ungueltige Eingabe!"));
  }

  if (baudRateGesperrt)
  {
    Serial.println(F("Baudrate gesperrt"));
    Serial.print(F("Max. Baudrate: "));
    Serial.println(maxBaudRate);
  }
  else
  {
    SWSerial.write(atCommand);
    warteAufAntwort();
  }
}

void aendereKanal()
{
  Serial.println(F("Aendere Kanal"));
  Serial.println(F("0 ... Abbruch"));
  Serial.print(F("Kanal(1-127): "));

  if (SRead.readByte(&inByte, SERIAL_WAIT))
  {
    Serial.println(inByte);
    if (inByte >= 1 && inByte <= 127)
    {
      if (inByte < 10)
      {
        kanal[0] = '0';
        kanal[1] = '0';
        kanal[2] = inByte + 48;
        kanal[3] = '\0';
      }
      else if (inByte < 100)
      {
        kanal[0] = '0';
        kanal[1] = (inByte / 10) + 48;
        kanal[2] = (inByte % 10) + 48;
        kanal[3] = '\0';
      }
      else
      {
        kanal[0] = '1';
        kanal[1] = ((inByte - 100) / 10) + 48;
        kanal[2] = ((inByte - 100) % 10) + 48;
        kanal[3] = '\0';
      }
      strcpy(atCommand, "AT+C");
      strncat(atCommand, kanal, 3);
      SWSerial.write(atCommand);
    }
    else if (inByte == 0)
    {
      Serial.println(F("Abbruch durch Benutzer!"));
      return;
    }
    else Serial.println(F("Ungueltige Zahl!"));
  }
  warteAufAntwort();
}

void aendereModus()
{
  Serial.println(F("Aendere Uebertragungsmodus"));
  Serial.println(F(" 0 ... Abbruch"));
  Serial.println(F(" 1 ... FU1"));
  Serial.println(F(" 2 ... FU2"));
  Serial.println(F(" 3 ... FU3"));
  Serial.println(F(" 4 ... FU4"));
  Serial.print(F("Eingabe: "));
  if (SRead.readByte(&inByte, SERIAL_WAIT))
  {
    Serial.println(inByte);
    if (inByte > 0 && inByte < 5)
    {
      strcpy(atCommand, "AT+FU");
      kanal[0] = inByte + 48;
      kanal[1] = '\0';
      strncat(atCommand, kanal, 1);
      SWSerial.write(atCommand);
    }
    else if (inByte == 0)
    {
      Serial.println(F("Abbruch durch Benutzer!"));
      return;
    }
    else Serial.println(F("Ungueltige Eingabe!"));
  }
  warteAufAntwort();
}

void aendereSendeleistg()
{
  Serial.println(F("Aendere Sendeleistung"));
  Serial.println(F(" 0 ... Abbruch"));
  Serial.println(F(" 1 ... -1 dBm"));
  Serial.println(F(" 2 ...  2 dBm"));
  Serial.println(F(" 3 ...  5 dBm"));
  Serial.println(F(" 4 ...  8 dBm"));
  Serial.println(F(" 5 ... 11 dBm"));
  Serial.println(F(" 6 ... 14 dBm"));
  Serial.println(F(" 7 ... 17 dBm"));
  Serial.println(F(" 8 ... 20 dBm"));
  Serial.print(F("Eingabe: "));
  if (SRead.readByte(&inByte, SERIAL_WAIT))
  {
    Serial.println(inByte);
    if (inByte > 0 && inByte < 9)
    {
      strcpy(atCommand, "AT+P");
      kanal[0] = inByte + 48;
      kanal[1] = '\0';
      strncat(atCommand, kanal, 1);
      SWSerial.write(atCommand);
    }
    else if (inByte == 0)
    {
      Serial.println(F("Abbruch durch Benutzer!"));
      return;
    }
    else Serial.println(F("Ungueltige Eingabe!"));
  }
  warteAufAntwort();
}

void testeSchlafModus()
{
  Serial.println(F("Teste Schlafmodus"));
  strcpy(atCommand, "AT+SLEEP");
  SWSerial.write(atCommand);
  warteAufAntwort();
  digitalWrite(setPin, HIGH); //Mit SET-Modus beenden Schlafmodus aktivieren
  Serial.println(F("Kontrolle des Stromverbrauchs im Schlafmodus jetzt moeglich!"));
  Serial.println(F("Wecken mit beliebiger Zahl!"));
  if (SRead.readByte(&inByte, SERIAL_WAIT));
  //Mit SET-Modus starten Schlafmodus beenden,
  //anschliessend HC-12 Reset und SET-Modus wieder starten
  digitalWrite(setPin, LOW);
  delay(50);
  digitalWrite(setPin, HIGH); //SET-Modus beenden (HC-12 fuehrt Reset aus)
  delay(200);
  digitalWrite(setPin, LOW); //SET-Modus starten
  delay(40);
  Serial.println(F("Schlafmodus beendet!"));
}

void scanBaudRate()
{
  //Eingestellte Baudrate ermitteln
  baudRate = 600; //Anfangswert fuer die Ermittlung der eingestellten Baudrate
  char inString[3];
  byte i;
  Serial.println(F("Scanne Baudrate des HC-12 Moduls ..."));
  do {
    if (baudRate == 38400) baudRate *= 1.5;
    else baudRate *= 2;
    if (baudRate > 115200)
    {
      Serial.println(F("Keine Kommunikation mit HC-12!"));
      return;
    }
    SWSerial.begin(baudRate);
    delay(100);
    SWSerial.write("AT");
    delay(readDelay);
    i = 0;
    while (SWSerial.available())
    {
      inString[i] = SWSerial.read();
      i++;
    }
  }
  while (strncmp(inString, "OK", 2) != 0);
  Serial.print(F("Baudrate: "));
  Serial.println(baudRate);
}

void warteAufAntwort()
{
  delay(readDelay);
  while (SWSerial.available())
  {
    inChar = SWSerial.read();
    Serial.print(inChar);
    delay(2);
  }
}

Hab mich da drauf bezogen. Wie geschrieben ist mir Wurst.

Achso, dann hab ich mich falsch ausgedrückt Sorry, die Lib wird für den Sketch zusätzlich verwendet/benötigt.
Der Set Pin wird natürlich im Sketch verwendet