push notifications with Google Cloud Messaging

Hello

I want to send push notifications from my arduino mega 2560 to my Android smartphone using Google cloud Messaging but I have no Idea how to do that with the Arduino. In the developer guidelines is described that I have to send an HTTP Post to the Cloud Server.

I don't know much about http an Website programming so can somebody help me with this? Maybe someone have already done it and can give me an example how it should be done...

regards Maik

This documents describes that the POST has to be done to a HTTPS server. SSL encryption is not possible with the limited memory an Arduino has. Use an embedded Linux platform (Raspberry Pi, Cubieboard, PCduino, etc.) for such tasks.

If you are open to using other services, then you might like to look at PubNub.
Main page is http://www.pubnub.com/

They have an API for Arduino here GitHub - pubnub/arduino: The Official PubNub Arduino-based API!

It is based on a publisher subscriber model, where you can very easily have your Arduino publish a message.
Any connected and subscribed clients will be notified right away.

It worth reading up on and seeing how this technoogy is used.
I use it currently on my Freetronics EtherMega which has onboard Ethernet and send my data only when a certain change has taken place rather than constant polling of data.

This can make a very responsive system, with new values able to be published from your Arduino at a fairly fast rate and then throttled back to almost nothing while there is no new data.

There are other services like this as well, such as Pusher.
Hope this helps.


Paul

pylon:
This documents describes that the POST has to be done to a HTTPS server. SSL encryption is not possible with the limited memory an Arduino has. Use an embedded Linux platform (Raspberry Pi, Cubieboard, PCduino, etc.) for such tasks.

Hmm..where do you see that it have to be an https server? The only thing I want to do is that the arduino send a message to the GCM server for example a temperature is to high. The GCM Server then send this message to my android devices to my app. On the android device should come a notification and when I open it the app starts and I can check what is wrong.
I don't understand why this is a problem for the arduino because it can run a http server or client.

Hmm..where do you see that it have to be an https server?

Maybe there.

To send a message, the application server issues a POST request to
https://android.googleapis.com/gcm/send.

Recently, I found a solution for your problem. There is no need to send a POST request to the GCM servers with https. They also accept http!
So I modified a sampe code by pushingbox.com to use it with google cloud messaging (GCM).

////Arduino push notifications
//
// General code from http://www.pushingbox.com for Arduino + Ethernet Shield (official) v1.2
// Modified by Perilex 2014-05-02 for google cloud messaging (GCM)
// Send push notification when button is pressed
////

#include <SPI.h>
#include <Ethernet.h>


  /////////////////
 // MODIFY HERE //
/////////////////
byte mac[] = { 0x00, 0xAA, 0xBB, 0xCC, 0xDE, 0x19 };   // Be sure this address is unique in your network

//Enter your secret API_key of your project, the RegID of the respective Android app on your specific device
//and your data
char API_key[] = "your_API_key"; 
char RegID[] = "your_app_regID";
char data[] ="data=your_data"; //data to send. obey GCM format!
 

//Numeric Pin where you connect your switch
uint8_t ButtonPin = 14; // Example : the switch is connect to the Pin 14 and GND

// Debug mode
boolean DEBUG = true;
  //////////////
 //   End    //
//////////////


char serverName[] = "android.googleapis.com"; //GCM server adress
boolean ButtonPinState = false;                // Save the last state of the Pin
boolean lastConnected = false;                 // State of the connection last time through the main loop


// Initialize the Ethernet client library
// with the IP address and port of the server 
// that you want to connect to (port 80 is default for HTTP):
EthernetClient client;


void setup() {
  Serial.begin(9600);
  pinMode(ButtonPin, INPUT);
  digitalWrite(ButtonPin, HIGH); // activate internal pullup resistor
  
  // start the Ethernet connection:
  if (Ethernet.begin(mac) == 0) {
    Serial.println("Failed to configure Ethernet using DHCP");
    // no point in carrying on, so do nothing forevermore:
    while(true);
  }
  else{
    Serial.println("Ethernet ready");
    // print the Ethernet board/shield's IP address:
    Serial.print("My IP address: ");
    Serial.println(Ethernet.localIP());
  }
  // give the Ethernet shield a second to initialize:
  delay(1000);
}

void loop()
{
      ////
      // Listening for the ButtonPin state
      ////
     
     if (digitalRead(ButtonPin) == HIGH && ButtonPinState == false) // switch on ButtonPin is ON 
      {
        if(DEBUG){Serial.println("ButtonPin is HIGH");}
        ButtonPinState = true;
        //Sending request when the pin is HIGH
        //sendToPushingBox(RegID);       
      }
     
     
       if (digitalRead(ButtonPin) == LOW && ButtonPinState == true) // switch on ButtonPin is OFF
      {
        if(DEBUG){Serial.println("ButtonPin is LOW");}
        ButtonPinState = false;
        //Sending request when the pin is LOW       
        sendToGCM(RegID);
       
      }
      
   
      //DEBUG part
      // this write the respons from GCM Server.
      // You should see a "200 OK"
      if (client.available()) 
         {
         char c = client.read();
         if(DEBUG){Serial.print(c);}
         }
      
      // if there's no net connection, but there was one last time
      // through the loop, then stop the client:
      if (!client.connected() && lastConnected) 
         {
         if(DEBUG){Serial.println();}
         if(DEBUG){Serial.println("disconnecting.");}
         client.stop();
         }
      lastConnected = client.connected();
}


//Function for sending the request to GCM
void sendToGCM(char RegID[]){
  client.stop();
  if(DEBUG){Serial.println("connecting...");}

  if (client.connect(serverName, 80)) {
    if(DEBUG){Serial.println("connected");}

    if(DEBUG){Serial.println("sending request");}
    client.print("POST /gcm/send"); // http POST request
    client.println(" HTTP/1.1");
    client.print("Host: ");
    client.println(serverName);
    client.println("User-Agent: Arduino");
    client.println("Content-Type: application/x-www-form-urlencoded;charset=UTF-8");
    client.print("Authorization:key=");
    client.println(API_key);
    client.print("Content-length: "); // has to be exactly the number of characters (bytes) in the POST body
    client.println(199+1+strlen(data)); // calculate content-length    
    client.println("Connection: close");
    client.println("");
    client.print("registration_id="); //199 characters
    client.print(RegID);
    client.print("&"); // 1 character
    client.print(data);
    if(DEBUG){
    Serial.print(strlen(data));
    Serial.println(" bytes data");
    }
  } 
  else {
    if(DEBUG){Serial.println("connection failed");}
  }
delay(10);  
}

Hope this will be useful for you.

GCM_Arduino.ino (4.3 KB)

Perilex:
Recently, I found a solution for your problem. There is no need to send a POST request to the GCM servers with https. They also accept http!
So I modified a sampe code by pushingbox.com to use it with google cloud messaging (GCM).

I was looking for some weeks a project like this.
Just one little question
How to connect GCM to my android phone?

Hey Arybot,
this is not as easy. You have sign in to the "Google Play Developer Console" and open a GCM project as described here:

Then you have to program you own android app with an implemented GCM client:

This app has then to request the unique RegID associated with your project ID. This RegID must then be used with your API key in the arduino code.

If you are not familiar with programming android apps you better use services like notify my android
https://www.notifymyandroid.com/
or pushing box

This also works fine without app programming since the respective apps are already available in play store.

Perilex:
If you are not familiar with programming android apps you better use services like notify my android
https://www.notifymyandroid.com/
or pushing box
PushingBox - Notifications for your Internet of Things devices
This also works fine without app programming since the respective apps are already available in play store.

Thanks for answering.

I tried NMA and it works fine. Unfortunately you get their icons and interfaces.
I would like to get my personalized app. Unfortunately i'm not a programmer (i´m mechanic engineer),
so my best option at this time is pay for somebody who could create the GCM-android interface.

can you please guide me that how I can send data from arduino to GCM. I have created a GCM receiver Android Application which is able to receive Messages from a Java application but when I am trying to send data from Arduino I am not able to receive it. To provide you with more info. when I run my Java application it sends data and Android application receives and displays a Toast. but when I send data from Arduino it displays empty toast.

and could you please explain how
"char data[] ="data=your_data"; //data to send. obey GCM format!"
can be used, because I guess Android GCM receiver receives intents and extract data from intent and then displays it

Thanks in advance