一、项目介绍
夏季雷电灾害频繁发生,属于气象灾害的一种,是世界公认的十大自然灾害之一。尤其近些年,极端天气频发。怀着敬畏的心理,对自然界发生的雷电,我们只有躲避。本项目是一个雷电来临预警装置,目的是为野外旷野中工作、游玩的人们,提供雷暴来袭警告。
由于雷电发生并非突然地发生,往往是由远及近,危险逐渐增强。本项目就是监控雷电的距离,当雷电靠近时,使用声音、图像、灯光等方式进行示警,以提醒人们进行躲避,避免雷电带来灾难。
二、硬件介绍
主控使用ATOMS3。AtomS3 是一款基于ESP32-S3主控的高集成度可编程控制器,内部集成了ESP32-S3主控,集成WiFi功能,8M片上FLASH,0.85寸IPS屏幕,屏幕下方具有可编程按键功能,内置5V转3.3V电路,6轴陀螺仪传感器MPU6886,板载Type-C接口,供电及固件下载,一个HY2.0-4P扩展端口,底部预留6个GPIO以及电源引脚,方便扩展应用。产品大小只有24*24*13mm,适用于各种嵌入式的智能设备应用。这里使用了AtomS3 的屏幕和下方6个GPIO引脚。
闪电传感器 Lightning Sensor。Dfrobot家的传感器,SKU:SEN0290。闪电传感器采用AMS独具创新的AS3935数字闪电传感芯片与Coilcraft的MA5532-AE专用天线,可在室内或室外,安全地检测方圆40km范围内发生闪电的距离,闪电强度与统计闪电发生次数。模块内嵌专门抗干扰算法可有效避免各类家用电器所产生的电气干扰。
三、系统设计
闪电传感器提供了IIC接口,同时提供了中断接口。当闪电发生时中断接口会有高电平输出。通过ATOMS3接收中断,读取IIC接口数据,获取闪电发生的信息。AtomS3自带屏幕,通过屏幕显示闪电信息,并且增加了蜂鸣器和一颗全彩LED灯,用来做闪电提醒。
AtomS3使用了FreeRtos操作系统,创建了三个进程,主进程负责接收中断,读取闪电传感器的内容,显示进程负责在屏幕上显示UI内容,还有一个警告进程,负责控制蜂鸣器和LED灯,做闪电提醒。进程之间使用消息队列进行通讯。
四、硬件设计
硬件还是比较简单,首先是电源部分,毕竟这个设备是需要便于携带的,所以使用锂电池作为动力来源。使用TP5400充放电管理芯片对锂电池进行管理,将锂电池升压到5v,供系统工作。主控AtomS3使用2.54mm排针固定在PCB上,闪电传感器使用2.0mm的排母与主控连接,并通过两颗铜柱固定在PCB上。增加了一个MicroUSB口,用来给锂电池充电。
五、软件设计
软件使用arduino编程。编程工具Vscode+platformio。DFRobot官方提供了闪电传感器读取的库文件和例子,所以直接拿来库文件就可以使用了。毕竟闪电不是一直都有发生的,所以增加了一个显示时间的功能,系统开机后首先连接WIFI,获取时间,如果连接成功,则能显示正确的时间。然后开启了额外的两个进程,一个负责屏幕显示,一个负责蜂鸣器和LED的驱动。
void setup(void)
{
uint8_t wifitimes = 0;
display.init();
display.setRotation(2);
display.setBrightness(120);
USBSerial.begin(115200);
WiFi.begin(ssid, password); // 连接wifi并返回连接状态
while (WiFi.status() != WL_CONNECTED)
{ // If the wifi connection fails. 若wifi未连接成功
delay(500); // delay 0.5s. 延迟0.5s 超过10次未能连上 则放弃
USBSerial.print(".");
wifitimes++;
if (wifitimes > 10)
{
break;
}
}
configTime(gmtOffset_sec, daylightOffset_sec, ntpServer); // init and get the time. 初始化并设置NTP
delay(200);
disptime();
WiFi.disconnect(true); // Disconnect wifi. 断开wifi连接
WiFi.mode(WIFI_OFF); // Set the wifi mode to off. 设置wifi模式为关闭
lightningInit();
delay(100);
xTaskCreatePinnedToCore(dispTimeTask, "dispTimeTask", 1024 * 4, NULL, 2, NULL, 0);
xTaskCreatePinnedToCore(alterTask, "alterTask", 1024 * 4, NULL, 2, NULL, 1);
}
闪电传感器的使用参考着例程进行初始化,这里设置了外部中断,当闪电发生时,就会触发对应的外部中断函数。
DFRobot_AS3935_I2C lightning0((uint8_t)IRQ_PIN);
void lightningInit()
{
lightning0.setI2CAddress(AS3935_ADD3);
while (lightning0.begin() != 0)
{
USBSerial.print(".");
}
lightning0.defInit();
lightning0.powerUp(); // Configure senso
lightning0.setIndoors(); // set indoors or outdoors models
// lightning0.setOutdoors();
// disturber detection
lightning0.disturberEn();
// lightning0.disturberDis();
lightning0.setIRQOutputSource(0);
attachInterrupt(digitalPinToInterrupt(IRQ_PIN), AS3935_ISR, RISING);
attachInterrupt(digitalPinToInterrupt(BUTTONPIN), AS3935_ISR, FALLING); // 按按键 强行进入闪电检测模式
// lightning0.manualCal(AS3935_CAPACITANCE, AS3935_MODE, AS3935_DIST);
delay(500);
// // set capacitance
lightning0.setTuningCaps(AS3935_CAPACITANCE);
USBSerial.println("AS3935 manual cal complete");
lightning0.setNoiseFloorLvl(2);
lightning0.setWatchdogThreshold(2);
lightning0.setSpikeRejection(2);
}
主进程中,负责读取闪电传感器的寄存器,当有闪电中断发生时,读取闪电的距离和闪电的能量。闪电距离是0~40km的距离值,闪电能量还没弄明白具体是个什么含义。将读取到的值丢到消息队列中,负责显示的进程收到消息队列后,就会将闪电的距离显示咋屏幕上,并且发送消息队列给负责蜂鸣器和LED灯的进程,去驱动蜂鸣器和LED灯。
void loop(void)
{
lightningNode msgnode;
uint8_t intSrc;
if (AS3935IsrTrig)
{
AS3935IsrTrig = 0;
intSrc = lightning0.getInterruptSrc();
USBSerial.print(" intSrc=");
USBSerial.println(intSrc);
// 检测到闪电 即intSrc=1 则提取 闪电距离 和强度
if (intSrc == 1)
{
// Get rid of non-distance data
msgnode.lightningDistKm = lightning0.getLightningDistKm();
msgnode.lightningEnergyVal = lightning0.getStrikeEnergyRaw();
USBSerial.print("lightningDistKm=");
USBSerial.print(msgnode.lightningDistKm);
USBSerial.print(" lightningEnergyVal=");
USBSerial.println(msgnode.lightningEnergyVal);
xQueueSend(lightningQueue, &msgnode, portMAX_DELAY); //发送消息队列
}
vTaskDelay(2000);
}
vTaskDelay(100);
}
当闪电发生时,屏幕显示闪电的距离信息。显示的颜色由闪电的距离决定。距离的远近决定着屏幕显示和LED灯的颜色。当距离较远时,显示冷色调,距离近时显示暖色调,距离小于20千米时,蜂鸣器配合响起。每次闪电发生时,屏幕会显示闪电距离20秒,20秒内没有新的闪电发生就退出闪电信息的显示,继续显示时间信息。
六、效果展示
七、心得体会:
超爱FastBond活动,感谢电子森林。平时一些想法舍不得花钱,借着这次活动,终于把想法付诸实践,而且实现过程中还有一批大佬们细心指导!感谢!