The best tools to make your project dreams come true

Login or Signup

4/3/2019 | By Maker.io Staff

How to Get Two Photons to Talk

Getting two Particle Photons to talk to each other can be useful in applications, including radio control and monitoring. In this How-To article, we will learn how to get two particle Photons to talk to each other over the internet!

BOM

Communication Methods

When it comes to getting microcontrollers to communicate, there are a number of different methods available. Most of these methods involve a direct electrical connection that has pulses representing data sent down. These methods include UART, I2C, SPI, and CAN. While it’s quick and easy to set up communication between two devices with these methods, they all have one problem in common: they require a physical connection. Particle Photon boards have Wi-Fi capabilities, which means that, in theory, two Photons can talk to each other using a TCP connection. In this tutorial, we will connect two Photons together on the same network (not over the internet) because there will be no need for port forwarding.

Before we learn how to setup TCP servers and clients, we will first look at data sending over the internet in general. While protocols themselves are very complex, most libraries and frameworks handle the protocol automatically. Therefore, we only need to deal with data that we stream.

Data that is sent over the internet is in binary form, but it is up to you how you interpret this data. This means that you can use an internet connection between two devices as a serial port and stream text (such as in HTTP), which is what we will be doing in this tutorial. Therefore, sending a string from one Photon to another can be as simple as:

  • Sending string “Hello world” from one Particle Photon
  • Receiving string “Hello world” on a second Particle Photon

For two Photons to communicate, one Photon must be configured as a TCP server (which accepts incoming requests) while the other is configured as a TCP client (which initiates a request to connect). Once the two devices are connected, they can transfer data to each other asynchronously.

TCP Client Class

The first class that needs to be used and understood is the TCPClient class. While there are at least 11 functions associated with this class, we will only learn about the basics, as they are simple and easy to understand.

  • connect()
  • println()
  • available()
  • read()
  • stop()

connect() is used to connect to a server. Two variables are passed to this function: the IP address of the server and the port. The IP address will be obtained from the TCP server later, and the IP address is in the form of a byte array. The port is predetermined and can be essentially anything you want, so in our example, we will use the standard HTTP port 80 . This function returns true if the connection was successful and false if it failed.

Copy Code
byte server_ip[] = {192, 168, 1, 150};	// Your servers address

// Keep trying to connect until connect function returns true while(!client.connect(server_ip, 80))

{ Serial.println(“connection failed trying again”); }

println() is used to send the text to the connected server and works in an identical fashion sending text down a serial port. This function also terminates the sent string with a carriage return line feed, so if the text was being printed on the other side, it would be printed on a new line.

available() is a function that returns how many bytes are waiting in the received buffer. If the connected server sends data to the client, it will be stored in a buffer that can be read later by the Photon. The data in the buffer is in byte form and must be converted into a suitable format if you are not using bytes. The data can be read using the read() function. The example below shows how to read strings up to 32 characters in length and convert that data into a string.

Copy Code
byte dataBuffer[32];	// Buffer for storing data

String data;

if(client.available())

{ client.read(dataBuffer, sizeof(dataBuffer));	// Read data into the buffer

for(int ptr = 0; dataBuffer[ptr] != 0x00; ptr++)	// Loop that copies byte string into string

{ data[ptr + 1] = 0x00;

data[ptr] = char(dataBuffer[ptr]); } }

stop() is used to disconnect from the currently connected server and should be called once you no longer require the communication link. This can be useful for freeing up the line for other devices that may also want to talk to the server.

TCP Server Class

Creating a TCP server is trivial to do on the Photon and takes advantage of the TCPServer class. Only a few functions need to be understood as the TCP server class is used with the TCP client class:

  • begin()
  • available()

begin() is used to start the TCP server, which accepts connection requests on the specified port (which is done when creating the server class). This function returns nothing and accepts no arguments; it merely needs to be called at the beginning of the code (and only once).

available() is used to determine if a client is requesting a connection. If there is such a connection request, then available() can be passed to a client-class object. From there, the client object can be used to send data to the connected client.

TCP Client Code

Copy Code
TCPClient client;                           // Create TCP Client object
byte server_ip[] = { 192, 168, 1, 100 };    // IP Address of server
byte dataBuffer[32];                        // Data buffer that holds received strings
 
void setup() 
{
    Serial.begin(9600);
}
 
void loop() 
{
    // Keep connecting until connection made
    while(!client.connect(server_ip, 80))
    {
        Serial.println("Server connection failed. Trying again...");
    }   
    
    // Send a sentence
    client.println("Hello there!!!");
    
    // Wait for a response 
    while(!client.available());
 
    // Read data from the buffer
    client.read(dataBuffer, sizeof(dataBuffer));
    
    // Print the string
    for(int ptr = 0; dataBuffer[ptr] != 0x00; ptr++)
    {
        Serial.print(char(dataBuffer[ptr]));
    }
    
    // Print new line
    Serial.println();
    
    // Stop the current connection
    client.stop();
    
    delay(1000);
}

TCP Server Code

Copy Code
TCPClient client;                           // Create TCP Client object
TCPServer server = TCPServer(80);           // Create TCP Server object and use port 80
byte dataBuffer[32];                        // Data buffer that holds received strings
 
void setup() 
{
    Serial.begin(9600);
    
    // Wait for a USB serial connection for up to 30 seconds
    waitFor(Serial.isConnected, 30000);
  
    Serial.println(WiFi.localIP());         // Print the local IP address (copy this to the client code)
    server.begin();                         // Start the TCP Server
}
 
void loop() 
{
    client = server.available();            // Pass a requesting client to the client object
    
    // Execute code if a client was detected and accepted
    if(client)
    {
        // Wait for a response 
        while(!client.available());        
    
        delay(100);
        
        // Read data from the buffer
        client.read(dataBuffer, sizeof(dataBuffer));
        
        // Print the string
        for(int ptr = 0; dataBuffer[ptr] != 0x00; ptr++)
        {
            Serial.print(char(dataBuffer[ptr]));
        }
        
        // Print new line
        Serial.println();
 
        // Send a sentence
        client.println("Hi!!!");
    }
 
    delay(1000);
}