基于STM32、FreeRTOS和Spring Boot的智能仓储管理系统:RFID、BLE和Three.js全栈解决方案(附代码示例)

1. 项目概述

随着电子商务和物流行业的快速发展,高效精准的仓储管理变得越来越重要。本文介绍了一个基于STM32微控制器和Spring Boot框架的智能仓储管理系统,该系统能够实时跟踪库存位置,优化仓储布局和拣货路径,显著提高仓储管理效率。

1.1 系统主要特点

  1. 实时定位:利用RFID和蓝牙低功耗(BLE)技术实现货物精确定位
  2. 自动化管理:通过嵌入式设备自动采集数据,减少人工操作
  3. 3D可视化:使用Three.js实现仓库布局和货物位置的直观展示
  4. 智能优化:基于实时数据优化仓储布局和拣货路径

1.2 技术栈

  • 嵌入式:STM32微控制器,FreeRTOS实时操作系统
  • 定位技术:RFID,蓝牙低功耗(BLE)
  • 后端:Java Spring Boot,MySQL数据库
  • 前端:Angular框架,Three.js 3D可视化库
  • 2. 系统设计

    2.1 硬件架构

    系统的硬件架构如下图所示:

  • STM32微控制器:作为系统的核心,连接并控制其他硬件模块
  • RFID读写器:读取货物上的RFID标签
  • BLE模块:扫描并接收BLE信标信号
  • WiFi模块:将采集到的数据传输到后端服务器
  • RFID标签和BLE信标:分别贴附在货物或货架上,用于定位
  • 2.2 软件架构

    系统的软件架构如下图所示:

     

  • 前端Angular应用:提供用户界面,展示仓库状态和管理功能
  • Spring Boot后端:处理业务逻辑,管理数据存储和检索
  • MySQL数据库:存储货物信息、位置数据和仓库布局
  • STM32嵌入式程序:采集RFID和BLE数据,通过MQTT协议发送到后端
  • 位置追踪模块:处理和分析位置数据
  • 库存管理模块:管理货物入库、出库和库存盘点
  • 路径优化模块:基于实时数据计算最优拣货路径
  • Three.js 3D可视化:在前端实现仓库和货物的三维可视化展示
  • 3. 代码实现

    3.1 STM32嵌入式程序

    STM32嵌入式程序使用FreeRTOS实时操作系统,主要包含RFID读取、BLE扫描和数据上传三个任务。

    #include "FreeRTOS.h"
    #include "task.h"
    #include "rfid.h"
    #include "ble.h"
    #include "wifi.h"
    #include "mqtt.h"
    
    // RFID读取任务
    void vRFIDTask(void *pvParameters)
    {
        RFIDData_t rfidData;
        for(;;)
        {
            if(RFID_Read(&rfidData) == SUCCESS)
            {
                // 处理RFID数据
                process_rfid_data(&rfidData);
                // 通过MQTT发送数据
                MQTT_Publish("rfid_topic", &rfidData, sizeof(RFIDData_t));
            }
            vTaskDelay(pdMS_TO_TICKS(100)); // 延时100ms
        }
    }
    
    // BLE扫描任务
    void vBLETask(void *pvParameters)
    {
        BLEData_t bleData;
        for(;;)
        {
            if(BLE_Scan(&bleData) == SUCCESS)
            {
                // 处理BLE数据
                process_ble_data(&bleData);
                // 通过MQTT发送数据
                MQTT_Publish("ble_topic", &bleData, sizeof(BLEData_t));
            }
            vTaskDelay(pdMS_TO_TICKS(200)); // 延时200ms
        }
    }
    
    // 数据上传任务
    void vUploadTask(void *pvParameters)
    {
        for(;;)
        {
            // 检查MQTT连接
            if(!MQTT_IsConnected())
            {
                MQTT_Connect();
            }
            // 处理MQTT消息
            MQTT_Process();
            vTaskDelay(pdMS_TO_TICKS(1000)); // 延时1s
        }
    }
    
    int main(void)
    {
        // 初始化外设
        RFID_Init();
        BLE_Init();
        WiFi_Init();
        MQTT_Init();
    
        // 创建任务
        xTaskCreate(vRFIDTask, "RFID Task", 1000, NULL, 1, NULL);
        xTaskCreate(vBLETask, "BLE Task", 1000, NULL, 1, NULL);
        xTaskCreate(vUploadTask, "Upload Task", 1000, NULL, 1, NULL);
        
        // 启动调度器
        vTaskStartScheduler();
        
        // 正常情况下不会到达这里
        for(;;);
    }
    

    这段代码创建了三个FreeRTOS任务:

    1. vRFIDTask:周期性读取RFID数据,处理后通过MQTT发送。
    2. vBLETask:周期性扫描BLE信标,处理后通过MQTT发送。
    3. vUploadTask:维护MQTT连接,确保数据能够正常上传到服务器。

    3.2 Spring Boot后端

    Spring Boot后端负责处理来自STM32的数据,并提供RESTful API供前端调用。以下是核心代码示例:

    @RestController
    @RequestMapping("/api/inventory")
    public class InventoryController {
    
        @Autowired
        private InventoryService inventoryService;
    
        @GetMapping("/{id}")
        public ResponseEntity<InventoryItem> getItem(@PathVariable Long id) {
            InventoryItem item = inventoryService.getItemById(id);
            if (item != null) {
                return ResponseEntity.ok(item);
            } else {
                return ResponseEntity.notFound().build();
            }
        }
    
        @PostMapping("/update")
        public ResponseEntity<Void> updateItemLocation(@RequestBody LocationUpdateRequest request) {
            boolean success = inventoryService.updateItemLocation(request.getItemId(), request.getNewLocation());
            if (success) {
                return ResponseEntity.ok().build();
            } else {
                return ResponseEntity.badRequest().build();
            }
        }
    
        @GetMapping("/optimize-path")
        public ResponseEntity<List<InventoryItem>> getOptimizedPickingPath(@RequestParam List<Long> itemIds) {
            List<InventoryItem> optimizedPath = inventoryService.calculateOptimizedPickingPath(itemIds);
            return ResponseEntity.ok(optimizedPath);
        }
    }
    
    @Service
    public class InventoryService {
    
        @Autowired
        private InventoryRepository inventoryRepository;
    
        @Autowired
        private LocationTrackingService locationTrackingService;
    
        public InventoryItem getItemById(Long id) {
            return inventoryRepository.findById(id).orElse(null);
        }
    
        public boolean updateItemLocation(Long itemId, Location newLocation) {
            InventoryItem item = inventoryRepository.findById(itemId).orElse(null);
            if (item != null) {
                item.setLocation(newLocation);
                inventoryRepository.save(item);
                return true;
            }
            return false;
        }
    
        public List<InventoryItem> calculateOptimizedPickingPath(List<Long> itemIds) {
            List<InventoryItem> items = inventoryRepository.findAllById(itemIds);
            // 实现路径优化算法,例如最近邻算法或遗传算法
            // 这里简化为按位置排序
            items.sort(Comparator.comparing(item -> item.getLocation().getDistance()));
            return items;
        }
    }
    
    @Component
    public class MqttHandler {
    
        @Autowired
        private LocationTrackingService locationTrackingService;
    
        @MqttSubscribe(topics = {"rfid_topic", "ble_topic"})
        public void handleLocationData(String topic, byte[] payload) {
            if ("rfid_topic".equals(topic)) {
                RFIDData rfidData = deserializeRFIDData(payload);
                locationTrackingService.updateRFIDLocation(rfidData);
            } else if ("ble_topic".equals(topic)) {
                BLEData bleData = deserializeBLEData(payload);
                locationTrackingService.updateBLELocation(bleData);
            }
        }
    
        // 反序列化方法省略
    }

    这段代码包含以下主要组件:

    1. InventoryController:提供RESTful API,包括获取单个物品信息、更新物品位置和获取优化拣货路径。

    2. InventoryService:实现业务逻辑,包括从数据库获取和更新物品信息,以及计算优化拣货路径。

    3. MqttHandler:处理来自STM32的MQTT消息,将RFID和BLE数据传递给位置追踪服务。

    主要功能说明:

    3.3 Angular前端

    Angular前端负责展示仓库状态和提供用户交互界面。以下是核心组件的示例代码:

  • getItem:根据ID获取物品信息。
  • updateItemLocation:更新物品位置。
  • getOptimizedPickingPath:计算优化的拣货路径。这里使用了一个简化的方法,实际应用中可能需要更复杂的算法。
  • handleLocationData:处理从MQTT接收到的RFID和BLE数据,更新物品位置信息。
  • @Component({
      selector: 'app-inventory-view',
      templateUrl: './inventory-view.component.html',
      styleUrls: ['./inventory-view.component.css']
    })
    export class InventoryViewComponent implements OnInit, AfterViewInit {
      inventoryItems: InventoryItem[] = [];
      scene: THREE.Scene;
      camera: THREE.PerspectiveCamera;
      renderer: THREE.WebGLRenderer;
    
      @ViewChild('rendererContainer') rendererContainer: ElementRef;
    
      constructor(private inventoryService: InventoryService) {}
    
      ngOnInit() {
        this.loadInventory();
      }
    
      ngAfterViewInit() {
        this.initThreeJS();
        this.animate();
      }
    
      loadInventory() {
        this.inventoryService.getAllItems().subscribe(
          (items) => {
            this.inventoryItems = items;
            this.updateVisualization();
          },
          (error) => {
            console.error('Error loading inventory:', error);
          }
        );
      }
    
      initThreeJS() {
        this.scene = new THREE.Scene();
        this.camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
        this.renderer = new THREE.WebGLRenderer();
        this.renderer.setSize(window.innerWidth, window.innerHeight);
        this.rendererContainer.nativeElement.appendChild(this.renderer.domElement);
    
        // 添加仓库基本结构
        this.addWarehouseStructure();
    
        this.camera.position.z = 5;
      }
    
      updateVisualization() {
        // 清除现有的物品可视化
        this.clearItemVisualizations();
    
        // 为每个物品添加3D表示
        this.inventoryItems.forEach(item => {
          const itemMesh = this.createItemMesh(item);
          this.scene.add(itemMesh);
        });
      }
    
      createItemMesh(item: InventoryItem): THREE.Mesh {
        const geometry = new THREE.BoxGeometry(0.2, 0.2, 0.2);
        const material = new THREE.MeshBasicMaterial({ color: 0x00ff00 });
        const mesh = new THREE.Mesh(geometry, material);
        mesh.position.set(item.location.x, item.location.y, item.location.z);
        return mesh;
      }
    
      animate() {
        requestAnimationFrame(() => this.animate());
        this.renderer.render(this.scene, this.camera);
      }
    
      // 其他辅助方法省略...
    }

    这个组件实现了以下功能:

    1. loadInventory:从服务器加载库存数据。
    2. initThreeJS:初始化Three.js场景、相机和渲染器。
    3. updateVisualization:根据库存数据更新3D可视化。
    4. createItemMesh:为每个物品创建3D网格表示。
    5. animate:实现3D场景的动画循环。

    4.4 结论

    本智能仓储管理系统通过整合STM32微控制器、RFID、BLE等硬件技术,以及Spring Boot、Angular等软件技术,实现了仓库库存的实时跟踪和可视化管理。系统不仅提高了仓储管理的效率和准确性,还为未来的智能化升级奠定了基础。

     

     

     

    作者:极客小张

    物联沃分享整理
    物联沃-IOTWORD物联网 » 基于STM32、FreeRTOS和Spring Boot的智能仓储管理系统:RFID、BLE和Three.js全栈解决方案(附代码示例)

    发表回复