柴火创客社区 · 10月17日 · 广东

创客项目秀|基于XIAO ESP32C3的Night Lamp项目

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

项目介绍

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

材料清单

电子元件数量价格
LED灯带1$34.9
XIAO ESP32C31$4.99
Grove DHT111$5
CONN HEADER SMD 10芯 1.27MM1$0.88
CONN 接头 SMD R/A 4POS 2.54MM1$0.93
CONN 接头 SMD R/A 3POS 2.54MM1$0.93
轻触开关 SPST-NO 顶部驱动表面贴装1$1.08
LED 蓝色透明 1206 SMD1$0.23
RES 1K 欧姆 1% 1/4W 12061$0.10
RES 499K 欧姆 1% 1/4W 12061$0.10
跳线 F/F 6“ 20PCS1$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 
#include 


#include "DHT.h"

#include 
#ifdef __AVR__
#include   // 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         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);
  }
推荐阅读
关注数
8784
内容数
48
深度服务产业的国际化双创平台
目录
极术微信服务号
关注极术微信号
实时接收点赞提醒和评论通知
安谋科技学堂公众号
关注安谋科技学堂
实时获取安谋科技及 Arm 教学资源
安谋科技招聘公众号
关注安谋科技招聘
实时获取安谋科技中国职位信息