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????
