家庭IC卡燃气表管理系统(附收费报警LCD显示功能)

家庭IC卡燃气表管理系统(附收费报警LCD显示功能)

家庭IC卡燃气表管理系统的C语言实现,包含IC卡读写、燃气计量、收费管理、报警功能和LCD显示等核心功能。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <unistd.h>

// 系统配置
#define MAX_USERS 100
#define GAS_PRICE_PER_CUBIC_METER 2.5  // 燃气价格 (元/立方米)
#define ALARM_THRESHOLD 5.0            // 报警阈值 (立方米)
#define SHUTOFF_THRESHOLD 1.0          // 关阀阈值 (立方米)
#define LCD_WIDTH 16                   // LCD显示宽度
#define LCD_HEIGHT 2                   // LCD显示高度

// 用户数据结构
typedef struct {
    char card_id[20];          // IC卡号
    char name[50];             // 用户名
    double balance;            // 账户余额 (元)
    double gas_used;           // 累计用气量 (立方米)
    double gas_remaining;      // 剩余气量 (立方米)
    time_t last_refill;        // 上次充值时间
    int valve_status;          // 阀门状态 (0:关闭, 1:开启)
} User;

// 系统状态
typedef struct {
    User users[MAX_USERS];     // 用户数组
    int user_count;            // 用户数量
    double current_gas_flow;   // 当前燃气流量 (立方米/小时)
    time_t current_time;       // 当前时间
    int alarm_status;          // 报警状态 (0:正常, 1:报警)
} GasSystem;

// LCD显示缓冲区
char lcd_buffer[LCD_HEIGHT][LCD_WIDTH + 1];

// 函数声明
void init_system(GasSystem *system);
int find_user(GasSystem *system, const char *card_id);
void insert_card(GasSystem *system, const char *card_id);
void refill_gas(GasSystem *system, const char *card_id, double amount);
void simulate_gas_usage(GasSystem *system, double hours);
void update_display(GasSystem *system, const char *card_id);
void check_alarm(GasSystem *system, const char *card_id);
void control_valve(GasSystem *system, const char *card_id, int status);
void display_lcd(int line, const char *message);
void clear_lcd();
void beep(int duration_ms);

// 初始化系统
void init_system(GasSystem *system) {
    system->user_count = 0;
    system->current_gas_flow = 0.0;
    system->current_time = time(NULL);
    system->alarm_status = 0;
    
    // 初始化LCD
    clear_lcd();
    display_lcd(0, "Gas System Ready");
    display_lcd(1, "Insert Card...");
    
    printf("系统初始化完成\n");
}

// 查找用户
int find_user(GasSystem *system, const char *card_id) {
    for (int i = 0; i < system->user_count; i++) {
        if (strcmp(system->users[i].card_id, card_id) == 0) {
            return i;
        }
    }
    return -1;
}

// 插入IC卡
void insert_card(GasSystem *system, const char *card_id) {
    int user_index = find_user(system, card_id);
    
    if (user_index == -1) {
        // 新用户
        if (system->user_count < MAX_USERS) {
            User new_user;
            strcpy(new_user.card_id, card_id);
            printf("请输入用户名: ");
            scanf("%s", new_user.name);
            new_user.balance = 0.0;
            new_user.gas_used = 0.0;
            new_user.gas_remaining = 0.0;
            new_user.last_refill = system->current_time;
            new_user.valve_status = 0; // 初始状态为关闭
            
            system->users[system->user_count] = new_user;
            system->user_count++;
            
            display_lcd(0, "New User Added");
            snprintf(lcd_buffer[1], LCD_WIDTH + 1, "%s", new_user.name);
            display_lcd(1, lcd_buffer[1]);
            
            printf("新用户添加成功: %s\n", new_user.name);
        } else {
            display_lcd(0, "Error: Max Users");
            display_lcd(1, "System Full");
            printf("错误: 系统用户数已达上限\n");
        }
    } else {
        // 老用户
        User *user = &system->users[user_index];
        
        if (user->valve_status == 0) {
            // 如果阀门关闭,检查是否有余量
            if (user->gas_remaining > SHUTOFF_THRESHOLD) {
                user->valve_status = 1; // 开启阀门
                display_lcd(0, "Valve Opened");
            } else {
                display_lcd(0, "No Gas! Refill");
                display_lcd(1, "Or Shutoff");
            }
        }
        
        update_display(system, card_id);
        printf("用户卡片已识别: %s (余额: ¥%.2f, 剩余气量: %.2f m³)\n", 
               user->name, user->balance, user->gas_remaining);
    }
}

// 充值燃气
void refill_gas(GasSystem *system, const char *card_id, double amount) {
    int user_index = find_user(system, card_id);
    
    if (user_index == -1) {
        display_lcd(0, "Error: User Not");
        display_lcd(1, "Found");
        printf("错误: 未找到用户\n");
        return;
    }
    
    User *user = &system->users[user_index];
    double gas_amount = amount / GAS_PRICE_PER_CUBIC_METER;
    
    user->balance += amount;
    user->gas_remaining += gas_amount;
    user->last_refill = system->current_time;
    
    // 如果阀门关闭且有余量,开启阀门
    if (user->valve_status == 0 && user->gas_remaining > SHUTOFF_THRESHOLD) {
        user->valve_status = 1;
    }
    
    char msg[LCD_WIDTH + 1];
    snprintf(msg, sizeof(msg), "Refilled:%.1fm3", gas_amount);
    display_lcd(0, msg);
    
    snprintf(msg, sizeof(msg), "Bal:¥%.1f Rem:%.1f", user->balance, user->gas_remaining);
    display_lcd(1, msg);
    
    printf("充值成功: ¥%.2f (%.2f m³), 新余额: ¥%.2f, 剩余气量: %.2f m³\n", 
           amount, gas_amount, user->balance, user->gas_remaining);
    
    update_display(system, card_id);
}

// 模拟燃气使用
void simulate_gas_usage(GasSystem *system, double hours) {
    for (int i = 0; i < system->user_count; i++) {
        User *user = &system->users[i];
        
        if (user->valve_status == 1) { // 阀门开启
            // 模拟燃气使用 (0.1-0.5 m³/小时)
            double hourly_usage = 0.1 + (double)rand() / RAND_MAX * 0.4;
            double usage = hourly_usage * hours;
            
            if (user->gas_remaining >= usage) {
                user->gas_remaining -= usage;
                user->gas_used += usage;
            } else {
                // 气量不足
                usage = user->gas_remaining;
                user->gas_remaining = 0;
                user->gas_used += usage;
                
                // 关闭阀门
                user->valve_status = 0;
            }
            
            // 更新余额
            user->balance -= usage * GAS_PRICE_PER_CUBIC_METER;
            if (user->balance < 0) user->balance = 0;
            
            // 检查报警
            check_alarm(system, user->card_id);
        }
    }
    
    system->current_time += (time_t)(hours * 3600);
}

// 更新显示
void update_display(GasSystem *system, const char *card_id) {
    int user_index = find_user(system, card_id);
    if (user_index == -1) return;
    
    User *user = &system->users[user_index];
    
    // 第一行: 用户名和阀门状态
    char line1[LCD_WIDTH + 1];
    snprintf(line1, sizeof(line1), "%s:%s", 
             user->name, 
             user->valve_status ? "ON " : "OFF");
    
    // 第二行: 剩余气量和余额
    char line2[LCD_WIDTH + 1];
    snprintf(line2, sizeof(line2), "G:%.1fm3 B:¥%.1f", 
             user->gas_remaining, 
             user->balance);
    
    display_lcd(0, line1);
    display_lcd(1, line2);
}

// 检查报警
void check_alarm(GasSystem *system, const char *card_id) {
    int user_index = find_user(system, card_id);
    if (user_index == -1) return;
    
    User *user = &system->users[user_index];
    
    if (user->gas_remaining <= ALARM_THRESHOLD && user->gas_remaining > SHUTOFF_THRESHOLD) {
        // 低气量报警
        if (!system->alarm_status) {
            system->alarm_status = 1;
            display_lcd(0, "LOW GAS WARNING");
            char msg[LCD_WIDTH + 1];
            snprintf(msg, sizeof(msg), "Rem:%.1fm3", user->gas_remaining);
            display_lcd(1, msg);
            beep(500); // 蜂鸣0.5秒
            printf("报警: 低气量警告! 用户: %s, 剩余气量: %.2f m³\n", 
                   user->name, user->gas_remaining);
        }
    } else if (user->gas_remaining <= SHUTOFF_THRESHOLD) {
        // 气量耗尽,关闭阀门
        if (user->valve_status == 1) {
            user->valve_status = 0;
            display_lcd(0, "GAS SHUTOFF!");
            char msg[LCD_WIDTH + 1];
            snprintf(msg, sizeof(msg), "Rem:%.1fm3", user->gas_remaining);
            display_lcd(1, msg);
            beep(1000); // 蜂鸣1秒
            printf("关阀: 气量耗尽! 用户: %s, 剩余气量: %.2f m³\n", 
                   user->name, user->gas_remaining);
        }
    } else {
        system->alarm_status = 0;
    }
}

// 控制阀门
void control_valve(GasSystem *system, const char *card_id, int status) {
    int user_index = find_user(system, card_id);
    if (user_index == -1) return;
    
    User *user = &system->users[user_index];
    user->valve_status = status;
    
    if (status) {
        display_lcd(0, "Valve Opened");
        printf("阀门已开启: %s\n", user->name);
    } else {
        display_lcd(0, "Valve Closed");
        printf("阀门已关闭: %s\n", user->name);
    }
    
    update_display(system, card_id);
}

// LCD显示函数 (模拟)
void display_lcd(int line, const char *message) {
    if (line < 0 || line >= LCD_HEIGHT) return;
    
    strncpy(lcd_buffer[line], message, LCD_WIDTH);
    lcd_buffer[line][LCD_WIDTH] = '\0'; // 确保字符串结束
    
    // 在实际应用中,这里会发送指令到LCD硬件
    printf("[LCD Line %d] %s\n", line + 1, lcd_buffer[line]);
}

// 清空LCD
void clear_lcd() {
    memset(lcd_buffer, ' ', sizeof(lcd_buffer));
    for (int i = 0; i < LCD_HEIGHT; i++) {
        lcd_buffer[i][LCD_WIDTH] = '\0';
    }
    printf("LCD Cleared\n");
}

// 蜂鸣器控制 (模拟)
void beep(int duration_ms) {
    printf("[BEEP] Beeping for %d ms\n", duration_ms);
    usleep(duration_ms * 1000); // 模拟蜂鸣时间
}

// 打印用户信息
void print_user_info(GasSystem *system, const char *card_id) {
    int user_index = find_user(system, card_id);
    if (user_index == -1) {
        printf("用户不存在\n");
        return;
    }
    
    User *user = &system->users[user_index];
    printf("\n=== 用户信息 ===\n");
    printf("卡号: %s\n", user->card_id);
    printf("姓名: %s\n", user->name);
    printf("余额: ¥%.2f\n", user->balance);
    printf("累计用气量: %.2f m³\n", user->gas_used);
    printf("剩余气量: %.2f m³\n", user->gas_remaining);
    printf("阀门状态: %s\n", user->valve_status ? "开启" : "关闭");
    printf("上次充值时间: %s", ctime(&user->last_refill));
}

// 主菜单
void show_menu() {
    printf("\n===== 家庭IC卡燃气表管理系统 =====\n");
    printf("1. 插入IC卡\n");
    printf("2. 充值燃气\n");
    printf("3. 模拟燃气使用\n");
    printf("4. 开启阀门\n");
    printf("5. 关闭阀门\n");
    printf("6. 查看用户信息\n");
    printf("7. 显示LCD内容\n");
    printf("8. 退出系统\n");
    printf("请选择操作: ");
}

int main() {
    GasSystem system;
    init_system(&system);
    
    // 添加测试用户
    User test_user;
    strcpy(test_user.card_id, "1234567890");
    strcpy(test_user.name, "张三");
    test_user.balance = 100.0;
    test_user.gas_used = 0.0;
    test_user.gas_remaining = 20.0;
    test_user.last_refill = time(NULL);
    test_user.valve_status = 1;
    system.users[0] = test_user;
    system.user_count = 1;
    
    int running = 1;
    char card_id[20];
    double amount, hours;
    
    while (running) {
        show_menu();
        int choice;
        scanf("%d", &choice);
        
        switch (choice) {
            case 1: // 插入IC卡
                printf("请输入IC卡号: ");
                scanf("%s", card_id);
                insert_card(&system, card_id);
                break;
                
            case 2: // 充值燃气
                printf("请输入IC卡号: ");
                scanf("%s", card_id);
                printf("请输入充值金额(元): ");
                scanf("%lf", &amount);
                refill_gas(&system, card_id, amount);
                break;
                
            case 3: // 模拟燃气使用
                printf("请输入模拟时间(小时): ");
                scanf("%lf", &hours);
                simulate_gas_usage(&system, hours);
                break;
                
            case 4: // 开启阀门
                printf("请输入IC卡号: ");
                scanf("%s", card_id);
                control_valve(&system, card_id, 1);
                break;
                
            case 5: // 关闭阀门
                printf("请输入IC卡号: ");
                scanf("%s", card_id);
                control_valve(&system, card_id, 0);
                break;
                
            case 6: // 查看用户信息
                printf("请输入IC卡号: ");
                scanf("%s", card_id);
                print_user_info(&system, card_id);
                break;
                
            case 7: // 显示LCD内容
                printf("LCD内容:\n");
                for (int i = 0; i < LCD_HEIGHT; i++) {
                    printf("行 %d: %s\n", i + 1, lcd_buffer[i]);
                }
                break;
                
            case 8: // 退出系统
                running = 0;
                printf("系统已退出\n");
                break;
                
            default:
                printf("无效选择,请重新输入\n");
        }
    }
    
    return 0;
}

系统功能说明

1. 核心功能模块

2. 关键功能实现

3. 安全机制

系统工作流程

  1. 初始化系统:加载用户数据,初始化LCD显示

  2. 用户插卡:系统识别IC卡,加载用户数据

  3. 余额检查:检查用户账户余额和剩余气量

  4. 阀门控制

    • 如果阀门关闭且有余量,自动开启
    • 如果气量不足,保持关闭
  5. 燃气使用

    • 系统定期计算燃气使用量
    • 更新剩余气量和账户余额
  6. 报警检测

    • 当剩余气量低于报警阈值时,触发LCD报警和蜂鸣
    • 当剩余气量低于关阀阈值时,关闭阀门并报警
  7. 充值操作:用户通过IC卡充值,增加账户余额和剩余气量

  8. 数据更新:所有操作更新系统状态和数据存储

系统特点

  1. 用户友好界面

    • LCD显示清晰的状态信息
    • 声音报警提示重要事件
    • 中文菜单和提示信息
  2. 安全可靠

    • 多重安全机制防止燃气泄漏
    • 自动关阀保护
    • 详细的用户账户管理
  3. 灵活配置

    • 可配置的燃气价格
    • 可调整的报警和关阀阈值
    • 支持多用户管理
  4. 实时监控

    • 实时显示剩余气量和账户余额
    • 实时显示阀门状态
    • 实时报警提示

实际应用扩展建议

  1. 硬件集成

    • 连接真实的IC卡读卡器
    • 集成LCD显示屏(如1602或12864)
    • 连接燃气流量计和电动阀门
    • 添加蜂鸣器和LED指示灯
  2. 数据安全

    • 使用加密存储用户数据
    • 实现数据备份和恢复功能
    • 添加防拆机保护机制
  3. 网络通信

    • 添加GPRS/4G模块实现远程抄表
    • 实现手机APP查询和充值功能
    • 连接燃气公司服务器进行数据同步
  4. 高级功能

    • 阶梯气价支持
    • 每日用气量统计和分析
    • 异常用气检测(如漏气检测)
    • 多语言支持

参考代码 家庭IC卡燃气表管理系统,附收费报警LCD显示功能 www.youwenfan.com/contentcss/160730.html

编译运行说明

  1. 将代码保存为 gas_meter.c

  2. 使用C编译器编译:

    gcc gas_meter.c -o gas_meter
    
  3. 运行程序:

    ./gas_meter
    
  4. 按照菜单提示进行操作

总结

本系统实现了一个完整的家庭IC卡燃气表管理系统,包含IC卡管理、燃气计量、收费管理、阀门控制和报警功能。系统通过LCD显示实时状态,在燃气不足时提供声光报警,并能自动关闭阀门确保安全。

专注于matlab/simulink,电子电路,编程