所有关于电路
项目

如何构建基于web的车库门控制器

2015年9月29日,通过特拉维斯Fagerness

使用Android设备打开并关闭您的车库门!比你使用的笨重遥控器好得多。

使用Android设备打开并关闭您的车库门!

概述

我有动力找到一个新的解决方案来控制我的车库门,因为我不想携带额外的遥控,他们只是不太努力。本文简化了如何使用CC3200连接到现有车库门开启器。CC3200充当TCP服务器,可以将关于车库门状态的信息发送到任何网络能力的设备。通过发送TCP消息,还可以打开和关闭车库门。还创建了一个Android应用程序以充当车库门遥控器。

要求

  • CC3200演示板
    • 更新到最新的固件为Energia支持,方向这里
  • 能源- 从TI的基于加工的IDE,类似于Arduino IDE
    • 用于文章:v。0101E00016
  • 连接到现有的车库门开启器
  • 可选:Android设备用作车库遥控器
    • 用于文章:安卓棒棒糖
  • 选修的:Android Studio用于制作Android应用程序

硬件设置

控制车库门电机

我的车库门开关是张伯伦牌的。车库门电机的后部有4根电线连接传感器和硬线开关。DMM是用来找出哪根线连接到硬接线开关,通过探测电压,而按下开关。我以为白色的电线是接地的。蓝色电线约5-6V,按下车库开关时没有反应。我发现开关未按下时红白线电位正常在15.8V左右,按下开关时电位下降到0V。这将使它很容易使用NPN或NMOS晶体管来模拟一个按钮按下CC3200。

读取车库门状态

读取车库门的状态有点棘手,因为没有办法从发动机上的任何连接来判断。我想到了几种方法来判断门是开着还是关着。

  1. 由电机在门的顶部使用一个限位开关。按下限位开关,则门打开。如果开关关着,就关门最有可能的是关闭的,但可能是半开着卡住了CC3200也不知道。
  2. 在门的顶部和底部使用两个限位开关。按下的开关决定门是开着还是关着,如果两者都开着,则门在移动或被卡住。
  3. 使用与门轨对齐的距离传感器。当门关闭时,距离会变大。这样你就能清楚地知道门的确切状态。

我要使用选项1来保持简单的事情。我可以将开关安装在靠近后方的门支架上,以便当门完全打开时激活它。

连接图

  • CC3200引出线这里
  • 该交换机刚刚向上拉到VCC,以创建与GPIO输入的有效连接。
  • GPIO输出通过NPN与电机红线接口,以将低压CC3200与15V开关电压隔离。
  • 电阻器的值并不重要,可以是任何你有放置,~500-50kohm是合理的。如果你用NMOS代替,你根本不需要电阻。

软件

嵌入式

以下Energia项目代码执行以下操作:

  1. 连接配置变量中指定的wifi网络
  2. 从路由器获取IP地址
  3. 在设置中指定的端口上打开TCP服务器
  4. 等待客户端连接
  5. 当客户端连接时,它会等待密码和命令。
  6. 如果密码正确并且命令匹配已知命令,则执行操作。
  7. 服务器以车库的状态响应:激活、打开或关闭,这取决于命令。
#include  #include  #define server_port 23 #define limit_sw_pin 2 #define motor_sw_pin 8 #define grn_led 10 #define red_led 29 #define yellow_led 9 //配置变量char ssid [] =“ssid”;char password [] =“pass”;char garage_password [] =“mypass”;char command_activate [] =“激活”;char command_status [] =“status”;Boolean已连接= false;//客户端是否已连接以前是Wifiserver服务器(Server_Port);void setup(){//调试串行端口串行.Begin(115200);//接口引脚PINMODE(GRN_LED,输出);PINMODE(RED_LED,输出); pinMode(YELLOW_LED, OUTPUT); pinMode(MOTOR_SW_PIN, OUTPUT); pinMode(LIMIT_SW_PIN, INPUT_PULLUP); digitalWrite(GRN_LED, LOW); digitalWrite(YELLOW_LED, LOW); digitalWrite(RED_LED, HIGH); // attempt to connect to Wifi network: Serial.print("Attempting to connect to Network named: "); // print the network name (SSID); Serial.println(ssid); // Connect to WPA/WPA2 network. Change this line if using open or WEP network: WiFi.begin(ssid, password); while ( WiFi.status() != WL_CONNECTED) { // print dots while we wait to connect Serial.print("."); delay(300); } Serial.println("\nYou're connected to the network"); Serial.println("Waiting for an ip address"); while (WiFi.localIP() == INADDR_NONE) { // print dots while we wait for an ip addresss Serial.print("."); delay(300); } Serial.println("\nIP Address obtained"); // you're connected now, so print out the status: printWifiStatus(); // start the server: server.begin(); digitalWrite(RED_LED, LOW); digitalWrite(YELLOW_LED, HIGH); } #define CLIENT_BUFF_SIZE 100 char client_in_buffer[CLIENT_BUFF_SIZE]; uint8_t idx=0; void loop() { // wait for a new client: WiFiClient client = server.available(); if (client) { digitalWrite(YELLOW_LED, LOW); if (!alreadyConnected) { // clead out the input buffer: client.flush(); Serial.println("Client connected"); client.println("Garage connected!"); alreadyConnected = true; digitalWrite(GRN_LED, HIGH); } if (client.available() > 0) { char thisChar = client.read(); Serial.write(thisChar); if(thisChar == '\n'){ if(strncmp(client_in_buffer,garage_password,strlen(garage_password)) == 0){ Serial.println("passwords match"); if(strncmp(client_in_buffer+strlen(garage_password)+1,command_activate,strlen(command_activate)) == 0){ Serial.println("Activate"); client.println("Garage activated"); digitalWrite(MOTOR_SW_PIN, HIGH); delay(200); digitalWrite(MOTOR_SW_PIN, LOW); } if(strncmp(client_in_buffer+strlen(garage_password)+1,command_status,strlen(command_status)) == 0){ Serial.println("Status"); if(digitalRead(LIMIT_SW_PIN) == HIGH) client.println("Garage is open"); else client.println("Garage is closed"); } } memset(client_in_buffer,0,CLIENT_BUFF_SIZE); idx=0; } else{ client_in_buffer[idx]=thisChar; idx++; if(idx>=CLIENT_BUFF_SIZE){ idx=0; memset(client_in_buffer,0,CLIENT_BUFF_SIZE); } } } } else{ digitalWrite(YELLOW_LED, HIGH); digitalWrite(GRN_LED, LOW); alreadyConnected = false; } } void printWifiStatus() { // print the SSID of the network you're attached to: Serial.print("SSID: "); Serial.println(WiFi.SSID()); // print your WiFi shield's IP address: IPAddress ip = WiFi.localIP(); Serial.print("IP Address: "); Serial.println(ip); // print the received signal strength: long rssi = WiFi.RSSI(); Serial.print("signal strength (RSSI):"); Serial.print(rssi); Serial.println(" dBm"); }

GarageControllerEnergia.zip

Android应用程序

Android应用程序打开到服务器的连接。你必须修改你想要使用的IP地址。如果你想从你的本地网络外连接,你必须通过路由器转发端口到IP地址。如果你只允许本地网络内的连接,你会有更多的安全性。这个应用程序只有几个按钮和一些状态指示。激活按钮触发电机按钮200ms,状态按钮读取限位开关。

package com.example.travis.GarageController;导入java.io.bufferedreader;导入java.io.buffeedwriter;导入java.io.ioException;导入java.io.InputStreamReader;导入java.io.outputStreamWriter;导入java.io.printwriter;导入java.net.inetAddress;导入java.net.socket;导入java.net.unknownhostException; import android.os.Bundle; import android.view.View; import android.support.v7.app.AppCompatActivity; import android.view.Menu; import android.view.MenuItem; import android.os.Handler; import android.widget.TextView; public class MainActivity extends AppCompatActivity { private Socket socket; Handler updateConversationHandler; private static final int SERVER_PORT = 23; private static final String SERVER_IP = "192.168.1.144"; private static final String PASSWORD = "mypass"; private TextView t_garage; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); t_garage = (TextView) findViewById(R.id.t_garage); updateConversationHandler = new Handler(); new Thread(new ClientThread()).start(); } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.menu_main, menu); return true; } @Override public boolean onOptionsItemSelected(MenuItem item) { // Handle action bar item clicks here. The action bar will // automatically handle clicks on the Home/Up button, so long // as you specify a parent activity in AndroidManifest.xml. int id = item.getItemId(); //noinspection SimplifiableIfStatement if (id == R.id.action_settings) { return true; } return super.onOptionsItemSelected(item); } public void onClick_activate(View view) { try { String packet = PASSWORD + ",Activate"; PrintWriter out = new PrintWriter(new BufferedWriter( new OutputStreamWriter(socket.getOutputStream())), true); out.println(packet); //get data back from server BufferedReader input = new BufferedReader(new InputStreamReader(socket.getInputStream())); } catch (UnknownHostException e) { t_garage.setText("Can't find garage"); } catch (IOException e) { t_garage.setText("Comm error connect"); } catch (Exception e) { t_garage.setText("Can't find garage"); } } public void onClick_status(View view) { try { String packet = PASSWORD + ",Status"; PrintWriter out = new PrintWriter(new BufferedWriter( new OutputStreamWriter(socket.getOutputStream())), true); out.println(packet); //get data back from server BufferedReader input = new BufferedReader(new InputStreamReader(socket.getInputStream())); } catch (UnknownHostException e) { t_garage.setText("Can't find garage"); } catch (IOException e) { t_garage.setText("Comm error connect"); } catch (Exception e) { t_garage.setText("Can't find garage"); } } class ClientThread implements Runnable { @Override public void run() { try { InetAddress serverAddr = InetAddress.getByName(SERVER_IP); socket = new Socket(serverAddr, SERVER_PORT); SeverResponseThread serverThread = new SeverResponseThread(socket); new Thread(serverThread).start(); } catch (UnknownHostException e1) { t_garage.setText("Can't find garage"); } catch (IOException e1) { t_garage.setText("Comm error connect"); } } } class SeverResponseThread implements Runnable { private Socket clientSocket; private BufferedReader input; public SeverResponseThread(Socket clientSocket) { this.clientSocket = clientSocket; try { this.input = new BufferedReader(new InputStreamReader(this.clientSocket.getInputStream())); } catch (IOException e) { t_garage.setText("Comm error write"); } } public void run() { while (!Thread.currentThread().isInterrupted()) { try { String read = input.readLine(); updateConversationHandler.post(new updateTextThread(read)); } catch (IOException e) { t_garage.setText("Comm error read"); } } } } class updateTextThread implements Runnable { private String server_response; public updateTextThread(String str) { this.server_response = str; } @Override public void run() { t_garage.setText(server_response); } } }

APK.

IP硬编码为192.168.1.144,端口为23。

garage_controller.zip

项目

garagecontroller.zip.

测试门

在下面的视频中,我通过按下手机上的激活按钮来控制车库门。

结论

您可以使用此项目作为指南,以使用与CC3200的TCP连接控制许多东西。您不一定必须使用Android设备。任何能够TCP的网络连接设备都可以用作车库门遥控器。

为自己提供这个项目!BOM。