簡體   English   中英

Arduino和Android UDP數據報

[英]Arduino and Android UDP Datagram

這是簡單的代碼,在這里我將使用我的Android手機通過網絡將密碼發送到ArduinoMKR1000,這將依次檢查您的密碼並解鎖禮物。 我使用UDP套接字。 Arduino代碼是:

#include <SPI.h>
#include <WiFi101.h>
#include <WiFiUdp.h>

// TODO change this
int  status = WL_IDLE_STATUS;
char ssid[] = "yourNetwork";    //  your network SSID (name)
char pass[] = "secretPassword"; // your network password (use for WPA, or use
                                // as key for WEP)

unsigned int localPort = 2390;  // local port to listen on

char packetBuffer[255];         // buffer to hold incoming packet
char replyRight[] = "you have your gift!"; // a string to send back
char replyWrong[] = "try again!";

WiFiUDP Udp;

// Array of passwords to choose from, expand it or fetch some words from the
// internet!
const int PasswordArrayLength=5;
String passwords[PasswordArrayLength] = {
  "Merry",
  "Christmas",
  "42", // The meaning of everything must be here!
  "Santa",
  "HoHo"
};

bool checkPassword();   // Checks for the received password
void openGift();    // Unlocks the gift
void showWarning(); // Locks the gift and displays the warning

const int lockPin = 4;
const int warningLedPin = 5;

String guess; // password guess

void setup() {
  // Initialize serial
  Serial.begin(9600);

  // attempt to connect to WiFi network:
  while (status != WL_CONNECTED) {
    Serial.print("Attempting to connect to Wifi: ");
    Serial.println(ssid);

    status = WiFi.begin(ssid, pass);

    // wait 10 seconds for connection:
    delay(10000);
  }

  Serial.println("Connected to wifi");

  // print your WiFi shield's IP address, your phone will connect to this IP Address
  IPAddress ip = WiFi.localIP();
  Serial.print("IP Address: ");
  Serial.println(ip);

  // if you get a connection, report back via serial:
  Udp.begin(localPort);
}

void loop() {
  // if there's data available, read a packet
  int packetSize = Udp.parsePacket();

  if (!packetSize) 
  {
    // read the packet into packetBufffer
    int len = Udp.read(packetBuffer, 255);

    if (len > 0) packetBuffer[len] = 0; // Null terminate the string to avoid data corruption

    Serial.println("Entered password:");
    Serial.println(packetBuffer);
    guess=String(packetBuffer);   // Put the char array in a string to compare easily

    if (checkPassword())
    {
        // Open the gift
        openGift();

        // Send the reply
        Udp.beginPacket(Udp.remoteIP(), Udp.remotePort());
        Udp.write(replyRight);
        Udp.endPacket();
    }
    else
    {
        // Show alert
        showWarning();

        // Tell the sender to try again
        Udp.beginPacket(Udp.remoteIP(), Udp.remotePort());
        Udp.write(replyWrong);
        Udp.endPacket();
    }
  }

}

void openGift()
{
  digitalWrite(lockPin,HIGH);   // Unlock the gift
  digitalWrite(warningLedPin,LOW);  // Turn of the warning if it was on
}

void showWarning()
{
  digitalWrite(warningLedPin,LOW);  // Turn on the warning led
  digitalWrite(lockPin,HIGH);   // Lock the gift
}

bool checkPassword()
{
  for(int i =0; i < PasswordArrayLength; i++)
  {
      if(guess.equals(passwords[i]))
        {
            return true;
        }
  }
  return false;
}

而android的代碼是:

package com.example.ahmed.udpsender;

import android.os.Bundle;
import android.support.design.widget.FloatingActionButton;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.text.Editable;
import android.view.View;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.EditText;
import android.widget.Toast;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.util.regex.Pattern;

public class MainActivity extends AppCompatActivity


private DatagramSocket socket;
private EditText ipEditText;
private EditText portEditText;
private EditText messageEditText;
// Socket operation time out in milliseconds
private static final int TIMEOUT_MILLIS = 2000;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
    setSupportActionBar(toolbar);

    FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);

    // Get the handles of the text fields to use them in validation later
    // NOTE: this must exist after "setContentView(R.layout.activity_main);"
    ipEditText = ((EditText) findViewById(R.id.editTextIp));
    portEditText = ((EditText) findViewById(R.id.editTextPort));
    messageEditText = ((EditText) findViewById(R.id.textAreaMessage));

    try {
        socket = new DatagramSocket();  // Create a UDP socket
        socket.setBroadcast(true);  // Enable broadcasts
        socket.setSoTimeout(TIMEOUT_MILLIS); // Set timeout for socket operations

    } catch (SocketException e) {
        showToast(e.getMessage());
    }

    fab.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            onSendButtonClick();
        }
    });
}

@Override
public void onDestroy() {
    super.onDestroy();
    this.socket.close();    // Destroy the socket when the app closes
}

private void onSendButtonClick() {
    final String ipString = ipEditText.getText().toString();
    final String portString = portEditText.getText().toString();

    boolean ipValidated = validateIp(ipString);
    boolean portValidated = validatePort(portString);

    if (!ipValidated && !portValidated) {
        showToast("Ip and Port are invalid");
    } else if (!ipValidated) {
        showToast("IP is invalid");
    } else if (!portValidated) {
        showToast("Port number is invalid");
    } else {    // Parameters are syntactically correct

        Editable editable = messageEditText.getText();
        final String message = editable.toString(); // Get the text in the EditText

        // Network operations must be started on a separate
        // thread other than the UI thread
        new Thread() {
            public void run() {

                if (sendPacket(message, ipString, Short.parseShort(portString))) {
                    String reply = receivePacket();
                    showToastOnUiThread(reply);
                }
            }
        }.start();

        editable.clear();    // Clear the message edit text
    }
}


@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);
}

private boolean validateIp(String ip) {


    if (ip.length() == 0) return false;

    if (!IP_ADDRESS.matcher(ip).matches()) {
        // Show a message
        showToast("Please enter a valid IP Address");
        return false;
    } else {
        return true;
    }
}

private boolean validatePort(String text) {

    if (text.length() == 0) return false;

    try {
        Short.parseShort(text); // If this succeeds, then it's a valid port
        return true;
    } catch (NumberFormatException e) {
        showToast("A valid port number is between 1 and " + Short.MAX_VALUE);
        return false;
    }

}

private boolean sendPacket(String message, String ipString, short portNumber) {

    byte messageBytes[] = message.getBytes();
    if (message.isEmpty()) return false;

    try {
        // Create the packet containing the message, IP and port number
        final DatagramPacket packet = new DatagramPacket(messageBytes, messageBytes.length,
                InetAddress.getByName(ipString), portNumber);

        socket.send(packet);

        // The UDP packet left the pc safely, we don't know if it was received somewhere
        return true;

    } catch (final UnknownHostException e) {

        showToastOnUiThread("Couldn't find host");
        return false;

    } catch (final IOException e) {

        showToastOnUiThread(e.getMessage());
        return false;   // Something went wrong
    }
}

private String receivePacket() {
    try {
        byte buffer[] = new byte[255];
        DatagramPacket p = new DatagramPacket(buffer, buffer.length);
        socket.receive(p);
        return new String(p.getData());    // Convert the packet to a string and return it
    } catch (IOException ignored) {
    }

    // Nobody replied to the packet, maybe the address didn't exist in the network
    return "Nothing received, timeout";
}

// A toast is the tiny message you see on the screen

private void showToastOnUiThread(final String text) {
    runOnUiThread(new Runnable() {
        @Override
        public void run() {
            showToast(text);
        }
    });
}

private void showToast(String message) {
    Toast.makeText(getApplicationContext(), message, Toast.LENGTH_SHORT).show();
}

//--------------------------------------------------------------------------------------
// Regex for validating IP addresses
private static final Pattern IP_ADDRESS
        = Pattern.compile(
        "((25[0-5]|2[0-4][0-9]|[0-1][0-9]{2}|[1-9][0-9]|[1-9])\\.(25[0-5]|2[0-4]"
                + "[0-9]|[0-1][0-9]{2}|[1-9][0-9]|[1-9]|0)\\.(25[0-5]|2[0-4][0-9]|[0-1]"
                + "[0-9]{2}|[1-9][0-9]|[1-9]|0)\\.(25[0-5]|2[0-4][0-9]|[0-1][0-9]{2}"
                + "|[1-9][0-9]|[0-9]))");

}

問題是:當我嘗試輸入密碼android時,在arduino停止void loop()時,返回烤面包機“ Nothing receive,timeout”。 問題是什么? 附言:我在同一外部熱點將arduino和android連接了

我已經解決了替換問題//用廣播IP發送答復:IP地址ip(255,255,255,255)中的Udp.remoteIP()更改;

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM