diff --git a/.cproject b/.cproject index 42d764f..3adf0d2 100644 --- a/.cproject +++ b/.cproject @@ -533,7 +533,9 @@ - + + + @@ -699,7 +701,9 @@ - + + + @@ -856,7 +860,9 @@ - + + + @@ -1014,7 +1020,9 @@ - + + + @@ -1024,7 +1032,7 @@ - + @@ -1044,7 +1052,7 @@ - + diff --git a/.project b/.project index f059ea4..350c330 100644 --- a/.project +++ b/.project @@ -1,6 +1,6 @@ - 828F + project diff --git a/applications/data/DATA_comm.c b/applications/data/DATA_comm.c index c85c137..a0899e3 100644 --- a/applications/data/DATA_comm.c +++ b/applications/data/DATA_comm.c @@ -132,6 +132,10 @@ void pasre_DAT(const char *api, const char *json_str) cJSON_AddItemToObject(dat,"SYSHUM",cJSON_CreateNumber(sys_humidity)); cJSON_AddItemToObject(dat,"SYSTIME",cJSON_CreateString(systime)); cJSON_AddItemToObject(dat,"NAME",cJSON_CreateString(machine_name)); + cJSON_AddItemToObject(dat,"PBAT",cJSON_CreateNumber(pow_bat)); + cJSON_AddItemToObject(dat,"PCODE",cJSON_CreateNumber(pow_code)); + cJSON_AddItemToObject(dat,"PDEV1",cJSON_CreateNumber(pow_dev1)); + cJSON_AddItemToObject(dat,"PDEV2",cJSON_CreateNumber(pow_dev2)); cJSON_AddItemToObject(dat,"VAR",cJSON_CreateString(sys_var)); } else if (strcmp(api, "SC810") == 0) diff --git a/applications/data/Variable.c b/applications/data/Variable.c index 3743962..8b84993 100644 --- a/applications/data/Variable.c +++ b/applications/data/Variable.c @@ -8,7 +8,10 @@ rt_int32_t sys_humidity;//主机环境湿度 char sys_var[8];//主机版本0.0.00A unsigned char sys_time[6];//系统时间 unsigned int sys_run_time;//运行时间 - +int pow_bat;//电池电压 +int pow_code;//主电压 +int pow_dev1;//设备电压.通讯 +int pow_dev2;//设备电压,其它 // 动态数据缓冲区(初始化为 NULL,后续分配) char *DATA_dat; diff --git a/applications/data/Variable.h b/applications/data/Variable.h index 6090254..455dc4a 100644 --- a/applications/data/Variable.h +++ b/applications/data/Variable.h @@ -9,6 +9,10 @@ extern rt_int32_t sys_humidity;//主机环境湿度 extern char sys_var[8];//主机版本0.0.00A extern unsigned char sys_time[6];//系统时间 extern unsigned int sys_run_time;//运行时间 +extern int pow_bat;//电池电压 +extern int pow_code;//主电压 +extern int pow_dev1;//设备电压.通讯 +extern int pow_dev2;//设备电压,其它 // ===== 字符串变量 ===== extern char *DATA_dat; diff --git a/applications/drv/drv_ads111x.c b/applications/drv/drv_ads111x.c new file mode 100644 index 0000000..ac96d73 --- /dev/null +++ b/applications/drv/drv_ads111x.c @@ -0,0 +1,226 @@ +/* + * Copyright (c) 2025, Your Name + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2025-12-27 Developer First version for ADS1115 on RT-Thread + */ + +#include +#include +#include +#include "Variable.h" + +#define DBG_TAG "sensor.ads1115" +#define DBG_LVL DBG_LOG +#include + +/* ADS1115 I2C 地址(A0 引脚接地时为 0x48) */ +#define ADS1115_I2C_ADDR 0x48 +/* 使用的 I2C 总线设备名 */ +#define ADS1115_I2C_BUS_NAME "i2c2" // 根据你的板子修改,如 "i2c1" + +/* ADS1115 寄存器地址 */ +#define ADS1115_REG_CONVERT 0x00 +#define ADS1115_REG_CONFIG 0x01 + +static struct rt_i2c_bus_device *i2c_bus = RT_NULL; + +/** + * 向 ADS1115 写入配置寄存器 + */ +static rt_err_t ads1115_write_config(rt_uint16_t config) +{ + rt_uint8_t buf[3] = { + ADS1115_REG_CONFIG, + (rt_uint8_t)(config >> 8), + (rt_uint8_t)(config & 0xFF) + }; + + struct rt_i2c_msg msgs[1] = { + { + .addr = ADS1115_I2C_ADDR, + .flags = RT_I2C_WR, + .buf = buf, + .len = 3, + } + }; + + if (rt_i2c_transfer(i2c_bus, msgs, 1) != 1) + { + LOG_E("Failed to write config register."); + return -RT_ERROR; + } + return RT_EOK; +} + +/** + * 从 ADS1115 读取转换结果 + */ +static rt_err_t ads1115_read_conversion(rt_int16_t *value) +{ + rt_uint8_t buf[2] = {0}; + + struct rt_i2c_msg msgs[2] = { + { + .addr = ADS1115_I2C_ADDR, + .flags = RT_I2C_WR, + .buf = (rt_uint8_t[]){ADS1115_REG_CONVERT}, + .len = 1, + }, + { + .addr = ADS1115_I2C_ADDR, + .flags = RT_I2C_RD, + .buf = buf, + .len = 2, + } + }; + + if (rt_i2c_transfer(i2c_bus, msgs, 2) != 2) + { + LOG_E("Failed to read conversion register."); + return -RT_ERROR; + } + + *value = (rt_int16_t)((buf[0] << 8) | buf[1]); + return RT_EOK; +} + +/** + * 读取指定通道的 ADC 值(单端输入) + * channel: 0 ~ 3 (对应 AIN0~AIN3 对 GND) + * 返回:RT_EOK 或错误码 + */ +static rt_err_t ads1115_read_channel(rt_uint8_t channel, rt_int16_t *raw_value) +{ + if (channel > 3) + { + LOG_E("Invalid channel: %d", channel); + return -RT_EINVAL; + } + + // 配置:OS=1, MUX=100+ch (单端), PGA=001 (±4.096V), MODE=1 (single), DR=100 (128SPS) + rt_uint16_t config = 0x8000 | // OS = 1 + ((0x04 | channel) << 12) | // MUX: AINx vs GND + (0x01 << 9) | // PGA = ±4.096V + (0x01 << 8) | // MODE = single-shot + (0x04 << 5); // DR = 128 SPS + + if (ads1115_write_config(config) != RT_EOK) + { + return -RT_ERROR; + } + + rt_thread_mdelay(10); // 等待转换完成(128SPS ≈ 8ms) + + return ads1115_read_conversion(raw_value); +} + + +/** + * 将原始 ADC 值转换为毫伏(mV) + * 假设使用 ±2.048V 量程(PGA=1),则 LSB = 2.048V / 32768 ≈ 0.0625 mV/LSB + * 但因为是单端且参考地,实际范围 0~2.048V → 满量程 2.048V = 32768 LSB + * 所以:Voltage(mV) = raw * (2048 / 32768) = raw * 0.0625 + */ +static rt_int32_t ads1115_raw_to_mv(rt_int16_t raw) +{ + /* 注意:单端模式下,raw 应为正数(0 ~ 32767)*/ + return (rt_int32_t)(((rt_int64_t)raw * 125) / 1000); // 等价于 raw * 0.0625 * 1000 +} + +/** + * ADS1115 读取线程(示例:读取 AIN0) + */ +static void ads1115_thread_entry(void *parameter) +{ + rt_int16_t raw = 0 ,mt = 3600; + + while (1) + { + if(mt>3600) + { + if (ads1115_read_channel(0, &raw) == RT_EOK) + { + pow_bat = ads1115_raw_to_mv(raw); + } + else + { + LOG_E("Failed to read ADS1115 P_BAT"); + } + } + else + { + mt = 0; + } + + if (ads1115_read_channel(1, &raw) == RT_EOK) + { + pow_code = ads1115_raw_to_mv(raw); + } + else + { + LOG_E("Failed to read ADS1115 P_CODE"); + } + + if (ads1115_read_channel(2, &raw) == RT_EOK) + { + pow_dev1 = ads1115_raw_to_mv(raw); + } + else + { + LOG_E("Failed to read ADS1115 P_DEV1"); + } + + if (ads1115_read_channel(3, &raw) == RT_EOK) + { + pow_dev2 = ads1115_raw_to_mv(raw); + } + else + { + LOG_E("Failed to read ADS1115 P_DEV2"); + } + + + rt_thread_mdelay(1000); // 每 秒读取一次 + } +} + +/** + * ADS1115 驱动初始化函数 + */ +static int rt_hw_ads1115_init(void) +{ + i2c_bus = rt_i2c_bus_device_find(ADS1115_I2C_BUS_NAME); + if (i2c_bus == RT_NULL) + { + LOG_E("Failed to find I2C bus: %s", ADS1115_I2C_BUS_NAME); + return -RT_ENOSYS; + } + + LOG_I("Found I2C bus: %s", ADS1115_I2C_BUS_NAME); + + /* 创建读取线程 */ + rt_thread_t tid = rt_thread_create("ads1115", + ads1115_thread_entry, + RT_NULL, + 512, + RT_THREAD_PRIORITY_MAX - 2, + 10); + if (tid != RT_NULL) + { + rt_thread_startup(tid); + } + else + { + LOG_E("Failed to create ADS1115 thread."); + return -RT_ERROR; + } + + return RT_EOK; +} + +/* 自动初始化 */ +INIT_APP_EXPORT(rt_hw_ads1115_init); diff --git a/packages/packages.dbsqlite b/packages/packages.dbsqlite index 97c5b00..5ac3905 100644 Binary files a/packages/packages.dbsqlite and b/packages/packages.dbsqlite differ diff --git a/packages/pkgs.json b/packages/pkgs.json index 0dda38f..9230d29 100644 --- a/packages/pkgs.json +++ b/packages/pkgs.json @@ -14,6 +14,11 @@ "ver": "v8.3.11", "name": "LVGL" }, + { + "path": "/packages/system/perf_counter", + "ver": "v2.2.4.1", + "name": "PERF_COUNTER" + }, { "path": "/packages/system/sqlite", "ver": "v3.19.3", @@ -33,5 +38,20 @@ "path": "/packages/peripherals/rs485", "ver": "v1.06", "name": "RS485" + }, + { + "path": "/packages/arduino/RTduino", + "ver": "latest", + "name": "RTDUINO" + }, + { + "path": "/packages/arduino/signalio/Adafruit-BusIO", + "ver": "latest", + "name": "ARDUINO_ADAFRUIT_BUSIO" + }, + { + "path": "/packages/arduino/signalio/Adafruit-ADS1X15", + "ver": "latest", + "name": "ARDUINO_ADAFRUIT_ADS1X15" } ] \ No newline at end of file