ESP32 with HC12 doesn't work

Hi guys,
I have connected my esp32 with my hc12 like this:
HC12 RX --> ESP32 TX2
HC12 TX --> ESP32 RX2
HC12 VCC --> ESP32 3V3
HC12 GND --> ESP32 GND

I post my entire code if is not a problem:

#include <ArduinoJson.h>
//#include <SoftwareSerial.h>
#include <WiFi.h>
#include <esp_adc_cal.h>
#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include "icons.h"
#include <HTTPClient.h>

#define LM35_Sensor1    35

#define RXD2 16  //(RX2)
#define TXD2 17 //(TX2)
#define HC12 Serial2  //Hardware serial 2 on the ESP32

#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels
#define OLED_RESET    -1 // Reset pin # (or -1 if sharing Arduino reset pin)
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

//SoftwareSerial HC12(8, 7); // HC-12 TX Pin, HC-12 RX Pin

const char* ssid     = "V = R * I";
const char* password = "blablabla"; 

int LM35_Raw_Sensor1 = 0;
float LM35_TempC_Sensor1 = 0.0;
float LM35_TempF_Sensor1 = 0.0;
float Voltage = 0.0;

bool giorno = true;
int ritenta = 0;
String desc = "default", wid = "default", type = "nointernet", rec = "";
String tempEsterna = "--.-'C", tempInterna = "--.-'C", pressioneEsterna = "--%";
float arrayTI[3]; int posATI = 0;

void task1(void * parameters){
  bool nuovo = false;
  for(;;){
    while (HC12.available()) {        // If HC-12 has data
      rec += HC12.read();
      Serial.println("There are some data incoming!");
      Serial.println(rec);
      nuovo = true;
    }
    if (nuovo == true){ 
      int temp;
      for (int i = 0; rec[i] != '@'; i++){
        tempEsterna += rec[i];
        temp = i;
      }
  
      for(int i = temp + 1; rec[i] != NULL; i++){
        pressioneEsterna += rec[i];
      }
      nuovo = false;
      rec = "";
      //Serial.println("temperatura: " + tempEsterna + ", umidità: " + pressioneEsterna);
      //display.fillRect(5, 61, 118, 2, BLACK);
      //display.display();
      //startBar();
    }
    vTaskDelay(100 / portTICK_PERIOD_MS);
    Serial.println("searching signal");
  }
}

void setup() {
  Serial.begin(9600);             // Serial port to computer
  HC12.begin(9600, SERIAL_8N1, RXD2, TXD2);      // Serial port to HC12
  if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { 
    Serial.println(F("SSD1306 allocation failed"));
    for(;;); // Don't proceed, loop forever
  }
  display.clearDisplay(); // Clear the buffer.
  display.setTextSize(1);
  display.setTextColor(WHITE);
  WiFi.begin(ssid, password);
  int cont = 0;
  while (WiFi.status() != WL_CONNECTED) {
    display.setCursor(5, 32);
    display.clearDisplay();
    display.println("<connection attempt>");
    //display.println(5-cont);
    display.display();
    cont++;
    delay(1000);
  }
  display.clearDisplay();
  setIcon("sole");
  xTaskCreate(
    task1,
    "Task 1",
    1000,
    NULL,
    1,
    NULL  
  );
}

void loop() {
  UpdateFromAPI();
  display.fillRect(0, 49, 128, 11, BLACK);
  display.display();
  display.setCursor(5, 50);
  display.print(desc);
  display.display();
  setIcon(type);
  
  display.drawFastHLine(4, 60, 120, WHITE);
  display.drawFastHLine(4, 63, 120, WHITE);
  display.drawFastVLine(4, 60, 4, WHITE);
  display.drawFastVLine(124, 60, 4, WHITE);
  //display.drawCircle(64, 32, 3, WHITE);
  
  updateLM35();

  display.fillRect(60, 5, 68, 44, BLACK);
  display.display();

  display.setCursor(64, 8);
  display.print(tempEsterna);
  display.setCursor(64, 23);
  display.print(tempInterna + "'C");
  display.setCursor(64, 38);
  display.print(pressioneEsterna);
  display.display();

  startBar();
  //Serial.println("end time wait");
}

void startBar(){
  for (int i = 1; i < 60; i+=2){
    display.fillRect(5, 61, i*2, 2, WHITE);
    display.display();
    //updateLM35();
    //display.fillRect(60, 5, 68, 44, BLACK);
    //display.setCursor(64, 23);
    //display.print(tempInterna + "'C");
    //display.display();
    delay(2000);
  }
  display.fillRect(5, 61, 118, 2, BLACK);
  display.display();
}

uint32_t readADC_Cal(int ADC_Raw)
{
  esp_adc_cal_characteristics_t adc_chars;
  
  esp_adc_cal_characterize(ADC_UNIT_1, ADC_ATTEN_DB_11, ADC_WIDTH_BIT_12, 1100, &adc_chars);
  return(esp_adc_cal_raw_to_voltage(ADC_Raw, &adc_chars));
}

void updateLM35(){
  LM35_Raw_Sensor1 = analogRead(LM35_Sensor1);
  Voltage = readADC_Cal(LM35_Raw_Sensor1);
  tempInterna = (Voltage / 10) - 3;
  String tmp = String(tempInterna[0]) + "" + String(tempInterna[1]) + "" + String(tempInterna[2]) + "" + String(tempInterna[3]);
  if(posATI == 0){
    arrayTI[posATI] = tmp.toFloat();
    posATI = 1;
  } else if (posATI == 1){
    arrayTI[posATI] = tmp.toFloat();
    posATI = 2;
  } else if (posATI == 2){
    arrayTI[posATI] = tmp.toFloat();
    posATI = 0;
  }
  float temp = (arrayTI[0] + arrayTI[1] + arrayTI[2]) / 3;
  String tempDiNuovo = String(temp);
  tempInterna = String(tempDiNuovo[0]) + "" + String(tempDiNuovo[1]) + "" + String(tempDiNuovo[2]) + "" + String(tempDiNuovo[3]);
}

void setIcon(String meteo){
  if(meteo == "alba"){
    display.fillRect(10, 15, 36, 33, BLACK);
    display.drawBitmap(10, 15, alba, 36, 33, WHITE);
    display.display();      
  } else if (meteo == "Thunderstorm"){
      display.fillRect(10, 15, 36, 33, BLACK);
      display.drawBitmap(10, 15, fulmini, 36, 33, WHITE);
      display.display();  
  } else if (meteo == "Clouds" && wid == "801" && giorno == false){
      display.fillRect(10, 15, 36, 33, BLACK);
      display.drawBitmap(10, 15, notte_nuvolosa, 36, 33, WHITE);
      display.display();  
  } else if (meteo == "Clear" && giorno == false){
      display.fillRect(10, 15, 36, 33, BLACK);
      display.drawBitmap(10, 15, notte, 36, 33, WHITE);
      display.display();  
  } else if (meteo == "Clouds"){
      display.fillRect(10, 15, 36, 33, BLACK);
      display.drawBitmap(10, 15, nuvoloso, 36, 33, WHITE);
      display.display();  
  } else if (meteo == "Drizzle" || meteo == "Rain"){
      display.fillRect(10, 15, 36, 33, BLACK);
      display.drawBitmap(10, 15, pioggia, 36, 33, WHITE);
      display.display();  
  } else if (meteo == "Clouds" && wid == "801" && giorno == true){
      display.fillRect(10, 15, 36, 33, BLACK);
      display.drawBitmap(10, 15, sole_nuvoloso, 36, 33, WHITE);
      display.display();  
  } else if (meteo == "Clear" && giorno == true){
      display.fillRect(10, 15, 36, 33, BLACK);
      display.drawBitmap(10, 15, sole, 36, 33, WHITE);
      display.display();  
  } else if (meteo == "tramonto"){
      display.fillRect(10, 15, 36, 33, BLACK);
      display.drawBitmap(10, 15, tramonto, 36, 33, WHITE);
      display.display();
  } else if (meteo == "Snow"){
      display.fillRect(10, 15, 36, 33, BLACK);
      display.drawBitmap(10, 15, neve, 36, 33, WHITE);
      display.display();
  } else {
      display.fillRect(10, 15, 36, 33, BLACK);
      display.drawBitmap(10, 15, nointernet, 36, 33, WHITE);
      display.display();
  }
}

void UpdateFromAPI(){
  if ((WiFi.status() == WL_CONNECTED)) { //Check the current connection status
    //setIcon("sole");
    HTTPClient http;
    DynamicJsonDocument doc(1024);
 
    http.begin("http://api.openweathermap.org/data/2.5/weather?lat=45.96&lon=12.60&appid=e703cc05c5ab1ba3e0906bcdb542a143&lang=it"); //Specify the URL
    int httpCode = http.GET();  //Make the request

    String payload;
    if (httpCode > 0) { //Check for the returning code
      String payload = http.getString();
      Serial.println(httpCode);
      Serial.println(payload);
      DeserializationError error = deserializeJson(doc, payload);
      if (error) {
        Serial.print(F("deserializeJson() failed: "));
        Serial.println(error.c_str());
        delay(120000);
        return;
      }
      
      bool cicle = true;
      for(int i = 0; cicle == true; i++){ //get id
        if(payload[i] == 'i' && payload[i+1] == 'd'){
          cicle = false;
          wid = String(payload[i+4]) + "" + String(payload[i+5]) + "" + String(payload[i+6]);
          //Serial.println("id: " + wid);
        }
      }
      cicle = true;
      desc = "";
      for(int i = 0; cicle == true; i++) { //get short desc
        if(payload[i] == 'd' && payload[i+10] == 'n'){
          cicle = false;
          int j = i;
          while(payload[j+14] != ','){
            if (payload[j+14] != '"')
              desc += payload[j+14];
            j++;
          }
          //Serial.println("short desc: " + desc);
        }
      }
      if(desc.length() >= 17){
        int temp = 0;
        String tmp = "";
        for (int h = 0; h <= 17; h++){
          tmp += desc[h];
        }
        desc = tmp + "...";
      }
      
      cicle = true;
      type = "";
      for(int i = 0; cicle == true; i++){ //get type weather
        if(payload[i] == 'm' && payload[i+3] == 'n'){
          cicle = false;
          int j = i;
          while(payload[j+7] != ','){
            if (payload[j+7] != '"')
              type += payload[j+7];
            j++;
          }
          //Serial.println("weather type: " + type);
        }
      }
    }
    http.end();
  } else {
    if(ritenta == 10){
      WiFi.begin(ssid, password);
      ritenta = 0;
    } else
      ritenta++;
    setIcon("nointernet");
    type = "nointernet";
    desc = "no internet";
  }
}

The problem is that he continually thinks that there are coming data, why?

this is infinite loop:

I know, and for Arduino uno is correct, because it say if there are data incoming, and while they are coming, save them in the String. Is not this correct for esp32?

and here will outbond of the array

if you data is not contains "@"

nope, this coding is bad for Uno too

Sorry i forgot to say about that, the receiving data is always like that:
temp@humidity
example: 21.5@45

But all tutorials for arduino uno or nano uses this while.

Think how your code will works, if the first loop is received only "tem" of "temp@humidity" string? It is absolutely normal that the string is received in parts...

Yes, is possible for some strange reason. But in the 99.9% of the cases the while loop will get the char coming and will put them into a String the will be always temp@humidity. I can't get your point.

I made it work: modified the function and added a new one:

void task1(void * parameters){
  bool nuovo = false;
  for(;;){
    while (HC12.available()) {        // If HC-12 has data
      rec += char(HC12.read());
      nuovo = true;
    }

    if (rec != " " && rec != ""){    
      Serial.println("what received: " + rec);
      String temp = "", temp2 = "";
      int c = 0;
      tempEsterna = splitString(rec, '@', 0);
      umiditaEsterna = splitString(rec, '@', 1);
      Serial.print(tempEsterna + ", " + umiditaEsterna);
      rec = "";
    }
    vTaskDelay(100 / portTICK_PERIOD_MS);
    Serial.println("searching signal");
  }
}

String splitString(String str, char sep, int index)
{
 int found = 0;
 int strIdx[] = { 0, -1 };
 int maxIdx = str.length() - 1;

 for (int i = 0; i <= maxIdx && found <= index; i++)
 {
    if (str.charAt(i) == sep || i == maxIdx)
    {
      found++;
      strIdx[0] = strIdx[1] + 1;
      strIdx[1] = (i == maxIdx) ? i+1 : i;
    }
 }
 return found > index ? str.substring(strIdx[0], strIdx[1]) : "";
}

And i think there was a problem powering the module, like that there was too much modules and he could not have sufficent power from the 3v3, idk, but fixed wiring the hc12 in the 5v. And i think that was the problem: somehow "receiving" a fake signal of receiving some data because now it doesn't eneter in the while until there is real signal.