1. 程式人生 > >WiFi-ESP8266入門開發(十九)--手機APP控制和透傳

WiFi-ESP8266入門開發(十九)--手機APP控制和透傳

注:對於ESP8266開源技術感興趣的可以加群,我們一起探索交流學習,群號:579932824。群名:ESP8266開源技術交流群。

1.手機控制

        通過上一篇我們使用了電腦tcp除錯軟體來控制繼電器,今天我們使用手機來控制繼電器,這裡同樣是使用手機除錯軟體和ESP8266接入同一個wifi網路即接同一個路由器,手機開熱點也可以。這裡我們使用的是手機和ESP8266連線同一個路由器。

開啟手機上的網路除錯助手

 

點選配置輸入埠號8266,點選啟用。ps:埠號可以任意取一個,兩邊對應即可

開啟arduino ide修改下程式碼,如下

/*這篇把8266作為TCPcleint,加入手機建立的tcpServer中來控制一個繼電器*/

#include <ESP8266WiFi.h>
   
#define relayPin 2               //繼電器連線在8266的GPIO2上
const char *ssid     = "TP_LINK_6960";//這裡是我的wifi,你使用時修改為你要連線的wifi ssid
const char *password = "123456789";//你要連線的wifi密碼
const char *host = "192.168.191.4";//修改為手機的的tcpServer服務端的IP地址,即手機在路由器上的ip
WiFiClient client;
const int tcpPort = 8266;//修改為你建立的Server服務端的埠號

void setup()
{    
    pinMode(relayPin,OUTPUT);
    Serial.begin(115200);
    delay(10);
    Serial.println();
    Serial.println();
    Serial.print("Connecting to ");//寫幾句提示
    Serial.println(ssid);
   
    WiFi.begin(ssid, password);
   
    while (WiFi.status() != WL_CONNECTED)//WiFi.status() ,這個函式是wifi連線狀態,返回wifi連結狀態
                                         //這裡就不一一贅述它返回的資料了,有興趣的到ESP8266WiFi.cpp中檢視
    {
        delay(500);
        Serial.print(".");
    }//如果沒有連通向串列埠傳送.....
   
    Serial.println("");
    Serial.println("WiFi connected");
    Serial.println("IP address: ");
    Serial.println(WiFi.localIP());//WiFi.localIP()返回8266獲得的ip地址
}
   
   
void loop()
{
    while (!client.connected())//幾個非連線的異常處理
    {
        if (!client.connect(host, tcpPort))
        {
            Serial.println("connection....");
            //client.stop();
            delay(500);
        }
    }
    while (client.available())//available()同ARDUINO,不解釋了
    {
        char val = client.read();//read()同arduino
        if(val=='a'){//pc端傳送a和b來控制
           digitalWrite(relayPin, LOW);
        }
        if(val=='b')
        {
            digitalWrite(relayPin, HIGH);
        }
    }
}

編譯燒寫韌體

 

給ESP8266上電,開啟手機除錯軟體可以看到已經有一個裝置加入網路了
 

傳送我們設定的0和1開關繼電器
 

哈哈,就可以開關繼電器啦。
我也發一個有按鈕的除錯軟體,用法一樣
 

手機設定為服務端,這裡我們使用一個指令控制,改下程式碼就可以了
先申明一個變數來存狀態
boolean ONorOFF=LOW;
在改成
if(val == 1) {
            digitalWrite(2,ONorOFF);
            Serial.print("ON");
            ONorOFF = (!ONorOFF);

這樣就可以一個指令控制了。

2.透傳

       ESP8266叫串列埠wifi模組,那麼透傳肯定不能少,把8266作為透傳同理就是把8266串列埠獲取到的資料無線傳送出去。

改下上面的程式碼即可:

    while (client.available())//改動的就這裡啦,無線讀取到的資料轉發到到串列埠
    {
        uint8_t c = client.read();
        Serial.write(c);
    }
 
 
    if (Serial.available())//串列埠讀取到的轉發到wifi,因為串列埠是一位一位的傳送所以在這裡快取完再發送
    {
        size_t counti = Serial.available();
        uint8_t sbuf[counti];
        Serial.readBytes(sbuf, counti);
        client.write(sbuf, counti);
 
    }

這樣透傳就OK啦,把8266的rx,tx接在其他微控制器的tx,rx上。

3.全域性廣播,無視IP

直接上原始碼:(有的ESP8266模組只能定向傳送)

#include <ESP8266WiFi.h>
#include <WiFiUdp.h>

const char *ssid = "MyWIFI";//這裡是我的wifi,你使用時修改為你要連線的wifi ssid
const char *password = "123123123";//你要連線的wifi密碼
const char *UDPhost = "255.255.255.255";//區域網全網UDP廣播地址,也可以使用你本地網段字尾為255也行,不過適應能力就弱了
WiFiClient client;
const int udpPort = 4321;//修改為你建立的Server服務端的埠號
unsigned int localPort = 3888;//UDP埠偵聽
char packetBuffer[255]; //存放接收到的UDP資料
char  whoamiBuffer[128]="Udp Test01";
char  ReplyBuffer[255] = "I Received packet!";       // 回覆廣播發送者
WiFiUDP Udp;

void setup()
{
  Serial.begin(115200);
  delay(10);
  Serial.println();
  Serial.println();
  Serial.print("Connecting to ");//寫幾句提示,哈哈
  Serial.println(ssid);
  WiFi.begin(ssid, password);//連線WIFI熱點

  while (WiFi.status() != WL_CONNECTED)//WiFi.status() ,這個函式是wifi連線狀態,返回wifi連結狀態
  {
    delay(500);
    Serial.print(".");//如果沒有連通向串列埠傳送.....
  }

  Serial.println("");
  Serial.println("WiFi connected");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());//WiFi.localIP()返回8266獲得的本機ip地址
  long rssi = WiFi.RSSI();
  Serial.print("signal strength (RSSI):");
  Serial.print(rssi);
  Serial.println(" dBm");//整幾個高大上的數字,比如訊號強度啥米的,呵呵

  // 開始UDP埠偵聽
  Udp.begin(localPort);

  //先把自己是誰廣播出去
  Udp.beginPacket(UDPhost, udpPort);
  Udp.write(whoamiBuffer); 
  Udp.endPacket();
  Serial.println(UDPhost);
}
void loop()
{

  //UDP廣播資料到達處理
  int packetSize = Udp.parsePacket();
  if (packetSize) {
    Serial.print("Received packet of size ");
    Serial.println(packetSize);
    Serial.print("From ");
    IPAddress remoteIp = Udp.remoteIP();//獲取遠端廣播包傳送IP
    Serial.print(remoteIp);
    Serial.print(", port ");
    Serial.println(Udp.remotePort());

    // 將到達的資料包讀入packetBufffer
    int len = Udp.read(packetBuffer, 255);
    if (len > 0) {
      packetBuffer[len] = 0;
    }
    Serial.println("Contents:");
    Serial.println(packetBuffer);

    // 回覆資訊給廣播發送IP
    Udp.beginPacket(Udp.remoteIP(), Udp.remotePort());
//    strcat(ReplyBuffer,Udp.remoteIP());
    Udp.write(Udp.remoteIP());
    Udp.write(ReplyBuffer);
    Udp.endPacket();
  }
}