Motion sensor to control philips hue light bulbs

Hi, i have been trying to make a connection from spark core to philips hue bulbs without success, it was a success on my arduino with the ethernetClient but i can’t figure out why it doesn’t work with the TCPClient on spark core. When there is motion detected, i call the PUT request but nothing happens.

This is my code :

    TCPClient client;
byte server[] = { 192, 168, 1, 134 }; // Local light server
int val = 0;  


int inputPin = D3;              // choose the input pin (for PIR sensor)
int pirState = LOW;             // we start, assuming no motion detected
int calibrateTime = 10000;      // wait for the thingy to calibrate
int ledPin = D7;

void setup()
{
    Serial.begin(9600);
    pinMode(inputPin, INPUT);     // declare sensor as input
    pinMode(ledPin, OUTPUT);
    delay(1000);
    client.connect(server, 80);
    if (client.connected()){ //initiate connection
        Serial.println("connected");
    }
    else{
        Serial.println("failed");
    }
}

bool calibrated() {
  return millis() - calibrateTime > 0;
}



void readTheSensor() {
  val = digitalRead(inputPin);
}

void reportTheData() {
  if (val == HIGH) {
    if (pirState == LOW) {
      // we have just turned on
      Serial.println("Motion detected!");
      Spark.publish("spark-hq/motion");
      // We only want to print on the output change, not state
        digitalWrite(ledPin, HIGH);   // Turn ON the LED pins


       if (client.connect(server, 80)) {
        if(client.connected())
        {

            client.println("PUT /api/newdeveloper/lights/1/state");
            client.println("Host: 192.168.1.134");
            client.println("Content-Length:56");
            client.println("Expect 100-continue");
            client.println("Connection: Keep-Alive");
            client.println("");
            client.println("{\"on\":false}");
              
            
        }
        client.stop();
        Serial.println("stopping");
     }
    delay(10);
      
      
      pirState = HIGH;
    }
  } else {
    if (pirState == HIGH) {
      // we have just turned of
      Serial.println("Motion ended!");
              digitalWrite(ledPin, LOW);   // Turn ON the LED pins


      // We only want to print on the output change, not state
      pirState = LOW;
    }
  }
}


void loop(){
  if (calibrated()) {
    readTheSensor();
    reportTheData();
  }
}

Thanks

Can you try adding client.stop(), the client isn't automatically closed on the next call to client.connect().

Could you confirm also that you're seeing output on serial and the motion events are published?

1 Like

I checked the output and it doesn’t even put ‘connected’, only failed

If it’s not connecting, and it worked on an ethernet board and not on Wi-Fi, it’s possible your network is setup to give out certain IP addresses to clients on your Wi-Fi network, and another set of IP addresses on your ethernet network. I would make sure you can connect a computer to your Wi-Fi and can still hit that the IP address / port on your hue just to be sure!

Thanks,
David

Thanks for the reply, i tested with my laptop on wifi and iphone on 192.168.1.134 and it shows the hue default page

Hmm… Is the page definitely HTTP, and not HTTPS?

Oh! It looks like you're trying to connect during setup, but then also again during loop. I think you'd be more successful connecting if this logic were just in your loop and not in setup. Since you're not calling client.stop() in the setup, and it might take a little while to connect, etc.

Ok ill try that, i think it is HTTP, i don’t know, it is the port by default for the hue lights i can check too. thanks

Could your problem be that the event you are publishing begins with the string "spark"?

I found the following http://docs.spark.io/firmware/#spark-publish:

A Core may not publish events beginning with a case-insensitive match for "spark". Such events are reserved for officially curated data originating from the Spark Cloud.

hey thanks, i will try that and let you know tonight

Looks like your Content-Length is off. The server is waiting for 56 bytes, you only feed it 12…

Also make it easier on yourself by stripping out everything but the essential headers:

String command = "{\"on\": true}"
client.println("PUT /api/newdeveloper/lights/1/state");
client.print("Content-Length: ");
client.println(command.length());
client.println("");
client.print(command);

Hey, i combined all your stuff and it gives this :

TCPClient client;
byte server[] = { 192, 168, 1, 125 };
int val = 0;  


int inputPin = D3;              // choose the input pin (for PIR sensor)
int pirState = LOW;             // we start, assuming no motion detected
int calibrateTime = 10000;      // wait for the thingy to calibrate
int ledPin = D7;

void setup()
{
    Serial.begin(9600);
    pinMode(inputPin, INPUT);     // declare sensor as input
    pinMode(ledPin, OUTPUT);

}

bool calibrated() {
  return millis() - calibrateTime > 0;
}



void readTheSensor() {
  val = digitalRead(inputPin);
}

void reportTheData() {
  if (val == HIGH) {
    if (pirState == LOW) {
      // we have just turned on
      Serial.println("Motion detected!");
      // We only want to print on the output change, not state


       if (client.connect(server, 80)) {
        if(client.connected())
        {

            String command = "{\"on\": false}";
            client.println("PUT /api/newdeveloper/lights/1/state");
            client.print("Content-Length: ");
            client.println(command.length());
            client.println("");
            client.print(command);
              
            
        }
        client.stop();
        Serial.println("stopping");
     }
    delay(10);
      
      
      pirState = HIGH;
    }
  } else {
    if (pirState == HIGH) {
      // we have just turned of
      Serial.println("Motion ended!");


      // We only want to print on the output change, not state
      pirState = LOW;
    }
  }
}


void loop(){
  if (calibrated()) {
    readTheSensor();
    reportTheData();
  }
}

In the serial console, i get ‘Motion detected’, then it seems to jam there because it never said motion ended.
Also, i added a Serial.println in the connected function and it goes so the connection is good but it wont close my light.

I tested it many times on the hue api and it works with the same ip address and user newdeveloper.

Thanks

I have found that the hue bridge won’t update the lights until I read it’s response.

while (hueClient.available())
{
char c = hueClient.read();
Serial.print(c);
}

Where did you add this?