Commit 63ec8d51 authored by 学习的菜鸟's avatar 学习的菜鸟

6

parent 277cc3bf
......@@ -6,14 +6,19 @@ int main(){
return -1;
}
if (wiringPiSetup() == -1) {
my_zlog_fatal("WiringPi setup failed!");
return -2;
}
if(device_id_file_init()!=0){
my_zlog_error("设备id读取失败");
return -2;
return -3;
}
if(device_mqtt_topic_init()!=0){
my_zlog_error("mqtt的topic读取失败");
return -2;
return -4;
}
int thread_rc=thread_start_init( thread_exit_time,thread_mqtt_beat,thread_open_browser,thread_mqtt_reconnect,thread_time_calculation,thread_play_mp3);
......
......@@ -13,6 +13,10 @@ int device_id_file_init();
/*初始化log日志*/
int mylog_init();
/*wiringPi初始化函数*/
int wiringPiSetup();
/*mqtt的topic初始化*/
int device_mqtt_topic_init();
......
......@@ -4,6 +4,7 @@
#include "mylog.h"
#include "mqtt_init.h"
#include "mqtt_infor_handle.h"
#include "browser_open.h"
#include "mqtt_verify.h"
pthread_t g_thread[6]; // 全局线程句柄数组(或传参)
......@@ -39,14 +40,14 @@ int thread_start_init(ThreadFunc thread_exit_time, ThreadFunc thread_mqtt_beat,
//出现意外自动停止
void *thread_exit_time(void *arg) {
// while(1){
// delay_ms(100);
// gPwmCount++;
// if(gPwmCount>=5) {
// device_warn_exit();
// gPwmCount=6;
// }
// }
while(1){
delay_ms(100);
g_devcontrol_exit_count++;
if(g_devcontrol_exit_count>=5) {
device_warn_exit();
g_devcontrol_exit_count=6;
}
}
return NULL;
}
......@@ -69,13 +70,13 @@ void *thread_mqtt_beat(void *arg) {
}
void *thread_open_browser(void *arg) {
// while(1){
// if(g_webrtc_index==1) {
// my_zlog_info("open cam");
// opencamsh();//10s后打开游览器并且进入网址
// }
// delay_ms(200);
// }
while(1){
if(g_webrtc_index==1) {
my_zlog_info("open cam");
opencamsh();//10s后打开游览器并且进入网址
}
delay_ms(200);
}
return NULL;
}
......
#include "device_init.h"
#include "gpio_init.h"
\ No newline at end of file
#ifndef DEVICE_INIT_H__
#define DEVICE_INIT_H__
#endif
\ No newline at end of file
......@@ -110,6 +110,6 @@ void pwm_init_speed() {
}
// void Device_exit_end(){//main最后结束需要调用的函数
// if(AppExit_pin_pwm == 202) tank_shot_back_stop_task_end();
// }
\ No newline at end of file
void device_exit_end(){//main最后结束需要调用的函数
if(AppExit_pin_pwm == 202) tank_shot_back_stop_task_end();
}
\ No newline at end of file
......@@ -2,10 +2,10 @@
此文件为通用文件,一般用于50hz的驱动等和引脚高低,适合车和船使用,
如果有其他需求,此文件就不需要使用
*/
#ifndef GPIO_COMMON_H__
#define GPIO_COMMON_H__
#ifndef GPIO_INIT_H__
#define GPIO_INIT_H__
extern int device_delay_count;//延时计算函数,使用前必须置0
//extern int device_delay_count;//延时计算函数,使用前必须置0
// 定义 PWM 引脚的 WiringPi 编号
#define PWM_PIN_SPEED 21
......@@ -23,6 +23,6 @@ void pin_value(int pin,int value);
void pwm_init_speed();
void pwm_value(int pin,int value); //软件陪我们控制调速
void Device_exit_end();//main最后结束需要调用的函数
void device_exit_end();//main最后结束需要调用的函数
#endif
#include <math.h>
#include <stdbool.h>
#include "common.h"
#include "INA226.h"
#include "softiic.h"
float currentLSB;
// 配置 INA226
bool INA226_configure() {
uint16_t config = 0x4127; // 默认配置:16次平均,1.1ms 转换时间,连续模式
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(float rShuntValue, float iMaxExpected) {
currentLSB = iMaxExpected / 32767.0; // 电流 LSB
uint16_t calibrationValue = (uint16_t)(0.00512 / (currentLSB * rShuntValue));
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() {
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.00125f; // 每 LSB = 1.25mV
}
// 读取电流
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;
}
#ifndef INA226_H
#define INA226_H
#define INA226_ADDRESS (0x40) // INA226 的 I2C 地址
#define INA226_REG_CONFIG (0x00)
#define INA226_REG_SHUNTVOLTAGE (0x01)
#define INA226_REG_BUSVOLTAGE (0x02)
#define INA226_REG_POWER (0x03)
#define INA226_REG_CURRENT (0x04)
#define INA226_REG_CALIBRATION (0x05)
// 配置 INA226
bool INA226_configure();
// 校准 INA226
bool INA226_calibrate( float rShuntValue, float iMaxExpected);
// 读取总线电压
float INA226_readBusVoltage();
// 读取电流
float INA226_readCurrent();
#endif // INA226_H
\ No newline at end of file
#include "ads1115.h"
#include "common.h"
#define ADS1115_ADDR 0x48
// I2C写寄存器
static void ads1115_write_register(uint8_t reg, uint16_t val) {
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();
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;
}
// 读取某个单端通道电压,channel = 0~3
float ads1115_read_channel(int channel) {
if (channel < 0 || channel > 3)
return -1.0f;
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; // 禁用比较器
ads1115_write_register(0x01, config);
delay(10); // 等待转换
int16_t val = (int16_t)ads1115_read_conversion();
float voltage = val * 6.144f / 32768.0f;
return voltage;
}
#ifndef ADS1115_H
#define ADS1115_H
#include <stdint.h>
#include <stdbool.h>
// 初始化GPIO引脚(SDA、SCL),必须先调用
bool ads1115_init();
// 读取指定通道AIN0~AIN3的电压值(单位伏特)
// 输入参数 channel: 0~3
// 返回实际电压值,负数代表错误
float ads1115_read_channel(int channel);
#endif
\ No newline at end of file
#include "common.h"
#include "heat.h"
#define MAX_LINE_LENGTH 20
char temperature[20];
float temp_str;
//温度获取
int heat_tem() {
FILE *file;
char line[MAX_LINE_LENGTH];
file = fopen("/sys/class/thermal/thermal_zone0/temp", "r");
if (file == NULL) {
perror("无法打开温度文件");
return 1;
}
if (fgets(line, sizeof(line), file) != NULL) {
temp_str = (float)atof(line) / 1000.0;
sprintf(temperature, "%.2f°C", temp_str);
my_zlog_debug("CPU 温度: %.2f°C", temp_str);
}
fclose(file);
return 0;
}
\ No newline at end of file
#ifndef HEAT_H__
#define HEAT_H__
int heat_tem();//获取CPU温度
extern char temperature[];//温度存储
#endif
\ No newline at end of file
#include "common.h"
#include "infrared_gun.h"
// 初始化
int infrared_Init() {
pinMode(IR_PIN, OUTPUT);
pinMode(IR_PIN_rec, INPUT);
return 0;
}
// 字符串补零并转为uint32数组
void pad_and_convert(const char* hex_str, uint32_t* data_out, int* count) {
char padded[17] = {0};
int len = strlen(hex_str);
int pad_len = 16 - len;
for (int i = 0; i < pad_len; i++) {
padded[i] = '0';
}
strcpy(padded + pad_len, hex_str);
*count = 0;
for (int i = 0; i < 16; i += 8) {
char temp[9] = {0};
strncpy(temp, padded + i, 8);
sscanf(temp, "%x", &data_out[*count]);
(*count)++;
}
}
// 发送32位数据(NEC协议)
void sendNEC(uint32_t data) {
// 起始码
digitalWrite(IR_PIN, HIGH);
Delay_us(START_PULSE_HIGH);
digitalWrite(IR_PIN, LOW);
Delay_us(START_PULSE_LOW);
// 发送32位数据
for (int i = 31; i >= 0; i--) {
if ((data >> i) & 1) {
digitalWrite(IR_PIN, HIGH);
Delay_us(ONE_PULSE_HIGH);
digitalWrite(IR_PIN, LOW);
Delay_us(ONE_PULSE_LOW);
} else {
digitalWrite(IR_PIN, HIGH);
Delay_us(ZERO_PULSE_HIGH);
digitalWrite(IR_PIN, LOW);
Delay_us(ZERO_PULSE_LOW);
}
}
// 停止码
digitalWrite(IR_PIN_rec, LOW);
Delay_us(STOP_PULSE);
}
// 发送完整字符串数据(如“00020200000000”)
void sendHexString(const char* hex_str) {
uint32_t data_arr[2];
int count = 0;
pad_and_convert(hex_str, data_arr, &count);
for (int i = 0; i < count; i++) {
sendNEC(data_arr[i]);
// 适当延时两次发送间隔
}
}
// 接收多段NEC数据(128位 = 4次)
void receiveNEC_Multi(int num_blocks) {
uint32_t data_arr[4] = {0};
for (int j = 0; j < num_blocks; j++) {
uint32_t data = 0;
// 等待高电平(起始码)
while (digitalRead(IR_PIN_rec) == LOW);
Delay_us(START_PULSE_MIN);
for (int i = 31; i >= 0; i--) {
while (digitalRead(IR_PIN_rec) == LOW);
Delay_us(ZERO_PULSE_MIN);
if (digitalRead(IR_PIN_rec) == HIGH) {
Delay_us(ONE_PULSE_MIN);
data |= (1 << i);
} else {
Delay_us(ZERO_PULSE_MIN);
}
}
data_arr[j] = data;
}
// 输出结果
printf("Received HEX: ");
for (int i = 0; i < num_blocks; i++) {
printf("%08X", data_arr[i]);
}
printf("\n");
}
\ No newline at end of file
#ifndef INFRARED_GUN_H
#define INFRARED_GUN_H
#define IR_PIN_rec 6 // 使用WiringPi,红外接收
#define IR_PIN 25 // 使用WiringPi,红外发射
// NEC协议的基础参数,红外发射
#define START_PULSE_HIGH 9000 // 起始码高电平持续时间(9ms)
#define START_PULSE_LOW 4500 // 起始码低电平持续时间(4.5ms)
#define ONE_PULSE_HIGH 560 // 逻辑1的高电平时间(0.56ms)
#define ONE_PULSE_LOW 1690 // 逻辑1的低电平时间(1.69ms)
#define ZERO_PULSE_HIGH 560 // 逻辑0的高电平时间(0.56ms)
#define ZERO_PULSE_LOW 560 // 逻辑0的低电平时间(0.56ms)
#define STOP_PULSE 500000 // 停止码的低电平时间(500ms)
// NEC协议的基础参数,红外接收
#define START_PULSE_MIN 8500 // 起始码高电平时间最小值(8.5ms)
#define START_PULSE_MAX 9500 // 起始码高电平时间最大值(9.5ms)
#define ONE_PULSE_MIN 1500 // 逻辑1的高电平时间最小值(1.5ms)
#define ONE_PULSE_MAX 1700 // 逻辑1的高电平时间最大值(1.7ms)
#define ZERO_PULSE_MIN 500 // 逻辑0的高电平时间最小值(0.5ms)
#define ZERO_PULSE_MAX 700 // 逻辑0的高电平时间最大值(0.7ms)
int infrared_Init();
void sendNEC(uint32_t data);
void receiveNEC();
#endif
\ No newline at end of file
#include "common.h"
#include "warm.h"
#include "http_request.h"
#include "mylog.h"
//最高警报,最低电压报警
int alarm_highest(int index) {
if(index == 1) {
pin_value(20,1);//紫灯
if(g_enable_buzzer_value) {
pin_value(22,1);//蜂鸣器
}
}else if(index == 0) {
pin_value(20,0);//紫灯
pin_value(22,0);//蜂鸣器
}
return index ;
}
//比较小警报
int alarm_low(int index) {
if(index == 1) {
pin_value(16,1);//黄灯
} else if(index == 0) {
pin_value(16,0);//黄灯
}
return index ;
}
int alarm_control_open(float voltage) {//关闭警报
if( voltage >= g_warn_voltage_value ) {
alarm_highest(0);
alarm_low(0);
}else if(voltage >= g_err_voltage_value&&voltage <= g_warn_voltage_value) {
alarm_low(1);
alarm_highest(0);
my_zlog_warn("电压警告");
}else if(voltage < g_err_voltage_value) {
alarm_highest(1);
alarm_low(1);
my_zlog_warn("换电警告");
}
return 0;
}
int alarm_control_close(float voltage) {//关闭警报
my_zlog_debug("未开启警报,读取电压:%.2f",voltage);
return 0;
}
int alarm_control(float voltage) {
#if WARM_MODE == 1
my_zlog_info("Mode 1: 执行代码A");
return alarm_control_open(voltage);
#elif WARM_MODE == 2
my_zlog_info("Mode 2: 执行代码B");
return alarm_control_close(voltage);
#else
my_zlog_error("未知的 WARM_MODE: %d", WARM_MODE);
return -1;
#endif
}
\ No newline at end of file
#ifndef WARM_H__
#define WARM_H__
/*当mode为1时候打开警报,为2时候关闭警告*/
#define WARM_MODE 1
int alarm_control(float voltage);
#endif
\ No newline at end of file
#include "common.h"
#include "browser_open.h"
#include "device_fileopen.h"
char gwebcam[254];//存放启动火狐网站命令
int opencamsh_china(){
const char* url = "https://jywy.yd-ss.com?dev=";
char urls[50];
topic_middle_value();
sprintf(urls,"%s%s",url,mqtt_topic_pure_number());
//setenv("DISPLAY", ":0", 1);//设置环境变量https://jywy.yd-ss.com?dev=controcar0004 --new-window sudo
sprintf(gwebcam,"su - orangepi -c \"chromium-browser --use-fake-ui-for-media-stream %s\"",urls);
system(gwebcam);
my_zlog_debug("%s",gwebcam);
my_zlog_debug("open cam");
return 0;
}
int opencamsh_abroad(){
const char* url = "https://video.luckycar.top/?dev=";
char urls[50];
topic_middle_value();
sprintf(urls,"%s%s",url,mqtt_topic_pure_number());
//setenv("DISPLAY", ":0", 1);//设置环境变量https://jywy.yd-ss.com?dev=controcar0004 --new-window sudo
sprintf(gwebcam,"su - orangepi -c \"chromium-browser --use-fake-ui-for-media-stream %s\"",urls);
system(gwebcam);
my_zlog_debug("%s",gwebcam);
my_zlog_debug("open cam");
return 0;
}
int opencamsh() {
#if BROWSER_MODE == 1
// 当MODE为1时的代码
my_zlog_info("Mode 1: 执行代码A");
return opencamsh_china();
#elif BROWSER_MODE == 2
// 当MODE为2时的代码
my_zlog_info("Mode 2: 执行代码B");
return opencamsh_abroad();
#else
my_zlog_error("未知的 WARM_MODE: %d", BROWSER_MODE);
return -1;
#endif
}
void refresh_cam() {//刷新页面
setenv("XAUTHORITY", "/home/orangepi/.Xauthority", 1);//加入授权
const char *search_command = "xdotool search --class \"chromium-browser\"";//获取窗口id
FILE *fp = popen(search_command, "r");
if (!fp) {
perror("Failed to execute search command");
return;
}
char window_id[32];
while (fgets(window_id, sizeof(window_id), fp) != NULL) {
window_id[strcspn(window_id, "\n")] = '\0';
char activate_command[128];
snprintf(activate_command, sizeof(activate_command), "xdotool windowactivate --sync %s key Ctrl+r", window_id);
pid_t pid = fork();
if (pid == 0) {
// 子进程执行命令
execl("/bin/sh", "sh", "-c", activate_command, (char *)NULL);
perror("Failed to execute command");
exit(EXIT_FAILURE);
} else if (pid > 0) {
// 父进程不等待子进程结束,继续执行
printf("Executing in child process: %s\n", activate_command);
} else {
perror("Failed to fork");
}
}
pclose(fp);
//printf("recam\n");
my_zlog_debug("刷新成功");
}
#ifndef BROWSER_OPEN_H__
#define BROWSER_OPEN_H__
/*打开摄像头函数,当MODE为1时候为国内网址,2时为国外网址*/
#define BROWSER_MODE 1
int opencamsh();
void refresh_cam();//刷新摄像头函数
#endif
\ No newline at end of file
#include<curl/curl.h>
#include <cjson/cJSON.h>
#include "cjson/cJSON.h"
#include "http_request.h"
#include "device_identity.h"
......@@ -8,8 +8,8 @@ const char *c_post = "http://47.119.190.60/api/v1/device/config";
int g_errCodeValue;
bool g_enable_buzzer_value=0;
double g_warn_voltage_value;
double g_err_voltage_value;
double g_warn_voltage_value=10.7;
double g_err_voltage_value=9.7;
double g_shot_speed_value=0.7;
// 回调函数,用于处理接收到的数据
......
......@@ -7,11 +7,16 @@
#include "temperature.h"
#include "common.h"
#include "mylog.h"
#include "device_fileopen.h"
bool g_verified_mode = TRUE;//控制是否需要验证
int g_heartbeat_count=0;
int g_devcontrol_exit_count=0;
int g_message_type=0;
unsigned char g_valt[4];//存放mqtt接收的tpye,mode等
//心跳发送格式*5/2
......@@ -30,7 +35,7 @@ void heartbeat_send() {
char current_str[20]; // 足够存储转换后的字符串的缓冲区
sprintf(current_str, "%.2f", current);
//alarm_control(voltage);//判断电压警报,在不动时候才判断
if(g_devcontrol_exit_count>5) alarm_control(voltage);//判断电压警报,在不动时候才判断
/*读取程序版本号*/
char *version_num = program_version();
......@@ -242,9 +247,9 @@ int device_message_receive(cJSON *json){//接收到的控制设备的mqtt消息
return 1;
}
gmessage_type=message_type->valueint;
g_message_type=message_type->valueint;
my_zlog_debug("message_type: %d",message_type->valueint);
switch(gmessage_type){
switch(g_message_type){
case 2:
//message_2_judyverify(body);
my_zlog_debug("进入刷新");
......@@ -282,7 +287,7 @@ int device_message_receive(cJSON *json){//接收到的控制设备的mqtt消息
my_zlog_debug("重启成功");
break;
case 2012:
//refresh_cam();
refresh_cam();
my_zlog_debug("刷新成功");
break;
default:
......
#ifndef MQTT_INFOR_HANDLE_H__
#define MQTT_INFOR_HANDLE_H__
#include <cjson/cJSON.h>
#include "cjson/cJSON.h"
extern int g_heartbeat_count;
extern int g_devcontrol_exit_count;
void mqtt_wirte();
int device_message_receive(cJSON *json);
......
......@@ -7,8 +7,6 @@
struct mosquitto *mosq;
int gPwmCount = 0; // 计数
int gmessage_type=10086;
uint16_t AppExit_pin_pwm=0;//判断坦克或者车的退出
......
#ifndef MQTT_INIT_H__
#define MQTT_INIT_H__
#include <time.h>
#include <mosquitto.h>
#include <cjson/cJSON.h>
extern int heartbeat_count;//心跳计时
#include "mosquitto.h"
#include "cjson/cJSON.h"
//extern ThreadPool *pool;
#define BROKER_ADDRESS "119.45.167.177"
#define BROKER_PORT 1883
#define USERNAME "admin" // 替换为你的用户名
......
#include <time.h>
#include <cjson/cJSON.h>
#include "cjson/cJSON.h"
#include "mqtt_verify.h"
#include "common.h"
#include <openssl/evp.h>
......
#ifndef MQTT_VERIFY_H__
#define MQTT_VERIFY_H__
#include <cjson/cJSON.h>
#include "cjson/cJSON.h"
#define AES_BLOCK_SIZE 16
......
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