You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Django中实时显示Arduino投币数据且无需刷新页面?

Django实时显示Arduino投币数据的解决方案

方法一:前端定时轮询(简单易实现)

通过前端定时请求后端接口获取最新数据,无需刷新页面即可更新内容,适合新手快速上手。

1. 新增后端API接口

修改views.py,添加仅返回数据的视图:

from django.http import JsonResponse
import serial

def get_coin_data(request):
    try:
        arduino = serial.Serial('COM6', 9600)
        data = arduino.readline().decode().strip()
        arduino.close()
        return JsonResponse({'data': data})
    except Exception as e:
        return JsonResponse({'data': f"Error communicating with Arduino: {str(e)}"}, status=500)

在项目urls.py中添加路由:

from django.urls import path
from . import views

urlpatterns = [
    # 保留原有路由
    path('get-coin-data/', views.get_coin_data, name='get_coin_data'),
]

2. 前端添加定时更新逻辑

修改usb.html,加入JavaScript定时请求并更新页面:

<div class="estimated-price">
    <label>Inserted Coins:</label>
    <span id="inserted-coins">₱{{data}}</span>
</div>

<script>
function updateCoinData() {
    fetch('/get-coin-data/')
        .then(response => response.json())
        .then(result => {
            document.getElementById('inserted-coins').textContent = '₱' + result.data;
        })
        .catch(err => console.error('获取数据失败:', err));
}

// 页面加载后立即更新,之后每隔1秒刷新一次
updateCoinData();
setInterval(updateCoinData, 1000);
</script>

注意:此方式每次请求都会开关串口,频繁操作可能不稳定,后续可优化为后端保持串口长连接。

方法二:WebSockets实时推送(高效稳定)

通过Django Channels实现WebSockets,后端主动推送Arduino数据到前端,适合持续数据传输场景。

1. 安装并配置Django Channels

安装依赖:

pip install channels

修改settings.py:

INSTALLED_APPS = [
    # 保留原有应用
    'channels',
]

ASGI_APPLICATION = '你的项目名称.asgi.application'

2. 创建WebSockets消费者

在应用目录下新建consumers.py:

import asyncio
import serial
from channels.generic.websocket import AsyncWebsocketConsumer

class CoinConsumer(AsyncWebsocketConsumer):
    async def connect(self):
        await self.accept()
        asyncio.create_task(self.read_arduino_stream())

    async def read_arduino_stream(self):
        try:
            arduino = serial.Serial('COM6', 9600)
            while True:
                data = arduino.readline().decode().strip()
                await self.send(text_data=data)
                await asyncio.sleep(0.1)
        except Exception as e:
            await self.send(text_data=f"Error communicating with Arduino: {str(e)}")
            arduino.close()

    async def disconnect(self, close_code):
        if hasattr(self, 'arduino'):
            self.arduino.close()

3. 配置WebSockets路由

项目根目录新建routing.py:

from django.urls import re_path
from .consumers import CoinConsumer

websocket_urlpatterns = [
    re_path(r'ws/coin-data/$', CoinConsumer.as_asgi()),
]

修改asgi.py:

import os
from django.core.asgi import get_asgi_application
from channels.routing import ProtocolTypeRouter, URLRouter
from . import routing

os.environ.setdefault('DJANGO_SETTINGS_MODULE', '你的项目名称.settings')

application = ProtocolTypeRouter({
    "http": get_asgi_application(),
    "websocket": URLRouter(routing.websocket_urlpatterns),
})

4. 前端连接WebSockets

修改usb.html:

<div class="estimated-price">
    <label>Inserted Coins:</label>
    <span id="inserted-coins">₱{{data}}</span>
</div>

<script>
const socket = new WebSocket('ws://' + window.location.host + '/ws/coin-data/');

socket.onmessage = function(e) {
    document.getElementById('inserted-coins').textContent = '₱' + e.data;
};

socket.onclose = function(e) {
    console.error('WebSocket连接断开,3秒后重试');
    setTimeout(() => window.location.reload(), 3000);
};
</script>

通用注意事项

  • 串口权限:确保运行Django的用户拥有串口访问权限(Linux/Mac需将用户加入dialout组)。
  • 稳定性优化:轮询模式可改为后端保持串口长连接,避免频繁开关;WebSockets模式需处理重连逻辑。
  • 错误提示:可在前端添加错误状态的友好展示,提升用户体验。

内容的提问来源于stack exchange,提问作者Pyxxelated

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.13 02:06:34