Impact Sensor

Published by cybermah in the blog cybermah's blog. Views: 548


Introduction
My project is to build an impact sensor using the IMU of the max32630fthr. Basically I wanted to be able to attach the sensor to an object so it could measure the impact force when the object is moved and store the readings to an sd card.

The difficulty level for this project is easy.

BOM
MAX32630FTHR
Battery or usb cable if running tethered to a pc
Micro SDCard

Schematics
All the required hardware is already on the board.

Instructions
To build the project all I had to do was load my code to the board , add a sd card and battery if you want to by itself or using the usb cable so you could watch the console output.

After doing research for the project, I found out that a couple of the sample projects for the board contain the majority of the code required. I decided to use the MAX32630FTH_IMU_Hello_World source code as my starting point. It contains all I needed to read the IMU values. I then added code to be able to enable different modes using the on board button. When the button is pressed, it executes an interrupt which will increment a variable that is used to enable and disable various functions, this also enable or disables the on board leds so you can tell which mode your in. The last step was to add code to write to a sd card.

Here is a couple of screen shots of the console. In the second image, the data is down further on the screen because I was playing around with positioning text on the screen.
upload_2017-6-16_20-59-1.png upload_2017-6-16_21-1-6.png

Here is a sample of the output on the sd card:
Fields are as follows Time Temp xAcc yAcc zAcc xGyr yGyr zGyr
230.399979 24.270 -0.635 -0.489 0.593 21.2 9.8 1.4
230.887009 24.258 -0.635 -0.564 0.726 10.2 -1.6 -2.2
231.103271 24.303 -0.644 -0.559 0.753 9.2 1.9 4.9
231.319839 24.293 -0.641 -0.535 0.731 34.8 5.7 -6.3
231.536011 24.291 -0.626 -0.447 0.851 11.5 2.1 0.1
231.752533 24.303 -0.594 -0.424 0.915 62.7 -2.2 -24.8
231.968719 24.314 -0.610 -0.422 0.898 -30.3 4.6 32.4
232.183762 24.299 -0.592 -0.452 0.885 2.9 -6.4 14.5
232.395920 24.379 -0.601 -0.419 0.737 -30.9 6.8 -8.2
232.624146 24.389 -0.635 -0.488 0.827 -5.2 4.8 -6.6

The data can be easily plotted using excel or a similar program. My intent was to use processing to create an app that would be able to continuously scroll as the data came in. The app would also let you set thresholds to highlight when the force exceed the set point, but I was unable to get the serial connection to work properly which was odd because terminal programs would connect without issue.

I would of like to get bluetooth working, but I didn't find any examples until an email came out a couple of days before the due date. Since processing apps can run on a phone or tablet, bluetooth would of been the best choice to get working as I wouldn't need the usb connection to monitor the output. This setup would also be ideal for one of my test which was to mount it on the back of my sons sparing gear, so I could see how hard he was actually getting hit.

After playing around with this board, I think adding a LoRa transceiver would be a great idea too. The sensor could then be mounted in remote locations and the data could be monitored very easily. I did see someone else has already added to a board like this which looks very interesting. I think when my transceivers come in that I order, I may try to add one to see if it works.

Conclusion
I found this board rather easy to get started with. The fact it works with the mbed compiler makes great development platform. The price for the board is pretty good especially for what you get built onto the board. If I had give a con for the board, I would have to say that there isn't very many examples out there for it, but I suspect that will change as people use it


Source Code
Code (Text):
  1.  
  2. [FONT=Courier New][SIZE=3]/**********************************************************************
  3. * Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved.
  4. *
  5. * Permission is hereby granted, free of charge, to any person obtaining a
  6. * copy of this software and associated documentation files (the "Software"),
  7. * to deal in the Software without restriction, including without limitation
  8. * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  9. * and/or sell copies of the Software, and to permit persons to whom the
  10. * Software is furnished to do so, subject to the following conditions:
  11. *
  12. * The above copyright notice and this permission notice shall be included
  13. * in all copies or substantial portions of the Software.
  14. *
  15. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  16. * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  17. * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
  18. * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES
  19. * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
  20. * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  21. * OTHER DEALINGS IN THE SOFTWARE.
  22. *
  23. * Except as contained in this notice, the name of Maxim Integrated
  24. * Products, Inc. shall not be used except as stated in the Maxim Integrated
  25. * Products, Inc. Branding Policy.
  26. *
  27. * The mere transfer of this software does not imply any licenses
  28. * of trade secrets, proprietary technology, copyrights, patents,
  29. * trademarks, maskwork rights, or any other form of intellectual
  30. * property whatsoever. Maxim Integrated Products, Inc. retains all
  31. * ownership rights.
  32. **********************************************************************/
  33.  
  34.  
  35. #include "mbed.h"
  36. #include "max32630fthr.h"
  37. #include "bmi160.h"
  38. #include "SDFileSystem.h"
  39.  
  40.  
  41. void dumpImuRegisters(BMI160 &imu);
  42. void printRegister(BMI160 &imu, BMI160::Registers reg);
  43. void printBlock(BMI160 &imu, BMI160::Registers startReg, BMI160::Registers stopReg);
  44.  
  45. void printData(BMI160::SensorData &accData, BMI160::SensorData &gyroData, BMI160::SensorTime &sensorTime, BMI160::AccRange accRange, BMI160::GyroRange gyroRange, float imuTemperature);
  46. void saveData(BMI160::SensorData &accData, BMI160::SensorData &gyroData, BMI160::SensorTime &sensorTime, BMI160::AccRange accRange, BMI160::GyroRange gyroRange, float imuTemperature);
  47.  
  48. //Setup start/stop button
  49. DigitalIn selectMenuBtn(P2_3, PullUp);
  50. InterruptIn selectMenu(P2_3);
  51. int iCase = 0;
  52. bool save = false;
  53. bool console = false;
  54. bool debug = false;
  55.  
  56. void selectMenuISR()
  57. {
  58.     iCase++;
  59.     if(iCase == 6){
  60.         iCase = 0;
  61.     }
  62.  
  63.     //Thread::wait(500);
  64.     wait_ms(100);
  65. }
  66.  
  67. int main()
  68. {
  69.     MAX32630FTHR pegasus(MAX32630FTHR::VIO_3V3);
  70.  
  71.     DigitalOut rLED(LED1, LED_OFF);
  72.     DigitalOut gLED(LED2, LED_OFF);
  73.     DigitalOut bLED(LED3, LED_OFF);
  74.  
  75.     I2C i2cBus(P5_7, P6_0);
  76.     i2cBus.frequency(400000);
  77.     BMI160_I2C imu(i2cBus, BMI160_I2C::I2C_ADRS_SDO_LO);
  78.  
  79.     printf("\033[H");  //home
  80.     printf("\033[0J");  //erase from cursor to end of screen
  81.  
  82.     uint32_t failures = 0;
  83.  
  84.     if(imu.setSensorPowerMode(BMI160::GYRO, BMI160::NORMAL) != BMI160::RTN_NO_ERROR)
  85.     {
  86.         printf("Failed to set gyroscope power mode\n\r");
  87.         failures++;
  88.     }
  89.     wait_ms(100);
  90.  
  91.     if(imu.setSensorPowerMode(BMI160::ACC, BMI160::NORMAL) != BMI160::RTN_NO_ERROR)
  92.     {
  93.         printf("Failed to set accelerometer power mode\n\r");
  94.         failures++;
  95.     }
  96.     wait_ms(100);
  97.  
  98.  
  99.     BMI160::AccConfig accConfig;
  100.     //example of using getSensorConfig
  101.     if(imu.getSensorConfig(accConfig) == BMI160::RTN_NO_ERROR)
  102.     {
  103.         printf("ACC Range = %d\n\r", accConfig.range);
  104.         printf("ACC UnderSampling = %d\n\r", accConfig.us);
  105.         printf("ACC BandWidthParam = %d\n\r", accConfig.bwp);
  106.         printf("ACC OutputDataRate = %d\n\r\n\r", accConfig.odr);
  107.     }
  108.     else
  109.     {
  110.         printf("Failed to get accelerometer configuration\n\r");
  111.         failures++;
  112.     }
  113.  
  114.     //example of setting user defined configuration
  115.     accConfig.range = BMI160::SENS_4G;
  116.     accConfig.us = BMI160::ACC_US_OFF;
  117.     accConfig.bwp = BMI160::ACC_BWP_2;
  118.     accConfig.odr = BMI160::ACC_ODR_8;
  119.     if(imu.setSensorConfig(accConfig) == BMI160::RTN_NO_ERROR)
  120.     {
  121.         printf("ACC Range = %d\n\r", accConfig.range);
  122.         printf("ACC UnderSampling = %d\n\r", accConfig.us);
  123.         printf("ACC BandWidthParam = %d\n\r", accConfig.bwp);
  124.         printf("ACC OutputDataRate = %d\n\r\n\r", accConfig.odr);
  125.     }
  126.     else
  127.     {
  128.         printf("Failed to set accelerometer configuration\n\r");
  129.         failures++;
  130.     }
  131.  
  132.     BMI160::GyroConfig gyroConfig;
  133.     if(imu.getSensorConfig(gyroConfig) == BMI160::RTN_NO_ERROR)
  134.     {
  135.         printf("GYRO Range = %d\n\r", gyroConfig.range);
  136.         printf("GYRO BandWidthParam = %d\n\r", gyroConfig.bwp);
  137.         printf("GYRO OutputDataRate = %d\n\r\n\r", gyroConfig.odr);
  138.     }
  139.     else
  140.     {
  141.         printf("Failed to get gyroscope configuration\n\r");
  142.         failures++;
  143.     }
  144.  
  145.     wait(1.0);
  146. //    printf("\033[H");  //home
  147.     printf("\033[0J");  //erase from cursor to end of screen
  148.  
  149.     selectMenu.fall(&selectMenuISR);
  150.  
  151.     if(failures == 0)
  152.     {
  153.         float imuTemperature;
  154.         BMI160::SensorData accData;
  155.         BMI160::SensorData gyroData;
  156.         BMI160::SensorTime sensorTime;
  157.      
  158.         while(1)
  159.         {
  160.             switch(iCase){
  161.             case 1:
  162.                 rLED = LED_ON;
  163.                 gLED = LED_OFF;
  164.                 bLED = LED_OFF;
  165.                 console = false;
  166.                 save = false;
  167.                 debug = false;
  168.                 break;
  169.             case 2:
  170.                 rLED = LED_ON;
  171.                 gLED = LED_ON;
  172.                 bLED = LED_OFF;
  173.                 console = true;
  174.                 save = false;
  175.                 debug = false;
  176.                 break;
  177.             case 3:
  178.                 rLED = LED_OFF;
  179.                 gLED = LED_ON;
  180.                 bLED = LED_OFF;
  181.                 console = false;
  182.                 save = true;
  183.                 debug = false;
  184.                 break;
  185.             case 4:
  186.                 rLED = LED_OFF;
  187.                 gLED = LED_ON;
  188.                 bLED = LED_ON;
  189.                 console = true;
  190.                 save = true;
  191.                 debug = false;
  192.                 break;
  193.             case 5:
  194.                 rLED = LED_OFF;
  195.                 gLED = LED_OFF;
  196.                 bLED = LED_ON;
  197.                 console = true;
  198.                 save = true;
  199.                 debug = true;
  200.                 break;
  201.             case 6:
  202.                 rLED = LED_ON;
  203.                 gLED = LED_OFF;
  204.                 bLED = LED_ON;
  205.                 break;              
  206.             default:
  207.                 rLED = LED_OFF;
  208.                 gLED = LED_OFF;
  209.                 bLED = LED_OFF;
  210.                 console = false;
  211.                 save = false;
  212.                 debug = false;
  213.                 printf("\033[H");
  214.                 printf("\033[0J");
  215.                 break;
  216.         }
  217.             imu.getGyroAccXYZandSensorTime(accData, gyroData, sensorTime, accConfig.range, gyroConfig.range);
  218.             imu.getTemperature(&imuTemperature);  
  219.             //if ((accData.xAxis.scaled >= 1)|(accData.yAxis.scaled >= 1)|(accData.zAxis.scaled >= 1)){      
  220.                 if (console == true)
  221.                     printData(accData, gyroData, sensorTime, accConfig.range, gyroConfig.range, imuTemperature);
  222.                 if (save == true)
  223.                     saveData(accData, gyroData, sensorTime, accConfig.range, gyroConfig.range, imuTemperature);
  224.                 if (debug == true)
  225.                     dumpImuRegisters(imu);
  226.             //}
  227.             //gLED = !gLED;
  228.             //rLED = !rLED;
  229.             //bLED = !bLED;
  230.          
  231.         }
  232.     }
  233.     else
  234.     {
  235.         while(1)
  236.         {
  237.             rLED = !rLED;
  238.             wait(0.25);
  239.         }
  240.     }
  241. }
  242.  
  243.  
  244. //*****************************************************************************
  245. void dumpImuRegisters(BMI160 &imu)
  246. {
  247.     printRegister(imu, BMI160::CHIP_ID);
  248.     printBlock(imu, BMI160::ERR_REG,BMI160::FIFO_DATA);
  249.     printBlock(imu, BMI160::ACC_CONF, BMI160::FIFO_CONFIG_1);
  250.     printBlock(imu, BMI160::MAG_IF_0, BMI160::SELF_TEST);
  251.     printBlock(imu, BMI160::NV_CONF, BMI160::STEP_CONF_1);
  252.     printRegister(imu, BMI160::CMD);
  253.     printf("\n\r");
  254. }
  255.  
  256. //*****************************************************************************
  257. void printBlock(BMI160 &imu, BMI160::Registers startReg, BMI160::Registers stopReg)
  258. {
  259.     uint8_t numBytes = ((stopReg - startReg) + 1);
  260.     uint8_t buff[numBytes];
  261.     uint8_t offset = static_cast<uint8_t>(startReg);
  262.  
  263.     if(imu.readBlock(startReg, stopReg, buff) == BMI160::RTN_NO_ERROR)
  264.     {
  265.         for(uint8_t idx = offset; idx < (numBytes + offset); idx++)
  266.         {
  267.             printf("IMU Register 0x%02x = 0x%02x\n\r", idx, buff[idx - offset]);
  268.         }
  269.     }
  270.     else
  271.     {
  272.         printf("Failed to read block\n\r");
  273.     }
  274. }
  275. //*****************************************************************************
  276. void printRegister(BMI160 &imu, BMI160::Registers reg)
  277. {
  278.     uint8_t data;
  279.     if(imu.readRegister(reg, &data) == BMI160::RTN_NO_ERROR)
  280.     {
  281.         printf("IMU Register 0x%02x = 0x%02x\n\r", reg, data);
  282.     }
  283.     else
  284.     {
  285.         printf("Failed to read register\n\r");
  286.     }
  287. }
  288. //*****************************************************************************
  289. void printData(BMI160::SensorData &accData, BMI160::SensorData &gyroData, BMI160::SensorTime &sensorTime, BMI160::AccRange accRange, BMI160::GyroRange gyroRange, float imuTemperature)
  290. {
  291.     //printf("\033[H");
  292.     //printf("\033[0J");
  293.     printf("ACC xAxis = %s%4.3f\n\r", "\033[K", accData.xAxis.scaled);
  294.     printf("ACC yAxis = %s%4.3f\n\r", "\033[K", accData.yAxis.scaled);
  295.     printf("ACC zAxis = %s%4.3f\n\n\r", "\033[K", accData.zAxis.scaled);
  296.  
  297.     printf("GYRO xAxis = %s%5.1f\n\r", "\033[K", gyroData.xAxis.scaled);
  298.     printf("GYRO yAxis = %s%5.1f\n\r", "\033[K", gyroData.yAxis.scaled);
  299.     printf("GYRO zAxis = %s%5.1f\n\n\r", "\033[K", gyroData.zAxis.scaled);
  300.  
  301.     printf("Sensor Time = %s%f\n\r", "\033[K", sensorTime.seconds);
  302.     printf("Sensor Temperature = %s%5.3f\n\r", "\033[K", imuTemperature);
  303.  
  304.     printf("\033[15;1H");
  305.     //printf("\033[H");  //home
  306. }
  307.  
  308. void saveData(BMI160::SensorData &accData, BMI160::SensorData &gyroData, BMI160::SensorTime &sensorTime, BMI160::AccRange accRange, BMI160::GyroRange gyroRange, float imuTemperature)
  309. {
  310.     SDFileSystem sd(P0_5, P0_6, P0_4, P0_7, "sd");  // mosi, miso, sclk, cs
  311.     FILE *fp;
  312.  
  313.     fp = fopen("/sd/impact.txt", "a");
  314.     if(fp != NULL)
  315.     {
  316.         fprintf(fp, "%f\t%5.3f\t%4.3f\t%4.3f\t%4.3f\t%5.1f\t%5.1f\t%5.1f\n\r",sensorTime.seconds, imuTemperature, accData.xAxis.scaled, accData.yAxis.scaled, accData.zAxis.scaled, gyroData.xAxis.scaled, gyroData.yAxis.scaled, gyroData.zAxis.scaled);
  317.         //fprintf(fp, "\n");
  318.         fclose(fp);
  319.     }
  320.     else
  321.     {
  322.         printf("\033[H");
  323.         printf("\033[0J");
  324.         printf("Failed to open file\t");
  325.     }
  326. }[/SIZE][/FONT]
  327.  
  328.  
You need to be logged in to comment