【基于ESP32-C2和ESP-IDF框架的工业温度振动传感器详细实现方案,包含波形录播、滤波算法和MQTT上传功能】

以下是一个基于ESP32-C2和ESP-IDF框架的工业温度振动传感器详细实现方案,包含波形录播、滤波算法和MQTT上传功能。

硬件准备

  • ESP32-C2开发板
  • 工业振动传感器(如ADXL345或IIS3DWB)
  • 温度传感器(如DS18B20或MAX31865)
  • 电源模块(建议3.3V稳压)

软件架构

  • 使用FreeRTOS任务管理
  • 双缓冲机制实现波形录播
  • 数字滤波处理振动数据
  • MQTT协议上传到云平台

传感器初始化(以IIS3DWB为例)

#include "iis3dwb_reg.h"

static iis3dwb_ctx_t dev_ctx;
static float acceleration_mg[3];

void iis3dwb_init(void) {
    dev_ctx.write_reg = i2c_write;
    dev_ctx.read_reg = i2c_read;
    dev_ctx.handle = &i2c_handle;
    
    // Check device ID
    uint8_t whoami;
    iis3dwb_device_id_get(&dev_ctx, &whoami);
    if(whoami != IIS3DWB_ID) {
        ESP_LOGE(TAG, "IIS3DWB not found");
        return;
    }
    
    // Configure sensor
    iis3dwb_block_data_update_set(&dev_ctx, PROPERTY_ENABLE);
    iis3dwb_xl_data_rate_set(&dev_ctx, IIS3DWB_XL_ODR_26k7Hz);
    iis3dwb_xl_full_scale_set(&dev_ctx, IIS3DWB_16g);
}

振动数据采集与滤波

#define SAMPLE_RATE 1000 // Hz
#define WINDOW_SIZE 128

// 移动平均滤波器
typedef struct {
    float buffer[WINDOW_SIZE];
    uint16_t index;
    float sum;
} MovingAverageFilter;

void init_filter(MovingAverageFilter* filter) {
    memset(filter->buffer, 0, sizeof(filter->buffer));
    filter->index = 0;
    filter->sum = 0.0f;
}

float update_filter(MovingAverageFilter* filter, float new_sample) {
    filter->sum -= filter->buffer[filter->index];
    filter->buffer[filter->index] = new_sample;
    filter->sum += new_sample;
    filter->index = (filter->index + 1) % WINDOW_SIZE;
    return filter->sum / WINDOW_SIZE;
}

// IIR低通滤波器
float iir_lowpass_filter(float input, float* prev_output, float alpha) {
    float output = alpha * input + (1 - alpha) * (*prev_output);
    *prev_output = output;
    return output;
}

波形录播功能实现

#define BUFFER_SIZE 2048

typedef struct {
    float x[BUFFER_SIZE];
    float y[BUFFER_SIZE];
    float z[BUFFER_SIZE];
    uint32_t timestamp[BUFFER_SIZE];
    uint16_t write_idx;
    bool ready_for_upload;
} WaveformBuffer;

WaveformBuffer buffer_a, buffer_b;
WaveformBuffer* active_buffer = &buffer_a;

void record_waveform_task(void* pvParameters) {
    MovingAverageFilter filter_x, filter_y, filter_z;
    init_filter(&filter_x);
    init_filter(&filter_y);
    init_filter(&filter_z);
    
    float iir_prev_x = 0, iir_prev_y = 0, iir_prev_z = 0;
    const float iir_alpha = 0.1f; // 截止频率约为采样率的1/10
    
    while(1) {
        // 读取原始数据
        int16_t raw_acc[3];
        iis3dwb_acceleration_raw_get(&dev_ctx, raw_acc);
        
        // 转换为g值并应用滤波
        float x = update_filter(&filter_x, raw_acc[0] * 0.049f); // 0.049 mg/LSB @ 16g
        float y = update_filter(&filter_y, raw_acc[1] * 0.049f);
        float z = update_filter(&filter_z, raw_acc[2] * 0.049f);
        
        x = iir_lowpass_filter(x, &iir_prev_x, iir_alpha);
        y = iir_lowpass_filter(y, &iir_prev_y, iir_alpha);
        z = iir_lowpass_filter(z, &iir_prev_z, iir_alpha);
        
        // 存储到缓冲区
        active_buffer->x[active_buffer->write_idx] = x;
        active_buffer->y[active_buffer->write_idx] = y;
        active_buffer->z[active_buffer->write_idx] = z;
        active_buffer->timestamp[active_buffer->write_idx] = xTaskGetTickCount() * portTICK_PERIOD_MS;
        
        if(++active_buffer->write_idx >= BUFFER_SIZE) {
            active_buffer->ready_for_upload = true;
            active_buffer = (active_buffer == &buffer_a) ? &buffer_b : &buffer_a;
            active_buffer->write_idx = 0;
        }
        
        vTaskDelay(pdMS_TO_TICKS(1000/SAMPLE_RATE));
    }
}

MQTT上传实现

#include "mqtt_client.h"

esp_mqtt_client_handle_t mqtt_client;

void mqtt_event_handler(void* handler_args, esp_event_base_t base, int32_t event_id, void* event_data) {
    esp_mqtt_event_handle_t event = event_data;
    
    switch(event->event_id) {
        case MQTT_EVENT_CONNECTED:
            ESP_LOGI(TAG, "MQTT connected");
            break;
        case MQTT_EVENT_DISCONNECTED:
            ESP_LOGI(TAG, "MQTT disconnected");
            break;
        case MQTT_EVENT_DATA:
            // 处理接收到的消息
            break;
    }
}

void init_mqtt() {
    esp_mqtt_client_config_t mqtt_cfg = {
        .uri = "mqtt://your.cloud.server:1883",
        .username = "device_user",
        .password = "device_password",
    };
    
    mqtt_client = esp_mqtt_client_init(&mqtt_cfg);
    esp_mqtt_client_register_event(mqtt_client, ESP_EVENT_ANY_ID, mqtt_event_handler, NULL);
    esp_mqtt_client_start(mqtt_client);
}

void upload_waveform_data(WaveformBuffer* buffer) {
    char topic[50];
    snprintf(topic, sizeof(topic), "device/%s/waveform", "your_device_id");
    
    cJSON* root = cJSON_CreateObject();
    cJSON* x_array = cJSON_CreateFloatArray(buffer->x, BUFFER_SIZE);
    cJSON* y_array = cJSON_CreateFloatArray(buffer->y, BUFFER_SIZE);
    cJSON* z_array = cJSON_CreateFloatArray(buffer->z, BUFFER_SIZE);
    cJSON* time_array = cJSON_CreateIntArray(buffer->timestamp, BUFFER_SIZE);
    
    cJSON_AddItemToObject(root, "x", x_array);
    cJSON_AddItemToObject(root, "y", y_array);
    cJSON_AddItemToObject(root, "z", z_array);
    cJSON_AddItemToObject(root, "timestamp", time_array);
    
    char* json_str = cJSON_PrintUnformatted(root);
    esp_mqtt_client_publish(mqtt_client, topic, json_str, 0, 1, 0);
    
    cJSON_Delete(root);
    free(json_str);
}

主任务调度

void app_main() {
    // 初始化硬件和外设
    i2c_init();
    iis3dwb_init();
    temperature_sensor_init();
    init_mqtt();
    
    // 创建任务
    xTaskCreate(record_waveform_task, "waveform_task", 4096, NULL, 5, NULL);
    xTaskCreate(temperature_task, "temp_task", 2048, NULL, 3, NULL);
    xTaskCreate(upload_task, "upload_task", 4096, NULL, 4, NULL);
}

void upload_task(void* pvParameters) {
    while(1) {
        if(buffer_a.ready_for_upload) {
            upload_waveform_data(&buffer_a);
            buffer_a.ready_for_upload = false;
        }
        if(buffer_b.ready_for_upload) {
            upload_waveform_data(&buffer_b);
            buffer_b.ready_for_upload = false;
        }
        vTaskDelay(pdMS_TO_TICKS(1000));
    }
}

数据库设计建议

云服务数据库建议采用时间序列数据库结构:

CREATE TABLE vibration_data (
    device_id VARCHAR(32),
    timestamp BIGINT,
    x_value FLOAT,
    y_value FLOAT,
    z_value FLOAT,
    temperature FLOAT,
    rms_value FLOAT,
    PRIMARY KEY (device_id, timestamp)
);

CREATE TABLE waveform_records (
    record_id UUID PRIMARY KEY,
    device_id VARCHAR(32),
    start_time BIGINT,
    end_time BIGINT,
    sample_rate INT,
    data_url TEXT
);

高级滤波算法实现

对于更复杂的振动分析,可添加频域处理:

#include "dsps_fft2r.h"

void fft_analysis(float* time_domain, float* freq_domain, size_t len) {
    float* fft_input = malloc(len * sizeof(float));
    float* fft_output = malloc(len * sizeof(float));
    
    // 复制数据并加窗
    for(int i=0; i<len; i++) {
        fft_input[i] = time_domain[i] * (0.54 - 0.46 * cos(2*M_PI*i/(len-1))); // Hamming窗
    }
    
    // 执行FFT
    dsps_fft2r_init_fc32(NULL, len);
    dsps_fft2r_fc32(fft_input, len);
    dsps_bit_rev_fc32(fft_input, len);
    dsps_cplx2real_fc32(fft_input, len, fft_output);
    
    // 计算幅值
    for(int i=0; i<len/2; i++) {
        freq_domain[i] = sqrtf(fft_output[2*i]*fft_output[2*i] + 
                              fft_output[2*i+1]*fft_output[2*i+1]);
    }
    
    free(fft_input);
    free(fft_output);
}

注意事项

  1. 实际应用中需要添加错误处理和重连机制
  2. 振动传感器采样率应根据实际需求调整
  3. 滤波参数需要根据信号特性优化
  4. MQTT传输应考虑数据压缩以减少带宽
  5. 对于长期运行,需要实现数据本地存储功能

完整项目应包含以下组件:

  • 传感器驱动层
  • 数据处理层(滤波/FFT)
  • 数据缓冲层
  • 通信协议层
  • 云端对接层

可根据具体硬件型号调整传感器初始化参数,并优化滤波算法以满足不同工业场景的需求。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值