2026 M-Design设计竞赛 基于ESP32制作的公交车到站信息显示器
该项目使用了Arduino ESP32,实现了在墨水屏上显示公交车实时到站信息的设计,它的主要功能为:显示公交车实时到站信息方便出行参考。
标签
Arduino
ESP32
LAB-Z.COM
Zoologsit
更新2026-06-09
29
  • 项目介绍和创意介绍

这是2026贸泽电子M-Design创意设计大赛方向一:智能家居 自命题


需要乘坐公交车的打工人都有这样的痛苦:出门之后会发现需要等待的公交车相比往常需要等待更长的时间;而更痛苦的事情是:到了公交站发现需要的公交车刚刚关门缓缓驶离。

当然,为了避免这样的问题,可以在出门之前掏出手机,查询一下公交信息,但是这样仍然让人感觉麻烦。

为了解决这个问题,这次设计一个公交信息看板,能够通过网络查询到当前需要的公交信息。这样,起来之后,偶尔看一下就可以做到心中有数,能够安排接下来的起床任务。同时,这个看板可以设定提示时间,比如,公交车还有15分钟到达时,自动进行提示,帮助你更好的准备。


  • 使用到的硬件介绍

硬件的核心是一款带有 ESP32(ESPRESSIF出品) 4.7寸墨水屏,来自 DFRobot,墨水屏有着显示内容不消耗电力的优点,非常适合这种大部分都在休眠的项目。此外,还有一个 DS3231 RTC 模块,负责唤醒设备。其余就是供电部分了,使用 18650电池,使用 DW60实现这个电池的保护,防止过充放;充电是通过 TP5067来完成的;电池的输出经过 TPS63802TI出品)实现稳压到 4.2V (选择这个电压的考量有两点:1.电池最高电压是 4.2V,尽量接近值减少损耗;2.ESP32 需要I2C RTC 模块通讯,4.2V*0.7=2.94V,能够保证I2C 高电平工作正常,如果升压到 5V,那么会出现奇怪的问题【参考1


  • 方案框图和项目设计思路介绍

硬件框图

我们是一个电池工作的设备,因此功耗是一个重要的考虑点:

左下是供电模块,是18650/充电模块/电池保护板组成,它对外提供 2.4V-4.2V 的供电输出。之后使用一个稳压芯片,将2.4-4.2V转为 3.3V 的稳定输出;系统的其他部分都是工作在 3.3V电压上的。我们采用 DS3231时钟模块,这个模块自带了一个纽扣电池,即便失去外部供电仍然能够保持时间。为了省电,我们使用了一个供电控制的芯片,只有DS3231触发之后才会对后面的设备进行供电。后面使用了一个墨水屏+ESP32 的设备。墨水屏的特点是显示完全不消耗电力,换句话说,关机之后仍能够显示内容,这样帮助我们尽可能的省电。上电工作之后 ESP32 会从网上抓取显示内容,完成工作后会通过 I2C 清除DS3231 的触发状态,这样能够实现自断电。

image.png

软件设计框图

电路图如下:

image.png

电路图中的1USB接口,用来充电;2DW06D,用来保护18650电池防止过充过放;3 TP4057充电芯片,负责给18650进行充电,最大充电电流是500ma4TPS63802模块,负责将电池输出的2.4-4.2V电源转为3.3V。这里设计模块的原因是这个芯片比较昂贵。所以设计成模块考虑复用。特别注意:这个芯片工作时一定不要触摸,否则非常容易损坏。在测试过程中我使用万用表测试其他部位电压,不慎手指触摸到就导致了损坏。此外,第一次上电的时候我还习惯性摸一下检查是否过热。因为这个原因前后我损坏了3块芯片。最后在使用时在上面贴一个透明胶防止触摸。5是一个DS3231模块,它可以设定闹钟,当到达指定时间时,能够通过EN 引脚输出低电平;6是一个电源控制芯片,当EN 引脚被拉低时,它能够将电源提供给墨水屏和ESP32

PCB 设计

image.png

特别介绍一下使用到的模块:

1TPS63802 升降压芯片模块【参考1

image.png

具体工作的输出时 R1 R2决定的,输出电压范围:1.8V 5.2V(可调节),计算公式 Vout=(R1/R2+1)*0.5V。因为要考虑ESP32 DS3231 I2C通讯,这里使用3.3V输出。


image.png

image.png

2DS3231模块

image.png

特别注意这个模块默认是工作时对纽扣电池充电的,如果你没有使用可充电的纽扣电池,当使用5V供电时会出现模块发热的情况。另外,I2C 模块已经有上拉电阻,因此外部无需再次上拉。

3.墨水屏和 ESP32 是一体的。

image.png


  • 软件流程图和关键代码介绍

image.png



  • 功能展示图及说明

image.png

3D 打印制作一个外壳,工作的照片

image.png


image.png


上电之后,ESP32 会循环对服务器请求指定的公交车到站信息,然后将结果更新在墨水屏上。这样在需要的时候只需要看一眼即可得到信息。


  • 设计中遇到的难题和解决方法

这个设计最大的难点在于如何获得公交实时信息,几乎所有的设计都是围绕这个来进行的。经过研究,上海市的可以通过“上海市公共数据开放平台” https://data.sh.gov.cn/)获得。下面的所有动作是围绕这个 API进行的。

image.png

1.      确定你要查询的站台信息,这里以获得莘庄公交站的信息为例。

http://jingweidu.757dy.com/ 上查询,得到坐标121.386027,31.114006BD09 百度坐标)。这里特别强调一下坐标系的问题。上海市公共数据开放平台使用的坐标系是WGS84,如果你使用其他方式获得的坐标为其他坐标(例如:前面网站提供的是BD09 百度坐标) 需要使用工具https://geo.toolkithub.net/coordinate-converter 上将坐标转为WGS84坐标:这两个坐标系的核心区别在于:BD09是百度在国家标准加密坐标GCJ-02基础上的二次加密坐标,而WGS84是全球通用的原始GPS坐标。若直接将WGS84坐标标注在百度地图上,会出现数百米至数公里的位置偏移,这个坐标的问题困扰了我很久,一直无法准确定位公交站);

image.png

最终得到WGS84坐标:121.3747863,31.11027359

image.png

2.      在上海市公共数据开放平台上进行注册,实名认证后能够拿到一个 Token,这个可以看作是你的身份证明,在每次请求的时候都要加上才能够请求到数据;

a.      推荐先使用 curl 进行测试


curl -X POST "https://data.sh.gov.cn/interface/idmp-api/gateway/portal/society-dataset/v1/sod-p4pm95e968tfxhil41cotzxyn" -H "content-type: application/json" -H "cache-control: no-cache" -H "token: 【你的TOKEN】" -d "{\"cityCode\":\"310100\",\"isGetStopArrive\":\"1\",\"lon\":\"121.3747863\",\"lat\":\"31.11027359\",\"limit\":20,\"offset\":0,\"coordinateType\":1}"


获得结果如下:

image.png

b.     使用 JSON 格式化工具(比如:https://jsonformatter.curiousconcept.com/#)整理之后更方便查看,可以校验位置信息是否正确。

image.png

c.   例如,我需要虹桥枢纽4路的信息,可以从 JSON 文件中解析出来。同一个线路会有不同的方向(上行下行),这个不要搞错了。代码中使用lineId来进行区分。

   "nearByTrafficLineStop":[

      {

         "isParkLine":0,

         "lineId":"512700",

         "lineName":"春运14线(虹桥枢纽4路)",

         "stopId":"15",

         "startStopName":"虹桥东交通中心",

         "upDown":0,

         "type":"1",

         "point":{

            "lon":"121.379482",

            "lat":"31.108315"

         },

         "followId":0,

         "startEarlyLateTime":"06:00",

         "dispatchCarSchedule":{

            "scheduleMsgDefault":"等待首站发车",

            "dispatchCars":[

               {

                  "countdown":"即将发车",

                  "time":"11:40",

                  "vehicle":"沪A-01994D"

               },

               {

                  "countdown":"剩余5分钟",

                  "time":"12:00",

                  "vehicle":"沪A-01097D"

               },

               {

                  "countdown":"剩余41分钟",

                  "time":"12:20",

                  "vehicle":"沪A-05327D"

               }

            ],

            "lineId":"512700",

            "lineName":"虹桥枢纽4路",

            "scheduleCode":1,

            "scheduleMsgShort":"即将发车",

            "direction":"0"

         },


设计上使用了4.7墨水屏,需要注意的是官方提供的库无法在最新的 Arduino ESP 环境(3.0.X)下运行,需要使用 2.0.3 这个版本

image.png

此外,还需要注意的是:数据使用 HTTPS 进行通讯,这个和常见的 HTTP Client会有一些差别。

在处理时间上需要特别注意,我们取得的互联网时间(UTC)不是北京时间。比如,我在https://www.unixtimestamp.com/上看到的时间是1776562678,但是实际上这个并非 4199:38:06,而是1:38:06。网页显示时间是自动根据你所在时区修正后的结果。

image.png

同一个网页,把这个值再解析就可以看到我上面说的结果:

image.png

如果你把1776562678设置到DS3231中,那么会让DS3231认为当前是20264191:38:06。你的代码取出来之后会发现日期时间不正确。DS3231没有时区功能。所以,我在设计上使用北京时间,当从互联网上取得时间后,加上8小时再存放再 DS3132中来克服这个问题。

考虑到网络的稳定性,以及 ESP32的可靠性,以时间作为关机条件而不是工作次数。比如,设定 7:30唤醒,工作时长20分钟,那么会在 7:50时进行关机操作。这样即便遇到服务器出错或者 得到的数据错误都不会影响关机。


  • 对本次竞赛的心得体会

感谢本次组委会提供的机会,给我支持和动力完成规划和构思很久的问题。


1.      https://www.lab-z.com/ds3231165/  DS3231 2165/165/165 165:165:85 问题分析

2.      https://www.lab-z.com/tps63/ TPS63802 升降压芯片模块测试



附件下载
BAIB.zip
底板电路图和PCB
TPS.zip
TPS 升降压模块电路图和PCB
BusAIB.zip
Arduino完整代码
团队介绍
个人主页 www.lab-z.com
评论
0 / 100
查看更多
硬禾服务号
关注最新动态
0512-67862536
info@eetree.cn
江苏省苏州市苏州工业园区新平街388号腾飞创新园A2幢815室
苏州硬禾信息科技有限公司
Copyright © 2024 苏州硬禾信息科技有限公司 All Rights Reserved 苏ICP备19040198号