Translate

bloggerads內文

2017年11月2日 星期四

IOT - DIY使用 NodeMcu(ESP8266) 控制LED

之前有介紹一篇是使用firebase來做IOT開關的文章,身為一個開發者要多方發展,所以這次我就利用空檔時間,來做一個裝置並用IOS來做LED 開關控制,之後可以接上繼電器做一般家電的電源的開關或是其他應用sensor感測回傳等等:



成果:


前置作業:

電子材料:麵包板,單芯線,LED燈,NodeMcu(ESP8266)
裝置溝通:MQTT , Socket
電腦:主要是架MQTT Server使用的(小編使用的是MAC)

流程思路:
1.讓裝置接上電源
2.在IOS上輸入 WIFI 的帳號及密碼,使裝置可以連接WIFI
3.輸入錯誤重新輸入,直到驗證正確
4.在IOS做開關,使LED燈亮

程式碼:

1.NodeMcu(Arduino) 不專業程式碼:

#include <ESP8266WiFi.h>
#include <PubSubClient.h>
#include <SoftwareSerial.h>

const char* mqtt_server = " ";//輸入MQTT Server
//const char* mqtt_server = "iot.eclipse.org";


WiFiClient espClient,clients;
PubSubClient client(espClient);
WiFiServer server(5000); //Initialize the server on Port 5000
int flag1=1,flag2=0,flag3=0; //待會往下看就知道為什麼要有3個flag,這是當作開關使用
long lastMsg = 0;
char msg[50];
int value = 0;
const char *array[5]; //array是拿來放資料
int i = 0;
int t = 0;
 
void setup_wifi() {

  delay(100);
  // We start by connecting to a WiFi network
    Serial.print("Connecting to ");
    WiFi.begin(array[0], array[1]);
    while (WiFi.status() != WL_CONNECTED)
    {
      delay(1000);
      Serial.print(".");
      t++;
   
      if(t==10){
         WiFi.mode(WIFI_AP); //讓ESP8266變成AP mode
         WiFi.softAP("Simple Care", ""); // 一開始ESP8266變成AP的名稱
         IPAddress myIP = WiFi.softAPIP();
         Serial.println();
         Serial.print("AP IP address: ");
         Serial.println(myIP);
         server.begin(); // Start the HTTP Server
        flag1=1;
        flag2=0;
        t=0;
        break;
      }
    }

    if(WiFi.status() == WL_CONNECTED){
      flag1=0;
      flag2=0;
      flag3=1;
       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("Command is :  ");
  Serial.print(topic);
  int p =(char)payload[0]-'0';
  if(p==0)
  {
    digitalWrite(15,LOW);
    Serial.println(" close Light");
  }
  // if MQTT comes a 1 message, show temperature
  if(p==1)
  {
  digitalWrite(15,HIGH);
 Serial.println(" open Light");
  }
  Serial.println();
} //end callback

void reconnect() {
  // Loop until we're reconnected
  while (!client.connected())
  {
    Serial.print("Attempting MQTT connection...");
    // Create a random client ID
    String clientId = "ESP8266Client-";
    clientId += String(random(0xffff), HEX);
    // Attempt to connect
    //if you MQTT broker has clientID,username and password
    //please change following line to    if (client.connect(clientId,userName,passWord))
    if (client.connect(clientId.c_str()))
    {
      Serial.println("connected");
     //once connected to MQTT broker, subscribe command if any
      client.subscribe("OsoyooCommand");
    } else {
      Serial.print("failed, rc=");
      Serial.print(client.state());
      Serial.println(" try again in 5 seconds");
      // Wait 6 seconds before retrying
      delay(6000);
    }
  }
} //end reconnect()

void setup() {
  Serial.begin(115200);
   pinMode(15,OUTPUT);
   Serial.println();
  Serial.print("Configuring access point...");
  WiFi.mode(WIFI_AP); //讓ESP8266變成AP mode
  WiFi.softAP("NodeMcu", ""); // 一開始ESP8266變成AP的名稱
  IPAddress myIP = WiFi.softAPIP();
  Serial.println();
  Serial.print("AP IP address: ");
  Serial.println(myIP);
  server.begin(); // Start the HTTP Server

}

void loop() {

     if(flag1==1){
           WiFiClient clients = server.available();
           server.write("等待連接");
           if (!clients) {
               delay(3000);
               Serial.println(" client not connected");
              return;
            }
       // Check if a client has connected
   
      // 如果手機與裝置連上了,就show個new client連進來了
       Serial.println("new client");
       while(!clients.available()){
         delay(1);
       }

    // Read the first line of the request
    String req = clients.readString();
    char charBuf[50];//for string to char
    int req_len = req.length() + 1;
    req.toCharArray(charBuf, req_len);
    Serial.println(charBuf);
    clients.flush();
   //以下是把手機送來的socket用strok切割放入array的陣列裡
    char *p = strtok (charBuf,",");
    while (p != NULL)
    {
        array[i++] = p;
        p = strtok (NULL,",");
    }
   
    WiFi.disconnect();
    WiFi.softAPdisconnect(true);
    WiFi.mode(WIFI_OFF);

    flag1=0;
    flag2=1;
  }


   if (flag2==1)
   {

    Serial.println("array[0]=");//
    Serial.println(array[0]);//印出android第一個值,拿來Debug用
    Serial.println("array[1]=");//
    Serial.println(array[1]); //印出android第二個值,拿來Debug用
 
    //WiFi.mode(WIFI_STA);//讓ESP8266變成Station mode
    setup_wifi();

    client.setServer(mqtt_server, 1883);
    client.setCallback(callback);

 
   }

  if(flag3==1){
     if (!client.connected()) {
      reconnect();
    }
      client.loop();
      long now = millis();
     // read DHT11 sensor every 6 seconds
    if (now - lastMsg > 6000) {
     
    }
     client.publish("OsoyooData", "from ESP8266");
  }
 
}



2.IOS 範例:如有需要再跟我說


結論:從無到有終於做好了,平常就在忙著寫專案,只能有空寫一點,雖然有很多地方可以修正,
但主要也是了解IOT的運用,或許到業界可以看到更專業的寫法吧,以上就介紹給有需要的人嚕,


1 則留言:

  1. 可以提供NodeMcu(ESP8266) 控制LED IOS 範例給我參考嗎?

    回覆刪除