Weather station

hello folks again. I spend this afternoon trying another approach. This time i use manchester encoder to transmit the data over RF. below i gonna post the transmitter and the receiver code.

Transmitter:

#include <Wire.h>
#include <SPI.h>
#include <SD.h>
#include <RTClib.h>
#include <DHT.h>
#include <Adafruit_BMP085.h>
#include <BH1750.h>
#include <Manchester.h> // https://github.com/mchr3k/arduino-libs-manchester

// Sensor Pins
#define DHTPIN 7
#define DHTTYPE DHT11
#define UV_PIN A0
#define RAIN_PIN 3
#define WIND_PIN 2
#define SD_CS_PIN 10
#define MQ135_PIN A1
#define TX_PIN 4 // RF transmitter

// Constants
#define RAIN_MM_PER_TICK 0.2
#define WIND_SPEED_FACTOR 2.4 // km/h per rotation/sec

// Sensor objects
RTC_DS3231 rtc;
DHT dht(DHTPIN, DHTTYPE);
Adafruit_BMP085 bmp;
BH1750 lightMeter;

// Variables
volatile unsigned int rainTicks = 0;
volatile unsigned int windTicks = 0;
unsigned long lastWindCalc = 0;
float windSpeedKmh = 0.0;
float rainfallMm = 0.0;

File dataFile;

void countRain() { rainTicks++; }
void countWind() { windTicks++; }

void setup() {
  Serial.begin(9600);
  man.setupTransmit(TX_PIN);

  dht.begin();
  bmp.begin();
  lightMeter.begin(BH1750::CONTINUOUS_HIGH_RES_MODE);
  rtc.begin();

  pinMode(RAIN_PIN, INPUT_PULLUP);
  pinMode(WIND_PIN, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(RAIN_PIN), countRain, FALLING);
  attachInterrupt(digitalPinToInterrupt(WIND_PIN), countWind, FALLING);

  if (SD.begin(SD_CS_PIN)) {
    if (!SD.exists("weather.csv")) {
      dataFile = SD.open("weather.csv", FILE_WRITE);
      dataFile.println("Timestamp,Temp_C_DHT,Humid_%,Temp_C_BMP,Pressure_hPa,UV,Light_lux,Rain_mm,Wind_kmh,MQ135_PPM");
      dataFile.close();
    }
  } else {
    Serial.println("SD init failed!");
  }

  lastWindCalc = millis();
}

void loop() {
  DateTime now = rtc.now();

  float tempDHT = dht.readTemperature();
  float humid = dht.readHumidity();
  float tempBMP = bmp.readTemperature();
  float pressure = bmp.readPressure() / 100.0;
  float lux = lightMeter.readLightLevel();
  float uvRaw = analogRead(UV_PIN);
  float uvIndex = (uvRaw / 1023.0) * 15.0;

  // Wind Speed
  if (millis() - lastWindCalc >= 2000) {
    noInterrupts();
    unsigned int ticks = windTicks;
    windTicks = 0;
    interrupts();
    float rps = ticks / 2.0;
    windSpeedKmh = rps * WIND_SPEED_FACTOR;
    lastWindCalc = millis();
  }

  // Rainfall
  noInterrupts();
  unsigned int rainCount = rainTicks;
  rainTicks = 0;
  interrupts();
  rainfallMm = rainCount * RAIN_MM_PER_TICK;

  // Air Quality
  int mq135_raw = analogRead(MQ135_PIN);
  float mq135_ppm = (mq135_raw / 1023.0) * 1000.0;

  // Timestamp
  char timestamp[20];
  sprintf(timestamp, "%04d-%02d-%02d %02d:%02d:%02d",
          now.year(), now.month(), now.day(),
          now.hour(), now.minute(), now.second());

  // Format message to send
  char rfMessage[80];
  snprintf(rfMessage, sizeof(rfMessage),
           "T:%.1fH:%.1fP:%.1fU:%.1fL:%.0fW:%.1fR:%.1fA:%.0f",
           tempDHT, humid, pressure, uvIndex, lux, windSpeedKmh, rainfallMm, mq135_ppm);

  Serial.print("Sending: ");
  Serial.println(rfMessage);

  // Transmit message using Manchester (char-by-char)
  for (int i = 0; i < strlen(rfMessage); i++) {
    man.transmit((uint16_t)rfMessage[i]);
    delay(5); // small delay between characters
  }

  // Save to SD
  dataFile = SD.open("weather.csv", FILE_WRITE);
  if (dataFile) {
    dataFile.print(timestamp); dataFile.print(",");
    dataFile.print(tempDHT); dataFile.print(",");
    dataFile.print(humid); dataFile.print(",");
    dataFile.print(tempBMP); dataFile.print(",");
    dataFile.print(pressure); dataFile.print(",");
    dataFile.print(uvIndex); dataFile.print(",");
    dataFile.print(lux); dataFile.print(",");
    dataFile.print(rainfallMm); dataFile.print(",");
    dataFile.print(windSpeedKmh); dataFile.print(",");
    dataFile.println(mq135_ppm);
    dataFile.close();
  }

  delay(10000); // Wait 10s
}

this is the receiver code:

#include <Manchester.h> // https://github.com/mchr3k/arduino-libs-manchester

#define RX_PIN 7          // RF receiver data pin
#define START_CHAR 'T'    // Start of message (you can adjust this if needed)
#define MAX_MESSAGE_LEN 80

char message[MAX_MESSAGE_LEN];
byte index = 0;

void setup() {
  Serial.begin(9600);
  man.setupReceive(RX_PIN);
  man.beginReceive();
  Serial.println("Manchester Receiver Started...");
}

void loop() {
  if (man.receiveComplete()) {
    uint16_t data = man.getMessage();
    man.beginReceive();

    // Only accept printable ASCII (safety filter)
    if (data >= 32 && data <= 126) {
      char c = (char)data;

      // Optional: reset message on new transmission
      if (c == START_CHAR) {
        index = 0;
      }

      if (index < MAX_MESSAGE_LEN - 1) {
        message[index++] = c;
        message[index] = '\0'; // Null-terminate
      }

      // Optionally detect end of message (e.g., message length or character)
      if (index > 5 && c == 'A') { // crude heuristic, "A:" is end (Air Quality)
        Serial.print("Received: ");
        Serial.println(message);
        index = 0;
      }
    } else {
      // Non-printable character — ignore or reset
      index = 0;
    }
  }
}

then i get this result in the serial of both arduinos

and my question is, why i only get an question mark and not the actual data????