مقدمه
به کمک ارتباط بیسیم WiFi یک شبیه ساز آتش بسازید! یک اپلیکیشن تلفن همراه (برای گوشیهای هوشمند اندروید) با رابطه کاربری جذاب آماده است تا به کمک آن ساختهی خود را کنترل کنید. همجنین از آردینو و ESP8266 برای کنترل شعله آتش استفاده میکنیم.
آن چه در این آموزش یاد میگیرید
- نئوپیکسل چگونه کار میکند.
- چگونه ESP8266 را برای کنترل متغیرهای WiFi برنامه ریزی کنید.
- چگونه با استفاده از نئوپیکسل یک شبیه ساز آتش بسازید.
آشنایی با نئوپیکسل
نئوپیکسلها مدت زیادی است که در بازار هستند و شما احتمالا آنها را میشناسید. اما اگر نمیشناسید نئوپیکسلها مانند ال ای دی های RGB هستند اما با این تفاوت که هر هر ال ای دی به طور جداگانه قابل تنظیم میباشد. این قابلیت باعث میشود که بتوان هزاران الگوی جالب به کمک نئوپیکسلها ایجاد کرد. برای WS2812b شما فقط به 3 سیم نیاز دارید، 2 سیم برای تغذیه و 1 سیم برای داده. این به این معنی است که شما فقط با یک پین آردوینو میتوانید تعداد زیادی ال ای دی را کنترل کنید.
در این پروژه ما قصد داریم از این LED های هوشمند برای ایجاد یک شبیه ساز آتش استفاده کنیم. برای کنترل LED ها از کتابخانه FastLED استفاده میکنیم. با مثال Fire2012 از کتابخانه ای که توسط مارک کریگسمن نوشته شده است شروع میکنیم. از 6 نوار LED که هر کدام دارای 30 LED (مجموع 180 LED) است استفاده می کنیم. 6 نوار LED که هر کدام دارای 30 LED (مجموع 180 LED) است را بر روی یک قطعه لوله PVC قرار داده و آنها را در یک سیلندر شیشه قرار می دهیم (این سیلندرهای شیشه ای معمولا به عنوان گلدان ها استفاده می شود). ما باید نور LED ها را پخش کنیم تا آنها را مداوم ببینیم، برای این کار از کاغذ ردیابی استفاده کردیم که نور را عبور داده و منتشر میکند.
لوازمی که با آن احتیاج دارید
قطعات مورد نیاز
نرم افزارهای مورد نیاز
ابزارهای مورد نیاز
چسب حرارتی |
هویه |
مراحل ساخت
برای اتصال نوارهای LED به هم می توانید یا به طور مستقیم نوارها را مانند شکل زیر یه هم لحیم کنید، یا ابتدا به نوارها پین هدر لحیم کنید و سپس به کمک یسم برد بورد آنها را به هم متصل کنید.
کد
برای کدنویسی و آپلود آن روی برد از Arduino IDE استفاده میکنیم. اگر میخواهید فایلهای نرم افزاری کنترلر را روی SPIFFS آپاود کنید، باید از بردی استفاده کنید که یک ESP8266 با 3MB از SPIFFS داشته باشد. شما میتوانید فایلهای کنترلر را روی SPIFFS که مخفف “Serial Peripheral Interface Flash File System” میباشد آپلود کنید تا در ادامه فایلها را از آن محل اجرا کنید. با انجام این کار می توانید مرورگر خود را (یا بر روی گوشی یا نوت بوک خود) باز کنید و آدرس ESP خود را وارد کنید (به طور پیش فرض 192.168.4.1 است) و رابط کنترل را در مرورگر خود بدون نیاز به نصب برنامه دریافت کنید، اگر شما آیفون یا iPad دارید این تنها انتخاب شماست.
کد زیر را روی برد ESP خود آپلود کنید. برای این کار به کتابخانه FastLED نیاز دارید، بنابراین ابتدا آن را به IDE Arduino خود اضافه کنید.(شما می توانید آن را اینجا دانلود کنید). کد شبیه سازی آتش، طرح Score2012 مارک Kriegsman است که میتوانید آن را در مثالها ببینید. این مثال برای یک نوار LED نوشته شده است، اما در اینجا ما کد را برای استفاده از تعداد متغیر نوارها اصلاح کردیم. هر چه تعداد نوارها بیشتر باشد نتیجهی بهتری خواهید داشت. منطق شبیه سازی آتش به وضوح در فایل مثال نشان داده شده است.اگر می خواهید بدانید که این کد چگونه کار می کند، کد منبع این مثال را مطالعه کنید.
فایلهای مورد نیاز:
EP’s Flame Android App
#include "ESP8266WiFi.h"
#include "ESP8266WebServer.h"
#include "FastLED.h"
#include "EEPROM.h"
#include "FS.h" //required for SPIFFS
#define DATA_PIN 5
#define LED_TYPE WS2811
#define COLOR_ORDER GRB
#define NUM_LEDS 30
#define NUM_STRIPS 6
#define CHIPSET WS2812B
//addresses to save data to EEPROM to preserve the state of fire simulation
#define cs0Adr 0
#define cs1Adr 3
#define cs2Adr 6
#define cs3Adr 9
#define BriAdr 15
#define FpsAdr 16
#define SparkingAdr 17
#define CoolingAdr 18
#define EEPROMCheckAdr 20 //if this value is 250 we assume we have previously saved to EEPROM and load data from that
CRGB leds[NUM_STRIPS * NUM_LEDS];
String inData;
uint8_t FPS = 100; //FRAMES_PER_SECOND
uint8_t SPARKING = 150;
uint8_t COOLING = 90;
uint8_t BRIGHTNESS = 100;
uint8_t csRGB[4][3] = {{0, 0, 0},
{255, 0, 0},
{255, 127, 0},
{255, 255, 255}};
unsigned long previousMillis = 0;
bool change = false; //if true we go to save to EEprom.
unsigned long changeMillis = 0; //changes will be saved 1 minute after no change is applied to avoid EEPROM wear.
bool initSetup = true;
CRGBPalette16 gPal;
ESP8266WebServer server(80); //Web server object. Will be listening in port 80 (default for HTTP)
void setup()
{
EEPROM.begin(200);
cWiFi();
setupFastLED();
loadConfig();
gPal = CRGBPalette16( CRGB(csRGB[0][0],csRGB[0][1],csRGB[0][2]),
CRGB(csRGB[1][0],csRGB[1][1],csRGB[1][2]),
CRGB(csRGB[2][0],csRGB[2][1],csRGB[2][2]),
CRGB(csRGB[3][0],csRGB[3][1],csRGB[3][2]));
}
inline void setupFastLED()
{
delay(1000); // sanity delay
FastLED.addLeds<CHIPSET, DATA_PIN, COLOR_ORDER>(leds, NUM_STRIPS * NUM_LEDS).setCorrection(TypicalLEDStrip);
FastLED.setBrightness(BRIGHTNESS);
}
void loop()
{
server.handleClient(); //Handling of incoming requests
if (change)
{
if (millis() - changeMillis > 60000)
{
change = false;
saveToEEPROM();
}
}
fire();
FastLED.show();
FastLED.delay(1000 / FPS);
}
void Fire2012WithPalette(int stripNo)
{
static byte heat[NUM_STRIPS][NUM_LEDS];
// Step 1. Cool down every cell a little
for( int i = 0; i < NUM_LEDS; i++) { heat[stripNo][i] = qsub8( heat[stripNo][i], random8(0, ((COOLING * 10) / NUM_LEDS) + 2)); }
// Step 2. Heat from each cell drifts 'up' and diffuses a little
for( int k= NUM_LEDS - 1; k >= 2; k--) {
heat[stripNo][k] = (heat[stripNo][k - 1] + heat[stripNo][k - 2] + heat[stripNo][k - 2] ) / 3;
}
// Step 3. Randomly ignite new 'sparks' of heat near the bottom
if( random8() < SPARKING ) {
int y = random8(5);
heat[stripNo][y] = qadd8( heat[stripNo][y], random8(160,200) );
}
// Step 4. Map from heat cells to LED colors
for( int j = 0; j < NUM_LEDS; j++) {
// Scale the heat value from 0-255 down to 0-240
// for best results with color palettes.
byte colorindex = scale8( heat[stripNo][j], 240);
CRGB color = ColorFromPalette( gPal, colorindex);
leds[j+stripNo*NUM_LEDS] = color;
}
}
void fire(){
for (int i=0; i<NUM_STRIPS; i++){ Fire2012WithPalette(i); } } int str2int(String InputStr) { return InputStr.toInt(); } boolean EveryNSec(uint8_t period) { unsigned long currentMillis = millis(); if (currentMillis - previousMillis >= period * 1000)
{
// save the last time you blinked the LED
previousMillis = currentMillis;
return true;
}
else
{
return false;
}
}
void EEPROMupdate(byte address, byte value)
{
if (EEPROM.read(address) != value)
{
EEPROM.write(address, value);
EEPROM.commit();
}
return;
}
void saveToEEPROM()
{
EEPROMupdate(BriAdr, BRIGHTNESS);
EEPROMupdate(FpsAdr, FPS);
EEPROMupdate(SparkingAdr, SPARKING);
EEPROMupdate(CoolingAdr, COOLING);
for (uint8_t i = 0; i < 4; i++)
{
for (uint8_t j = 0; j < 3; j++)
{
EEPROMupdate((i * 3 + j), csRGB[i][j]);
}
}
}
void handleCS0Change(){
csRGB[0][0] = str2int(server.arg("R"));
csRGB[0][1] = str2int(server.arg("G"));
csRGB[0][2] = str2int(server.arg("B"));
gPal = CRGBPalette16( CRGB(csRGB[0][0],csRGB[0][1],csRGB[0][2]), CRGB(csRGB[1][0],csRGB[1][1],csRGB[1][2]), CRGB(csRGB[2][0],csRGB[2][1],csRGB[2][2]), CRGB(csRGB[3][0],csRGB[3][1],csRGB[3][2]));
changeMillis = millis();
change = true;
}
void handleCS1Change(){
csRGB[1][0] = str2int(server.arg("R"));
csRGB[1][1] = str2int(server.arg("G"));
csRGB[1][2] = str2int(server.arg("B"));
gPal = CRGBPalette16( CRGB(csRGB[0][0],csRGB[0][1],csRGB[0][2]), CRGB(csRGB[1][0],csRGB[1][1],csRGB[1][2]), CRGB(csRGB[2][0],csRGB[2][1],csRGB[2][2]), CRGB(csRGB[3][0],csRGB[3][1],csRGB[3][2]));
changeMillis = millis();
change = true;
}
void handleCS2Change(){
csRGB[2][0] = str2int(server.arg("R"));
csRGB[2][1] = str2int(server.arg("G"));
csRGB[2][2] = str2int(server.arg("B"));
gPal = CRGBPalette16( CRGB(csRGB[0][0],csRGB[0][1],csRGB[0][2]), CRGB(csRGB[1][0],csRGB[1][1],csRGB[1][2]), CRGB(csRGB[2][0],csRGB[2][1],csRGB[2][2]), CRGB(csRGB[3][0],csRGB[3][1],csRGB[3][2]));
changeMillis = millis();
change = true;
}
void handleCS3Change(){
csRGB[3][0] = str2int(server.arg("R"));
csRGB[3][1] = str2int(server.arg("G"));
csRGB[3][2] = str2int(server.arg("B"));
gPal = CRGBPalette16( CRGB(csRGB[0][0],csRGB[0][1],csRGB[0][2]), CRGB(csRGB[1][0],csRGB[1][1],csRGB[1][2]), CRGB(csRGB[2][0],csRGB[2][1],csRGB[2][2]), CRGB(csRGB[3][0],csRGB[3][1],csRGB[3][2]));
changeMillis = millis();
change = true;
}
void handleConf()
{
if (server.arg("brightness") != "")
{
BRIGHTNESS = str2int(server.arg("brightness"));
FastLED.setBrightness(BRIGHTNESS);
changeMillis = millis();
change = true;
}
if (server.arg("fps") != "")
{
FPS = str2int(server.arg("fps"));
changeMillis = millis();
change = true;
}
if (server.arg("sparking") != "")
{
SPARKING = str2int(server.arg("sparking"));
changeMillis = millis();
change = true;
}
if (server.arg("cooling") != "")
{
COOLING = str2int(server.arg("cooling"));
changeMillis = millis();
change = true;
}
server.sendHeader("Connection", "close");
server.sendHeader("Access-Control-Allow-Origin", "*");
server.send(200, "text/plain", ""); //Returns the HTTP response
}
void loadConfig()
{
if (EEPROM.read(EEPROMCheckAdr) == 250)
{
BRIGHTNESS = EEPROM.read(BriAdr);
SPARKING = EEPROM.read(SparkingAdr);
COOLING = EEPROM.read(CoolingAdr);
FPS = EEPROM.read(FpsAdr);
if (FPS == 0)
FPS = 100;
for (uint8_t i = 0; i < 4; i++)
{
for (uint8_t j = 0; j < 3; j++)
{
csRGB[i][j] = EEPROM.read(i * 3 + j);
}
}
}else{
EEPROMupdate(BriAdr,BRIGHTNESS);
EEPROMupdate(FpsAdr,FPS);
EEPROMupdate(CoolingAdr,COOLING);
EEPROMupdate(SparkingAdr, SPARKING);
for (uint8_t i = 0; i < 4; i++)
{
for (uint8_t j = 0; j < 3; j++)
{
EEPROMupdate((i*3+j) , csRGB[i][j]);
}
}
EEPROMupdate(EEPROMCheckAdr, 250);
}
}
void cWiFi()
{
WiFi.softAP("ElectroPeak's Flame", ""); //set a password here if you want i.e. WiFi.softAP("ElectroPeak's Flame", "12345678");
IPAddress myIP = WiFi.softAPIP();
server.on("/cs0", handleCS0Change);
server.on("/cs1", handleCS1Change);
server.on("/cs2", handleCS2Change);
server.on("/cs3", handleCS3Change);
server.on("/conf", handleConf);
server.serveStatic("/", SPIFFS, "/", "max-age=86400");
server.begin(); //Start the server
}
چگونه روی SPIFFS آپلود کنیم؟
شبیه ساز آتش چگونه کار می کند؟
برنامه آپلود شده روی ESP8266 یک وب سرور روی سیستم ایجاد می کند که به درخواست ارسال شده از اپلیکیشن، پاسخ می دهد. اپلیکیشن به سادگی درخواست های GET را بع سرور(ESP8266) ارسال می کند. اطلاعات رنگ برای ساخت پالت بعنوان یک آرگومان در درخواست GET ارسال می شود، برای پارامترهای دیگر نظیر SPARKING و COOLING نیز همین روند تکرار می شود.
برای مثال برای تنظیم شدت روشنایی، درخواست زیر توسط اپلیکیشن ارسال می شود:
http://192.168.4.1/conf?brightness=224
در برنامه آردوینو الگوریتمی وجود دارد که وقتی درخواست بالا دریافت شد، شدت روشنایی را متناسب با درخواست تغییر دهد. برای اطلاعات بیشتر کد را مطالعه کنید.
اپلیکیشن اندروید
اپلیکیشن اندروید با استفاده از Phonegap طراحی شده که به شما اجازه می دهد اپلیکیشن های موبایلی را با تکنولوژی های وب(HTML, CSS, Javascript) طراحی کنید.
می توانید سورس کد این اپلیکیشن را از لینک زیر دانلود کنید:
Comments (3)
سلام خسته نباشید من این ارور را دارم میشه راهنمایی کنید؟
Arduino: 1.8.13 (Windows 10), Board: “Generic ESP8285 Module, 80 MHz, Flash, Legacy (new can return nullptr), All SSL ciphers (most compatible), dtr (aka nodemcu), 26 MHz, 1MB (FS:64KB OTA:~470KB), 2, v2 Lower Memory, Disabled, None, Only Sketch, 115200”
In file included from C:\Users\Ali\AppData\Local\Temp\arduino_modified_sketch_303853\BasicHttpClient.ino:3:0:
C:\Users\Ali\Documents\Arduino\libraries\FastLED\src/FastLED.h:14:21: note: #pragma message: FastLED version 3.004.000
# pragma message “FastLED version 3.004.000”
^
In file included from C:\Users\Ali\Documents\Arduino\libraries\FastLED\src/FastLED.h:65:0,
from C:\Users\Ali\AppData\Local\Temp\arduino_modified_sketch_303853\BasicHttpClient.ino:3:
C:\Users\Ali\Documents\Arduino\libraries\FastLED\src/fastspi.h:135:23: note: #pragma message: No hardware SPI pins defined. All SPI access will default to bitbanged output
# pragma message “No hardware SPI pins defined. All SPI access will default to bitbanged output”
^
C:\Users\Ali\AppData\Local\Temp\arduino_modified_sketch_303853\BasicHttpClient.ino: In function ‘void setup()’:
BasicHttpClient:51:3: error: ‘c’ was not declared in this scope
c.WiFi();
^
BasicHttpClient:53:14: error: ‘loadConfig’ was not declared in this scope
loadConfig();
^
C:\Users\Ali\AppData\Local\Temp\arduino_modified_sketch_303853\BasicHttpClient.ino: In function ‘void loop()’:
BasicHttpClient:77:20: error: ‘saveToEEPROM’ was not declared in this scope
saveToEEPROM();
^
BasicHttpClient:80:8: error: ‘fire’ was not declared in this scope
fire();
^
C:\Users\Ali\AppData\Local\Temp\arduino_modified_sketch_303853\BasicHttpClient.ino: In function ‘void Fire2012WithPalette(int)’:
BasicHttpClient:92:21: error: ‘k’ was not declared in this scope
heat[stripNo][k] = (heat[stripNo][k – 1] + heat[stripNo][k – 2] + heat[stripNo][k – 2] ) / 3;
^
C:\Users\Ali\AppData\Local\Temp\arduino_modified_sketch_303853\BasicHttpClient.ino: At global scope:
BasicHttpClient:96:5: error: expected unqualified-id before ‘if’
if( random8() < SPARKING ) {
^
BasicHttpClient:102:5: error: expected unqualified-id before 'for'
for( int j = 0; j < NUM_LEDS; j++) {
^
BasicHttpClient:102:21: error: 'j' does not name a type
for( int j = 0; j < NUM_LEDS; j++) {
^
BasicHttpClient:102:35: error: 'j' does not name a type
for( int j = 0; j Preferences.
سلام این کد ها را میشه با گوشی وارد کرد یا فقط سیستم میتواند کد را اجرا کند اگر امکان اجرا کد با گوشی امکان پذیر است لطفا راهنمایی کنید ممنون لطفا
با سلام
در صورتی که منظور شما از پروگرام کردن برد می باشد، یکسری برنامه اندرویدی برای این قضیه وجود دارد ولی اکثرا به دلیل محدودیت هایی که دارند پیشنهاد نمیکنم و بهتر از یک سیستم برای این کار استفاده کنید.
اگر منظور شما از صفحه وبی که در آن تغییرات داده میشود را مد نظر دارید، فرقی نمیکند که چه گوشی باشد یا سیستم فقط کافی است صفحه مورد نظر را داخل مرورگر مورد نظر خود باز کنید.