Commit c5a0df49 authored by 957dd's avatar 957dd

加入 了ads1115读取电压

parent 4cb33b70
......@@ -2,5 +2,5 @@
#define PROJECT_VERSION_MINOR 1
#define PROJECT_VERSION_PATCH 3
#define GIT_HASH ""
#define BUILD_TIMESTAMP "2025-05-22T11:00:34"
#define BUILD_TIMESTAMP "2025-05-24T09:39:55"
#define BUILD_USER "orangepi"
No preview for this file type
......@@ -4,16 +4,18 @@
extern int sda_pin; // GPIO0
extern int scl_pin; // GPIO1
bool SOFTiic_init();
// I2C 起始信号
void i2c_start(int sda, int scl);
void i2c_start();
// I2C 停止信号
void i2c_stop(int sda, int scl);
void i2c_stop();
// I2C 发送一个字节
void i2c_write_byte(int sda, int scl, uint8_t data);
void i2c_write_byte(uint8_t data);
// I2C 读取一个字节
uint8_t i2c_read_byte(int sda, int scl, bool ack);
uint8_t i2c_read_byte(bool ack);
#endif
\ No newline at end of file
......@@ -51,7 +51,7 @@ int mqtt_init() {
// 初始化 mosquitto 库
mosquitto_lib_init();
mosq = mosquitto_new(NULL, true, NULL);
mosq = mosquitto_new(NULL, true, NULL);//
if (!mosq) {
my_zlog_fatal("Failed to create Mosquitto client");
return -1;
......@@ -74,15 +74,22 @@ void on_connect(struct mosquitto *mosq, void *obj, int rc) {//回调函数
}
}
void heartbeat_send() {//心跳发送格式
float voltage = INA226_readBusVoltage(sda_pin, scl_pin);
float current = INA226_readCurrent(sda_pin, scl_pin);
void heartbeat_send() {//心跳发送格式*5/2
float voltage = INA226_readBusVoltage();
float current = INA226_readCurrent();
my_zlog_debug("%.2f\n", voltage);
if(voltage<=0.5){
voltage=ads1115_read_channel(0)*5/2;
current=ads1115_read_channel(1)*5/2;
my_zlog_debug("%.2f\n", voltage);
current=(current-voltage)*100;
}
char voltage_str[20]; // 足够存储转换后的字符串的缓冲区
sprintf(voltage_str, "%.2f", voltage);
char current_str[20]; // 足够存储转换后的字符串的缓冲区
sprintf(current_str, "%.2f", current);
if(gPwmCount >= 5) alarm_control(voltage);//判断电压警报
if(gPwmCount >= 5) alarm_control(voltage);//判断电压警报,在不动时候才判断
/*读取程序版本号*/
char *version_num = program_version();
......@@ -92,7 +99,7 @@ void heartbeat_send() {//心跳发送格式
}
message=1;
topic_middle_value();
topic_middle_value();//指针中间函数
cJSON *root = cJSON_CreateObject();
cJSON *body = cJSON_CreateObject();
......@@ -124,8 +131,8 @@ void heartbeat_send() {//心跳发送格式
void angle_mqtt_send() {
float angle_shot=ads1115_read_channel(2);
if(angle_shot>0){
angle_shot=ads1115_read_channel(2)*365/5;
my_zlog_debug("%.2f",angle_shot);
angle_shot=angle_shot*360/5;
//my_zlog_debug("%.2f",angle_shot);
topic_middle_value();
cJSON *root = cJSON_CreateObject();
char TOPIC_send_angle[26];
......@@ -144,9 +151,8 @@ void angle_mqtt_send() {
void mqtt_wirte(){//心跳格式,每5s一次心跳
if( AppExit_pin_pwm == 202) angle_mqtt_send();
if( heartbeat_count >= 30) heartbeat_send();
if( AppExit_pin_pwm == 202) angle_mqtt_send();
}
......@@ -159,10 +165,6 @@ void message_3(cJSON *body,cJSON *pwm_ctrl){//message_type为3,控制pwm
typeTemp=type->valueint;
valTemp= val->valueint;
if(typeTemp==3){
valTemp= val->valueint;
}
gvalt[0]=typeTemp;
gvalt[1]=modeTemp;
gvalt[2]=valTemp;
......
......@@ -2,70 +2,94 @@
#include "common.h"
#include "softiic.h"
int sda_pin=0; // GPIO0
int scl_pin=1; // GPIO1
int sda_pin = 0; // GPIO0
int scl_pin = 1; // GPIO1
// 软件 I2C 延时
void i2c_delay() {
delayMicroseconds(5);
delayMicroseconds(5); // ~5μs 延迟,适配 100kHz I2C
}
// 初始化 I2C 引脚
bool SOFTiic_init() {
pinMode(sda_pin, OUTPUT);
pinMode(scl_pin, OUTPUT);
digitalWrite(sda_pin, HIGH);
digitalWrite(scl_pin, HIGH);
return true;
}
// I2C 起始信号
void i2c_start(int sda, int scl) {
digitalWrite(sda, HIGH);
digitalWrite(scl, HIGH);
void i2c_start() {
pinMode(sda_pin, OUTPUT);
digitalWrite(sda_pin, HIGH);
digitalWrite(scl_pin, HIGH);
i2c_delay();
digitalWrite(sda, LOW);
digitalWrite(sda_pin, LOW);
i2c_delay();
digitalWrite(scl, LOW);
digitalWrite(scl_pin, LOW);
i2c_delay();
}
// I2C 停止信号
void i2c_stop(int sda, int scl) {
digitalWrite(sda, LOW);
digitalWrite(scl, LOW);
void i2c_stop() {
pinMode(sda_pin, OUTPUT);
digitalWrite(sda_pin, LOW);
digitalWrite(scl_pin, LOW);
i2c_delay();
digitalWrite(scl, HIGH);
digitalWrite(scl_pin, HIGH);
i2c_delay();
digitalWrite(sda, HIGH);
digitalWrite(sda_pin, HIGH);
i2c_delay();
}
// I2C 发送一个字节
void i2c_write_byte(int sda, int scl, uint8_t data) {
// I2C 发送一个字节,并检查 ACK(不返回,但内部可判断是否 ACK)
void i2c_write_byte(uint8_t data) {
pinMode(sda_pin, OUTPUT);
for (int i = 7; i >= 0; i--) {
digitalWrite(sda, (data >> i) & 0x01);
digitalWrite(sda_pin, (data >> i) & 0x01);
i2c_delay();
digitalWrite(scl, HIGH);
digitalWrite(scl_pin, HIGH);
i2c_delay();
digitalWrite(scl, LOW);
digitalWrite(scl_pin, LOW);
i2c_delay();
}
// 接收 ACK
pinMode(sda, INPUT);
digitalWrite(scl, HIGH);
pinMode(sda_pin, INPUT); // 释放 SDA
i2c_delay();
digitalWrite(scl_pin, HIGH);
i2c_delay();
int ack = digitalRead(sda_pin); // 0 = ACK,1 = NACK(你可以打印或设置状态变量)
// printf("ACK = %d\n", ack);
digitalWrite(scl_pin, LOW);
pinMode(sda_pin, OUTPUT); // 拉回输出模式
i2c_delay();
digitalWrite(scl, LOW);
pinMode(sda, OUTPUT);
}
// I2C 读取一个字节
uint8_t i2c_read_byte(int sda, int scl, bool ack) {
// I2C 读取一个字节并发送 ACK/NACK
uint8_t i2c_read_byte(bool ack) {
uint8_t data = 0;
pinMode(sda, INPUT);
pinMode(sda_pin, INPUT);
for (int i = 7; i >= 0; i--) {
digitalWrite(scl, HIGH);
digitalWrite(scl_pin, HIGH);
i2c_delay();
data |= (digitalRead(sda) << i);
digitalWrite(scl, LOW);
data |= (digitalRead(sda_pin) << i);
digitalWrite(scl_pin, LOW);
i2c_delay();
}
// 发送 ACK/NACK
pinMode(sda, OUTPUT);
digitalWrite(sda, ack ? LOW : HIGH);
digitalWrite(scl, HIGH);
pinMode(sda_pin, OUTPUT);
digitalWrite(sda_pin, ack ? LOW : HIGH); // 发送 ACK or NACK
i2c_delay();
digitalWrite(scl_pin, HIGH);
i2c_delay();
digitalWrite(scl, LOW);
pinMode(sda, INPUT);
digitalWrite(scl_pin, LOW);
i2c_delay();
pinMode(sda_pin, INPUT);
return data;
}
\ No newline at end of file
}
......@@ -67,7 +67,7 @@ void *Mqttbeat(void *arg) {
Delay_Ms(15,0);
while(1) {
ipaddr();//获取ip
if( AppExit_pin_pwm == 202) Delay_Ms(0,80);
if( AppExit_pin_pwm == 202) Delay_Ms(0,45);
if( AppExit_pin_pwm != 202) Delay_Ms(0,100);
heartbeat_count++;
mqtt_wirte();//心跳,3s一个
......
......@@ -3,67 +3,60 @@
#include "INA226.h"
float currentLSB ;
// 初始化 INA226
bool INA226_begin(int sda, int scl) {
pinMode(sda, OUTPUT);
pinMode(scl, OUTPUT);
digitalWrite(sda, HIGH);
digitalWrite(scl, HIGH);
return true;
}
// 配置 INA226
bool INA226_configure(int sda, int scl) {
bool INA226_configure() {
uint16_t config = 0x4127; // 默认配置:16 次平均,1.1ms 转换时间,连续模式
i2c_start(sda, scl);
i2c_write_byte(sda, scl, INA226_ADDRESS << 1);
i2c_write_byte(sda, scl, INA226_REG_CONFIG);
i2c_write_byte(sda, scl, config >> 8);
i2c_write_byte(sda, scl, config & 0xFF);
i2c_stop(sda, scl);
i2c_start();
i2c_write_byte(INA226_ADDRESS << 1);
i2c_write_byte(INA226_REG_CONFIG);
i2c_write_byte(config >> 8);
i2c_write_byte(config & 0xFF);
i2c_stop();
return true;
}
// 校准 INA226
bool INA226_calibrate(int sda, int scl, float rShuntValue, float iMaxExpected) {
bool INA226_calibrate(float rShuntValue, float iMaxExpected) {
currentLSB = iMaxExpected/32767.0 ; // 计算电流 LSB,/INA226_REG_CALIBRATION
uint16_t calibrationValue = (uint16_t)(0.00512 / (currentLSB * rShuntValue));
i2c_start(sda, scl);
i2c_write_byte(sda, scl, INA226_ADDRESS << 1);
i2c_write_byte(sda, scl, INA226_REG_CALIBRATION);
i2c_write_byte(sda, scl, calibrationValue >> 8);
i2c_write_byte(sda, scl, calibrationValue & 0xFF);
i2c_stop(sda, scl);
i2c_start();
i2c_write_byte(INA226_ADDRESS << 1);
i2c_write_byte(INA226_REG_CALIBRATION);
i2c_write_byte(calibrationValue >> 8);
i2c_write_byte(calibrationValue & 0xFF);
i2c_stop();
return true;
}
// 读取总线电压
float INA226_readBusVoltage(int sda, int scl) {
i2c_start(sda, scl);
i2c_write_byte(sda, scl, INA226_ADDRESS << 1);
i2c_write_byte(sda, scl, INA226_REG_BUSVOLTAGE);
i2c_start(sda, scl);
i2c_write_byte(sda, scl, (INA226_ADDRESS << 1) | 1);
uint8_t high = i2c_read_byte(sda, scl, true);
uint8_t low = i2c_read_byte(sda, scl, false);
i2c_stop(sda, scl);
float INA226_readBusVoltage() {
i2c_start();
i2c_write_byte(INA226_ADDRESS << 1);
i2c_write_byte(INA226_REG_BUSVOLTAGE);
i2c_start();
i2c_write_byte((INA226_ADDRESS << 1) | 1);
uint8_t high = i2c_read_byte(true);
uint8_t low = i2c_read_byte(false);
i2c_stop();
int16_t value = (high << 8) | low;
return value * 0.00125; // 1.25mV/LSB
}
// 读取电流
float INA226_readCurrent(int sda, int scl) {
i2c_start(sda, scl);
i2c_write_byte(sda, scl, INA226_ADDRESS << 1);
i2c_write_byte(sda, scl, INA226_REG_CURRENT);
i2c_start(sda, scl);
i2c_write_byte(sda, scl, (INA226_ADDRESS << 1) | 1);
uint8_t high = i2c_read_byte(sda, scl, true);
uint8_t low = i2c_read_byte(sda, scl, false);
i2c_stop(sda, scl);
float INA226_readCurrent() {
i2c_start();
i2c_write_byte(INA226_ADDRESS << 1);
i2c_write_byte(INA226_REG_CURRENT);
i2c_start();
i2c_write_byte((INA226_ADDRESS << 1) | 1);
uint8_t high = i2c_read_byte(true);
uint8_t low = i2c_read_byte(false);
i2c_stop();
int16_t value = (high << 8) | low;
return value * currentLSB; // 假设电流 LSB 为 1mA
}
\ No newline at end of file
......@@ -10,19 +10,16 @@
#define INA226_REG_CURRENT (0x04)
#define INA226_REG_CALIBRATION (0x05)
// 初始化 INA226
bool INA226_begin(int sda, int scl);
// 配置 INA226
bool INA226_configure(int sda, int scl);
bool INA226_configure();
// 校准 INA226
bool INA226_calibrate(int sda, int scl, float rShuntValue, float iMaxExpected);
bool INA226_calibrate( float rShuntValue, float iMaxExpected);
// 读取总线电压
float INA226_readBusVoltage(int sda, int scl);
float INA226_readBusVoltage();
// 读取电流
float INA226_readCurrent(int sda, int scl);
float INA226_readCurrent();
#endif // INA226_H
\ No newline at end of file
#include "ads1115.h"
#include "common.h"
int _sda_pin =0;
int _scl_pin =1;
#define ADS1115_ADDR 0x48
// I2C写寄存器
static void ads1115_write_register(uint8_t reg, uint16_t val) {
i2c_start(_sda_pin, _scl_pin);
i2c_write_byte(_sda_pin, _scl_pin, (ADS1115_ADDR << 1) | 0);
i2c_write_byte(_sda_pin, _scl_pin, reg);
i2c_write_byte(_sda_pin, _scl_pin, (val >> 8) & 0xFF);
i2c_write_byte(_sda_pin, _scl_pin, val & 0xFF);
i2c_stop(_sda_pin, _scl_pin);
i2c_start();
i2c_write_byte((ADS1115_ADDR << 1) | 0);
i2c_write_byte(reg);
i2c_write_byte((val >> 8) & 0xFF);
i2c_write_byte(val & 0xFF);
i2c_stop();
}
// 读取转换寄存器
static uint16_t ads1115_read_conversion() {
uint16_t result = 0;
i2c_start(_sda_pin, _scl_pin);
i2c_write_byte(_sda_pin, _scl_pin, (ADS1115_ADDR << 1) | 0);
i2c_write_byte(_sda_pin, _scl_pin, 0x00);
i2c_start(_sda_pin, _scl_pin);
i2c_write_byte(_sda_pin, _scl_pin, (ADS1115_ADDR << 1) | 1);
uint8_t msb = i2c_read_byte(_sda_pin, _scl_pin, 1);
uint8_t lsb = i2c_read_byte(_sda_pin, _scl_pin, 0);
i2c_stop(_sda_pin, _scl_pin);
i2c_start();
i2c_write_byte((ADS1115_ADDR << 1) | 0);
i2c_write_byte(0x00);
i2c_start();
i2c_write_byte((ADS1115_ADDR << 1) | 1);
uint8_t msb = i2c_read_byte(1);
uint8_t lsb = i2c_read_byte(0);
i2c_stop();
result = (msb << 8) | lsb;
return result;
}
bool ads1115_init(int _sda_pin, int _scl_pin) {
pinMode(_sda_pin, OUTPUT);
pinMode(_scl_pin, OUTPUT);
digitalWrite(_sda_pin, HIGH);
digitalWrite(_scl_pin, HIGH);
return true;
}
// 读取某个单端通道电压,channel = 0~3
float ads1115_read_channel(int channel) {
uint16_t config = 0;
if (channel == 0) config = 0xC203; // MUX=100 (AIN0-GND)
else if (channel == 1) config = 0xD203; // MUX=101 (AIN1-GND)
else if (channel == 2) config = 0xE203; // MUX=110 (AIN2-GND)
else if (channel == 3) config = 0xF203; // MUX=111 (AIN3-GND)
else return -1.0f;
if (channel < 0 || channel > 3)
return -1.0f;
ads1115_write_register(0x01, config);
delayMicroseconds(10000); // 等待转换
uint16_t config = 0x8000; // OS=1,启动转换
config |= ((4 + channel) << 12); // 单端MUX
config |= (0x00 << 9); // PGA ±6.144V
config |= (1 << 8); // 单次模式
config |= (0x04 << 5); // 128SPS
config |= 0x03; // 禁用比较器
uint16_t raw = ads1115_read_conversion();
int16_t val = (int16_t)raw;
float voltage_divided = val * 4.096f / 32768.0f;
//float real_voltage = val * 6.144f / 32768.0f;
// 假设分压电阻 R1=2k, R2=10k
float real_voltage = voltage_divided * (10.0f + 2.0f) / 10.0f;//无分压电阻
ads1115_write_register(0x01, config);
delay(10); // 等待转换
return real_voltage;
int16_t val = (int16_t)ads1115_read_conversion();
float voltage = val * 6.144f / 32768.0f;
return voltage;
}
......@@ -4,7 +4,7 @@
#include <stdint.h>
#include <stdbool.h>
// 初始化GPIO引脚(SDA、SCL),必须先调用
bool ads1115_init(int _sda_pin, int _scl_pin);
bool ads1115_init();
// 读取指定通道AIN0~AIN3的电压值(单位伏特)
// 输入参数 channel: 0~3
......
#include "main.h"
int main(int argc, char *argv[]) {
int main_start_error_return() {
if(logconf_create() != 0) {
return 1;
}
if(logprject_Init() != 0) {
my_zlog_fatal( "日志初始化失败");
//printf("日志初始化失败");
return 2;
}
if (wiringPiSetup() == -1) {
my_zlog_fatal("WiringPi setup failed!");
//printf("WiringPi setup failed!\n");
return 3;
}
if (!INA226_begin(sda_pin, scl_pin)&& !ads1115_init(sda_pin, scl_pin)) {
if (!SOFTiic_init()) {
my_zlog_fatal("INA226 初始化失败或者ads1115初始化失败!");
//printf("INA226 初始化失败!\n");
return 4;
return 4;
}
if(Device_File_Init()!=0) {
my_zlog_fatal("This is a fatal message");
//printf("设备文件读取初始化失败!\n");
return 5;
}
if(request_date() != 0) {
my_zlog_fatal("This is a fatal message");
//printf("拉取接口初始化失败\n");
return 6;
}
int adino_jude = system("pactl load-module module-alsa-source device=hw:2,0");
if (adino_jude == 0) {
......@@ -40,30 +35,38 @@ int main(int argc, char *argv[]) {
my_zlog_info("程序初始化成功");
//printf("程序初始化成功\n");
system("pkill chromium");
// 配置 INA226
if(!INA226_configure(sda_pin, scl_pin)) {
if(!INA226_configure()) {
my_zlog_warn("INA226初始化失败");
}
// 校准 INA226
float rShuntValue = 0.1; // 分流电阻值(单位:欧姆)
float iMaxExpected = 5; // 最大预期电流(单位:安培)
if(!INA226_calibrate(sda_pin, scl_pin, rShuntValue, iMaxExpected)){
if(!INA226_calibrate(rShuntValue, iMaxExpected)){
my_zlog_warn("INA226校准失败");
}
gStart=time(NULL);//开始时间戳
if(ipaddr() != 0) {//获取ip
my_zlog_fatal("I获取失败");
my_zlog_fatal("Ip获取失败");
return -1;
}
if(thread_start(AppExit,Mqttbeat,opensh,Mqtt_onnect,delay_count) !=0 ) {//开启线程)
my_zlog_fatal("开启线程失败");
return -1 ;
}
return 0;
}
int main(int argc, char *argv[]) {
if(main_start_error_return()!=0){
my_zlog_error("程序错误代码:%d\n",main_start_error_return());
return -1;
}
thread_end(); //关闭线程
my_zlog_info("程序关闭成功");
......@@ -71,6 +74,5 @@ int main(int argc, char *argv[]) {
Device_exit_end();//结束相应的设备的程序执行
//printf("程序关闭成功\n");
return EXIT_SUCCESS;
}
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment