雷竞技注册
项目

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

2015年9月29日经过特拉维斯船用伪造

使用你的Android设备来打开和关闭你的车库门!比你用的那个笨重的遥控器好多了。

使用你的Android设备来打开和关闭你的车库门!

概述

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

需求

  • CC3200.演示板
    • 更新到最新固件的Energia支持,方向在这里
  • Energia.-一个来自TI基于处理的IDE,类似于Arduino IDE
    • 用于文章:v。0101E00016
  • 连接现有车库门开关的电线
  • 可选:Android设备,用作车库遥控器
    • 用于文章:Android棒棒糖
  • 可选:Android工作室制作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.zip.

Android应用程序

Android应用程序打开与服务器的连接。您必须修改要使用的IP地址。如果要从本地网络外部连接,则必须将端口通过路由器转发到IP地址。如果您只允许本地网络内部的连接,您将拥有更多的安全性。该应用程序只是一个耦合按钮和一些状态指示。Activate按钮触发了200ms的电机按钮,状态按钮读取限位开关。

包com.example.travis.garagecontroller;进口java.io.BufferedReader;进口java.io.BufferedWriter;进口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。