Hardware/YF3300_ESP32S3.cs
using System;
namespace YFSoft.Hardware.YF3300_ESP32S3
{
public static class CPU
{
public static class Pins
{
// GPIO 0-47
public const int GPIO0 = 0;
public const int GPIO1 = 1;
public const int GPIO2 = 2;
public const int GPIO3 = 3;
public const int GPIO4 = 4;
public const int GPIO5 = 5;
public const int GPIO6 = 6;
public const int GPIO7 = 7;
public const int GPIO8 = 8;
public const int GPIO9 = 9;
public const int GPIO10 = 10;
public const int GPIO11 = 11;
public const int GPIO12 = 12;
public const int GPIO13 = 13;
public const int GPIO14 = 14;
public const int GPIO15 = 15;
public const int GPIO16 = 16;
public const int GPIO17 = 17;
public const int GPIO18 = 18;
public const int GPIO19 = 19;
public const int GPIO20 = 20;
public const int GPIO21 = 21;
public const int GPIO22 = 22;
public const int GPIO23 = 23;
public const int GPIO24 = 24;
public const int GPIO25 = 25;
public const int GPIO26 = 26;
public const int GPIO27 = 27;
public const int GPIO28 = 28;
public const int GPIO29 = 29;
public const int GPIO30 = 30;
public const int GPIO31 = 31;
public const int GPIO32 = 32;
public const int GPIO33 = 33;
public const int GPIO34 = 34;
public const int GPIO35 = 35;
public const int GPIO36 = 36;
public const int GPIO37 = 37;
public const int GPIO38 = 38;
public const int GPIO39 = 39;
public const int GPIO40 = 40;
public const int GPIO41 = 41;
public const int GPIO42 = 42;
public const int GPIO43 = 43;
public const int GPIO44 = 44;
public const int GPIO45 = 45;
public const int GPIO46 = 46;
public const int GPIO47 = 47;
public const int GPIO48 = 48;
}
}
public static class Mainboard
{
// 主板引脚定义
public static class Pins
{
// LED 指示灯(根据实际硬件连接)
public const int YellowLED = CPU.Pins.GPIO40; // 黄色LED - 网络状态指示
public const int GreenLED = CPU.Pins.GPIO39; // 绿色LED - 配网状态指示
// 兼容旧命名
public const int CommLED = YellowLED; // 通信指示灯(黄色)
public const int UserLED = GreenLED; // 用户指示灯(绿色)
// 按钮
public const int BOOT = CPU.Pins.GPIO0;
// 开关量输入
public const int I1 = CPU.Pins.GPIO21; // 输入1
public const int I2 = CPU.Pins.GPIO47; // 输入2
// 继电器输出
public const int Q1 = CPU.Pins.GPIO48; // 继电器1
}
// RS485 串口定义
public static class RS485
{
public const string PortName = "COM1";
public const int DefaultBaudRate = 9600;
public const int TxPin = CPU.Pins.GPIO9; // UART1 TX (电路图: TX1=IO9)
public const int RxPin = CPU.Pins.GPIO10; // UART1 RX (电路图: RX1=IO10)
}
// RS232 串口定义
public static class RS232
{
public const string PortName = "COM2";
public const int DefaultBaudRate = 9600;
public const int TxPin = CPU.Pins.GPIO11; // UART2 TX (电路图: TX2=IO11)
public const int RxPin = CPU.Pins.GPIO12; // UART2 RX (电路图: RX2=IO12)
}
// I2C 总线定义
public static class I2C
{
public const int BusId = 1;
public const int SdaPin = CPU.Pins.GPIO17;
public const int SclPin = CPU.Pins.GPIO18;
public const int DefaultSpeed = 100000; // 100kHz
}
// 开关量输入通道
public static class DigitalInputs
{
public const int Count = 2;
public static readonly int[] Channels = { Mainboard.Pins.I1, Mainboard.Pins.I2 };
}
// 继电器输出通道
public static class Relays
{
public const int Count = 1;
public static readonly int[] Channels = { Mainboard.Pins.Q1 };
}
// LED 闪烁时间定义(毫秒)
public static class LEDTiming
{
// 黄色LED - 网络状态指示
public const int NetworkConnecting_On = 0; // 常亮(正在连接)
public const int NetworkConnecting_Off = int.MaxValue;
public const int NetworkNormal_On = 500; // 慢闪(正常)
public const int NetworkNormal_Off = 1500;
public const int NetworkError_On = 200; // 快闪(异常)
public const int NetworkError_Off = 200;
// 绿色LED - 配网状态指示
public const int ConfigAP_On = 0; // 常亮(配网中)
public const int ConfigAP_Off = int.MaxValue;
public const int ConfigSuccess_On = 500; // 慢闪(配网成功)
public const int ConfigSuccess_Off = 1500;
public const int ConfigFailed_On = 200; // 快闪(配网失败)
public const int ConfigFailed_Off = 200;
public const int ConfigNormal_On = 0; // 熄灭(正常运行)
public const int ConfigNormal_Off = 0;
}
}
// 设备信息定义
public static class DeviceInfo
{
public const string DeviceName = "YF3300-ESP32S3"; // 设备名称
public const string Manufacturer = "YFSoft"; // 制造商
public const string HardwareVersion = "1.0.0"; // 硬件版本
public const string FirmwareVersion = "1.0.0"; // 固件版本
public const string Model = "YF3300-ESP32S3"; // 设备型号
}
// 系统配置常量
public static class SystemConfig
{
// WiFi 配置
public const int WiFiConnectTimeout = 15000; // WiFi连接超时(毫秒)
public const int WiFiReconnectInterval = 5000; // WiFi重连间隔(毫秒)
// MQTT 配置
public const string DefaultMqttServer = "mqtt.yfiot.com"; // 默认MQTT服务器
public const int DefaultMqttPort = 1883; // 默认MQTT端口
public const int MqttKeepAliveInterval = 60; // MQTT心跳间隔(秒)
public const int MqttReconnectInterval = 5000; // MQTT重连间隔(毫秒)
// AP 配网配置
public const string APSSID = "YF3300_ESP32S3"; // AP热点名称
public const string APPassword = "yf123456"; // AP热点密码
public const string APIP = "192.168.4.1"; // AP网关IP
public const int APConfigTimeout = 600000; // 配网超时(10分钟)
// 数据采集配置
public const int SensorReadInterval = 30000; // 传感器读取间隔(毫秒)
public const int DataUploadInterval = 30000; // 数据上传间隔(毫秒)
// 看门狗配置
public const int WatchdogTimeout = 30000; // 看门狗超时(毫秒)
// NTP 配置
public const string DefaultNtpServer = "ntp.aliyun.com"; // 默认NTP服务器
public const int NtpSyncInterval = 3600000; // NTP同步间隔(1小时)
// 按钮配置
public const int ButtonLongPressDuration = 5000; // 长按时间(毫秒)
public const int ButtonDebounceTime = 50; // 按钮防抖时间(毫秒)
}
}
Models/YFLinkModels.cs
using System;
using System.Collections;
namespace YeFanIoTTest.Models
{
// YFLink协议基础请求模型
public class YFLinkRequest
{
public int id { get; set; } // 消息ID(32位整数)
public string ver { get; set; } = "1.3.0"; // 协议版本
public long timestamp { get; set; } // 时间戳(1970年1月1日以来的毫秒数)
}
// YFLink协议基础响应模型
public class YFLinkResponse
{
public int id { get; set; } // 消息ID(与请求ID对应)
public int code { get; set; } // 返回结果编码(200表示成功)
public string message { get; set; } // 返回结果描述
}
// 属性上传请求模型
public class PropertyPostRequest : YFLinkRequest
{
public Hashtable parameters { get; set; } // 属性键值对集合
}
// 属性上传响应模型
public class PropertyPostResponse : YFLinkResponse
{
public ArrayList data { get; set; } // 验证不通过的属性标识列表
}
// 事件上传请求模型
public class EventPostRequest : YFLinkRequest
{
public ArrayList parameters { get; set; } // 事件数据列表
}
// 事件数据模型
public class EventData
{
public int type { get; set; } // 事件类型(0-信息,1-告警,2-故障)
public int code { get; set; } // 事件编码(32位整数)
public string content { get; set; } // 事件内容(不超过1024字节)
public long time { get; set; } // 事件时间戳
}
// 服务下发请求模型
public class ServiceSendRequest : YFLinkRequest
{
public int serviceType { get; set; } // 服务类型(0-命令,1-参数)
public ServiceParams parameters { get; set; } // 服务参数
}
// 服务参数模型
public class ServiceParams
{
public string command { get; set; } // 服务命令
public string parameter { get; set; } // 服务参数
}
// 服务响应模型
public class ServiceSendResponse : YFLinkRequest
{
public ServiceResultParams parameters { get; set; } // 服务响应参数
}
// 服务响应参数模型
public class ServiceResultParams
{
public int code { get; set; } // 服务响应标识符
public string content { get; set; } // 服务响应内容
}
// NTP校时请求模型
public class NtpRequest : YFLinkRequest
{
public NtpParams parameters { get; set; } // NTP参数
}
// NTP参数模型
public class NtpParams
{
public long deviceSendTime { get; set; } // 设备发送请求的时间
}
// NTP校时响应模型
public class NtpResponse : YFLinkResponse
{
public NtpResponseParams parameters { get; set; } // NTP响应参数
}
// NTP响应参数模型
public class NtpResponseParams
{
public long deviceSendTime { get; set; } // 设备发送请求的时间
public long serverRecvTime { get; set; } // 服务器接收到该请求的时间
public long serverSendTime { get; set; } // 服务器发起发送该响应的时间
}
}
Models/DeviceModels.cs
using System;
namespace YeFanIoTTest.Models
{
// 设备配置模型 - 包含YFLink协议四元组及MQTT服务器配置
public class DeviceConfig
{
public string ProjectID { get; set; } // 项目ID
public string ProductID { get; set; } // 产品ID
public string DeviceID { get; set; } // 设备ID
public string DeviceKey { get; set; } // 设备密钥(32位随机字符)
public string MqttServer { get; set; } // MQTT服务器地址
public int MqttPort { get; set; } // MQTT服务器端口
// 验证设备配置是否有效
public bool IsValid()
{
return !string.IsNullOrEmpty(ProjectID) &&
!string.IsNullOrEmpty(ProductID) &&
!string.IsNullOrEmpty(DeviceID) &&
!string.IsNullOrEmpty(DeviceKey);
}
}
// WiFi配置模型
public class WifiConfig
{
public string SSID { get; set; } // WiFi名称
public string Password { get; set; } // WiFi密码
// 验证WiFi配置是否有效
public bool IsValid()
{
return !string.IsNullOrEmpty(SSID) && !string.IsNullOrEmpty(Password);
}
}
// 传感器数据模型 - 存储温湿度传感器采集的数据
public class SensorData
{
public double Temperature { get; set; } // 温度值(摄氏度)
public double Humidity { get; set; } // 湿度值(百分比)
public DateTime Timestamp { get; set; } // 数据采集时间戳
// 格式化输出传感器数据
public override string ToString()
{
return $"Temperature: {Temperature:F1}°C, Humidity: {Humidity:F1}%";
}
}
// 继电器状态模型
public class RelayState
{
public int RelayId { get; set; } // 继电器ID(1, 2, 3...)
public bool IsOn { get; set; } // 继电器状态(true=打开,false=关闭)
public DateTime Timestamp { get; set; } // 状态更新时间戳
}
// 开关量输入状态模型
public class DigitalInputState
{
public int InputId { get; set; } // 输入通道ID(1, 2, 3...)
public bool IsHigh { get; set; } // 输入状态(true=高电平,false=低电平)
public DateTime Timestamp { get; set; } // 状态更新时间戳
}
}
Enums/Enums.cs
using System;
namespace YeFanIoTTest.Enums
{
// 设备状态枚举 - 用于表示设备的生命周期状态
public enum DeviceState
{
Initializing, // 初始化中
CheckingConfig, // 检查配置
APConfiguring, // AP配网中
ConnectingWifi, // 连接WiFi中
ConnectingCloud, // 连接云端中
NormalRunning, // 正常运行
Error // 错误状态
}
// 网络状态枚举 - 用于表示WiFi和MQTT连接状态
public enum NetworkStatus
{
Connecting, // 连接中
Connected, // 已连接
Disconnected, // 已断开
Error // 错误
}
// 配网状态枚举 - 用于表示AP配网过程的状态
public enum ConfigStatus
{
Configuring, // 配网中
Success, // 配网成功
Failed, // 配网失败
Normal // 正常运行
}
// LED闪烁模式枚举
public enum LedBlinkMode
{
Off, // 关闭
On, // 常亮
SlowBlink, // 慢闪
FastBlink // 快闪
}
// 事件类型枚举 - 对应YFLink协议中的事件类型定义
public enum EventType
{
Info = 0, // 信息事件
Warning = 1, // 告警事件
Fault = 2 // 故障事件
}
// 服务类型枚举 - 对应YFLink协议中的服务类型定义
public enum ServiceType
{
Command = 0, // 命令服务
Parameter = 1 // 参数服务
}
}
Drivers/Sht30Sensor.cs
using System;
using System.Device.I2c;
using Microsoft.Extensions.Logging;
using nanoFramework.Logging;
using nanoFramework.Hardware.Esp32;
using YFSoft.Hardware.YF3300_ESP32S3;
namespace YeFanIoTTest.Drivers
{
// SHT30传感器数据模型
public class Sht30Data
{
public double Temperature { get; set; } // 温度值(摄氏度)
public double Humidity { get; set; } // 湿度值(百分比)
public DateTime Timestamp { get; set; } // 数据读取时间戳
// 格式化输出传感器数据
public override string ToString()
{
return $"Temperature: {Temperature:F1}°C, Humidity: {Humidity:F1}%, Time: {Timestamp:HH:mm:ss}";
}
}
// SHT30温湿度传感器驱动类
// 使用纯I2C通信协议实现,不依赖外部库
public class Sht30Sensor : IDisposable
{
private readonly ILogger _logger;
private I2cDevice _i2cDevice; // I2C 设备实例
private bool _disposed = false;
// SHT30 I2C命令定义
private const byte CMD_MEASURE_HIGH_REP = 0x2C; // 单次测量命令(高重复性)
private const byte CMD_MEASURE_HIGH_REP_2 = 0x06; // 单次测量命令第二字节
private const byte CMD_SOFT_RESET = 0x30; // 软复位命令
private const byte CMD_SOFT_RESET_2 = 0xA2; // 软复位命令第二字节
private const byte CMD_READ_STATUS = 0xF3; // 读状态寄存器命令
private const byte CMD_READ_STATUS_2 = 0x2D; // 读状态寄存器命令第二字节
// 默认构造函数:使用默认I2C配置
public Sht30Sensor()
{
_logger = LogDispatcher.LoggerFactory.CreateLogger("Sht30Sensor");
try
{
// 配置I2C引脚
Configuration.SetPinFunction(Mainboard.I2C.SdaPin, DeviceFunction.I2C1_DATA);
Configuration.SetPinFunction(Mainboard.I2C.SclPin, DeviceFunction.I2C1_CLOCK);
// 创建I2C设备(默认地址0x44)
var i2cSettings = new I2cConnectionSettings(Mainboard.I2C.BusId, 0x44);
_i2cDevice = I2cDevice.Create(i2cSettings);
_logger.LogInformation($"SHT30 sensor initialized on I2C bus {Mainboard.I2C.BusId}, address: 0x44");
}
catch (Exception ex)
{
_logger.LogError($"Failed to initialize SHT30 sensor: {ex.Message}");
throw;
}
}
// 带参数构造函数
// i2cBusId: I2C总线ID
// sensorAddress: 传感器地址(0x44或0x45)
public Sht30Sensor(int i2cBusId, byte sensorAddress)
{
_logger = LogDispatcher.LoggerFactory.CreateLogger("Sht30Sensor");
try
{
// 配置I2C引脚
Configuration.SetPinFunction(Mainboard.I2C.SdaPin, DeviceFunction.I2C1_DATA);
Configuration.SetPinFunction(Mainboard.I2C.SclPin, DeviceFunction.I2C1_CLOCK);
// 创建I2C设备
var i2cSettings = new I2cConnectionSettings(i2cBusId, sensorAddress);
_i2cDevice = I2cDevice.Create(i2cSettings);
_logger.LogInformation($"SHT30 sensor initialized on I2C bus {i2cBusId}, address: 0x{sensorAddress:X2}");
}
catch (Exception ex)
{
_logger.LogError($"Failed to initialize SHT30 sensor: {ex.Message}");
throw;
}
}
// 读取传感器数据
// 返回:Sht30Data对象,读取失败返回null
public Sht30Data ReadMeasurement()
{
if (_disposed)
{
_logger.LogWarning("Sensor has been disposed");
return null;
}
try
{
// 发送测量命令(单次测量,高重复性)
byte[] writeBuffer = new byte[] { CMD_MEASURE_HIGH_REP, CMD_MEASURE_HIGH_REP_2 };
_i2cDevice.Write(writeBuffer);
// 等待测量完成(高重复性测量需要约15ms)
System.Threading.Thread.Sleep(20);
// 读取6字节数据:温度高字节、温度低字节、温度CRC、湿度高字节、湿度低字节、湿度CRC
byte[] readBuffer = new byte[6];
_i2cDevice.Read(readBuffer);
// 解析温度数据(前2字节)
int rawTemperature = (readBuffer[0] << 8) | readBuffer[1];
// 解析湿度数据(后2字节,跳过CRC)
int rawHumidity = (readBuffer[3] << 8) | readBuffer[4];
// 计算实际温度和湿度
// 温度公式:T = -45 + 175 * (raw / 65535.0)
// 湿度公式:RH = 100 * (raw / 65535.0)
double temperature = -45.0 + (175.0 * rawTemperature / 65535.0);
double humidity = 100.0 * rawHumidity / 65535.0;
// CRC校验(可选)
if (!CheckCRC(readBuffer[0], readBuffer[1], readBuffer[2]))
{
_logger.LogWarning("Temperature CRC check failed");
}
if (!CheckCRC(readBuffer[3], readBuffer[4], readBuffer[5]))
{
_logger.LogWarning("Humidity CRC check failed");
}
return new Sht30Data
{
Temperature = temperature,
Humidity = humidity,
Timestamp = DateTime.UtcNow
};
}
catch (Exception ex)
{
_logger.LogError($"Failed to read SHT30 sensor: {ex.Message}");
return null;
}
}
// 重置传感器
public void Reset()
{
if (_disposed)
{
_logger.LogWarning("Sensor has been disposed");
return;
}
try
{
// 发送软复位命令
byte[] writeBuffer = new byte[] { CMD_SOFT_RESET, CMD_SOFT_RESET_2 };
_i2cDevice.Write(writeBuffer);
// 等待复位完成
System.Threading.Thread.Sleep(10);
_logger.LogInformation("SHT30 sensor reset successfully");
}
catch (Exception ex)
{
_logger.LogError($"Failed to reset SHT30 sensor: {ex.Message}");
}
}
// 读取状态寄存器
public ushort ReadStatus()
{
if (_disposed)
{
_logger.LogWarning("Sensor has been disposed");
return 0;
}
try
{
// 发送读状态命令
byte[] writeBuffer = new byte[] { CMD_READ_STATUS, CMD_READ_STATUS_2 };
_i2cDevice.Write(writeBuffer);
// 读取3字节:状态高字节、状态低字节、CRC
byte[] readBuffer = new byte[3];
_i2cDevice.Read(readBuffer);
// 组合状态字
ushort status = (ushort)((readBuffer[0] << 8) | readBuffer[1]);
return status;
}
catch (Exception ex)
{
_logger.LogError($"Failed to read SHT30 status: {ex.Message}");
return 0;
}
}
// CRC校验函数
// data1: 数据字节1
// data2: 数据字节2
// crc: CRC校验字节
// 返回:校验是否通过
private bool CheckCRC(byte data1, byte data2, byte crc)
{
// SHT30使用CRC-8校验
// 多项式:0x31 (x^8 + x^5 + x^4 + 1)
// 初始值:0xFF
byte crcValue = 0xFF;
// 计算第一个字节的CRC
crcValue ^= data1;
for (int i = 0; i < 8; i++)
{
if ((crcValue & 0x80) != 0)
{
crcValue = (byte)((crcValue << 1) ^ 0x31);
}
else
{
crcValue = (byte)(crcValue << 1);
}
}
// 计算第二个字节的CRC
crcValue ^= data2;
for (int i = 0; i < 8; i++)
{
if ((crcValue & 0x80) != 0)
{
crcValue = (byte)((crcValue << 1) ^ 0x31);
}
else
{
crcValue = (byte)(crcValue << 1);
}
}
return crcValue == crc;
}
// 释放资源
public void Dispose()
{
if (_disposed) return;
try
{
if (_i2cDevice != null)
{
_i2cDevice.Dispose();
_i2cDevice = null;
}
_disposed = true;
_logger.LogInformation("SHT30 sensor disposed");
}
catch (Exception ex)
{
_logger.LogError($"Error disposing SHT30 sensor: {ex.Message}");
}
}
}
更多推荐

所有评论(0)