1

Forgive me if this is a really dumb question but I am new to IOT and hardware in general.

I have a Huzzah Feather ESP8266 and I am trying to make a bathroom occupancy sensor. I am using a standard reed switch door sensor (example here).

Ultimately what I want this device to do is:

  1. The plan is to wake the device from deep sleep when the door is closed, according to the documentation GPIO16 needs to be connected to RST to send a wake signal.

  2. Once awoken check the reed switch and send a message to Azure IoT hub that says the bathroom is occupied if door is closed.

  3. Put the device into deep sleep, waking every 30 seconds.
  4. Every time the device wakes check the switch, once the door is opened I send a message to Azure that the bathroom is not occupied and then put into deepSleep(0) (i.e asleep until the door is closed again, then the process repeats)

Right now this all works but in the opposite. I can wake the device when the door is opened, the message sends successfully to Azure.

From my super limited understanding of this it seems like what I want to do should be possible. I imagine I am missing something very simple, but I have hit a wall here.

I dont know how to make wiring diagrams so hopefully a description of my setup will suffice:

  • GPIO 16: Door sensor wire #2
  • RST: GPIO 16
  • GND: Door sensor wire #2

Simplified code sample:

void setup()
{
    initSerial(); //inits serial
    initWifi(); //initis wifi
    door_open(); //sends message
}

void door_open() {
  IOTHUB_CLIENT_LL_HANDLE iotHubClientHandle = IoTHubClient_LL_CreateFromConnectionString(connectionString, HTTP_Protocol);

  if (iotHubClientHandle == NULL)
  {
    Serial.print("Failed on IoTHubClient_LL_Create\r\n");
  }
  else
  {
    // Because it can poll "after 9 seconds" polls will happen 
    // effectively at ~10 seconds.
    // Note that for scalabilty, the default value of minimumPollingTime
    // is 25 minutes. For more information, see:
    // https://azure.microsoft.com/documentation/articles/iot-hub-devguide/#messaging
    unsigned int minimumPollingTime = 9;

    if (IoTHubClient_LL_SetOption(iotHubClientHandle, "MinimumPollingTime", &minimumPollingTime) != IOTHUB_CLIENT_OK)
    {
      Serial.print("failure to set option \"MinimumPollingTime\"\r\n");
    }

    if (IoTHubClient_LL_SetOption(iotHubClientHandle, "TrustedCerts", certificates) != IOTHUB_CLIENT_OK)
    {
      Serial.printf("failure to set option \"TrustedCerts\"\r\n");
    }

    if (IoTHubClient_LL_SetMessageCallback(iotHubClientHandle, IoTHubMessage, NULL) != IOTHUB_CLIENT_OK)
    {
      Serial.print("unable to IoTHubClient_SetMessageCallback\r\n");
    }

    IOTHUB_MESSAGE_HANDLE messageHandle;
    if(digitalRead(DOOR) == LOW) 
    {
      messageHandle = IoTHubMessage_CreateFromString("closed");
      Serial.println("Door closed");
    } 
    else 
    {
      messageHandle = IoTHubMessage_CreateFromString("open");
      Serial.println("Door Open");
    }

    if (messageHandle == NULL)
    {
      Serial.print("unable to create a new IoTHubMessage\r\n");
    }
    else
    {
      MAP_HANDLE propMap = IoTHubMessage_Properties(messageHandle);

      if (IoTHubClient_LL_SendEventAsync(iotHubClientHandle, messageHandle, sendCallback, (void*)1) != IOTHUB_CLIENT_OK)
      {
        Serial.print("failed to hand over the message to IoTHubClient");
      }
      else
      {
        Serial.print("IoTHubClient accepted the message for delivery\r\n");
      }
      IoTHubMessage_Destroy(messageHandle);
    }

    while (1)
    {
      IoTHubClient_LL_DoWork(iotHubClientHandle);
      ThreadAPI_Sleep(100);
    }
  }  
}

To clarify: Right now my device will wake when the door sensors magnetic parts are separated. I want the device to wake when the circuit is complete (i.e the sensors are together).

  • 1
    Your code IS important here. It is most likely the cause of your problem. So show us your code (as text and properly formatted). Also: what do you mean with "AND RST"? – chrisl May 4 '18 at 20:58
  • @chrisl added code sample, although the code is what I am most comfortable with (.NET developer). The problem currently is that it wakes when the sensors are apart (door opened), I want it to wake when sensors are together (door closed) – maccettura May 4 '18 at 21:02
  • @chrisl I tried to clarify my wire diagram in the edit too, One of the door sensor wires is in GPIO16, then RST has a wire to GPIO16, then the other door sensor wire is in GND – maccettura May 4 '18 at 21:06
  • Why are you connecting the Reset pin of your ESP to the reed switch? This will hold it in a reset state, until you open the door – chrisl May 4 '18 at 21:11
  • @chrisl I thought I was supposed to do that to get the device to reset. I want the device to be turned on/woken from deep sleep when the door is closed. According to what I have read about the ESP8266 to "wake" from deep sleep a signal needs to be sent to RST (from the docs: "GPIO16 needs to be tied to RST to wake from deepSleep"). This was just how I thought it worked. – maccettura May 4 '18 at 21:13
2

The RST (reset) pin of the ESP works as the reset pin of any other microcontroller. If you pull it to LOW long enough (the threshold is surely listed in the datasheet), the whole microcontroller will reset as if you had cut and reestablished the power supply. So it will not wake it from sleep, but reset it completely.

It is correct, that you can use GPIO16 connected to RST, to let the ESP reset itself from a deep sleep. This seems to be an internal hardware functionality, that is distinct from the normal IO hardware. But you cannot use the same pin for some other functionality at the same time. Your reed switch is closed, if the door is closed. So it gives a LOW level to GPIO16 and RST, holding it in reset state. In this state no code is executed, thus you never get a message, that the door is closed. When you then open the door, the switch opens too. Since the RST pin isn't pulled to LOW anymore, the ESP can boot and execute your code. The door is open, so you get the corresponding message.

So you have to use a different pin for the reed switch.

  • Is it possible to include a very straightforward "wiring diagram" to achieve what I want to do, I am very new to this haha – maccettura May 4 '18 at 21:47
  • Just connect the one wire from the reed switch to an unused pin of the Feather and set your code to the corresponding pin. I don't have a Feather and cannot be sure, what a good choice would be. But how about GPIO4 or 5. You don't seem to need the I2C hardware on them. – chrisl May 5 '18 at 14:04
  • So one wire from the reed switch into GPIO5 lets say, then where would the other go, RST? Doe's the switch need to be grounded? – maccettura May 5 '18 at 14:15
  • Do you know how detecting the state of a switch works? It doesn't seem so. The other wire from the reed switch has to go to ground, so that the pin is pulled to LOW, when the switch is closed. Also you should activate the internal pullup resistor with pinMode(DOOR, INPUT_PULLUP), else the pin will be floating when the door is open and will randomly change it's state. You should study a tutorial for switches/buttons, so that you really understand, whats happening there – chrisl May 5 '18 at 14:20
  • Like I said in the post, I am an absolute beginner in hardware. I have zero electrical engineering experience. I want to make sure I am understanding you right, thats why I am asking supplemental questions. Are you saying that my exact setup will work if I switch from GPIO16 to GPIO5? So Reed switch 1 to GPIO5, GPIO5 to RST and Reed Switch 2 to GND – maccettura May 5 '18 at 14:25
2

I would get an NC or NO reed switch, the opposite of whatever you have now that's backwards. I would then get rid of all the sleep wakeup stuff and turn the unit on through the reed switch, so it has power when the door is closed, if that's more common than it being open. When closed (powered), the MCU sends a ping on boot to a server that says "hey i closed", and go to deep sleep for 10 seconds.

Once re-awaking, send out a ping that says "I'm still busy". The server needs a tiny bit of smarts, a time-out feature that sets the door state as open 12 seconds after the last ping (10s + some accounting for wifi delays).

This setup uses NO standby power, and only a tiny amount of battery-killing on-time, so it should last a lot longer than trying to sleep and externally wakeup.

For added efficiency, consider building an ESPNOW router with two more ESP8266s. Once you have that ESPNOW router up and running, you can fire off a ping in about 200ms (from a cold/warm boot) instead of 2000ms with wifi, and go back to sleep. This extends your battery life ~10x, at the cost of running two more ESPs 24/7 where power is easily available.

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.