Google Code Prettify

2016年10月21日 星期五

[Arduino + Android]ESP8266 arduino + android studio 設計應用(二)


大家好~ 最近因為朋友有反應之前APP有跳出顯示動窗,不知道該怎樣修改掉,
所以Farmer有修改一下版本

直接PO CODE 讓大家嘗嘗





 ARDUINO CODE]


#include <SoftwareSerial.h>

#define DEBUG true

/*
Farmer使用mega版,所以RXTX使用Serial1(D19、D18)
如果使用uno版可以修改下方註解,因為預設RXTX是電腦燒入時會應用,
所以使用的話,燒入記得要拔除,但怕麻煩,可以改變腳位使用,即可避免燒入衝突。
*/
HardwareSerial& esp8266=Serial1;
//SoftwareSerial esp8266(10,11);

void setup()
{
  Serial.begin(9600);
  esp8266.begin(9600); // esp韌體的胞率,若為115200,請記得修改

  pinMode(13,OUTPUT);
  digitalWrite(13,LOW);
 
  sendCommand("AT+RST\r\n",2000,DEBUG); // reset module
  sendCommand("AT+CWMODE=1\r\n",1000,DEBUG); // configure as access point

  /***************************************************************/
  /*SSID、PASSWD請輸入您要連接的AP(如家中數據機或是手機分享網路),這邊一定要修改*/

  sendCommand("AT+CWJAP=\"SSID\",\"PASSWD\"\r\n",3000,DEBUG);
  delay(5000);

  sendCommand("AT+CIFSR\r\n",1000,DEBUG); // get ip address
  sendCommand("AT+CIPMUX=1\r\n",1000,DEBUG); // configure for multiple connections
  sendCommand("AT+CIPSERVER=1,80\r\n",1000,DEBUG); // turn on server on port 80
  Serial.println("Server Ready");
}

void loop()
{

  String Read,ReadD;
  if(esp8266.available()) // 檢查ESP是否有傳送
  {
    if(esp8266.find("+IPD,"))
    {
      delay(1000);
      int connectionId = esp8266.read()-48;
   
      while(esp8266.available()){
        char inChar = esp8266.read();
        Read = Read + String(inChar);
        if(inChar=='\n'){
          Serial.println("Read: "+Read);
          ReadD = Read.substring(Read.indexOf("?")+1,Read.indexOf("e"));
          Serial.println("ReadD: "+ReadD);
       
          if(ReadD == "13")
            digitalWrite(ReadD, !digitalRead(ReadD)); // toggle pin
          else if(ReadD == "S5")
            for(int val =0;val<11;val++)
            {
              digitalWrite(13, !digitalRead(13));
              delay(200);
            }
        }
      }
      sendHTTPResponse(connectionId,"OK");
    }
  }

}

/*
* Name: sendData
* Description: Function used to send data to ESP8266.
* Params: command - the data/command to send; timeout - the time to wait for a response; debug - print to Serial window?(true = yes, false = no)
* Returns: The response from the esp8266 (if there is a reponse)
*/
String sendData(String command, const int timeout, boolean debug)
{
    String response = "";
 
    int dataSize = command.length();
    char data[dataSize];
    command.toCharArray(data,dataSize);
         
    esp8266.write(data,dataSize); // send the read character to the esp8266
    if(debug)
    {
      Serial.println("\r\n====== HTTP Response From Arduino ======");
      Serial.write(data,dataSize);
      Serial.println("\r\n========================================");
    }
 
    long int time = millis();
    while( (time+timeout) > millis())
    {
      while(esp8266.available())
      {
        // The esp has data so display its output to the serial window
        char c = esp8266.read(); // read the next character.
        response+=c;
      }
    }
 
    if(debug)
    {
      Serial.print(response);
    }
 
    return response;
}

/*
* Name: sendHTTPResponse
* Description: Function that sends HTTP 200, HTML UTF-8 response
*/
void sendHTTPResponse(int connectionId, String content)
{
   
     // build HTTP response
     String httpResponse;
     String httpHeader;
     // HTTP Header
     httpHeader = "HTTP/1.1 200 OK\r\nContent-Type: text/html; charset=UTF-8\r\n";
     httpHeader += "Content-Length: ";
     httpHeader += content.length();
     httpHeader += "\r\n";
     httpHeader +="Connection: close\r\n\r\n";
     httpResponse = httpHeader + content + " "; // There is a bug in this code: the last character of "content" is not sent, I cheated by adding this extra space
     sendCIPData(connectionId,httpResponse);
}

/*
* Name: sendCIPDATA
* Description: sends a CIPSEND=<connectionId>,<data> command
*
*/
void sendCIPData(int connectionId, String data)
{
   String cipSend = "AT+CIPSEND=";
   cipSend += connectionId;
   cipSend += ",";
   cipSend +=data.length();
   cipSend +="\r\n";
   sendCommand(cipSend,1000,DEBUG);
   sendData(data,1000,DEBUG);
}

/*
* Name: sendCommand
* Description: Function used to send data to ESP8266.
* Params: command - the data/command to send; timeout - the time to wait for a response; debug - print to Serial window?(true = yes, false = no)
* Returns: The response from the esp8266 (if there is a reponse)
*/
String sendCommand(String command, const int timeout, boolean debug)
{
    String response = "";
    esp8266.print(command); // send the read character to the esp8266
    long int time = millis();
    while( (time+timeout) > millis())
    {
      while(esp8266.available())
      {
     
        // The esp has data so display its output to the serial window
        char c = esp8266.read(); // read the next character.
        response+=c;
      }
    }
    if(debug)
    {
      Serial.print(response);
    }
    return response;
}

[ 二、 ANDROID STUDIO CODE]



Manifest File


會有人發現這次的layout有點不太一樣,因為我有修改一下樣式
android:theme="@style/Theme.AppCompat.NoActionBar"
去掉了開頭標題跟上面槓槓~

<uses-permission android:name="android.permission.INTERNET" />

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/Theme.AppCompat.NoActionBar">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>


Layout


有些改一些元件

<EditText
        android:id="@+id/ip"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="192.168.43.176"
        android:layout_marginTop="18dp"
        android:layout_below="@+id/textView2"
        android:layout_alignParentEnd="true" />

    <Button
        android:id="@+id/btnflash"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="D13 LED Flashes"
        android:layout_below="@+id/btnonoff"
        android:layout_alignStart="@+id/btnonoff"
        android:layout_marginTop="21dp" />

    <Button
        android:id="@+id/btnonoff"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="D13 LED ON/OFF"
        android:layout_marginTop="33dp"
        android:layout_below="@+id/info1"
        android:layout_alignParentStart="true"
        android:layout_marginStart="19dp" />
    <TextView
        android:id="@+id/info1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:textStyle="italic"
        android:layout_below="@+id/info2"
        android:layout_alignParentStart="true"
        android:layout_marginTop="26dp" />
    <TextView
        android:id="@+id/info2"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:textStyle="bold"
        android:layout_marginTop="22dp"
        android:layout_below="@+id/textView"
        android:layout_alignParentStart="true" />

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="IP Address:"
        android:id="@+id/textView2"
        android:layout_alignParentTop="true"
        android:layout_alignParentStart="true"
        android:layout_marginTop="16dp" />

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Arduino Response:"
        android:id="@+id/textView"
        android:layout_below="@+id/ip"
        android:layout_alignParentStart="true"
        android:layout_marginTop="18dp" />


Main




import android.support.v7.app.AppCompatActivity;

import android.os.Bundle;
import android.os.AsyncTask;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;

import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URI;
import java.net.URISyntaxException;

public class MainActivity extends AppCompatActivity {

    EditText editIp;
    Button btnflash, btnonoff;
    TextView textInfo1, textInfo2;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        editIp = (EditText)findViewById(R.id.ip);
        btnflash = (Button)findViewById(R.id.btnflash);
        btnonoff = (Button)findViewById(R.id.btnonoff);
        textInfo1 = (TextView)findViewById(R.id.info1);
        textInfo2 = (TextView)findViewById(R.id.info2);

        btnflash.setOnClickListener(btnClickListener);
        btnonoff.setOnClickListener(btnClickListener);
    }

    View.OnClickListener btnClickListener = new View.OnClickListener(){
        @Override
        public void onClick(View v) {
            String parameterValue;

            //判斷是哪個Btn在Click
        if(v.getId() == btnflash.getId()){
            parameterValue="S5";
        }else{
            parameterValue="13";
        }

        //btnflash.setEnabled(false);
        //btnonoff.setEnabled(false);

        // arduino 上已固定燒入 Port:80
        // 若 arduino 有更新此80也需要更改
        String serverIP = editIp.getText().toString()+":80";

            HttpRequestAsyncTask taskEsp = new HttpRequestAsyncTask(serverIP);
            taskEsp.execute(parameterValue);

        }
    };

    //背景執行傳送接受應用。
    private class HttpRequestAsyncTask extends AsyncTask<String, Void, String> {

        String server;

        HttpRequestAsyncTask(String server){
            this.server = server;
        }

        @Override
        protected String doInBackground(String... params) {

            String val = params[0];

            final String p = "http://"+server+"?"+val+"e";

            runOnUiThread(new Runnable(){
                @Override
                public void run() {
                    int pVal;
                    pVal = p.indexOf("?");
                    textInfo1.setText(p.substring(pVal));
                }
            });

            //傳送指令
            String serverResponse = "ERROR";
            HttpClient httpclient = new DefaultHttpClient();
            try {
                HttpGet httpGet = new HttpGet();
                httpGet.setURI(new URI(p));
                HttpResponse httpResponse = httpclient.execute(httpGet);

                InputStream inputStream = null;
                inputStream = httpResponse.getEntity().getContent();
                BufferedReader bufferedReader =
                        new BufferedReader(new InputStreamReader(inputStream));
                serverResponse = bufferedReader.readLine();

                inputStream.close();
            } catch (URISyntaxException e) {
                e.printStackTrace();
                serverResponse = e.getMessage();
            } catch (ClientProtocolException e) {
                e.printStackTrace();
                serverResponse = e.getMessage();
            } catch (IOException e) {
                e.printStackTrace();
                serverResponse = e.getMessage();
            }

            return serverResponse;
        }

        //接收指令
        @Override
        protected void onPostExecute(String s) {
            textInfo2.setText(s);
            //btnflash.setEnabled(true);
            //btnonoff.setEnabled(true);
        }
    }

}

2 則留言:

  1. 不好意思,arduino 程式碼有顯示以下的錯誤訊息
    cannot convert 'String' to 'uint8_t {aka unsigned char}' for argument '1' to 'int digitalRead(uint8_t)'
    請問是哪個地方需要修改呢?

    回覆刪除
    回覆
    1. 在Loop裡的ReadD,因為是String,在digitalWrite(ReadD, !digitalRead(ReadD))中的ReadD是需要UInt的格式,所以需要將ReadD轉為UInt。
      將String To Int,請參考https://www.arduino.cc/en/Tutorial/StringToIntExample

      刪除