Author Topic: Tilting Trigger on the Accelerometer  (Read 3979 times)

SK

  • Newbie
  • *
  • Posts: 18
    • View Profile
Tilting Trigger on the Accelerometer
« on: January 09, 2017, 06:48:10 pm »
Hi all,
Just a couple of questions on the x, y, z sensor on the accelerometer:
  • Is there a way to wake up the MC205 on change in axis?
  • Is there a way to make it wait until the device has stopped tilting and report to sigfox the final axis it has tilted to?
  • Can I use the MMA8652 library that comes with MCStudio for this?

I've looked at dmm's tilt code(http://mcthings.createaforum.com/mc-innovations/accelerometer-code-help/msg1303/#msg1303) but instead of waking up every 30 sec, I'd like it to only wake up only when it has changed orientation.
Cheers

Share on Facebook Share on Twitter


mc-T2

  • Administrator
  • Sr. Member
  • *****
  • Posts: 252
  • mc-Things! The opportunities are endless!
  • Location: Canada
    • View Profile
Re: Tilting Trigger on the Accelerometer
« Reply #1 on: January 10, 2017, 11:33:25 am »
Hi SK,

1) Yes, you can use the accelerometer to wake up the mcDemo205
2) Yes, you can write a code that allows the device to wait until it does not detect movement again and then send that information via SIGFOX
3) No, the mma8625 library is for the accelerometer on the mcmod110. the mcMod120 and the mcDemo205 use the LIS2DH12 accelerometer library. Here is a link to the datasheet for this accelerometer: http://www.st.com/content/ccc/resource/technical/document/datasheet/12/c0/5c/36/b9/58/46/f2/DM00091513.pdf/files/DM00091513.pdf/jcr:content/translations/en.DM00091513.pdf


You can find the correct library here (Thanks to Nick_W!): https://github.com/NickWaterton/mcScript/tree/master/projects/DoorSensor%20-%20120 . You can also check out Nick's script that uses the accelerometer to detect a knock. You can modify this to your use-case.

Also, this may help:

http://mcthings.createaforum.com/support/accelerometer-events/msg1139/#msg1139

We released a beta version of a garage door open/closed detection using the accelerometer on the mcMod110 (MMA8652 accelerometer). You could use some of this code (modified to use the LIS2DH12 library). You can also take sections for dmm's code (http://mcthings.createaforum.com/mc-innovations/accelerometer-code-help/msg1303/#msg1303) for relaying the tilt value and using the above different codes, can incorporate the interrupt function to relay that information.

I would recommend looking through the mcScript guide (https://static1.squarespace.com/static/5644f11fe4b0d6ca7d80d351/t/57c61f35b8a79ba9708b2cc4/1472601916268/mc-ScriptUserGuide.pdf) to become familiar with the different functions available within the programming language. This document should help you to write the wait time required before sending the information out via SIGFOX.
There are two accelerometer interrupts available so you may want to look at using both interrupts for your code. maybe something like:
1) have the accelerometer 'wake up' when it detects movement
2) have the accelerometer detect when it has stopped moving
3) wait a specific period of time before sending the last tilt axis to the cloud via SIGFOX

I also have an example project that I found in my projects that might also help you out:
Code: [Select]
Class LISDH12_Test
    Shared accel As LIS2DH12
   
    Shared Event Boot()
        accel = New LIS2DH12
       
        'set accelerometer to cause interrupt if accelation is > 1.15Gs for longer than 2ms (any axis)
        accel.ConfigureShockInterrupt(1.15, 2.0)
    End Event
   
    Shared Event AccelerometerInt1()
        'debounce interrupt
        Thread.Sleep(100000)
        Thread.ClearHardwareEvent()
       
        'Read Int source register to clear interrupt
        If ((accel.ReadSingleByte(LIS2DH12.INT1_SRC_REG) & LIS2DH12.INT_ACTIVE) = LIS2DH12.INT_ACTIVE) Then
            'interrupt generated
           
            LedRed = Not LedRed
           
        End If
       
        'restart interrupt       
        accel.WriteSingleByte(LIS2DH12.INT1_CFG_REG, 0x2a)
    End Event
End Class
This is a simple example of using the accelerometer to detect movement in any axis and then turn on the LED on the module. A combination of all the codes mentioned and listed above should give you a good starting point to create code specific to your use-case.

Hope that helps!
« Last Edit: January 10, 2017, 11:47:01 am by mc-T2 »
Need more mc-Modules, mc-Gateways or other mc-Things? Check out our product page: www.mcthings.com/products. mc-Development kits are available too!
Check out a live Dashboard using mcThings and Losant! Click here: https://goo.gl/ST43hB

SK

  • Newbie
  • *
  • Posts: 18
    • View Profile
Re: Tilting Trigger on the Accelerometer
« Reply #2 on: January 11, 2017, 07:27:15 pm »
Thanks for the feedback.

I just wanted to check if the MMA8652 could be used for the 205 since it already has a interrupt on orientation function in it.
I've been able to use the LIS2DH12 to detect movement, but I'm not sure on where to begin with figuring out how to detect/wake on change in orientation.
The functions from the LIS2DH12 library 'accel.Accel(LIS2DH12.X_AXIS)', 'accel.Accel(LIS2DH12.Y_AXIS)' and 'accel.Accel(LIS2DH12.Z_AXIS)' all return 0 but I haven't yet figured out why.

 :-\

Bartw

  • Newbie
  • *
  • Posts: 29
    • View Profile
Re: Tilting Trigger on the Accelerometer
« Reply #3 on: January 11, 2017, 08:43:35 pm »
Thanks for posting...
I just noticed the part change in the specification.

This driver here worked from the get go.
https://github.com/NickWaterton/mcScript/blob/master/projects/LISDH12%20Beta/LIS2DH12.mcScript
« Last Edit: January 11, 2017, 09:01:08 pm by Bartw »

Nick_W

  • Full Member
  • ***
  • Posts: 215
    • View Profile
Re: Tilting Trigger on the Accelerometer
« Reply #4 on: January 12, 2017, 11:10:36 pm »
The library Bartw refers to is the only currently working library, and its "alpha" at best. I am in the process of making a full featured library for the accelerometer in the 120 module, but was waiting for the battery issue to be solved.

With that likely solved in the latest firmware, I will get back to making this library into a full "beta" release, but it may take a little while.

The accelerometer in the 120 module can do what you want, and there are "bare bones" hooks into the functions in the library - but they are mostly untested, and need a deep understanding of the device and how it works (ie deep dive into the data sheet) to make working code from the current library. This was just my first pass.

I also have a 205, and some 120's, so I'm interested in getting this library to a usable state. I'll let you know when I have something easier to use.

If you dive into it, you could get something working from what we currently have though.

Take a look at

Code: [Select]
    Public Sub SetInterruptEnable1Bits(mode As Byte)
        'Set Interrupt 1 Enable bits  bits 1,2,3,4,5,6,7 (bit 0 not used)
        '(0: disable; 1: enable)
        'I1_CLICK CLICK interrupt on INT1 pin. Default value 0. bit 7
        'I1_AOI1 AOI1 interrupt on INT1 pin. Default value 0. bit 6
        'I1_AOI2 AOI2 interrupt on INT1 pin. Default value 0. bit 5
        'I1_DRDY1 DRDY1 interrupt on INT1 pin. Default value 0. bit 4
        'I1_DRDY2 DRDY2 interrupt on INT1 pin. Default value 0. bit 3
        'I1_WTM FIFO watermark interrupt on INT1 pin. Default value 0. bit 2
        'I1_OVERRUN FIFO overrun interrupt on INT1 pin. Default value 0. bit 1
        write(CTRL_REG3, (read(CTRL_REG3) & ~INT1_ENABLE_MASK) | mode)
    End Sub

And

Code: [Select]
    Public Sub SetINT1ActiveInterrupt(interrupt As Byte)
        'AOI And/Or combination of interrupt events. Default value: 0. Refer to Table 51 bit 7
        '6D 6-direction detection function enabled. Default value: 0. Refer to Table 51 bit 6
        'AOI 6D Interrupt mode
        ' 0  0 OR combination of interrupt events
        ' 0  1 6-direction movement recognition
        ' 1  0 AND combination of interrupt events
        ' 1  1 6-direction position recognition
        'Default value: 0 (0: disable interrupt request;1: enable interrupt request)
        'ZHIE/ZUPE Enable interrupt generation on Z high event or on direction recognition. bit 5
        'ZLIE/ZDOWNE Enable interrupt generation on Z low event or on direction recognition. bit 4
        'YHIE/YUPE Enable interrupt generation on Y high event or on direction recognition. bit 3
        'YLIE/YDOWNE Enable interrupt generation on Y low event or on direction recognition. bit 2
        'XHIE/XUPE Enable interrupt generation on X high event or on direction recognition. bit 1
        'XLIE/XDOWNE Enable interrupt generation on X low event or on direction recognition. bit 0
        write(INT1_CFG, interrupt)
    End Sub

AOI is the Accelerator Orientation Interrupt, DRDY is Data Ready.. You need to configure things correctly first, and clear the interrupts after they fire though.

Read through the library and see what you can come up with.
« Last Edit: January 12, 2017, 11:26:20 pm by Nick_W »

Nick_W

  • Full Member
  • ***
  • Posts: 215
    • View Profile
Re: Tilting Trigger on the Accelerometer
« Reply #5 on: January 15, 2017, 08:59:34 pm »
Update:

Checkout my github https://github.com/NickWaterton/mcScript for a new Demo 205 test program!

This program publishes the GPS location on motion start, or end of motion (selectable). Currently publishing via MQTT as we don't have a SigFox network in Canada, but good for proof of concept.

Also new: updated LIS2DH12 (accelerometer) library, with easy to configure options, and capability of reading the event name that triggered an interrupt (double_click, x_axis etc) (see demo 205 program for usage, and source for details).

Updated MQTT library (only one change as mcStudio 906 didn't like checking the count of Nothing) minor, but needed, still backwards compatible.

New mcthings_log.py Python program for logging (and displaying) MQTT data from your modules (actually should work with any mqtt data), features pretty printing of json, decoding of timestamps (at least my implementation of them), calculation of transmission delay, etc. Command line configurable, probably full of bugs, but works for me.

NOTE: mcStudio 906 and the demo 205 have some serious gremlins in them. The following is the only way I have been able to load a program into my 205:

  • Start mcStudio (this usually takes two tries), and load project. Do not connect 205 yet!
  • Click on build (hammer, icon). This will fail don't worry! This is just a test from the demons of debugging hell
  • Click on build again (wait.. wait) success! Demons begone. MCThings people you owe me 4 hours of my life back for figuring this out
  • Remove tiny power jumper from 205, and try not to loose it again...
  • Connect 205 via USB (I have never had OTA update working, so go with this)
  • Open "devices" screen, and connect "testboardGateway"
  • Insert tiny power jumper in USB position (assuming you haven't lost it again)
  • Wait for device to appear, and click on connect
  • Back on the main screen, click on "download to device" (or upload if you think that way), anyway, send program to 205. Do not try run, to debug, mcStudio will crash!
  • Wait for success message box, click OK. Then disconnect USB (device will not publish when connected to USB, so you can't see any messages)
  • Move tiny power jumper to battery position, and watch mqtt/logging program for data. Shake 205 to activate GPS, gasp as data appears (OK there is some waiting, a lot of waiting)

If you want to change anything, you can't reconnect the 205 (go ahead and try, mcStudio will crash when you click on "connect"). You have to make your changes, save them, then close mcStudio, and start from step 1 above. If you think this takes a long time to write/debug a program this way, you would be right.

If anyone has found a faster/easier way to do this, please let me know and I will be eternally grateful.

I am certain that there are some bugs in my test program, but the debug cycle was so exhausting, when it was working reasonably well, I decided to release it into the wild.

Things to note!

The push buttons do not work the way the way you think (at least if you are a positive logic person like me), they work on negative inside out logic. To be fair the clues are in the documentation, but the example is bonzo (if that is a word). The logic is active low (clue!), so false is button pressed. The example actually works because it ignores the button press interrupt, and detects the button release interrupt (SW1 = true = not pressed). So if you think the example detects button presses, it doesn't, it detects button unpresses by testing to see if the SW1/2 variable is unchanged from the normal state (true). As I say bonzo to me until you figure it out (but it is important if you want to detect long vs short presses).

Devices (all of them) do not publish when connected to USB testboard gateway. As you don't seem to be able to disconnect the gateway once it's connected. You will see nothing published after loading the program.

You can't debug a program with an MQTT.Subscription in it (also any type of module)

If you have a run time error in your program, Led 2 will flash every 5 seconds or so as the modules reboots. If you are using LED 2 to indicate activity, this may confuse you for some time.

It is really hard to tell which LED is flashing as they are all red, and right next to each other. Obviously given the cost of different coloured LEDs, this is understandable, so you have to look really closely to see what is being indicated. Or just turn an LED on and leave it on to make things easier.

With the current scarcity of switches, a tiny jumper was needed to select USB or battery power. I suggest attaching it with a large chain, to prevent loosing it.

Try it out!, let me know what you think, and feel free to improve it.

All I need now is a SigFox network, and a gateway that doesn't loose WiFi at crucial moments.

And yes, the wife is away visiting family this weekend.
« Last Edit: January 15, 2017, 09:47:20 pm by Nick_W »
Winner Winner x 1 Love Love x 1 View List

SK

  • Newbie
  • *
  • Posts: 18
    • View Profile
Re: Tilting Trigger on the Accelerometer
« Reply #6 on: February 24, 2017, 03:20:27 am »
Nick your accelerometer/timer libraries and examples have been so helpful. Thank you so much.

I managed to get a program working which sends x, y, and z values followed by the location to sigfox at the end of movement. However, I was wondering what the x, y, z values meant? What units are they in?

Eg. I got x = 5.603067e-39, y = 5.557149e-39, z = 1.75883332e-38.
 :-[

Nick_W

  • Full Member
  • ***
  • Posts: 215
    • View Profile
Re: Tilting Trigger on the Accelerometer
« Reply #7 on: February 24, 2017, 08:21:52 am »
Glad you found them useful!

The values for X,Y,and Z are in gravities (g) so Z should usually read 1.0 (depending on the orientation of the module). X and Y would read 0 (no acceleration). As you rotate the module in 3 axes, the values would change from 0 to 1.0.

Can you post your code? I can look at what you are reading.

SK

  • Newbie
  • *
  • Posts: 18
    • View Profile
Re: Tilting Trigger on the Accelerometer
« Reply #8 on: February 26, 2017, 02:31:32 pm »
This is my code:
Code: [Select]
// Based off 'End Motion' detection program by Nick Waterton (https://github.com/NickWaterton/mcScript/tree/master/libraries/accelerometer/lis2dh12/examples/EndMotionTest)
// This program detects Start and End of Motion for the MC DEMO 250 module
// After detecting End of Motion, it fires up the GPS and sends the location to Sigfox
// Needs Timing and LIS2DH12(accelerometer) libraries to run
// Libraries by N Waterton 25th January 2017 (https://github.com/NickWaterton/mcScript)

// default configuration is:
// Low Power mode, 50 Hz, 2G
// Sleep mode enabled only when interrupts are enabled (data rate is 10Hz in sleep mode) - wake time is 5 seconds (ie accelerometer wakes up for 5 sconds when threshold is exceeded).
// Motion detection on INT1, pin 1.

// For help go to (http://mcthings.createaforum.com/index.php)
// McScript user guide can be found here (https://www.mcthings.com/downloads/)
// Shaika.K February 2017


Class MotionLocation
    ' Libraries and accelerometer fields
    Shared accel As LIS2DH12 //accelerometer library
    Shared pin1data As Json //a Json object is a list and at each index of the list it stores a name and a value.
    Shared pin2data As Json //to access value at a particular index go (.Item(0).Value().Get___()) eg pin2data.Item(0).Value().Get___()
    //to access name at a particular index go (.Item(0).Name()) eg pin2data.Item(0).Name()
    Shared pin1count As Integer
    Shared pin2count As Integer
    Shared Start_Motion_Detected As Boolean //used to detect start of motion
    Shared End_Motion_Detected As Boolean //used to detect end of motion
    Shared motionStartTime As String
    Shared timer1 As Timing //Timer library
   
    ' Message Types
    Const MSGTYPE_LOCATION As Byte = 1
   
    ' Configuration Constants
    Const GPS_TIMEOUT_uS As Integer = 120000000 '120 second timeout
    Const GPS_MIN_SAT_COUNT As Integer = 3 'minimum satellites to get a fix
   
    ' Battery Status
    Const BAT_CRITICAL As Byte = 0
    Const BAT_LOW As Byte = 1
    Const BAT_NORMAL As Byte = 2
    Const BAT_OPTIMAL As Byte = 3
   
    Shared Event Boot()
        //Lplan.SetMidPowerMode(5000)
        Lplan.SigfoxRadioZone(SigfoxRadioZone.Australia)
        Led2 = False
        Led3 = False
        pin1data = New Json
        pin2data = New Json
        Start_Motion_Detected = False
        End_Motion_Detected = True
        timer1 = New Timing()
        accel = New LIS2DH12
        If accel.online Then
            If LIS2DH12.VERSION < 5 Then
                'Both LED means error on Boot -> LIS2DH12 Library is out of Date, please upgrade!
                Led2 = True
                Led3 = True
            Else
                'Nicks's setup:                 
                accel.Setup(LIS2DH12.LOW_POWER_MODE, LIS2DH12.DATA_RATE_50HZ, LIS2DH12.SCALE_2G)               
                accel.ConfigureMotionInterrupt(1.15, 20.0, 1, 1, True) 'INT1 pin 1, Latched. Pin 1 activates AccelerometerInt1()
                'accel.ConfigureTransientInterrupt(0.15, 20.0) 'same as above
                'accel.ConfigureTransientInterrupt(0.15, 20.0, 1, 1, True, LIS2DH12.INT_SRC_YH) ' as above, but only Y High axis interrupt enabled
                accel.SetFilterBypass(False) 'disable HP filter bypass (values read will be with HP applied - usually this is enabled, or you just read 0's with interrupts enabled, but gets re-enabled in Publish() )
               
                'To publish a paramterer value to Sigfox insert the corresponding number.
                '0= general control registers
                '1= Interrupt 1 settings
                '2= Interrupt 2 settings
                '3= Click Interrupt settings
                '4= Misc others
                Dim accelconfig As Json = accel.ReadConfiguration(0) //general control registers
                'Lplan.Sigfox(accelconfig.Item(0).Value().GetString())
            End If
        Else
            'Led3 means error on Boot -> accel didnt boot
            Led3 = True
        End If
        //MQTT.use_delay = True
        Led2 = True //indicates start of detection
    End Event
   
    Shared Event AccelerometerInt1() //this event is activated after pin1 is initialised and boot finsihes             
        //MOTION/TRANSIENT Detection INT1
        'Read Int source register To clear interrupt And get source
        Dim IntSource As Json = accel.GetInt1SourceAsJson(LIS2DH12.J_VALUES | LIS2DH12.J_SUMMARY)
        If IntSource.Count> 0 Then 'if we have an interrupt (of any kind, x,y or z)           
            MotionLocation.updateTimer(True) //next motion has started
            End_Motion_Detected = False   
            Led2 = False       
        End If         
    End Event
   
    Shared Event MotionCheck() RaiseEvent Every 10 Seconds //change time to max time without motion to detect (actual time could be double this in theory)
        If Start_Motion_Detected And End_Motion_Detected Then //no motion in last 10 seconds
            MotionLocation.updateTimer(False) //motion ended
        End If
       
        End_Motion_Detected = True               
       
    End Event
   
    Shared Function updateTimer(motion As Boolean) As Nothing
        If motion Then
            If Not Start_Motion_Detected Then //not old "start motion" but new one
                motionStartTime = Timing.GetTimestamp(TIME_FORMAT.T_SECONDS)
                timer1.GetTimeSpan() 'start timer
                Start_Motion_Detected = True
                Led2 = True
                Thread.Sleep(50000)
            End If
        Else
            Dim motionStopTime As String = Timing.GetTimestamp(TIME_FORMAT.T_SECONDS)
            Dim duration As Integer = (timer1.GetTimeSpan() / 1000).ToInteger         
            Start_Motion_Detected = False
            Thread.Sleep(50000)   
            Led2 = False
            Lplan.Sigfox(getOrientation(0)) 'send message to sigfox
            Thread.Delay(20000000)
            Lplan.Sigfox(getOrientation(1)) 'send message to sigfox
            Thread.Delay(20000000)
            Lplan.Sigfox(getOrientation(2)) 'send message to sigfox
            Thread.Delay(20000000)
            Led3 = True   
            Device.StartGPS(GPS_TIMEOUT_uS, GPS_MIN_SAT_COUNT)           
        End If
    End Function
       
    'runs after GPS starts up, when GPS location has been aquired OR timeout has been reached
    Shared Event LocationDelivery()
        Dim msg As ListOfByte = New ListOfByte() 'message to send to sigfox
       
        Dim Lat As Float = Device.GetLatitude()
        Dim Lon As Float = Device.GetLongitude()       
       
        'if GPS timed out when retrieving location
        If Lat.IsNaN() Then
            Lat = 0.0 'lattitude is 0
        End If
        If Lon.IsNaN() Then
            Lon = 0.0 'longitude is 0
        End If
       
        msg.Add(0x00) '00 is an indication to Losant that this payload contains location data
        msg.AddFloat(Lat)
        msg.AddFloat(Lon)       
       
        Lplan.Sigfox(msg) 'send message to sigfox
        Led3 = False 'turn off Led to indicate transmission complete     
    End Event
   
    Private Function getOrientation(type As Integer) As ListOfByte
        accel.SetFilterBypass(True) 'enable HP filter bypass (so that values read below do not go through HP filter) - this is the normal configuration
        accel.GetAccel() 'dummy read
        Do
            Thread.Sleep((accel.GetmsFromDataRate* 1000).ToInteger) 'wait 1 clock cycle for new unfiltered reading
        While Not accel.NewDataAvailable() 'wait for new data
        Dim accelValues As ListOfFloat = accel.GetAccel()
        Dim PitchRoll As ListOfFloat = accel.GetPitchRollDegrees()
        accel.SetFilterBypass(False) 'disable filter bypass again, this means the *values* given by interrupts (if you are displaying them) will be with HP filter enabled.
       
        Dim msgData As ListOfByte = New ListOfByte()
        msgData.Add(0x08) '08 is an indication to Losant that this payload contains location data
        msgData.AddInteger(type)
        'msgData.AddFloat(accelValues(0)) //x
        msgData.AddFloat(accelValues(type)) //y
        'msgData.AddFloat(accelValues(2)) //z
        'msgData.AddFloat(PitchRoll(0))
        'msgData.AddFloat(PitchRoll(1))
       
        Return msgData         
       
    End Function
   
End Class

Am I doing things correctly?
I got the values x = 5.603067e-39, y = 5.557149e-39, z = 1.75883332e-38 when I shook the the device and laid it on its back like normal.

Nick_W

  • Full Member
  • ***
  • Posts: 215
    • View Profile
Re: Tilting Trigger on the Accelerometer
« Reply #9 on: February 26, 2017, 02:45:06 pm »
I'll try this on my 205 tomorrow, first thing I notice is that you keep tuning the HP bypass on and off, why not just leave it on? if you accidentally read with bypass off, you'll just get 0's.

SK

  • Newbie
  • *
  • Posts: 18
    • View Profile
Re: Tilting Trigger on the Accelerometer
« Reply #10 on: February 26, 2017, 04:16:32 pm »
I don't really understand what that line does, I modified you publish() function and took out the json vars and MQTT lines and left everything else including setFilterBypass.

My getOrientation():
Code: [Select]
Private Function getOrientation(type As Integer) As ListOfByte
        accel.SetFilterBypass(True) 'enable HP filter bypass (so that values read below do not go through HP filter) - this is the normal configuration
        accel.GetAccel() 'dummy read
        Do
            Thread.Sleep((accel.GetmsFromDataRate* 1000).ToInteger) 'wait 1 clock cycle for new unfiltered reading
        While Not accel.NewDataAvailable() 'wait for new data
        Dim accelValues As ListOfFloat = accel.GetAccel()
        Dim PitchRoll As ListOfFloat = accel.GetPitchRollDegrees()
        accel.SetFilterBypass(False) 'disable filter bypass again, this means the *values* given by interrupts (if you are displaying them) will be with HP filter enabled.
       
        Dim msgData As ListOfByte = New ListOfByte()
        msgData.Add(0x08) '08 is an indication to Losant that this payload contains location data
        msgData.AddInteger(type)
        'msgData.AddFloat(accelValues(0)) //x
        msgData.AddFloat(accelValues(type)) //y
        'msgData.AddFloat(accelValues(2)) //z
        'msgData.AddFloat(PitchRoll(0))
        'msgData.AddFloat(PitchRoll(1))
       
        Return msgData         
       
    End Function

Your publish() from End Motion program -> https://github.com/NickWaterton/mcScript/blob/master/libraries/accelerometer/lis2dh12/examples/EndMotionTest/EndMotionTest.mcScript:
   
Code: [Select]
Shared Event Publish() RaiseEvent Every 10 Seconds
        accel.SetFilterBypass(True) 'enable HP filter bypass (so that values read below do not go through HP filter) - this is the normal configuration
        accel.GetAccel() 'dummy read
        Do
            Thread.Sleep((accel.GetmsFromDataRate* 1000).ToInteger) 'wait 1 clock cycle for new unfiltered reading
        While Not accel.NewDataAvailable() 'wait for new data
        Dim accelValues As ListOfFloat = accel.GetAccel()
        Dim PitchRoll As ListOfFloat = accel.GetPitchRollDegrees()
        accel.SetFilterBypass(False) 'disable filter bypass again, this means the *values* given by interrupts (if you are displaying them) will be with HP filter enabled.
        Dim jint As Json = New Json
        'NOTE: If you put too much in a json object, it will cause a run time error (overlow) and the module will reboot
        '      Below is too much for one json object, so I've split it into two
       
        Dim jData As Json = New Json
        jData.Add("X_Accel", accelValues(0))
        jData.Add("Y_Accel", accelValues(1))
        jData.Add("Z_Accel", accelValues(2))
        jData.Add("Pitch", PitchRoll(0))
        jData.Add("Roll", PitchRoll(1))
        'jData.Add("PitchAlt", PitchRoll(2))
        'jData.Add("RollAlt", PitchRoll(3))
        If Start_Motion_Detected Then
            jData.Add("State", "Moving")
        Else
            jData.Add("State", "Stationary")
        End If
        MQTT.Publish("Data", jData)
       
        If pin1data.Count() > 0 Then
            jint.Add("Pin1 Count", pin1count) 'number of interrupts generated
            jint.Add("Pin1", pin1data)
        End If
        If pin2data.Count() > 0 Then
            jint.Add("Pin2 Count", pin2count) 'number of interrupts generated
            jint.Add("Pin2", pin2data)
        End If
        If jint.Count> 0 Then
            MQTT.Publish("Ints", jint)
        End If
       
        pin1data.Clear()
        pin2data.Clear()
        pin1count = 0
        pin2count = 0
    End Event

Should I leave it as true?

Nick_W

  • Full Member
  • ***
  • Posts: 215
    • View Profile
Re: Tilting Trigger on the Accelerometer
« Reply #11 on: February 26, 2017, 04:51:22 pm »
I think that was more in the way of an example, normally you leave it on true, and you don't need to do any of the other stuff - dummy read, sleep etc, you just read GetAccel().

To explain the HP filter, when it is enabled, it removes the DC component (caused by gravity ie 1). This is what is then used by the interrupt routines (except orientation). So if you want an interrupt to trigger on acceleration of 0.5, with the hp filter on, gravity is ignored, and it triggers when the change of acceleration exceeds 0.5 (otherwise it would trigger all the time as acceleration due to gravity is 1.0).

If you read GetAccel(), you would read 0 for X,Y and Z, unless you were shaking the module or something.

So to get the real reading, you turn hpbypass on, now the readings from GetAccel() are the absolute values (including gravity). The interrupts are not affected, they still use the filtered values.

Anyway, I'll take a look tomorrow, and see what I can do.

Nick_W

  • Full Member
  • ***
  • Posts: 215
    • View Profile
Re: Tilting Trigger on the Accelerometer
« Reply #12 on: February 27, 2017, 09:33:38 am »
Ok, I have it working, as is!.

There are a couple of problems, mostly minor. First, your GetOrientation() function is declared as Private, which is not valid (but does work due to a bug in mcStudio) it should be shared, and then referenced as MotionLocation.GetOrientation(). You can leave it as it is, but just note that this is not strictly a valid definition.

Second, you have mixed two of my examples together. The "EndMotion" example uses accel.ConfigureTransientInterrupt(0.15, 20.0, 1, 1, True), which you have changed to accel.ConfigureMotionInterrupt(1.15, 20.0, 1, 1, True). This is important as they are two similar but different things.

ConfigureTransientInterrupt uses the High Pass filter, hence the example has all the enabling and disabling of hpbypass to get absolute values.
ConfigureMotionInterrupt does not use the High Pass filter, so no manipulation of hpbypass is needed to get absolute values, but the threshold value has to be greater than 1.0 to prevent the interrupt triggering constantly because of earths acceleration due to gravity.

Having said that, it doesn't matter, you just don't need it.

So substituting MQTT.Publish for your SigFox publishing (we don't have SigFox in Canada), I get this:

Code: [Select]
MCThings/00020004/Sigfox 0 -0.064000
MCThings/00020004/Sigfox 1 0.064000
MCThings/00020004/Sigfox 2 -1.008000
MCThings/00020004/Sigfox GPS 43.601692,-79.708992

Which looks correct (Z is -1 as it depends which way up the module is). This is without changing your code.

I would remove the hpbypass stuff as you don't need it (you don't need accel.ReadConfiguration(0) either unless you want to see the accelerator configuration):

Code: [Select]
    Private Function getOrientation(type As Integer) As ListOfByte
        Dim accelValues As ListOfFloat = accel.GetAccel()
        Dim PitchRoll As ListOfFloat = accel.GetPitchRollDegrees()

        Dim msgData As ListOfByte = New ListOfByte()
        msgData.Add(0x08) '08 is an indication to Losant that this payload contains location data
        msgData.AddInteger(type)
        'msgData.AddFloat(accelValues(0)) //x
        msgData.AddFloat(accelValues(type)) //y
        'msgData.AddFloat(accelValues(2)) //z
        'msgData.AddFloat(PitchRoll(0))
        'msgData.AddFloat(PitchRoll(1))
        Dim top_msg As String = "Sigfox " + type.ToString()
        Dim msg_payload As String = accelValues(type).ToString()
        MQTT.Publish(top_msg, msg_payload)
        Return msgData         
       
    End Function

Boot() event
Code: [Select]
'Nicks's setup:                 
                accel.Setup(LIS2DH12.LOW_POWER_MODE, LIS2DH12.DATA_RATE_50HZ, LIS2DH12.SCALE_2G)               
                accel.ConfigureMotionInterrupt(1.15, 20.0, 1, 1, True) 'INT1 pin 1, Latched. Pin 1 activates AccelerometerInt1()
                'accel.ConfigureTransientInterrupt(0.15, 20.0) 'same as above
                'accel.ConfigureTransientInterrupt(0.15, 20.0, 1, 1, True, LIS2DH12.INT_SRC_YH) ' as above, but only Y High axis interrupt enabled
                'accel.SetFilterBypass(False) 'disable HP filter bypass (values read will be with HP applied - usually this is enabled, or you just read 0's with interrupts enabled, but gets re-enabled in Publish() )
               
                'To publish a paramterer value to Sigfox insert the corresponding number.
                '0= general control registers
                '1= Interrupt 1 settings
                '2= Interrupt 2 settings
                '3= Click Interrupt settings
                '4= Misc others
                'Dim accelconfig As Json = accel.ReadConfiguration(0) //general control registers
                MQTT.Publish("Status", "Online")
                'Lplan.Sigfox(accelconfig.Item(0).Value().GetString())

If you are getting 0's in losant, its due to something else. I do notice that you are publishing to SigFox every 20 seconds. This does not seem allowable by SigFox, as they restrict you to 140 messages per day, or one per 10 minutes. Maybe they don't restrict frequency, just the total number per day - as I say we don't have SigFox so I don't know. Once per 20 seconds does seem a bit fast for SigFox though.

Anyway, your code does work as is. Your problem is elsewhere.

Hope this helps.
« Last Edit: February 27, 2017, 09:47:54 am by Nick_W »

SK

  • Newbie
  • *
  • Posts: 18
    • View Profile
Re: Tilting Trigger on the Accelerometer
« Reply #13 on: February 27, 2017, 03:15:20 pm »
Thank you. Yes I used the motion trigger instead of transient.
If I make getOrientation() Shared and replace calls to getOrientation() with MotionLocation.getOrientation(), then I get and error which says the function is undefined? :/

Also if the range for the axis is between 0 to 1 then why do I get values such as 3.961e+28 for x axis? I'm having trouble understanding the values I get.

Nick_W

  • Full Member
  • ***
  • Posts: 215
    • View Profile
Re: Tilting Trigger on the Accelerometer
« Reply #14 on: February 27, 2017, 03:26:54 pm »
Yes, there are some bugs is mcStudio. To get the shared function to work you have to:

Code: [Select]
Dim value as Float = MotionLocation.getOrientation(0)

Then use value in your SigFox publish. I know it's a pain and it does work as is, but Private is not correct (because your class is not instantiated)- this isn't the problem though.

The range isn't 0 to 1 as such, it's +/- range so whatever you set in setup (2G I think, so it would be +/-2.0), it's just that earths gravity is 1.0, so if the module is not moving, you should get +/-1.0 on one axis, and 0 on the others, if the module is level.

Why you get 3.961e+28 for the X axis, I don't know, but the values from the accelerometer are correct. have you tried just substituting fake numbers (like 0.01 and 1.01) for the X,Y,Z float values, and see what shows up in losant? I suspect the math is wrong somewhere in the SigFox - losant chain.

How are you extracting the float in Losant? it's an IEE float representation so it's not a simple extract unless losant has a way of extracting IEE floats.