iT邦幫忙

1

想用MIT APP Inventor 做一個app連到esp8266 wifi模組控制arduino

想用MIT APP Inventor 做一個app連到esp8266 wifi模組控制arduino
現在app大概做好了
但是程式內容好像有衝突到
做了三個button來控制arduino
https://ithelp.ithome.com.tw/upload/images/20191223/20123502Ux16Uk4pVN.jpg
以下是app的程式
https://ithelp.ithome.com.tw/upload/images/20191223/20123502XHLA0X4UtG.jpghttps://ithelp.ithome.com.tw/upload/images/20191223/20123502RaxS4pTUR7.jpghttps://ithelp.ithome.com.tw/upload/images/20191223/201235024EBKKrKQWc.jpghttps://ithelp.ithome.com.tw/upload/images/20191223/20123502SIyLSbC247.jpg
以下是arduino的回傳app的程式
https://ithelp.ithome.com.tw/upload/images/20191223/20123502bd0ng1QZHT.jpg
https://ithelp.ithome.com.tw/upload/images/20191223/20123502weZUnbi11X.jpg

1 個回答

1
marlin12
iT邦新手 1 級 ‧ 2019-12-24 00:33:44

程式內容怎樣[衝突]?
假設ESP8266跟安卓app的資料傳送沒問題,單從程式的邏輯上看。
在MIT APP Inventor那邊,較好的做法是[發了一個http request,等收到相關的http response後,才容許發出下一個http request]。

initialize global waitResponse to false

When hot.Click
do if global waitResponse = false
   then set global waitResponse to true
        set Web1.Url to ...
        call Web1.Get
 ...    ...   ...   
 
When Web1.GotText
do set global waitResponse to false
   if get responseCode = 200
   then ...   ...

在Arduino那邊,為何有些query沒有httpResponse?!那怕是收到錯誤的httpRequest,也要有httpResponse回應問題在那裏。
另外,對inventor發過來X=1的httpRequest,為何在Arduino那邊沒有回應"X1=on"或者"X1=off"的httpResponse?!

bool autoEnable = false;  // global variable

if(ESP8266.available() && ESP8266.find("+IPD,")) {
  do { c = ESP8266.read(); } while(c < '0' || c > '9');
  connectionId = c - '0';
  
  action = "";
  
  if( ESP8266.find("X=") ) {
    switch( ESP8266.read() ) {
      case '1':
        autoEnable = !autoEnable;
        action = autoEnable ? "X1=on" : "X1=off";
        if( autoEnable ) {
          ...  ...  ...
        }
        break;
      case '2':
        action = temp + "," + humi;      
        break;
      case '3':
        ledStatus[0] ^= 1;
        digitalWrite(led[0], ledStatus[0]);
        action = (ledStatus[0] == 0) ? "X3=off" : "X3=on";
        break;
      case '4':
        ledStatus[1] ^= 1;
        digitalWrite(led[1], ledStatus[1]);
        action = (ledStatus[1] == 0) ? "X4=off" : "X4=on";      
        break;
      default:
        break;
    }
  }
  
  httpResponse(connectionId, action);
}
看更多先前的回應...收起先前的回應...
555wei iT邦新手 5 級 ‧ 2019-12-25 23:16:15 檢舉

我是想按下Auto(X=1)的button時可以讓Arduino自己做溫度控制,
但是X=1時它不能自己控制(t>25,t<=24),需要按Auto按鈕才會變化,不知道是不是因為if迴圈的關係

我現在將程式更改成以下
https://ithelp.ithome.com.tw/upload/images/20191225/20123502XIswiIE7Eg.jpg
https://ithelp.ithome.com.tw/upload/images/20191225/20123502ZEpvWjQ6Yr.jpg
![https://ithelp.ithome.com.tw/upload/images/20191225/20123502oDTYSAuOfD.jpg](https://ithelp.ithome.com.tw/upload/images/20191225/20123502oDTYSAuOfD.jpg
https://ithelp.ithome.com.tw/upload/images/20191225/20123502XoN5LySGM1.jpg
https://ithelp.ithome.com.tw/upload/images/20191225/201235028l3HAUkBfi.jpg
https://ithelp.ithome.com.tw/upload/images/20191225/20123502d1JBKFwulc.jpg

謝謝幫忙

marlin12 iT邦新手 1 級 ‧ 2019-12-26 01:11:55 檢舉

因為你把[温度控制]的那段程式,放在if(ESP8266.available())裏面。在沒有收到ESP8266的httpRequest時,便不能運行那段程式。你嘗試改成這樣吧!

bool autoEnable = false;  // 當設定為true時,開啟自動控制

void loop() {
  if( (millis() - realtime) >= 10000 ) {
    realtime = millis();

    if( autoEnable ) {
      float t = dht.readTemperature();
      float h = dht.readHumidity();

      if( t > 25) {
        digitalWrite(led[1], HIGH);
        digitalWrite(led[0], LOW);
        digitalWrite(led[2], LOW);
      } else if( t <= 24 ) {
        digitalWrite(led[2], HIGH);
        digitalWrite(led[0], LOW);
        digitalWrite(led[1], LOW);
      } else {
        digitalWrite(led[0], HIGH);
        digitalWrite(led[1], LOW);
        digitalWrite(led[2], LOW);
      }
    }
  }

  if( ESP8266.available() && ESP8266.find("+IPD,") ) {
    do { c = ESP8266.read(); } while(c < '0' || c > '9');
    connectionId = c - '0';

    if( ESP8266.find("X=") ) {
      switch( ESP8266.read() ) {
        case '1':
          autoEnable = !autoEnable;
          action = autoEnable ? "X1=on" : "X1=off";
          break;
        case '2':
          action = temp + "," + humi;      
          break;
        case '3':
          ledStatus[1] ^= 1;
          digitalWrite(led[1], ledStatus[1]);
          action = (ledStatus[1] == 0) ? "X3=off" : "X3=on";
          break;
        case '4':
          ledStatus[2] ^= 1;
          digitalWrite(led[2], ledStatus[2]);
          action = (ledStatus[2] == 0) ? "X4=off" : "X4=on";      
          break;
        default:
          action = "X=?";
          break;
      }
    }

    httpResponse(connectionId, action);
  }
}
555wei iT邦新手 5 級 ‧ 2019-12-26 20:52:03 檢舉

謝謝你 幫助很大
還有一個問題想請教你
我現在的APP所在的手機和ESP8266WiFi是在同一個網路下才可以進行控制,沒有達到我想要的遠端,若我的APP想在任何網路下都可以連到ESP8266進行遠端控制該如何處理,是APP的程式或是Arduino的程式需要加些什麼,還是有其他辦法。

marlin12 iT邦新手 1 級 ‧ 2019-12-27 01:03:28 檢舉

如果要做到跨網路的遠程控制,目前最流行的方法,是使用在互聯網上的MQTT broker作為中繼器,把發佈者(即手機)和訂閱者(即Arduino)連起來。MQTT協定跟你現在用的HTTP協定不同,你要另做手機APP和Arduino的程式。有興趣的話,可以參考以下的連結:
認識MQTT
簡簡單單的MQTT入門
MQTT遠端遙控

555wei iT邦新手 5 級 ‧ 2019-12-30 21:59:35 檢舉

謝謝你提供參考資料

如果我想做一個加熱的東西有什麼方法
我現在的降溫是用DC12V的風扇,使用8個AA電池做的12V電源,那麼加熱的東西有什麼是可以用12V就可以發熱的,有想過燈泡,但不知有沒有12V的燈泡,或是其他比較簡單的方式。

marlin12 iT邦新手 1 級 ‧ 2019-12-31 21:44:00 檢舉

我沒有用過12V的加熱裝置,或者你可以去淘寶搜尋一下。

我要發表回答

立即登入回答