返回首页

气象站 Atmega328 NRF24L01:原理图和代码

文章分析 Atmega328 搭配 NRF24L01 气象站的实现:RGB 平衡电路设计、软件闪烁滤波器、BMP280 最小二乘降水预报、通信控制。描述了设计错误和优化。

创建气象站:Atmega328 + NRF24L01 + 代码
Advertisement 728x90

基于Atmega328与NRF24L01的气象站:硬件与软件实现详解

气象站基站采用Atmega328微控制器构建,外接16 MHz谐振器。电源为5 V,通过独立的AMS1117 3.3 V稳压器为NRF24L01模块供电。电路包含RGB背光亮度平衡设计:红色通道使用100 Ω电阻,绿色和蓝色通道使用200 Ω电阻,以补偿人眼生理敏感度和晶体发光差异。

电源优化方案

初始电路中,电源和AREF各使用一个旁路电容。这虽然可行,但违反了推荐规范:每个VCC-GND对都需要单独的100 nF电容来抑制微控制器脉冲噪声。最优方案是电源端三个电容加上AREF端一个。在I²C总线上,两对上拉电阻是多余的;一对4.7 kΩ电阻就足够了。

PCB布局与接地设计

电路板采用光刻胶法和UV阻焊层手工制作。底层为实心GND多边形,过孔通过焊接导线实现。为光敏电阻分离模拟和数字接地被证明是不必要的:该传感器为低频,信号范围0.5–4.5 V,噪声在毫伏级。ADC输入端的0.1 µF滤波器可分流高频干扰并补偿共模接地尖峰。

Google AdInline article slot
  • 光敏电阻与光电二极管对比:光敏电阻(kΩ–MΩ)提供电压信号,抗噪性强;光电二极管(µA)需要干净的AGND。
  • 推荐方案:对于光敏电阻,采用公共接地并在ADC端加0.1 µF电容。

接地分离适用于低电流传感器(如热电偶、压电传感器)。

软件闪烁滤波技术

显示和背光亮度通过PWM基于光敏电阻调节。ADC噪声和热噪声(±3–4单位)会导致闪烁。电源优化未能解决问题;应用了3阶中值滤波器和指数滤波器。

int rawValue = analogRead(0);
int filteredValue = med.filter(rawValue);
float smoothValue = expF.filter(filteredValue);
int fotoresistor = map(smoothValue, 260, 1023, 0, 255);
fotoresistor = constrain(fotoresistor, 0, 255);
analogWrite(3, 255 - fotoresistor);

这种滤波器组合优于10次平均值:能消除尖峰且无明显反应延迟。

Google AdInline article slot

通过气压计预测降水

BMP280每10分钟测量一次气压,取10次读数平均值。使用最小二乘法分析最近6个值的数组进行近似计算。

if (millis() - lasttime > 600000) {
  lasttime = millis();
  PP = davlenie();
  for (byte i = 0; i < 5; i++) {
    pres1_array[i] = pres1_array[i + 1];
  }
  pres1_array[5] = PP;
}

// 最小二乘法
for (byte i = 0; i < 6; i++) {
  sumX += time_array[i];
  sumY += (long)pres1_array[i];
  sumX2 += time_array[i] * time_array[i];
  sumXY += (long)time_array[i] * pres1_array[i];
}
a = (long)6 * sumXY - (long)sumX * sumY;
a = (float)a / (6 * sumX2 - sumX * sumX);
delta = a * 6;
rain = map(delta, -250, 250, 100, -100);

系数a为斜率,delta为每小时变化量(Pa)。rain范围从-100(上升,晴朗)到+100(下降,降雨)。

通信控制与超时处理

当接收到户外传感器数据包时,记录lastReceiveTime。如果超过60分钟无数据:

Google AdInline article slot
if (radio.available()) {
  radio.read(&rxData, sizeof(rxData));
  lastReceiveTime = millis();
  dataIsFresh = true;
}
if (lastReceiveTime > 0 && millis() - lastReceiveTime > 3600000) {
  resetWirelessData();
}

resetWirelessData()dataIsFresh归零,屏幕显示破折号。

大气RGB背光效果

颜色随时间变化,模拟自然光:早晨——黄色,白天——蓝色,傍晚——粉色,夜晚——紫色。基于区间内进度的RGB线性插值实现。

float progress = (currentHour - 8 + (float)currentMinute / 60.0) / 3.0;
if (progress < 0.5) {
  float subProgress = progress * 2.0;
  r = 255;
  g = 80 + subProgress * 90;
  b = 0 + subProgress * 50;
} else {
  float subProgress = (progress - 0.5) * 2.0;
  r = 255 - subProgress * 170;
  g = 180 - subProgress * 50;
  b = 60 + subProgress * 195;
}
void day() {
  r = 85; g = 130; b = 255;
}

分阶段确保平滑过渡,无突兀跳跃。

外壳与固件

外壳:ABS + 透明PETG,电路板尺寸匹配显示屏。固件通过Arduino作为ISP在PLS连接器上烧录。

关键要点

  • RGB平衡:红色通道100 Ω电阻实现视觉均衡。
  • 滤波器:中值+指数滤波器优于平均值法,有效抑制闪烁。
  • 气压最小二乘法:delta ±250 Pa决定降雨概率。
  • NRF24L01 60分钟超时防止显示陈旧数据。
  • 光敏电阻采用公共接地加0.1 µF电容即可。

— Editorial Team

Advertisement 728x90

继续阅读