connecting device sensor - MinnowBoard-org/website GitHub Wiki

Sample code for connecting the accelerometer to a servo on PWM pin 22. Assuming the following text is in a file called tilt-servo.cxx, build it with:

gcc -o tilt-servo -I/usr/local/include/upm tilt-servo.cxx -lupmc-mma7660 -lmraa -lupm-adxl345

/*
 * Author: Mark van der Pol ([email protected])
 * Copyright (c) 2018 Intel Corporation.
 *
 * Permission is hereby granted, free of charge, to any person obtaining
 * a copy of this software and associated documentation files (the
 * "Software"), to deal in the Software without restriction, including
 * without limitation the rights to use, copy, modify, merge, publish,
 * distribute, sublicense, and/or sell copies of the Software, and to
 * permit persons to whom the Software is furnished to do so, subject to
 * the following conditions:
 *
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */
#define ACC_MMA7660
// #define ACC_ADXL345
#include 

#include 

#include "mraa.h"

#ifdef ACC_ADXL345
#include "adxl345.hpp"
#endif

#ifdef ACC_MMA7660
#include "mma7660.hpp"
#endif

#include "upm_utilities.h"

mraa_pwm_context pwm;

void servo_seek( int pos)
{
	// Send out a single pulse duration .7mS to 2.4mS
        // pos is angle 0 to 180 degrees
	if ((pos >= 0 ) && (pos <= 180 ))
	{
		mraa_pwm_pulsewidth_us(pwm, 700 + 9 * pos);
        	mraa_pwm_enable(pwm, 1);
		mraa_pwm_enable(pwm, 0);
	}
}
int shouldRun = true;

void sig_handler(int signo)
{
    if (signo == SIGINT)
        shouldRun = false;
}
int
main()
{
    signal(SIGINT, sig_handler);

    mraa_init();
    //! [Interesting]
    pwm = mraa_pwm_init(22);
    if (pwm == NULL) {
        return 1;
    }
    mraa_pwm_period_us(pwm, 2630); 
/* The MinnowBoard PWM hardware has some resolution restrictions.
   For a deep dive refer to the MinnowBoard.org PWM tutorial.
   In essence, there is quantized series of frequencies that the 
   period can be. The duty cycle can be resolved within this to
   256 steps.
   While the driver dutyfully accepts any valid number in range, 
   the hardware runs at one of the frequencies closest. However,
   when calculating the percentage duty-cycle, it uses the declared
   period, not the actual one and can create values that are erroneous
   and even jam the PWM hardware.
   It is critical for this servo application to specify the period at
   the actual hardware preiod output.
*/
    mraa_pwm_write(pwm, 0);  // SoC Doc say this should force output to 0,but it doesn't.
    mraa_pwm_enable(pwm, 1);
    usleep(20000); // observe what it does with a duty cycle of 0

    int min_width = 0;
    int max_width = 180;
    int step = 1;
    int value = (min_width + max_width ) / 2;

	// Test drive servo to extreme positions.
/*   servo_seek(0);
    usleep(2000000);
    servo_seek(180);
    usleep(2000000);
    servo_seek(0);
    usleep(2000000);
    servo_seek(180);
    usleep(2000000);
*/
    float acc[3];

    while (0) {  // SImple loop to sweep servo up and down.
        value = value + step;
//	mraa_pwm_pulsewidth_us(pwm, 10000 * value);
//        mraa_pwm_enable(pwm, 1);

//        mraa_pwm_write(pwm, value);  // Is actually a percentage of the period 0.0 to 1.0
//      usleep(100);  // Max period servo on time, so wake up and shut down PWM
//	mraa_pwm_write(pwm,0);
//	mraa_pwm_enable(pwm, 0);
	servo_seek(value); 

        if ((value >= max_width) | (value <= min_width)) {
            step = - step;
//	    usleep(2000000);
        }
	usleep(30000);  // 20 mS, then repeat.
 //       float output = mraa_pwm_read(pwm);
 //       printf("PWM value is %f\n", output);
    }

 printf("Tilt-Servo example\n");
    // Note: Sensor only works at 3.3V
#ifdef ACC_ADXL345
    upm::Adxl345 accel(0);
#endif
#ifdef ACC_MMA7660
	printf (" MMA7660 on bus %d and address 0x%x \n", 
	MMA7660_DEFAULT_I2C_BUS, MMA7660_DEFAULT_I2C_ADDR);
        printf("\n");

   mma7660_context accel = mma7660_init(MMA7660_DEFAULT_I2C_BUS,
                                         MMA7660_DEFAULT_I2C_ADDR);
    if (!accel)
    {
        printf("mma7660_init() failed\n");
        return 1;
    }
    // place device in standby mode so we can write registers
    mma7660_set_mode_standby(accel);

    // enable 64 samples per second
    mma7660_set_sample_rate(accel, MMA7660_AUTOSLEEP_64);

    // place device into active mode
    mma7660_set_mode_active(accel);

#endif

    while (shouldRun) {
#ifdef ACC_ADXL345
        accel.update();                // Update the data
        acc = accel.getAcceleration(); // Read acceleration (g)
#endif
#ifdef ACC_MMA7660
	mma7660_get_acceleration(accel,&acc[0], &acc[1], &acc[2] );
#endif

	servo_seek(90 + 90* acc[0]);  // x axis nominally in range -1 to 1 
	usleep(30000);  // 30 mS, then repeat.

    }
	printf("Exiting...\n");
#ifdef ACC_MMA7660
	mma7660_close(accel);
#endif

    return 0;
}
⚠️ **GitHub.com Fallback** ⚠️