Commit 89a9bc9b275ca65e0084895c871ae07c4326a697

Authored by Ruben.T
1 parent 477015c4
Exists in master

Added Libraries and code example to the Accelerometer folder, have tested the ac…

…celerometer and it seems to work
robots/little_john/telemetry/code/robot/Accelerometer/H3LIS331DL_Accelerometer_library/Dependancies/I2C/I2C.cpp 0 → 100644
@@ -0,0 +1,709 @@ @@ -0,0 +1,709 @@
  1 +/*
  2 + I2C.cpp - I2C library
  3 + Copyright (c) 2011-2012 Wayne Truchsess. All right reserved.
  4 + Rev 5.0 - January 24th, 2012
  5 + - Removed the use of interrupts completely from the library
  6 + so TWI state changes are now polled.
  7 + - Added calls to lockup() function in most functions
  8 + to combat arbitration problems
  9 + - Fixed scan() procedure which left timeouts enabled
  10 + and set to 80msec after exiting procedure
  11 + - Changed scan() address range back to 0 - 0x7F
  12 + - Removed all Wire legacy functions from library
  13 + - A big thanks to Richard Baldwin for all the testing
  14 + and feedback with debugging bus lockups!
  15 + Rev 4.0 - January 14th, 2012
  16 + - Updated to make compatible with 8MHz clock frequency
  17 + Rev 3.0 - January 9th, 2012
  18 + - Modified library to be compatible with Arduino 1.0
  19 + - Changed argument type from boolean to uint8_t in pullUp(),
  20 + setSpeed() and receiveByte() functions for 1.0 compatability
  21 + - Modified return values for timeout feature to report
  22 + back where in the transmission the timeout occured.
  23 + - added function scan() to perform a bus scan to find devices
  24 + attached to the I2C bus. Similar to work done by Todbot
  25 + and Nick Gammon
  26 + Rev 2.0 - September 19th, 2011
  27 + - Added support for timeout function to prevent
  28 + and recover from bus lockup (thanks to PaulS
  29 + and CrossRoads on the Arduino forum)
  30 + - Changed return type for stop() from void to
  31 + uint8_t to handle timeOut function
  32 + Rev 1.0 - August 8th, 2011
  33 +
  34 + This is a modified version of the Arduino Wire/TWI
  35 + library. Functions were rewritten to provide more functionality
  36 + and also the use of Repeated Start. Some I2C devices will not
  37 + function correctly without the use of a Repeated Start. The
  38 + initial version of this library only supports the Master.
  39 +
  40 +
  41 + This library is free software; you can redistribute it and/or
  42 + modify it under the terms of the GNU Lesser General Public
  43 + License as published by the Free Software Foundation; either
  44 + version 2.1 of the License, or (at your option) any later version.
  45 +
  46 + This library is distributed in the hope that it will be useful,
  47 + but WITHOUT ANY WARRANTY; without even the implied warranty of
  48 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  49 + Lesser General Public License for more details.
  50 +
  51 + You should have received a copy of the GNU Lesser General Public
  52 + License along with this library; if not, write to the Free Software
  53 + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  54 +*/
  55 +
  56 +#if(ARDUINO >= 100)
  57 +#include <Arduino.h>
  58 +#else
  59 +#include <WProgram.h>
  60 +#endif
  61 +
  62 +#include <inttypes.h>
  63 +#include "I2C.h"
  64 +
  65 +
  66 +
  67 +uint8_t I2C::bytesAvailable = 0;
  68 +uint8_t I2C::bufferIndex = 0;
  69 +uint8_t I2C::totalBytes = 0;
  70 +uint16_t I2C::timeOutDelay = 0;
  71 +
  72 +I2C::I2C()
  73 +{
  74 +}
  75 +
  76 +
  77 +////////////// Public Methods ////////////////////////////////////////
  78 +
  79 +
  80 +
  81 +void I2C::begin()
  82 +{
  83 + #if defined(__AVR_ATmega168__) || defined(__AVR_ATmega8__) || defined(__AVR_ATmega328P__)
  84 + // activate internal pull-ups for twi
  85 + // as per note from atmega8 manual pg167
  86 + sbi(PORTC, 4);
  87 + sbi(PORTC, 5);
  88 + #else
  89 + // activate internal pull-ups for twi
  90 + // as per note from atmega128 manual pg204
  91 + sbi(PORTD, 0);
  92 + sbi(PORTD, 1);
  93 + #endif
  94 + // initialize twi prescaler and bit rate
  95 + cbi(TWSR, TWPS0);
  96 + cbi(TWSR, TWPS1);
  97 + TWBR = ((F_CPU / 100000) - 16) / 2;
  98 + // enable twi module and acks
  99 + TWCR = _BV(TWEN) | _BV(TWEA);
  100 +}
  101 +
  102 +void I2C::end()
  103 +{
  104 + TWCR = 0;
  105 +}
  106 +
  107 +void I2C::timeOut(uint16_t _timeOut)
  108 +{
  109 + timeOutDelay = _timeOut;
  110 +}
  111 +
  112 +void I2C::setSpeed(uint8_t _fast)
  113 +{
  114 + if(!_fast)
  115 + {
  116 + TWBR = ((F_CPU / 100000) - 16) / 2;
  117 + }
  118 + else
  119 + {
  120 + TWBR = ((F_CPU / 400000) - 16) / 2;
  121 + }
  122 +}
  123 +
  124 +void I2C::pullup(uint8_t activate)
  125 +{
  126 + if(activate)
  127 + {
  128 + #if defined(__AVR_ATmega168__) || defined(__AVR_ATmega8__) || defined(__AVR_ATmega328P__)
  129 + // activate internal pull-ups for twi
  130 + // as per note from atmega8 manual pg167
  131 + sbi(PORTC, 4);
  132 + sbi(PORTC, 5);
  133 + #else
  134 + // activate internal pull-ups for twi
  135 + // as per note from atmega128 manual pg204
  136 + sbi(PORTD, 0);
  137 + sbi(PORTD, 1);
  138 + #endif
  139 + }
  140 + else
  141 + {
  142 + #if defined(__AVR_ATmega168__) || defined(__AVR_ATmega8__) || defined(__AVR_ATmega328P__)
  143 + // deactivate internal pull-ups for twi
  144 + // as per note from atmega8 manual pg167
  145 + cbi(PORTC, 4);
  146 + cbi(PORTC, 5);
  147 + #else
  148 + // deactivate internal pull-ups for twi
  149 + // as per note from atmega128 manual pg204
  150 + cbi(PORTD, 0);
  151 + cbi(PORTD, 1);
  152 + #endif
  153 + }
  154 +}
  155 +
  156 +void I2C::scan()
  157 +{
  158 + uint16_t tempTime = timeOutDelay;
  159 + timeOut(80);
  160 + uint8_t totalDevicesFound = 0;
  161 + Serial.println("Scanning for devices...please wait");
  162 + Serial.println();
  163 + for(uint8_t s = 0; s <= 0x7F; s++)
  164 + {
  165 + returnStatus = 0;
  166 + returnStatus = start();
  167 + if(!returnStatus)
  168 + {
  169 + returnStatus = sendAddress(SLA_W(s));
  170 + }
  171 + if(returnStatus)
  172 + {
  173 + if(returnStatus == 1)
  174 + {
  175 + Serial.println("There is a problem with the bus, could not complete scan");
  176 + timeOutDelay = tempTime;
  177 + return;
  178 + }
  179 + }
  180 + else
  181 + {
  182 + Serial.print("Found device at address - ");
  183 + Serial.print(" 0x");
  184 + Serial.println(s,HEX);
  185 + totalDevicesFound++;
  186 + }
  187 + stop();
  188 + }
  189 + if(!totalDevicesFound){Serial.println("No devices found");}
  190 + timeOutDelay = tempTime;
  191 +}
  192 +
  193 +
  194 +uint8_t I2C::available()
  195 +{
  196 + return(bytesAvailable);
  197 +}
  198 +
  199 +uint8_t I2C::receive()
  200 +{
  201 + bufferIndex = totalBytes - bytesAvailable;
  202 + if(!bytesAvailable)
  203 + {
  204 + bufferIndex = 0;
  205 + return(0);
  206 + }
  207 + bytesAvailable--;
  208 + return(data[bufferIndex]);
  209 +}
  210 +
  211 +
  212 +/*return values for new functions that use the timeOut feature
  213 + will now return at what point in the transmission the timeout
  214 + occurred. Looking at a full communication sequence between a
  215 + master and slave (transmit data and then readback data) there
  216 + a total of 7 points in the sequence where a timeout can occur.
  217 + These are listed below and correspond to the returned value:
  218 + 1 - Waiting for successful completion of a Start bit
  219 + 2 - Waiting for ACK/NACK while addressing slave in transmit mode (MT)
  220 + 3 - Waiting for ACK/NACK while sending data to the slave
  221 + 4 - Waiting for successful completion of a Repeated Start
  222 + 5 - Waiting for ACK/NACK while addressing slave in receiver mode (MR)
  223 + 6 - Waiting for ACK/NACK while receiving data from the slave
  224 + 7 - Waiting for successful completion of the Stop bit
  225 +
  226 + All possible return values:
  227 + 0 Function executed with no errors
  228 + 1 - 7 Timeout occurred, see above list
  229 + 8 - 0xFF See datasheet for exact meaning */
  230 +
  231 +
  232 +/////////////////////////////////////////////////////
  233 +
  234 +uint8_t I2C::write(uint8_t address, uint8_t registerAddress)
  235 +{
  236 + returnStatus = 0;
  237 + returnStatus = start();
  238 + if(returnStatus){return(returnStatus);}
  239 + returnStatus = sendAddress(SLA_W(address));
  240 + if(returnStatus)
  241 + {
  242 + if(returnStatus == 1){return(2);}
  243 + return(returnStatus);
  244 + }
  245 + returnStatus = sendByte(registerAddress);
  246 + if(returnStatus)
  247 + {
  248 + if(returnStatus == 1){return(3);}
  249 + return(returnStatus);
  250 + }
  251 + returnStatus = stop();
  252 + if(returnStatus)
  253 + {
  254 + if(returnStatus == 1){return(7);}
  255 + return(returnStatus);
  256 + }
  257 + return(returnStatus);
  258 +}
  259 +
  260 +uint8_t I2C::write(int address, int registerAddress)
  261 +{
  262 + return(write((uint8_t) address, (uint8_t) registerAddress));
  263 +}
  264 +
  265 +uint8_t I2C::write(uint8_t address, uint8_t registerAddress, uint8_t data)
  266 +{
  267 + returnStatus = 0;
  268 + returnStatus = start();
  269 + if(returnStatus){return(returnStatus);}
  270 + returnStatus = sendAddress(SLA_W(address));
  271 + if(returnStatus)
  272 + {
  273 + if(returnStatus == 1){return(2);}
  274 + return(returnStatus);
  275 + }
  276 + returnStatus = sendByte(registerAddress);
  277 + if(returnStatus)
  278 + {
  279 + if(returnStatus == 1){return(3);}
  280 + return(returnStatus);
  281 + }
  282 + returnStatus = sendByte(data);
  283 + if(returnStatus)
  284 + {
  285 + if(returnStatus == 1){return(3);}
  286 + return(returnStatus);
  287 + }
  288 + returnStatus = stop();
  289 + if(returnStatus)
  290 + {
  291 + if(returnStatus == 1){return(7);}
  292 + return(returnStatus);
  293 + }
  294 + return(returnStatus);
  295 +}
  296 +
  297 +uint8_t I2C::write(int address, int registerAddress, int data)
  298 +{
  299 + return(write((uint8_t) address, (uint8_t) registerAddress, (uint8_t) data));
  300 +}
  301 +
  302 +uint8_t I2C::write(uint8_t address, uint8_t registerAddress, char *data)
  303 +{
  304 + uint8_t bufferLength = strlen(data);
  305 + returnStatus = 0;
  306 + returnStatus = write(address, registerAddress, (uint8_t*)data, bufferLength);
  307 + return(returnStatus);
  308 +}
  309 +
  310 +uint8_t I2C::write(uint8_t address, uint8_t registerAddress, uint8_t *data, uint8_t numberBytes)
  311 +{
  312 + returnStatus = 0;
  313 + returnStatus = start();
  314 + if(returnStatus){return(returnStatus);}
  315 + returnStatus = sendAddress(SLA_W(address));
  316 + if(returnStatus)
  317 + {
  318 + if(returnStatus == 1){return(2);}
  319 + return(returnStatus);
  320 + }
  321 + returnStatus = sendByte(registerAddress);
  322 + if(returnStatus)
  323 + {
  324 + if(returnStatus == 1){return(3);}
  325 + return(returnStatus);
  326 + }
  327 + for (uint8_t i = 0; i < numberBytes; i++)
  328 + {
  329 + returnStatus = sendByte(data[i]);
  330 + if(returnStatus)
  331 + {
  332 + if(returnStatus == 1){return(3);}
  333 + return(returnStatus);
  334 + }
  335 + }
  336 + returnStatus = stop();
  337 + if(returnStatus)
  338 + {
  339 + if(returnStatus == 1){return(7);}
  340 + return(returnStatus);
  341 + }
  342 + return(returnStatus);
  343 +}
  344 +
  345 +uint8_t I2C::read(int address, int numberBytes)
  346 +{
  347 + return(read((uint8_t) address, (uint8_t) numberBytes));
  348 +}
  349 +
  350 +uint8_t I2C::read(uint8_t address, uint8_t numberBytes)
  351 +{
  352 + bytesAvailable = 0;
  353 + bufferIndex = 0;
  354 + if(numberBytes == 0){numberBytes++;}
  355 + nack = numberBytes - 1;
  356 + returnStatus = 0;
  357 + returnStatus = start();
  358 + if(returnStatus){return(returnStatus);}
  359 + returnStatus = sendAddress(SLA_R(address));
  360 + if(returnStatus)
  361 + {
  362 + if(returnStatus == 1){return(5);}
  363 + return(returnStatus);
  364 + }
  365 + for(uint8_t i = 0; i < numberBytes; i++)
  366 + {
  367 + if( i == nack )
  368 + {
  369 + returnStatus = receiveByte(0);
  370 + if(returnStatus == 1){return(6);}
  371 +
  372 + if(returnStatus != MR_DATA_NACK){return(returnStatus);}
  373 + }
  374 + else
  375 + {
  376 + returnStatus = receiveByte(1);
  377 + if(returnStatus == 1){return(6);}
  378 + if(returnStatus != MR_DATA_ACK){return(returnStatus);}
  379 + }
  380 + data[i] = TWDR;
  381 + bytesAvailable = i+1;
  382 + totalBytes = i+1;
  383 + }
  384 + returnStatus = stop();
  385 + if(returnStatus)
  386 + {
  387 + if(returnStatus == 1){return(7);}
  388 + return(returnStatus);
  389 + }
  390 + return(returnStatus);
  391 +}
  392 +
  393 +uint8_t I2C::read(int address, int registerAddress, int numberBytes)
  394 +{
  395 + return(read((uint8_t) address, (uint8_t) registerAddress, (uint8_t) numberBytes));
  396 +}
  397 +
  398 +uint8_t I2C::read(uint8_t address, uint8_t registerAddress, uint8_t numberBytes)
  399 +{
  400 + bytesAvailable = 0;
  401 + bufferIndex = 0;
  402 + if(numberBytes == 0){numberBytes++;}
  403 + nack = numberBytes - 1;
  404 + returnStatus = 0;
  405 + returnStatus = start();
  406 + if(returnStatus){return(returnStatus);}
  407 + returnStatus = sendAddress(SLA_W(address));
  408 + if(returnStatus)
  409 + {
  410 + if(returnStatus == 1){return(2);}
  411 + return(returnStatus);
  412 + }
  413 + returnStatus = sendByte(registerAddress);
  414 + if(returnStatus)
  415 + {
  416 + if(returnStatus == 1){return(3);}
  417 + return(returnStatus);
  418 + }
  419 + returnStatus = start();
  420 + if(returnStatus)
  421 + {
  422 + if(returnStatus == 1){return(4);}
  423 + return(returnStatus);
  424 + }
  425 + returnStatus = sendAddress(SLA_R(address));
  426 + if(returnStatus)
  427 + {
  428 + if(returnStatus == 1){return(5);}
  429 + return(returnStatus);
  430 + }
  431 + for(uint8_t i = 0; i < numberBytes; i++)
  432 + {
  433 + if( i == nack )
  434 + {
  435 + returnStatus = receiveByte(0);
  436 + if(returnStatus == 1){return(6);}
  437 + if(returnStatus != MR_DATA_NACK){return(returnStatus);}
  438 + }
  439 + else
  440 + {
  441 + returnStatus = receiveByte(1);
  442 + if(returnStatus == 1){return(6);}
  443 + if(returnStatus != MR_DATA_ACK){return(returnStatus);}
  444 + }
  445 + data[i] = TWDR;
  446 + bytesAvailable = i+1;
  447 + totalBytes = i+1;
  448 + }
  449 + returnStatus = stop();
  450 + if(returnStatus)
  451 + {
  452 + if(returnStatus == 1){return(7);}
  453 + return(returnStatus);
  454 + }
  455 + return(returnStatus);
  456 +}
  457 +
  458 +uint8_t I2C::read(uint8_t address, uint8_t numberBytes, uint8_t *dataBuffer)
  459 +{
  460 + bytesAvailable = 0;
  461 + bufferIndex = 0;
  462 + if(numberBytes == 0){numberBytes++;}
  463 + nack = numberBytes - 1;
  464 + returnStatus = 0;
  465 + returnStatus = start();
  466 + if(returnStatus){return(returnStatus);}
  467 + returnStatus = sendAddress(SLA_R(address));
  468 + if(returnStatus)
  469 + {
  470 + if(returnStatus == 1){return(5);}
  471 + return(returnStatus);
  472 + }
  473 + for(uint8_t i = 0; i < numberBytes; i++)
  474 + {
  475 + if( i == nack )
  476 + {
  477 + returnStatus = receiveByte(0);
  478 + if(returnStatus == 1){return(6);}
  479 + if(returnStatus != MR_DATA_NACK){return(returnStatus);}
  480 + }
  481 + else
  482 + {
  483 + returnStatus = receiveByte(1);
  484 + if(returnStatus == 1){return(6);}
  485 + if(returnStatus != MR_DATA_ACK){return(returnStatus);}
  486 + }
  487 + dataBuffer[i] = TWDR;
  488 + bytesAvailable = i+1;
  489 + totalBytes = i+1;
  490 + }
  491 + returnStatus = stop();
  492 + if(returnStatus)
  493 + {
  494 + if(returnStatus == 1){return(7);}
  495 + return(returnStatus);
  496 + }
  497 + return(returnStatus);
  498 +}
  499 +
  500 +uint8_t I2C::read(uint8_t address, uint8_t registerAddress, uint8_t numberBytes, uint8_t *dataBuffer)
  501 +{
  502 + bytesAvailable = 0;
  503 + bufferIndex = 0;
  504 + if(numberBytes == 0){numberBytes++;}
  505 + nack = numberBytes - 1;
  506 + returnStatus = 0;
  507 + returnStatus = start();
  508 + if(returnStatus){return(returnStatus);}
  509 + returnStatus = sendAddress(SLA_W(address));
  510 + if(returnStatus)
  511 + {
  512 + if(returnStatus == 1){return(2);}
  513 + return(returnStatus);
  514 + }
  515 + returnStatus = sendByte(registerAddress);
  516 + if(returnStatus)
  517 + {
  518 + if(returnStatus == 1){return(3);}
  519 + return(returnStatus);
  520 + }
  521 + returnStatus = start();
  522 + if(returnStatus)
  523 + {
  524 + if(returnStatus == 1){return(4);}
  525 + return(returnStatus);
  526 + }
  527 + returnStatus = sendAddress(SLA_R(address));
  528 + if(returnStatus)
  529 + {
  530 + if(returnStatus == 1){return(5);}
  531 + return(returnStatus);
  532 + }
  533 + for(uint8_t i = 0; i < numberBytes; i++)
  534 + {
  535 + if( i == nack )
  536 + {
  537 + returnStatus = receiveByte(0);
  538 + if(returnStatus == 1){return(6);}
  539 + if(returnStatus != MR_DATA_NACK){return(returnStatus);}
  540 + }
  541 + else
  542 + {
  543 + returnStatus = receiveByte(1);
  544 + if(returnStatus == 1){return(6);}
  545 + if(returnStatus != MR_DATA_ACK){return(returnStatus);}
  546 + }
  547 + dataBuffer[i] = TWDR;
  548 + bytesAvailable = i+1;
  549 + totalBytes = i+1;
  550 + }
  551 + returnStatus = stop();
  552 + if(returnStatus)
  553 + {
  554 + if(returnStatus == 1){return(7);}
  555 + return(returnStatus);
  556 + }
  557 + return(returnStatus);
  558 +}
  559 +
  560 +
  561 +/////////////// Private Methods ////////////////////////////////////////
  562 +
  563 +
  564 +uint8_t I2C::start()
  565 +{
  566 + unsigned long startingTime = millis();
  567 + TWCR = (1<<TWINT)|(1<<TWSTA)|(1<<TWEN);
  568 + while (!(TWCR & (1<<TWINT)))
  569 + {
  570 + if(!timeOutDelay){continue;}
  571 + if((millis() - startingTime) >= timeOutDelay)
  572 + {
  573 + lockUp();
  574 + return(1);
  575 + }
  576 +
  577 + }
  578 + if ((TWI_STATUS == START) || (TWI_STATUS == REPEATED_START))
  579 + {
  580 + return(0);
  581 + }
  582 + if (TWI_STATUS == LOST_ARBTRTN)
  583 + {
  584 + uint8_t bufferedStatus = TWI_STATUS;
  585 + lockUp();
  586 + return(bufferedStatus);
  587 + }
  588 + return(TWI_STATUS);
  589 +}
  590 +
  591 +uint8_t I2C::sendAddress(uint8_t i2cAddress)
  592 +{
  593 + TWDR = i2cAddress;
  594 + unsigned long startingTime = millis();
  595 + TWCR = (1<<TWINT) | (1<<TWEN);
  596 + while (!(TWCR & (1<<TWINT)))
  597 + {
  598 + if(!timeOutDelay){continue;}
  599 + if((millis() - startingTime) >= timeOutDelay)
  600 + {
  601 + lockUp();
  602 + return(1);
  603 + }
  604 +
  605 + }
  606 + if ((TWI_STATUS == MT_SLA_ACK) || (TWI_STATUS == MR_SLA_ACK))
  607 + {
  608 + return(0);
  609 + }
  610 + uint8_t bufferedStatus = TWI_STATUS;
  611 + if ((TWI_STATUS == MT_SLA_NACK) || (TWI_STATUS == MR_SLA_NACK))
  612 + {
  613 + stop();
  614 + return(bufferedStatus);
  615 + }
  616 + else
  617 + {
  618 + lockUp();
  619 + return(bufferedStatus);
  620 + }
  621 +}
  622 +
  623 +uint8_t I2C::sendByte(uint8_t i2cData)
  624 +{
  625 + TWDR = i2cData;
  626 + unsigned long startingTime = millis();
  627 + TWCR = (1<<TWINT) | (1<<TWEN);
  628 + while (!(TWCR & (1<<TWINT)))
  629 + {
  630 + if(!timeOutDelay){continue;}
  631 + if((millis() - startingTime) >= timeOutDelay)
  632 + {
  633 + lockUp();
  634 + return(1);
  635 + }
  636 +
  637 + }
  638 + if (TWI_STATUS == MT_DATA_ACK)
  639 + {
  640 + return(0);
  641 + }
  642 + uint8_t bufferedStatus = TWI_STATUS;
  643 + if (TWI_STATUS == MT_DATA_NACK)
  644 + {
  645 + stop();
  646 + return(bufferedStatus);
  647 + }
  648 + else
  649 + {
  650 + lockUp();
  651 + return(bufferedStatus);
  652 + }
  653 +}
  654 +
  655 +uint8_t I2C::receiveByte(uint8_t ack)
  656 +{
  657 + unsigned long startingTime = millis();
  658 + if(ack)
  659 + {
  660 + TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWEA);
  661 +
  662 + }
  663 + else
  664 + {
  665 + TWCR = (1<<TWINT) | (1<<TWEN);
  666 + }
  667 + while (!(TWCR & (1<<TWINT)))
  668 + {
  669 + if(!timeOutDelay){continue;}
  670 + if((millis() - startingTime) >= timeOutDelay)
  671 + {
  672 + lockUp();
  673 + return(1);
  674 + }
  675 + }
  676 + if (TWI_STATUS == LOST_ARBTRTN)
  677 + {
  678 + uint8_t bufferedStatus = TWI_STATUS;
  679 + lockUp();
  680 + return(bufferedStatus);
  681 + }
  682 + return(TWI_STATUS);
  683 +}
  684 +
  685 +uint8_t I2C::stop()
  686 +{
  687 + unsigned long startingTime = millis();
  688 + TWCR = (1<<TWINT)|(1<<TWEN)| (1<<TWSTO);
  689 + while ((TWCR & (1<<TWSTO)))
  690 + {
  691 + if(!timeOutDelay){continue;}
  692 + if((millis() - startingTime) >= timeOutDelay)
  693 + {
  694 + lockUp();
  695 + return(1);
  696 + }
  697 +
  698 + }
  699 + return(0);
  700 +}
  701 +
  702 +void I2C::lockUp()
  703 +{
  704 + TWCR = 0; //releases SDA and SCL lines to high impedance
  705 + TWCR = _BV(TWEN) | _BV(TWEA); //reinitialize TWI
  706 +}
  707 +
  708 +I2C I2c = I2C();
  709 +
robots/little_john/telemetry/code/robot/Accelerometer/H3LIS331DL_Accelerometer_library/Dependancies/I2C/I2C.h 0 → 100644
@@ -0,0 +1,135 @@ @@ -0,0 +1,135 @@
  1 +/*
  2 + I2C.h - I2C library
  3 + Copyright (c) 2011-2012 Wayne Truchsess. All right reserved.
  4 + Rev 5.0 - January 24th, 2012
  5 + - Removed the use of interrupts completely from the library
  6 + so TWI state changes are now polled.
  7 + - Added calls to lockup() function in most functions
  8 + to combat arbitration problems
  9 + - Fixed scan() procedure which left timeouts enabled
  10 + and set to 80msec after exiting procedure
  11 + - Changed scan() address range back to 0 - 0x7F
  12 + - Removed all Wire legacy functions from library
  13 + - A big thanks to Richard Baldwin for all the testing
  14 + and feedback with debugging bus lockups!
  15 + Rev 4.0 - January 14th, 2012
  16 + - Updated to make compatible with 8MHz clock frequency
  17 + Rev 3.0 - January 9th, 2012
  18 + - Modified library to be compatible with Arduino 1.0
  19 + - Changed argument type from boolean to uint8_t in pullUp(),
  20 + setSpeed() and receiveByte() functions for 1.0 compatability
  21 + - Modified return values for timeout feature to report
  22 + back where in the transmission the timeout occured.
  23 + - added function scan() to perform a bus scan to find devices
  24 + attached to the I2C bus. Similar to work done by Todbot
  25 + and Nick Gammon
  26 + Rev 2.0 - September 19th, 2011
  27 + - Added support for timeout function to prevent
  28 + and recover from bus lockup (thanks to PaulS
  29 + and CrossRoads on the Arduino forum)
  30 + - Changed return type for stop() from void to
  31 + uint8_t to handle timeOut function
  32 + Rev 1.0 - August 8th, 2011
  33 +
  34 + This is a modified version of the Arduino Wire/TWI
  35 + library. Functions were rewritten to provide more functionality
  36 + and also the use of Repeated Start. Some I2C devices will not
  37 + function correctly without the use of a Repeated Start. The
  38 + initial version of this library only supports the Master.
  39 +
  40 +
  41 + This library is free software; you can redistribute it and/or
  42 + modify it under the terms of the GNU Lesser General Public
  43 + License as published by the Free Software Foundation; either
  44 + version 2.1 of the License, or (at your option) any later version.
  45 +
  46 + This library is distributed in the hope that it will be useful,
  47 + but WITHOUT ANY WARRANTY; without even the implied warranty of
  48 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  49 + Lesser General Public License for more details.
  50 +
  51 + You should have received a copy of the GNU Lesser General Public
  52 + License along with this library; if not, write to the Free Software
  53 + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  54 +*/
  55 +
  56 +#if(ARDUINO >= 100)
  57 +#include <Arduino.h>
  58 +#else
  59 +#include <WProgram.h>
  60 +#endif
  61 +
  62 +#include <inttypes.h>
  63 +
  64 +#ifndef I2C_h
  65 +#define I2C_h
  66 +
  67 +
  68 +#define START 0x08
  69 +#define REPEATED_START 0x10
  70 +#define MT_SLA_ACK 0x18
  71 +#define MT_SLA_NACK 0x20
  72 +#define MT_DATA_ACK 0x28
  73 +#define MT_DATA_NACK 0x30
  74 +#define MR_SLA_ACK 0x40
  75 +#define MR_SLA_NACK 0x48
  76 +#define MR_DATA_ACK 0x50
  77 +#define MR_DATA_NACK 0x58
  78 +#define LOST_ARBTRTN 0x38
  79 +#define TWI_STATUS (TWSR & 0xF8)
  80 +#define SLA_W(address) (address << 1)
  81 +#define SLA_R(address) ((address << 1) + 0x01)
  82 +#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
  83 +#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
  84 +
  85 +#define MAX_BUFFER_SIZE 32
  86 +
  87 +
  88 +
  89 +
  90 +class I2C
  91 +{
  92 + public:
  93 + I2C();
  94 + void begin();
  95 + void end();
  96 + void timeOut(uint16_t);
  97 + void setSpeed(uint8_t);
  98 + void pullup(uint8_t);
  99 + void scan();
  100 + uint8_t available();
  101 + uint8_t receive();
  102 + uint8_t write(uint8_t, uint8_t);
  103 + uint8_t write(int, int);
  104 + uint8_t write(uint8_t, uint8_t, uint8_t);
  105 + uint8_t write(int, int, int);
  106 + uint8_t write(uint8_t, uint8_t, char*);
  107 + uint8_t write(uint8_t, uint8_t, uint8_t*, uint8_t);
  108 + uint8_t read(uint8_t, uint8_t);
  109 + uint8_t read(int, int);
  110 + uint8_t read(uint8_t, uint8_t, uint8_t);
  111 + uint8_t read(int, int, int);
  112 + uint8_t read(uint8_t, uint8_t, uint8_t*);
  113 + uint8_t read(uint8_t, uint8_t, uint8_t, uint8_t*);
  114 +
  115 +
  116 + private:
  117 + uint8_t start();
  118 + uint8_t sendAddress(uint8_t);
  119 + uint8_t sendByte(uint8_t);
  120 + uint8_t receiveByte(uint8_t);
  121 + uint8_t stop();
  122 + void lockUp();
  123 + uint8_t returnStatus;
  124 + uint8_t nack;
  125 + uint8_t data[MAX_BUFFER_SIZE];
  126 + static uint8_t bytesAvailable;
  127 + static uint8_t bufferIndex;
  128 + static uint8_t totalBytes;
  129 + static uint16_t timeOutDelay;
  130 +
  131 +};
  132 +
  133 +extern I2C I2c;
  134 +
  135 +#endif
robots/little_john/telemetry/code/robot/Accelerometer/H3LIS331DL_Accelerometer_library/Dependancies/I2C/examples/HMC5883L/HMC5883L.pde 0 → 100644
@@ -0,0 +1,70 @@ @@ -0,0 +1,70 @@
  1 +/*******************************************
  2 + Sample sketch that configures an HMC5883L 3 axis
  3 + magnetometer to continuous mode and reads back
  4 + the three axis of data.
  5 + Code compiles to a size of 1500 bytes
  6 + Equivalent Wire Library code compiles to 2032 bytes
  7 + *******************************************/
  8 +
  9 +#include <I2C.h>
  10 +
  11 +#define HMC5883L 0x1E
  12 +
  13 +int x = 0;
  14 +int y = 0;
  15 +int z = 0;
  16 +
  17 +
  18 +void setup()
  19 +{
  20 + I2c.begin();
  21 + I2c.write(HMC5883L,0x02,0x00); //configure device for continuous mode
  22 +}
  23 +
  24 +void loop()
  25 +{
  26 + I2c.read(HMC5883L,0x03,6); //read 6 bytes (x,y,z) from the device
  27 + x = I2c.receive() << 8;
  28 + x |= I2c.receive();
  29 + y = I2c.receive() << 8;
  30 + y |= I2c.receive();
  31 + z = I2c.receive() << 8;
  32 + z |= I2c.receive();
  33 +}
  34 +
  35 +
  36 +/* Wire library equivalent would be this
  37 +
  38 +//#include <Wire.h>
  39 +
  40 +#define HMC5883L 0x1E
  41 +
  42 +int x = 0;
  43 +int y = 0;
  44 +int z = 0;
  45 +
  46 +
  47 +void setup()
  48 +{
  49 + Wire.begin();
  50 + Wire.beginTransmission(HMC5883L);
  51 + Wire.send(0x02);
  52 + Wire.send(0x00);
  53 + Wire.endTransmission();
  54 +}
  55 +
  56 +void loop()
  57 +{
  58 + Wire.beginTransmission(HMC5883L);
  59 + Wire.send(0x03);
  60 + Wire.endTransmission();
  61 + Wire.requestFrom(HMC5883L,6);
  62 + x = Wire.receive() << 8;
  63 + x |= Wire.receive();
  64 + y = Wire.receive() << 8;
  65 + y |= Wire.receive();
  66 + z = Wire.receive() << 8;
  67 + z |= Wire.receive();
  68 +}
  69 +
  70 +********************************************/
robots/little_john/telemetry/code/robot/Accelerometer/H3LIS331DL_Accelerometer_library/Dependancies/I2C/keywords.txt 0 → 100644
@@ -0,0 +1,33 @@ @@ -0,0 +1,33 @@
  1 +#######################################
  2 +# Syntax Coloring Map For I2C
  3 +#######################################
  4 +
  5 +#######################################
  6 +# Datatypes (KEYWORD1)
  7 +#######################################
  8 +I2C KEYWORD1
  9 +
  10 +#######################################
  11 +# Methods and Functions (KEYWORD2)
  12 +#######################################
  13 +
  14 +begin KEYWORD2
  15 +end KEYWORD2
  16 +timeOut KEYWORD2
  17 +setSpeed KEYWORD2
  18 +pullup KEYWORD2
  19 +scan KEYWORD2
  20 +write KEYWORD2
  21 +read KEYWORD2
  22 +available KEYWORD2
  23 +receive KEYWORD2
  24 +
  25 +#######################################
  26 +# Instances (KEYWORD2)
  27 +#######################################
  28 +
  29 +I2c KEYWORD2
  30 +
  31 +#######################################
  32 +# Constants (LITERAL1)
  33 +#######################################
0 \ No newline at end of file 34 \ No newline at end of file
robots/little_john/telemetry/code/robot/Accelerometer/H3LIS331DL_Accelerometer_library/LIS331/LICENSE 0 → 100644
@@ -0,0 +1,674 @@ @@ -0,0 +1,674 @@
  1 + GNU GENERAL PUBLIC LICENSE
  2 + Version 3, 29 June 2007
  3 +
  4 + Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
  5 + Everyone is permitted to copy and distribute verbatim copies
  6 + of this license document, but changing it is not allowed.
  7 +
  8 + Preamble
  9 +
  10 + The GNU General Public License is a free, copyleft license for
  11 +software and other kinds of works.
  12 +
  13 + The licenses for most software and other practical works are designed
  14 +to take away your freedom to share and change the works. By contrast,
  15 +the GNU General Public License is intended to guarantee your freedom to
  16 +share and change all versions of a program--to make sure it remains free
  17 +software for all its users. We, the Free Software Foundation, use the
  18 +GNU General Public License for most of our software; it applies also to
  19 +any other work released this way by its authors. You can apply it to
  20 +your programs, too.
  21 +
  22 + When we speak of free software, we are referring to freedom, not
  23 +price. Our General Public Licenses are designed to make sure that you
  24 +have the freedom to distribute copies of free software (and charge for
  25 +them if you wish), that you receive source code or can get it if you
  26 +want it, that you can change the software or use pieces of it in new
  27 +free programs, and that you know you can do these things.
  28 +
  29 + To protect your rights, we need to prevent others from denying you
  30 +these rights or asking you to surrender the rights. Therefore, you have
  31 +certain responsibilities if you distribute copies of the software, or if
  32 +you modify it: responsibilities to respect the freedom of others.
  33 +
  34 + For example, if you distribute copies of such a program, whether
  35 +gratis or for a fee, you must pass on to the recipients the same
  36 +freedoms that you received. You must make sure that they, too, receive
  37 +or can get the source code. And you must show them these terms so they
  38 +know their rights.
  39 +
  40 + Developers that use the GNU GPL protect your rights with two steps:
  41 +(1) assert copyright on the software, and (2) offer you this License
  42 +giving you legal permission to copy, distribute and/or modify it.
  43 +
  44 + For the developers' and authors' protection, the GPL clearly explains
  45 +that there is no warranty for this free software. For both users' and
  46 +authors' sake, the GPL requires that modified versions be marked as
  47 +changed, so that their problems will not be attributed erroneously to
  48 +authors of previous versions.
  49 +
  50 + Some devices are designed to deny users access to install or run
  51 +modified versions of the software inside them, although the manufacturer
  52 +can do so. This is fundamentally incompatible with the aim of
  53 +protecting users' freedom to change the software. The systematic
  54 +pattern of such abuse occurs in the area of products for individuals to
  55 +use, which is precisely where it is most unacceptable. Therefore, we
  56 +have designed this version of the GPL to prohibit the practice for those
  57 +products. If such problems arise substantially in other domains, we
  58 +stand ready to extend this provision to those domains in future versions
  59 +of the GPL, as needed to protect the freedom of users.
  60 +
  61 + Finally, every program is threatened constantly by software patents.
  62 +States should not allow patents to restrict development and use of
  63 +software on general-purpose computers, but in those that do, we wish to
  64 +avoid the special danger that patents applied to a free program could
  65 +make it effectively proprietary. To prevent this, the GPL assures that
  66 +patents cannot be used to render the program non-free.
  67 +
  68 + The precise terms and conditions for copying, distribution and
  69 +modification follow.
  70 +
  71 + TERMS AND CONDITIONS
  72 +
  73 + 0. Definitions.
  74 +
  75 + "This License" refers to version 3 of the GNU General Public License.
  76 +
  77 + "Copyright" also means copyright-like laws that apply to other kinds of
  78 +works, such as semiconductor masks.
  79 +
  80 + "The Program" refers to any copyrightable work licensed under this
  81 +License. Each licensee is addressed as "you". "Licensees" and
  82 +"recipients" may be individuals or organizations.
  83 +
  84 + To "modify" a work means to copy from or adapt all or part of the work
  85 +in a fashion requiring copyright permission, other than the making of an
  86 +exact copy. The resulting work is called a "modified version" of the
  87 +earlier work or a work "based on" the earlier work.
  88 +
  89 + A "covered work" means either the unmodified Program or a work based
  90 +on the Program.
  91 +
  92 + To "propagate" a work means to do anything with it that, without
  93 +permission, would make you directly or secondarily liable for
  94 +infringement under applicable copyright law, except executing it on a
  95 +computer or modifying a private copy. Propagation includes copying,
  96 +distribution (with or without modification), making available to the
  97 +public, and in some countries other activities as well.
  98 +
  99 + To "convey" a work means any kind of propagation that enables other
  100 +parties to make or receive copies. Mere interaction with a user through
  101 +a computer network, with no transfer of a copy, is not conveying.
  102 +
  103 + An interactive user interface displays "Appropriate Legal Notices"
  104 +to the extent that it includes a convenient and prominently visible
  105 +feature that (1) displays an appropriate copyright notice, and (2)
  106 +tells the user that there is no warranty for the work (except to the
  107 +extent that warranties are provided), that licensees may convey the
  108 +work under this License, and how to view a copy of this License. If
  109 +the interface presents a list of user commands or options, such as a
  110 +menu, a prominent item in the list meets this criterion.
  111 +
  112 + 1. Source Code.
  113 +
  114 + The "source code" for a work means the preferred form of the work
  115 +for making modifications to it. "Object code" means any non-source
  116 +form of a work.
  117 +
  118 + A "Standard Interface" means an interface that either is an official
  119 +standard defined by a recognized standards body, or, in the case of
  120 +interfaces specified for a particular programming language, one that
  121 +is widely used among developers working in that language.
  122 +
  123 + The "System Libraries" of an executable work include anything, other
  124 +than the work as a whole, that (a) is included in the normal form of
  125 +packaging a Major Component, but which is not part of that Major
  126 +Component, and (b) serves only to enable use of the work with that
  127 +Major Component, or to implement a Standard Interface for which an
  128 +implementation is available to the public in source code form. A
  129 +"Major Component", in this context, means a major essential component
  130 +(kernel, window system, and so on) of the specific operating system
  131 +(if any) on which the executable work runs, or a compiler used to
  132 +produce the work, or an object code interpreter used to run it.
  133 +
  134 + The "Corresponding Source" for a work in object code form means all
  135 +the source code needed to generate, install, and (for an executable
  136 +work) run the object code and to modify the work, including scripts to
  137 +control those activities. However, it does not include the work's
  138 +System Libraries, or general-purpose tools or generally available free
  139 +programs which are used unmodified in performing those activities but
  140 +which are not part of the work. For example, Corresponding Source
  141 +includes interface definition files associated with source files for
  142 +the work, and the source code for shared libraries and dynamically
  143 +linked subprograms that the work is specifically designed to require,
  144 +such as by intimate data communication or control flow between those
  145 +subprograms and other parts of the work.
  146 +
  147 + The Corresponding Source need not include anything that users
  148 +can regenerate automatically from other parts of the Corresponding
  149 +Source.
  150 +
  151 + The Corresponding Source for a work in source code form is that
  152 +same work.
  153 +
  154 + 2. Basic Permissions.
  155 +
  156 + All rights granted under this License are granted for the term of
  157 +copyright on the Program, and are irrevocable provided the stated
  158 +conditions are met. This License explicitly affirms your unlimited
  159 +permission to run the unmodified Program. The output from running a
  160 +covered work is covered by this License only if the output, given its
  161 +content, constitutes a covered work. This License acknowledges your
  162 +rights of fair use or other equivalent, as provided by copyright law.
  163 +
  164 + You may make, run and propagate covered works that you do not
  165 +convey, without conditions so long as your license otherwise remains
  166 +in force. You may convey covered works to others for the sole purpose
  167 +of having them make modifications exclusively for you, or provide you
  168 +with facilities for running those works, provided that you comply with
  169 +the terms of this License in conveying all material for which you do
  170 +not control copyright. Those thus making or running the covered works
  171 +for you must do so exclusively on your behalf, under your direction
  172 +and control, on terms that prohibit them from making any copies of
  173 +your copyrighted material outside their relationship with you.
  174 +
  175 + Conveying under any other circumstances is permitted solely under
  176 +the conditions stated below. Sublicensing is not allowed; section 10
  177 +makes it unnecessary.
  178 +
  179 + 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
  180 +
  181 + No covered work shall be deemed part of an effective technological
  182 +measure under any applicable law fulfilling obligations under article
  183 +11 of the WIPO copyright treaty adopted on 20 December 1996, or
  184 +similar laws prohibiting or restricting circumvention of such
  185 +measures.
  186 +
  187 + When you convey a covered work, you waive any legal power to forbid
  188 +circumvention of technological measures to the extent such circumvention
  189 +is effected by exercising rights under this License with respect to
  190 +the covered work, and you disclaim any intention to limit operation or
  191 +modification of the work as a means of enforcing, against the work's
  192 +users, your or third parties' legal rights to forbid circumvention of
  193 +technological measures.
  194 +
  195 + 4. Conveying Verbatim Copies.
  196 +
  197 + You may convey verbatim copies of the Program's source code as you
  198 +receive it, in any medium, provided that you conspicuously and
  199 +appropriately publish on each copy an appropriate copyright notice;
  200 +keep intact all notices stating that this License and any
  201 +non-permissive terms added in accord with section 7 apply to the code;
  202 +keep intact all notices of the absence of any warranty; and give all
  203 +recipients a copy of this License along with the Program.
  204 +
  205 + You may charge any price or no price for each copy that you convey,
  206 +and you may offer support or warranty protection for a fee.
  207 +
  208 + 5. Conveying Modified Source Versions.
  209 +
  210 + You may convey a work based on the Program, or the modifications to
  211 +produce it from the Program, in the form of source code under the
  212 +terms of section 4, provided that you also meet all of these conditions:
  213 +
  214 + a) The work must carry prominent notices stating that you modified
  215 + it, and giving a relevant date.
  216 +
  217 + b) The work must carry prominent notices stating that it is
  218 + released under this License and any conditions added under section
  219 + 7. This requirement modifies the requirement in section 4 to
  220 + "keep intact all notices".
  221 +
  222 + c) You must license the entire work, as a whole, under this
  223 + License to anyone who comes into possession of a copy. This
  224 + License will therefore apply, along with any applicable section 7
  225 + additional terms, to the whole of the work, and all its parts,
  226 + regardless of how they are packaged. This License gives no
  227 + permission to license the work in any other way, but it does not
  228 + invalidate such permission if you have separately received it.
  229 +
  230 + d) If the work has interactive user interfaces, each must display
  231 + Appropriate Legal Notices; however, if the Program has interactive
  232 + interfaces that do not display Appropriate Legal Notices, your
  233 + work need not make them do so.
  234 +
  235 + A compilation of a covered work with other separate and independent
  236 +works, which are not by their nature extensions of the covered work,
  237 +and which are not combined with it such as to form a larger program,
  238 +in or on a volume of a storage or distribution medium, is called an
  239 +"aggregate" if the compilation and its resulting copyright are not
  240 +used to limit the access or legal rights of the compilation's users
  241 +beyond what the individual works permit. Inclusion of a covered work
  242 +in an aggregate does not cause this License to apply to the other
  243 +parts of the aggregate.
  244 +
  245 + 6. Conveying Non-Source Forms.
  246 +
  247 + You may convey a covered work in object code form under the terms
  248 +of sections 4 and 5, provided that you also convey the
  249 +machine-readable Corresponding Source under the terms of this License,
  250 +in one of these ways:
  251 +
  252 + a) Convey the object code in, or embodied in, a physical product
  253 + (including a physical distribution medium), accompanied by the
  254 + Corresponding Source fixed on a durable physical medium
  255 + customarily used for software interchange.
  256 +
  257 + b) Convey the object code in, or embodied in, a physical product
  258 + (including a physical distribution medium), accompanied by a
  259 + written offer, valid for at least three years and valid for as
  260 + long as you offer spare parts or customer support for that product
  261 + model, to give anyone who possesses the object code either (1) a
  262 + copy of the Corresponding Source for all the software in the
  263 + product that is covered by this License, on a durable physical
  264 + medium customarily used for software interchange, for a price no
  265 + more than your reasonable cost of physically performing this
  266 + conveying of source, or (2) access to copy the
  267 + Corresponding Source from a network server at no charge.
  268 +
  269 + c) Convey individual copies of the object code with a copy of the
  270 + written offer to provide the Corresponding Source. This
  271 + alternative is allowed only occasionally and noncommercially, and
  272 + only if you received the object code with such an offer, in accord
  273 + with subsection 6b.
  274 +
  275 + d) Convey the object code by offering access from a designated
  276 + place (gratis or for a charge), and offer equivalent access to the
  277 + Corresponding Source in the same way through the same place at no
  278 + further charge. You need not require recipients to copy the
  279 + Corresponding Source along with the object code. If the place to
  280 + copy the object code is a network server, the Corresponding Source
  281 + may be on a different server (operated by you or a third party)
  282 + that supports equivalent copying facilities, provided you maintain
  283 + clear directions next to the object code saying where to find the
  284 + Corresponding Source. Regardless of what server hosts the
  285 + Corresponding Source, you remain obligated to ensure that it is
  286 + available for as long as needed to satisfy these requirements.
  287 +
  288 + e) Convey the object code using peer-to-peer transmission, provided
  289 + you inform other peers where the object code and Corresponding
  290 + Source of the work are being offered to the general public at no
  291 + charge under subsection 6d.
  292 +
  293 + A separable portion of the object code, whose source code is excluded
  294 +from the Corresponding Source as a System Library, need not be
  295 +included in conveying the object code work.
  296 +
  297 + A "User Product" is either (1) a "consumer product", which means any
  298 +tangible personal property which is normally used for personal, family,
  299 +or household purposes, or (2) anything designed or sold for incorporation
  300 +into a dwelling. In determining whether a product is a consumer product,
  301 +doubtful cases shall be resolved in favor of coverage. For a particular
  302 +product received by a particular user, "normally used" refers to a
  303 +typical or common use of that class of product, regardless of the status
  304 +of the particular user or of the way in which the particular user
  305 +actually uses, or expects or is expected to use, the product. A product
  306 +is a consumer product regardless of whether the product has substantial
  307 +commercial, industrial or non-consumer uses, unless such uses represent
  308 +the only significant mode of use of the product.
  309 +
  310 + "Installation Information" for a User Product means any methods,
  311 +procedures, authorization keys, or other information required to install
  312 +and execute modified versions of a covered work in that User Product from
  313 +a modified version of its Corresponding Source. The information must
  314 +suffice to ensure that the continued functioning of the modified object
  315 +code is in no case prevented or interfered with solely because
  316 +modification has been made.
  317 +
  318 + If you convey an object code work under this section in, or with, or
  319 +specifically for use in, a User Product, and the conveying occurs as
  320 +part of a transaction in which the right of possession and use of the
  321 +User Product is transferred to the recipient in perpetuity or for a
  322 +fixed term (regardless of how the transaction is characterized), the
  323 +Corresponding Source conveyed under this section must be accompanied
  324 +by the Installation Information. But this requirement does not apply
  325 +if neither you nor any third party retains the ability to install
  326 +modified object code on the User Product (for example, the work has
  327 +been installed in ROM).
  328 +
  329 + The requirement to provide Installation Information does not include a
  330 +requirement to continue to provide support service, warranty, or updates
  331 +for a work that has been modified or installed by the recipient, or for
  332 +the User Product in which it has been modified or installed. Access to a
  333 +network may be denied when the modification itself materially and
  334 +adversely affects the operation of the network or violates the rules and
  335 +protocols for communication across the network.
  336 +
  337 + Corresponding Source conveyed, and Installation Information provided,
  338 +in accord with this section must be in a format that is publicly
  339 +documented (and with an implementation available to the public in
  340 +source code form), and must require no special password or key for
  341 +unpacking, reading or copying.
  342 +
  343 + 7. Additional Terms.
  344 +
  345 + "Additional permissions" are terms that supplement the terms of this
  346 +License by making exceptions from one or more of its conditions.
  347 +Additional permissions that are applicable to the entire Program shall
  348 +be treated as though they were included in this License, to the extent
  349 +that they are valid under applicable law. If additional permissions
  350 +apply only to part of the Program, that part may be used separately
  351 +under those permissions, but the entire Program remains governed by
  352 +this License without regard to the additional permissions.
  353 +
  354 + When you convey a copy of a covered work, you may at your option
  355 +remove any additional permissions from that copy, or from any part of
  356 +it. (Additional permissions may be written to require their own
  357 +removal in certain cases when you modify the work.) You may place
  358 +additional permissions on material, added by you to a covered work,
  359 +for which you have or can give appropriate copyright permission.
  360 +
  361 + Notwithstanding any other provision of this License, for material you
  362 +add to a covered work, you may (if authorized by the copyright holders of
  363 +that material) supplement the terms of this License with terms:
  364 +
  365 + a) Disclaiming warranty or limiting liability differently from the
  366 + terms of sections 15 and 16 of this License; or
  367 +
  368 + b) Requiring preservation of specified reasonable legal notices or
  369 + author attributions in that material or in the Appropriate Legal
  370 + Notices displayed by works containing it; or
  371 +
  372 + c) Prohibiting misrepresentation of the origin of that material, or
  373 + requiring that modified versions of such material be marked in
  374 + reasonable ways as different from the original version; or
  375 +
  376 + d) Limiting the use for publicity purposes of names of licensors or
  377 + authors of the material; or
  378 +
  379 + e) Declining to grant rights under trademark law for use of some
  380 + trade names, trademarks, or service marks; or
  381 +
  382 + f) Requiring indemnification of licensors and authors of that
  383 + material by anyone who conveys the material (or modified versions of
  384 + it) with contractual assumptions of liability to the recipient, for
  385 + any liability that these contractual assumptions directly impose on
  386 + those licensors and authors.
  387 +
  388 + All other non-permissive additional terms are considered "further
  389 +restrictions" within the meaning of section 10. If the Program as you
  390 +received it, or any part of it, contains a notice stating that it is
  391 +governed by this License along with a term that is a further
  392 +restriction, you may remove that term. If a license document contains
  393 +a further restriction but permits relicensing or conveying under this
  394 +License, you may add to a covered work material governed by the terms
  395 +of that license document, provided that the further restriction does
  396 +not survive such relicensing or conveying.
  397 +
  398 + If you add terms to a covered work in accord with this section, you
  399 +must place, in the relevant source files, a statement of the
  400 +additional terms that apply to those files, or a notice indicating
  401 +where to find the applicable terms.
  402 +
  403 + Additional terms, permissive or non-permissive, may be stated in the
  404 +form of a separately written license, or stated as exceptions;
  405 +the above requirements apply either way.
  406 +
  407 + 8. Termination.
  408 +
  409 + You may not propagate or modify a covered work except as expressly
  410 +provided under this License. Any attempt otherwise to propagate or
  411 +modify it is void, and will automatically terminate your rights under
  412 +this License (including any patent licenses granted under the third
  413 +paragraph of section 11).
  414 +
  415 + However, if you cease all violation of this License, then your
  416 +license from a particular copyright holder is reinstated (a)
  417 +provisionally, unless and until the copyright holder explicitly and
  418 +finally terminates your license, and (b) permanently, if the copyright
  419 +holder fails to notify you of the violation by some reasonable means
  420 +prior to 60 days after the cessation.
  421 +
  422 + Moreover, your license from a particular copyright holder is
  423 +reinstated permanently if the copyright holder notifies you of the
  424 +violation by some reasonable means, this is the first time you have
  425 +received notice of violation of this License (for any work) from that
  426 +copyright holder, and you cure the violation prior to 30 days after
  427 +your receipt of the notice.
  428 +
  429 + Termination of your rights under this section does not terminate the
  430 +licenses of parties who have received copies or rights from you under
  431 +this License. If your rights have been terminated and not permanently
  432 +reinstated, you do not qualify to receive new licenses for the same
  433 +material under section 10.
  434 +
  435 + 9. Acceptance Not Required for Having Copies.
  436 +
  437 + You are not required to accept this License in order to receive or
  438 +run a copy of the Program. Ancillary propagation of a covered work
  439 +occurring solely as a consequence of using peer-to-peer transmission
  440 +to receive a copy likewise does not require acceptance. However,
  441 +nothing other than this License grants you permission to propagate or
  442 +modify any covered work. These actions infringe copyright if you do
  443 +not accept this License. Therefore, by modifying or propagating a
  444 +covered work, you indicate your acceptance of this License to do so.
  445 +
  446 + 10. Automatic Licensing of Downstream Recipients.
  447 +
  448 + Each time you convey a covered work, the recipient automatically
  449 +receives a license from the original licensors, to run, modify and
  450 +propagate that work, subject to this License. You are not responsible
  451 +for enforcing compliance by third parties with this License.
  452 +
  453 + An "entity transaction" is a transaction transferring control of an
  454 +organization, or substantially all assets of one, or subdividing an
  455 +organization, or merging organizations. If propagation of a covered
  456 +work results from an entity transaction, each party to that
  457 +transaction who receives a copy of the work also receives whatever
  458 +licenses to the work the party's predecessor in interest had or could
  459 +give under the previous paragraph, plus a right to possession of the
  460 +Corresponding Source of the work from the predecessor in interest, if
  461 +the predecessor has it or can get it with reasonable efforts.
  462 +
  463 + You may not impose any further restrictions on the exercise of the
  464 +rights granted or affirmed under this License. For example, you may
  465 +not impose a license fee, royalty, or other charge for exercise of
  466 +rights granted under this License, and you may not initiate litigation
  467 +(including a cross-claim or counterclaim in a lawsuit) alleging that
  468 +any patent claim is infringed by making, using, selling, offering for
  469 +sale, or importing the Program or any portion of it.
  470 +
  471 + 11. Patents.
  472 +
  473 + A "contributor" is a copyright holder who authorizes use under this
  474 +License of the Program or a work on which the Program is based. The
  475 +work thus licensed is called the contributor's "contributor version".
  476 +
  477 + A contributor's "essential patent claims" are all patent claims
  478 +owned or controlled by the contributor, whether already acquired or
  479 +hereafter acquired, that would be infringed by some manner, permitted
  480 +by this License, of making, using, or selling its contributor version,
  481 +but do not include claims that would be infringed only as a
  482 +consequence of further modification of the contributor version. For
  483 +purposes of this definition, "control" includes the right to grant
  484 +patent sublicenses in a manner consistent with the requirements of
  485 +this License.
  486 +
  487 + Each contributor grants you a non-exclusive, worldwide, royalty-free
  488 +patent license under the contributor's essential patent claims, to
  489 +make, use, sell, offer for sale, import and otherwise run, modify and
  490 +propagate the contents of its contributor version.
  491 +
  492 + In the following three paragraphs, a "patent license" is any express
  493 +agreement or commitment, however denominated, not to enforce a patent
  494 +(such as an express permission to practice a patent or covenant not to
  495 +sue for patent infringement). To "grant" such a patent license to a
  496 +party means to make such an agreement or commitment not to enforce a
  497 +patent against the party.
  498 +
  499 + If you convey a covered work, knowingly relying on a patent license,
  500 +and the Corresponding Source of the work is not available for anyone
  501 +to copy, free of charge and under the terms of this License, through a
  502 +publicly available network server or other readily accessible means,
  503 +then you must either (1) cause the Corresponding Source to be so
  504 +available, or (2) arrange to deprive yourself of the benefit of the
  505 +patent license for this particular work, or (3) arrange, in a manner
  506 +consistent with the requirements of this License, to extend the patent
  507 +license to downstream recipients. "Knowingly relying" means you have
  508 +actual knowledge that, but for the patent license, your conveying the
  509 +covered work in a country, or your recipient's use of the covered work
  510 +in a country, would infringe one or more identifiable patents in that
  511 +country that you have reason to believe are valid.
  512 +
  513 + If, pursuant to or in connection with a single transaction or
  514 +arrangement, you convey, or propagate by procuring conveyance of, a
  515 +covered work, and grant a patent license to some of the parties
  516 +receiving the covered work authorizing them to use, propagate, modify
  517 +or convey a specific copy of the covered work, then the patent license
  518 +you grant is automatically extended to all recipients of the covered
  519 +work and works based on it.
  520 +
  521 + A patent license is "discriminatory" if it does not include within
  522 +the scope of its coverage, prohibits the exercise of, or is
  523 +conditioned on the non-exercise of one or more of the rights that are
  524 +specifically granted under this License. You may not convey a covered
  525 +work if you are a party to an arrangement with a third party that is
  526 +in the business of distributing software, under which you make payment
  527 +to the third party based on the extent of your activity of conveying
  528 +the work, and under which the third party grants, to any of the
  529 +parties who would receive the covered work from you, a discriminatory
  530 +patent license (a) in connection with copies of the covered work
  531 +conveyed by you (or copies made from those copies), or (b) primarily
  532 +for and in connection with specific products or compilations that
  533 +contain the covered work, unless you entered into that arrangement,
  534 +or that patent license was granted, prior to 28 March 2007.
  535 +
  536 + Nothing in this License shall be construed as excluding or limiting
  537 +any implied license or other defenses to infringement that may
  538 +otherwise be available to you under applicable patent law.
  539 +
  540 + 12. No Surrender of Others' Freedom.
  541 +
  542 + If conditions are imposed on you (whether by court order, agreement or
  543 +otherwise) that contradict the conditions of this License, they do not
  544 +excuse you from the conditions of this License. If you cannot convey a
  545 +covered work so as to satisfy simultaneously your obligations under this
  546 +License and any other pertinent obligations, then as a consequence you may
  547 +not convey it at all. For example, if you agree to terms that obligate you
  548 +to collect a royalty for further conveying from those to whom you convey
  549 +the Program, the only way you could satisfy both those terms and this
  550 +License would be to refrain entirely from conveying the Program.
  551 +
  552 + 13. Use with the GNU Affero General Public License.
  553 +
  554 + Notwithstanding any other provision of this License, you have
  555 +permission to link or combine any covered work with a work licensed
  556 +under version 3 of the GNU Affero General Public License into a single
  557 +combined work, and to convey the resulting work. The terms of this
  558 +License will continue to apply to the part which is the covered work,
  559 +but the special requirements of the GNU Affero General Public License,
  560 +section 13, concerning interaction through a network will apply to the
  561 +combination as such.
  562 +
  563 + 14. Revised Versions of this License.
  564 +
  565 + The Free Software Foundation may publish revised and/or new versions of
  566 +the GNU General Public License from time to time. Such new versions will
  567 +be similar in spirit to the present version, but may differ in detail to
  568 +address new problems or concerns.
  569 +
  570 + Each version is given a distinguishing version number. If the
  571 +Program specifies that a certain numbered version of the GNU General
  572 +Public License "or any later version" applies to it, you have the
  573 +option of following the terms and conditions either of that numbered
  574 +version or of any later version published by the Free Software
  575 +Foundation. If the Program does not specify a version number of the
  576 +GNU General Public License, you may choose any version ever published
  577 +by the Free Software Foundation.
  578 +
  579 + If the Program specifies that a proxy can decide which future
  580 +versions of the GNU General Public License can be used, that proxy's
  581 +public statement of acceptance of a version permanently authorizes you
  582 +to choose that version for the Program.
  583 +
  584 + Later license versions may give you additional or different
  585 +permissions. However, no additional obligations are imposed on any
  586 +author or copyright holder as a result of your choosing to follow a
  587 +later version.
  588 +
  589 + 15. Disclaimer of Warranty.
  590 +
  591 + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
  592 +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
  593 +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
  594 +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
  595 +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  596 +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
  597 +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
  598 +ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
  599 +
  600 + 16. Limitation of Liability.
  601 +
  602 + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
  603 +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
  604 +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
  605 +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
  606 +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
  607 +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
  608 +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
  609 +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
  610 +SUCH DAMAGES.
  611 +
  612 + 17. Interpretation of Sections 15 and 16.
  613 +
  614 + If the disclaimer of warranty and limitation of liability provided
  615 +above cannot be given local legal effect according to their terms,
  616 +reviewing courts shall apply local law that most closely approximates
  617 +an absolute waiver of all civil liability in connection with the
  618 +Program, unless a warranty or assumption of liability accompanies a
  619 +copy of the Program in return for a fee.
  620 +
  621 + END OF TERMS AND CONDITIONS
  622 +
  623 + How to Apply These Terms to Your New Programs
  624 +
  625 + If you develop a new program, and you want it to be of the greatest
  626 +possible use to the public, the best way to achieve this is to make it
  627 +free software which everyone can redistribute and change under these terms.
  628 +
  629 + To do so, attach the following notices to the program. It is safest
  630 +to attach them to the start of each source file to most effectively
  631 +state the exclusion of warranty; and each file should have at least
  632 +the "copyright" line and a pointer to where the full notice is found.
  633 +
  634 + {one line to give the program's name and a brief idea of what it does.}
  635 + Copyright (C) {year} {name of author}
  636 +
  637 + This program is free software: you can redistribute it and/or modify
  638 + it under the terms of the GNU General Public License as published by
  639 + the Free Software Foundation, either version 3 of the License, or
  640 + (at your option) any later version.
  641 +
  642 + This program is distributed in the hope that it will be useful,
  643 + but WITHOUT ANY WARRANTY; without even the implied warranty of
  644 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  645 + GNU General Public License for more details.
  646 +
  647 + You should have received a copy of the GNU General Public License
  648 + along with this program. If not, see <http://www.gnu.org/licenses/>.
  649 +
  650 +Also add information on how to contact you by electronic and paper mail.
  651 +
  652 + If the program does terminal interaction, make it output a short
  653 +notice like this when it starts in an interactive mode:
  654 +
  655 + {project} Copyright (C) {year} {fullname}
  656 + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
  657 + This is free software, and you are welcome to redistribute it
  658 + under certain conditions; type `show c' for details.
  659 +
  660 +The hypothetical commands `show w' and `show c' should show the appropriate
  661 +parts of the General Public License. Of course, your program's commands
  662 +might be different; for a GUI interface, you would use an "about box".
  663 +
  664 + You should also get your employer (if you work as a programmer) or school,
  665 +if any, to sign a "copyright disclaimer" for the program, if necessary.
  666 +For more information on this, and how to apply and follow the GNU GPL, see
  667 +<http://www.gnu.org/licenses/>.
  668 +
  669 + The GNU General Public License does not permit incorporating your program
  670 +into proprietary programs. If your program is a subroutine library, you
  671 +may consider it more useful to permit linking proprietary applications with
  672 +the library. If this is what you want to do, use the GNU Lesser General
  673 +Public License instead of this License. But first, please read
  674 +<http://www.gnu.org/philosophy/why-not-lgpl.html>.
robots/little_john/telemetry/code/robot/Accelerometer/H3LIS331DL_Accelerometer_library/LIS331/README.md 0 → 100644
@@ -0,0 +1,32 @@ @@ -0,0 +1,32 @@
  1 +LIS331 triple-axis accelerometer library for Arduino
  2 +========================
  3 +
  4 +Implements all features of the STMicroelectronics [LIS331HH](http://www.st.com/content/st_com/en/products/mems-and-sensors/accelerometers/lis331hh.html) accelerometer according to its data sheet. Should be compatible with [LIS331DLH](http://www.st.com/content/st_com/en/products/mems-and-sensors/accelerometers/lis331dlh.html) and [H3LIS331DL](http://www.st.com/en/mems-and-sensors/h3lis331dl.html) apart from the selectable scale:
  5 +
  6 +* LIS331HH: ±6g/±12g/±24g
  7 +* LIS331DLH: ±2g/±4g/±8g
  8 +* H3LIS331DL: ±100g/±200g/±400g
  9 +
  10 +## Wiring
  11 +
  12 +The code uses the I²C protocol to communicate with the sensor. If you attach the sensor to a 5V Arduino board, please consider using a [bi-directional level shifter](https://playground.arduino.cc/Main/I2CBi-directionalLevelShifter).
  13 +
  14 +| LIS331 pin | Arduino Nano pin | Description |
  15 +|------------|------------------|---------------------------------------------|
  16 +| GND | GND | |
  17 +| INT2 | D3 | Optional, pin should be interrupt-capable |
  18 +| INT1 | D2 | Optional, pin should be interrupt-capable |
  19 +| SDA | A4 | Serial data |
  20 +| SCL | A5 | Serial clock |
  21 +| SA0 | 3V3 or GND | Least significant bit of the device address |
  22 +| CS | 3V3 | Selects I²C protocol over SPI |
  23 +| VCC | 3V3 | |
  24 +
  25 +## Dependencies
  26 +
  27 +Install [I2C Master Library](http://dsscircuits.com/index.php/articles/66-arduino-i2c-master-library). It's more robust and customisable than the built-in Wire.h library.
  28 +
  29 +## Pull requests
  30 +
  31 +Any code loves refactoring and feature expansion. Please, do create pull requests if you added something to this library.
  32 +
robots/little_john/telemetry/code/robot/Accelerometer/H3LIS331DL_Accelerometer_library/LIS331/examples/ReadAxes/ReadAxes.ino 0 → 100644
@@ -0,0 +1,112 @@ @@ -0,0 +1,112 @@
  1 +#include <I2C.h>
  2 +#include <LIS331.h>
  3 +
  4 +#define ACCELEROMETER_ADDR 0x18
  5 +
  6 +LIS331 accelerometer{ACCELEROMETER_ADDR};
  7 +
  8 +void print_err(byte err_code)
  9 +{
  10 + switch (err_code) {
  11 + case START:
  12 + Serial.println(F("START"));
  13 + break;
  14 + case REPEATED_START:
  15 + Serial.println(F("REPEATED_START"));
  16 + break;
  17 + case MT_SLA_ACK:
  18 + Serial.println(F("MT_SLA_ACK"));
  19 + break;
  20 + case MT_SLA_NACK:
  21 + Serial.println(F("MT_SLA_NACK"));
  22 + break;
  23 + case MT_DATA_ACK:
  24 + Serial.println(F("MT_DATA_ACK"));
  25 + break;
  26 + case MT_DATA_NACK:
  27 + Serial.println(F("MT_DATA_NACK"));
  28 + break;
  29 + case MR_SLA_ACK:
  30 + Serial.println(F("MR_SLA_ACK"));
  31 + break;
  32 + case MR_SLA_NACK:
  33 + Serial.println(F("MR_SLA_NACK"));
  34 + break;
  35 + case MR_DATA_ACK:
  36 + Serial.println(F("MR_DATA_ACK"));
  37 + break;
  38 + case MR_DATA_NACK:
  39 + Serial.println(F("MR_DATA_NACK"));
  40 + break;
  41 + case LOST_ARBTRTN:
  42 + Serial.println(F("LOST_ARBTRTN"));
  43 + break;
  44 + case E_OK:
  45 + Serial.println(F("E_OK"));
  46 + break;
  47 + case E_WRONG_INTERRUPT:
  48 + Serial.println(F("E_WRONG_INTERRUPT"));
  49 + break;
  50 + case E_NUM_TOO_BIG:
  51 + Serial.println(F("E_NUM_TOO_BIG"));
  52 + break;
  53 + case E_WRONG_SCALE:
  54 + Serial.println(F("E_WRONG_SCALE"));
  55 + break;
  56 + default:
  57 + Serial.print(F("Unknown error message: 0x"));
  58 + Serial.println(err_code, HEX);
  59 + break;
  60 + }
  61 +}
  62 +
  63 +void setup()
  64 +{
  65 + Serial.begin(230400);
  66 +
  67 + I2c.begin();
  68 + I2c.pullup(1);
  69 + I2c.setSpeed(1); // 400 kHz
  70 + I2c.timeOut(2000); // Reset communication when it's blocking the system for more than 2 seconds
  71 +
  72 + byte err = accelerometer.setPowerMode(LIS331::PowerMode::normalMode);
  73 + print_err(err);
  74 + err = accelerometer.setDataRate(LIS331::DataRate::odr1000Hz);
  75 + print_err(err);
  76 + err = accelerometer.setBDUEnabled(true);
  77 + print_err(err);
  78 + err = accelerometer.setScale(LIS331::Scale::scale24g);
  79 + print_err(err);
  80 + err = accelerometer.setXEnabled(true);
  81 + print_err(err);
  82 + err = accelerometer.setYEnabled(true);
  83 + print_err(err);
  84 + err = accelerometer.setZEnabled(true);
  85 + print_err(err);
  86 +}
  87 +
  88 +void loop()
  89 +{
  90 + int16_t x = 0, y = 0, z = 0;
  91 + accelerometer.getXValue(x);
  92 + accelerometer.getYValue(y);
  93 + accelerometer.getZValue(z);
  94 +
  95 + bool xOverran = false, yEnabled = false, zAvailable = false;
  96 + accelerometer.isXDataOverrun(xOverran);
  97 + accelerometer.isYEnabled(yEnabled);
  98 + accelerometer.isZDataAvailable(zAvailable);
  99 +
  100 + Serial.print(F("X: "));
  101 + Serial.print(x);
  102 + Serial.print(F(", Y: "));
  103 + Serial.print(y);
  104 + Serial.print(F(", Z: "));
  105 + Serial.print(z);
  106 + Serial.print(F(", X overran: "));
  107 + Serial.print(xOverran);
  108 + Serial.print(F(", Y enabled: "));
  109 + Serial.print(yEnabled);
  110 + Serial.print(F(", Z available: "));
  111 + Serial.println(zAvailable);
  112 +}
robots/little_john/telemetry/code/robot/Accelerometer/H3LIS331DL_Accelerometer_library/LIS331/keywords.txt 0 → 100644
@@ -0,0 +1,70 @@ @@ -0,0 +1,70 @@
  1 +LIS331 KEYWORD1
  2 +getAxisValuesG KEYWORD2
  3 +getDataRate KEYWORD2
  4 +getHPReference KEYWORD2
  5 +getHighPassCutOff KEYWORD2
  6 +getHighPassFilterMode KEYWORD2
  7 +getInt1DataSignal KEYWORD2
  8 +getInt2DataSignal KEYWORD2
  9 +getInterruptDuration KEYWORD2
  10 +getInterruptSource KEYWORD2
  11 +getInterruptThreshold KEYWORD2
  12 +getInterruptThresholdG KEYWORD2
  13 +getInterruptValue KEYWORD2
  14 +getPPOD KEYWORD2
  15 +getPowerMode KEYWORD2
  16 +getRebootMemoryContent KEYWORD2
  17 +getScale KEYWORD2
  18 +getSelfTestSign KEYWORD2
  19 +getXValue KEYWORD2
  20 +getYValue KEYWORD2
  21 +getZValue KEYWORD2
  22 +isAllDataAvailable KEYWORD2
  23 +isAllDataOverrun KEYWORD2
  24 +isBDUEnabled KEYWORD2
  25 +isFilteredDataSection KEYWORD2
  26 +isHPenabledForInterrupt1 KEYWORD2
  27 +isHPenabledForInterrupt2 KEYWORD2
  28 +isInterruptActiveHL KEYWORD2
  29 +isInterruptEnabled KEYWORD2
  30 +isInterruptGenerated KEYWORD2
  31 +isInterruptLatched KEYWORD2
  32 +isSelfTestEnabled KEYWORD2
  33 +isSleepToWakeEnabled KEYWORD2
  34 +isXDataAvailable KEYWORD2
  35 +isXDataOverrun KEYWORD2
  36 +isXEnabled KEYWORD2
  37 +isYDataAvailable KEYWORD2
  38 +isYDataOverrun KEYWORD2
  39 +isYEnabled KEYWORD2
  40 +isZDataAvailable KEYWORD2
  41 +isZDataOverrun KEYWORD2
  42 +isZEnabled KEYWORD2
  43 +readInterrupt KEYWORD2
  44 +resetHighPassFilter KEYWORD2
  45 +setBDUEnabled KEYWORD2
  46 +setDataRate KEYWORD2
  47 +setDataSignal KEYWORD2
  48 +setFilteredDataSection KEYWORD2
  49 +setHPReference KEYWORD2
  50 +setHPenabledForInterrupt1 KEYWORD2
  51 +setHPenabledForInterrupt2 KEYWORD2
  52 +setHighPassCutOff KEYWORD2
  53 +setHighPassFilterMode KEYWORD2
  54 +setInterruptActiveHL KEYWORD2
  55 +setInterruptDuration KEYWORD2
  56 +setInterruptEnabled KEYWORD2
  57 +setInterruptLatched KEYWORD2
  58 +setInterruptSource KEYWORD2
  59 +setInterruptThreshold KEYWORD2
  60 +setInterruptThresholdG KEYWORD2
  61 +setPPOD KEYWORD2
  62 +setPowerMode KEYWORD2
  63 +setRebootMemoryContent KEYWORD2
  64 +setScale KEYWORD2
  65 +setSelfTestEnabled KEYWORD2
  66 +setSelfTestSign KEYWORD2
  67 +setSleepToWakeEnabled KEYWORD2
  68 +setXEnabled KEYWORD2
  69 +setYEnabled KEYWORD2
  70 +setZEnabled KEYWORD2
robots/little_john/telemetry/code/robot/Accelerometer/H3LIS331DL_Accelerometer_library/LIS331/library.properties 0 → 100644
@@ -0,0 +1,9 @@ @@ -0,0 +1,9 @@
  1 +name=LIS331
  2 +version=2.2.2
  3 +author=Szőts Ákos <szotsaki@gmail.com>
  4 +maintainer=Szőts Ákos <szotsaki@gmail.com>
  5 +sentence=LIS331 triple axis acceleromenter Arduino library
  6 +paragraph=Use LIS331 acceleromenter via I2C protocol. Depends on the more reliable external I2C libary (and not on the built-in Wire.h). Please, read README.md
  7 +category=Sensors
  8 +url=https://github.com/szotsaki/LIS331
  9 +architectures=*
robots/little_john/telemetry/code/robot/Accelerometer/H3LIS331DL_Accelerometer_library/LIS331/src/LIS331.cpp 0 → 100644
@@ -0,0 +1,678 @@ @@ -0,0 +1,678 @@
  1 +/* Copyright © 2017 Szőts Ákos <szotsaki@gmail.com>
  2 + *
  3 + * This program is free software: you can redistribute it and/or modify
  4 + * it under the terms of the GNU General Public License as published by
  5 + * the Free Software Foundation, either version 3 of the License, or
  6 + * (at your option) any later version.
  7 + *
  8 + * This program is distributed in the hope that it will be useful,
  9 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  10 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11 + * GNU General Public License for more details.
  12 + * You should have received a copy of the GNU General Public License
  13 + * along with this program. If not, see <http://www.gnu.org/licenses/>.
  14 + *
  15 +*/
  16 +
  17 +#include "LIS331.h"
  18 +
  19 +LIS331::LIS331(const uint8_t i2cAddress)
  20 + : i2cAddress(i2cAddress),
  21 + interruptSource(0),
  22 + currentScale(Scale::scale6g)
  23 +{
  24 +
  25 +}
  26 +
  27 +uint8_t LIS331::readReg(const byte addr, byte &val)
  28 +{
  29 + return I2c.read(i2cAddress, addr, 1, &val);
  30 +}
  31 +
  32 +uint8_t LIS331::writeReg(const byte addr, const byte val)
  33 +{
  34 + return I2c.write(i2cAddress, addr, val);
  35 +}
  36 +
  37 +uint8_t LIS331::readRegisterBit(const byte registerAddr, const byte bit, bool &ret)
  38 +{
  39 + byte registerValue = 0;
  40 + const uint8_t err = readReg(registerAddr, registerValue);
  41 + if (err != E_OK) {
  42 + return err;
  43 + }
  44 +
  45 + ret = bitRead(registerValue, bit);
  46 + return E_OK;
  47 +}
  48 +
  49 +uint8_t LIS331::writeRegisterBit(const byte registerAddr, const byte bit, const bool enabled)
  50 +{
  51 + byte registerValue = 0;
  52 + const uint8_t err = readReg(registerAddr, registerValue);
  53 + if (err != E_OK) {
  54 + return err;
  55 + }
  56 +
  57 + bitWrite(registerValue, bit, enabled);
  58 + return writeReg(registerAddr, registerValue);
  59 +}
  60 +
  61 +uint8_t LIS331::getAxisValue(const byte addressLow, const byte addressHigh, int16_t &ret)
  62 +{
  63 + byte low = 0;
  64 + byte high = 0;
  65 +
  66 + uint8_t err = readReg(addressLow, low);
  67 + if (err != E_OK) {
  68 + return err;
  69 + }
  70 +
  71 + err = readReg(addressHigh, high);
  72 + if (err != E_OK) {
  73 + return err;
  74 + }
  75 +
  76 + ret = ((high << 8) | low) / 16;
  77 +
  78 + return E_OK;
  79 +}
  80 +
  81 +// Control register 1
  82 +
  83 +uint8_t LIS331::getPowerMode(PowerMode &ret)
  84 +{
  85 + byte ctrlReg1 = 0;
  86 + const uint8_t err = readReg(LIS_CTRL_REG1, ctrlReg1);
  87 + if (err != E_OK) {
  88 + return err;
  89 + }
  90 +
  91 + byte mode = 0;
  92 + bitWrite(mode, LIS_CTRL_REG1_PM0, bitRead(ctrlReg1, LIS_CTRL_REG1_PM0));
  93 + bitWrite(mode, LIS_CTRL_REG1_PM1, bitRead(ctrlReg1, LIS_CTRL_REG1_PM1));
  94 + bitWrite(mode, LIS_CTRL_REG1_PM2, bitRead(ctrlReg1, LIS_CTRL_REG1_PM2));
  95 +
  96 + ret = PowerMode(mode);
  97 + return E_OK;
  98 +}
  99 +
  100 +uint8_t LIS331::setPowerMode(const PowerMode mode)
  101 +{
  102 + byte ctrlReg1 = 0;
  103 + const uint8_t err = readReg(LIS_CTRL_REG1, ctrlReg1);
  104 + if (err != E_OK) {
  105 + return err;
  106 + }
  107 +
  108 + bitWrite(ctrlReg1, LIS_CTRL_REG1_PM0, bitRead(mode, LIS_CTRL_REG1_PM0));
  109 + bitWrite(ctrlReg1, LIS_CTRL_REG1_PM1, bitRead(mode, LIS_CTRL_REG1_PM1));
  110 + bitWrite(ctrlReg1, LIS_CTRL_REG1_PM2, bitRead(mode, LIS_CTRL_REG1_PM2));
  111 +
  112 + return writeReg(LIS_CTRL_REG1, ctrlReg1);
  113 +}
  114 +
  115 +uint8_t LIS331::getDataRate(DataRate &ret)
  116 +{
  117 + byte ctrlReg1 = 0;
  118 + const uint8_t err = readReg(LIS_CTRL_REG1, ctrlReg1);
  119 + if (err != E_OK) {
  120 + return err;
  121 + }
  122 +
  123 + byte dataRate = 0;
  124 + bitWrite(dataRate, LIS_CTRL_REG1_DR0, bitRead(ctrlReg1, LIS_CTRL_REG1_DR0));
  125 + bitWrite(dataRate, LIS_CTRL_REG1_DR1, bitRead(ctrlReg1, LIS_CTRL_REG1_DR1));
  126 +
  127 + ret = DataRate(dataRate);
  128 + return E_OK;
  129 +}
  130 +
  131 +uint8_t LIS331::setDataRate(const DataRate dataRate)
  132 +{
  133 + byte ctrlReg1 = 0;
  134 + const uint8_t err = readReg(LIS_CTRL_REG1, ctrlReg1);
  135 + if (err != E_OK) {
  136 + return err;
  137 + }
  138 +
  139 + bitWrite(ctrlReg1, LIS_CTRL_REG1_DR0, bitRead(dataRate, LIS_CTRL_REG1_DR0));
  140 + bitWrite(ctrlReg1, LIS_CTRL_REG1_DR1, bitRead(dataRate, LIS_CTRL_REG1_DR1));
  141 +
  142 + return writeReg(LIS_CTRL_REG1, ctrlReg1);
  143 +}
  144 +
  145 +uint8_t LIS331::getAxisValuesG(float &x, float &y, float &z)
  146 +{
  147 + int16_t x_ = 0, y_ = 0, z_ = 0;
  148 +
  149 + uint8_t err = getXValue(x_);
  150 + if (err != E_OK) {
  151 + return err;
  152 + }
  153 +
  154 + err = getYValue(y_);
  155 + if (err != E_OK) {
  156 + return err;
  157 + }
  158 +
  159 + err = getZValue(z_);
  160 + if (err != E_OK) {
  161 + return err;
  162 + }
  163 +
  164 + float scale = 0.0f;
  165 + switch (currentScale) {
  166 + case Scale::scale6g:
  167 + scale = (6 * 2) / 4096.0f;
  168 + break;
  169 + case Scale::scale12g:
  170 + scale = (12 * 2) / 4096.0f;
  171 + break;
  172 + case Scale::scale24g:
  173 + scale = (24 * 2) / 4096.0f;
  174 + break;
  175 + default:
  176 + return E_WRONG_SCALE;
  177 + }
  178 +
  179 + x = x_ * scale;
  180 + y = y_ * scale;
  181 + z = z_ * scale;
  182 +
  183 + return E_OK;
  184 +}
  185 +
  186 +uint8_t LIS331::getHighPassFilterMode(HighPassFilter &ret)
  187 +{
  188 + byte ctrlReg2 = 0;
  189 + const uint8_t err = readReg(LIS_CTRL_REG2, ctrlReg2);
  190 + if (err != E_OK) {
  191 + return err;
  192 + }
  193 +
  194 + byte mode = 0;
  195 + bitWrite(mode, LIS_CTRL_REG2_HPM0, bitRead(ctrlReg2, LIS_CTRL_REG2_HPM0));
  196 + bitWrite(mode, LIS_CTRL_REG2_HPM1, bitRead(ctrlReg2, LIS_CTRL_REG2_HPM1));
  197 +
  198 + ret = HighPassFilter(mode);
  199 + return E_OK;
  200 +}
  201 +
  202 +uint8_t LIS331::setHighPassFilterMode(const HighPassFilter mode)
  203 +{
  204 + byte ctrlReg2 = 0;
  205 + const uint8_t err = readReg(LIS_CTRL_REG2, ctrlReg2);
  206 + if (err != E_OK) {
  207 + return err;
  208 + }
  209 +
  210 + bitWrite(ctrlReg2, LIS_CTRL_REG2_HPM0, bitRead(mode, LIS_CTRL_REG2_HPM0));
  211 + bitWrite(ctrlReg2, LIS_CTRL_REG2_HPM1, bitRead(mode, LIS_CTRL_REG2_HPM1));
  212 +
  213 + return writeReg(LIS_CTRL_REG2, ctrlReg2);
  214 +}
  215 +
  216 +uint8_t LIS331::getHighPassCutOff(HighPassCutOff &ret)
  217 +{
  218 + byte ctrlReg2 = 0;
  219 + const uint8_t err = readReg(LIS_CTRL_REG2, ctrlReg2);
  220 + if (err != E_OK) {
  221 + return err;
  222 + }
  223 +
  224 + byte mode = 0;
  225 + bitWrite(mode, LIS_CTRL_REG2_HPCF0, bitRead(ctrlReg2, LIS_CTRL_REG2_HPCF0));
  226 + bitWrite(mode, LIS_CTRL_REG2_HPCF1, bitRead(ctrlReg2, LIS_CTRL_REG2_HPCF1));
  227 +
  228 + ret = HighPassCutOff(mode);
  229 + return E_OK;
  230 +}
  231 +
  232 +uint8_t LIS331::setHighPassCutOff(const HighPassCutOff mode)
  233 +{
  234 + byte ctrlReg2 = 0;
  235 + const uint8_t err = readReg(LIS_CTRL_REG2, ctrlReg2);
  236 + if (err != E_OK) {
  237 + return err;
  238 + }
  239 +
  240 + bitWrite(ctrlReg2, LIS_CTRL_REG2_HPCF0, bitRead(mode, LIS_CTRL_REG2_HPCF0));
  241 + bitWrite(ctrlReg2, LIS_CTRL_REG2_HPCF1, bitRead(mode, LIS_CTRL_REG2_HPCF1));
  242 +
  243 + return writeReg(LIS_CTRL_REG2, ctrlReg2);
  244 +}
  245 +
  246 +uint8_t LIS331::isInterruptLatched(const byte interrupt, bool &ret)
  247 +{
  248 + if (interrupt == 1) {
  249 + return readRegisterBit(LIS_CTRL_REG3, LIS_CTRL_REG3_LIR1, ret);
  250 + } else if (interrupt == 2) {
  251 + return readRegisterBit(LIS_CTRL_REG3, LIS_CTRL_REG3_LIR2, ret);
  252 + }
  253 +
  254 + return E_WRONG_INTERRUPT;
  255 +}
  256 +
  257 +uint8_t LIS331::setInterruptLatched(const byte interrupt, const bool latched)
  258 +{
  259 + if (interrupt == 1) {
  260 + return writeRegisterBit(LIS_CTRL_REG3, LIS_CTRL_REG3_LIR1, latched);
  261 + } else if (interrupt == 2) {
  262 + return writeRegisterBit(LIS_CTRL_REG3, LIS_CTRL_REG3_LIR2, latched);
  263 + }
  264 +
  265 + return E_WRONG_INTERRUPT;
  266 +}
  267 +
  268 +uint8_t LIS331::getInt1DataSignal(Int1DataSignal &ret)
  269 +{
  270 + byte ctrlReg3 = 0;
  271 + const uint8_t err = readReg(LIS_CTRL_REG3, ctrlReg3);
  272 + if (err != E_OK) {
  273 + return err;
  274 + }
  275 +
  276 + byte signal = 0;
  277 + bitWrite(signal, LIS_CTRL_REG3_I1_CFG0, bitRead(ctrlReg3, LIS_CTRL_REG3_I1_CFG0));
  278 + bitWrite(signal, LIS_CTRL_REG3_I1_CFG1, bitRead(ctrlReg3, LIS_CTRL_REG3_I1_CFG1));
  279 +
  280 + ret = Int1DataSignal(signal);
  281 + return E_OK;
  282 +}
  283 +
  284 +uint8_t LIS331::getInt2DataSignal(Int2DataSignal &ret)
  285 +{
  286 + byte ctrlReg3 = 0;
  287 + const uint8_t err = readReg(LIS_CTRL_REG3, ctrlReg3);
  288 + if (err != E_OK) {
  289 + return err;
  290 + }
  291 +
  292 + byte signal = 0;
  293 + bitWrite(signal, LIS_CTRL_REG3_I2_CFG0, bitRead(ctrlReg3, LIS_CTRL_REG3_I2_CFG0));
  294 + bitWrite(signal, LIS_CTRL_REG3_I2_CFG1, bitRead(ctrlReg3, LIS_CTRL_REG3_I2_CFG1));
  295 +
  296 + ret = Int2DataSignal(signal);
  297 + return E_OK;
  298 +}
  299 +
  300 +uint8_t LIS331::setDataSignal(const Int1DataSignal signal)
  301 +{
  302 + byte ctrlReg3 = 0;
  303 + const uint8_t err = readReg(LIS_CTRL_REG3, ctrlReg3);
  304 + if (err != E_OK) {
  305 + return err;
  306 + }
  307 +
  308 + bitWrite(ctrlReg3, LIS_CTRL_REG3_I1_CFG0, bitRead(signal, LIS_CTRL_REG3_I1_CFG0));
  309 + bitWrite(ctrlReg3, LIS_CTRL_REG3_I1_CFG1, bitRead(signal, LIS_CTRL_REG3_I1_CFG1));
  310 +
  311 + return writeReg(LIS_CTRL_REG3, ctrlReg3);
  312 +}
  313 +
  314 +uint8_t LIS331::setDataSignal(const Int2DataSignal signal)
  315 +{
  316 + byte ctrlReg3 = 0;
  317 + const uint8_t err = readReg(LIS_CTRL_REG3, ctrlReg3);
  318 + if (err != E_OK) {
  319 + return err;
  320 + }
  321 +
  322 + bitWrite(ctrlReg3, LIS_CTRL_REG3_I2_CFG0, bitRead(signal, LIS_CTRL_REG3_I2_CFG0));
  323 + bitWrite(ctrlReg3, LIS_CTRL_REG3_I2_CFG1, bitRead(signal, LIS_CTRL_REG3_I2_CFG1));
  324 +
  325 + return writeReg(LIS_CTRL_REG3, ctrlReg3);
  326 +}
  327 +
  328 +uint8_t LIS331::getScale(Scale &ret)
  329 +{
  330 + byte ctrlReg4 = 0;
  331 + const uint8_t err = readReg(LIS_CTRL_REG4, ctrlReg4);
  332 + if (err != E_OK) {
  333 + return err;
  334 + }
  335 +
  336 + byte scale = 0;
  337 + bitWrite(scale, LIS_CTRL_REG4_FS0, bitRead(ctrlReg4, LIS_CTRL_REG4_FS0));
  338 + bitWrite(scale, LIS_CTRL_REG4_FS1, bitRead(ctrlReg4, LIS_CTRL_REG4_FS1));
  339 +
  340 + ret = Scale(scale);
  341 + currentScale = ret;
  342 +
  343 + return E_OK;
  344 +}
  345 +
  346 +uint8_t LIS331::setScale(const Scale scale)
  347 +{
  348 + byte ctrlReg4 = 0;
  349 + uint8_t err = readReg(LIS_CTRL_REG4, ctrlReg4);
  350 + if (err != E_OK) {
  351 + return err;
  352 + }
  353 +
  354 + bitWrite(ctrlReg4, LIS_CTRL_REG4_FS0, bitRead(scale, LIS_CTRL_REG4_FS0));
  355 + bitWrite(ctrlReg4, LIS_CTRL_REG4_FS1, bitRead(scale, LIS_CTRL_REG4_FS1));
  356 +
  357 + err = writeReg(LIS_CTRL_REG4, ctrlReg4);
  358 + if (err == E_OK) {
  359 + currentScale = scale;
  360 + }
  361 +
  362 + return err;
  363 +}
  364 +
  365 +uint8_t LIS331::isSleepToWakeEnabled(bool &ret)
  366 +{
  367 + byte ctrlReg5 = 0;
  368 + const uint8_t err = readReg(LIS_CTRL_REG5, ctrlReg5);
  369 + if (err != E_OK) {
  370 + return err;
  371 + }
  372 +
  373 + ret = bitRead(ctrlReg5, LIS_CTRL_REG5_TURNON_0) && bitRead(ctrlReg5, LIS_CTRL_REG5_TURNON_1);
  374 + return E_OK;
  375 +}
  376 +
  377 +uint8_t LIS331::setSleepToWakeEnabled(const bool enabled)
  378 +{
  379 + byte ctrlReg5 = 0;
  380 + const uint8_t err = readReg(LIS_CTRL_REG5, ctrlReg5);
  381 + if (err != E_OK) {
  382 + return err;
  383 + }
  384 +
  385 + bitWrite(ctrlReg5, LIS_CTRL_REG5_TURNON_0, enabled);
  386 + bitWrite(ctrlReg5, LIS_CTRL_REG5_TURNON_1, enabled);
  387 +
  388 + return writeReg(LIS_CTRL_REG5, ctrlReg5);
  389 +}
  390 +
  391 +uint8_t LIS331::getInterruptSource(const byte interrupt, IntSource &ret)
  392 +{
  393 + byte intRegAddr = 0;
  394 + switch (interrupt) {
  395 + case 1:
  396 + intRegAddr = LIS_INT1_CFG;
  397 + break;
  398 + case 2:
  399 + intRegAddr = LIS_INT2_CFG;
  400 + break;
  401 + default:
  402 + return E_WRONG_INTERRUPT;
  403 + }
  404 +
  405 + byte intRegVal = 0;
  406 + const uint8_t err = readReg(intRegAddr, intRegVal);
  407 + if (err != E_OK) {
  408 + return err;
  409 + }
  410 +
  411 + byte source = 0;
  412 + bitWrite(source, LIS_INT_CFG_AOI, bitRead(intRegVal, LIS_INT_CFG_AOI));
  413 + bitWrite(source, LIS_INT_CFG_6D, bitRead(intRegVal, LIS_INT_CFG_6D));
  414 +
  415 + ret = IntSource(source);
  416 + return E_OK;
  417 +}
  418 +
  419 +uint8_t LIS331::setInterruptSource(const byte interrupt, IntSource source)
  420 +
  421 +{
  422 + byte intRegAddr = 0;
  423 + switch (interrupt) {
  424 + case 1:
  425 + intRegAddr = LIS_INT1_CFG;
  426 + break;
  427 + case 2:
  428 + intRegAddr = LIS_INT2_CFG;
  429 + break;
  430 + default:
  431 + return E_WRONG_INTERRUPT;
  432 + }
  433 +
  434 + byte intRegVal = 0;
  435 + const uint8_t err = readReg(intRegAddr, intRegVal);
  436 + if (err != E_OK) {
  437 + return err;
  438 + }
  439 +
  440 + bitWrite(intRegVal, LIS_INT_CFG_AOI, bitRead(source, LIS_INT_CFG_AOI));
  441 + bitWrite(intRegVal, LIS_INT_CFG_6D, bitRead(source, LIS_INT_CFG_6D));
  442 +
  443 + return writeReg(intRegAddr, intRegVal);
  444 +}
  445 +
  446 +uint8_t LIS331::isInterruptEnabled(const byte interrupt, const Axis axis, const bool highEvent, bool &ret)
  447 +{
  448 + byte intCfgAddr = 0;
  449 + switch (interrupt) { // TODO: Simplify with C++17 Structured Bindings
  450 + case 1:
  451 + intCfgAddr = LIS_INT1_CFG;
  452 + break;
  453 + case 2:
  454 + intCfgAddr = LIS_INT2_CFG;
  455 + break;
  456 + default:
  457 + return E_WRONG_INTERRUPT;
  458 + }
  459 +
  460 + byte bit = 0;
  461 + bit += axis; // set X, Y or Z
  462 + bit += highEvent; // set high or low
  463 +
  464 + byte intCfgVal = 0;
  465 + const uint8_t err = readReg(intCfgAddr, intCfgVal);
  466 + if (err != E_OK) {
  467 + return err;
  468 + }
  469 +
  470 + return readRegisterBit(intCfgAddr, bit, ret);
  471 +}
  472 +
  473 +uint8_t LIS331::setInterruptEnabled(const byte interrupt, const Axis axis, const bool highEvent, const bool enabled)
  474 +{
  475 + byte intCfgAddr = 0;
  476 + switch (interrupt) { // TODO: Simplify with C++17 Structured Bindings
  477 + case 1:
  478 + intCfgAddr = LIS_INT1_CFG;
  479 + break;
  480 + case 2:
  481 + intCfgAddr = LIS_INT2_CFG;
  482 + break;
  483 + default:
  484 + return E_WRONG_INTERRUPT;
  485 + }
  486 +
  487 + byte bit = 0;
  488 + bit += axis; // set X, Y or Z
  489 + bit += highEvent; // set high or low
  490 +
  491 + byte intCfgVal = 0;
  492 + const uint8_t err = readReg(intCfgAddr, intCfgVal);
  493 + if (err != E_OK) {
  494 + return err;
  495 + }
  496 +
  497 + bitWrite(intCfgVal, bit, enabled);
  498 + return writeReg(intCfgAddr, intCfgVal);
  499 +}
  500 +
  501 +uint8_t LIS331::readInterrupt(const byte interrupt)
  502 +{
  503 + byte intSrcAddr = 0;
  504 + switch (interrupt) { // TODO: Simplify with C++17 Structured Bindings
  505 + case 1:
  506 + intSrcAddr = LIS_INT1_SOURCE;
  507 + break;
  508 + case 2:
  509 + intSrcAddr = LIS_INT2_SOURCE;
  510 + break;
  511 + default:
  512 + return E_WRONG_INTERRUPT;
  513 + }
  514 +
  515 + byte intSrcVal = 0;
  516 + const uint8_t err = readReg(intSrcAddr, intSrcVal);
  517 + if (err != E_OK) {
  518 + return err;
  519 + }
  520 +
  521 + interruptSource = intSrcVal;
  522 + return E_OK;
  523 +}
  524 +
  525 +uint8_t LIS331::getInterruptValue(const Axis axis, const bool highEvent, bool &ret)
  526 +{
  527 + byte bit = 0;
  528 + bit += axis; // set X, Y or Z
  529 + bit += highEvent; // set high or low
  530 +
  531 + ret = bitRead(interruptSource, bit);
  532 + return E_OK;
  533 +}
  534 +
  535 +uint8_t LIS331::getInterruptThreshold(const byte interrupt, byte &ret)
  536 +{
  537 + byte intThsAddr = 0;
  538 + switch (interrupt) { // TODO: Simplify with C++17 Structured Bindings
  539 + case 1:
  540 + intThsAddr = LIS_INT1_THS;
  541 + break;
  542 + case 2:
  543 + intThsAddr = LIS_INT2_THS;
  544 + break;
  545 + default:
  546 + return E_WRONG_INTERRUPT;
  547 + }
  548 +
  549 + return getInterruptThresholdAndDuration(intThsAddr, ret);
  550 +}
  551 +
  552 +uint8_t LIS331::setInterruptThreshold(const byte interrupt, const byte threshold)
  553 +{
  554 + byte intThsAddr = 0;
  555 + switch (interrupt) { // TODO: Simplify with C++17 Structured Bindings
  556 + case 1:
  557 + intThsAddr = LIS_INT1_THS;
  558 + break;
  559 + case 2:
  560 + intThsAddr = LIS_INT2_THS;
  561 + break;
  562 + default:
  563 + return E_WRONG_INTERRUPT;
  564 + }
  565 +
  566 + return setInterruptThresholdAndDuration(intThsAddr, threshold);
  567 +}
  568 +
  569 +uint8_t LIS331::getInterruptThresholdG(const byte interrupt, float &ret)
  570 +{
  571 + float scale = 0.0f;
  572 + switch (currentScale) {
  573 + case Scale::scale6g:
  574 + scale = 6 / 127.0f;
  575 + break;
  576 + case Scale::scale12g:
  577 + scale = 12 / 127.0f;
  578 + break;
  579 + case Scale::scale24g:
  580 + scale = 24 / 127.0f;
  581 + break;
  582 + default:
  583 + return E_WRONG_SCALE;
  584 + }
  585 +
  586 + byte rawThreshold = 0;
  587 + const uint8_t err = getInterruptThreshold(interrupt, rawThreshold);
  588 + if (err != E_OK) {
  589 + return err;
  590 + }
  591 +
  592 + ret = rawThreshold * scale;
  593 + return E_OK;
  594 +}
  595 +
  596 +uint8_t LIS331::setInterruptThresholdG(const byte interrupt, const float threshold)
  597 +{
  598 + float scale = 0.0f;
  599 + switch (currentScale) {
  600 + case Scale::scale6g:
  601 + if (threshold > 6) {
  602 + return E_NUM_TOO_BIG;
  603 + }
  604 + scale = 6 / 127.0f;
  605 + break;
  606 + case Scale::scale12g:
  607 + if (threshold > 12) {
  608 + return E_NUM_TOO_BIG;
  609 + }
  610 + scale = 12 / 127.0f;
  611 + break;
  612 + case Scale::scale24g:
  613 + if (threshold > 24) {
  614 + return E_NUM_TOO_BIG;
  615 + }
  616 + scale = 24 / 127.0f;
  617 + break;
  618 + default:
  619 + return E_WRONG_SCALE;
  620 + }
  621 +
  622 + const byte rawValue = static_cast<const byte>(threshold / scale); // round: floor
  623 + return setInterruptThreshold(interrupt, rawValue);
  624 +}
  625 +
  626 +uint8_t LIS331::getInterruptDuration(const byte interrupt, byte &ret)
  627 +{
  628 + byte intDurAddr = 0;
  629 + switch (interrupt) { // TODO: Simplify with C++17 Structured Bindings
  630 + case 1:
  631 + intDurAddr = LIS_INT1_DURATION;
  632 + break;
  633 + case 2:
  634 + intDurAddr = LIS_INT2_DURATION;
  635 + break;
  636 + default:
  637 + return E_WRONG_INTERRUPT;
  638 + }
  639 +
  640 + return getInterruptThresholdAndDuration(intDurAddr, ret);
  641 +}
  642 +
  643 +uint8_t LIS331::setInterruptDuration(const byte interrupt, const byte duration)
  644 +{
  645 + byte intDurAddr = 0;
  646 + switch (interrupt) { // TODO: Simplify with C++17 Structured Bindings
  647 + case 1:
  648 + intDurAddr = LIS_INT1_DURATION;
  649 + break;
  650 + case 2:
  651 + intDurAddr = LIS_INT2_DURATION;
  652 + break;
  653 + default:
  654 + return E_WRONG_INTERRUPT;
  655 + }
  656 +
  657 + return setInterruptThresholdAndDuration(intDurAddr, duration);
  658 +}
  659 +
  660 +uint8_t LIS331::getInterruptThresholdAndDuration(const byte address, byte &ret)
  661 +{
  662 + const uint8_t err = readReg(address, ret);
  663 + if (err != E_OK) {
  664 + return err;
  665 + }
  666 +
  667 + bitClear(ret, CHAR_BIT - 1);
  668 + return E_OK;
  669 +}
  670 +
  671 +uint8_t LIS331::setInterruptThresholdAndDuration(const byte address, const byte value)
  672 +{
  673 + if (bitRead(value, CHAR_BIT - 1) == 1) {
  674 + return E_NUM_TOO_BIG;
  675 + }
  676 +
  677 + return writeReg(address, value);
  678 +}
robots/little_john/telemetry/code/robot/Accelerometer/H3LIS331DL_Accelerometer_library/LIS331/src/LIS331.h 0 → 100644
@@ -0,0 +1,656 @@ @@ -0,0 +1,656 @@
  1 +/* Copyright © 2017 Szőts Ákos <szotsaki@gmail.com>
  2 + *
  3 + * This program is free software: you can redistribute it and/or modify
  4 + * it under the terms of the GNU General Public License as published by
  5 + * the Free Software Foundation, either version 3 of the License, or
  6 + * (at your option) any later version.
  7 + *
  8 + * This program is distributed in the hope that it will be useful,
  9 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  10 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11 + * GNU General Public License for more details.
  12 + * You should have received a copy of the GNU General Public License
  13 + * along with this program. If not, see <http://www.gnu.org/licenses/>.
  14 + *
  15 +*/
  16 +
  17 +#ifndef LIS331_H
  18 +#define LIS331_H
  19 +
  20 +#include <limits.h>
  21 +
  22 +#include "Arduino.h"
  23 +#include <I2C.h>
  24 +
  25 +// More error codes besides the ones in I2C.h
  26 +#define E_OK 0x0
  27 +#define E_WRONG_INTERRUPT 0x75
  28 +#define E_NUM_TOO_BIG 0x76
  29 +#define E_WRONG_SCALE 0x77
  30 +
  31 +// Register addresses
  32 +#define LIS_CTRL_REG1 0x20
  33 +#define LIS_CTRL_REG2 0x21
  34 +#define LIS_CTRL_REG3 0x22
  35 +#define LIS_CTRL_REG4 0x23
  36 +#define LIS_CTRL_REG5 0x24
  37 +#define LIS_HP_FILTER_RESET 0x25
  38 +#define LIS_REFERENCE 0x26
  39 +#define LIS_STATUS_REG 0x27
  40 +#define LIS_OUT_X_L 0x28
  41 +#define LIS_OUT_X_H 0x29
  42 +#define LIS_OUT_Y_L 0x2A
  43 +#define LIS_OUT_Y_H 0x2B
  44 +#define LIS_OUT_Z_L 0x2C
  45 +#define LIS_OUT_Z_H 0x2D
  46 +#define LIS_INT1_CFG 0x30
  47 +#define LIS_INT1_SOURCE 0x31
  48 +#define LIS_INT1_THS 0x32
  49 +#define LIS_INT1_DURATION 0x33
  50 +#define LIS_INT2_CFG 0x34
  51 +#define LIS_INT2_SOURCE 0x35
  52 +#define LIS_INT2_THS 0x36
  53 +#define LIS_INT2_DURATION 0x37
  54 +
  55 +// Control register 1
  56 +#define LIS_CTRL_REG1_PM2 7
  57 +#define LIS_CTRL_REG1_PM1 6
  58 +#define LIS_CTRL_REG1_PM0 5
  59 +#define LIS_CTRL_REG1_DR1 4
  60 +#define LIS_CTRL_REG1_DR0 3
  61 +#define LIS_CTRL_REG1_ZEN 2
  62 +#define LIS_CTRL_REG1_YEN 1
  63 +#define LIS_CTRL_REG1_XEN 0
  64 +
  65 +// Control register 2
  66 +#define LIS_CTRL_REG2_BOOT 7
  67 +#define LIS_CTRL_REG2_HPM1 6
  68 +#define LIS_CTRL_REG2_HPM0 5
  69 +#define LIS_CTRL_REG2_FDS 4
  70 +#define LIS_CTRL_REG2_HPEN2 3
  71 +#define LIS_CTRL_REG2_HPEN1 2
  72 +#define LIS_CTRL_REG2_HPCF1 1
  73 +#define LIS_CTRL_REG2_HPCF0 0
  74 +
  75 +// Control register 3
  76 +#define LIS_CTRL_REG3_IHL 7
  77 +#define LIS_CTRL_REG3_PP_OD 6
  78 +#define LIS_CTRL_REG3_LIR2 5
  79 +#define LIS_CTRL_REG3_I2_CFG1 4
  80 +#define LIS_CTRL_REG3_I2_CFG0 3
  81 +#define LIS_CTRL_REG3_LIR1 2
  82 +#define LIS_CTRL_REG3_I1_CFG1 1
  83 +#define LIS_CTRL_REG3_I1_CFG0 0
  84 +
  85 +// Control register 4
  86 +#define LIS_CTRL_REG4_BDU 7
  87 +// BLE 6
  88 +#define LIS_CTRL_REG4_FS1 5
  89 +#define LIS_CTRL_REG4_FS0 4
  90 +#define LIS_CTRL_REG4_STSIGN 3
  91 +// 0 2
  92 +#define LIS_CTRL_REG4_ST 1
  93 +// SIM 0
  94 +
  95 +// Control register 5
  96 +// Unused 7..2
  97 +#define LIS_CTRL_REG5_TURNON_1 1
  98 +#define LIS_CTRL_REG5_TURNON_0 0
  99 +
  100 +// Status register
  101 +#define LIS_STATUS_REG_ZYXOR 7
  102 +#define LIS_STATUS_REG_ZOR 6
  103 +#define LIS_STATUS_REG_YOR 5
  104 +#define LIS_STATUS_REG_XOR 4
  105 +#define LIS_STATUS_REG_ZYXDA 3
  106 +#define LIS_STATUS_REG_ZDA 2
  107 +#define LIS_STATUS_REG_YDA 1
  108 +#define LIS_STATUS_REG_XDA 0
  109 +
  110 +// Interrupt registers
  111 +#define LIS_INT_CFG_AOI 7
  112 +#define LIS_INT_CFG_6D 6
  113 +
  114 +#define LIS_INT_SRC_IA 6
  115 +
  116 +class LIS331
  117 +{
  118 +public:
  119 + enum Scale : byte;
  120 +
  121 +private:
  122 + const uint8_t i2cAddress;
  123 + byte interruptSource;
  124 + Scale currentScale;
  125 +
  126 + uint8_t readReg(const byte addr, byte &val);
  127 + uint8_t writeReg(const byte addr, const byte val);
  128 +
  129 + uint8_t readRegisterBit(const byte registerAddr, const byte bit, bool &ret);
  130 + uint8_t writeRegisterBit(const byte registerAddr, const byte bit, const bool enabled);
  131 +
  132 + uint8_t getAxisValue(const byte addressLow, const byte addressHigh, int16_t &ret);
  133 +
  134 + uint8_t getInterruptThresholdAndDuration(const byte address, byte &ret);
  135 + uint8_t setInterruptThresholdAndDuration(const byte address, const byte value);
  136 +
  137 +public:
  138 + enum PowerMode : byte
  139 + {
  140 + powerDown = B00000000,
  141 + normalMode = B00100000,
  142 + lowPower05Hz = B01000000,
  143 + lowPower1Hz = B01100000,
  144 + lowPower2Hz = B10000000,
  145 + lowPower5Hz = B10100000,
  146 + lowPower10Hz = B11000000
  147 + };
  148 +
  149 + enum DataRate : byte
  150 + {
  151 + odr50Hz = B00000000,
  152 + odr100Hz = B00001000,
  153 + odr400Hz = B00010000,
  154 + odr1000Hz = B00011000
  155 + };
  156 +
  157 + enum Scale : byte
  158 + {
  159 + scale6g = B00000000,
  160 + scale12g = B00010000,
  161 + scale24g = B00110000
  162 + };
  163 +
  164 + enum HighPassFilter : byte
  165 + {
  166 + hpfNormal = B00000000,
  167 + hpfReference = B00100000,
  168 + hpfConfigCutOff = B01000000
  169 + };
  170 +
  171 + enum HighPassCutOff : byte
  172 + {
  173 + hpCutOff8 = B00000000,
  174 + hpCutOff16 = B00000001,
  175 + hpCutOff32 = B00000010,
  176 + hpCutOff64 = B00000011
  177 + };
  178 +
  179 + enum Int1DataSignal : byte
  180 + {
  181 + ds1Interrupt1Source = B00000000,
  182 + ds1Interrupt1Or2Src = B00000001,
  183 + ds1DataReady = B00000010,
  184 + ds1BootRunning = B00000011
  185 + };
  186 +
  187 + enum Int2DataSignal : byte
  188 + {
  189 + ds2Interrupt2Source = B00000000,
  190 + ds2Interrupt1Or2Src = B00001000,
  191 + ds2DataReady = B00010000,
  192 + ds2BootRunning = B00011000
  193 + };
  194 +
  195 + enum Axis : byte
  196 + {
  197 + X = 0,
  198 + Y = 1,
  199 + Z = 2
  200 + };
  201 +
  202 + enum IntSource : byte
  203 + {
  204 + intsOrCombination = B00000000,
  205 + intsAndCombination = B10000000,
  206 + ints6DirMovementRec = B01000000,
  207 + ints6DirPositionRec = B11000000
  208 + };
  209 +
  210 + explicit LIS331(const uint8_t i2cAddress = 0x18);
  211 +
  212 + // Control register 1
  213 + uint8_t getPowerMode(PowerMode &ret);
  214 + uint8_t setPowerMode(const PowerMode mode);
  215 +
  216 + uint8_t getDataRate(DataRate &ret);
  217 + uint8_t setDataRate(const DataRate dataRate);
  218 +
  219 + inline uint8_t isXEnabled(bool &ret) {
  220 + return readRegisterBit(LIS_CTRL_REG1, LIS_CTRL_REG1_XEN, ret);
  221 + }
  222 +
  223 + inline uint8_t isYEnabled(bool &ret) {
  224 + return readRegisterBit(LIS_CTRL_REG1, LIS_CTRL_REG1_YEN, ret);
  225 + }
  226 +
  227 + inline uint8_t isZEnabled(bool &ret) {
  228 + return readRegisterBit(LIS_CTRL_REG1, LIS_CTRL_REG1_ZEN, ret);
  229 + }
  230 +
  231 + inline uint8_t setXEnabled(const bool enabled) {
  232 + return writeRegisterBit(LIS_CTRL_REG1, LIS_CTRL_REG1_XEN, enabled);
  233 + }
  234 +
  235 + inline uint8_t setYEnabled(const bool enabled) {
  236 + return writeRegisterBit(LIS_CTRL_REG1, LIS_CTRL_REG1_YEN, enabled);
  237 + }
  238 +
  239 + inline uint8_t setZEnabled(const bool enabled) {
  240 + return writeRegisterBit(LIS_CTRL_REG1, LIS_CTRL_REG1_ZEN, enabled);
  241 + }
  242 +
  243 + // X, Y, Z axes
  244 + /**
  245 + * @brief getAxisValuesG
  246 + * @param x
  247 + * @param y
  248 + * @param z
  249 + * @return The acceleration in [g] for all three axes
  250 + */
  251 + uint8_t getAxisValuesG(float &x, float &y, float &z);
  252 +
  253 + inline uint8_t getXValue(int16_t &ret) {
  254 + return getAxisValue(LIS_OUT_X_L, LIS_OUT_X_H, ret);
  255 + }
  256 +
  257 + inline uint8_t getYValue(int16_t &ret) {
  258 + return getAxisValue(LIS_OUT_Y_L, LIS_OUT_Y_H, ret);
  259 + }
  260 +
  261 + inline uint8_t getZValue(int16_t &ret) {
  262 + return getAxisValue(LIS_OUT_Z_L, LIS_OUT_Z_H, ret);
  263 + }
  264 +
  265 + // Control register 2
  266 +
  267 + /**
  268 + * @see setRebootMemoryContent
  269 + * @brief getRebootMemoryContent
  270 + * @return
  271 + */
  272 + inline uint8_t getRebootMemoryContent(bool &ret) {
  273 + return readRegisterBit(LIS_CTRL_REG2, LIS_CTRL_REG2_BOOT, ret);
  274 + }
  275 +
  276 + /**
  277 + * BOOT bit is used to refresh the content of internal registers stored in the flash memory
  278 + * block. At the device power up the content of the flash memory block is transferred to the
  279 + * internal registers related to trimming functions to permit a good behavior of the device itself.
  280 + * If for any reason the content of trimming registers was changed it is sufficient to use this bit
  281 + * to restore correct values. When BOOT bit is set to ‘1’ the content of internal flash is copied
  282 + * inside corresponding internal registers and it is used to calibrate the device. These values
  283 + * are factory trimmed and they are different for every accelerometer. They permit a good
  284 + * behavior of the device and normally they have not to be changed. At the end of the boot
  285 + * process the BOOT bit is set again to ‘0’.
  286 + *
  287 + * @brief setRebootMemoryContent
  288 + * @param reboot false: normal mode
  289 + * true: reboot memory content
  290 + * @return
  291 + */
  292 + inline uint8_t setRebootMemoryContent(const bool reboot) {
  293 + return writeRegisterBit(LIS_CTRL_REG2, LIS_CTRL_REG2_BOOT, reboot);
  294 + }
  295 +
  296 + uint8_t getHighPassFilterMode(HighPassFilter &ret);
  297 + uint8_t setHighPassFilterMode(const HighPassFilter mode);
  298 +
  299 + /**
  300 + * @brief isFilteredDataSection
  301 + * @return false: internal filter bypassed;
  302 + * true: data from internal filter sent to output register
  303 + */
  304 + inline uint8_t isFilteredDataSection(bool &ret) {
  305 + return readRegisterBit(LIS_CTRL_REG2, LIS_CTRL_REG2_FDS, ret);
  306 + }
  307 +
  308 + /**
  309 + * @brief setFilteredDataSection
  310 + * @param enabled false: internal filter bypassed;
  311 + * true: data from internal filter sent to output register
  312 + * @return
  313 + */
  314 + inline uint8_t setFilteredDataSection(const bool enabled) {
  315 + return writeRegisterBit(LIS_CTRL_REG2, LIS_CTRL_REG2_FDS, enabled);
  316 + }
  317 +
  318 + /**
  319 + * @brief isHPenabledForInterrupt1 High pass filter enabled for interrupt 1 source
  320 + * @return
  321 + */
  322 + inline uint8_t isHPenabledForInterrupt1(bool &ret) {
  323 + return readRegisterBit(LIS_CTRL_REG2, LIS_CTRL_REG2_HPEN1, ret);
  324 + }
  325 +
  326 + /**
  327 + * @brief setHPenabledForInterrupt1 High pass filter enabled for interrupt 1 source
  328 + * @param enabled
  329 + * @return
  330 + */
  331 + inline uint8_t setHPenabledForInterrupt1(const bool enabled) {
  332 + return writeRegisterBit(LIS_CTRL_REG2, LIS_CTRL_REG2_HPEN1, enabled);
  333 + }
  334 +
  335 + /**
  336 + * @brief isHPenabledForInterrupt2 High pass filter enabled for interrupt 2 source
  337 + * @return
  338 + */
  339 + inline uint8_t isHPenabledForInterrupt2(bool &ret) {
  340 + return readRegisterBit(LIS_CTRL_REG2, LIS_CTRL_REG2_HPEN2, ret);
  341 + }
  342 +
  343 + /**
  344 + * @brief setHPenabledForInterrupt2 High pass filter enabled for interrupt 2 source
  345 + * @param enabled
  346 + * @return
  347 + */
  348 + inline uint8_t setHPenabledForInterrupt2(const bool enabled) {
  349 + return writeRegisterBit(LIS_CTRL_REG2, LIS_CTRL_REG2_HPEN2, enabled);
  350 + }
  351 +
  352 + uint8_t getHighPassCutOff(HighPassCutOff &ret);
  353 + uint8_t setHighPassCutOff(const HighPassCutOff mode);
  354 +
  355 + /**
  356 + * If the high pass filter is enabled, all three axes are instantaneously set to 0g.
  357 + * This allows to overcome the settling time of the high pass filter.
  358 + * @brief resetHighPassFilter
  359 + * @return
  360 + */
  361 + inline uint8_t resetHighPassFilter() {
  362 + byte tmp = 0;
  363 + // Dummy register. Reading at this address zeroes instantaneously the content of the internal high pass-filter
  364 + return readReg(LIS_HP_FILTER_RESET, tmp);
  365 + }
  366 +
  367 + /**
  368 + * @see setHPReference()
  369 + * @brief getHPReference
  370 + * @return
  371 + */
  372 + inline uint8_t getHPReference(byte &reference) {
  373 + return readReg(LIS_REFERENCE, reference);
  374 + }
  375 +
  376 + /**
  377 + * This register sets the acceleration value taken as a reference for the high-pass filter output.
  378 + * When filter is turned on (at least one of setFilteredDataSection(), setHPenabledForInterrupt1(),
  379 + * or setHPenabledForInterrupt2() is enabled) and setHighPassFilterMode() is set to “hpfReference”,
  380 + * filter out is generated taking this value as a reference.
  381 + *
  382 + * @brief setHPReference
  383 + * @param reference
  384 + * @return
  385 + */
  386 + uint8_t setHPReference(const byte reference) {
  387 + return writeReg(LIS_REFERENCE, reference);
  388 + }
  389 +
  390 + // Control register 3
  391 + /**
  392 + * @brief isInterruptActiveHL
  393 + * @return false: active high (default)
  394 + * true: active low
  395 + */
  396 + inline uint8_t isInterruptActiveHL(bool &ret) {
  397 + return readRegisterBit(LIS_CTRL_REG3, LIS_CTRL_REG3_IHL, ret);
  398 + }
  399 +
  400 + /**
  401 + * @brief setInterruptActiveHL
  402 + * @param active false: active high (the level on interrupt pin is low and goes high when the interrupt occurs)
  403 + * true: active low (the level on interrupt pin is high and goes low when the interrupt occurs)
  404 + * @return
  405 + */
  406 + inline uint8_t setInterruptActiveHL(bool low) {
  407 + return writeRegisterBit(LIS_CTRL_REG3, LIS_CTRL_REG3_IHL, low);
  408 + }
  409 +
  410 + /**
  411 + * @brief getPPOD Push-pull/Open drain selection on interrupt pad. Default value false
  412 + * @return false: push-pull
  413 + * true: open drain
  414 + */
  415 + inline uint8_t getPPOD(bool &ret) {
  416 + return readRegisterBit(LIS_CTRL_REG3, LIS_CTRL_REG3_PP_OD, ret);
  417 + }
  418 +
  419 + /**
  420 + * @brief setPPOD Push-pull/Open drain selection on interrupt pad
  421 + * @param ppod false: push-pull
  422 + * true: open drain
  423 + * @return
  424 + */
  425 + inline uint8_t setPPOD(bool ppod) {
  426 + return writeRegisterBit(LIS_CTRL_REG3, LIS_CTRL_REG3_PP_OD, ppod);
  427 + }
  428 +
  429 + /**
  430 + * @brief isInterruptLatched The interrupt register is cleared by calling readInterrupt().
  431 + * Default value: false
  432 + * @param interrupt 1 or 2 depending on pin assignment
  433 + * @return false: interrupt request not latched
  434 + * true: interrupt request latched
  435 + */
  436 + uint8_t isInterruptLatched(const byte interrupt, bool &ret);
  437 +
  438 + /**
  439 + * @brief setInterruptLatched Latch interrupt request. The register is cleared by calling readInterrupt()
  440 + * @param interrupt 1 or 2 depending on pin assignment
  441 + * @param value false: interrupt request not latched
  442 + * true: interrupt request latched
  443 + * @return
  444 + */
  445 + uint8_t setInterruptLatched(const byte interrupt, const bool latched);
  446 +
  447 + uint8_t getInt1DataSignal(Int1DataSignal &ret);
  448 + uint8_t getInt2DataSignal(Int2DataSignal &ret);
  449 +
  450 + uint8_t setDataSignal(const Int1DataSignal signal);
  451 + uint8_t setDataSignal(const Int2DataSignal signal);
  452 +
  453 + // Control register 4
  454 + /**
  455 + * @brief isBDUEnabled: Block data update. Default value: 0
  456 + * @return true: output registers not updated between MSB and LSB reading
  457 + * false: continuos update
  458 + */
  459 + inline uint8_t isBDUEnabled(bool &ret) {
  460 + return readRegisterBit(LIS_CTRL_REG4, LIS_CTRL_REG4_BDU, ret);
  461 + }
  462 +
  463 + /**
  464 + * @brief setBDUEnabled: Block data update. Default value: 0
  465 + * @param enabled true: output registers not updated between MSB and LSB reading
  466 + * false: continuos update
  467 + * @return
  468 + */
  469 + inline uint8_t setBDUEnabled(const bool enabled) {
  470 + return writeRegisterBit(LIS_CTRL_REG4, LIS_CTRL_REG4_BDU, enabled);
  471 + }
  472 +
  473 + uint8_t getScale(Scale &ret);
  474 + uint8_t setScale(const Scale scale);
  475 +
  476 + /**
  477 + * @brief getSelfTestSign Self-test sign. Default value: 0
  478 + * @return true: self-test minus
  479 + * false: self-test plus
  480 + */
  481 + inline uint8_t getSelfTestSign(bool &ret) {
  482 + return readRegisterBit(LIS_CTRL_REG4, LIS_CTRL_REG4_STSIGN, ret);
  483 + }
  484 +
  485 + /**
  486 + * @brief setSelfTestSign Self-test sign. Default value: 0
  487 + * @param sign true: self-test minus
  488 + * false: self-test plus
  489 + * @return
  490 + */
  491 + inline uint8_t setSelfTestSign(const bool sign) {
  492 + return writeRegisterBit(LIS_CTRL_REG4, LIS_CTRL_REG4_STSIGN, sign);
  493 + }
  494 +
  495 + inline uint8_t isSelfTestEnabled(bool &ret) {
  496 + return readRegisterBit(LIS_CTRL_REG4, LIS_CTRL_REG4_ST, ret);
  497 + }
  498 +
  499 + inline uint8_t setSelfTestEnabled(const bool enabled) {
  500 + return writeRegisterBit(LIS_CTRL_REG4, LIS_CTRL_REG4_ST, enabled);
  501 + }
  502 +
  503 + // Control register 5
  504 + /**
  505 + * When an interrupt event occurs the device is turned to normal mode
  506 + * increasing the ODR (output data rate) to the value defined with setDataRate().
  507 + * Although the device is in normal mode, getPowerMode() is not
  508 + * automatically changed to “normal mode” configuration.
  509 + *
  510 + * @brief isSleepToWakeEnabled
  511 + * @return
  512 + */
  513 + uint8_t isSleepToWakeEnabled(bool &ret);
  514 + uint8_t setSleepToWakeEnabled(const bool enabled);
  515 +
  516 + // Status register
  517 + inline uint8_t isAllDataOverrun(bool &ret) {
  518 + return readRegisterBit(LIS_STATUS_REG, LIS_STATUS_REG_ZYXOR, ret);
  519 + }
  520 +
  521 + inline uint8_t isXDataOverrun(bool &ret) {
  522 + return readRegisterBit(LIS_STATUS_REG, LIS_STATUS_REG_XOR, ret);
  523 + }
  524 +
  525 + inline uint8_t isYDataOverrun(bool &ret) {
  526 + return readRegisterBit(LIS_STATUS_REG, LIS_STATUS_REG_YOR, ret);
  527 + }
  528 +
  529 + inline uint8_t isZDataOverrun(bool &ret) {
  530 + return readRegisterBit(LIS_STATUS_REG, LIS_STATUS_REG_ZOR, ret);
  531 + }
  532 +
  533 + inline uint8_t isAllDataAvailable(bool &ret) {
  534 + return readRegisterBit(LIS_STATUS_REG, LIS_STATUS_REG_ZYXDA, ret);
  535 + }
  536 +
  537 + inline uint8_t isXDataAvailable(bool &ret) {
  538 + return readRegisterBit(LIS_STATUS_REG, LIS_STATUS_REG_XDA, ret);
  539 + }
  540 +
  541 + inline uint8_t isYDataAvailable(bool &ret) {
  542 + return readRegisterBit(LIS_STATUS_REG, LIS_STATUS_REG_YDA, ret);
  543 + }
  544 +
  545 + inline uint8_t isZDataAvailable(bool &ret) {
  546 + return readRegisterBit(LIS_STATUS_REG, LIS_STATUS_REG_ZDA, ret);
  547 + }
  548 +
  549 + // Interrupt config register
  550 + uint8_t getInterruptSource(const byte interrupt, IntSource &ret);
  551 + uint8_t setInterruptSource(const byte interrupt, IntSource source);
  552 +
  553 + /**
  554 + * @see setInterruptEnabled()
  555 + * @brief isInterruptEnabled
  556 + * @param interrupt
  557 + * @param axis
  558 + * @param highEvent
  559 + * @param ret
  560 + * @return
  561 + */
  562 + uint8_t isInterruptEnabled(const byte interrupt, const Axis axis, const bool highEvent, bool &ret);
  563 +
  564 + /**
  565 + * @brief setInterruptEnabled
  566 + * @param interrupt 1 or 2
  567 + * @param axis
  568 + * @param highEvent True to enable interrupt request on measured acceleration value higher than
  569 + * preset threshold.
  570 + * @param enabled
  571 + * @return
  572 + */
  573 + uint8_t setInterruptEnabled(const byte interrupt, const Axis axis, const bool highEvent, const bool enabled);
  574 +
  575 + // Interrupt source register
  576 + /**
  577 + * Reading at this address clears isInterruptGenerated() bit (and the interrupt signal on the pin) and
  578 + * allows the refreshment of data in the interrupt source register if the latched option was chosen
  579 + * with setInterruptLatched().
  580 + *
  581 + * This function reads the entire register into a temporal variable, thus:
  582 + * - it's possible to gather information based on one consistent state with the isInterruptGenerated()
  583 + * and getInterruptValue() functions;
  584 + * - it's necessary to call this function before you call any of the two aforementioned functions.
  585 + * @brief readInterrupt
  586 + * @param interrupt
  587 + * @return
  588 + */
  589 + uint8_t readInterrupt(const byte interrupt);
  590 +
  591 + inline uint8_t isInterruptGenerated(bool &ret) {
  592 + ret = bitRead(interruptSource, LIS_INT_SRC_IA);
  593 + return E_OK;
  594 + }
  595 +
  596 + uint8_t getInterruptValue(const Axis axis, const bool highEvent, bool &ret);
  597 +
  598 + // Interrupt threshold register
  599 + /**
  600 + * @see setInterruptThreshold()
  601 + * @brief getInterruptThreshold
  602 + * @param interrupt
  603 + * @param ret
  604 + * @return
  605 + */
  606 + uint8_t getInterruptThreshold(const byte interrupt, byte &ret);
  607 +
  608 + /**
  609 + * @brief setInterruptThreshold
  610 + * @param interrupt
  611 + * @param threshold Must be between 0..127
  612 + * @return
  613 + */
  614 + uint8_t setInterruptThreshold(const byte interrupt, const byte threshold);
  615 +
  616 + /**
  617 + * @see setInterruptThresholdG()
  618 + * @brief getInterruptThresholdG
  619 + * @param interrupt
  620 + * @param ret
  621 + * @return
  622 + */
  623 + uint8_t getInterruptThresholdG(const byte interrupt, float &ret);
  624 +
  625 + /**
  626 + * @brief setInterruptThresholdG Use [g] values to set an interrupt threshold instead of raw values.
  627 + * Since the resolution is not infinite, it may not be set to exact value. If it is the case,
  628 + * the raw value will be rounded down to the nearest acceptable. It is worth running
  629 + * getInterruptThresholdG() to obtain the programmed value (or calculate it manually).
  630 + * @param interrupt 1 or 2
  631 + * @param threshold Must be smaller or equal than the configured scale (6g, 12g, or 24g)
  632 + * @return
  633 + */
  634 + uint8_t setInterruptThresholdG(const byte interrupt, const float threshold);
  635 +
  636 + // Interrupt duration register
  637 + /**
  638 + * @see setInterruptDuration()
  639 + * @brief getInterruptDuration
  640 + * @param interrupt
  641 + * @param ret
  642 + * @return
  643 + */
  644 + uint8_t getInterruptDuration(const byte interrupt, byte &ret);
  645 +
  646 + /**
  647 + * @brief setInterruptDuration Sets the minimum duration of the interrupt event to be recognized
  648 + * @param interrupt
  649 + * @param duration Must be between 0..127. Duration time steps and maximum values depend on the
  650 + * DataRate chosen.
  651 + * @return
  652 + */
  653 + uint8_t setInterruptDuration(const byte interrupt, const byte duration);
  654 +};
  655 +
  656 +#endif // LIS331_H
robots/little_john/telemetry/code/robot/Accelerometer/H3LIS331DL_Accelerometer_library/README_Accelerometer 0 → 100644
@@ -0,0 +1,7 @@ @@ -0,0 +1,7 @@
  1 +The Accelerometer is intended for use with an Arduino Nano.
  2 +The arduino code example file is found under:
  3 +/robots/little_john/telemetry/code/robot/Accelerometer/H3LIS331DL_Accelerometer_library/LIS331/examples/ReadAxes
  4 +
  5 +It uses the LIS331 Arduino library and the I2C Master library which is found inside the dependancies folder.
  6 +
  7 +The Accelerometer to Arduino pin connections is found on the README file inside the LIS331 folder.