{"id":2154,"date":"2015-03-03T05:42:28","date_gmt":"2015-03-03T05:42:28","guid":{"rendered":"http:\/\/41j.com\/blog\/?p=2154"},"modified":"2015-03-03T05:42:28","modified_gmt":"2015-03-03T05:42:28","slug":"mma7455l-3-axis-accelerometer-notes","status":"publish","type":"post","link":"https:\/\/41j.com\/blog\/2015\/03\/mma7455l-3-axis-accelerometer-notes\/","title":{"rendered":"MMA7455L 3-axis accelerometer notes"},"content":{"rendered":"<p>The Safecast X Kickstarter Geiger counter which I wrote the firmware for contained a MMA7455L 3-axis accelerometer. The MMA7455L is an I2C device and it&#8217;s fairly easy to work with.<\/p>\n<p>We didn&#8217;t end up doing much with the accelerometer but the readings were stored in the log files. I figured it might be interesting to filter the readings based on device orientation at some point.<\/p>\n<p>Here&#8217;s the relevant portion of the code, it was written for the STM32 (and libmaple) but should be easily adaptable for other platforms, accel_read_state wakeups up the accelerometer and grabs a reading, before sending it back to sleep, this fit the use-case in the geiger counter where we were only taking periodic readings.<\/p>\n<pre class=\"brush: cpp; title: ; notranslate\" title=\"\">\r\n#include &quot;i2c.h&quot;\r\n#include &lt;stdint.h&gt;\r\n#define ACCEL_I2C I2C1\r\n#define ACCEL_ADDR 0x1D\r\n\r\nstatic struct i2c_dev *i2c = ACCEL_I2C;\r\n\r\nstatic int accel_write(uint8 addr, uint8 value) {\r\n    struct i2c_msg msg;\r\n    uint8 bytes&#x5B;2];\r\n    int result;\r\n\r\n    bytes&#x5B;0] = addr;\r\n    bytes&#x5B;1] = value;\r\n\r\n    msg.addr    = ACCEL_ADDR;\r\n    msg.flags   = 0;\r\n    msg.length  = sizeof(bytes);\r\n    msg.xferred = 0;\r\n    msg.data    = bytes;\r\n\r\n    result = i2c_master_xfer(i2c, &amp;msg, 1, 1);\r\n\r\n    return result;\r\n}\r\n\r\nstatic uint8 accel_read(uint8 addr) {\r\n    struct i2c_msg msgs&#x5B;2];\r\n    uint8 byte;\r\n\r\n    byte = addr;\r\n    msgs&#x5B;0].addr   = msgs&#x5B;1].addr   = ACCEL_ADDR;\r\n    msgs&#x5B;0].length = msgs&#x5B;1].length = sizeof(byte);\r\n    msgs&#x5B;0].data   = msgs&#x5B;1].data   = &amp;byte;\r\n    msgs&#x5B;0].flags = 0;\r\n    msgs&#x5B;1].flags = I2C_MSG_READ;\r\n    i2c_master_xfer(i2c, msgs, 2, 1);\r\n    return byte;\r\n}\r\n\r\n\r\nstatic void accel_wakeup(void) {\r\n    \/* Set the mode to &quot;measurement&quot;, measuring 2g *\/\r\n    accel_write(0x16, 0x04 | 0x01);\r\n}\r\n\r\nstatic int accel_ready(void) {\r\n    return (accel_read(0x09) &amp; 1);\r\n}\r\n\r\nstatic int accel_sleep(void) {\r\n    return accel_write(0x16, 0);\r\n}\r\n\r\n\r\nuint8 accel_read_state(int16 *x, int16 *y, int16 *z) {\r\n  struct i2c_msg msgs&#x5B;2];\r\n  signed char values&#x5B;6];\r\n  uint8 addr = 0x00; \/* 10-bits read value *\/\r\n  int32 result = 0;\r\n\r\n  accel_wakeup();\r\n  for(int n=0;(!accel_ready()) &amp;&amp; (n &lt; 10);n++) delay_us(1000);\r\n  if(!accel_ready()) return 200;\r\n\r\n  msgs&#x5B;0].addr   = ACCEL_ADDR;\r\n  msgs&#x5B;0].length = sizeof(uint8_t);\r\n  msgs&#x5B;0].data   = &amp;addr;\r\n  msgs&#x5B;0].flags  = 0;\r\n\r\n  msgs&#x5B;1].addr   = ACCEL_ADDR;\r\n  msgs&#x5B;1].length = sizeof(values);\r\n  msgs&#x5B;1].data   = (uint8 *)values;\r\n  msgs&#x5B;1].flags  = I2C_MSG_READ;\r\n\r\n  result = i2c_master_xfer(i2c, msgs, 2, 1);\r\n\r\n  if(result == I2C_STATE_ERROR  ) return 100;\r\n  if(result == I2C_ERROR_TIMEOUT) return 10;\r\n\r\n  if (x)\r\n      *x = (values&#x5B;1]&lt;&lt;2) | (values&#x5B;0]);\r\n  if (y)\r\n      *y = (values&#x5B;3]&lt;&lt;2) | (values&#x5B;2]);\r\n  if (z)\r\n      *z = (values&#x5B;5]&lt;&lt;2) | (values&#x5B;4]);\r\n\r\n  accel_sleep();\r\n\r\n  return 0;\r\n}\r\n\r\nint accel_init(void) {\r\n  return 0;\r\n}\r\n\r\nint accel_deinit() {\r\n    \/\/ suspends accel\r\n    accel_write(0x16, 0);\r\n    return 0;\r\n}\r\n<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>The Safecast X Kickstarter Geiger counter which I wrote the firmware for contained a MMA7455L 3-axis accelerometer. The MMA7455L is an I2C device and it&#8217;s fairly easy to work with. We didn&#8217;t end up doing much with the accelerometer but the readings were stored in the log files. I figured it might be interesting to [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"MMA7455L 3-axis accelerometer notes","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":true,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2}},"categories":[1],"tags":[],"class_list":["post-2154","post","type-post","status-publish","format-standard","hentry","category-uncategorized"],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_shortlink":"https:\/\/wp.me\/p1RRoU-yK","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/41j.com\/blog\/wp-json\/wp\/v2\/posts\/2154","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/41j.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/41j.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/41j.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/41j.com\/blog\/wp-json\/wp\/v2\/comments?post=2154"}],"version-history":[{"count":1,"href":"https:\/\/41j.com\/blog\/wp-json\/wp\/v2\/posts\/2154\/revisions"}],"predecessor-version":[{"id":2155,"href":"https:\/\/41j.com\/blog\/wp-json\/wp\/v2\/posts\/2154\/revisions\/2155"}],"wp:attachment":[{"href":"https:\/\/41j.com\/blog\/wp-json\/wp\/v2\/media?parent=2154"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/41j.com\/blog\/wp-json\/wp\/v2\/categories?post=2154"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/41j.com\/blog\/wp-json\/wp\/v2\/tags?post=2154"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}