Author Topic: Where I'm keeping my Code  (Read 982 times)

Nick_W

  • Full Member
  • ***
  • Posts: 215
    • View Profile
Where I'm keeping my Code
« on: September 02, 2016, 05:10:21 pm »
Until we have the Github site here figure out (and maybe even after that), all my stuff is located at:
https://github.com/NickWaterton

The structure is not great, and things that are there and have the same name as on the mcThings GitHub site are probably NOT the same. I have changed a lot of stuff (examples too) and re-written some of the libraries (the accelerator library for instance is re-written).

Feel free to use it, no guarantees that there aren't any bugs, it's all a work in progress.  ;D
« Last Edit: September 04, 2016, 02:28:07 pm by Nick_W »

Share on Facebook Share on Twitter

Like Like x 1 View List

plains203

  • Newbie
  • *
  • Posts: 48
    • View Profile
Re: Where I'm keeping my Code
« Reply #1 on: September 02, 2016, 06:56:39 pm »
Thanks for sharing your code. I am sure to find some useful ideas in there.
McGateway 0.6-360, 0.7-405
McModules 0.7-358
McStudio 0.7-894

kbrooking

  • Full Member
  • ***
  • Posts: 104
    • View Profile
Re: Where I'm keeping my Code
« Reply #2 on: September 09, 2016, 09:54:23 pm »
Thanks Nick. Much appreciated. Lots of good stuff here to get newbies started.

One question. The "Class to utilize MMA8652 Accelerometer" is this the accelerometer that comes on the Mod120 or is this an external sensor you added?

Nick_W

  • Full Member
  • ***
  • Posts: 215
    • View Profile
Re: Where I'm keeping my Code
« Reply #3 on: September 09, 2016, 10:37:44 pm »
This is the on board accelerometer, no other hardware required (I'm using 110 modules, but I think the 120 accelerometer is the same).

I mostly added utility functions, plus re-did the transient and orientation configuration routines to make them more readable (and work better!).

I added a bunch of Constants so that you can use meaningful names in place of magic numbers. Mostly shamelessly stolen from other Aduino libraries.

There is a lot more work to do on it, but it's a start.

kbrooking

  • Full Member
  • ***
  • Posts: 104
    • View Profile
Re: Where I'm keeping my Code
« Reply #4 on: September 09, 2016, 10:49:44 pm »
Hmmm... That's interesting. So you can reuse other folks Aduino code samples on these devices as well, is that correct?

Nick_W

  • Full Member
  • ***
  • Posts: 215
    • View Profile
Re: Where I'm keeping my Code
« Reply #5 on: September 09, 2016, 11:09:02 pm »
Not as is. The Arduino libraries are written in C (or C++), so you have to rewrite them into the modules language, which is vb.net "like".

I don't know vb.net, but it's not too difficult, however I do know C (and C++), so it's not hard to translate one to the other, assuming you can figure out what the C library is doing. Just time consuming...

Now if the modules language just had unsigned integers, and a long data type, and a millis equivalent... It would be so much easier. Still, it does have a String type, which C still doesn't.

It's almost as bad as trying to write Java! (but no, nothing is that bad).
« Last Edit: September 09, 2016, 11:10:37 pm by Nick_W »

kbrooking

  • Full Member
  • ***
  • Posts: 104
    • View Profile
Re: Where I'm keeping my Code
« Reply #6 on: September 17, 2016, 07:00:24 pm »
Hello Nick,

I’m looking over your DoorSensor code and is very interesting. A lot here a newbie could learn from.

I know it’s a lot to ask but, would it be possible for you to do an article stepping us through your code?

 I know I, as well as others in the community could really benefit from this. ;D

Nick_W

  • Full Member
  • ***
  • Posts: 215
    • View Profile
Re: Where I'm keeping my Code
« Reply #7 on: September 17, 2016, 07:04:26 pm »
I can put something together, most of it is simple bit wise masking, as with this accelerometer, everything is set via bits.

I'll post when I have something.

Nick_W

  • Full Member
  • ***
  • Posts: 215
    • View Profile
Re: Where I'm keeping my Code
« Reply #8 on: September 18, 2016, 11:31:16 am »
I will post in small (digestible) chunks.

First, to understand the code, you need to understand the mma8652fc - you can read the data sheet (DS in the code references) but it can be hard to understand. Here is the condensed version.

The mma8652 works in two ways:
1) X,Y,Z acceleration (including gravity) are continually measured at the  Output Data Rate (ODR), which can be configured to be between 1.56 to 800 Hz. These values are read from the OUT registers, and can be configured to have a range of 0 to (+-)2,4, or 8 g. New reading available is indicated by the STATUS register, but you can ignore this and just read the OUT registers, which will reset the STATUS register. The higher the frequency of readings, the more power is used.

2) Events can be detected, and trigger interrupts. The interrupts can be INT 1 or 2 and correspond to the MCThings accelerator interrupt 1 or 2. Events can be: Motion, Tap (pulse), Transient, Freefall, Orientation.

There are two settings, Active and Standby. You can read registers in Active or Standby mode, but you can only write (configure) registers in Standby mode. The system only takes readings in Active mode. So to configure the system, you switch to Standby, configure, then switch to Active mode.

There are two modes, Wake and Sleep. In wake mode, the system runs at the wake ODR (up to 800 Hz), in sleep mode the system runs at the sleep ODR (up to 50Hz).
The idea is that you run at a low ODR in sleep mode, to save power, then when an event triggers, the system wakes and switches to the wake ODR. After a configurable period, the system switches back to sleep mode. You can trigger the transition manually, or even disable sleep mode, but using the MCThings modules, it makes most sense to have it set up to switch from sleep to wake mode and back automatically.

The thing to realize about the ODR is that at a low ODR (1.56 Hz), there is 680ms between readings, so if you want to detect a transient or tap of duration 50ms, this won't work. You would need an ODR which has a sample rate of less than 50ms (if you care, google Nyquist sampling). 50Hz is 20ms per reading, so that would detect a 50ms duration event. An event like Landscape/Portrate switch obviously has a long duration, so 680ms detection rate would work perfectly well. Some experimentation with ODR is required if you are trying to detect short duration events (taps, thumps, rapid changes etc).

There are 5 configuration registers CTL_REG1 to 5. These are what are used for the basic set up, then each event has its own set of registers that set things specific to that event (threshold, angles, duration of event to trigger etc).

CTL_REG1 sets wake and sleep frequency, plus Active/Standby mode.
CTL_REG2 sets sleep/wake configuration (enable sleep, hi-res vs low-power etc)
CTL_REG3 sets the events to use to switch from sleep to wake mode, plus interrupt mode.
CTR_REG4 sets the events to cause an interrupt (note this is different from just switching from sleep mode)
CTL_REG5 sets which INT to activate (1 or 2) for each event.

When an interrupt is generated, you then have to read the INT_SOURCE register, to find out what the source of the interrupt was. Ie if INT1 is triggered, you don't know what triggered it (you can assign anything to either interrupt), so you read INT_SOURCE, and the bits that are set tells you what generated the interrupt.

Once you know what generated the interrupt, if you want more data (like magnitude, angle etc) you read the status register for that event. Reading the status register also clears the interrupt in the INT_SOURCE register, reading INT_SOURCE does not clear INT_SOURCE.

So for example, if you configured the orientation interrupt, to detect Portrate/Landscape change (called PL in the code/Data Sheet), then when an event triggers, you read INT_SOURCE, find that it's the PL interrupt, then read the PL_STATUS register to get details (such as portrate or landscape orientation), which resets the INT_SOURCE PL bit.

Now we know what we are trying to do, the next post will explain the code that does it.
« Last Edit: September 18, 2016, 12:38:48 pm by Nick_W »

kbrooking

  • Full Member
  • ***
  • Posts: 104
    • View Profile
Re: Where I'm keeping my Code
« Reply #9 on: September 18, 2016, 12:16:41 pm »
Thanks Nick. Good information here but, I’m a bit confused.

Are we responsible for instructing mma8652fc which specific events we want to detect (via the CTR_REG4 while in Standby mode) or is the mma8652fc always monitoring these events and triggering the interrupts automatically?

kbrooking

  • Full Member
  • ***
  • Posts: 104
    • View Profile
Re: Where I'm keeping my Code
« Reply #10 on: September 18, 2016, 08:05:14 pm »
Hello Nick,

In the below code snippet from the MMA8652 library, the whoAmI() function call is returning 0x00 and so the Accelerometer is never enabled.
Any suggestions as to why it is not returning 0x4a?

Public Sub New()
        gAccelerometer = I2c.Create(I2C_SPEED, Pin.SCL, Pin.SDA, I2C_ADDR)
        If whoAmI() = 0x4a Then
            online = True
            reset()
            // Set interrupt active low
            write(CTRL_REG3, read(CTRL_REG3) & ~IPOL_MASK) // clear bit 1 (active low)
            // Set interrupt push/pull
            write(CTRL_REG3, read(CTRL_REG3) & ~PP_OD_MASK) // clear bit 0 (push-pull)
        End If
    End Sub

Nick_W

  • Full Member
  • ***
  • Posts: 215
    • View Profile
Re: Where I'm keeping my Code
« Reply #11 on: September 19, 2016, 09:31:34 am »
Quote
Are we responsible for instructing mma8652fc which specific events we want to detect (via the CTR_REG4 while in Standby mode) or is the mma8652fc always monitoring these events and triggering the interrupts automatically?

The answer is yes, you have to specifically enable which interrupts you want the MMA8652 to generate, it does not generate any by default. You also have to configure parameters specific to that event. For some, the default values will work, but others (say threshold), you would need to set explicity.

You then have to switch to Active() mode, to start the MMA8652 running.

Also note the interrupts do not fire in sleep mode, the device has to wake from sleep, then trigger the interrupt, so you have to set the same event to trigger wake from sleep in CTR_REG3 (assuming you have enabled sleep mode).

Nick_W

  • Full Member
  • ***
  • Posts: 215
    • View Profile
Re: Where I'm keeping my Code
« Reply #12 on: September 19, 2016, 09:54:24 am »
Quote
In the below code snippet from the MMA8652 library, the whoAmI() function call is returning 0x00 and so the Accelerometer is never enabled.
Any suggestions as to why it is not returning 0x4a?

It works fine for me. I have just loaded the code into a new 110 module running 7.370 F/W

Here is the MQTT output

Code: [Select]
MCThings/000111B4/Status Booted: V1.02
MCThings/000111B4/Status Accel Sensor Online
MCThings/000111B4/KnockEnable True
MCThings/000111B4/Status OnLine

In order to read/write the I2C to the module, the read and write routines in the library are very specific. The MMA8562 needs a "repeated start" before you can read it. It is possible that I have a bug in here, as I'm not sure how to do a "repeated start", with the code tools we have. I do a write (without a stop) then a read - which is required for a repeated start - ie you can't have a stop before a read.

Can you post your code somewhere (I appreciate it's probably quite long) so that I can try it, or download from my github again? I did fix some small typo's in the last day or so. Not that they should effect anything, but it's working as is on my two 110 test modules.

If you put a magnet against the reedswitch, wait 5 seconds, then tap the module several times quickly (like a knock...), this is what you should see:

Quote
MCThings/000111B4/Door False
MCThings/000111B4/Doorknock True

Door False is the door detected as closed.
Doorknock True is what you get when two taps less than 0.75 seconds apart are detected (and the door remains closed for more than 1 second afterward).
« Last Edit: September 19, 2016, 09:59:33 am by Nick_W »

Nick_W

  • Full Member
  • ***
  • Posts: 215
    • View Profile
Re: Where I'm keeping my Code
« Reply #13 on: September 19, 2016, 10:47:09 am »
Here is my test set up (note the magnet), and the actual installation (top left hand corner of door).



« Last Edit: January 18, 2017, 09:06:13 am by mc-T2 »

kbrooking

  • Full Member
  • ***
  • Posts: 104
    • View Profile
Re: Where I'm keeping my Code
« Reply #14 on: September 19, 2016, 03:08:33 pm »
Hello Nick,

I'm using the 120 modules. Could that be the reason?