创客项目秀|基于XIAO ESP32C3的Night Lamp With Chinese Traditional Pane项目

news2024/12/1 0:32:01

 Fab Academy,源自麻省理工学院的先进教育项目,致力于培养具有全球视野的创新者和制造者。通过密集学习和实践,学生们掌握了从基础到高级的制造技术,学习了如何将创意转化为现实。今天小编给大家带来的是Fab academy学员Dion Tsang的结课项目:Night Lamp With Chinese Traditional Pane,具有中国文化特色的外观结构,同时可以实现远程控制和数据可视化等功能,让我们一起了解这个项目的开发过程。

项目介绍

具有远程切换、颜色调节功能,并提供夜灯所在空间的温度和湿度值的可视化。用户只需在界面上进行相应的操作即可。台灯的外观是一个类似于汉字——“中”的设计。

材料清单


电子元件

数量

价格

LED灯带

1

$34.9

XIAO ESP32C3

1

$4.99

Grove DHT11

1

$5

CONN HEADER SMD 10芯 1.27MM

1

$0.88

CONN 接头 SMD R/A 4POS 2.54MM

1

$0.93

CONN 接头 SMD R/A 3POS 2.54MM

1

$0.93

轻触开关 SPST-NO 顶部驱动表面贴装

1

$1.08

LED 蓝色透明 1206 SMD

1

$0.23

RES 1K 欧姆 1% 1/4W 1206

1

$0.10

RES 499K 欧姆 1% 1/4W 1206

1

$0.10

跳线 F/F 6“ 20PCS

1

$2.10

杜邦线

1

$8.99

PCB设计与制作

对于PCB的设计、焊接与铣削,主要内容参考:

夜灯,我将包括Xiao ESP32-C3,一个LED条(WS2812B),一个温度和湿度传感器Grove DHT11和其他组件,对于Xiao,我们需要将Fab Electronics Library添加到Kicad。

由于在 Kicad 中找不到这个元件元件,我把它取下来,重新焊接,用 3 组合起来,用连接器(线)连接到板子上。喜欢这个:Pin header 2.54MM 1*40 2*40 P

您可能会注意到 Grove 电缆有 4 种不同的颜色。

引脚 1 - 黄色(例如,I2C Grove 连接器上的 SCL)

引脚 2 - 白色(例如,I2C Grove 连接器上的 SDA)

引脚 3 - 红色 - 所有 Grove 连接器 上的 VCC

引脚 4 - 黑色 - 所有 Grove 连接器上的 GND

我拆下了电缆末端的一端,并使用排针将其连接到 CONN HEADER SMD。

远程控制与数据可视化功能

对于远程控制与数据可视化功能的实现,参考视频:

https://www.bilibili.com/video/BV1U34y1Y7wv/?spm_id_from=333.880.my_history.page.click&vd_source=de467befc07e98c5fa1b53ff474c2875

从这个视频获得电灯的遥控切换。视频中的博主使用 MQTT 实现了对 LED 灯带的远程开/关控制。我从灯的这个观点中获得灵感。这些花型、巧妙的线结构设计和压接设计给我留下了深刻的印象!它的图案让我想起了中国古代的图案,这个想法鼓励我设计一个中国传统图案,尤其是紫禁城文物的一些图案。我希望我能设计这些模式并将它们应用到我的项目工作中。

输入设备

这是一个更新版本,我将使用 XIAO 和 Grove - Ultrasonic Ranger 为我的输入设备周制作一个新项目。

我有来自我们实验室的一种 XIAO:

接下来,让我们开始 PCB 设计吧!

PCB 铣削:

焊接及短路测试

项目代码

本项目具体代码如下:

/*

Originally from MQTT ESP8266 Example

Basic XIAO-ESP32 MQTTS example

 Before starting , You should have
 - MQTT Broker Name
 - MQTT Broker Username
 - MQTT Borker Password

  Modified by Salman Faris - Added MQTTS Implimenation as per ESP32 and MQTTS.

  Modified by Dion Tsang - Added Colorwheel, DHT Datavisualization.

*/

#include <WiFi.h>
#include <PubSubClient.h>


#include "DHT.h"

#include <Adafruit_NeoPixel.h>
#ifdef __AVR__
#include <avr/power.h>  // Required for 16 MHz Adafruit Trinket
#endif

#define DHTPIN D2
#define DHTTYPE DHT11  // DHT 11
#define NUMPIXELS 80   // Popular NeoPixel ring size
#define PIN D1

#define BUF_SIZE (100)
#define BUF_SIZE2 (100)

DHT dht(DHTPIN, DHTTYPE);  // Initialize DHT sensor.
Adafruit_NeoPixel strip(NUMPIXELS, PIN, NEO_GRBW + NEO_KHZ800);

Adafruit_NeoPixel pixels(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);
#define DELAYVAL 20  // Time (in milliseconds) to pause between pixels


// Update these with values suitable for your network.

const char* ssid = "AndroidAP26ab";             // WiFi Name
const char* password = "tawd7050";              // WiFi Password
const char* mqtt_server = "mqtt.fabcloud.org";  //MQTT Broker Name


WiFiClient espClient;
PubSubClient client(espClient);
unsigned long lastMsg = 0;
#define MSG_BUFFER_SIZE (50)
char msg[MSG_BUFFER_SIZE];
int value = 0;
// int BUILTIN_LED = D10



void setup_wifi() {

  delay(10);
  // We start by connecting to a WiFi network
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(ssid);

  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED) {
    delay(DELAYVAL);
    Serial.print(".");
  }

  randomSeed(micros());

  Serial.println("");
  Serial.println("WiFi connected");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
}

void callback(char* topic, byte* payload, unsigned int length) {
  Serial.print("Message arrived [");
  Serial.print(topic);
  Serial.print("] ");
  for (int i = 0; i < length; i++) {
    Serial.print((char)payload[i]);
  }
  Serial.print("This is length");
  Serial.print(length);
  Serial.println();


  if (strcmp(topic, "fabacademy/myLampSwitch") == 0) {
    if ((char)payload[0] == '1') {
      pixels.clear();  // Set all pixel colors to 'On'
      for (int i = 0; i < NUMPIXELS; i++) {
        // pixels.setPixelColor(i, pixels.Color(0, 150, 0));
        pixels.setPixelColor(i,0xDE3759);
      }
      pixels.show();  // Send the updated pixel colors to the hardware
    } else if ((char)payload[0] == '0') {
      pixels.clear();  // Set all pixel colors to 'Off'
      for (int i = 0; i < NUMPIXELS; i++) {
        pixels.setPixelColor(i, pixels.Color(0, 0, 0));
      }
      pixels.show();  // Send the updated pixel colors to the hardware
    }
  }

 if (strcmp(topic, "fabacademy/LampColor") == 0) {
    // Parse the hex color code from the payload
    char hexColor[7] = { 0 };  // 6 characters + null terminator
    if (length == 7) {
      // strncpy(hexColor, (char*)payload, 6);
      for (int i=1; i <length;i++){
        hexColor[i-1]=(char)payload[i];
        Serial.println(hexColor[i-1]);
      }
      hexColor[6] = '\0';  // Ensure null-terminated string

      // Serial.println(hexColor);

      // Convert hex color code to a 32-bit integer
      uint32_t color = (uint32_t)strtol(hexColor, NULL, 16);

      // Extract RGB components from the 32-bit color value

      byte red = (color >> 16) & 0xFF;
      byte green = (color >> 8) & 0xFF;
      byte blue = color & 0xFF;

      // Set the NeoPixel color using the 32-bit integer
      pixels.clear();
      for (int i = 1; i < NUMPIXELS; i++) {
        pixels.setPixelColor(i, pixels.Color(red, green, blue));
      }
      pixels.show();  // Send the updated pixel colors to the hardware
    }
  }
}

  void reconnect() {
    // Loop until we're reconnected
    while (!client.connected()) {
      Serial.print("Attempting MQTT connection...");
      // Create a random client ID
      String clientId = "XIAO-ESP32-Client-";
      clientId += String(random(0xffff), HEX);
      // Attempt to connect
      // if (client.connect(clientId.c_str())) {
      if (client.connect(clientId.c_str(), "fabacademy", "fabacademy")) {
        Serial.println("connected");
        // Once connected, publish an announcement...
        //client.publish("fabacademy/dionTest/Temperature", "hello world");

        // ... and resubscribe
        client.subscribe("fabacademy/myLampSwitch");
        client.subscribe("fabacademy/LampColor");

      } else {
        Serial.print("failed, rc=");
        Serial.print(client.state());
        Serial.println(" try again in 5 seconds");
        // Wait 5 seconds before retrying
        delay(DELAYVAL);
      }
    }
  }

  void setup() {
    // pinMode(PIN, OUTPUT);  // Initialize the BUILTIN_LED pin as an output
    Serial.begin(115200);
    setup_wifi();
    client.setServer(mqtt_server, 1883);
    client.setCallback(callback);
    dht.begin();

    // END of Trinket-specific code.

    pixels.begin();  // INITIALIZE NeoPixel strip object (REQUIRED)
  }


  void loop() {

    if (!client.connected()) {
      reconnect();
    }
    client.loop();

    delay(DELAYVAL);

    // Reading temperature or humidity takes about 250 milliseconds!
    // Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor)
    float h = dht.readHumidity();
    // Read temperature as Celsius (the default)
    float t = dht.readTemperature();
    // Read temperature as Fahrenheit (isFahrenheit = true)
    float f = dht.readTemperature(true);

    // Check if any reads failed and exit early (to try again).
    if (isnan(h) || isnan(t) || isnan(f)) {
      Serial.println(F("Failed to read from DHT sensor!"));
      return;
    }

    // unsigned long now = millis();
    // if (now - lastMsg > 2000) {
    //   lastMsg = now;
    //   ++value;
    //   snprintf (msg, MSG_BUFFER_SIZE, "hello world #%ld", value);
    //   Serial.print("Publish message: ");
    //   Serial.println(msg);
    //   client.publish("fabacademy/dionTest", msg);
    // }

// #define BUF_SIZE (100)
// #define BUF_SIZE2 (100)
    char tempra[BUF_SIZE];
    snprintf(tempra, BUF_SIZE, "%f", t);
    client.publish("fabacademy/Temprature", tempra);
    char humidity[BUF_SIZE2];
    snprintf(humidity, BUF_SIZE2, "%f", h);
    client.publish("fabacademy/Humidity", humidity);
  }

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2215285.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

前端全栈混合之路Deno篇:Deno2.0与Bun对比,谁更胜一筹?或者说谁更适合怎样的项目

在前端全栈开发中&#xff0c;工具的不断演变让开发者们始终在寻找更高效、更现代化的解决方案。继Node.js之后&#xff0c;Deno和Bun 成为了两个比较火热的运行时。Deno2.0的近期的发布让它在性能和兼容性方面大幅提升-尤其是兼容了npm包&#xff08;但我感觉应该不是全部兼容…

如何给低代码平台取名?命名策略与技巧全解析

低代码平台正日益成为企业数字化转型的重要工具。为了确保您的平台能够脱颖而出&#xff0c;吸引到更多的用户和开发者&#xff0c;选择一个恰到好处的名字至关重要。本文将探讨如何为您的低代码平台选择一个既独特又易于记忆的好名字&#xff0c;并详细介绍一系列行之有效的命…

第二百七十九节 JPA教程 - JPA查询IN一对多示例

JPA教程 - JPA查询IN一对多示例 以下JPQL显示如何在一对多映射中使用IN运算符。 executeAndPrintQuery("SELECT DISTINCT p FROM Employee e, IN(e.directs) p");例子 下面的代码来自Department.java。 package cn.w3cschool.common;import java.util.ArrayList; …

中药药材推荐系统

毕业设计还在发愁选题&#xff1f;又想实用又怕复杂&#xff1f;那这篇介绍你一定感兴趣&#xff01; 今天为大家推荐一个基于Django框架开发的中药药材推荐系统&#xff0c;简洁易用&#xff0c;功能丰富&#xff0c;非常适合毕业设计。无论你是技术经验丰富的开发人员&#…

praat语音标注

一、软件下载 praat软件下载链接 下载后双击 二、软件界面

【机器学习】朴素贝叶斯算法|商品评论情感分析案例介绍及代码实现

文章目录 朴素贝叶斯算法朴素贝叶斯算法介绍概率数学基础复习朴素贝叶斯算法-利用概率值进行分类的一种机器学习算法贝叶斯公式朴素贝叶斯算法拉普拉斯平滑系数 朴素贝叶斯API案例分析流程数据集代码实现运行结果 朴素贝叶斯算法 朴素贝叶斯算法介绍 概率数学基础复习 条件概…

扇形旋转切换效果(等级切换转盘)

实现动态扇形旋转切换效果&#xff0c;切换进度支持渐变效果 效果展示 在线示例 https://code.juejin.cn/pen/7425559403589271588 源码实现 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"v…

华宇携司法大模型亮相2024中国移动全球合作伙伴大会

2024中国移动全球合作伙伴大会于10月11日在广州琶洲保利世贸博览馆盛大开幕。本届大会以“智焕新生 共创AI时代”为主题&#xff0c;深入探讨数据、算力与人工智能如何深度融合&#xff0c;全力推进AI规模发展、规模应用&#xff0c;加快形成AI技术能力、经济效益上的规模效应&…

【NestJS入门到精通】装饰器

目录 方法装饰器通过prototype添加属性、方法 属性装饰器拓展 方法装饰器参数装饰器 方法装饰器 ClassDecorator 定义了一个类装饰器 a&#xff0c;并将其应用于类 A。装饰器 a 会在类 A 被定义时执行。 const a:ClassDecorator (target:any)>{console.log(target,targe…

Python Django 数据库优化与性能调优

Python Django 数据库优化与性能调优 Django 是一个非常流行的 Python Web 框架&#xff0c;它的 ORM&#xff08;对象关系映射&#xff09;允许开发者以简单且直观的方式操作数据库。然而&#xff0c;随着数据量的增长&#xff0c;数据库操作的效率可能会成为瓶颈&#xff0c…

【SQL Server】数据库在新建查询后闪退——解决方案:以管理员的身份运行

我的SQLServer2022之前都是可以用的&#xff0c;隔了好久没有使用&#xff0c;今天要用到去写一些SQL 语句 结果在点击新建查询后闪退了&#xff0c; 经过查询后&#xff0c;解决方案&#xff1a; 以管理员的身份运行后点击新建查询&#xff0c;发现正常了 总结&#xff1a;以…

PyQt 入门教程(2)搭建开发环境

文章目录 一、搭建开发环境1、安装PyQt6与pyqt6-tools2、配置外部工具QtDesigner与PYUIC 一、搭建开发环境 1、安装PyQt6与pyqt6-tools PyQt6&#xff1a; PyQt的开发库。pyqt6-tools&#xff1a; QtDesigner 设计器支撑库。 通过PyCharm安装开发库&#xff0c;命令如下&…

探索全流量回溯分析系统:IT运维的必备利器

目录 一、什么是全流量回溯分析系统&#xff1f; 二、全流量回溯分析系统的核心功能 三、IT运维中的实际应用案例 四、IT运维中使用全流量回溯分析系统的技巧 结语 AnaTraf 网络性能监控系统NPM | 全流量回溯分析 | 网络故障排除工具 在当今的IT运维中&#xff0c;网络故…

【Python爬虫实战】正则:多字符匹配、开头与结尾定位、分组技术详解

&#x1f308;个人主页&#xff1a;https://blog.csdn.net/2401_86688088?typeblog &#x1f525; 系列专栏&#xff1a;https://blog.csdn.net/2401_86688088/category_12797772.html 目录 前言 一、匹配多个字符 &#xff08;一&#xff09;匹配任意多个字符 &#xff0…

OpenAI Canvas:提升编程与写作效率的全新工作界面

随着人工智能技术的飞速发展&#xff0c;大语言模型&#xff08;LLM&#xff09;不仅限于生成文本&#xff0c;还能逐步扩展至编程、设计等任务的支持。近期&#xff0c;OpenAI 推出了一个名为 Canvas 的全新功能&#xff0c;专门用于协助用户进行编程和写作。这一功能与 Claud…

请求参数中字符串的+变成了空格

前端请求 后端接收到的结果 在URL中&#xff0c;某些字符&#xff08;包括空格、、&、? 等&#xff09;需要被编码。具体而言&#xff0c;在URL中&#xff0c;空格通常被编码为 或 %20。因此&#xff0c;如果你在请求参数中使用 &#xff0c;它会被解释为一个空格。 如果…

C++ | Leetcode C++题解之第473题火柴拼正方形

题目&#xff1a; 题解&#xff1a; class Solution { public:bool makesquare(vector<int>& matchsticks) {int totalLen accumulate(matchsticks.begin(), matchsticks.end(), 0);if (totalLen % 4 ! 0) {return false;}int len totalLen / 4, n matchsticks.s…

lstm和informer和gru模型对比

1 介绍 本文使用数据集&#xff0c;对三个模型进行了对比&#xff0c;代码使用python完成&#xff0c;通过对比&#xff0c;发现lstm>gru>informer. 2 数据读取 使用降水量数据集&#xff0c;第一列表示降水&#xff0c;第二列表示出水量。 输入是两个特征输出是一个…

百度视觉搜索架构演进实践

本文深入探讨百度视觉搜索在快速发展的业务及技术背景下&#xff0c;如何通过持续的技术创新和架构升级强化自身的竞争力和适应性&#xff0c;支撑业务健康高效迭代。本文介绍了我们如何通过技术栈升级、架构能力提升以及稳定性建设&#xff0c;来实现全链路架构的演进。借助Go…

MySQL 9从入门到性能优化-二进制日志

【图书推荐】《MySQL 9从入门到性能优化&#xff08;视频教学版&#xff09;》-CSDN博客 《MySQL 9从入门到性能优化&#xff08;视频教学版&#xff09;&#xff08;数据库技术丛书&#xff09;》(王英英)【摘要 书评 试读】- 京东图书 (jd.com) MySQL9数据库技术_夏天又到了…