mirror of
https://github.com/eclipse/upm.git
synced 2025-03-15 04:57:30 +03:00
grovemd: add support for 'mode1' stepping and add stepper examples
The current grovemd driver supported 'mode2' stepping, where the driver simply passed various stepper commands to the board for it to carry out on it's own. This doesn't work very well (or at all if you have old/buggy firmware) so add a new 'mode1' stepper capability. This mode lets the driver manually control the stepping operation without requiring special firmware. This is now the default and recommended mode to use for stepper motors on this device. It is also more flexible in terms of the maximum number of steps you can do (mode2 was limited to 254 steps max). This was tested using a bipolar NEMA-17 stepper motor with an external 12v power supply. Note: 'Mode1' and 'Mode2' are the Seeed Studio terms for these different stepping modes. Signed-off-by: Jon Trulson <jtrulson@ics.com> Signed-off-by: Mihai Tudor Panu <mihai.tudor.panu@intel.com>
This commit is contained in:
parent
d94a6d00fb
commit
83e62aabba
@ -98,6 +98,7 @@ add_executable (l298-example l298.cxx)
|
||||
add_executable (l298-stepper-example l298-stepper.cxx)
|
||||
add_executable (at42qt1070-example at42qt1070.cxx)
|
||||
add_executable (grovemd-example grovemd.cxx)
|
||||
add_executable (grovemd-stepper-example grovemd-stepper.cxx)
|
||||
add_executable (pca9685-example pca9685.cxx)
|
||||
add_executable (groveeldriver-example groveeldriver.cxx)
|
||||
add_executable (adafruitss-example adafruitss.cxx)
|
||||
@ -352,6 +353,7 @@ target_link_libraries (l298-example l298 ${CMAKE_THREAD_LIBS_INIT})
|
||||
target_link_libraries (l298-stepper-example l298 ${CMAKE_THREAD_LIBS_INIT})
|
||||
target_link_libraries (at42qt1070-example at42qt1070 ${CMAKE_THREAD_LIBS_INIT})
|
||||
target_link_libraries (grovemd-example grovemd ${CMAKE_THREAD_LIBS_INIT})
|
||||
target_link_libraries (grovemd-stepper-example grovemd ${CMAKE_THREAD_LIBS_INIT})
|
||||
target_link_libraries (pca9685-example pca9685 ${CMAKE_THREAD_LIBS_INIT})
|
||||
target_link_libraries (groveeldriver-example groveeldriver ${CMAKE_THREAD_LIBS_INIT})
|
||||
target_link_libraries (adafruitss-example adafruitss ${CMAKE_THREAD_LIBS_INIT})
|
||||
|
66
examples/c++/grovemd-stepper.cxx
Normal file
66
examples/c++/grovemd-stepper.cxx
Normal file
@ -0,0 +1,66 @@
|
||||
/*
|
||||
* Author: Jon Trulson <jtrulson@ics.com>
|
||||
* Copyright (c) 2015 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.
|
||||
*/
|
||||
|
||||
#include <unistd.h>
|
||||
#include <signal.h>
|
||||
#include <iostream>
|
||||
#include "grovemd.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
//! [Interesting]
|
||||
// Instantiate an I2C Grove Motor Driver on I2C bus 0
|
||||
|
||||
upm::GroveMD *motors = new upm::GroveMD(GROVEMD_I2C_BUS,
|
||||
GROVEMD_DEFAULT_I2C_ADDR);
|
||||
|
||||
// This example demonstrates using the GroveMD to drive a stepper motor
|
||||
|
||||
// configure it, for this example, we'll assume 200 steps per rev
|
||||
motors->configStepper(200);
|
||||
|
||||
// set for half a rotation
|
||||
motors->setStepperSteps(100);
|
||||
|
||||
// let it go - clockwise rotation, 10 RPM speed
|
||||
motors->enableStepper(upm::GroveMD::STEP_DIR_CW, 10);
|
||||
|
||||
sleep(3);
|
||||
|
||||
// Now do it backwards...
|
||||
motors->setStepperSteps(100);
|
||||
motors->enableStepper(upm::GroveMD::STEP_DIR_CCW, 10);
|
||||
|
||||
// now disable
|
||||
motors->disableStepper();
|
||||
|
||||
//! [Interesting]
|
||||
|
||||
cout << "Exiting..." << endl;
|
||||
|
||||
delete motors;
|
||||
return 0;
|
||||
}
|
95
examples/javascript/grovemd-stepper.js
Normal file
95
examples/javascript/grovemd-stepper.js
Normal file
@ -0,0 +1,95 @@
|
||||
/*jslint node:true, vars:true, bitwise:true, unparam:true */
|
||||
/*jshint unused:true */
|
||||
|
||||
/*
|
||||
* Author: Jon Trulson <jtrulson@ics.com>
|
||||
* Copyright (c) 2015 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.
|
||||
*/
|
||||
|
||||
var grovemdObj = require('jsupm_grovemd');
|
||||
|
||||
// This example demonstrates using the GroveMD to drive a stepper motor
|
||||
|
||||
function start()
|
||||
{
|
||||
if (motor)
|
||||
{
|
||||
// configure it, for this example, we'll assume 200 steps per rev
|
||||
motor.configStepper(200);
|
||||
motor.setStepperSteps(100);
|
||||
// start it going at 10 RPM
|
||||
motor.enableStepper(grovemdObj.GroveMD.STEP_DIR_CW, 10);
|
||||
}
|
||||
}
|
||||
|
||||
function reverse()
|
||||
{
|
||||
if (motor)
|
||||
{
|
||||
// now reverse
|
||||
motor.setStepperSteps(100);
|
||||
// start it going at 10 RPM
|
||||
motor.enableStepper(grovemdObj.GroveMD.STEP_DIR_CCW, 10);
|
||||
}
|
||||
}
|
||||
|
||||
function end()
|
||||
{
|
||||
if (motor)
|
||||
{
|
||||
motor.disableStepper();
|
||||
}
|
||||
exit();
|
||||
}
|
||||
|
||||
// When exiting: clear memory and print exit message
|
||||
function exit()
|
||||
{
|
||||
if (motor)
|
||||
{
|
||||
motor = null;
|
||||
grovemdObj.cleanUp();
|
||||
}
|
||||
grovemdObj = null;
|
||||
console.log("Exiting");
|
||||
process.exit(0);
|
||||
}
|
||||
|
||||
|
||||
// Instantiate an I2C Grove Motor Driver on I2C bus 0
|
||||
var motor = new grovemdObj.GroveMD(
|
||||
grovemdObj.GROVEMD_I2C_BUS,
|
||||
grovemdObj.GROVEMD_DEFAULT_I2C_ADDR);
|
||||
|
||||
start();
|
||||
|
||||
setTimeout(function()
|
||||
{
|
||||
reverse();
|
||||
setTimeout(end, 3000);
|
||||
}, 3000);
|
||||
|
||||
|
||||
process.on('SIGINT', function()
|
||||
{
|
||||
exit();
|
||||
});
|
52
examples/python/grovemd-stepper.py
Normal file
52
examples/python/grovemd-stepper.py
Normal file
@ -0,0 +1,52 @@
|
||||
#!/usr/bin/python
|
||||
# Author: Jon Trulson <jtrulson@ics.com>
|
||||
# Copyright (c) 2015 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.
|
||||
|
||||
import time
|
||||
import pyupm_grovemd as upmGrovemd
|
||||
|
||||
I2C_BUS = upmGrovemd.GROVEMD_I2C_BUS
|
||||
I2C_ADDR = upmGrovemd.GROVEMD_DEFAULT_I2C_ADDR
|
||||
|
||||
# Instantiate an I2C Grove Motor Driver on I2C bus 0
|
||||
myMotorDriver = upmGrovemd.GroveMD(I2C_BUS, I2C_ADDR)
|
||||
|
||||
# This example demonstrates using the GroveMD to drive a stepper motor
|
||||
|
||||
# configure it, for this example, we'll assume 200 steps per rev
|
||||
myMotorDriver.configStepper(200)
|
||||
|
||||
# set for half a rotation
|
||||
myMotorDriver.setStepperSteps(100)
|
||||
|
||||
# let it go - clockwise rotation, 10 RPM speed
|
||||
myMotorDriver.enableStepper(upmGrovemd.GroveMD.STEP_DIR_CW, 10)
|
||||
|
||||
time.sleep(3)
|
||||
|
||||
# Now do it backwards...
|
||||
myMotorDriver.setStepperSteps(100)
|
||||
myMotorDriver.enableStepper(upmGrovemd.GroveMD.STEP_DIR_CCW, 10)
|
||||
|
||||
# now disable
|
||||
myMotorDriver.disableStepper()
|
||||
|
@ -33,39 +33,36 @@ using namespace upm;
|
||||
using namespace std;
|
||||
|
||||
|
||||
GroveMD::GroveMD(int bus, uint8_t address)
|
||||
GroveMD::GroveMD(int bus, uint8_t address) :
|
||||
m_i2c(bus)
|
||||
{
|
||||
m_addr = address;
|
||||
|
||||
// setup our i2c link
|
||||
if ( !(m_i2c = mraa_i2c_init(bus)) )
|
||||
{
|
||||
throw std::invalid_argument(std::string(__FUNCTION__) +
|
||||
": mraa_i2c_init() failed");
|
||||
return;
|
||||
}
|
||||
|
||||
// this board *requires* 100Khz i2c bus only
|
||||
mraa_result_t rv;
|
||||
if ( (rv = mraa_i2c_frequency(m_i2c, MRAA_I2C_STD)) != MRAA_SUCCESS )
|
||||
mraa::Result rv;
|
||||
if ( (rv = m_i2c.frequency(mraa::I2C_STD)) != mraa::SUCCESS )
|
||||
{
|
||||
throw std::invalid_argument(std::string(__FUNCTION__) +
|
||||
": mraa_i2c_frequency(MRAA_I2C_STD) failed");
|
||||
": I2c.frequency(I2C_STD) failed");
|
||||
return;
|
||||
}
|
||||
|
||||
if (mraa_i2c_address(m_i2c, m_addr))
|
||||
if (m_i2c.address(m_addr))
|
||||
{
|
||||
throw std::runtime_error(std::string(__FUNCTION__) +
|
||||
": mraa_i2c_address() failed");
|
||||
": I2c.address() failed");
|
||||
return;
|
||||
}
|
||||
|
||||
initClock();
|
||||
// default to mode1 stepper operation, 200 steps per rev.
|
||||
configStepper(200, STEP_MODE1);
|
||||
}
|
||||
|
||||
GroveMD::~GroveMD()
|
||||
{
|
||||
setMotorSpeeds(0, 0);
|
||||
mraa_i2c_stop(m_i2c);
|
||||
writePacket(SET_DIRECTION, 0, GROVEMD_NOOP);
|
||||
}
|
||||
|
||||
bool GroveMD::writePacket(REG_T reg, uint8_t data1, uint8_t data2)
|
||||
@ -76,11 +73,10 @@ bool GroveMD::writePacket(REG_T reg, uint8_t data1, uint8_t data2)
|
||||
buf[1] = data1;
|
||||
buf[2] = data2;
|
||||
|
||||
mraa_result_t rv;
|
||||
if ( (rv = mraa_i2c_address(m_i2c, m_addr)) != MRAA_SUCCESS )
|
||||
if ( m_i2c.write(buf, 3) != mraa::SUCCESS )
|
||||
{
|
||||
throw std::runtime_error(std::string(__FUNCTION__) +
|
||||
": mraa_i2c_address() failed");
|
||||
": I2c.write() failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -91,13 +87,6 @@ bool GroveMD::writePacket(REG_T reg, uint8_t data1, uint8_t data2)
|
||||
|
||||
usleep(100);
|
||||
|
||||
if ( (rv = mraa_i2c_write(m_i2c, buf, 3)) != MRAA_SUCCESS )
|
||||
{
|
||||
throw std::runtime_error(std::string(__FUNCTION__) +
|
||||
": mraa_i2c_write() failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -119,25 +108,137 @@ bool GroveMD::setMotorDirections(DC_DIRECTION_T dirA, DC_DIRECTION_T dirB)
|
||||
|
||||
bool GroveMD::enableStepper(STEP_DIRECTION_T dir, uint8_t speed)
|
||||
{
|
||||
return writePacket(STEPPER_ENABLE, dir, speed);
|
||||
// If mode 2, send the command and return immediately
|
||||
if (m_stepMode == STEP_MODE2)
|
||||
return writePacket(STEPPER_ENABLE, dir, speed);
|
||||
|
||||
// otherwise, mode 1, setup the basics and start stepping.
|
||||
|
||||
m_stepDelay = 60 * 1000 / m_stepsPerRev / speed;
|
||||
m_stepDirection = ((dir == STEP_DIR_CW) ? 1 : -1);
|
||||
|
||||
// seeed says speed should always be 255,255 for stepper operation
|
||||
setMotorSpeeds(255, 255);
|
||||
|
||||
while (m_totalSteps > 0)
|
||||
{
|
||||
if (getMillis() >= m_stepDelay)
|
||||
{
|
||||
// reset the clock
|
||||
initClock();
|
||||
|
||||
m_currentStep += m_stepDirection;
|
||||
|
||||
if (m_stepDirection == 1)
|
||||
{
|
||||
if (m_currentStep >= m_stepsPerRev)
|
||||
m_currentStep = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_currentStep <= 0)
|
||||
m_currentStep = m_stepsPerRev;
|
||||
}
|
||||
|
||||
m_totalSteps--;
|
||||
stepperStep();
|
||||
}
|
||||
}
|
||||
|
||||
// and... we're done
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GroveMD::disableStepper()
|
||||
{
|
||||
return writePacket(STEPPER_DISABLE, GROVEMD_NOOP, GROVEMD_NOOP);
|
||||
if (m_stepMode == STEP_MODE2)
|
||||
return writePacket(STEPPER_DISABLE, GROVEMD_NOOP, GROVEMD_NOOP);
|
||||
|
||||
// else, mode 1
|
||||
writePacket(SET_DIRECTION, 0, GROVEMD_NOOP);
|
||||
return setMotorSpeeds(0, 0);
|
||||
}
|
||||
|
||||
bool GroveMD::setStepperSteps(uint8_t steps)
|
||||
bool GroveMD::setStepperSteps(unsigned int steps)
|
||||
{
|
||||
if (steps == 0)
|
||||
if (m_stepMode == STEP_MODE2)
|
||||
{
|
||||
// invalid
|
||||
throw std::out_of_range(std::string(__FUNCTION__) +
|
||||
": invalid number of steps. " +
|
||||
"Valid values are between 1 and 255.");
|
||||
return false;
|
||||
if (steps == 0)
|
||||
{
|
||||
// invalid
|
||||
throw std::out_of_range(std::string(__FUNCTION__) +
|
||||
": invalid number of steps. " +
|
||||
"Valid values are between 1 and 255.");
|
||||
return false;
|
||||
}
|
||||
return writePacket(STEPPER_NUM_STEPS, steps, GROVEMD_NOOP);
|
||||
}
|
||||
|
||||
return writePacket(STEPPER_NUM_STEPS, steps, GROVEMD_NOOP);
|
||||
// for mode one, just store it for future use by enableStepper()
|
||||
m_totalSteps = steps;
|
||||
return true;
|
||||
}
|
||||
|
||||
void GroveMD::initClock()
|
||||
{
|
||||
gettimeofday(&m_startTime, NULL);
|
||||
}
|
||||
|
||||
uint32_t GroveMD::getMillis()
|
||||
{
|
||||
struct timeval elapsed, now;
|
||||
uint32_t elapse;
|
||||
|
||||
// get current time
|
||||
gettimeofday(&now, NULL);
|
||||
|
||||
// compute the delta since m_startTime
|
||||
if( (elapsed.tv_usec = now.tv_usec - m_startTime.tv_usec) < 0 )
|
||||
{
|
||||
elapsed.tv_usec += 1000000;
|
||||
elapsed.tv_sec = now.tv_sec - m_startTime.tv_sec - 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
elapsed.tv_sec = now.tv_sec - m_startTime.tv_sec;
|
||||
}
|
||||
|
||||
elapse = (uint32_t)((elapsed.tv_sec * 1000) + (elapsed.tv_usec / 1000));
|
||||
|
||||
// never return 0
|
||||
if (elapse == 0)
|
||||
elapse = 1;
|
||||
|
||||
return elapse;
|
||||
}
|
||||
|
||||
void GroveMD::configStepper(unsigned int stepsPerRev, STEP_MODE_T mode)
|
||||
{
|
||||
m_stepsPerRev = stepsPerRev;
|
||||
m_stepMode = mode;
|
||||
m_currentStep = 0;
|
||||
m_stepDelay = 0;
|
||||
m_stepDirection = 1;
|
||||
m_totalSteps = 0;
|
||||
}
|
||||
|
||||
void GroveMD::stepperStep()
|
||||
{
|
||||
int step = m_currentStep % 4;
|
||||
|
||||
switch (step)
|
||||
{
|
||||
case 0:
|
||||
writePacket(SET_DIRECTION, 0b0101, GROVEMD_NOOP);
|
||||
break;
|
||||
case 1:
|
||||
writePacket(SET_DIRECTION, 0b0110, GROVEMD_NOOP);
|
||||
break;
|
||||
case 2:
|
||||
writePacket(SET_DIRECTION, 0b1010, GROVEMD_NOOP);
|
||||
break;
|
||||
case 3:
|
||||
writePacket(SET_DIRECTION, 0b1001, GROVEMD_NOOP);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -23,15 +23,15 @@
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include <sys/time.h>
|
||||
#include <string>
|
||||
#include <mraa/i2c.h>
|
||||
#include <mraa/types.hpp>
|
||||
#include <mraa/i2c.hpp>
|
||||
|
||||
#define GROVEMD_I2C_BUS 0
|
||||
#define GROVEMD_DEFAULT_I2C_ADDR 0x0f
|
||||
|
||||
// This is a NOOP value used to pad packets
|
||||
#define GROVEMD_NOOP 0x01
|
||||
|
||||
namespace upm {
|
||||
/**
|
||||
* @brief Grove I2C Motor Driver library
|
||||
@ -61,10 +61,23 @@ namespace upm {
|
||||
* accepts I2C commands for its various operations.
|
||||
*
|
||||
* This module was tested with version 1.3 of the Grove I2C Motor
|
||||
* Driver
|
||||
* Driver.
|
||||
*
|
||||
* For stepper operation, this driver can run in one of two modes -
|
||||
* Mode 1, where this driver handles the stepping operation, and
|
||||
* Mode 2, where this driver simply sends commands to the Grove
|
||||
* Motor Driver, and it handles the stepping operation. Mode2
|
||||
* requires updated (and working) firmware to be loaded onto the
|
||||
* device.
|
||||
*
|
||||
* The default stepper operation mode is Mode1, which is generally
|
||||
* more flexible and is supported on all firmware revisions.
|
||||
*
|
||||
* @image html grovemd.jpg
|
||||
* An example showing the use of a DC motor
|
||||
* @snippet grovemd.cxx Interesting
|
||||
* An example showing the use of a 4-wire stepper
|
||||
* @snippet grovemd-stepper.cxx Interesting
|
||||
*/
|
||||
class GroveMD {
|
||||
|
||||
@ -81,8 +94,8 @@ namespace upm {
|
||||
} REG_T;
|
||||
|
||||
// legal directions for the stepper
|
||||
typedef enum { STEP_DIR_CCW = 0x0a,
|
||||
STEP_DIR_CW = 0x05
|
||||
typedef enum { STEP_DIR_CCW = 0x01,
|
||||
STEP_DIR_CW = 0x00
|
||||
} STEP_DIRECTION_T;
|
||||
|
||||
// legal directions for individual DC motors
|
||||
@ -90,6 +103,11 @@ namespace upm {
|
||||
DIR_CW = 0x01
|
||||
} DC_DIRECTION_T;
|
||||
|
||||
// stepper modes
|
||||
typedef enum { STEP_MODE1 = 0x00,
|
||||
STEP_MODE2 = 0x01
|
||||
} STEP_MODE_T;
|
||||
|
||||
/**
|
||||
* GroveMD constructor
|
||||
*
|
||||
@ -146,10 +164,16 @@ namespace upm {
|
||||
|
||||
/**
|
||||
* To control a stepper motor, sets its direction and speed, and
|
||||
* then enables it.
|
||||
* then starts operation. For Mode2, this method will return
|
||||
* immediately. For Mode1 (the default) this method returns when
|
||||
* the number of steps specified by setStepperSteps() has
|
||||
* completed.
|
||||
*
|
||||
* @param dir Direction, STEP_DIR_CW or STEP_DIR_CCW
|
||||
* @param speed Motor speed. Valid range is 1-255, higher is slower.
|
||||
* @param speed Motor speed. Valid range is 1-255. For Mode 1
|
||||
* (default), this specifies the speed in RPM's. For Mode 2,
|
||||
* speed is multiplied by 4ms by the board, so higher numbers
|
||||
* will mean a slower speed.
|
||||
* @return True if successful
|
||||
*/
|
||||
bool enableStepper(STEP_DIRECTION_T dir, uint8_t speed);
|
||||
@ -163,17 +187,68 @@ namespace upm {
|
||||
|
||||
/**
|
||||
* To control a stepper motor, specifies the number of steps to
|
||||
* execute. Valid values are 1-255, 255 means continuous rotation.
|
||||
* execute. For Mode2, valid values are between 1-255, 255 means
|
||||
* continuous rotation.
|
||||
*
|
||||
* @param steps Number of steps to execute. 255 means continuous rotation.
|
||||
* For Mode1 (the default) steps can be any positive integer.
|
||||
*
|
||||
* @param steps Number of steps to execute. 255 (only in Mode2)
|
||||
* means continuous rotation.
|
||||
* @return True if successful
|
||||
*/
|
||||
bool setStepperSteps(uint8_t steps);
|
||||
bool setStepperSteps(unsigned int steps);
|
||||
|
||||
/**
|
||||
* Configure the initial Stepper parameters. This should be
|
||||
* called before any other stepper method.
|
||||
*
|
||||
* @param stepsPerRev The number of steps required to complete one
|
||||
* full revolution.
|
||||
* @param mode The stepper operating mode, default STEP_MODE1
|
||||
* @return Elapsed milliseconds
|
||||
*/
|
||||
void configStepper(unsigned int stepsPerRev, STEP_MODE_T mode=STEP_MODE1);
|
||||
|
||||
protected:
|
||||
mraa::I2c m_i2c;
|
||||
uint8_t m_addr;
|
||||
|
||||
private:
|
||||
mraa_i2c_context m_i2c;
|
||||
uint8_t m_addr;
|
||||
// steps per revolution
|
||||
int m_stepsPerRev;
|
||||
int m_currentStep;
|
||||
uint32_t m_stepDelay;
|
||||
uint32_t m_totalSteps;
|
||||
STEP_MODE_T m_stepMode;
|
||||
|
||||
/**
|
||||
* Steps the motor one tick
|
||||
*
|
||||
*/
|
||||
void stepperStep();
|
||||
|
||||
// step direction: - 1 = forward, -1 = backward
|
||||
int m_stepDirection;
|
||||
|
||||
// This is a NOOP value used to pad packets
|
||||
static const uint8_t GROVEMD_NOOP = 0x01;
|
||||
// our timer
|
||||
struct timeval m_startTime;
|
||||
|
||||
/**
|
||||
* Returns the number of milliseconds elapsed since initClock()
|
||||
* was last called.
|
||||
*
|
||||
* @return Elapsed milliseconds
|
||||
*/
|
||||
uint32_t getMillis();
|
||||
|
||||
/**
|
||||
* Resets the clock
|
||||
*
|
||||
*/
|
||||
void initClock();
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user