โคมไฟ AZIMUT: เชื่อมต่อทิศทางถึงสถานที่ที่คุณผูกพัน
สวัสดีชาว Maker ทุกคนครับ! วันนี้เรามีโปรเจกต์ที่ทั้งล้ำและโรแมนติกสุดๆ มาฝาก นั่นคือ AZIMUT Lamp โคมไฟที่ไม่ได้มีไว้แค่ส่องสว่าง แต่ทำหน้าที่คล้าย "เข็มทิศ" ที่คอยชี้ไปยังสถานที่ที่มีความหมายสำหรับคุณครับ[cite: 7, 8]
คอนเซปต์ของมันเรียบง่ายแต่ลึกซึ้ง: คุณแค่วางวัตถุที่มีความทรงจำ (เช่น ก้อนหินจากบ้านเกิด, พวงกุญแจ, หรือเปลือกหอย) ลงบนโคมไฟ จากนั้นใช้มือถือเลือกพิกัดปลายทางบนแผนที่ เมื่อคุณหมุนโคมไฟจนชี้ตรงกับทิศทาง (Azimuth) ของสถานที่นั้น... ไฟก็จะสว่างขึ้นทันที! [cite: 11, 12, 13, 14]
อุปกรณ์ที่ต้องใช้ (Supplies) 🧰
โปรเจกต์นี้เป็นการผสมผสานระหว่างงาน 3D Printing, วงจรอิเล็กทรอนิกส์ และ Web App ครับ[cite: 18, 19, 21, 35]
สมองกล: บอร์ด ESP32-C3 Mini หรือ SuperMini[cite: 37]
เซนเซอร์ตรวจจับองศา: โมดูลมุมแม่เหล็ก AS5600 + แม่เหล็กกลม[cite: 38, 39]
ระบบแสง: ไดรเวอร์หลอดไฟ LD06AJSA และหลอด LED 1W (Warm white)[cite: 40, 41]
ของเล่นเสริม: NFC Tag (สติกเกอร์) สำหรับแตะเปิดแอป[cite: 42]
โครงสร้าง: อะลูมิเนียมตัว U ขนาด 10มม. และชิ้นส่วน 3D Print[cite: 48, 50]
💡 Maker's Tip: การทำโคมไฟหมุนได้แบบนี้ จำเป็นต้องใช้เซนเซอร์วัดองศาที่แม่นยำอย่าง AS5600 ควบคู่กับไมโครคอนโทรลเลอร์ที่มี Wi-Fi ในตัวอย่าง ESP32-C3 ครับ หากเพื่อนๆ กำลังหาอุปกรณ์ลุยโปรเจกต์ แวะมาช้อป บอร์ด ESP32, เซนเซอร์ AS5600, โมดูลไฟ LED ของแท้ได้ที่ร้านเราเลยครับ! และถ้าใครไม่มีเครื่องพิมพ์ 3 มิติ ทาง Globalbyte Shop ของเราก็มี บริการรับปริ้นท์ 3D (3D Printing Service) ให้ด้วย ส่งไฟล์มาให้เราจัดการได้เลยครับ!
ขั้นตอนการสร้างแบบคร่าวๆ (Step-by-Step) 🛠️
พิมพ์ชิ้นส่วน 3D (3D Print): โครงสร้างหลักประกอบด้วยฐาน, จานหมุน (Lazy Susan), ที่วางวัตถุ, ข้อต่อ, และเข็มทิศ แนะนำให้ใช้ PLA Infill 30%[cite: 81-87]
ต่อวงจรอิเล็กทรอนิกส์: ต่อเซนเซอร์ AS5600 เข้ากับ ESP32-C3 ผ่านพิน I2C (SDA=2, SCL=10) และต่อไดรเวอร์ LED ควบคุมการเปิด/ปิดผ่านพิน GPIO5[cite: 98-106]
ประกอบฐาน (Base Assembly): ยัดบอร์ดและเซนเซอร์ลงในฐานที่พิมพ์ไว้ โดยให้ "แม่เหล็ก" อยู่ตรงกลางเหนือชิป AS5600 พอดี (เว้นระยะห่างเล็กน้อยอย่าให้สีกัน)[cite: 609-616]
ประกอบแขนโคมไฟ: ตัดอะลูมิเนียมตัว U แล้วใช้ค้อนยางเคาะเข้ากับพิมพ์ 3D เพื่อดัดให้เป็นรูปทรงสามเหลี่ยม ร้อยสายไฟให้เรียบร้อย[cite: 626-641]
ตั้งค่าแอปพลิเคชัน & NFC: อัปโหลดโค้ดลง ESP32 จากนั้นเอา URL ของ Web App (ที่ใช้หาองศาแผนที่) ไปเขียนลงสติกเกอร์ NFC แปะไว้ที่ฐานโคมไฟ[cite: 1128-1132]
เพียงเท่านี้ เวลาจะใช้งานก็แค่ เอามือถือแตะที่ฐาน -> เลือกสถานที่บนแผนที่ -> ค่อยๆ หมุนโคมไฟ -> ไฟสว่าง! เป็นกิมมิกตั้งโต๊ะที่เท่ไม่ซ้ำใครแน่นอนครับ[cite: 1145-1152]
⚠️ คำเตือนเรื่องการใช้ไฟ
โปรเจกต์นี้ออกแบบมาให้ใช้ไฟ 5V จากสาย USB เท่านั้น ห้ามนำไปต่อกับไฟบ้าน (Mains voltage) โดยตรงเด็ดขาด! และหลอด LED 1W จะมีความร้อนสูง ไม่ควรเปิดค้างไว้นานๆ โดยไม่มีฮีตซิงก์ระบายความร้อนครับ[cite: 74, 75, 602]
▼ เปิดดูภาพประกอบ, วิดีโอ, โค้ด และไฟล์ 3D ▲ ซ่อนรายละเอียดทั้งหมด
วิดีโอสาธิตการทำงานหลัก 🎬
VIDEO
1. ภาพรวมอุปกรณ์และวงจร 🔌
2. การพิมพ์และประกอบชิ้นส่วน 3D 🖨️
วิดีโอสาธิตการพับอะลูมิเนียม (Step 4) 🎬
VIDEO
3. การใช้งาน Web App และ NFC 📱
วิดีโอสาธิตการใช้ Web App และ NFC 🎬
VIDEO
ดาวน์โหลดไฟล์ 3D (STL Files) 📥
โค้ดโปรแกรมฉบับเต็ม (Arduino C++) 💻
คัดลอกโค้ดนี้ไปเบิร์นลงบอร์ด ESP32-C3 ของคุณได้เลยครับ:
Copy Code
#include <WiFi.h>
#include <WebServer.h>
#include <Wire.h>
#include <Preferences.h>
#define SDA_PIN 2
#define SCL_PIN 10
#define LED_CE_PIN 5
#define AS5600_ADDR 0x36
#define AS5600_RAW_ANGLE_H 0x0C
const char* AP_SSID = "AZIMUT-LAMP";
const char* AP_PASS = ""; // Open Wi-Fi, no password
WebServer server(80);
Preferences prefs;
const int PWM_FREQ = 1000;
const int PWM_RES = 8;
const int PWM_MAX = 255;
const float FULL_ON_DEG = 3.0;
const float FADE_OUT_DEG = 35.0;
float targetAngleDeg = 0.0;
bool calibrated = false;
float normalizeDeg(float a) {
while (a < 0) a += 360.0;
while (a >= 360.0) a -= 360.0;
return a;
}
float angleDiffDeg(float a, float b) {
float d = a - b;
while (d > 180.0) d -= 360.0;
while (d < -180.0) d += 360.0;
return d;
}
bool as5600Present() {
Wire.beginTransmission(AS5600_ADDR);
return Wire.endTransmission() == 0;
}
float readAS5600Deg() {
Wire.beginTransmission(AS5600_ADDR);
Wire.write(AS5600_RAW_ANGLE_H);
if (Wire.endTransmission(false) != 0) return -1;
Wire.requestFrom(AS5600_ADDR, (uint8_t)2);
if (Wire.available() < 2) return -1;
uint8_t high = Wire.read();
uint8_t low = Wire.read();
uint16_t raw = ((high & 0x0F) << 8) | low;
return raw * 360.0 / 4096.0;
}
void setLed(int pwm) {
pwm = constrain(pwm, 0, PWM_MAX);
ledcWrite(LED_CE_PIN, pwm);
}
int computeLedPWM(float currentDeg) {
if (!calibrated) return 0;
float diff = abs(angleDiffDeg(currentDeg, targetAngleDeg));
if (diff <= FULL_ON_DEG) return PWM_MAX;
if (diff >= FADE_OUT_DEG) return 0;
float t = (FADE_OUT_DEG - diff) / (FADE_OUT_DEG - FULL_ON_DEG);
t = t * t * (3.0 - 2.0 * t);
return round(t * PWM_MAX);
}
// ... (ส่วนการตั้งค่า HTML String / Web Server Functions ถูกละไว้เพื่อความกระชับ) ...
void setup() {
Serial.begin(115200);
delay(1200);
pinMode(LED_CE_PIN, OUTPUT);
digitalWrite(LED_CE_PIN, LOW);
Wire.begin(SDA_PIN, SCL_PIN);
Wire.setClock(100000);
ledcAttach(LED_CE_PIN, PWM_FREQ, PWM_RES);
setLed(0);
prefs.begin("azimut", false);
calibrated = prefs.getBool("calibrated", false);
targetAngleDeg = prefs.getFloat("target", 0.0);
WiFi.mode(WIFI_AP);
WiFi.softAP(AP_SSID);
// server.on("/", HTTP_GET, handleRoot);
// server.on("/calibrate", HTTP_GET, handleCalibrate);
// server.on("/reset", HTTP_GET, handleReset);
// server.on("/status", HTTP_GET, handleStatus);
server.begin();
}
void loop() {
server.handleClient();
float currentDeg = readAS5600Deg();
if (currentDeg < 0) {
setLed(0);
return;
}
int pwm = computeLedPWM(currentDeg);
setLed(pwm);
}
📚 แหล่งข้อมูลศึกษาเพิ่มเติม:
*คำเตือนและข้อแนะนำ: เนื้อหาบทความนี้สรุปและแปลมาจากคู่มือของต่างประเทศ โค้ดโปรแกรมในบทความได้ถูกย่อเพื่อให้เห็นโครงสร้างหลัก หากต้องการคัดลอกโค้ด Web Server ฉบับเต็มพร้อม HTML และ JavaScript แนะนำให้ดาวน์โหลดจากหน้า Instructables ต้นฉบับครับ