基于ESP32与3D打印的智能潮汐时钟:硬件、软件与创意融合实践
1. 项目概述:一个会戴帽子的潮汐时钟
如果你住在海边,或者对海洋的韵律着迷,那么潮汐时钟绝对是个有趣的玩意儿。它不像普通时钟那样告诉你几点几分,而是告诉你潮水正在涨还是落,离高潮或低潮还有多久。市面上的潮汐时钟大多是指针式的,看久了难免觉得单调。今天我想分享的,是一个完全不同的、充满生命力的设计:一个会“戴帽子”的海胆潮汐时钟。
这个项目的核心创意在于,它用一个3D打印的海胆(或者沙钱、海星等棘皮动物模型)作为指示器,通过一个微型伺服电机驱动其旋转。海胆的“头顶”上可以吸附不同样式的3D打印小帽子(比如牛仔帽、猫耳朵、硬礼帽)。潮汐的高低状态,则通过两条不同颜色的柔性LED灯带(我称之为“Noods”)来指示,它们被巧妙地安装在竹筒背景上,形成一圈渐变的光晕。海胆旋转的角度,精确对应着当前潮位在高低潮之间的百分比;而LED灯带的颜色则明确告诉你现在是涨潮(趋向高潮)还是落潮(趋向低潮)。整个装置被封装在一段天然的竹筒里,既有自然质朴的美感,又充满了机械与电子的趣味。
这个项目完美融合了硬件、软件和创意设计。硬件上,它依赖ESP32微控制器作为大脑,负责获取网络数据并控制一切;软件上,它需要从互联网API获取精确的潮汐数据并进行解析;机械上,3D打印和手工组装让想法变成实物。无论你是物联网开发的爱好者,想学习如何让硬件“上网”获取实时数据;还是3D打印的玩家,想做一个有实用功能的装饰品;亦或是单纯被这个可爱的创意打动,这个项目都能带给你从设计思维到动手实现的全流程体验。接下来,我将拆解每一个环节,分享我是如何从零开始把它做出来的,以及过程中那些值得注意的细节和踩过的坑。
2. 核心设计思路与方案选型
做一个潮汐时钟,听起来简单,但怎么做得有趣、直观且稳定,需要在一开始就想清楚。市面上有基于纯机械齿轮计算的潮汐钟,但其精度固定且无法适应不同地点。我们生活在物联网时代,自然要选择更智能、更灵活的方案。
2.1 为什么选择ESP32 + 网络API的方案?
潮汐数据本质上是天体引力和地理位置共同作用的复杂计算结果。自己从零编写算法不仅难度极大,而且精度难以保证。因此,接入专业的潮汐数据服务API是最可靠、最经济的选择。这就需要一个能连接Wi-Fi的微控制器。
在众多物联网微控制器中,我选择了ESP32,原因有三点:
- 强大的网络能力与性价比:ESP32内置Wi-Fi和蓝牙,网络连接稳定,且价格远低于同等功能的Arduino搭配Wi-Fi扩展板。对于需要持续从互联网获取数据的应用,它是性价比之王。
- 充足的硬件资源:本项目需要驱动一个伺服电机(至少1个PWM引脚)、控制两条LED灯带(2个GPIO)、运行一个解析JSON数据的程序,可能还需要为未来的功能扩展留有余地。ESP32丰富的GPIO口和较强的处理能力(双核)完全能够胜任,游刃有余。
- 成熟的生态与社区支持:围绕ESP32的Arduino核心库和第三方库非常丰富。例如,用于HTTP请求和JSON解析的库都有很好的支持,这能极大降低开发难度,避免重复造轮子。
注意:选择ESP32开发板时,我推荐使用像TTGO T-Display这类自带小屏幕的型号。虽然在本项目中屏幕并非必须(我们用海胆和LED指示),但在调试阶段,屏幕能直接打印网络状态、潮汐数据等信息,对于排查问题有巨大帮助,价值远超其增加的几美元成本。
2.2 机械指示方案:伺服电机 + 3D打印模型的考量
如何将抽象的潮汐百分比(例如,当前潮位是高潮位的63%)转化为直观的物理指示?我放弃了传统的步进电机(控制复杂、需要驱动板)和减速电机(难以精确控制角度),选择了微型伺服电机(Servo Motor)。
- 伺服电机的优势:伺服电机可以通过PWM信号精确控制旋转角度(通常是0-180度)。我们只需要将潮汐百分比(0%-100%)线性映射到电机的角度范围,就能让海胆精确地指向相应位置。控制代码极其简单,Arduino IDE内置的
Servo库就能轻松驱动。 - 模型选择与固定:选择海胆、沙钱等模型,是因为它们中心对称,且表面有大量凸起,方便安装和粘贴帽子。将模型固定在伺服电机的舵盘上是关键。我设计了一个3D打印的连接器,一端卡住伺服电机输出轴,另一端通过螺丝或强力胶与海胆模型固定。这里有个坑:务必确保模型的重心与伺服电机转轴对齐。如果模型歪斜或重心偏移,会导致伺服电机负载不均,产生噪音甚至烧毁电机。在打印连接器时,可以设计一个可调节的紧定螺丝结构,方便微调模型的垂直度。
2.3 灯光指示方案:柔性LED灯带(Noods)的运用
仅用海胆旋转指示位置还不够直观,尤其是在光线不足时。我需要一个能清晰区分“涨潮”和“落潮”状态的视觉元素。我选择了Adafruit的“Noods”柔性LED灯带。
- 为什么是Noods?:这种灯带每条只有一个颜色,但非常柔软,可以弯曲成任意形状,并且是5V供电,可以直接由ESP32的GPIO口驱动(需串联合适电阻)。我选用两条不同颜色(例如,蓝色代表涨潮/趋向高潮,橙色代表落潮/趋向低潮),将它们分别弯曲成半圆形,背对背安装在竹筒内壁,形成一个完整的彩色光环。
- 控制逻辑:程序逻辑很简单。当计算发现下一个潮汐事件是高潮时,点亮“高潮色”灯带;当是低潮时,点亮“低潮色”灯带。灯带的亮度或闪烁模式也可以用来表示接近高潮/低潮的程度,增加信息维度。由于ESP32的GPIO口驱动能力有限,直接驱动多条LED灯带可能电流不足,如果未来想扩展更多灯光效果,可以考虑增加一个简单的MOSFET晶体管驱动电路。
2.4 外壳与结构:自然材料与功能结合
外壳选用竹筒,并非仅仅为了美观。竹子中空的筒状结构天然形成了一个深邃的“窗口”,能将观众的视线聚焦于中心的海胆和背景的光环上。内部的竹节(baffle)恰好成为了安装伺服电机和电路板的完美支架,省去了额外设计固定结构的麻烦。
实操心得:寻找合适尺寸的竹筒可能需要一点运气。直径最好在10-15厘米,长度15-20厘米为宜。如果找不到竹筒,完全可以用一大段PVC管喷漆仿竹纹,或者直接设计一个圆筒状的外壳进行3D打印。核心在于,外壳要能牢固地容纳所有内部组件,并为LED灯带提供均匀的漫反射背景。我曾在竹筒内壁贴了一层白色的描图纸,让LED光线更加柔和、均匀,效果提升非常明显。
3. 硬件搭建与组装详解
有了清晰的设计思路,就可以开始动手组装了。这个过程像是完成一个精致的立体拼图,每一步的精度都影响着最终的效果和稳定性。
3.1 材料与工具清单
除了项目正文中提到的核心部件,这里列出一个更详细、更实用的清单:
- 核心控制器:TTGO ESP32开发板(带屏幕款最佳) 1个
- 执行器:9g微型数字伺服电机(金属齿轮版,更安静耐用) 1个
- 指示器:
- 3D打印的海胆/沙钱模型 1个
- 3D打印的小帽子模型 若干(建议至少打印2-3种)
- 柔性单色LED灯带(Noods或类似WS2812B可寻址灯带亦可) 2条(不同颜色)
- 结构件:
- 竹筒一节(或PVC管/3D打印外壳)
- 3D打印的伺服电机固定架
- 3D打印的LED灯带固定卡扣
- 3D打印的海胆与伺服电机连接器
- 连接与固定:
- 5V/2A直流电源适配器 1个
- DC电源插座(与适配器匹配) 1个
- 细导线若干
- M3*10mm螺丝螺母套装
- 5x2mm微型钕铁硼磁铁 至少8对(用于帽子吸附)
- 热熔胶枪及胶棒
- 万用表
- 电钻及不同尺寸钻头(2mm, 5mm, 10mm)
- 螺丝刀套装
3.2 3D打印部件的处理与准备
所有的STL文件都可以在开源模型网站找到。打印时使用标准的PLA材料,层高0.2mm,填充率20%即可,无需支撑。
- 模型选择与打磨:海胆模型表面细节丰富,打印后可能会有一些拉丝或毛刺。建议用小镊子或精细砂纸轻轻处理,特别是与连接器接触的底部平面,务必保持平整,以确保安装后不歪斜。小帽子模型通常很小,打印时要注意底部的吸附磁铁安装孔是否清晰,必要时可以用合适尺寸的钻头手动扩孔。
- 磁铁安装:这是实现“换帽”功能的关键。在海胆模型的“头顶”中心位置,用胶水固定一颗磁铁(注意极性朝上)。在每一顶帽子的底部中心,也固定一颗磁铁,但极性必须与海胆头上的磁铁相反,这样才能相互吸引。一个避免搞混极性的小技巧:先在海胆头上固定好一颗磁铁,然后用每顶帽子去吸附它,能吸住就标记帽子底部,然后在这个标记位置涂胶固定帽子上的磁铁。竹筒边缘用于存放备用帽子的磁铁,其极性方向则需与帽子底部的磁铁相反,这样帽子才能被吸附在竹筒上。
3.3 竹筒外壳的加工
竹筒是项目的灵魂,加工需要耐心。
- 切割与清洁:截取一段长度合适的竹筒,确保一端有竹节封闭作为底部,另一端开放。用砂纸打磨切口,防止毛刺。仔细清洁内部,去除竹膜和灰尘。
- 定位与打孔:
- 伺服电机安装孔:找到竹筒内部大约一半高度位置的竹节(隔板)。在竹节的中心位置,钻一个10mm的孔。这个孔将用来穿过伺服电机的输出轴。
- LED灯带导线孔:在竹节上,伺服电机安装孔的两侧,各钻一个小孔(约3mm),用于穿过控制LED灯带的导线。
- 电源线孔:在竹筒背面靠近底部的位置,钻一个适合DC电源插座尺寸的孔。
- 帽子吸附磁铁孔:在竹筒开放端的边缘,等间距地钻出几个深2mm、直径5mm的浅孔,用于嵌入吸附备用帽子的磁铁。孔的数量取决于你准备的帽子数量。
- 安装内部支架:将3D打印的伺服电机固定架用M3螺丝从竹节背面(底部方向)固定到竹节上,确保固定架上的轴孔与刚才钻的10mm孔对齐。然后将伺服电机塞入固定架,并用配套的小螺丝锁紧。此时,伺服电机的输出轴应该从竹节正面(海胆所在腔体)伸出。
3.4 电路连接与焊接
电路部分其实非常简单,遵循“先规划,后焊接”的原则。
- 电源分配:这是最重要的一步。使用一个5V/2A的直流电源适配器为整个系统供电。将电源正极(+5V)同时连接到伺服电机的VCC引脚和ESP32开发板的5V或VIN引脚。将电源负极(GND)连接到伺服电机的GND和ESP32的GND引脚。务必确保共地。
- 信号线连接:
- 伺服电机的信号线(通常是橙色或白色)连接到ESP32的GPIO 17。
- 两条LED灯带的正极(+)分别通过一个220欧姆的限流电阻(保护GPIO口),连接到ESP32的GPIO 32和GPIO 33。灯带的负极(-)直接连接到GND。
- (如果使用TTGO屏幕板,其供电和通信通常已集成,无需额外接线)。
- 布线技巧:所有导线建议使用不同颜色的硅胶线,便于区分。连接处最好使用焊接,并用热缩管绝缘,比电工胶布更可靠美观。将ESP32开发板、电源插座等用尼龙扎带或双面胶固定在竹筒底部空腔,确保线路整洁,不干扰伺服电机转动。
3.5 总装与校准
- 安装LED灯带:将两条弯曲成半圆形的LED灯带,用3D打印的卡扣或者一点点热熔胶,固定在竹筒内壁,位于竹节(伺服电机安装面)的前方。确保两条灯带对称,形成一个完整的圆环。
- 安装海胆指针:将海胆模型通过3D打印的连接器牢牢固定在伺服电机的舵盘上。关键校准步骤来了:上传一个简单的测试程序,让伺服电机分别转动到0度和180度。观察海胆在这两个极限位置时,是否正好指向LED灯带环的“最低点”和“最高点”(或者你定义的其他起始/结束位置)。如果不准,需要物理调整连接器的安装角度,或者在软件中修改角度映射的偏移量。
- 磁铁吸附测试:将不同的帽子吸附到海胆头上,检查是否牢固。同时,测试备用帽子是否能稳稳地吸附在竹筒边缘的磁铁上。
- 合盖:最后,可以将前面板(如果设计了的话)盖上,或者就这样保持开放式的机械美感。确保所有线路不被挤压,伺服电机转动无阻碍。
4. 软件程序设计:从网络获取数据到机械运动
硬件是身体,软件才是灵魂。程序的职责是定时从互联网获取潮汐数据,计算出当前潮位状态,并据此控制伺服电机和LED灯带。
4.1 开发环境搭建与库安装
我们使用Arduino IDE进行开发。首先需要添加对ESP32的支持:
- 打开Arduino IDE,进入“文件”->“首选项”,在“附加开发板管理器网址”中添加:
https://espressif.github.io/arduino-esp32/package_esp32_index.json - 打开“工具”->“开发板”->“开发板管理器”,搜索“esp32”,安装“Espressif Systems”提供的ESP32开发板包。
- 安装必要的库。打开“工具”->“管理库”,搜索并安装以下库:
ArduinoJson(by Benoit Blanchon):用于解析从API返回的复杂JSON数据。WiFi(通常已内置):用于连接Wi-Fi网络。HTTPClient(通常已内置):用于发起HTTP请求获取数据。Servo(通常已内置):用于控制伺服电机。
4.2 核心代码逻辑拆解
程序主要运行在一个循环中,但为了清晰,我们将其分为几个模块。
4.2.1 网络连接与数据获取
首先,需要连接到Wi-Fi。为了避免将密码硬编码在主程序里,我采用一个单独的secrets.h头文件来存储敏感信息。
secrets.h文件内容:
// secrets.h - 切勿将此文件上传至公开的代码仓库! #define WIFI_SSID "你的Wi-Fi名称" #define WIFI_PASSWORD "你的Wi-Fi密码" #define WORLD_TIDES_API_KEY "你在worldtides.info申请的API密钥"主程序中,引入这个文件并连接Wi-Fi:
#include "secrets.h" #include <WiFi.h> void connectToWiFi() { WiFi.begin(WIFI_SSID, WIFI_PASSWORD); Serial.print("Connecting to WiFi"); while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); } Serial.println("\nConnected! IP address: "); Serial.println(WiFi.localIP()); }连接成功后,就可以向潮汐数据API发起请求了。我使用的是WorldTides.info的API,它有免费的层级,对于个人项目完全够用。
构建HTTP请求:
#include <HTTPClient.h> #include <ArduinoJson.h> String getTideData(double lat, double lon) { HTTPClient http; // 构建请求URL,包含经纬度和API Key String url = "https://www.worldtides.info/api/v3?extremes&lat=" + String(lat, 6) + "&lon=" + String(lon, 6) + "&key=" + WORLD_TIDES_API_KEY; http.begin(url); int httpCode = http.GET(); String payload = ""; if (httpCode == HTTP_CODE_OK) { payload = http.getString(); } else { Serial.printf("HTTP GET failed, error: %s\n", http.errorToString(httpCode).c_str()); } http.end(); return payload; }4.2.2 JSON数据解析与潮汐计算
API返回的是JSON格式的数据,包含了未来一段时间内所有高潮和低潮的时间点(Unix时间戳格式)。我们需要从中找出当前时间前后最近的两个潮汐事件(一个高潮,一个低潮)。
void parseTideData(String jsonPayload, TideEvent *nextHigh, TideEvent *nextLow) { // 假设TideEvent是一个结构体,包含timestamp(时间戳)和isHigh(是否高潮) DynamicJsonDocument doc(2048); // 根据返回数据大小调整 deserializeJson(doc, jsonPayload); JsonArray extremes = doc["extremes"]; unsigned long currentTime = getCurrentEpochTime(); // 需要从网络时间服务获取当前时间戳 // 初始化 nextHigh->timestamp = ULONG_MAX; nextLow->timestamp = ULONG_MAX; for (JsonObject e : extremes) { unsigned long eventTime = e["dt"]; bool isHigh = strcmp(e["type"], "High") == 0; if (eventTime > currentTime) { // 只关心未来的事件 if (isHigh && eventTime < nextHigh->timestamp) { nextHigh->timestamp = eventTime; } if (!isHigh && eventTime < nextLow->timestamp) { nextLow->timestamp = eventTime; } } } // 还需要找到当前时间之前最近的一个事件,以确定当前处于涨潮还是落潮周期 // ... (类似逻辑,寻找 eventTime < currentTime 且最接近的事件) }得到最近的高潮(nextHigh)和低潮(nextLow)时间戳后,就能计算当前潮位状态:
- 判断当前周期:如果上一个事件是低潮,当前正走向高潮,属于“涨潮期”;反之是“落潮期”。这决定了点亮哪条LED灯带。
- 计算潮位百分比:
- 在涨潮期:百分比 = (当前时间 - 上一个低潮时间) / (下一个高潮时间 - 上一个低潮时间) * 100%
- 在落潮期:百分比 = (当前时间 - 上一个高潮时间) / (下一个低潮时间 - 上一个高潮时间) * 100%
- 映射到伺服电机角度:将计算出的百分比(0-100%)线性映射到伺服电机的角度范围(例如,0-180度)。
angle = percentage * 180 / 100。
4.2.3 执行器控制
计算得到角度和潮汐状态后,控制就很简单了:
#include <Servo.h> Servo tideServo; const int servoPin = 17; const int ledHighPin = 32; // 高潮/涨潮指示灯 const int ledLowPin = 33; // 低潮/落潮指示灯 void controlActuators(float tidePercentage, bool isRising) { // 控制伺服电机 int angle = map(tidePercentage * 100, 0, 100, 0, 180); // 将百分比转为角度 angle = constrain(angle, 0, 180); // 限制在有效范围 tideServo.write(angle); // 控制LED灯带 if (isRising) { digitalWrite(ledHighPin, HIGH); // 点亮涨潮灯带 digitalWrite(ledLowPin, LOW); } else { digitalWrite(ledHighPin, LOW); digitalWrite(ledLowPin, HIGH); // 点亮落潮灯带 } }4.2.4 主循环与优化
主程序loop()函数中,我们不需要每秒都去请求API(这会产生不必要的网络流量和API调用)。潮汐变化以小时计,每隔10-30分钟更新一次数据就足够了。
void loop() { unsigned long currentMillis = millis(); // 每30分钟(1,800,000毫秒)更新一次潮汐数据 if (currentMillis - previousTideUpdateMillis >= TIDE_UPDATE_INTERVAL) { updateTideData(); // 这个函数包含获取、解析、计算全过程 previousTideUpdateMillis = currentMillis; } // 更频繁地更新伺服电机位置(例如每秒一次),使运动更平滑 if (currentMillis - previousServoUpdateMillis >= SERVO_UPDATE_INTERVAL) { float currentPercentage = calculateCurrentTidePercentage(); // 基于最新数据计算实时百分比 controlActuators(currentPercentage, isRisingTide); previousServoUpdateMillis = currentMillis; } // 可以在这里加入屏幕刷新、状态打印等代码 delay(100); // 防止循环过快 }实操心得:时间同步的重要性。ESP32本身没有实时时钟(RTC),断电后时间会丢失。因此,在连接Wi-Fi后,第一件事应该是通过NTP(网络时间协议)同步当前时间。可以使用WiFiClient和time.h库来实现。准确的时间戳是正确解析潮汐数据的前提。
5. 调试、优化与问题排查实录
即使按照步骤操作,第一次通电也难免遇到问题。下面是我在制作和调试过程中遇到的一些典型情况及解决方法。
5.1 常见问题速查表
| 问题现象 | 可能原因 | 排查步骤与解决方案 |
|---|---|---|
| ESP32无法连接Wi-Fi | 1. SSID/密码错误 2. Wi-Fi信号弱 3. 路由器设置了MAC过滤 | 1. 检查secrets.h文件中的信息,确保无空格或错误。2. 将设备靠近路由器,或通过串口打印Wi-Fi状态码( WiFi.status())。3. 在路由器后台查看ESP32是否被阻止,或暂时关闭MAC过滤。 |
| 伺服电机不转动或抖动 | 1. 电源功率不足 2. 信号线接触不良 3. 机械负载卡死 4. 程序角度值超限 | 1.最常见原因!确保使用5V/2A以上的电源单独为伺服电机供电,或确认开发板USB口能提供足够电流。 2. 检查信号线是否焊接牢固,是否接对了GPIO口。 3. 手动拨动海胆模型,检查转动是否顺滑,有无阻碍。 4. 在 Servo.write()前打印角度值,确认其在0-180范围内。 |
| LED灯带不亮或亮度异常 | 1. 正负极接反 2. 限流电阻过大或过小 3. GPIO口驱动能力不足 | 1. 用万用表检查线路。 2. 对于普通LED,220欧姆电阻是常用值。如果太暗可减小电阻,但需注意不要超过GPIO口最大电流(通常~20mA)。 3. 考虑使用MOSFET或晶体管来驱动,ESP32的GPIO仅作信号控制。 |
| 潮汐数据获取失败 | 1. API Key无效或过期 2. 网络请求超时 3. JSON解析失败 | 1. 登录WorldTides.info确认Key状态,并检查代码中Key是否正确。 2. 增加HTTP客户端超时时间,检查网络连接。 3. 将API返回的原始JSON字符串打印到串口,用在线JSON校验工具检查格式,并调整 DynamicJsonDocument的容量。 |
| 海胆指针位置不准 | 1. 伺服电机初始位置未校准 2. 潮汐百分比计算有误 3. 机械连接松动 | 1. 上传一个让伺服电机归中(90度)的程序,物理调整海胆到中间位置。 2. 在串口监视器中打印出计算出的百分比、下一个高潮/低潮时间,与手机潮汐App对比。 3. 紧固连接器和舵盘之间的螺丝。 |
| 程序运行一段时间后死机 | 1. 内存泄漏(常见于JSON解析) 2. 看门狗定时器触发 3. 电源不稳定 | 1. 确保DynamicJsonDocument在函数结束时离开作用域被自动释放,或手动doc.clear()。2. 在长时间运行的循环中适当加入 delay()或yield()。3. 检查电源适配器质量,劣质电源可能导致电压波动使ESP32复位。 |
5.2 深度优化技巧
- 降低功耗:这个项目通常插电使用,功耗不敏感。但如果想用电池,可以深度优化:让ESP32大部分时间处于深度睡眠模式,每15分钟唤醒一次,连接Wi-Fi获取数据,更新伺服电机位置后再次睡眠。伺服电机只在位置变化时通电。
- 增加本地缓存与容错:网络可能不稳定。可以在ESP32的Flash或SPIFFS文件系统中缓存最后一次成功获取的潮汐数据。当网络请求失败时,使用缓存数据计算潮位,虽然精度会随时间下降,但保证了时钟的基本运行。
- 平滑运动与噪音控制:伺服电机直接跳转到目标角度可能产生噪音和抖动。可以在代码中实现平滑移动算法,让角度每次变化一小步,延时几毫秒,直到到达目标位置。使用数字伺服电机(本项目推荐)本身也比模拟伺服电机安静得多。
- 扩展灯光效果:如果使用WS2812B这类可寻址RGB灯带,效果会更炫酷。你可以编程实现潮位百分比用彩虹色渐变表示,或者用亮度脉冲来指示潮水变化的速度。这需要用到
FastLED或NeoPixel库,并注意其功耗会比单色LED高。
5.3 个人踩坑记录
- 电源的坑:最初我用一个旧的手机充电器(标称5V/1A)供电。当伺服电机转动时,ESP32会突然重启。用万用表测量发现,电机启动瞬间电压被拉低到3.5V以下。教训:驱动电机类负载,务必选择输出电流充足、质量好的电源,并考虑在电源输入端并联一个大电容(如1000uF)来缓冲瞬时电流需求。
- 磁铁的坑:第一次用的磁铁太小(2x1mm),吸力不足,帽子容易掉。后来换成了5x2mm的钕铁硼磁铁,吸力强劲。教训:在涉及物理交互的设计中,安全性和可靠性优先,该用大磁铁就用大的。
- API调用的坑:一开始我把API请求放在主循环里,每10秒请求一次,很快就把免费API的调用额度用光了。教训:仔细阅读API服务商的条款,合理设置数据更新频率。潮汐数据变化很慢,每小时甚至每6小时更新一次都完全足够。
这个项目从构思到实现,充满了硬件调试的乐趣和软件逻辑的挑战。当你看到海胆缓缓转动,LED光晕随着潮起潮落变换颜色,那种将虚拟数据转化为实体运动的美妙感觉,是纯软件项目无法给予的。它不仅仅是一个时钟,更是一个放在桌面的、关于地球与月球舞蹈的微小雕塑。你可以根据自己的喜好,设计更多有趣的帽子,或者更换不同的海洋生物模型,让它成为独一无二的个人作品。
