Author Topic: Reed Switch Problems  (Read 622 times)

kbrooking

  • Full Member
  • ***
  • Posts: 104
    • View Profile
Reed Switch Problems
« on: January 10, 2017, 10:18:45 pm »
I noticed that a few of my 120 modules fail to catch changes in the reed switch. I'm using the reed switch example that turns on the Red led when ReedSwitch is = true and turn it off when it's false. On some of the modules the led remains in the same state even if I move the magnet back and forth.

Are there any tips or tricks to be aware of when using the reed switch to make it consistent?

Share on Facebook Share on Twitter


Nick_W

  • Full Member
  • ***
  • Posts: 215
    • View Profile
Re: Reed Switch Problems
« Reply #1 on: January 10, 2017, 10:47:17 pm »
I have implemented some code to work around some similar issues, for instance I make a persistent Boolean to store the read switch state, then compare the current value against the stored value. This way, you can call the read switch check routine multiple times - I then call it from the readswichchanged() interrupt. I usually call it twice, with a small delay between the two, to avoid debounce issues.

Can you share your code? I can show you what I have done to make it more reliable.

mc-Josh

  • Global Moderator
  • Newbie
  • *****
  • Posts: 27
    • View Profile
Re: Reed Switch Problems
« Reply #2 on: January 11, 2017, 09:43:13 am »
Try this event for the reed switch:

Code: [Select]
Shared Event ReedSwitchChanged()
        'debounce interrupt
        Thread.Sleep(100000)
        Thread.ClearHardwareEvent()
               
        If ReedSwitch = True Then
            'magnet far from reed switch
            LedRed = False   
        Else
            'magnet close to reed switch
            LedRed = True
        End If

    End Event
Useful Useful x 1 View List

Nick_W

  • Full Member
  • ***
  • Posts: 215
    • View Profile
Re: Reed Switch Problems
« Reply #3 on: January 11, 2017, 02:42:05 pm »
This is what I'm using:

Code: [Select]
    Public Sub PublishDoorStatus()
        //Thread.ClearHardwareEvent()
        Thread.Sleep(10000) '10ms debounce delay
        If Door_Status <> ReedSwitch Then
            Door_Status = ReedSwitch
            Dim jData As Json = New Json
            jData.Add("time", GetTimestamp())
            jData.Add("Door", Door_Status)
            MQTT.Publish("Data", jData, QoS.AtLeastOnce)
            //MQTT.Publish("Door", Door_Status, QoS.AtLeastOnce)
            MQTT.BeaconPublish(dataType.DOOR, Door_Status)
            LedGreenFlash()
        End If
    End Sub
   
    Shared Event ReedSwitchChanged()
        TimeSinceDoorClosed = Device.Uptime()
        TimeSinceKnockTriggered = 0
        PublishDoorStatus()
        //PublishDoorStatus() //call twice to deal with rapid door cycling...
    End Event

Door_Status is a shared boolean, defined in the class.

See my other post here  http://mcthings.createaforum.com/support/datetime-issues/msg1587/#msg1587
for example output.
Like Like x 1 View List

kbrooking

  • Full Member
  • ***
  • Posts: 104
    • View Profile
Re: Reed Switch Problems
« Reply #4 on: January 12, 2017, 11:35:04 pm »
Thanks Nick, Josh. That works very well now. I also replaced the magnet with one I bought off Amazon that seems to work better than the magnet that came with cases even through its feels much weaker.

Here is the new code I'm using based on your suggestion. Let me know if it can be improved upon.
Class Type1Sensor
    Shared sensorMessage As String
    Shared sensorType As Integer
    Shared sensorInterval As Integer
    Shared TempF As Float
    Shared TempC As Float
    Shared BattVolt As Integer
    Shared strBattVolt As String
   
    Shared Event Boot()
        sensorType = 1
        sensorInterval = 5 //minutes 
        sensorMessage = "closed"
    End Event
   
    Shared Event keepalive() RaiseEvent Every 10 Seconds
        BattVolt = Device.BatteryVoltage// Get battery voltage
        TempC = TempSensor.GetTemp
        TempF = TempSensor.ToFarenheit(TempC)
        MQTT.BeaconPublish(dataType.TEMPERATURE, TempF, BattVolt)
    End Event
   
    Shared Event inSync() RaiseEvent Every 60 Seconds //keep the status inSync with dashboard in case of fast transistations
        BattVolt = Device.BatteryVoltage// Get battery voltage
        TempC = TempSensor.GetTemp
        TempF = TempSensor.ToFarenheit(TempC)
        If ReedSwitch = True Then
            sensorMessage = "open"
        Else
            sensorMessage = "closed"
        End If
        MQTT.Publish(sensorType, sensorInterval, sensorMessage, TempF, BattVolt)
        Thread.Sleep(10000)
        Thread.ClearHardwareEvent()
    End Event
   
    Shared Event ReedSwitchChanged()
        //initialize system variables
        If ReedSwitch = True Then
            sensorMessage = "open"
            LedRed = True
        Else
            sensorMessage = "closed"
            LedRed = False
        End If
        BattVolt = Device.BatteryVoltage// Get battery voltage
        TempC = TempSensor.GetTemp
        TempF = TempSensor.ToFarenheit(TempC)
        MQTT.Publish(sensorType, sensorInterval, sensorMessage, TempF, BattVolt)
        Thread.Sleep(10000)
        Thread.ClearHardwareEvent()
    End Event
End Class
« Last Edit: January 12, 2017, 11:37:23 pm by kbrooking »

Nick_W

  • Full Member
  • ***
  • Posts: 215
    • View Profile
Re: Reed Switch Problems
« Reply #5 on: January 12, 2017, 11:58:18 pm »
The

Code: [Select]
Thread.Sleep(10000)
Thread.ClearHardwareEvent()

In inSync() won't do anything (except for a small delay), so you should remove that.

The second occurance in ReedSwitchChanged() should come first, ie before if ReedSwitch = True Then....

What this is doing is compensating for switch bounce. Because the reedswitch is a physical piece of metal, it can "bounce" so you get several interrupts while it is "bouncing". If you read the ReedSwitch while it is bouncing, you can get false readings. The idea behind Thread.sleep(10000) is to wait 10ms for it to stop bouncing, then read it, hence the delay has to come before you read the switch.

The Thread.ClearHardwareEvent() clears any waiting interrupts in the routine that called it, in this case probably caused by the switch bouncing (otherwise the interrupt may trigger twice - the queue is only 2 deep).

This means that you can't read events that happen faster than every 10ms, but given that this is a physical switch, that is probably not possible anyway.

Hope this explains!
« Last Edit: January 13, 2017, 12:01:56 am by Nick_W »