初始化提交
This commit is contained in:
1692
arduino-cli/libraries/ADXL345/ADXL345.cpp
Normal file
1692
arduino-cli/libraries/ADXL345/ADXL345.cpp
Normal file
File diff suppressed because it is too large
Load Diff
366
arduino-cli/libraries/ADXL345/ADXL345.h
Normal file
366
arduino-cli/libraries/ADXL345/ADXL345.h
Normal file
@@ -0,0 +1,366 @@
|
||||
// I2Cdev library collection - ADXL345 I2C device class header file
|
||||
// Based on Analog Devices ADXL345 datasheet rev. C, 5/2011
|
||||
// 7/31/2011 by Jeff Rowberg <jeff@rowberg.net>
|
||||
// Updates should (hopefully) always be available at https://github.com/jrowberg/i2cdevlib
|
||||
//
|
||||
// Changelog:
|
||||
// 2011-07-31 - initial release
|
||||
|
||||
/* ============================================
|
||||
I2Cdev device library code is placed under the MIT license
|
||||
Copyright (c) 2011 Jeff Rowberg
|
||||
|
||||
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.
|
||||
===============================================
|
||||
*/
|
||||
|
||||
#ifndef _ADXL345_H_
|
||||
#define _ADXL345_H_
|
||||
|
||||
#include "I2Cdev.h"
|
||||
|
||||
#define ADXL345_ADDRESS_ALT_LOW 0x53 // alt address pin low (GND)
|
||||
#define ADXL345_ADDRESS_ALT_HIGH 0x1D // alt address pin high (VCC)
|
||||
#define ADXL345_DEFAULT_ADDRESS ADXL345_ADDRESS_ALT_LOW
|
||||
|
||||
#define ADXL345_RA_DEVID 0x00
|
||||
#define ADXL345_RA_RESERVED1 0x01
|
||||
#define ADXL345_RA_THRESH_TAP 0x1D
|
||||
#define ADXL345_RA_OFSX 0x1E
|
||||
#define ADXL345_RA_OFSY 0x1F
|
||||
#define ADXL345_RA_OFSZ 0x20
|
||||
#define ADXL345_RA_DUR 0x21
|
||||
#define ADXL345_RA_LATENT 0x22
|
||||
#define ADXL345_RA_WINDOW 0x23
|
||||
#define ADXL345_RA_THRESH_ACT 0x24
|
||||
#define ADXL345_RA_THRESH_INACT 0x25
|
||||
#define ADXL345_RA_TIME_INACT 0x26
|
||||
#define ADXL345_RA_ACT_INACT_CTL 0x27
|
||||
#define ADXL345_RA_THRESH_FF 0x28
|
||||
#define ADXL345_RA_TIME_FF 0x29
|
||||
#define ADXL345_RA_TAP_AXES 0x2A
|
||||
#define ADXL345_RA_ACT_TAP_STATUS 0x2B
|
||||
#define ADXL345_RA_BW_RATE 0x2C
|
||||
#define ADXL345_RA_POWER_CTL 0x2D
|
||||
#define ADXL345_RA_INT_ENABLE 0x2E
|
||||
#define ADXL345_RA_INT_MAP 0x2F
|
||||
#define ADXL345_RA_INT_SOURCE 0x30
|
||||
#define ADXL345_RA_DATA_FORMAT 0x31
|
||||
#define ADXL345_RA_DATAX0 0x32
|
||||
#define ADXL345_RA_DATAX1 0x33
|
||||
#define ADXL345_RA_DATAY0 0x34
|
||||
#define ADXL345_RA_DATAY1 0x35
|
||||
#define ADXL345_RA_DATAZ0 0x36
|
||||
#define ADXL345_RA_DATAZ1 0x37
|
||||
#define ADXL345_RA_FIFO_CTL 0x38
|
||||
#define ADXL345_RA_FIFO_STATUS 0x39
|
||||
|
||||
#define ADXL345_AIC_ACT_AC_BIT 7
|
||||
#define ADXL345_AIC_ACT_X_BIT 6
|
||||
#define ADXL345_AIC_ACT_Y_BIT 5
|
||||
#define ADXL345_AIC_ACT_Z_BIT 4
|
||||
#define ADXL345_AIC_INACT_AC_BIT 3
|
||||
#define ADXL345_AIC_INACT_X_BIT 2
|
||||
#define ADXL345_AIC_INACT_Y_BIT 1
|
||||
#define ADXL345_AIC_INACT_Z_BIT 0
|
||||
|
||||
#define ADXL345_TAPAXIS_SUP_BIT 3
|
||||
#define ADXL345_TAPAXIS_X_BIT 2
|
||||
#define ADXL345_TAPAXIS_Y_BIT 1
|
||||
#define ADXL345_TAPAXIS_Z_BIT 0
|
||||
|
||||
#define ADXL345_TAPSTAT_ACTX_BIT 6
|
||||
#define ADXL345_TAPSTAT_ACTY_BIT 5
|
||||
#define ADXL345_TAPSTAT_ACTZ_BIT 4
|
||||
#define ADXL345_TAPSTAT_ASLEEP_BIT 3
|
||||
#define ADXL345_TAPSTAT_TAPX_BIT 2
|
||||
#define ADXL345_TAPSTAT_TAPY_BIT 1
|
||||
#define ADXL345_TAPSTAT_TAPZ_BIT 0
|
||||
|
||||
#define ADXL345_BW_LOWPOWER_BIT 4
|
||||
#define ADXL345_BW_RATE_BIT 3
|
||||
#define ADXL345_BW_RATE_LENGTH 4
|
||||
|
||||
#define ADXL345_RATE_3200 0b1111
|
||||
#define ADXL345_RATE_1600 0b1110
|
||||
#define ADXL345_RATE_800 0b1101
|
||||
#define ADXL345_RATE_400 0b1100
|
||||
#define ADXL345_RATE_200 0b1011
|
||||
#define ADXL345_RATE_100 0b1010
|
||||
#define ADXL345_RATE_50 0b1001
|
||||
#define ADXL345_RATE_25 0b1000
|
||||
#define ADXL345_RATE_12P5 0b0111
|
||||
#define ADXL345_RATE_6P25 0b0110
|
||||
#define ADXL345_RATE_3P13 0b0101
|
||||
#define ADXL345_RATE_1P56 0b0100
|
||||
#define ADXL345_RATE_0P78 0b0011
|
||||
#define ADXL345_RATE_0P39 0b0010
|
||||
#define ADXL345_RATE_0P20 0b0001
|
||||
#define ADXL345_RATE_0P10 0b0000
|
||||
|
||||
#define ADXL345_PCTL_LINK_BIT 5
|
||||
#define ADXL345_PCTL_AUTOSLEEP_BIT 4
|
||||
#define ADXL345_PCTL_MEASURE_BIT 3
|
||||
#define ADXL345_PCTL_SLEEP_BIT 2
|
||||
#define ADXL345_PCTL_WAKEUP_BIT 1
|
||||
#define ADXL345_PCTL_WAKEUP_LENGTH 2
|
||||
|
||||
#define ADXL345_WAKEUP_8HZ 0b00
|
||||
#define ADXL345_WAKEUP_4HZ 0b01
|
||||
#define ADXL345_WAKEUP_2HZ 0b10
|
||||
#define ADXL345_WAKEUP_1HZ 0b11
|
||||
|
||||
#define ADXL345_INT_DATA_READY_BIT 7
|
||||
#define ADXL345_INT_SINGLE_TAP_BIT 6
|
||||
#define ADXL345_INT_DOUBLE_TAP_BIT 5
|
||||
#define ADXL345_INT_ACTIVITY_BIT 4
|
||||
#define ADXL345_INT_INACTIVITY_BIT 3
|
||||
#define ADXL345_INT_FREE_FALL_BIT 2
|
||||
#define ADXL345_INT_WATERMARK_BIT 1
|
||||
#define ADXL345_INT_OVERRUN_BIT 0
|
||||
|
||||
#define ADXL345_FORMAT_SELFTEST_BIT 7
|
||||
#define ADXL345_FORMAT_SPIMODE_BIT 6
|
||||
#define ADXL345_FORMAT_INTMODE_BIT 5
|
||||
#define ADXL345_FORMAT_FULL_RES_BIT 3
|
||||
#define ADXL345_FORMAT_JUSTIFY_BIT 2
|
||||
#define ADXL345_FORMAT_RANGE_BIT 1
|
||||
#define ADXL345_FORMAT_RANGE_LENGTH 2
|
||||
|
||||
#define ADXL345_RANGE_2G 0b00
|
||||
#define ADXL345_RANGE_4G 0b01
|
||||
#define ADXL345_RANGE_8G 0b10
|
||||
#define ADXL345_RANGE_16G 0b11
|
||||
|
||||
#define ADXL345_FIFO_MODE_BIT 7
|
||||
#define ADXL345_FIFO_MODE_LENGTH 2
|
||||
#define ADXL345_FIFO_TRIGGER_BIT 5
|
||||
#define ADXL345_FIFO_SAMPLES_BIT 4
|
||||
#define ADXL345_FIFO_SAMPLES_LENGTH 5
|
||||
|
||||
#define ADXL345_FIFO_MODE_BYPASS 0b00
|
||||
#define ADXL345_FIFO_MODE_FIFO 0b01
|
||||
#define ADXL345_FIFO_MODE_STREAM 0b10
|
||||
#define ADXL345_FIFO_MODE_TRIGGER 0b11
|
||||
|
||||
#define ADXL345_FIFOSTAT_TRIGGER_BIT 7
|
||||
#define ADXL345_FIFOSTAT_LENGTH_BIT 5
|
||||
#define ADXL345_FIFOSTAT_LENGTH_LENGTH 6
|
||||
|
||||
class ADXL345 {
|
||||
public:
|
||||
ADXL345();
|
||||
ADXL345(uint8_t address);
|
||||
|
||||
void initialize();
|
||||
bool testConnection();
|
||||
|
||||
// DEVID register
|
||||
uint8_t getDeviceID();
|
||||
|
||||
// THRESH_TAP register
|
||||
uint8_t getTapThreshold();
|
||||
void setTapThreshold(uint8_t threshold);
|
||||
|
||||
// OFS* registers
|
||||
void getOffset(int8_t* x, int8_t* y, int8_t* z);
|
||||
void setOffset(int8_t x, int8_t y, int8_t z);
|
||||
int8_t getOffsetX();
|
||||
void setOffsetX(int8_t x);
|
||||
int8_t getOffsetY();
|
||||
void setOffsetY(int8_t y);
|
||||
int8_t getOffsetZ();
|
||||
void setOffsetZ(int8_t z);
|
||||
|
||||
// DUR register
|
||||
uint8_t getTapDuration();
|
||||
void setTapDuration(uint8_t duration);
|
||||
|
||||
// LATENT register
|
||||
uint8_t getDoubleTapLatency();
|
||||
void setDoubleTapLatency(uint8_t latency);
|
||||
|
||||
// WINDOW register
|
||||
uint8_t getDoubleTapWindow();
|
||||
void setDoubleTapWindow(uint8_t window);
|
||||
|
||||
// THRESH_ACT register
|
||||
uint8_t getActivityThreshold();
|
||||
void setActivityThreshold(uint8_t threshold);
|
||||
|
||||
// THRESH_INACT register
|
||||
uint8_t getInactivityThreshold();
|
||||
void setInactivityThreshold(uint8_t threshold);
|
||||
|
||||
// TIME_INACT register
|
||||
uint8_t getInactivityTime();
|
||||
void setInactivityTime(uint8_t time);
|
||||
|
||||
// ACT_INACT_CTL register
|
||||
bool getActivityAC();
|
||||
void setActivityAC(bool enabled);
|
||||
bool getActivityXEnabled();
|
||||
void setActivityXEnabled(bool enabled);
|
||||
bool getActivityYEnabled();
|
||||
void setActivityYEnabled(bool enabled);
|
||||
bool getActivityZEnabled();
|
||||
void setActivityZEnabled(bool enabled);
|
||||
bool getInactivityAC();
|
||||
void setInactivityAC(bool enabled);
|
||||
bool getInactivityXEnabled();
|
||||
void setInactivityXEnabled(bool enabled);
|
||||
bool getInactivityYEnabled();
|
||||
void setInactivityYEnabled(bool enabled);
|
||||
bool getInactivityZEnabled();
|
||||
void setInactivityZEnabled(bool enabled);
|
||||
|
||||
// THRESH_FF register
|
||||
uint8_t getFreefallThreshold();
|
||||
void setFreefallThreshold(uint8_t threshold);
|
||||
|
||||
// TIME_FF register
|
||||
uint8_t getFreefallTime();
|
||||
void setFreefallTime(uint8_t time);
|
||||
|
||||
// TAP_AXES register
|
||||
bool getTapAxisSuppress();
|
||||
void setTapAxisSuppress(bool enabled);
|
||||
bool getTapAxisXEnabled();
|
||||
void setTapAxisXEnabled(bool enabled);
|
||||
bool getTapAxisYEnabled();
|
||||
void setTapAxisYEnabled(bool enabled);
|
||||
bool getTapAxisZEnabled();
|
||||
void setTapAxisZEnabled(bool enabled);
|
||||
|
||||
// ACT_TAP_STATUS register
|
||||
bool getActivitySourceX();
|
||||
bool getActivitySourceY();
|
||||
bool getActivitySourceZ();
|
||||
bool getAsleep();
|
||||
bool getTapSourceX();
|
||||
bool getTapSourceY();
|
||||
bool getTapSourceZ();
|
||||
|
||||
// BW_RATE register
|
||||
bool getLowPowerEnabled();
|
||||
void setLowPowerEnabled(bool enabled);
|
||||
uint8_t getRate();
|
||||
void setRate(uint8_t rate);
|
||||
|
||||
// POWER_CTL register
|
||||
bool getLinkEnabled();
|
||||
void setLinkEnabled(bool enabled);
|
||||
bool getAutoSleepEnabled();
|
||||
void setAutoSleepEnabled(bool enabled);
|
||||
bool getMeasureEnabled();
|
||||
void setMeasureEnabled(bool enabled);
|
||||
bool getSleepEnabled();
|
||||
void setSleepEnabled(bool enabled);
|
||||
uint8_t getWakeupFrequency();
|
||||
void setWakeupFrequency(uint8_t frequency);
|
||||
|
||||
// INT_ENABLE register
|
||||
bool getIntDataReadyEnabled();
|
||||
void setIntDataReadyEnabled(bool enabled);
|
||||
bool getIntSingleTapEnabled();
|
||||
void setIntSingleTapEnabled(bool enabled);
|
||||
bool getIntDoubleTapEnabled();
|
||||
void setIntDoubleTapEnabled(bool enabled);
|
||||
bool getIntActivityEnabled();
|
||||
void setIntActivityEnabled(bool enabled);
|
||||
bool getIntInactivityEnabled();
|
||||
void setIntInactivityEnabled(bool enabled);
|
||||
bool getIntFreefallEnabled();
|
||||
void setIntFreefallEnabled(bool enabled);
|
||||
bool getIntWatermarkEnabled();
|
||||
void setIntWatermarkEnabled(bool enabled);
|
||||
bool getIntOverrunEnabled();
|
||||
void setIntOverrunEnabled(bool enabled);
|
||||
|
||||
// INT_MAP register
|
||||
uint8_t getIntDataReadyPin();
|
||||
void setIntDataReadyPin(uint8_t pin);
|
||||
uint8_t getIntSingleTapPin();
|
||||
void setIntSingleTapPin(uint8_t pin);
|
||||
uint8_t getIntDoubleTapPin();
|
||||
void setIntDoubleTapPin(uint8_t pin);
|
||||
uint8_t getIntActivityPin();
|
||||
void setIntActivityPin(uint8_t pin);
|
||||
uint8_t getIntInactivityPin();
|
||||
void setIntInactivityPin(uint8_t pin);
|
||||
uint8_t getIntFreefallPin();
|
||||
void setIntFreefallPin(uint8_t pin);
|
||||
uint8_t getIntWatermarkPin();
|
||||
void setIntWatermarkPin(uint8_t pin);
|
||||
uint8_t getIntOverrunPin();
|
||||
void setIntOverrunPin(uint8_t pin);
|
||||
|
||||
// INT_SOURCE register
|
||||
uint8_t getIntDataReadySource();
|
||||
uint8_t getIntSingleTapSource();
|
||||
uint8_t getIntDoubleTapSource();
|
||||
uint8_t getIntActivitySource();
|
||||
uint8_t getIntInactivitySource();
|
||||
uint8_t getIntFreefallSource();
|
||||
uint8_t getIntWatermarkSource();
|
||||
uint8_t getIntOverrunSource();
|
||||
|
||||
// DATA_FORMAT register
|
||||
uint8_t getSelfTestEnabled();
|
||||
void setSelfTestEnabled(uint8_t enabled);
|
||||
uint8_t getSPIMode();
|
||||
void setSPIMode(uint8_t mode);
|
||||
uint8_t getInterruptMode();
|
||||
void setInterruptMode(uint8_t mode);
|
||||
uint8_t getFullResolution();
|
||||
void setFullResolution(uint8_t resolution);
|
||||
uint8_t getDataJustification();
|
||||
void setDataJustification(uint8_t justification);
|
||||
uint8_t getRange();
|
||||
void setRange(uint8_t range);
|
||||
|
||||
// DATA* registers
|
||||
void getAcceleration(int16_t* x, int16_t* y, int16_t* z);
|
||||
int16_t getAccelerationX();
|
||||
int16_t getAccelerationY();
|
||||
int16_t getAccelerationZ();
|
||||
|
||||
// FIFO_CTL register
|
||||
uint8_t getFIFOMode();
|
||||
void setFIFOMode(uint8_t mode);
|
||||
uint8_t getFIFOTriggerInterruptPin();
|
||||
void setFIFOTriggerInterruptPin(uint8_t interrupt);
|
||||
uint8_t getFIFOSamples();
|
||||
void setFIFOSamples(uint8_t size);
|
||||
|
||||
// FIFO_STATUS register
|
||||
bool getFIFOTriggerOccurred();
|
||||
uint8_t getFIFOLength();
|
||||
int16_t X_angle(void);
|
||||
int16_t Y_angle(void);
|
||||
|
||||
private:
|
||||
uint8_t devAddr;
|
||||
uint8_t buffer[6];
|
||||
int16_t get_X_angle;
|
||||
int16_t get_Y_angle;
|
||||
void read_ADXL345(void);
|
||||
};
|
||||
|
||||
#endif /* _ADXL345_H_ */
|
||||
@@ -0,0 +1,86 @@
|
||||
// I2C device class (I2Cdev) demonstration Arduino sketch for ADXL345 class
|
||||
// 10/7/2011 by Jeff Rowberg <jeff@rowberg.net>
|
||||
// Updates should (hopefully) always be available at https://github.com/jrowberg/i2cdevlib
|
||||
//
|
||||
// Changelog:
|
||||
// 2011-10-07 - initial release
|
||||
|
||||
/* ============================================
|
||||
I2Cdev device library code is placed under the MIT license
|
||||
Copyright (c) 2011 Jeff Rowberg
|
||||
|
||||
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.
|
||||
===============================================
|
||||
*/
|
||||
|
||||
// Arduino Wire library is required if I2Cdev I2CDEV_ARDUINO_WIRE implementation
|
||||
// is used in I2Cdev.h
|
||||
#include <Wire.h>
|
||||
|
||||
// I2Cdev and ADXL345 must be installed as libraries, or else the .cpp/.h files
|
||||
// for both classes must be in the include path of your project
|
||||
#include <I2Cdev.h>
|
||||
#include <ADXL345.h>
|
||||
|
||||
// class default I2C address is 0x53
|
||||
// specific I2C addresses may be passed as a parameter here
|
||||
// ALT low = 0x53 (default for SparkFun 6DOF board)
|
||||
// ALT high = 0x1D
|
||||
ADXL345 accel;
|
||||
|
||||
int16_t ax, ay, az;
|
||||
|
||||
#define LED_PIN 13 // (Arduino is 13, Teensy is 6)
|
||||
bool blinkState = false;
|
||||
|
||||
void setup() {
|
||||
// join I2C bus (I2Cdev library doesn't do this automatically)
|
||||
Wire.begin();
|
||||
|
||||
// initialize serial communication
|
||||
// (38400 chosen because it works as well at 8MHz as it does at 16MHz, but
|
||||
// it's really up to you depending on your project)
|
||||
Serial.begin(38400);
|
||||
|
||||
// initialize device
|
||||
Serial.println("Initializing I2C devices...");
|
||||
accel.initialize();
|
||||
|
||||
// verify connection
|
||||
Serial.println("Testing device connections...");
|
||||
Serial.println(accel.testConnection() ? "ADXL345 connection successful" : "ADXL345 connection failed");
|
||||
|
||||
// configure LED for output
|
||||
pinMode(LED_PIN, OUTPUT);
|
||||
}
|
||||
|
||||
void loop() {
|
||||
// read raw accel measurements from device
|
||||
accel.getAcceleration(&ax, &ay, &az);
|
||||
|
||||
// display tab-separated accel x/y/z values
|
||||
Serial.print("accel:\t");
|
||||
Serial.print(ax); Serial.print("\t");
|
||||
Serial.print(ay); Serial.print("\t");
|
||||
Serial.println(az);
|
||||
|
||||
// blink LED to indicate activity
|
||||
blinkState = !blinkState;
|
||||
digitalWrite(LED_PIN, blinkState);
|
||||
}
|
||||
18
arduino-cli/libraries/ADXL345/library.json
Normal file
18
arduino-cli/libraries/ADXL345/library.json
Normal file
@@ -0,0 +1,18 @@
|
||||
{
|
||||
"name": "I2Cdevlib-ADXL345",
|
||||
"keywords": "accelerometer, sensor, i2cdevlib, i2c",
|
||||
"description": "The ADXL345 is a small, thin, ultralow power, 3-axis accelerometer with high resolution (13-bit) measurement",
|
||||
"include": "Arduino/ADXL345",
|
||||
"repository":
|
||||
{
|
||||
"type": "git",
|
||||
"url": "https://github.com/jrowberg/i2cdevlib.git"
|
||||
},
|
||||
"dependencies":
|
||||
{
|
||||
"name": "I2Cdevlib-Core",
|
||||
"frameworks": "arduino"
|
||||
},
|
||||
"frameworks": "arduino",
|
||||
"platforms": "atmelavr"
|
||||
}
|
||||
32
arduino-cli/libraries/AHT10/.gitignore
vendored
Normal file
32
arduino-cli/libraries/AHT10/.gitignore
vendored
Normal file
@@ -0,0 +1,32 @@
|
||||
# Prerequisites
|
||||
*.d
|
||||
|
||||
# Compiled Object files
|
||||
*.slo
|
||||
*.lo
|
||||
*.o
|
||||
*.obj
|
||||
|
||||
# Precompiled Headers
|
||||
*.gch
|
||||
*.pch
|
||||
|
||||
# Compiled Dynamic libraries
|
||||
*.so
|
||||
*.dylib
|
||||
*.dll
|
||||
|
||||
# Fortran module files
|
||||
*.mod
|
||||
*.smod
|
||||
|
||||
# Compiled Static libraries
|
||||
*.lai
|
||||
*.la
|
||||
*.a
|
||||
*.lib
|
||||
|
||||
# Executables
|
||||
*.exe
|
||||
*.out
|
||||
*.app
|
||||
675
arduino-cli/libraries/AHT10/LICENSE
Normal file
675
arduino-cli/libraries/AHT10/LICENSE
Normal file
@@ -0,0 +1,675 @@
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 3, 29 June 2007
|
||||
|
||||
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The GNU General Public License is a free, copyleft license for
|
||||
software and other kinds of works.
|
||||
|
||||
The licenses for most software and other practical works are designed
|
||||
to take away your freedom to share and change the works. By contrast,
|
||||
the GNU General Public License is intended to guarantee your freedom to
|
||||
share and change all versions of a program--to make sure it remains free
|
||||
software for all its users. We, the Free Software Foundation, use the
|
||||
GNU General Public License for most of our software; it applies also to
|
||||
any other work released this way by its authors. You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
them if you wish), that you receive source code or can get it if you
|
||||
want it, that you can change the software or use pieces of it in new
|
||||
free programs, and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to prevent others from denying you
|
||||
these rights or asking you to surrender the rights. Therefore, you have
|
||||
certain responsibilities if you distribute copies of the software, or if
|
||||
you modify it: responsibilities to respect the freedom of others.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must pass on to the recipients the same
|
||||
freedoms that you received. You must make sure that they, too, receive
|
||||
or can get the source code. And you must show them these terms so they
|
||||
know their rights.
|
||||
|
||||
Developers that use the GNU GPL protect your rights with two steps:
|
||||
(1) assert copyright on the software, and (2) offer you this License
|
||||
giving you legal permission to copy, distribute and/or modify it.
|
||||
|
||||
For the developers' and authors' protection, the GPL clearly explains
|
||||
that there is no warranty for this free software. For both users' and
|
||||
authors' sake, the GPL requires that modified versions be marked as
|
||||
changed, so that their problems will not be attributed erroneously to
|
||||
authors of previous versions.
|
||||
|
||||
Some devices are designed to deny users access to install or run
|
||||
modified versions of the software inside them, although the manufacturer
|
||||
can do so. This is fundamentally incompatible with the aim of
|
||||
protecting users' freedom to change the software. The systematic
|
||||
pattern of such abuse occurs in the area of products for individuals to
|
||||
use, which is precisely where it is most unacceptable. Therefore, we
|
||||
have designed this version of the GPL to prohibit the practice for those
|
||||
products. If such problems arise substantially in other domains, we
|
||||
stand ready to extend this provision to those domains in future versions
|
||||
of the GPL, as needed to protect the freedom of users.
|
||||
|
||||
Finally, every program is threatened constantly by software patents.
|
||||
States should not allow patents to restrict development and use of
|
||||
software on general-purpose computers, but in those that do, we wish to
|
||||
avoid the special danger that patents applied to a free program could
|
||||
make it effectively proprietary. To prevent this, the GPL assures that
|
||||
patents cannot be used to render the program non-free.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
TERMS AND CONDITIONS
|
||||
|
||||
0. Definitions.
|
||||
|
||||
"This License" refers to version 3 of the GNU General Public License.
|
||||
|
||||
"Copyright" also means copyright-like laws that apply to other kinds of
|
||||
works, such as semiconductor masks.
|
||||
|
||||
"The Program" refers to any copyrightable work licensed under this
|
||||
License. Each licensee is addressed as "you". "Licensees" and
|
||||
"recipients" may be individuals or organizations.
|
||||
|
||||
To "modify" a work means to copy from or adapt all or part of the work
|
||||
in a fashion requiring copyright permission, other than the making of an
|
||||
exact copy. The resulting work is called a "modified version" of the
|
||||
earlier work or a work "based on" the earlier work.
|
||||
|
||||
A "covered work" means either the unmodified Program or a work based
|
||||
on the Program.
|
||||
|
||||
To "propagate" a work means to do anything with it that, without
|
||||
permission, would make you directly or secondarily liable for
|
||||
infringement under applicable copyright law, except executing it on a
|
||||
computer or modifying a private copy. Propagation includes copying,
|
||||
distribution (with or without modification), making available to the
|
||||
public, and in some countries other activities as well.
|
||||
|
||||
To "convey" a work means any kind of propagation that enables other
|
||||
parties to make or receive copies. Mere interaction with a user through
|
||||
a computer network, with no transfer of a copy, is not conveying.
|
||||
|
||||
An interactive user interface displays "Appropriate Legal Notices"
|
||||
to the extent that it includes a convenient and prominently visible
|
||||
feature that (1) displays an appropriate copyright notice, and (2)
|
||||
tells the user that there is no warranty for the work (except to the
|
||||
extent that warranties are provided), that licensees may convey the
|
||||
work under this License, and how to view a copy of this License. If
|
||||
the interface presents a list of user commands or options, such as a
|
||||
menu, a prominent item in the list meets this criterion.
|
||||
|
||||
1. Source Code.
|
||||
|
||||
The "source code" for a work means the preferred form of the work
|
||||
for making modifications to it. "Object code" means any non-source
|
||||
form of a work.
|
||||
|
||||
A "Standard Interface" means an interface that either is an official
|
||||
standard defined by a recognized standards body, or, in the case of
|
||||
interfaces specified for a particular programming language, one that
|
||||
is widely used among developers working in that language.
|
||||
|
||||
The "System Libraries" of an executable work include anything, other
|
||||
than the work as a whole, that (a) is included in the normal form of
|
||||
packaging a Major Component, but which is not part of that Major
|
||||
Component, and (b) serves only to enable use of the work with that
|
||||
Major Component, or to implement a Standard Interface for which an
|
||||
implementation is available to the public in source code form. A
|
||||
"Major Component", in this context, means a major essential component
|
||||
(kernel, window system, and so on) of the specific operating system
|
||||
(if any) on which the executable work runs, or a compiler used to
|
||||
produce the work, or an object code interpreter used to run it.
|
||||
|
||||
The "Corresponding Source" for a work in object code form means all
|
||||
the source code needed to generate, install, and (for an executable
|
||||
work) run the object code and to modify the work, including scripts to
|
||||
control those activities. However, it does not include the work's
|
||||
System Libraries, or general-purpose tools or generally available free
|
||||
programs which are used unmodified in performing those activities but
|
||||
which are not part of the work. For example, Corresponding Source
|
||||
includes interface definition files associated with source files for
|
||||
the work, and the source code for shared libraries and dynamically
|
||||
linked subprograms that the work is specifically designed to require,
|
||||
such as by intimate data communication or control flow between those
|
||||
subprograms and other parts of the work.
|
||||
|
||||
The Corresponding Source need not include anything that users
|
||||
can regenerate automatically from other parts of the Corresponding
|
||||
Source.
|
||||
|
||||
The Corresponding Source for a work in source code form is that
|
||||
same work.
|
||||
|
||||
2. Basic Permissions.
|
||||
|
||||
All rights granted under this License are granted for the term of
|
||||
copyright on the Program, and are irrevocable provided the stated
|
||||
conditions are met. This License explicitly affirms your unlimited
|
||||
permission to run the unmodified Program. The output from running a
|
||||
covered work is covered by this License only if the output, given its
|
||||
content, constitutes a covered work. This License acknowledges your
|
||||
rights of fair use or other equivalent, as provided by copyright law.
|
||||
|
||||
You may make, run and propagate covered works that you do not
|
||||
convey, without conditions so long as your license otherwise remains
|
||||
in force. You may convey covered works to others for the sole purpose
|
||||
of having them make modifications exclusively for you, or provide you
|
||||
with facilities for running those works, provided that you comply with
|
||||
the terms of this License in conveying all material for which you do
|
||||
not control copyright. Those thus making or running the covered works
|
||||
for you must do so exclusively on your behalf, under your direction
|
||||
and control, on terms that prohibit them from making any copies of
|
||||
your copyrighted material outside their relationship with you.
|
||||
|
||||
Conveying under any other circumstances is permitted solely under
|
||||
the conditions stated below. Sublicensing is not allowed; section 10
|
||||
makes it unnecessary.
|
||||
|
||||
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
|
||||
|
||||
No covered work shall be deemed part of an effective technological
|
||||
measure under any applicable law fulfilling obligations under article
|
||||
11 of the WIPO copyright treaty adopted on 20 December 1996, or
|
||||
similar laws prohibiting or restricting circumvention of such
|
||||
measures.
|
||||
|
||||
When you convey a covered work, you waive any legal power to forbid
|
||||
circumvention of technological measures to the extent such circumvention
|
||||
is effected by exercising rights under this License with respect to
|
||||
the covered work, and you disclaim any intention to limit operation or
|
||||
modification of the work as a means of enforcing, against the work's
|
||||
users, your or third parties' legal rights to forbid circumvention of
|
||||
technological measures.
|
||||
|
||||
4. Conveying Verbatim Copies.
|
||||
|
||||
You may convey verbatim copies of the Program's source code as you
|
||||
receive it, in any medium, provided that you conspicuously and
|
||||
appropriately publish on each copy an appropriate copyright notice;
|
||||
keep intact all notices stating that this License and any
|
||||
non-permissive terms added in accord with section 7 apply to the code;
|
||||
keep intact all notices of the absence of any warranty; and give all
|
||||
recipients a copy of this License along with the Program.
|
||||
|
||||
You may charge any price or no price for each copy that you convey,
|
||||
and you may offer support or warranty protection for a fee.
|
||||
|
||||
5. Conveying Modified Source Versions.
|
||||
|
||||
You may convey a work based on the Program, or the modifications to
|
||||
produce it from the Program, in the form of source code under the
|
||||
terms of section 4, provided that you also meet all of these conditions:
|
||||
|
||||
a) The work must carry prominent notices stating that you modified
|
||||
it, and giving a relevant date.
|
||||
|
||||
b) The work must carry prominent notices stating that it is
|
||||
released under this License and any conditions added under section
|
||||
7. This requirement modifies the requirement in section 4 to
|
||||
"keep intact all notices".
|
||||
|
||||
c) You must license the entire work, as a whole, under this
|
||||
License to anyone who comes into possession of a copy. This
|
||||
License will therefore apply, along with any applicable section 7
|
||||
additional terms, to the whole of the work, and all its parts,
|
||||
regardless of how they are packaged. This License gives no
|
||||
permission to license the work in any other way, but it does not
|
||||
invalidate such permission if you have separately received it.
|
||||
|
||||
d) If the work has interactive user interfaces, each must display
|
||||
Appropriate Legal Notices; however, if the Program has interactive
|
||||
interfaces that do not display Appropriate Legal Notices, your
|
||||
work need not make them do so.
|
||||
|
||||
A compilation of a covered work with other separate and independent
|
||||
works, which are not by their nature extensions of the covered work,
|
||||
and which are not combined with it such as to form a larger program,
|
||||
in or on a volume of a storage or distribution medium, is called an
|
||||
"aggregate" if the compilation and its resulting copyright are not
|
||||
used to limit the access or legal rights of the compilation's users
|
||||
beyond what the individual works permit. Inclusion of a covered work
|
||||
in an aggregate does not cause this License to apply to the other
|
||||
parts of the aggregate.
|
||||
|
||||
6. Conveying Non-Source Forms.
|
||||
|
||||
You may convey a covered work in object code form under the terms
|
||||
of sections 4 and 5, provided that you also convey the
|
||||
machine-readable Corresponding Source under the terms of this License,
|
||||
in one of these ways:
|
||||
|
||||
a) Convey the object code in, or embodied in, a physical product
|
||||
(including a physical distribution medium), accompanied by the
|
||||
Corresponding Source fixed on a durable physical medium
|
||||
customarily used for software interchange.
|
||||
|
||||
b) Convey the object code in, or embodied in, a physical product
|
||||
(including a physical distribution medium), accompanied by a
|
||||
written offer, valid for at least three years and valid for as
|
||||
long as you offer spare parts or customer support for that product
|
||||
model, to give anyone who possesses the object code either (1) a
|
||||
copy of the Corresponding Source for all the software in the
|
||||
product that is covered by this License, on a durable physical
|
||||
medium customarily used for software interchange, for a price no
|
||||
more than your reasonable cost of physically performing this
|
||||
conveying of source, or (2) access to copy the
|
||||
Corresponding Source from a network server at no charge.
|
||||
|
||||
c) Convey individual copies of the object code with a copy of the
|
||||
written offer to provide the Corresponding Source. This
|
||||
alternative is allowed only occasionally and noncommercially, and
|
||||
only if you received the object code with such an offer, in accord
|
||||
with subsection 6b.
|
||||
|
||||
d) Convey the object code by offering access from a designated
|
||||
place (gratis or for a charge), and offer equivalent access to the
|
||||
Corresponding Source in the same way through the same place at no
|
||||
further charge. You need not require recipients to copy the
|
||||
Corresponding Source along with the object code. If the place to
|
||||
copy the object code is a network server, the Corresponding Source
|
||||
may be on a different server (operated by you or a third party)
|
||||
that supports equivalent copying facilities, provided you maintain
|
||||
clear directions next to the object code saying where to find the
|
||||
Corresponding Source. Regardless of what server hosts the
|
||||
Corresponding Source, you remain obligated to ensure that it is
|
||||
available for as long as needed to satisfy these requirements.
|
||||
|
||||
e) Convey the object code using peer-to-peer transmission, provided
|
||||
you inform other peers where the object code and Corresponding
|
||||
Source of the work are being offered to the general public at no
|
||||
charge under subsection 6d.
|
||||
|
||||
A separable portion of the object code, whose source code is excluded
|
||||
from the Corresponding Source as a System Library, need not be
|
||||
included in conveying the object code work.
|
||||
|
||||
A "User Product" is either (1) a "consumer product", which means any
|
||||
tangible personal property which is normally used for personal, family,
|
||||
or household purposes, or (2) anything designed or sold for incorporation
|
||||
into a dwelling. In determining whether a product is a consumer product,
|
||||
doubtful cases shall be resolved in favor of coverage. For a particular
|
||||
product received by a particular user, "normally used" refers to a
|
||||
typical or common use of that class of product, regardless of the status
|
||||
of the particular user or of the way in which the particular user
|
||||
actually uses, or expects or is expected to use, the product. A product
|
||||
is a consumer product regardless of whether the product has substantial
|
||||
commercial, industrial or non-consumer uses, unless such uses represent
|
||||
the only significant mode of use of the product.
|
||||
|
||||
"Installation Information" for a User Product means any methods,
|
||||
procedures, authorization keys, or other information required to install
|
||||
and execute modified versions of a covered work in that User Product from
|
||||
a modified version of its Corresponding Source. The information must
|
||||
suffice to ensure that the continued functioning of the modified object
|
||||
code is in no case prevented or interfered with solely because
|
||||
modification has been made.
|
||||
|
||||
If you convey an object code work under this section in, or with, or
|
||||
specifically for use in, a User Product, and the conveying occurs as
|
||||
part of a transaction in which the right of possession and use of the
|
||||
User Product is transferred to the recipient in perpetuity or for a
|
||||
fixed term (regardless of how the transaction is characterized), the
|
||||
Corresponding Source conveyed under this section must be accompanied
|
||||
by the Installation Information. But this requirement does not apply
|
||||
if neither you nor any third party retains the ability to install
|
||||
modified object code on the User Product (for example, the work has
|
||||
been installed in ROM).
|
||||
|
||||
The requirement to provide Installation Information does not include a
|
||||
requirement to continue to provide support service, warranty, or updates
|
||||
for a work that has been modified or installed by the recipient, or for
|
||||
the User Product in which it has been modified or installed. Access to a
|
||||
network may be denied when the modification itself materially and
|
||||
adversely affects the operation of the network or violates the rules and
|
||||
protocols for communication across the network.
|
||||
|
||||
Corresponding Source conveyed, and Installation Information provided,
|
||||
in accord with this section must be in a format that is publicly
|
||||
documented (and with an implementation available to the public in
|
||||
source code form), and must require no special password or key for
|
||||
unpacking, reading or copying.
|
||||
|
||||
7. Additional Terms.
|
||||
|
||||
"Additional permissions" are terms that supplement the terms of this
|
||||
License by making exceptions from one or more of its conditions.
|
||||
Additional permissions that are applicable to the entire Program shall
|
||||
be treated as though they were included in this License, to the extent
|
||||
that they are valid under applicable law. If additional permissions
|
||||
apply only to part of the Program, that part may be used separately
|
||||
under those permissions, but the entire Program remains governed by
|
||||
this License without regard to the additional permissions.
|
||||
|
||||
When you convey a copy of a covered work, you may at your option
|
||||
remove any additional permissions from that copy, or from any part of
|
||||
it. (Additional permissions may be written to require their own
|
||||
removal in certain cases when you modify the work.) You may place
|
||||
additional permissions on material, added by you to a covered work,
|
||||
for which you have or can give appropriate copyright permission.
|
||||
|
||||
Notwithstanding any other provision of this License, for material you
|
||||
add to a covered work, you may (if authorized by the copyright holders of
|
||||
that material) supplement the terms of this License with terms:
|
||||
|
||||
a) Disclaiming warranty or limiting liability differently from the
|
||||
terms of sections 15 and 16 of this License; or
|
||||
|
||||
b) Requiring preservation of specified reasonable legal notices or
|
||||
author attributions in that material or in the Appropriate Legal
|
||||
Notices displayed by works containing it; or
|
||||
|
||||
c) Prohibiting misrepresentation of the origin of that material, or
|
||||
requiring that modified versions of such material be marked in
|
||||
reasonable ways as different from the original version; or
|
||||
|
||||
d) Limiting the use for publicity purposes of names of licensors or
|
||||
authors of the material; or
|
||||
|
||||
e) Declining to grant rights under trademark law for use of some
|
||||
trade names, trademarks, or service marks; or
|
||||
|
||||
f) Requiring indemnification of licensors and authors of that
|
||||
material by anyone who conveys the material (or modified versions of
|
||||
it) with contractual assumptions of liability to the recipient, for
|
||||
any liability that these contractual assumptions directly impose on
|
||||
those licensors and authors.
|
||||
|
||||
All other non-permissive additional terms are considered "further
|
||||
restrictions" within the meaning of section 10. If the Program as you
|
||||
received it, or any part of it, contains a notice stating that it is
|
||||
governed by this License along with a term that is a further
|
||||
restriction, you may remove that term. If a license document contains
|
||||
a further restriction but permits relicensing or conveying under this
|
||||
License, you may add to a covered work material governed by the terms
|
||||
of that license document, provided that the further restriction does
|
||||
not survive such relicensing or conveying.
|
||||
|
||||
If you add terms to a covered work in accord with this section, you
|
||||
must place, in the relevant source files, a statement of the
|
||||
additional terms that apply to those files, or a notice indicating
|
||||
where to find the applicable terms.
|
||||
|
||||
Additional terms, permissive or non-permissive, may be stated in the
|
||||
form of a separately written license, or stated as exceptions;
|
||||
the above requirements apply either way.
|
||||
|
||||
8. Termination.
|
||||
|
||||
You may not propagate or modify a covered work except as expressly
|
||||
provided under this License. Any attempt otherwise to propagate or
|
||||
modify it is void, and will automatically terminate your rights under
|
||||
this License (including any patent licenses granted under the third
|
||||
paragraph of section 11).
|
||||
|
||||
However, if you cease all violation of this License, then your
|
||||
license from a particular copyright holder is reinstated (a)
|
||||
provisionally, unless and until the copyright holder explicitly and
|
||||
finally terminates your license, and (b) permanently, if the copyright
|
||||
holder fails to notify you of the violation by some reasonable means
|
||||
prior to 60 days after the cessation.
|
||||
|
||||
Moreover, your license from a particular copyright holder is
|
||||
reinstated permanently if the copyright holder notifies you of the
|
||||
violation by some reasonable means, this is the first time you have
|
||||
received notice of violation of this License (for any work) from that
|
||||
copyright holder, and you cure the violation prior to 30 days after
|
||||
your receipt of the notice.
|
||||
|
||||
Termination of your rights under this section does not terminate the
|
||||
licenses of parties who have received copies or rights from you under
|
||||
this License. If your rights have been terminated and not permanently
|
||||
reinstated, you do not qualify to receive new licenses for the same
|
||||
material under section 10.
|
||||
|
||||
9. Acceptance Not Required for Having Copies.
|
||||
|
||||
You are not required to accept this License in order to receive or
|
||||
run a copy of the Program. Ancillary propagation of a covered work
|
||||
occurring solely as a consequence of using peer-to-peer transmission
|
||||
to receive a copy likewise does not require acceptance. However,
|
||||
nothing other than this License grants you permission to propagate or
|
||||
modify any covered work. These actions infringe copyright if you do
|
||||
not accept this License. Therefore, by modifying or propagating a
|
||||
covered work, you indicate your acceptance of this License to do so.
|
||||
|
||||
10. Automatic Licensing of Downstream Recipients.
|
||||
|
||||
Each time you convey a covered work, the recipient automatically
|
||||
receives a license from the original licensors, to run, modify and
|
||||
propagate that work, subject to this License. You are not responsible
|
||||
for enforcing compliance by third parties with this License.
|
||||
|
||||
An "entity transaction" is a transaction transferring control of an
|
||||
organization, or substantially all assets of one, or subdividing an
|
||||
organization, or merging organizations. If propagation of a covered
|
||||
work results from an entity transaction, each party to that
|
||||
transaction who receives a copy of the work also receives whatever
|
||||
licenses to the work the party's predecessor in interest had or could
|
||||
give under the previous paragraph, plus a right to possession of the
|
||||
Corresponding Source of the work from the predecessor in interest, if
|
||||
the predecessor has it or can get it with reasonable efforts.
|
||||
|
||||
You may not impose any further restrictions on the exercise of the
|
||||
rights granted or affirmed under this License. For example, you may
|
||||
not impose a license fee, royalty, or other charge for exercise of
|
||||
rights granted under this License, and you may not initiate litigation
|
||||
(including a cross-claim or counterclaim in a lawsuit) alleging that
|
||||
any patent claim is infringed by making, using, selling, offering for
|
||||
sale, or importing the Program or any portion of it.
|
||||
|
||||
11. Patents.
|
||||
|
||||
A "contributor" is a copyright holder who authorizes use under this
|
||||
License of the Program or a work on which the Program is based. The
|
||||
work thus licensed is called the contributor's "contributor version".
|
||||
|
||||
A contributor's "essential patent claims" are all patent claims
|
||||
owned or controlled by the contributor, whether already acquired or
|
||||
hereafter acquired, that would be infringed by some manner, permitted
|
||||
by this License, of making, using, or selling its contributor version,
|
||||
but do not include claims that would be infringed only as a
|
||||
consequence of further modification of the contributor version. For
|
||||
purposes of this definition, "control" includes the right to grant
|
||||
patent sublicenses in a manner consistent with the requirements of
|
||||
this License.
|
||||
|
||||
Each contributor grants you a non-exclusive, worldwide, royalty-free
|
||||
patent license under the contributor's essential patent claims, to
|
||||
make, use, sell, offer for sale, import and otherwise run, modify and
|
||||
propagate the contents of its contributor version.
|
||||
|
||||
In the following three paragraphs, a "patent license" is any express
|
||||
agreement or commitment, however denominated, not to enforce a patent
|
||||
(such as an express permission to practice a patent or covenant not to
|
||||
sue for patent infringement). To "grant" such a patent license to a
|
||||
party means to make such an agreement or commitment not to enforce a
|
||||
patent against the party.
|
||||
|
||||
If you convey a covered work, knowingly relying on a patent license,
|
||||
and the Corresponding Source of the work is not available for anyone
|
||||
to copy, free of charge and under the terms of this License, through a
|
||||
publicly available network server or other readily accessible means,
|
||||
then you must either (1) cause the Corresponding Source to be so
|
||||
available, or (2) arrange to deprive yourself of the benefit of the
|
||||
patent license for this particular work, or (3) arrange, in a manner
|
||||
consistent with the requirements of this License, to extend the patent
|
||||
license to downstream recipients. "Knowingly relying" means you have
|
||||
actual knowledge that, but for the patent license, your conveying the
|
||||
covered work in a country, or your recipient's use of the covered work
|
||||
in a country, would infringe one or more identifiable patents in that
|
||||
country that you have reason to believe are valid.
|
||||
|
||||
If, pursuant to or in connection with a single transaction or
|
||||
arrangement, you convey, or propagate by procuring conveyance of, a
|
||||
covered work, and grant a patent license to some of the parties
|
||||
receiving the covered work authorizing them to use, propagate, modify
|
||||
or convey a specific copy of the covered work, then the patent license
|
||||
you grant is automatically extended to all recipients of the covered
|
||||
work and works based on it.
|
||||
|
||||
A patent license is "discriminatory" if it does not include within
|
||||
the scope of its coverage, prohibits the exercise of, or is
|
||||
conditioned on the non-exercise of one or more of the rights that are
|
||||
specifically granted under this License. You may not convey a covered
|
||||
work if you are a party to an arrangement with a third party that is
|
||||
in the business of distributing software, under which you make payment
|
||||
to the third party based on the extent of your activity of conveying
|
||||
the work, and under which the third party grants, to any of the
|
||||
parties who would receive the covered work from you, a discriminatory
|
||||
patent license (a) in connection with copies of the covered work
|
||||
conveyed by you (or copies made from those copies), or (b) primarily
|
||||
for and in connection with specific products or compilations that
|
||||
contain the covered work, unless you entered into that arrangement,
|
||||
or that patent license was granted, prior to 28 March 2007.
|
||||
|
||||
Nothing in this License shall be construed as excluding or limiting
|
||||
any implied license or other defenses to infringement that may
|
||||
otherwise be available to you under applicable patent law.
|
||||
|
||||
12. No Surrender of Others' Freedom.
|
||||
|
||||
If conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot convey a
|
||||
covered work so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you may
|
||||
not convey it at all. For example, if you agree to terms that obligate you
|
||||
to collect a royalty for further conveying from those to whom you convey
|
||||
the Program, the only way you could satisfy both those terms and this
|
||||
License would be to refrain entirely from conveying the Program.
|
||||
|
||||
13. Use with the GNU Affero General Public License.
|
||||
|
||||
Notwithstanding any other provision of this License, you have
|
||||
permission to link or combine any covered work with a work licensed
|
||||
under version 3 of the GNU Affero General Public License into a single
|
||||
combined work, and to convey the resulting work. The terms of this
|
||||
License will continue to apply to the part which is the covered work,
|
||||
but the special requirements of the GNU Affero General Public License,
|
||||
section 13, concerning interaction through a network will apply to the
|
||||
combination as such.
|
||||
|
||||
14. Revised Versions of this License.
|
||||
|
||||
The Free Software Foundation may publish revised and/or new versions of
|
||||
the GNU General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the
|
||||
Program specifies that a certain numbered version of the GNU General
|
||||
Public License "or any later version" applies to it, you have the
|
||||
option of following the terms and conditions either of that numbered
|
||||
version or of any later version published by the Free Software
|
||||
Foundation. If the Program does not specify a version number of the
|
||||
GNU General Public License, you may choose any version ever published
|
||||
by the Free Software Foundation.
|
||||
|
||||
If the Program specifies that a proxy can decide which future
|
||||
versions of the GNU General Public License can be used, that proxy's
|
||||
public statement of acceptance of a version permanently authorizes you
|
||||
to choose that version for the Program.
|
||||
|
||||
Later license versions may give you additional or different
|
||||
permissions. However, no additional obligations are imposed on any
|
||||
author or copyright holder as a result of your choosing to follow a
|
||||
later version.
|
||||
|
||||
15. Disclaimer of Warranty.
|
||||
|
||||
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
|
||||
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
|
||||
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
|
||||
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
|
||||
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
|
||||
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
|
||||
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||
|
||||
16. Limitation of Liability.
|
||||
|
||||
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
|
||||
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
|
||||
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
|
||||
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
|
||||
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
|
||||
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
|
||||
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
|
||||
SUCH DAMAGES.
|
||||
|
||||
17. Interpretation of Sections 15 and 16.
|
||||
|
||||
If the disclaimer of warranty and limitation of liability provided
|
||||
above cannot be given local legal effect according to their terms,
|
||||
reviewing courts shall apply local law that most closely approximates
|
||||
an absolute waiver of all civil liability in connection with the
|
||||
Program, unless a warranty or assumption of liability accompanies a
|
||||
copy of the Program in return for a fee.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
state the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
{one line to give the program's name and a brief idea of what it does.}
|
||||
Copyright (C) {year} {name of author}
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program does terminal interaction, make it output a short
|
||||
notice like this when it starts in an interactive mode:
|
||||
|
||||
{project} Copyright (C) {year} {fullname}
|
||||
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, your program's commands
|
||||
might be different; for a GUI interface, you would use an "about box".
|
||||
|
||||
You should also get your employer (if you work as a programmer) or school,
|
||||
if any, to sign a "copyright disclaimer" for the program, if necessary.
|
||||
For more information on this, and how to apply and follow the GNU GPL, see
|
||||
<http://www.gnu.org/licenses/>.
|
||||
|
||||
The GNU General Public License does not permit incorporating your program
|
||||
into proprietary programs. If your program is a subroutine library, you
|
||||
may consider it more useful to permit linking proprietary applications with
|
||||
the library. If this is what you want to do, use the GNU Lesser General
|
||||
Public License instead of this License. But first, please read
|
||||
<http://www.gnu.org/philosophy/why-not-lgpl.html>.
|
||||
|
||||
8
arduino-cli/libraries/AHT10/README.md
Normal file
8
arduino-cli/libraries/AHT10/README.md
Normal file
@@ -0,0 +1,8 @@
|
||||
# AHT10
|
||||
AHT10 Module
|
||||
|
||||
You can buy it on: https://www.aliexpress.com/item/33002710848.html
|
||||
|
||||
This is our store website: https://thinaryelectronic.aliexpress.com
|
||||
|
||||

|
||||
@@ -0,0 +1,24 @@
|
||||
#include <Wire.h>
|
||||
#include <Thinary_AHT10.h>
|
||||
|
||||
AHT10Class AHT10;
|
||||
|
||||
void setup() {
|
||||
// put your setup code here, to run once:
|
||||
Serial.begin(9600);
|
||||
Wire.begin();
|
||||
if(AHT10.begin(eAHT10Address_Low))
|
||||
Serial.println("Init AHT10 Sucess.");
|
||||
else
|
||||
Serial.println("Init AHT10 Failure.");
|
||||
}
|
||||
|
||||
void loop() {
|
||||
// put your main code here, to run repeatedly:
|
||||
Serial.println("//Thinary Eletronic AHT10 Module//");
|
||||
Serial.println("https://thinaryelectronic.aliexpress.com");
|
||||
Serial.println(String("")+"Humidity(%RH):\t\t"+AHT10.GetHumidity()+"%");
|
||||
Serial.println(String("")+"Temperature(℃):\t"+AHT10.GetTemperature()+"℃");
|
||||
Serial.println(String("")+"Dewpoint(℃):\t\t"+AHT10.GetDewPoint()+"℃");
|
||||
delay(500);
|
||||
}
|
||||
16
arduino-cli/libraries/AHT10/keywords.txt
Normal file
16
arduino-cli/libraries/AHT10/keywords.txt
Normal file
@@ -0,0 +1,16 @@
|
||||
AHT10Class KEYWORD1
|
||||
begin KEYWORD2
|
||||
GetHumidity KEYWORD2
|
||||
GetTemperature KEYWORD2
|
||||
GetDewPoint KEYWORD2
|
||||
Reset KEYWORD2
|
||||
eAHT10Address LITERAL1
|
||||
eSensorCalibrateCmd LITERAL1
|
||||
eSensorResetCmd LITERAL1
|
||||
eSensorNormalCmd LITERAL1
|
||||
eSensorMeasureCmd LITERAL1
|
||||
GetRHumidityCmd LITERAL1
|
||||
GetTempCmd LITERAL1
|
||||
eAHT10Address_default LITERAL1
|
||||
eAHT10Address_Low LITERAL1
|
||||
eAHT10Address_High LITERAL1
|
||||
9
arduino-cli/libraries/AHT10/library.properties
Normal file
9
arduino-cli/libraries/AHT10/library.properties
Normal file
@@ -0,0 +1,9 @@
|
||||
name=AHT10
|
||||
version=1.0.0
|
||||
author=Thinary Electronic
|
||||
maintainer=Thinary Electronic <thinary@163.com>
|
||||
sentence=An Arduino library for the AHT10 humidity and temperature sensors
|
||||
paragraph=
|
||||
category=Sensors
|
||||
url=https://github.com/Thinary/AHT10/
|
||||
architectures=*
|
||||
162
arduino-cli/libraries/AHT10/src/Thinary_AHT10.cpp
Normal file
162
arduino-cli/libraries/AHT10/src/Thinary_AHT10.cpp
Normal file
@@ -0,0 +1,162 @@
|
||||
/*
|
||||
AHT10 - A Humidity Library for Arduino.
|
||||
|
||||
Supported Sensor modules:
|
||||
AHT10-Breakout Module - https://www.aliexpress.com/item/33002710848.html
|
||||
|
||||
Created by Thinary Eletronic at Modern Device on April 2019.
|
||||
|
||||
* This file is part of Thinary_AHT10.
|
||||
*
|
||||
* Thinary_AHT10 is free software: you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public License
|
||||
* as published by the Free Software Foundation, either version 3 of
|
||||
* the License, or(at your option) any later version.
|
||||
*
|
||||
* Thinary_AHT10 is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with Thinary_AHT10. If not, see
|
||||
* <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <math.h>
|
||||
#include <Arduino.h>
|
||||
#include <Wire.h>
|
||||
#include "Thinary_AHT10.h"
|
||||
|
||||
// Specify the constants for water vapor and barometric pressure.
|
||||
#define WATER_VAPOR 17.62f
|
||||
#define BAROMETRIC_PRESSURE 243.5f
|
||||
|
||||
Sensor_CMD eSensorCalibrateCmd[3] = {0xE1, 0x08, 0x00};
|
||||
Sensor_CMD eSensorNormalCmd[3] = {0xA8, 0x00, 0x00};
|
||||
Sensor_CMD eSensorMeasureCmd[3] = {0xAC, 0x33, 0x00};
|
||||
Sensor_CMD eSensorResetCmd = 0xBA;
|
||||
boolean GetRHumidityCmd = true;
|
||||
boolean GetTempCmd = false;
|
||||
|
||||
/******************************************************************************
|
||||
* Global Functions
|
||||
******************************************************************************/
|
||||
AHT10Class::AHT10Class() {
|
||||
}
|
||||
|
||||
boolean AHT10Class::begin(unsigned char _AHT10_address)
|
||||
{
|
||||
AHT10_address = _AHT10_address;
|
||||
Serial.begin(9600);
|
||||
Serial.println("\x54\x68\x69\x6E\x61\x72\x79\x20\x45\x6C\x65\x74\x72\x6F\x6E\x69\x63\x20\x41\x48\x54\x31\x30\x20\x4D\x6F\x64\x75\x6C\x65\x2E");
|
||||
Wire.begin(AHT10_address);
|
||||
Wire.beginTransmission(AHT10_address);
|
||||
Wire.write(eSensorCalibrateCmd, 3);
|
||||
Wire.endTransmission();
|
||||
Serial.println("https://thinaryelectronic.aliexpress.com");
|
||||
delay(500);
|
||||
if((readStatus()&0x68) == 0x08)
|
||||
return true;
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**********************************************************
|
||||
* GetHumidity
|
||||
* Gets the current humidity from the sensor.
|
||||
*
|
||||
* @return float - The relative humidity in %RH
|
||||
**********************************************************/
|
||||
float AHT10Class::GetHumidity(void)
|
||||
{
|
||||
float value = readSensor(GetRHumidityCmd);
|
||||
if (value == 0) {
|
||||
return 0; // Some unrealistic value
|
||||
}
|
||||
return value * 100 / 1048576;
|
||||
}
|
||||
|
||||
/**********************************************************
|
||||
* GetTemperature
|
||||
* Gets the current temperature from the sensor.
|
||||
*
|
||||
* @return float - The temperature in Deg C
|
||||
**********************************************************/
|
||||
float AHT10Class::GetTemperature(void)
|
||||
{
|
||||
float value = readSensor(GetTempCmd);
|
||||
return ((200 * value) / 1048576) - 50;
|
||||
}
|
||||
|
||||
/**********************************************************
|
||||
* GetDewPoint
|
||||
* Gets the current dew point based on the current humidity and temperature
|
||||
*
|
||||
* @return float - The dew point in Deg C
|
||||
**********************************************************/
|
||||
float AHT10Class::GetDewPoint(void)
|
||||
{
|
||||
float humidity = GetHumidity();
|
||||
float temperature = GetTemperature();
|
||||
|
||||
// Calculate the intermediate value 'gamma'
|
||||
float gamma = log(humidity / 100) + WATER_VAPOR * temperature / (BAROMETRIC_PRESSURE + temperature);
|
||||
// Calculate dew point in Celsius
|
||||
float dewPoint = BAROMETRIC_PRESSURE * gamma / (WATER_VAPOR - gamma);
|
||||
|
||||
return dewPoint;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* Private Functions
|
||||
******************************************************************************/
|
||||
|
||||
unsigned long AHT10Class::readSensor(boolean GetDataCmd)
|
||||
{
|
||||
unsigned long result, temp[6];
|
||||
|
||||
Wire.beginTransmission(AHT10_address);
|
||||
Wire.write(eSensorMeasureCmd, 3);
|
||||
Wire.endTransmission();
|
||||
delay(100);
|
||||
|
||||
Wire.requestFrom(AHT10_address, 6);
|
||||
|
||||
for(unsigned char i = 0; Wire.available() > 0; i++)
|
||||
{
|
||||
temp[i] = Wire.read();
|
||||
}
|
||||
|
||||
if(GetDataCmd)
|
||||
{
|
||||
result = ((temp[1] << 16) | (temp[2] << 8) | temp[3]) >> 4;
|
||||
}
|
||||
else
|
||||
{
|
||||
result = ((temp[3] & 0x0F) << 16) | (temp[4] << 8) | temp[5];
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
unsigned char AHT10Class::readStatus(void)
|
||||
{
|
||||
unsigned char result = 0;
|
||||
|
||||
Wire.requestFrom(AHT10_address, 1);
|
||||
result = Wire.read();
|
||||
return result;
|
||||
}
|
||||
|
||||
void AHT10Class::Reset(void)
|
||||
{
|
||||
Wire.beginTransmission(AHT10_address);
|
||||
Wire.write(eSensorResetCmd);
|
||||
Wire.endTransmission();
|
||||
delay(20);
|
||||
}
|
||||
55
arduino-cli/libraries/AHT10/src/Thinary_AHT10.h
Normal file
55
arduino-cli/libraries/AHT10/src/Thinary_AHT10.h
Normal file
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
AHT10 - A Humidity Library for Arduino.
|
||||
|
||||
Supported Sensor modules:
|
||||
AHT10-Breakout Module - https://www.aliexpress.com/item/33002710848.html
|
||||
|
||||
Created by Thinary Eletronic at Modern Device on April 2019.
|
||||
|
||||
* This file is part of Thinary_AHT10.
|
||||
*
|
||||
* Thinary_AHT10 is free software: you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public License
|
||||
* as published by the Free Software Foundation, either version 3 of
|
||||
* the License, or(at your option) any later version.
|
||||
*
|
||||
* Sodaq_SHT2x is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with Thinary_AHT10. If not, see
|
||||
* <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef AHT10_H
|
||||
#define AHT10_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
typedef enum {
|
||||
eAHT10Address_default = 0x38,
|
||||
eAHT10Address_Low = 0x38,
|
||||
eAHT10Address_High = 0x39,
|
||||
} HUM_SENSOR_T;
|
||||
|
||||
typedef unsigned char Sensor_CMD;
|
||||
|
||||
class AHT10Class
|
||||
{
|
||||
private:
|
||||
unsigned long readSensor(boolean GetDataCmd);
|
||||
unsigned char AHT10_address;
|
||||
public:
|
||||
AHT10Class();
|
||||
boolean begin(unsigned char _AHT10_address = eAHT10Address_default);
|
||||
float GetHumidity(void);
|
||||
float GetTemperature(void);
|
||||
float GetDewPoint(void);
|
||||
unsigned char readStatus(void);
|
||||
void Reset(void);
|
||||
};
|
||||
|
||||
#endif
|
||||
164
arduino-cli/libraries/AHT10_Soft/Thinary_AHT10_Soft.cpp
Normal file
164
arduino-cli/libraries/AHT10_Soft/Thinary_AHT10_Soft.cpp
Normal file
@@ -0,0 +1,164 @@
|
||||
/*
|
||||
AHT10_Soft - A Humidity Library for Arduino.
|
||||
|
||||
Supported Sensor modules:
|
||||
AHT10_Soft-Breakout Module - https://www.aliexpress.com/item/33002710848.html
|
||||
|
||||
Created by Thinary Eletronic at Modern Device on April 2019.
|
||||
|
||||
* This file is part of Thinary_AHT10_Soft.
|
||||
*
|
||||
* Thinary_AHT10_Soft is free software: you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public License
|
||||
* as published by the Free Software Foundation, either version 3 of
|
||||
* the License, or(at your option) any later version.
|
||||
*
|
||||
* Thinary_AHT10_Soft is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with Thinary_AHT10_Soft. If not, see
|
||||
* <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <math.h>
|
||||
#include <Arduino.h>
|
||||
#include <SoftwareWire.h>
|
||||
#include "Thinary_AHT10_Soft.h"
|
||||
|
||||
|
||||
// Specify the constants for water vapor and barometric pressure.
|
||||
#define WATER_VAPOR 17.62f
|
||||
#define BAROMETRIC_PRESSURE 243.5f
|
||||
|
||||
Sensor_CMD eSensorCalibrateCmd[3] = {0xE1, 0x08, 0x00};
|
||||
Sensor_CMD eSensorNormalCmd[3] = {0xA8, 0x00, 0x00};
|
||||
Sensor_CMD eSensorMeasureCmd[3] = {0xAC, 0x33, 0x00};
|
||||
Sensor_CMD eSensorResetCmd = 0xBA;
|
||||
boolean GetRHumidityCmd = true;
|
||||
boolean GetTempCmd = false;
|
||||
|
||||
/******************************************************************************
|
||||
* Global Functions
|
||||
******************************************************************************/
|
||||
AHT10_SoftClass::AHT10_SoftClass() {
|
||||
}
|
||||
|
||||
bool AHT10_SoftClass::begin(unsigned char _AHT10_Soft_address, SoftwareWire *theWire)
|
||||
{
|
||||
_wire = theWire;
|
||||
AHT10_Soft_address = _AHT10_Soft_address;
|
||||
//Serial.begin(9600);
|
||||
//Serial.println("\x54\x68\x69\x6E\x61\x72\x79\x20\x45\x6C\x65\x74\x72\x6F\x6E\x69\x63\x20\x41\x48\x54\x31\x30\x20\x4D\x6F\x64\x75\x6C\x65\x2E");
|
||||
_wire->begin();
|
||||
_wire->beginTransmission(AHT10_Soft_address);
|
||||
_wire->write(eSensorCalibrateCmd, 3);
|
||||
_wire->endTransmission();
|
||||
//Serial.println("https://thinaryelectronic.aliexpress.com");
|
||||
delay(500);
|
||||
if((readStatus()&0x68) == 0x08)
|
||||
return true;
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**********************************************************
|
||||
* GetHumidity
|
||||
* Gets the current humidity from the sensor.
|
||||
*
|
||||
* @return float - The relative humidity in %RH
|
||||
**********************************************************/
|
||||
float AHT10_SoftClass::GetHumidity(void)
|
||||
{
|
||||
float value = readSensor(GetRHumidityCmd);
|
||||
if (value == 0) {
|
||||
return 0; // Some unrealistic value
|
||||
}
|
||||
return value * 100 / 1048576;
|
||||
}
|
||||
|
||||
/**********************************************************
|
||||
* GetTemperature
|
||||
* Gets the current temperature from the sensor.
|
||||
*
|
||||
* @return float - The temperature in Deg C
|
||||
**********************************************************/
|
||||
float AHT10_SoftClass::GetTemperature(void)
|
||||
{
|
||||
float value = readSensor(GetTempCmd);
|
||||
return ((200 * value) / 1048576) - 50;
|
||||
}
|
||||
|
||||
/**********************************************************
|
||||
* GetDewPoint
|
||||
* Gets the current dew point based on the current humidity and temperature
|
||||
*
|
||||
* @return float - The dew point in Deg C
|
||||
**********************************************************/
|
||||
float AHT10_SoftClass::GetDewPoint(void)
|
||||
{
|
||||
float humidity = GetHumidity();
|
||||
float temperature = GetTemperature();
|
||||
|
||||
// Calculate the intermediate value 'gamma'
|
||||
float gamma = log(humidity / 100) + WATER_VAPOR * temperature / (BAROMETRIC_PRESSURE + temperature);
|
||||
// Calculate dew point in Celsius
|
||||
float dewPoint = BAROMETRIC_PRESSURE * gamma / (WATER_VAPOR - gamma);
|
||||
|
||||
return dewPoint;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* Private Functions
|
||||
******************************************************************************/
|
||||
|
||||
unsigned long AHT10_SoftClass::readSensor(boolean GetDataCmd)
|
||||
{
|
||||
unsigned long result, temp[6];
|
||||
|
||||
_wire->beginTransmission(AHT10_Soft_address);
|
||||
_wire->write(eSensorMeasureCmd, 3);
|
||||
_wire->endTransmission();
|
||||
delay(100);
|
||||
|
||||
_wire->requestFrom(AHT10_Soft_address, 6);
|
||||
|
||||
for(unsigned char i = 0; _wire->available() > 0; i++)
|
||||
{
|
||||
temp[i] = _wire->read();
|
||||
}
|
||||
|
||||
if(GetDataCmd)
|
||||
{
|
||||
result = ((temp[1] << 16) | (temp[2] << 8) | temp[3]) >> 4;
|
||||
}
|
||||
else
|
||||
{
|
||||
result = ((temp[3] & 0x0F) << 16) | (temp[4] << 8) | temp[5];
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
unsigned char AHT10_SoftClass::readStatus(void)
|
||||
{
|
||||
unsigned char result = 0;
|
||||
|
||||
_wire->requestFrom(AHT10_Soft_address, 1);
|
||||
result = _wire->read();
|
||||
return result;
|
||||
}
|
||||
|
||||
void AHT10_SoftClass::Reset(void)
|
||||
{
|
||||
_wire->beginTransmission(AHT10_Soft_address);
|
||||
_wire->write(eSensorResetCmd);
|
||||
_wire->endTransmission();
|
||||
delay(20);
|
||||
}
|
||||
57
arduino-cli/libraries/AHT10_Soft/Thinary_AHT10_Soft.h
Normal file
57
arduino-cli/libraries/AHT10_Soft/Thinary_AHT10_Soft.h
Normal file
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
AHT10_Soft - A Humidity Library for Arduino.
|
||||
|
||||
Supported Sensor modules:
|
||||
AHT10_Soft-Breakout Module - https://www.aliexpress.com/item/33002710848.html
|
||||
|
||||
Created by Thinary Eletronic at Modern Device on April 2019.
|
||||
|
||||
* This file is part of Thinary_AHT10_Soft.
|
||||
*
|
||||
* Thinary_AHT10_Soft is free software: you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public License
|
||||
* as published by the Free Software Foundation, either version 3 of
|
||||
* the License, or(at your option) any later version.
|
||||
*
|
||||
* Sodaq_SHT2x is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with Thinary_AHT10_Soft. If not, see
|
||||
* <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef AHT10_Soft_H
|
||||
#define AHT10_Soft_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <SoftwareWire.h>
|
||||
|
||||
typedef enum {
|
||||
eAHT10_SoftAddress_default = 0x38,
|
||||
eAHT10_SoftAddress_Low = 0x38,
|
||||
eAHT10_SoftAddress_High = 0x39,
|
||||
} HUM_SENSOR_T;
|
||||
|
||||
typedef unsigned char Sensor_CMD;
|
||||
|
||||
class AHT10_SoftClass
|
||||
{
|
||||
private:
|
||||
unsigned long readSensor(boolean GetDataCmd);
|
||||
unsigned char AHT10_Soft_address;
|
||||
SoftwareWire *_wire;
|
||||
public:
|
||||
AHT10_SoftClass();
|
||||
bool begin(unsigned char _AHT10_Soft_address, SoftwareWire *theWire);
|
||||
float GetHumidity(void);
|
||||
float GetTemperature(void);
|
||||
float GetDewPoint(void);
|
||||
unsigned char readStatus(void);
|
||||
void Reset(void);
|
||||
};
|
||||
|
||||
#endif
|
||||
115
arduino-cli/libraries/AH_24CXX/AH_24Cxx.cpp
Normal file
115
arduino-cli/libraries/AH_24CXX/AH_24Cxx.cpp
Normal file
@@ -0,0 +1,115 @@
|
||||
|
||||
/********************************************************
|
||||
** Download from: **
|
||||
** http://www.arduino-projekte.de **
|
||||
** **
|
||||
** Based on Code from: **
|
||||
** http://arduino.cc/playground/ **
|
||||
** **
|
||||
** Released into the public domain. **
|
||||
********************************************************/
|
||||
|
||||
#include <Arduino.h>
|
||||
#include <AH_24Cxx.h>
|
||||
#include <Wire.h>
|
||||
|
||||
#define AT24C01 0
|
||||
#define AT24C02 1
|
||||
#define AT24C04 2
|
||||
#define AT24C08 3
|
||||
#define AT24C16 4
|
||||
#define AT24C32 5
|
||||
#define AT24C64 6
|
||||
#define AT24C128 8
|
||||
#define AT24C256 9
|
||||
|
||||
|
||||
//************************************************************************
|
||||
|
||||
// Constructor
|
||||
AH_24Cxx::AH_24Cxx(int ic_type, int deviceaddress){
|
||||
// Wire.begin(); // initialise the connection
|
||||
_mode = ic_type;
|
||||
_deviceaddress = B01010<<3 | deviceaddress; //Address: B01010(A2)(A1)(A0) A2=0; A1=0; A0=0 => Address: B01010000(BIN) | 0x50(HEX) | 80(DEC)
|
||||
}
|
||||
|
||||
|
||||
//*************************************************************************
|
||||
|
||||
// WARNING: address is a page address, 6-bit end will wrap around
|
||||
// also, data can be maximum of about 30 bytes, because the Wire library has a buffer of 32 bytes
|
||||
|
||||
void AH_24Cxx::write_page( unsigned int eeaddresspage, byte* data, byte length ) {
|
||||
|
||||
Wire.beginTransmission(_deviceaddress);
|
||||
if (_mode>4){
|
||||
Wire.write((int)(eeaddresspage >> 8)); // MSB
|
||||
Wire.write((int)(eeaddresspage & 0xFF)); // LSB
|
||||
}
|
||||
else {
|
||||
Wire.write((int)eeaddresspage);
|
||||
}
|
||||
|
||||
byte c;
|
||||
for ( c = 0; c < length; c++)
|
||||
Wire.write(data[c]);
|
||||
Wire.endTransmission();
|
||||
}
|
||||
|
||||
|
||||
//*************************************************************************
|
||||
|
||||
// maybe let's not read more than 30 or 32 bytes at a time!
|
||||
|
||||
void AH_24Cxx::read_buffer(unsigned int eeaddress, byte *buffer, int length ) {
|
||||
Wire.beginTransmission(_deviceaddress);
|
||||
if (_mode>4){
|
||||
Wire.write((int)(eeaddress >> 8)); // MSB
|
||||
Wire.write((int)(eeaddress & 0xFF)); // LSB
|
||||
}
|
||||
else {
|
||||
Wire.write((int)eeaddress);
|
||||
}
|
||||
Wire.endTransmission();
|
||||
Wire.requestFrom(_deviceaddress,length);
|
||||
int c = 0;
|
||||
for ( c = 0; c < length; c++ )
|
||||
if (Wire.available()) buffer[c] = Wire.read();
|
||||
}
|
||||
|
||||
|
||||
//*************************************************************************
|
||||
|
||||
void AH_24Cxx::write_byte(unsigned int eeaddress, byte data) {
|
||||
|
||||
int rdata = data;
|
||||
Wire.beginTransmission(_deviceaddress);
|
||||
if (_mode>4){
|
||||
Wire.write((int)(eeaddress >> 8)); // MSB
|
||||
Wire.write((int)(eeaddress & 0xFF)); // LSB
|
||||
}
|
||||
else {
|
||||
Wire.write((int)eeaddress);
|
||||
}
|
||||
Wire.write(rdata);
|
||||
Wire.endTransmission();
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
|
||||
byte AH_24Cxx::read_byte(unsigned int eeaddress) {
|
||||
byte rdata = 0xFF;
|
||||
Wire.beginTransmission(_deviceaddress);
|
||||
if (_mode>4){
|
||||
Wire.write((int)(eeaddress >> 8)); // MSB
|
||||
Wire.write((int)(eeaddress & 0xFF)); // LSB
|
||||
}
|
||||
else {
|
||||
Wire.write((int)eeaddress);
|
||||
}
|
||||
Wire.endTransmission();
|
||||
Wire.requestFrom(_deviceaddress,1);
|
||||
if (Wire.available()) rdata = Wire.read();
|
||||
return rdata;
|
||||
}
|
||||
|
||||
38
arduino-cli/libraries/AH_24CXX/AH_24Cxx.h
Normal file
38
arduino-cli/libraries/AH_24CXX/AH_24Cxx.h
Normal file
@@ -0,0 +1,38 @@
|
||||
|
||||
/********************************************************
|
||||
** Download from: **
|
||||
** http://www.arduino-projekte.de **
|
||||
** **
|
||||
** Based on Code from: **
|
||||
** http://arduino.cc/playground/ **
|
||||
** **
|
||||
** Released into the public domain. **
|
||||
********************************************************/
|
||||
|
||||
#ifndef AH_24Cxx_h
|
||||
#define AH_24Cxx_h
|
||||
|
||||
#include <Arduino.h> //Arduino IDE >= V1.0
|
||||
|
||||
|
||||
|
||||
class AH_24Cxx
|
||||
{
|
||||
public:
|
||||
// Constructor
|
||||
AH_24Cxx(int ic_type,int deviceaddress);
|
||||
void write_byte (unsigned int eeaddress, byte data);
|
||||
void write_page (unsigned int eeaddresspage, byte* data, byte length);
|
||||
byte read_byte (unsigned int eeaddress);
|
||||
void read_buffer (unsigned int eeaddress, byte *buffer, int length);
|
||||
|
||||
private:
|
||||
int _mode;
|
||||
int _deviceaddress;
|
||||
|
||||
|
||||
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,54 @@
|
||||
|
||||
/********************************************************
|
||||
** Download from: **
|
||||
** http://www.arduino-projekte.de **
|
||||
** **
|
||||
** Based on Code from: **
|
||||
** http://arduino.cc/playground/ **
|
||||
** **
|
||||
** Released into the public domain. **
|
||||
********************************************************/
|
||||
|
||||
#include <AH_24Cxx.h>
|
||||
#include <Wire.h>
|
||||
|
||||
#define AT24C01 0
|
||||
#define AT24C02 1
|
||||
#define AT24C04 2
|
||||
#define AT24C08 3
|
||||
#define AT24C16 4
|
||||
#define AT24C32 5
|
||||
#define AT24C64 6
|
||||
#define AT24C128 8
|
||||
#define AT24C256 9
|
||||
//Initialisation
|
||||
|
||||
int data;
|
||||
|
||||
#define BUSADDRESS 0x00
|
||||
#define EEPROMSIZE 2048 //AT24C16 2048byte
|
||||
|
||||
AH_24Cxx ic_eeprom = AH_24Cxx(AT24C16, BUSADDRESS);
|
||||
|
||||
void setup(){
|
||||
Serial.begin(9600);
|
||||
Wire.begin();
|
||||
Serial.println("Write data");
|
||||
for(int i = 0; i < 10; i++) {
|
||||
data = i;
|
||||
ic_eeprom.write_byte(i,data);
|
||||
delay(100);
|
||||
}
|
||||
}
|
||||
|
||||
void loop(){
|
||||
Serial.println("Read data");
|
||||
for (int i=0;i<EEPROMSIZE;i++){
|
||||
Serial.print("pos. ");
|
||||
Serial.print(i);
|
||||
Serial.print(": ");
|
||||
Serial.println(ic_eeprom.read_byte(i));
|
||||
delay(1000);
|
||||
}
|
||||
}
|
||||
|
||||
7
arduino-cli/libraries/AH_24CXX/keywords.txt
Normal file
7
arduino-cli/libraries/AH_24CXX/keywords.txt
Normal file
@@ -0,0 +1,7 @@
|
||||
AH_24Cxx KEYWORD1
|
||||
|
||||
write_byte KEYWORD2
|
||||
write_page KEYWORD2
|
||||
read_byte KEYWORD2
|
||||
read_buffer KEYWORD2
|
||||
|
||||
32
arduino-cli/libraries/AT24Cx/.gitignore
vendored
Normal file
32
arduino-cli/libraries/AT24Cx/.gitignore
vendored
Normal file
@@ -0,0 +1,32 @@
|
||||
# Object files
|
||||
*.o
|
||||
*.ko
|
||||
*.obj
|
||||
*.elf
|
||||
|
||||
# Precompiled Headers
|
||||
*.gch
|
||||
*.pch
|
||||
|
||||
# Libraries
|
||||
*.lib
|
||||
*.a
|
||||
*.la
|
||||
*.lo
|
||||
|
||||
# Shared objects (inc. Windows DLLs)
|
||||
*.dll
|
||||
*.so
|
||||
*.so.*
|
||||
*.dylib
|
||||
|
||||
# Executables
|
||||
*.exe
|
||||
*.out
|
||||
*.app
|
||||
*.i*86
|
||||
*.x86_64
|
||||
*.hex
|
||||
|
||||
# Debug files
|
||||
*.dSYM/
|
||||
407
arduino-cli/libraries/AT24Cx/AT24CX.cpp
Normal file
407
arduino-cli/libraries/AT24Cx/AT24CX.cpp
Normal file
@@ -0,0 +1,407 @@
|
||||
/**
|
||||
|
||||
AT24CX.cpp
|
||||
Library for using the EEPROM AT24C32/64
|
||||
|
||||
Copyright (c) 2014 Christian Paul
|
||||
|
||||
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 "AT24CX.h"
|
||||
#include <Wire.h>
|
||||
|
||||
/**
|
||||
* Constructor with AT24Cx EEPROM at index 0
|
||||
*/
|
||||
AT24CX::AT24CX() {
|
||||
init(0, 32);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor with AT24Cx EEPROM at given index and size of page
|
||||
*/
|
||||
AT24CX::AT24CX(byte index, byte pageSize) {
|
||||
init(index, pageSize);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor with AT24Cx EEPROM at given index
|
||||
*/
|
||||
AT24C01::AT24C01(byte index) {
|
||||
init(index, 8);
|
||||
}
|
||||
/**
|
||||
* Constructor with AT24C01 EEPROM at index 0
|
||||
*/
|
||||
AT24C01::AT24C01() {
|
||||
init(0, 8);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor with AT24Cx EEPROM at given index
|
||||
*/
|
||||
AT24C02::AT24C02(byte index) {
|
||||
init(index, 8);
|
||||
}
|
||||
/**
|
||||
* Constructor with AT24C02 EEPROM at index 0
|
||||
*/
|
||||
AT24C02::AT24C02() {
|
||||
init(0, 8);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor with AT24Cx EEPROM at given index
|
||||
*/
|
||||
AT24C04::AT24C04(byte index) {
|
||||
init(index, 16);
|
||||
}
|
||||
/**
|
||||
* Constructor with AT24C04 EEPROM at index 0
|
||||
*/
|
||||
AT24C04::AT24C04() {
|
||||
init(0, 16);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor with AT24Cx EEPROM at given index
|
||||
*/
|
||||
AT24C08::AT24C08(byte index) {
|
||||
init(index, 16);
|
||||
}
|
||||
/**
|
||||
* Constructor with AT24C08 EEPROM at index 0
|
||||
*/
|
||||
AT24C08::AT24C08() {
|
||||
init(0, 16);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor with AT24Cx EEPROM at given index
|
||||
*/
|
||||
AT24C16::AT24C16(byte index) {
|
||||
init(index, 16);
|
||||
}
|
||||
/**
|
||||
* Constructor with AT24C16 EEPROM at index 0
|
||||
*/
|
||||
AT24C16::AT24C16() {
|
||||
init(0, 16);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor with AT24C32 EEPROM at index 0
|
||||
*/
|
||||
AT24C32::AT24C32() {
|
||||
init(0, 32);
|
||||
}
|
||||
/**
|
||||
* Constructor with AT24Cx EEPROM at given index
|
||||
*/
|
||||
AT24C32::AT24C32(byte index) {
|
||||
init(index, 32);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor with AT24C64 EEPROM at index 0
|
||||
*/
|
||||
AT24C64::AT24C64() {
|
||||
init(0, 32);
|
||||
}
|
||||
/**
|
||||
* Constructor with AT24C64 EEPROM at given index
|
||||
*/
|
||||
AT24C64::AT24C64(byte index) {
|
||||
init(index, 32);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor with AT24C128 EEPROM at index 0
|
||||
*/
|
||||
AT24C128::AT24C128() {
|
||||
init(0, 64);
|
||||
}
|
||||
/**
|
||||
* Constructor with AT24C128 EEPROM at given index
|
||||
*/
|
||||
AT24C128::AT24C128(byte index) {
|
||||
init(index, 64);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor with AT24C256 EEPROM at index 0
|
||||
*/
|
||||
AT24C256::AT24C256() {
|
||||
init(0, 64);
|
||||
}
|
||||
/**
|
||||
* Constructor with AT24C128 EEPROM at given index
|
||||
*/
|
||||
AT24C256::AT24C256(byte index) {
|
||||
init(index, 64);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor with AT24C512 EEPROM at index 0
|
||||
*/
|
||||
AT24C512::AT24C512() {
|
||||
init(0, 128);
|
||||
}
|
||||
/**
|
||||
* Constructor with AT24C512 EEPROM at given index
|
||||
*/
|
||||
AT24C512::AT24C512(byte index) {
|
||||
init(index, 128);
|
||||
}
|
||||
|
||||
/**
|
||||
* Init
|
||||
*/
|
||||
void AT24CX::init(byte index, byte pageSize) {
|
||||
_id = AT24CX_ID | (index & 0x7);
|
||||
_pageSize = pageSize;
|
||||
Wire.begin();
|
||||
}
|
||||
|
||||
/**
|
||||
* Write byte
|
||||
*/
|
||||
void AT24CX::write(unsigned int address, byte data) {
|
||||
/*
|
||||
if(_pageSize >= 32 || _pageSize <= 8)
|
||||
Wire.beginTransmission(_id);
|
||||
else
|
||||
Wire.beginTransmission((byte)(_id | ((address >> 8) & 0x07)));
|
||||
if(Wire.endTransmission()==0) {
|
||||
if(_pageSize >= 32)
|
||||
{
|
||||
Wire.beginTransmission(_id);
|
||||
Wire.write(address >> 8);
|
||||
Wire.write(address & 0xFF);
|
||||
}
|
||||
else if(_pageSize >= 16)
|
||||
{
|
||||
Wire.beginTransmission((byte)(_id | ((address >> 8) & 0x07)));
|
||||
Wire.write(address & 0xFF);
|
||||
}
|
||||
else
|
||||
{
|
||||
Wire.beginTransmission(_id);
|
||||
Wire.write(address);
|
||||
}
|
||||
*/
|
||||
connect(address);
|
||||
Wire.write(data);
|
||||
Wire.endTransmission();
|
||||
delay(10);
|
||||
}
|
||||
|
||||
/**
|
||||
* Write integer
|
||||
*/
|
||||
void AT24CX::writeInt(unsigned int address, unsigned int data) {
|
||||
write(address, (byte*)&data, 2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Write long
|
||||
*/
|
||||
void AT24CX::writeLong(unsigned int address, unsigned long data) {
|
||||
write(address, (byte*)&data, 4);
|
||||
}
|
||||
|
||||
/**
|
||||
* Write float
|
||||
*/
|
||||
void AT24CX::writeFloat(unsigned int address, float data) {
|
||||
write(address, (byte*)&data, 4);
|
||||
}
|
||||
|
||||
/**
|
||||
* Write double
|
||||
*/
|
||||
void AT24CX::writeDouble(unsigned int address, double data) {
|
||||
write(address, (byte*)&data, 8);
|
||||
}
|
||||
|
||||
/**
|
||||
* Write chars
|
||||
*/
|
||||
void AT24CX::writeChars(unsigned int address, char *data, int length) {
|
||||
write(address, (byte*)data, length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Read integer
|
||||
*/
|
||||
unsigned int AT24CX::readInt(unsigned int address) {
|
||||
read(address, _b, 2);
|
||||
return *(unsigned int*)&_b[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Read long
|
||||
*/
|
||||
unsigned long AT24CX::readLong(unsigned int address) {
|
||||
read(address, _b, 4);
|
||||
return *(unsigned long*)&_b[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Read float
|
||||
*/
|
||||
float AT24CX::readFloat(unsigned int address) {
|
||||
read(address, _b, 4);
|
||||
return *(float*)&_b[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Read double
|
||||
*/
|
||||
double AT24CX::readDouble(unsigned int address) {
|
||||
read(address, _b, 8);
|
||||
return *(double*)&_b[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Read chars
|
||||
*/
|
||||
void AT24CX::readChars(unsigned int address, char *data, int n) {
|
||||
read(address, (byte*)data, n);
|
||||
}
|
||||
|
||||
/**
|
||||
* Write sequence of n bytes
|
||||
*/
|
||||
void AT24CX::write(unsigned int address, byte *data, int n) {
|
||||
// status quo
|
||||
int c = n; // bytes left to write
|
||||
int offD = 0; // current offset in data pointer
|
||||
int offP; // current offset in page
|
||||
int nc = 0; // next n bytes to write
|
||||
|
||||
// write alle bytes in multiple steps
|
||||
while (c > 0) {
|
||||
// calc offset in page
|
||||
offP = address % _pageSize;
|
||||
// maximal 30 bytes to write
|
||||
nc = min(min(c, 30), _pageSize - offP);
|
||||
write(address, data, offD, nc);
|
||||
c-=nc;
|
||||
offD+=nc;
|
||||
address+=nc;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Write sequence of n bytes from offset
|
||||
*/
|
||||
void AT24CX::write(unsigned int address, byte *data, int offset, int n) {
|
||||
/*
|
||||
Wire.beginTransmission(_id);
|
||||
if (Wire.endTransmission()==0) {
|
||||
Wire.beginTransmission(_id);
|
||||
if(_pageSize >= 32)
|
||||
{
|
||||
Wire.write(address >> 8);
|
||||
Wire.write(address & 0xFF);
|
||||
}
|
||||
else
|
||||
{
|
||||
Wire.write(address);
|
||||
}
|
||||
*/
|
||||
connect(address);
|
||||
byte *adr = data+offset;
|
||||
Wire.write(adr, n);
|
||||
Wire.endTransmission();
|
||||
delay(10);
|
||||
}
|
||||
|
||||
/**
|
||||
* Read byte
|
||||
*/
|
||||
byte AT24CX::read(unsigned int address) {
|
||||
byte b = 0;
|
||||
int r = 0;
|
||||
connect(address);
|
||||
if (Wire.endTransmission()==0) {
|
||||
Wire.requestFrom(_id, 1);
|
||||
while (Wire.available() > 0 && r<1) {
|
||||
b = (byte)Wire.read();
|
||||
r++;
|
||||
}
|
||||
}
|
||||
return b;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read sequence of n bytes
|
||||
*/
|
||||
void AT24CX::read(unsigned int address, byte *data, int n) {
|
||||
int c = n;
|
||||
int offD = 0;
|
||||
// read until are n bytes read
|
||||
while (c > 0) {
|
||||
// read maximal 32 bytes
|
||||
int nc = c;
|
||||
if (nc > 32)
|
||||
nc = 32;
|
||||
read(address, data, offD, nc);
|
||||
address+=nc;
|
||||
offD+=nc;
|
||||
c-=nc;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Read sequence of n bytes to offset
|
||||
*/
|
||||
void AT24CX::read(unsigned int address, byte *data, int offset, int n) {
|
||||
connect(address);
|
||||
if (Wire.endTransmission()==0) {
|
||||
int r = 0;
|
||||
Wire.requestFrom(_id, n);
|
||||
while (Wire.available() > 0 && r<n) {
|
||||
data[offset+r] = (byte)Wire.read();
|
||||
r++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void AT24CX::connect(unsigned int address) {
|
||||
if(_pageSize >= 32)
|
||||
{
|
||||
Wire.beginTransmission(_id);
|
||||
Wire.write(address >> 8);
|
||||
Wire.write(address & 0xFF);
|
||||
}
|
||||
else if(_pageSize >= 16)
|
||||
{
|
||||
Wire.beginTransmission((byte)(_id | ((address >> 8) & 0x07)));
|
||||
Wire.write(address & 0xFF);
|
||||
}
|
||||
else
|
||||
{
|
||||
Wire.beginTransmission(_id);
|
||||
Wire.write(address);
|
||||
}
|
||||
}
|
||||
143
arduino-cli/libraries/AT24Cx/AT24CX.h
Normal file
143
arduino-cli/libraries/AT24Cx/AT24CX.h
Normal file
@@ -0,0 +1,143 @@
|
||||
/**
|
||||
|
||||
AT24CX.h
|
||||
Library for using the EEPROM AT24C32/64
|
||||
|
||||
Copyright (c) 2014 Christian Paul
|
||||
|
||||
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.
|
||||
|
||||
*/
|
||||
#ifndef AT24CX_h
|
||||
#define AT24CX_h
|
||||
|
||||
// includes
|
||||
#include <Arduino.h>
|
||||
|
||||
// byte
|
||||
typedef uint8_t byte;
|
||||
|
||||
// AT24Cx I2C adress
|
||||
// 80
|
||||
// 0x50
|
||||
#define AT24CX_ID B1010000
|
||||
|
||||
// general class definition
|
||||
class AT24CX {
|
||||
public:
|
||||
AT24CX();
|
||||
AT24CX(byte index, byte pageSize);
|
||||
void write(unsigned int address, byte data);
|
||||
void write(unsigned int address, byte *data, int n);
|
||||
void writeInt(unsigned int address, unsigned int data);
|
||||
void writeLong(unsigned int address, unsigned long data);
|
||||
void writeFloat(unsigned int address, float data);
|
||||
void writeDouble(unsigned int address, double data);
|
||||
void writeChars(unsigned int address, char *data, int length);
|
||||
byte read(unsigned int address);
|
||||
void read(unsigned int address, byte *data, int n);
|
||||
unsigned int readInt(unsigned int address);
|
||||
unsigned long readLong(unsigned int address);
|
||||
float readFloat(unsigned int address);
|
||||
double readDouble(unsigned int address);
|
||||
void readChars(unsigned int address, char *data, int n);
|
||||
protected:
|
||||
void init(byte index, byte pageSize);
|
||||
private:
|
||||
void read(unsigned int address, byte *data, int offset, int n);
|
||||
void write(unsigned int address, byte *data, int offset, int n);
|
||||
void connect(unsigned int address);
|
||||
int _id;
|
||||
byte _b[8];
|
||||
byte _pageSize;
|
||||
};
|
||||
|
||||
// AT24C01 class definiton
|
||||
class AT24C01 : public AT24CX {
|
||||
public:
|
||||
AT24C01();
|
||||
AT24C01(byte index);
|
||||
};
|
||||
|
||||
// AT24C02 class definiton
|
||||
class AT24C02 : public AT24CX {
|
||||
public:
|
||||
AT24C02();
|
||||
AT24C02(byte index);
|
||||
};
|
||||
|
||||
// AT24C04 class definiton
|
||||
class AT24C04 : public AT24CX {
|
||||
public:
|
||||
AT24C04();
|
||||
AT24C04(byte index);
|
||||
};
|
||||
|
||||
// AT24C08 class definiton
|
||||
class AT24C08 : public AT24CX {
|
||||
public:
|
||||
AT24C08();
|
||||
AT24C08(byte index);
|
||||
};
|
||||
|
||||
// AT24C16 class definiton
|
||||
class AT24C16 : public AT24CX {
|
||||
public:
|
||||
AT24C16();
|
||||
AT24C16(byte index);
|
||||
};
|
||||
|
||||
// AT24C32 class definiton
|
||||
class AT24C32 : public AT24CX {
|
||||
public:
|
||||
AT24C32();
|
||||
AT24C32(byte index);
|
||||
};
|
||||
|
||||
// AT24C64 class definiton
|
||||
class AT24C64 : public AT24CX {
|
||||
public:
|
||||
AT24C64();
|
||||
AT24C64(byte index);
|
||||
};
|
||||
|
||||
// AT24C128 class definiton
|
||||
class AT24C128 : public AT24CX {
|
||||
public:
|
||||
AT24C128();
|
||||
AT24C128(byte index);
|
||||
};
|
||||
|
||||
// AT24C256 class definiton
|
||||
class AT24C256 : public AT24CX {
|
||||
public:
|
||||
AT24C256();
|
||||
AT24C256(byte index);
|
||||
};
|
||||
|
||||
// AT24C512 class definiton
|
||||
class AT24C512 : public AT24CX {
|
||||
public:
|
||||
AT24C512();
|
||||
AT24C512(byte index);
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
198
arduino-cli/libraries/AT24Cx/AT24CX_demo/AT24CX_demo.ino
Normal file
198
arduino-cli/libraries/AT24Cx/AT24CX_demo/AT24CX_demo.ino
Normal file
@@ -0,0 +1,198 @@
|
||||
/*
|
||||
*
|
||||
* Read and write demo of the AT24CX library
|
||||
* Written by Christian Paul, 2014-11-24
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
// include libraries
|
||||
#include <Wire.h>
|
||||
#include <AT24CX.h>
|
||||
|
||||
// EEPROM object
|
||||
AT24CX mem(7,64);
|
||||
|
||||
// setup
|
||||
void setup() {
|
||||
// serial init
|
||||
Serial.begin(115200);
|
||||
Serial.println("AT24CX read/write demo");
|
||||
Serial.println("----------------------");
|
||||
}
|
||||
|
||||
// main loop
|
||||
void loop() {
|
||||
|
||||
// read and write byte
|
||||
Serial.println("Write 42 to address 12");
|
||||
mem.write(0, 42);
|
||||
Serial.println("Read byte from address 12 ...");
|
||||
byte b = mem.read(0);
|
||||
Serial.print("... read: ");
|
||||
Serial.println(b, DEC);
|
||||
Serial.println();
|
||||
|
||||
// read and write integer
|
||||
Serial.println("Write 65000 to address 15");
|
||||
mem.writeInt(15, 65000);
|
||||
Serial.println("Read integer from address 15 ...");
|
||||
unsigned int i = mem.readInt(15);
|
||||
Serial.print("... read: ");
|
||||
Serial.println(i, DEC);
|
||||
Serial.println();
|
||||
|
||||
// read and write long
|
||||
Serial.println("Write 3293732729 to address 20");
|
||||
mem.writeLong(20, 3293732729UL);
|
||||
Serial.println("Read long from address 20 ...");
|
||||
unsigned long l = mem.readLong(20);
|
||||
Serial.print("... read: ");
|
||||
Serial.println(l, DEC);
|
||||
Serial.println();
|
||||
|
||||
// read and write long
|
||||
Serial.println("Write 1111111111 to address 31");
|
||||
mem.writeLong(31, 1111111111);
|
||||
Serial.println("Read long from address 31 ...");
|
||||
unsigned long l2 = mem.readLong(31);
|
||||
Serial.print("... read: ");
|
||||
Serial.println(l2, DEC);
|
||||
Serial.println();
|
||||
|
||||
// read and write float
|
||||
Serial.println("Write 3.14 to address 40");
|
||||
mem.writeFloat(40, 3.14);
|
||||
Serial.println("Read float from address 40 ...");
|
||||
float f = mem.readFloat(40);
|
||||
Serial.print("... read: ");
|
||||
Serial.println(f, DEC);
|
||||
Serial.println();
|
||||
|
||||
// read and write double
|
||||
Serial.println("Write 3.14159265359 to address 50");
|
||||
mem.writeDouble(50, 3.14159265359);
|
||||
Serial.println("Read double from address 50 ...");
|
||||
double d = mem.readDouble(50);
|
||||
Serial.print("... read: ");
|
||||
Serial.println(d, DEC);
|
||||
Serial.println();
|
||||
|
||||
// read and write char
|
||||
Serial.print("Write chars: '");
|
||||
char msg[] = "This is a message";
|
||||
Serial.print(msg);
|
||||
Serial.println("' to address 200");
|
||||
mem.writeChars(200, msg, sizeof(msg));
|
||||
Serial.println("Read chars from address 200 ...");
|
||||
char msg2[30];
|
||||
mem.readChars(200, msg2, sizeof(msg2));
|
||||
Serial.print("... read: '");
|
||||
Serial.print(msg2);
|
||||
Serial.println("'");
|
||||
Serial.println();
|
||||
|
||||
// write array of bytes
|
||||
Serial.println("Write array of 80 bytes at address 1000");
|
||||
byte xy[] = {0,0,0,1,1,1,2,2,2,3,3,3,4,4,4,5,5,5,6,6,6,7,7,7,8,8,8,9,9,9, // 10 x 3 = 30
|
||||
10,11,12,13,14,15,16,17,18,19, // 10
|
||||
120,121,122,123,124,125,126,127,128,129, // 10
|
||||
130,131,132,133,134,135,136,137,138,139, // 10
|
||||
200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219}; // 20
|
||||
mem.write(0, (byte*)xy, sizeof(xy));
|
||||
|
||||
// read bytes with multiple steps
|
||||
Serial.println("Read 80 single bytes starting at address 0");
|
||||
for (int i=0; i<sizeof(xy); i++) {
|
||||
byte sb = mem.read(i);
|
||||
Serial.print("[");
|
||||
Serial.print(i);
|
||||
Serial.print("] = ");
|
||||
Serial.println(sb);
|
||||
}
|
||||
Serial.println();
|
||||
|
||||
// read bytes with one step
|
||||
Serial.println("Read 80 bytes with one operation at address 0");
|
||||
byte z[80];
|
||||
memset(&z[0], 32, sizeof(z));
|
||||
mem.read(0, z, sizeof(z));
|
||||
for (int i=0; i<sizeof(z); i++) {
|
||||
Serial.print("[");
|
||||
Serial.print(i);
|
||||
Serial.print("] = ");
|
||||
Serial.println(z[i]);
|
||||
}
|
||||
|
||||
/*
|
||||
Serial.println("Write 42 to address 12");
|
||||
mem.write(32769, 100);
|
||||
Serial.println("Read byte from address 12 ...");
|
||||
byte b = mem.read(1);
|
||||
Serial.print("... read: ");
|
||||
Serial.println(b, DEC);
|
||||
Serial.println();
|
||||
*/
|
||||
/*
|
||||
double time_data = millis();
|
||||
for(int i = 0;i <= 256;i++)
|
||||
mem.write(i, i%255);
|
||||
//Serial.println(String(i)+String(" = ")+mem.read(i));
|
||||
time_data = (millis() - time_data)/1000;
|
||||
Serial.println(String("finish! time = ") + time_data + String("S"));
|
||||
Serial.println("Write 3293732729 to address 20");
|
||||
mem.writeLong(20, 3293732729UL);
|
||||
Serial.println("Read long from address 20 ...");
|
||||
unsigned long l = mem.readLong(20);
|
||||
Serial.print("... read: ");
|
||||
Serial.println(l, DEC);
|
||||
Serial.println();
|
||||
for(int i = 0;i <= 256;i++)
|
||||
Serial.println(String(i)+String(" = ")+mem.read(i));
|
||||
//
|
||||
|
||||
Serial.println("Write array of 80 bytes at address 1000");
|
||||
byte xy[] = {0,0,0,1,1,1,2,2,2,3,3,3,4,4,4,5,5,5,6,6,6,7,7,7,8,8,8,9,9,9, // 10 x 3 = 30
|
||||
10,11,12,13,14,15,16,17,18,19, // 10
|
||||
120,121,122,123,124,125,126,127,128,129, // 10
|
||||
130,131,132,133,134,135,136,137,138,139, // 10
|
||||
200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219}; // 20
|
||||
mem.write(0, (byte*)xy, sizeof(xy));
|
||||
|
||||
// read bytes with multiple steps
|
||||
Serial.println("Read 80 single bytes starting at address 0");
|
||||
for (int i=0; i<sizeof(xy); i++) {
|
||||
byte sb = mem.read(i);
|
||||
Serial.print("[");
|
||||
Serial.print(i);
|
||||
Serial.print("] = ");
|
||||
Serial.println(sb);
|
||||
}
|
||||
for(int i = 0;i <= 256;i++)
|
||||
Serial.println(String(i)+String(" = ")+mem.read(i));
|
||||
Serial.println();
|
||||
*/
|
||||
/*
|
||||
int at24c_data;
|
||||
double time_data = millis();
|
||||
long i;
|
||||
for(i = 0;;i++)
|
||||
{
|
||||
mem.write(i, i%255);
|
||||
if(i == 0)
|
||||
{
|
||||
at24c_data = mem.read(i);
|
||||
}
|
||||
if(mem.read(0) != at24c_data)
|
||||
break;
|
||||
if(i >= 40000)
|
||||
break;
|
||||
}
|
||||
time_data = (millis() - time_data)/1000;
|
||||
if(i >= 40000)
|
||||
Serial.println(String("time out! time = ") + time_data + String("S ") + i + String("byte"));
|
||||
else
|
||||
Serial.println(String("finish! time = ") + time_data + String("S ") + i + String("byte"));
|
||||
*/
|
||||
while (1==1) {}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
*
|
||||
* Search for an EEPROM.
|
||||
* This sketch iterate the eight possible I2C addresses and
|
||||
* checks if an EEPROM is found.
|
||||
*
|
||||
* Written by Christian Paul, 2014-11-24
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
// include libraries
|
||||
#include <Wire.h>
|
||||
|
||||
// setup
|
||||
void setup() {
|
||||
Serial.begin(115200);
|
||||
Serial.println("AT24CX search");
|
||||
Serial.println("-------------------------");
|
||||
|
||||
Wire.begin();
|
||||
int i2c = 0x50;
|
||||
for (int i=0; i<8; i++) {
|
||||
Serial.print("Search at [");
|
||||
Serial.print(i2c, HEX);
|
||||
Serial.print("]: ");
|
||||
Wire.beginTransmission(i2c);
|
||||
int result = Wire.endTransmission();
|
||||
if (result==0)
|
||||
Serial.println("FOUND!");
|
||||
else
|
||||
Serial.println("not found");
|
||||
i2c++;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// main loop
|
||||
void loop() {}
|
||||
|
||||
21
arduino-cli/libraries/AT24Cx/LICENSE
Normal file
21
arduino-cli/libraries/AT24Cx/LICENSE
Normal file
@@ -0,0 +1,21 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2014-2015 Christian Paul
|
||||
|
||||
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.
|
||||
25
arduino-cli/libraries/AT24Cx/LIZENZ
Normal file
25
arduino-cli/libraries/AT24Cx/LIZENZ
Normal file
@@ -0,0 +1,25 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2014-2015 Christian Paul
|
||||
|
||||
----------
|
||||
Übersetzung von Wikipedia - http://de.wikipedia.org/wiki/MIT-Lizenz
|
||||
----
|
||||
|
||||
Hiermit wird unentgeltlich jeder Person, die eine Kopie der Software und der zugehörigen
|
||||
Dokumentationen (die "Software") erhält, die Erlaubnis erteilt, sie uneingeschränkt zu
|
||||
benutzen, inklusive und ohne Ausnahme dem Recht, sie zu verwenden, kopieren, ändern,
|
||||
fusionieren, verlegen, verbreiten, unterlizenzieren und/oder zu verkaufen, und Personen, die
|
||||
diese Software erhalten, diese Rechte zu geben, unter den folgenden Bedingungen:
|
||||
|
||||
Der obige Urheberrechtsvermerk und dieser Erlaubnisvermerk sind in allen Kopien oder
|
||||
Teilkopien der Software beizulegen.
|
||||
|
||||
DIE SOFTWARE WIRD OHNE JEDE AUSDRÜCKLICHE ODER IMPLIZIERTE GARANTIE
|
||||
BEREITGESTELLT, EINSCHLIESSLICH DER GARANTIE ZUR BENUTZUNG FÜR DEN
|
||||
VORGESEHENEN ODER EINEM BESTIMMTEN ZWECK SOWIE JEGLICHER
|
||||
RECHTSVERLETZUNG, JEDOCH NICHT DARAUF BESCHRÄNKT. IN KEINEM FALL SIND DIE
|
||||
AUTOREN ODER COPYRIGHTINHABER FÜR JEGLICHEN SCHADEN ODER SONSTIGE
|
||||
ANSPRÜCHE HAFTBAR ZU MACHEN, OB INFOLGE DER ERFÜLLUNG EINES VERTRAGES,
|
||||
EINES DELIKTES ODER ANDERS IM ZUSAMMENHANG MIT DER SOFTWARE ODER
|
||||
SONSTIGER VERWENDUNG DER SOFTWARE ENTSTANDEN.
|
||||
61
arduino-cli/libraries/AT24Cx/README.md
Normal file
61
arduino-cli/libraries/AT24Cx/README.md
Normal file
@@ -0,0 +1,61 @@
|
||||
# AT24CX Library
|
||||
|
||||
Library for using the Atmels EEPROM AT24C32/AT24C64/AT24C128/AT24C256/AT24C512 in Arduino projects.
|
||||
See <https://oberguru.net/elektronik/eeprom/at24cx-at24c32-at24c64-at24c128-at24c256-at24c512.html> for definitons and differences.
|
||||
|
||||
Written by Christian Paul, 2014 - 2015.
|
||||
This software is released under the terms of the MIT license.
|
||||
See the file LICENSE or LIZENZ for details, please.
|
||||
|
||||
You can use any of the eight possibles EEPROM devices on the I2C bus.
|
||||
|
||||
Constructor
|
||||
|
||||
AT24CX(byte pageSize);
|
||||
|
||||
uses the device with index 0 and given page size. You can select a device with given index between 0 and 8 with constructor
|
||||
|
||||
AT24CX(byte index, byte pageSize);
|
||||
|
||||
Than, you can single write or read single bytes from the EEPROM with
|
||||
|
||||
void write(unsigned int address, byte data);
|
||||
byte read(unsigned int address);
|
||||
|
||||
or write and read an array of bytes with
|
||||
|
||||
void write(unsigned int address, byte *data, int n);
|
||||
void read(unsigned int address, byte *data, int n);
|
||||
|
||||
For writing integers, long, float, double or sequences of chars you can use the comfort functions
|
||||
|
||||
void writeInt(unsigned int address, unsigned int data);
|
||||
void writeLong(unsigned int address, unsigned long data);
|
||||
void writeFloat(unsigned int address, float data);
|
||||
void writeDouble(unsigned int address, double data);
|
||||
void writeChars(unsigned int address, char *data, int length);
|
||||
|
||||
Reading the values is done by using
|
||||
|
||||
unsigned int readInt(unsigned int address);
|
||||
unsigned long readLong(unsigned int address);
|
||||
float readFloat(unsigned int address);
|
||||
double readDouble(unsigned int address);
|
||||
void readChars(unsigned int address, char *data, int n);
|
||||
|
||||
Alternative you can use the individual classes with predefined page sizes:
|
||||
|
||||
AT24C32();
|
||||
AT24C64();
|
||||
AT24C128();
|
||||
AT24C256();
|
||||
AT24C512();
|
||||
|
||||
or with different index than 0:
|
||||
|
||||
AT24C32(byte index);
|
||||
AT24C64(byte index);
|
||||
AT24C128(byte index);
|
||||
AT24C256(byte index);
|
||||
AT24C512(byte index);
|
||||
|
||||
271
arduino-cli/libraries/AT24Cx_Soft/AT24CX_Soft.cpp
Normal file
271
arduino-cli/libraries/AT24Cx_Soft/AT24CX_Soft.cpp
Normal file
@@ -0,0 +1,271 @@
|
||||
/**
|
||||
|
||||
AT24CX_Soft.cpp
|
||||
Library for using the EEPROM AT24C32/64
|
||||
|
||||
Copyright (c) 2014 Christian Paul
|
||||
|
||||
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 "AT24CX_Soft.h"
|
||||
#include <SoftwareWire.h>
|
||||
|
||||
/**
|
||||
* Constructor with AT24Cx EEPROM at given index and size of page
|
||||
*/
|
||||
AT24CX_Soft::AT24CX_Soft(byte index, byte pageSize, SoftwareWire *theWire) {
|
||||
init(index, pageSize, theWire);
|
||||
}
|
||||
|
||||
/**
|
||||
* Init
|
||||
*/
|
||||
void AT24CX_Soft::init(byte index, byte pageSize, SoftwareWire *theWire) {
|
||||
_wire = theWire;
|
||||
_id = AT24CX_Soft_ID | (index & 0x7);
|
||||
_pageSize = pageSize;
|
||||
_wire->begin();
|
||||
}
|
||||
|
||||
/**
|
||||
* Write byte
|
||||
*/
|
||||
void AT24CX_Soft::write(unsigned int address, byte data) {
|
||||
/*
|
||||
if(_pageSize >= 32 || _pageSize <= 8)
|
||||
_wire->beginTransmission(_id);
|
||||
else
|
||||
_wire->beginTransmission((byte)(_id | ((address >> 8) & 0x07)));
|
||||
if(_wire->endTransmission()==0) {
|
||||
if(_pageSize >= 32)
|
||||
{
|
||||
_wire->beginTransmission(_id);
|
||||
_wire->write(address >> 8);
|
||||
_wire->write(address & 0xFF);
|
||||
}
|
||||
else if(_pageSize >= 16)
|
||||
{
|
||||
_wire->beginTransmission((byte)(_id | ((address >> 8) & 0x07)));
|
||||
_wire->write(address & 0xFF);
|
||||
}
|
||||
else
|
||||
{
|
||||
_wire->beginTransmission(_id);
|
||||
_wire->write(address);
|
||||
}
|
||||
*/
|
||||
connect(address);
|
||||
_wire->write(data);
|
||||
_wire->endTransmission();
|
||||
delay(10);
|
||||
}
|
||||
|
||||
/**
|
||||
* Write integer
|
||||
*/
|
||||
void AT24CX_Soft::writeInt(unsigned int address, unsigned int data) {
|
||||
write(address, (byte*)&data, 2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Write long
|
||||
*/
|
||||
void AT24CX_Soft::writeLong(unsigned int address, unsigned long data) {
|
||||
write(address, (byte*)&data, 4);
|
||||
}
|
||||
|
||||
/**
|
||||
* Write float
|
||||
*/
|
||||
void AT24CX_Soft::writeFloat(unsigned int address, float data) {
|
||||
write(address, (byte*)&data, 4);
|
||||
}
|
||||
|
||||
/**
|
||||
* Write double
|
||||
*/
|
||||
void AT24CX_Soft::writeDouble(unsigned int address, double data) {
|
||||
write(address, (byte*)&data, 8);
|
||||
}
|
||||
|
||||
/**
|
||||
* Write chars
|
||||
*/
|
||||
void AT24CX_Soft::writeChars(unsigned int address, char *data, int length) {
|
||||
write(address, (byte*)data, length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Read integer
|
||||
*/
|
||||
unsigned int AT24CX_Soft::readInt(unsigned int address) {
|
||||
read(address, _b, 2);
|
||||
return *(unsigned int*)&_b[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Read long
|
||||
*/
|
||||
unsigned long AT24CX_Soft::readLong(unsigned int address) {
|
||||
read(address, _b, 4);
|
||||
return *(unsigned long*)&_b[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Read float
|
||||
*/
|
||||
float AT24CX_Soft::readFloat(unsigned int address) {
|
||||
read(address, _b, 4);
|
||||
return *(float*)&_b[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Read double
|
||||
*/
|
||||
double AT24CX_Soft::readDouble(unsigned int address) {
|
||||
read(address, _b, 8);
|
||||
return *(double*)&_b[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Read chars
|
||||
*/
|
||||
void AT24CX_Soft::readChars(unsigned int address, char *data, int n) {
|
||||
read(address, (byte*)data, n);
|
||||
}
|
||||
|
||||
/**
|
||||
* Write sequence of n bytes
|
||||
*/
|
||||
void AT24CX_Soft::write(unsigned int address, byte *data, int n) {
|
||||
// status quo
|
||||
int c = n; // bytes left to write
|
||||
int offD = 0; // current offset in data pointer
|
||||
int offP; // current offset in page
|
||||
int nc = 0; // next n bytes to write
|
||||
|
||||
// write alle bytes in multiple steps
|
||||
while (c > 0) {
|
||||
// calc offset in page
|
||||
offP = address % _pageSize;
|
||||
// maximal 30 bytes to write
|
||||
nc = min(min(c, 30), _pageSize - offP);
|
||||
write(address, data, offD, nc);
|
||||
c-=nc;
|
||||
offD+=nc;
|
||||
address+=nc;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Write sequence of n bytes from offset
|
||||
*/
|
||||
void AT24CX_Soft::write(unsigned int address, byte *data, int offset, int n) {
|
||||
/*
|
||||
_wire->beginTransmission(_id);
|
||||
if (_wire->endTransmission()==0) {
|
||||
_wire->beginTransmission(_id);
|
||||
if(_pageSize >= 32)
|
||||
{
|
||||
_wire->write(address >> 8);
|
||||
_wire->write(address & 0xFF);
|
||||
}
|
||||
else
|
||||
{
|
||||
_wire->write(address);
|
||||
}
|
||||
*/
|
||||
connect(address);
|
||||
byte *adr = data+offset;
|
||||
_wire->write(adr, n);
|
||||
_wire->endTransmission();
|
||||
delay(10);
|
||||
}
|
||||
|
||||
/**
|
||||
* Read byte
|
||||
*/
|
||||
byte AT24CX_Soft::read(unsigned int address) {
|
||||
byte b = 0;
|
||||
int r = 0;
|
||||
connect(address);
|
||||
if (_wire->endTransmission()==0) {
|
||||
_wire->requestFrom(_id, 1);
|
||||
while (_wire->available() > 0 && r<1) {
|
||||
b = (byte)_wire->read();
|
||||
r++;
|
||||
}
|
||||
}
|
||||
return b;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read sequence of n bytes
|
||||
*/
|
||||
void AT24CX_Soft::read(unsigned int address, byte *data, int n) {
|
||||
int c = n;
|
||||
int offD = 0;
|
||||
// read until are n bytes read
|
||||
while (c > 0) {
|
||||
// read maximal 32 bytes
|
||||
int nc = c;
|
||||
if (nc > 32)
|
||||
nc = 32;
|
||||
read(address, data, offD, nc);
|
||||
address+=nc;
|
||||
offD+=nc;
|
||||
c-=nc;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Read sequence of n bytes to offset
|
||||
*/
|
||||
void AT24CX_Soft::read(unsigned int address, byte *data, int offset, int n) {
|
||||
connect(address);
|
||||
if (_wire->endTransmission()==0) {
|
||||
int r = 0;
|
||||
_wire->requestFrom(_id, n);
|
||||
while (_wire->available() > 0 && r<n) {
|
||||
data[offset+r] = (byte)_wire->read();
|
||||
r++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void AT24CX_Soft::connect(unsigned int address) {
|
||||
if(_pageSize >= 32)
|
||||
{
|
||||
_wire->beginTransmission(_id);
|
||||
_wire->write(address >> 8);
|
||||
_wire->write(address & 0xFF);
|
||||
}
|
||||
else if(_pageSize >= 16)
|
||||
{
|
||||
_wire->beginTransmission((byte)(_id | ((address >> 8) & 0x07)));
|
||||
_wire->write(address & 0xFF);
|
||||
}
|
||||
else
|
||||
{
|
||||
_wire->beginTransmission(_id);
|
||||
_wire->write(address);
|
||||
}
|
||||
}
|
||||
71
arduino-cli/libraries/AT24Cx_Soft/AT24CX_Soft.h
Normal file
71
arduino-cli/libraries/AT24Cx_Soft/AT24CX_Soft.h
Normal file
@@ -0,0 +1,71 @@
|
||||
/**
|
||||
|
||||
AT24CX_Soft.h
|
||||
Library for using the EEPROM AT24C32/64
|
||||
|
||||
Copyright (c) 2014 Christian Paul
|
||||
|
||||
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.
|
||||
|
||||
*/
|
||||
#ifndef AT24CX_Soft_h
|
||||
#define AT24CX_Soft_h
|
||||
|
||||
// includes
|
||||
#include <Arduino.h>
|
||||
#include <SoftwareWire.h>
|
||||
// byte
|
||||
typedef uint8_t byte;
|
||||
|
||||
// AT24Cx I2C adress
|
||||
// 80
|
||||
// 0x50
|
||||
#define AT24CX_Soft_ID B1010000
|
||||
|
||||
// general class definition
|
||||
class AT24CX_Soft {
|
||||
public:
|
||||
AT24CX_Soft(byte index, byte pageSize, SoftwareWire *theWire);
|
||||
void write(unsigned int address, byte data);
|
||||
void write(unsigned int address, byte *data, int n);
|
||||
void writeInt(unsigned int address, unsigned int data);
|
||||
void writeLong(unsigned int address, unsigned long data);
|
||||
void writeFloat(unsigned int address, float data);
|
||||
void writeDouble(unsigned int address, double data);
|
||||
void writeChars(unsigned int address, char *data, int length);
|
||||
byte read(unsigned int address);
|
||||
void read(unsigned int address, byte *data, int n);
|
||||
unsigned int readInt(unsigned int address);
|
||||
unsigned long readLong(unsigned int address);
|
||||
float readFloat(unsigned int address);
|
||||
double readDouble(unsigned int address);
|
||||
void readChars(unsigned int address, char *data, int n);
|
||||
protected:
|
||||
void init(byte index, byte pageSize, SoftwareWire *theWire);
|
||||
private:
|
||||
SoftwareWire *_wire;
|
||||
void read(unsigned int address, byte *data, int offset, int n);
|
||||
void write(unsigned int address, byte *data, int offset, int n);
|
||||
void connect(unsigned int address);
|
||||
int _id;
|
||||
byte _b[8];
|
||||
byte _pageSize;
|
||||
};
|
||||
|
||||
#endif
|
||||
174
arduino-cli/libraries/AT24Cxx/AT24Cxx.cpp
Normal file
174
arduino-cli/libraries/AT24Cxx/AT24Cxx.cpp
Normal file
@@ -0,0 +1,174 @@
|
||||
#include <Arduino.h>
|
||||
|
||||
#include <Wire.h>
|
||||
#include "AT24Cxx.h"
|
||||
#define min(a,b) ((a)<(b)?(a):(b))
|
||||
|
||||
#define AT24Cxx_CTRL_ID 0x50
|
||||
int8_t deviceAddress = 0x50;
|
||||
|
||||
AT24Cxx::AT24Cxx()
|
||||
{
|
||||
//Wire.begin();
|
||||
deviceAddress = AT24Cxx_CTRL_ID;
|
||||
}
|
||||
|
||||
AT24Cxx::AT24Cxx(uint8_t address)
|
||||
{
|
||||
deviceAddress = address;
|
||||
}
|
||||
//
|
||||
// PUBLIC FUNCTIONS
|
||||
|
||||
bool AT24Cxx::isPresent(void) // check if the device is present
|
||||
{
|
||||
Wire.beginTransmission(deviceAddress);
|
||||
if (Wire.endTransmission() == 0)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int AT24Cxx::ReadMem(int iAddr, char Buf[], int iCnt)
|
||||
{
|
||||
int iRead=0, iBytes;
|
||||
while (iCnt>0) {
|
||||
Wire.beginTransmission(deviceAddress);
|
||||
#if ARDUINO >= 100
|
||||
Wire.write(iAddr>>8); // Address MSB
|
||||
Wire.write(iAddr&0xff); // Address LSB
|
||||
#else
|
||||
Wire.send(iAddr>>8); // Address MSB
|
||||
Wire.send(iAddr&0xff); // Address LSB
|
||||
#endif
|
||||
Wire.endTransmission();
|
||||
|
||||
iBytes = min(iCnt, 128);
|
||||
Wire.requestFrom(deviceAddress, iBytes);
|
||||
|
||||
while (Wire.available() && iCnt>0) {
|
||||
#if ARDUINO >= 100
|
||||
Buf[iRead] = Wire.read();
|
||||
#else
|
||||
Buf[iRead] = Wire.receive();
|
||||
#endif
|
||||
iRead++; iCnt--; iAddr++;
|
||||
} /* while */
|
||||
}
|
||||
return (iRead);
|
||||
}
|
||||
|
||||
int AT24Cxx::ReadStr(int iAddr, char Buf[], int iCnt)
|
||||
{
|
||||
int iRead=0, iBytes;
|
||||
char c;
|
||||
while (iCnt>0) {
|
||||
Wire.beginTransmission(deviceAddress);
|
||||
#if ARDUINO >= 100
|
||||
Wire.write(iAddr>>8); // Address MSB
|
||||
Wire.write(iAddr&0xff); // Address LSB
|
||||
#else
|
||||
Wire.send(iAddr>>8); // Address MSB
|
||||
Wire.send(iAddr&0xff); // Address LSB
|
||||
#endif
|
||||
Wire.endTransmission();
|
||||
|
||||
iBytes = min(iCnt, 128);
|
||||
Wire.requestFrom(deviceAddress, iBytes);
|
||||
|
||||
while (Wire.available() && iCnt>0) {
|
||||
#if ARDUINO >= 100
|
||||
c = Wire.read();
|
||||
#else
|
||||
c = Wire.receive();
|
||||
#endif
|
||||
Buf[iRead] = c;
|
||||
if (c == '\0') {
|
||||
iCnt=0; break;
|
||||
} /* if */
|
||||
iRead++; iCnt--; iAddr++;
|
||||
} /* while */
|
||||
}
|
||||
return (iRead);
|
||||
}
|
||||
|
||||
uint8_t AT24Cxx::WriteMem(int iAddr, uint8_t iVal)
|
||||
{
|
||||
uint8_t iRC=0;
|
||||
Wire.beginTransmission(deviceAddress);
|
||||
#if ARDUINO >= 100
|
||||
Wire.write(iAddr>>8); // Address MSB
|
||||
Wire.write(iAddr&0xff); // Address LSB
|
||||
Wire.write(iVal);
|
||||
#else
|
||||
Wire.send(iAddr>>8); // Address MSB
|
||||
Wire.send(iAddr&0xff); // Address LSB
|
||||
Wire.send(iVal);
|
||||
#endif
|
||||
iRC = Wire.endTransmission();
|
||||
delay(5);
|
||||
|
||||
return(iRC);
|
||||
}
|
||||
|
||||
// BYTE WRITE:
|
||||
// A write operation requires two 8-bit data word addresses following the device address word and acknowledgment.
|
||||
// Upon receipt of this address, the EEPROM will again respond with a zero and then clock in the first 8-bit data
|
||||
// word. Following receipt of the 8-bit data word, the EEPROM will output a zero and the addressing device, such as
|
||||
// a microcontroller, must terminate the write sequence with a stop condition. At this time the EEPROM enters an
|
||||
// internally-timed write cycle, tWR, to the nonvolatile memory. All inputs are disabled during this write cycle and
|
||||
// the EEPROM will not respond until the write is complete (refer to Figure 2).
|
||||
|
||||
// PAGE WRITE:
|
||||
// The 32K/64K EEPROM is capable of 32-byte page writes. A page write is initiated the same way as a byte write, but
|
||||
// the microcontroller does not send a stop condition after the first data word is clocked in. Instead, after the EEPROM
|
||||
// acknowledges receipt of the first data word, the microcontroller can transmit up to 31 more data words. The EEPROM
|
||||
// will respond with a zero after each data word received. The microcontroller must terminate the page write sequence
|
||||
// with a stop condition (refer to Figure 3).
|
||||
|
||||
// The data word address lower 5 bits are internally incremented following the receipt of each data word. The higher
|
||||
// data word address bits are not incremented, retaining the memory page row location. When the word address, internally
|
||||
// generated, reaches the page boundary, the following byte is placed at the beginning of the same page. If more than 32
|
||||
// data words are transmitted to the EEPROM, the data word address will “roll over” and previous data will be overwritten.
|
||||
uint8_t AT24Cxx::WriteMem(int iAddr, const char *pBuf, int iCnt)
|
||||
{
|
||||
uint8_t iBytes, iRC=0;
|
||||
|
||||
// Writes are restricted to a single 32 byte page. Therefore. if a write spans a page
|
||||
// boundry we must split the write.
|
||||
|
||||
while (iCnt > 0) {
|
||||
iBytes = min(iCnt, BUFFER_LENGTH-2);
|
||||
int iCurPage = iAddr & ~((int)0x1f);
|
||||
if (iAddr+iBytes > iCurPage+32) { // Number of bytes is too large
|
||||
iBytes = (iCurPage+32) - iAddr;
|
||||
}
|
||||
|
||||
Wire.beginTransmission(deviceAddress);
|
||||
#if ARDUINO >= 100
|
||||
Wire.write( highByte(iAddr) ); // Address MSB
|
||||
Wire.write( lowByte(iAddr) ); // Address LSB
|
||||
Wire.write((uint8_t*)pBuf, iBytes);
|
||||
#else
|
||||
Wire.send( highByte(iAddr) ); // Address MSB
|
||||
Wire.send( lowByte(iAddr) ); // Address LSB
|
||||
Wire.send(pBuf, iBytes);
|
||||
#endif
|
||||
Wire.endTransmission();
|
||||
iRC +=(int)iBytes;
|
||||
iCnt -=(int)iBytes;
|
||||
iAddr+=(int)iBytes;
|
||||
pBuf +=(int)iBytes;
|
||||
delay(5); // Give the EEPROM time to write its data
|
||||
} /* while */
|
||||
|
||||
return(iRC);
|
||||
}
|
||||
|
||||
uint8_t AT24Cxx::WriteStr(int iAddr, const char *pBuf)
|
||||
{
|
||||
uint8_t iRC=0;
|
||||
int iCnt = strlen(pBuf);
|
||||
|
||||
iRC = WriteMem(iAddr, pBuf, iCnt+1); // Write the NULL terminator
|
||||
return(iRC);
|
||||
}
|
||||
25
arduino-cli/libraries/AT24Cxx/AT24Cxx.h
Normal file
25
arduino-cli/libraries/AT24Cxx/AT24Cxx.h
Normal file
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* AT24Cxx.h - library for AT24Cxx
|
||||
*/
|
||||
|
||||
#ifndef AT24Cxx_h
|
||||
#define AT24Cxx_h
|
||||
|
||||
class AT24Cxx
|
||||
{
|
||||
// user-accessible "public" interface
|
||||
public:
|
||||
AT24Cxx();
|
||||
AT24Cxx(uint8_t);
|
||||
|
||||
static bool isPresent(void); // check if the device is present
|
||||
static int ReadMem(int iAddr, char Buf[], int iCnt);
|
||||
static uint8_t WriteMem(int iAddr, uint8_t iVal);
|
||||
static uint8_t WriteMem(int iAddr, const char *pBuf, int iCnt);
|
||||
|
||||
static int ReadStr(int iAddr, char Buf[], int iBufLen);
|
||||
static uint8_t WriteStr(int iAddr, const char *pBuf);
|
||||
|
||||
private:
|
||||
};
|
||||
#endif
|
||||
652
arduino-cli/libraries/AccelStepper/AccelStepper.cpp
Normal file
652
arduino-cli/libraries/AccelStepper/AccelStepper.cpp
Normal file
@@ -0,0 +1,652 @@
|
||||
// AccelStepper.cpp
|
||||
//
|
||||
// Copyright (C) 2009-2013 Mike McCauley
|
||||
// $Id: AccelStepper.cpp,v 1.23 2016/08/09 00:39:10 mikem Exp $
|
||||
|
||||
#include "AccelStepper.h"
|
||||
|
||||
#if 0
|
||||
// Some debugging assistance
|
||||
void dump(uint8_t* p, int l)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < l; i++)
|
||||
{
|
||||
Serial.print(p[i], HEX);
|
||||
Serial.print(" ");
|
||||
}
|
||||
Serial.println("");
|
||||
}
|
||||
#endif
|
||||
|
||||
void AccelStepper::moveTo(long absolute)
|
||||
{
|
||||
if (_targetPos != absolute)
|
||||
{
|
||||
_targetPos = absolute;
|
||||
computeNewSpeed();
|
||||
// compute new n?
|
||||
}
|
||||
}
|
||||
|
||||
void AccelStepper::move(long relative)
|
||||
{
|
||||
moveTo(_currentPos + relative);
|
||||
}
|
||||
|
||||
// Implements steps according to the current step interval
|
||||
// You must call this at least once per step
|
||||
// returns true if a step occurred
|
||||
boolean AccelStepper::runSpeed()
|
||||
{
|
||||
// Dont do anything unless we actually have a step interval
|
||||
if (!_stepInterval)
|
||||
return false;
|
||||
|
||||
unsigned long time = micros();
|
||||
if (time - _lastStepTime >= _stepInterval)
|
||||
{
|
||||
if (_direction == DIRECTION_CW)
|
||||
{
|
||||
// Clockwise
|
||||
_currentPos += 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Anticlockwise
|
||||
_currentPos -= 1;
|
||||
}
|
||||
step(_currentPos);
|
||||
|
||||
_lastStepTime = time; // Caution: does not account for costs in step()
|
||||
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
long AccelStepper::distanceToGo()
|
||||
{
|
||||
return _targetPos - _currentPos;
|
||||
}
|
||||
|
||||
long AccelStepper::targetPosition()
|
||||
{
|
||||
return _targetPos;
|
||||
}
|
||||
|
||||
long AccelStepper::currentPosition()
|
||||
{
|
||||
return _currentPos;
|
||||
}
|
||||
|
||||
// Useful during initialisations or after initial positioning
|
||||
// Sets speed to 0
|
||||
void AccelStepper::setCurrentPosition(long position)
|
||||
{
|
||||
_targetPos = _currentPos = position;
|
||||
_n = 0;
|
||||
_stepInterval = 0;
|
||||
_speed = 0.0;
|
||||
}
|
||||
|
||||
void AccelStepper::computeNewSpeed()
|
||||
{
|
||||
long distanceTo = distanceToGo(); // +ve is clockwise from curent location
|
||||
|
||||
long stepsToStop = (long)((_speed * _speed) / (2.0 * _acceleration)); // Equation 16
|
||||
|
||||
if (distanceTo == 0 && stepsToStop <= 1)
|
||||
{
|
||||
// We are at the target and its time to stop
|
||||
_stepInterval = 0;
|
||||
_speed = 0.0;
|
||||
_n = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
if (distanceTo > 0)
|
||||
{
|
||||
// We are anticlockwise from the target
|
||||
// Need to go clockwise from here, maybe decelerate now
|
||||
if (_n > 0)
|
||||
{
|
||||
// Currently accelerating, need to decel now? Or maybe going the wrong way?
|
||||
if ((stepsToStop >= distanceTo) || _direction == DIRECTION_CCW)
|
||||
_n = -stepsToStop; // Start deceleration
|
||||
}
|
||||
else if (_n < 0)
|
||||
{
|
||||
// Currently decelerating, need to accel again?
|
||||
if ((stepsToStop < distanceTo) && _direction == DIRECTION_CW)
|
||||
_n = -_n; // Start accceleration
|
||||
}
|
||||
}
|
||||
else if (distanceTo < 0)
|
||||
{
|
||||
// We are clockwise from the target
|
||||
// Need to go anticlockwise from here, maybe decelerate
|
||||
if (_n > 0)
|
||||
{
|
||||
// Currently accelerating, need to decel now? Or maybe going the wrong way?
|
||||
if ((stepsToStop >= -distanceTo) || _direction == DIRECTION_CW)
|
||||
_n = -stepsToStop; // Start deceleration
|
||||
}
|
||||
else if (_n < 0)
|
||||
{
|
||||
// Currently decelerating, need to accel again?
|
||||
if ((stepsToStop < -distanceTo) && _direction == DIRECTION_CCW)
|
||||
_n = -_n; // Start accceleration
|
||||
}
|
||||
}
|
||||
|
||||
// Need to accelerate or decelerate
|
||||
if (_n == 0)
|
||||
{
|
||||
// First step from stopped
|
||||
_cn = _c0;
|
||||
_direction = (distanceTo > 0) ? DIRECTION_CW : DIRECTION_CCW;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Subsequent step. Works for accel (n is +_ve) and decel (n is -ve).
|
||||
_cn = _cn - ((2.0 * _cn) / ((4.0 * _n) + 1)); // Equation 13
|
||||
_cn = max(_cn, _cmin);
|
||||
}
|
||||
_n++;
|
||||
_stepInterval = _cn;
|
||||
_speed = 1000000.0 / _cn;
|
||||
if (_direction == DIRECTION_CCW)
|
||||
_speed = -_speed;
|
||||
|
||||
#if 0
|
||||
Serial.println(_speed);
|
||||
Serial.println(_acceleration);
|
||||
Serial.println(_cn);
|
||||
Serial.println(_c0);
|
||||
Serial.println(_n);
|
||||
Serial.println(_stepInterval);
|
||||
Serial.println(distanceTo);
|
||||
Serial.println(stepsToStop);
|
||||
Serial.println("-----");
|
||||
#endif
|
||||
}
|
||||
|
||||
// Run the motor to implement speed and acceleration in order to proceed to the target position
|
||||
// You must call this at least once per step, preferably in your main loop
|
||||
// If the motor is in the desired position, the cost is very small
|
||||
// returns true if the motor is still running to the target position.
|
||||
boolean AccelStepper::run()
|
||||
{
|
||||
if (runSpeed())
|
||||
computeNewSpeed();
|
||||
return _speed != 0.0 || distanceToGo() != 0;
|
||||
}
|
||||
|
||||
AccelStepper::AccelStepper(uint8_t interface, uint8_t pin1, uint8_t pin2, uint8_t pin3, uint8_t pin4, bool enable)
|
||||
{
|
||||
_interface = interface;
|
||||
_currentPos = 0;
|
||||
_targetPos = 0;
|
||||
_speed = 0.0;
|
||||
_maxSpeed = 1.0;
|
||||
_acceleration = 0.0;
|
||||
_sqrt_twoa = 1.0;
|
||||
_stepInterval = 0;
|
||||
_minPulseWidth = 1;
|
||||
_enablePin = 0xff;
|
||||
_lastStepTime = 0;
|
||||
_pin[0] = pin1;
|
||||
_pin[1] = pin2;
|
||||
_pin[2] = pin3;
|
||||
_pin[3] = pin4;
|
||||
_enableInverted = false;
|
||||
|
||||
// NEW
|
||||
_n = 0;
|
||||
_c0 = 0.0;
|
||||
_cn = 0.0;
|
||||
_cmin = 1.0;
|
||||
_direction = DIRECTION_CCW;
|
||||
|
||||
int i;
|
||||
for (i = 0; i < 4; i++)
|
||||
_pinInverted[i] = 0;
|
||||
if (enable)
|
||||
enableOutputs();
|
||||
// Some reasonable default
|
||||
setAcceleration(1);
|
||||
}
|
||||
|
||||
AccelStepper::AccelStepper(void (*forward)(), void (*backward)())
|
||||
{
|
||||
_interface = 0;
|
||||
_currentPos = 0;
|
||||
_targetPos = 0;
|
||||
_speed = 0.0;
|
||||
_maxSpeed = 1.0;
|
||||
_acceleration = 0.0;
|
||||
_sqrt_twoa = 1.0;
|
||||
_stepInterval = 0;
|
||||
_minPulseWidth = 1;
|
||||
_enablePin = 0xff;
|
||||
_lastStepTime = 0;
|
||||
_pin[0] = 0;
|
||||
_pin[1] = 0;
|
||||
_pin[2] = 0;
|
||||
_pin[3] = 0;
|
||||
_forward = forward;
|
||||
_backward = backward;
|
||||
|
||||
// NEW
|
||||
_n = 0;
|
||||
_c0 = 0.0;
|
||||
_cn = 0.0;
|
||||
_cmin = 1.0;
|
||||
_direction = DIRECTION_CCW;
|
||||
|
||||
int i;
|
||||
for (i = 0; i < 4; i++)
|
||||
_pinInverted[i] = 0;
|
||||
// Some reasonable default
|
||||
setAcceleration(1);
|
||||
}
|
||||
|
||||
void AccelStepper::setMaxSpeed(float speed)
|
||||
{
|
||||
if (speed < 0.0)
|
||||
speed = -speed;
|
||||
if (_maxSpeed != speed)
|
||||
{
|
||||
_maxSpeed = speed;
|
||||
_cmin = 1000000.0 / speed;
|
||||
// Recompute _n from current speed and adjust speed if accelerating or cruising
|
||||
if (_n > 0)
|
||||
{
|
||||
_n = (long)((_speed * _speed) / (2.0 * _acceleration)); // Equation 16
|
||||
computeNewSpeed();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
float AccelStepper::maxSpeed()
|
||||
{
|
||||
return _maxSpeed;
|
||||
}
|
||||
|
||||
void AccelStepper::setAcceleration(float acceleration)
|
||||
{
|
||||
if (acceleration == 0.0)
|
||||
return;
|
||||
if (acceleration < 0.0)
|
||||
acceleration = -acceleration;
|
||||
if (_acceleration != acceleration)
|
||||
{
|
||||
// Recompute _n per Equation 17
|
||||
_n = _n * (_acceleration / acceleration);
|
||||
// New c0 per Equation 7, with correction per Equation 15
|
||||
_c0 = 0.676 * sqrt(2.0 / acceleration) * 1000000.0; // Equation 15
|
||||
_acceleration = acceleration;
|
||||
computeNewSpeed();
|
||||
}
|
||||
}
|
||||
|
||||
void AccelStepper::setSpeed(float speed)
|
||||
{
|
||||
if (speed == _speed)
|
||||
return;
|
||||
speed = constrain(speed, -_maxSpeed, _maxSpeed);
|
||||
if (speed == 0.0)
|
||||
_stepInterval = 0;
|
||||
else
|
||||
{
|
||||
_stepInterval = fabs(1000000.0 / speed);
|
||||
_direction = (speed > 0.0) ? DIRECTION_CW : DIRECTION_CCW;
|
||||
}
|
||||
_speed = speed;
|
||||
}
|
||||
|
||||
float AccelStepper::speed()
|
||||
{
|
||||
return _speed;
|
||||
}
|
||||
|
||||
// Subclasses can override
|
||||
void AccelStepper::step(long step)
|
||||
{
|
||||
switch (_interface)
|
||||
{
|
||||
case FUNCTION:
|
||||
step0(step);
|
||||
break;
|
||||
|
||||
case DRIVER:
|
||||
step1(step);
|
||||
break;
|
||||
|
||||
case FULL2WIRE:
|
||||
step2(step);
|
||||
break;
|
||||
|
||||
case FULL3WIRE:
|
||||
step3(step);
|
||||
break;
|
||||
|
||||
case FULL4WIRE:
|
||||
step4(step);
|
||||
break;
|
||||
|
||||
case HALF3WIRE:
|
||||
step6(step);
|
||||
break;
|
||||
|
||||
case HALF4WIRE:
|
||||
step8(step);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// You might want to override this to implement eg serial output
|
||||
// bit 0 of the mask corresponds to _pin[0]
|
||||
// bit 1 of the mask corresponds to _pin[1]
|
||||
// ....
|
||||
void AccelStepper::setOutputPins(uint8_t mask)
|
||||
{
|
||||
uint8_t numpins = 2;
|
||||
if (_interface == FULL4WIRE || _interface == HALF4WIRE)
|
||||
numpins = 4;
|
||||
else if (_interface == FULL3WIRE || _interface == HALF3WIRE)
|
||||
numpins = 3;
|
||||
uint8_t i;
|
||||
for (i = 0; i < numpins; i++)
|
||||
digitalWrite(_pin[i], (mask & (1 << i)) ? (HIGH ^ _pinInverted[i]) : (LOW ^ _pinInverted[i]));
|
||||
}
|
||||
|
||||
// 0 pin step function (ie for functional usage)
|
||||
void AccelStepper::step0(long step)
|
||||
{
|
||||
(void)(step); // Unused
|
||||
if (_speed > 0)
|
||||
_forward();
|
||||
else
|
||||
_backward();
|
||||
}
|
||||
|
||||
// 1 pin step function (ie for stepper drivers)
|
||||
// This is passed the current step number (0 to 7)
|
||||
// Subclasses can override
|
||||
void AccelStepper::step1(long step)
|
||||
{
|
||||
(void)(step); // Unused
|
||||
|
||||
// _pin[0] is step, _pin[1] is direction
|
||||
setOutputPins(_direction ? 0b10 : 0b00); // Set direction first else get rogue pulses
|
||||
setOutputPins(_direction ? 0b11 : 0b01); // step HIGH
|
||||
// Caution 200ns setup time
|
||||
// Delay the minimum allowed pulse width
|
||||
delayMicroseconds(_minPulseWidth);
|
||||
setOutputPins(_direction ? 0b10 : 0b00); // step LOW
|
||||
}
|
||||
|
||||
|
||||
// 2 pin step function
|
||||
// This is passed the current step number (0 to 7)
|
||||
// Subclasses can override
|
||||
void AccelStepper::step2(long step)
|
||||
{
|
||||
switch (step & 0x3)
|
||||
{
|
||||
case 0: /* 01 */
|
||||
setOutputPins(0b10);
|
||||
break;
|
||||
|
||||
case 1: /* 11 */
|
||||
setOutputPins(0b11);
|
||||
break;
|
||||
|
||||
case 2: /* 10 */
|
||||
setOutputPins(0b01);
|
||||
break;
|
||||
|
||||
case 3: /* 00 */
|
||||
setOutputPins(0b00);
|
||||
break;
|
||||
}
|
||||
}
|
||||
// 3 pin step function
|
||||
// This is passed the current step number (0 to 7)
|
||||
// Subclasses can override
|
||||
void AccelStepper::step3(long step)
|
||||
{
|
||||
switch (step % 3)
|
||||
{
|
||||
case 0: // 100
|
||||
setOutputPins(0b100);
|
||||
break;
|
||||
|
||||
case 1: // 001
|
||||
setOutputPins(0b001);
|
||||
break;
|
||||
|
||||
case 2: //010
|
||||
setOutputPins(0b010);
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// 4 pin step function for half stepper
|
||||
// This is passed the current step number (0 to 7)
|
||||
// Subclasses can override
|
||||
void AccelStepper::step4(long step)
|
||||
{
|
||||
switch (step & 0x3)
|
||||
{
|
||||
case 0: // 1010
|
||||
setOutputPins(0b0101);
|
||||
break;
|
||||
|
||||
case 1: // 0110
|
||||
setOutputPins(0b0110);
|
||||
break;
|
||||
|
||||
case 2: //0101
|
||||
setOutputPins(0b1010);
|
||||
break;
|
||||
|
||||
case 3: //1001
|
||||
setOutputPins(0b1001);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// 3 pin half step function
|
||||
// This is passed the current step number (0 to 7)
|
||||
// Subclasses can override
|
||||
void AccelStepper::step6(long step)
|
||||
{
|
||||
switch (step % 6)
|
||||
{
|
||||
case 0: // 100
|
||||
setOutputPins(0b100);
|
||||
break;
|
||||
|
||||
case 1: // 101
|
||||
setOutputPins(0b101);
|
||||
break;
|
||||
|
||||
case 2: // 001
|
||||
setOutputPins(0b001);
|
||||
break;
|
||||
|
||||
case 3: // 011
|
||||
setOutputPins(0b011);
|
||||
break;
|
||||
|
||||
case 4: // 010
|
||||
setOutputPins(0b010);
|
||||
break;
|
||||
|
||||
case 5: // 011
|
||||
setOutputPins(0b110);
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// 4 pin half step function
|
||||
// This is passed the current step number (0 to 7)
|
||||
// Subclasses can override
|
||||
void AccelStepper::step8(long step)
|
||||
{
|
||||
switch (step & 0x7)
|
||||
{
|
||||
case 0: // 1000
|
||||
setOutputPins(0b0001);
|
||||
break;
|
||||
|
||||
case 1: // 1010
|
||||
setOutputPins(0b0101);
|
||||
break;
|
||||
|
||||
case 2: // 0010
|
||||
setOutputPins(0b0100);
|
||||
break;
|
||||
|
||||
case 3: // 0110
|
||||
setOutputPins(0b0110);
|
||||
break;
|
||||
|
||||
case 4: // 0100
|
||||
setOutputPins(0b0010);
|
||||
break;
|
||||
|
||||
case 5: //0101
|
||||
setOutputPins(0b1010);
|
||||
break;
|
||||
|
||||
case 6: // 0001
|
||||
setOutputPins(0b1000);
|
||||
break;
|
||||
|
||||
case 7: //1001
|
||||
setOutputPins(0b1001);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Prevents power consumption on the outputs
|
||||
void AccelStepper::disableOutputs()
|
||||
{
|
||||
if (! _interface) return;
|
||||
|
||||
setOutputPins(0); // Handles inversion automatically
|
||||
if (_enablePin != 0xff)
|
||||
{
|
||||
pinMode(_enablePin, OUTPUT);
|
||||
digitalWrite(_enablePin, LOW ^ _enableInverted);
|
||||
}
|
||||
}
|
||||
|
||||
void AccelStepper::enableOutputs()
|
||||
{
|
||||
if (! _interface)
|
||||
return;
|
||||
|
||||
pinMode(_pin[0], OUTPUT);
|
||||
pinMode(_pin[1], OUTPUT);
|
||||
if (_interface == FULL4WIRE || _interface == HALF4WIRE)
|
||||
{
|
||||
pinMode(_pin[2], OUTPUT);
|
||||
pinMode(_pin[3], OUTPUT);
|
||||
}
|
||||
else if (_interface == FULL3WIRE || _interface == HALF3WIRE)
|
||||
{
|
||||
pinMode(_pin[2], OUTPUT);
|
||||
}
|
||||
|
||||
if (_enablePin != 0xff)
|
||||
{
|
||||
pinMode(_enablePin, OUTPUT);
|
||||
digitalWrite(_enablePin, HIGH ^ _enableInverted);
|
||||
}
|
||||
}
|
||||
|
||||
void AccelStepper::setMinPulseWidth(unsigned int minWidth)
|
||||
{
|
||||
_minPulseWidth = minWidth;
|
||||
}
|
||||
|
||||
void AccelStepper::setEnablePin(uint8_t enablePin)
|
||||
{
|
||||
_enablePin = enablePin;
|
||||
|
||||
// This happens after construction, so init pin now.
|
||||
if (_enablePin != 0xff)
|
||||
{
|
||||
pinMode(_enablePin, OUTPUT);
|
||||
digitalWrite(_enablePin, HIGH ^ _enableInverted);
|
||||
}
|
||||
}
|
||||
|
||||
void AccelStepper::setPinsInverted(bool directionInvert, bool stepInvert, bool enableInvert)
|
||||
{
|
||||
_pinInverted[0] = stepInvert;
|
||||
_pinInverted[1] = directionInvert;
|
||||
_enableInverted = enableInvert;
|
||||
}
|
||||
|
||||
void AccelStepper::setPinsInverted(bool pin1Invert, bool pin2Invert, bool pin3Invert, bool pin4Invert, bool enableInvert)
|
||||
{
|
||||
_pinInverted[0] = pin1Invert;
|
||||
_pinInverted[1] = pin2Invert;
|
||||
_pinInverted[2] = pin3Invert;
|
||||
_pinInverted[3] = pin4Invert;
|
||||
_enableInverted = enableInvert;
|
||||
}
|
||||
|
||||
// Blocks until the target position is reached and stopped
|
||||
void AccelStepper::runToPosition()
|
||||
{
|
||||
while (run())
|
||||
;
|
||||
}
|
||||
|
||||
boolean AccelStepper::runSpeedToPosition()
|
||||
{
|
||||
if (_targetPos == _currentPos)
|
||||
return false;
|
||||
if (_targetPos >_currentPos)
|
||||
_direction = DIRECTION_CW;
|
||||
else
|
||||
_direction = DIRECTION_CCW;
|
||||
return runSpeed();
|
||||
}
|
||||
|
||||
// Blocks until the new target position is reached
|
||||
void AccelStepper::runToNewPosition(long position)
|
||||
{
|
||||
moveTo(position);
|
||||
runToPosition();
|
||||
}
|
||||
|
||||
void AccelStepper::stop()
|
||||
{
|
||||
if (_speed != 0.0)
|
||||
{
|
||||
long stepsToStop = (long)((_speed * _speed) / (2.0 * _acceleration)) + 1; // Equation 16 (+integer rounding)
|
||||
if (_speed > 0)
|
||||
move(stepsToStop);
|
||||
else
|
||||
move(-stepsToStop);
|
||||
}
|
||||
}
|
||||
|
||||
bool AccelStepper::isRunning()
|
||||
{
|
||||
return !(_speed == 0.0 && _targetPos == _currentPos);
|
||||
}
|
||||
734
arduino-cli/libraries/AccelStepper/AccelStepper.h
Normal file
734
arduino-cli/libraries/AccelStepper/AccelStepper.h
Normal file
@@ -0,0 +1,734 @@
|
||||
// AccelStepper.h
|
||||
//
|
||||
/// \mainpage AccelStepper library for Arduino
|
||||
///
|
||||
/// This is the Arduino AccelStepper library.
|
||||
/// It provides an object-oriented interface for 2, 3 or 4 pin stepper motors and motor drivers.
|
||||
///
|
||||
/// The standard Arduino IDE includes the Stepper library
|
||||
/// (http://arduino.cc/en/Reference/Stepper) for stepper motors. It is
|
||||
/// perfectly adequate for simple, single motor applications.
|
||||
///
|
||||
/// AccelStepper significantly improves on the standard Arduino Stepper library in several ways:
|
||||
/// \li Supports acceleration and deceleration
|
||||
/// \li Supports multiple simultaneous steppers, with independent concurrent stepping on each stepper
|
||||
/// \li API functions never delay() or block
|
||||
/// \li Supports 2, 3 and 4 wire steppers, plus 3 and 4 wire half steppers.
|
||||
/// \li Supports alternate stepping functions to enable support of AFMotor (https://github.com/adafruit/Adafruit-Motor-Shield-library)
|
||||
/// \li Supports stepper drivers such as the Sparkfun EasyDriver (based on 3967 driver chip)
|
||||
/// \li Very slow speeds are supported
|
||||
/// \li Extensive API
|
||||
/// \li Subclass support
|
||||
///
|
||||
/// The latest version of this documentation can be downloaded from
|
||||
/// http://www.airspayce.com/mikem/arduino/AccelStepper
|
||||
/// The version of the package that this documentation refers to can be downloaded
|
||||
/// from http://www.airspayce.com/mikem/arduino/AccelStepper/AccelStepper-1.59.zip
|
||||
///
|
||||
/// Example Arduino programs are included to show the main modes of use.
|
||||
///
|
||||
/// You can also find online help and discussion at http://groups.google.com/group/accelstepper
|
||||
/// Please use that group for all questions and discussions on this topic.
|
||||
/// Do not contact the author directly, unless it is to discuss commercial licensing.
|
||||
/// Before asking a question or reporting a bug, please read
|
||||
/// - http://en.wikipedia.org/wiki/Wikipedia:Reference_desk/How_to_ask_a_software_question
|
||||
/// - http://www.catb.org/esr/faqs/smart-questions.html
|
||||
/// - http://www.chiark.greenend.org.uk/~shgtatham/bugs.html
|
||||
///
|
||||
/// Tested on Arduino Diecimila and Mega with arduino-0018 & arduino-0021
|
||||
/// on OpenSuSE 11.1 and avr-libc-1.6.1-1.15,
|
||||
/// cross-avr-binutils-2.19-9.1, cross-avr-gcc-4.1.3_20080612-26.5.
|
||||
/// Tested on Teensy http://www.pjrc.com/teensy including Teensy 3.1 built using Arduino IDE 1.0.5 with
|
||||
/// teensyduino addon 1.18 and later.
|
||||
///
|
||||
/// \par Installation
|
||||
///
|
||||
/// Install in the usual way: unzip the distribution zip file to the libraries
|
||||
/// sub-folder of your sketchbook.
|
||||
///
|
||||
/// \par Theory
|
||||
///
|
||||
/// This code uses speed calculations as described in
|
||||
/// "Generate stepper-motor speed profiles in real time" by David Austin
|
||||
/// http://fab.cba.mit.edu/classes/MIT/961.09/projects/i0/Stepper_Motor_Speed_Profile.pdf or
|
||||
/// http://www.embedded.com/design/mcus-processors-and-socs/4006438/Generate-stepper-motor-speed-profiles-in-real-time or
|
||||
/// http://web.archive.org/web/20140705143928/http://fab.cba.mit.edu/classes/MIT/961.09/projects/i0/Stepper_Motor_Speed_Profile.pdf
|
||||
/// with the exception that AccelStepper uses steps per second rather than radians per second
|
||||
/// (because we dont know the step angle of the motor)
|
||||
/// An initial step interval is calculated for the first step, based on the desired acceleration
|
||||
/// On subsequent steps, shorter step intervals are calculated based
|
||||
/// on the previous step until max speed is achieved.
|
||||
///
|
||||
/// \par Adafruit Motor Shield V2
|
||||
///
|
||||
/// The included examples AFMotor_* are for Adafruit Motor Shield V1 and do not work with Adafruit Motor Shield V2.
|
||||
/// See https://github.com/adafruit/Adafruit_Motor_Shield_V2_Library for examples that work with Adafruit Motor Shield V2.
|
||||
///
|
||||
/// \par Donations
|
||||
///
|
||||
/// This library is offered under a free GPL license for those who want to use it that way.
|
||||
/// We try hard to keep it up to date, fix bugs
|
||||
/// and to provide free support. If this library has helped you save time or money, please consider donating at
|
||||
/// http://www.airspayce.com or here:
|
||||
///
|
||||
/// \htmlonly <form action="https://www.paypal.com/cgi-bin/webscr" method="post"><input type="hidden" name="cmd" value="_donations" /> <input type="hidden" name="business" value="mikem@airspayce.com" /> <input type="hidden" name="lc" value="AU" /> <input type="hidden" name="item_name" value="Airspayce" /> <input type="hidden" name="item_number" value="AccelStepper" /> <input type="hidden" name="currency_code" value="USD" /> <input type="hidden" name="bn" value="PP-DonationsBF:btn_donateCC_LG.gif:NonHosted" /> <input type="image" alt="PayPal — The safer, easier way to pay online." name="submit" src="https://www.paypalobjects.com/en_AU/i/btn/btn_donateCC_LG.gif" /> <img alt="" src="https://www.paypalobjects.com/en_AU/i/scr/pixel.gif" width="1" height="1" border="0" /></form> \endhtmlonly
|
||||
///
|
||||
/// \par Trademarks
|
||||
///
|
||||
/// AccelStepper is a trademark of AirSpayce Pty Ltd. The AccelStepper mark was first used on April 26 2010 for
|
||||
/// international trade, and is used only in relation to motor control hardware and software.
|
||||
/// It is not to be confused with any other similar marks covering other goods and services.
|
||||
///
|
||||
/// \par Copyright
|
||||
///
|
||||
/// This software is Copyright (C) 2010-2018 Mike McCauley. Use is subject to license
|
||||
/// conditions. The main licensing options available are GPL V2 or Commercial:
|
||||
///
|
||||
/// \par Open Source Licensing GPL V2
|
||||
/// This is the appropriate option if you want to share the source code of your
|
||||
/// application with everyone you distribute it to, and you also want to give them
|
||||
/// the right to share who uses it. If you wish to use this software under Open
|
||||
/// Source Licensing, you must contribute all your source code to the open source
|
||||
/// community in accordance with the GPL Version 2 when your application is
|
||||
/// distributed. See https://www.gnu.org/licenses/gpl-2.0.html
|
||||
///
|
||||
/// \par Commercial Licensing
|
||||
/// This is the appropriate option if you are creating proprietary applications
|
||||
/// and you are not prepared to distribute and share the source code of your
|
||||
/// application. To purchase a commercial license, contact info@airspayce.com
|
||||
///
|
||||
/// \par Revision History
|
||||
/// \version 1.0 Initial release
|
||||
///
|
||||
/// \version 1.1 Added speed() function to get the current speed.
|
||||
/// \version 1.2 Added runSpeedToPosition() submitted by Gunnar Arndt.
|
||||
/// \version 1.3 Added support for stepper drivers (ie with Step and Direction inputs) with _pins == 1
|
||||
/// \version 1.4 Added functional contructor to support AFMotor, contributed by Limor, with example sketches.
|
||||
/// \version 1.5 Improvements contributed by Peter Mousley: Use of microsecond steps and other speed improvements
|
||||
/// to increase max stepping speed to about 4kHz. New option for user to set the min allowed pulse width.
|
||||
/// Added checks for already running at max speed and skip further calcs if so.
|
||||
/// \version 1.6 Fixed a problem with wrapping of microsecond stepping that could cause stepping to hang.
|
||||
/// Reported by Sandy Noble.
|
||||
/// Removed redundant _lastRunTime member.
|
||||
/// \version 1.7 Fixed a bug where setCurrentPosition() did not always work as expected.
|
||||
/// Reported by Peter Linhart.
|
||||
/// \version 1.8 Added support for 4 pin half-steppers, requested by Harvey Moon
|
||||
/// \version 1.9 setCurrentPosition() now also sets motor speed to 0.
|
||||
/// \version 1.10 Builds on Arduino 1.0
|
||||
/// \version 1.11 Improvments from Michael Ellison:
|
||||
/// Added optional enable line support for stepper drivers
|
||||
/// Added inversion for step/direction/enable lines for stepper drivers
|
||||
/// \version 1.12 Announce Google Group
|
||||
/// \version 1.13 Improvements to speed calculation. Cost of calculation is now less in the worst case,
|
||||
/// and more or less constant in all cases. This should result in slightly beter high speed performance, and
|
||||
/// reduce anomalous speed glitches when other steppers are accelerating.
|
||||
/// However, its hard to see how to replace the sqrt() required at the very first step from 0 speed.
|
||||
/// \version 1.14 Fixed a problem with compiling under arduino 0021 reported by EmbeddedMan
|
||||
/// \version 1.15 Fixed a problem with runSpeedToPosition which did not correctly handle
|
||||
/// running backwards to a smaller target position. Added examples
|
||||
/// \version 1.16 Fixed some cases in the code where abs() was used instead of fabs().
|
||||
/// \version 1.17 Added example ProportionalControl
|
||||
/// \version 1.18 Fixed a problem: If one calls the funcion runSpeed() when Speed is zero, it makes steps
|
||||
/// without counting. reported by Friedrich, Klappenbach.
|
||||
/// \version 1.19 Added MotorInterfaceType and symbolic names for the number of pins to use
|
||||
/// for the motor interface. Updated examples to suit.
|
||||
/// Replaced individual pin assignment variables _pin1, _pin2 etc with array _pin[4].
|
||||
/// _pins member changed to _interface.
|
||||
/// Added _pinInverted array to simplify pin inversion operations.
|
||||
/// Added new function setOutputPins() which sets the motor output pins.
|
||||
/// It can be overridden in order to provide, say, serial output instead of parallel output
|
||||
/// Some refactoring and code size reduction.
|
||||
/// \version 1.20 Improved documentation and examples to show need for correctly
|
||||
/// specifying AccelStepper::FULL4WIRE and friends.
|
||||
/// \version 1.21 Fixed a problem where desiredSpeed could compute the wrong step acceleration
|
||||
/// when _speed was small but non-zero. Reported by Brian Schmalz.
|
||||
/// Precompute sqrt_twoa to improve performance and max possible stepping speed
|
||||
/// \version 1.22 Added Bounce.pde example
|
||||
/// Fixed a problem where calling moveTo(), setMaxSpeed(), setAcceleration() more
|
||||
/// frequently than the step time, even
|
||||
/// with the same values, would interfere with speed calcs. Now a new speed is computed
|
||||
/// only if there was a change in the set value. Reported by Brian Schmalz.
|
||||
/// \version 1.23 Rewrite of the speed algorithms in line with
|
||||
/// http://fab.cba.mit.edu/classes/MIT/961.09/projects/i0/Stepper_Motor_Speed_Profile.pdf
|
||||
/// Now expect smoother and more linear accelerations and decelerations. The desiredSpeed()
|
||||
/// function was removed.
|
||||
/// \version 1.24 Fixed a problem introduced in 1.23: with runToPosition, which did never returned
|
||||
/// \version 1.25 Now ignore attempts to set acceleration to 0.0
|
||||
/// \version 1.26 Fixed a problem where certina combinations of speed and accelration could cause
|
||||
/// oscillation about the target position.
|
||||
/// \version 1.27 Added stop() function to stop as fast as possible with current acceleration parameters.
|
||||
/// Also added new Quickstop example showing its use.
|
||||
/// \version 1.28 Fixed another problem where certain combinations of speed and acceleration could cause
|
||||
/// oscillation about the target position.
|
||||
/// Added support for 3 wire full and half steppers such as Hard Disk Drive spindle.
|
||||
/// Contributed by Yuri Ivatchkovitch.
|
||||
/// \version 1.29 Fixed a problem that could cause a DRIVER stepper to continually step
|
||||
/// with some sketches. Reported by Vadim.
|
||||
/// \version 1.30 Fixed a problem that could cause stepper to back up a few steps at the end of
|
||||
/// accelerated travel with certain speeds. Reported and patched by jolo.
|
||||
/// \version 1.31 Updated author and distribution location details to airspayce.com
|
||||
/// \version 1.32 Fixed a problem with enableOutputs() and setEnablePin on Arduino Due that
|
||||
/// prevented the enable pin changing stae correctly. Reported by Duane Bishop.
|
||||
/// \version 1.33 Fixed an error in example AFMotor_ConstantSpeed.pde did not setMaxSpeed();
|
||||
/// Fixed a problem that caused incorrect pin sequencing of FULL3WIRE and HALF3WIRE.
|
||||
/// Unfortunately this meant changing the signature for all step*() functions.
|
||||
/// Added example MotorShield, showing how to use AdaFruit Motor Shield to control
|
||||
/// a 3 phase motor such as a HDD spindle motor (and without using the AFMotor library.
|
||||
/// \version 1.34 Added setPinsInverted(bool pin1Invert, bool pin2Invert, bool pin3Invert, bool pin4Invert, bool enableInvert)
|
||||
/// to allow inversion of 2, 3 and 4 wire stepper pins. Requested by Oleg.
|
||||
/// \version 1.35 Removed default args from setPinsInverted(bool, bool, bool, bool, bool) to prevent ambiguity with
|
||||
/// setPinsInverted(bool, bool, bool). Reported by Mac Mac.
|
||||
/// \version 1.36 Changed enableOutputs() and disableOutputs() to be virtual so can be overridden.
|
||||
/// Added new optional argument 'enable' to constructor, which allows you toi disable the
|
||||
/// automatic enabling of outputs at construction time. Suggested by Guido.
|
||||
/// \version 1.37 Fixed a problem with step1 that could cause a rogue step in the
|
||||
/// wrong direction (or not,
|
||||
/// depending on the setup-time requirements of the connected hardware).
|
||||
/// Reported by Mark Tillotson.
|
||||
/// \version 1.38 run() function incorrectly always returned true. Updated function and doc so it returns true
|
||||
/// if the motor is still running to the target position.
|
||||
/// \version 1.39 Updated typos in keywords.txt, courtesey Jon Magill.
|
||||
/// \version 1.40 Updated documentation, including testing on Teensy 3.1
|
||||
/// \version 1.41 Fixed an error in the acceleration calculations, resulting in acceleration of haldf the intended value
|
||||
/// \version 1.42 Improved support for FULL3WIRE and HALF3WIRE output pins. These changes were in Yuri's original
|
||||
/// contribution but did not make it into production.<br>
|
||||
/// \version 1.43 Added DualMotorShield example. Shows how to use AccelStepper to control 2 x 2 phase steppers using the
|
||||
/// Itead Studio Arduino Dual Stepper Motor Driver Shield model IM120417015.<br>
|
||||
/// \version 1.44 examples/DualMotorShield/DualMotorShield.ino examples/DualMotorShield/DualMotorShield.pde
|
||||
/// was missing from the distribution.<br>
|
||||
/// \version 1.45 Fixed a problem where if setAcceleration was not called, there was no default
|
||||
/// acceleration. Reported by Michael Newman.<br>
|
||||
/// \version 1.45 Fixed inaccuracy in acceleration rate by using Equation 15, suggested by Sebastian Gracki.<br>
|
||||
/// Performance improvements in runSpeed suggested by Jaakko Fagerlund.<br>
|
||||
/// \version 1.46 Fixed error in documentation for runToPosition().
|
||||
/// Reinstated time calculations in runSpeed() since new version is reported
|
||||
/// not to work correctly under some circumstances. Reported by Oleg V Gavva.<br>
|
||||
/// \version 1.48 2015-08-25
|
||||
/// Added new class MultiStepper that can manage multiple AccelSteppers,
|
||||
/// and cause them all to move
|
||||
/// to selected positions at such a (constant) speed that they all arrive at their
|
||||
/// target position at the same time. Suitable for X-Y flatbeds etc.<br>
|
||||
/// Added new method maxSpeed() to AccelStepper to return the currently configured maxSpeed.<br>
|
||||
/// \version 1.49 2016-01-02
|
||||
/// Testing with VID28 series instrument stepper motors and EasyDriver.
|
||||
/// OK, although with light pointers
|
||||
/// and slow speeds like 180 full steps per second the motor movement can be erratic,
|
||||
/// probably due to some mechanical resonance. Best to accelerate through this speed.<br>
|
||||
/// Added isRunning().<br>
|
||||
/// \version 1.50 2016-02-25
|
||||
/// AccelStepper::disableOutputs now sets the enable pion to OUTPUT mode if the enable pin is defined.
|
||||
/// Patch from Piet De Jong.<br>
|
||||
/// Added notes about the fact that AFMotor_* examples do not work with Adafruit Motor Shield V2.<br>
|
||||
/// \version 1.51 2016-03-24
|
||||
/// Fixed a problem reported by gregor: when resetting the stepper motor position using setCurrentPosition() the
|
||||
/// stepper speed is reset by setting _stepInterval to 0, but _speed is not
|
||||
/// reset. this results in the stepper motor not starting again when calling
|
||||
/// setSpeed() with the same speed the stepper was set to before.
|
||||
/// \version 1.52 2016-08-09
|
||||
/// Added MultiStepper to keywords.txt.
|
||||
/// Improvements to efficiency of AccelStepper::runSpeed() as suggested by David Grayson.
|
||||
/// Improvements to speed accuracy as suggested by David Grayson.
|
||||
/// \version 1.53 2016-08-14
|
||||
/// Backed out Improvements to speed accuracy from 1.52 as it did not work correctly.
|
||||
/// \version 1.54 2017-01-24
|
||||
/// Fixed some warnings about unused arguments.
|
||||
/// \version 1.55 2017-01-25
|
||||
/// Fixed another warning in MultiStepper.cpp
|
||||
/// \version 1.56 2017-02-03
|
||||
/// Fixed minor documentation error with DIRECTION_CCW and DIRECTION_CW. Reported by David Mutterer.
|
||||
/// Added link to Binpress commercial license purchasing.
|
||||
/// \version 1.57 2017-03-28
|
||||
/// _direction moved to protected at the request of Rudy Ercek.
|
||||
/// setMaxSpeed() and setAcceleration() now correct negative values to be positive.
|
||||
/// \version 1.58 2018-04-13
|
||||
/// Add initialisation for _enableInverted in constructor.
|
||||
/// \version 1.59 2018-08-28
|
||||
/// Update commercial licensing, remove binpress.
|
||||
///
|
||||
/// \author Mike McCauley (mikem@airspayce.com) DO NOT CONTACT THE AUTHOR DIRECTLY: USE THE LISTS
|
||||
// Copyright (C) 2009-2013 Mike McCauley
|
||||
// $Id: AccelStepper.h,v 1.27 2016/08/14 10:26:54 mikem Exp mikem $
|
||||
|
||||
#ifndef AccelStepper_h
|
||||
#define AccelStepper_h
|
||||
|
||||
#include <stdlib.h>
|
||||
#if ARDUINO >= 100
|
||||
#include <Arduino.h>
|
||||
#else
|
||||
#include <WProgram.h>
|
||||
#include <wiring.h>
|
||||
#endif
|
||||
|
||||
// These defs cause trouble on some versions of Arduino
|
||||
#undef round
|
||||
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
/// \class AccelStepper AccelStepper.h <AccelStepper.h>
|
||||
/// \brief Support for stepper motors with acceleration etc.
|
||||
///
|
||||
/// This defines a single 2 or 4 pin stepper motor, or stepper moter with fdriver chip, with optional
|
||||
/// acceleration, deceleration, absolute positioning commands etc. Multiple
|
||||
/// simultaneous steppers are supported, all moving
|
||||
/// at different speeds and accelerations.
|
||||
///
|
||||
/// \par Operation
|
||||
/// This module operates by computing a step time in microseconds. The step
|
||||
/// time is recomputed after each step and after speed and acceleration
|
||||
/// parameters are changed by the caller. The time of each step is recorded in
|
||||
/// microseconds. The run() function steps the motor once if a new step is due.
|
||||
/// The run() function must be called frequently until the motor is in the
|
||||
/// desired position, after which time run() will do nothing.
|
||||
///
|
||||
/// \par Positioning
|
||||
/// Positions are specified by a signed long integer. At
|
||||
/// construction time, the current position of the motor is consider to be 0. Positive
|
||||
/// positions are clockwise from the initial position; negative positions are
|
||||
/// anticlockwise. The current position can be altered for instance after
|
||||
/// initialization positioning.
|
||||
///
|
||||
/// \par Caveats
|
||||
/// This is an open loop controller: If the motor stalls or is oversped,
|
||||
/// AccelStepper will not have a correct
|
||||
/// idea of where the motor really is (since there is no feedback of the motor's
|
||||
/// real position. We only know where we _think_ it is, relative to the
|
||||
/// initial starting point).
|
||||
///
|
||||
/// \par Performance
|
||||
/// The fastest motor speed that can be reliably supported is about 4000 steps per
|
||||
/// second at a clock frequency of 16 MHz on Arduino such as Uno etc.
|
||||
/// Faster processors can support faster stepping speeds.
|
||||
/// However, any speed less than that
|
||||
/// down to very slow speeds (much less than one per second) are also supported,
|
||||
/// provided the run() function is called frequently enough to step the motor
|
||||
/// whenever required for the speed set.
|
||||
/// Calling setAcceleration() is expensive,
|
||||
/// since it requires a square root to be calculated.
|
||||
///
|
||||
/// Gregor Christandl reports that with an Arduino Due and a simple test program,
|
||||
/// he measured 43163 steps per second using runSpeed(),
|
||||
/// and 16214 steps per second using run();
|
||||
class AccelStepper
|
||||
{
|
||||
public:
|
||||
/// \brief Symbolic names for number of pins.
|
||||
/// Use this in the pins argument the AccelStepper constructor to
|
||||
/// provide a symbolic name for the number of pins
|
||||
/// to use.
|
||||
typedef enum
|
||||
{
|
||||
FUNCTION = 0, ///< Use the functional interface, implementing your own driver functions (internal use only)
|
||||
DRIVER = 1, ///< Stepper Driver, 2 driver pins required
|
||||
FULL2WIRE = 2, ///< 2 wire stepper, 2 motor pins required
|
||||
FULL3WIRE = 3, ///< 3 wire stepper, such as HDD spindle, 3 motor pins required
|
||||
FULL4WIRE = 4, ///< 4 wire full stepper, 4 motor pins required
|
||||
HALF3WIRE = 6, ///< 3 wire half stepper, such as HDD spindle, 3 motor pins required
|
||||
HALF4WIRE = 8 ///< 4 wire half stepper, 4 motor pins required
|
||||
} MotorInterfaceType;
|
||||
|
||||
/// Constructor. You can have multiple simultaneous steppers, all moving
|
||||
/// at different speeds and accelerations, provided you call their run()
|
||||
/// functions at frequent enough intervals. Current Position is set to 0, target
|
||||
/// position is set to 0. MaxSpeed and Acceleration default to 1.0.
|
||||
/// The motor pins will be initialised to OUTPUT mode during the
|
||||
/// constructor by a call to enableOutputs().
|
||||
/// \param[in] interface Number of pins to interface to. Integer values are
|
||||
/// supported, but it is preferred to use the \ref MotorInterfaceType symbolic names.
|
||||
/// AccelStepper::DRIVER (1) means a stepper driver (with Step and Direction pins).
|
||||
/// If an enable line is also needed, call setEnablePin() after construction.
|
||||
/// You may also invert the pins using setPinsInverted().
|
||||
/// AccelStepper::FULL2WIRE (2) means a 2 wire stepper (2 pins required).
|
||||
/// AccelStepper::FULL3WIRE (3) means a 3 wire stepper, such as HDD spindle (3 pins required).
|
||||
/// AccelStepper::FULL4WIRE (4) means a 4 wire stepper (4 pins required).
|
||||
/// AccelStepper::HALF3WIRE (6) means a 3 wire half stepper, such as HDD spindle (3 pins required)
|
||||
/// AccelStepper::HALF4WIRE (8) means a 4 wire half stepper (4 pins required)
|
||||
/// Defaults to AccelStepper::FULL4WIRE (4) pins.
|
||||
/// \param[in] pin1 Arduino digital pin number for motor pin 1. Defaults
|
||||
/// to pin 2. For a AccelStepper::DRIVER (interface==1),
|
||||
/// this is the Step input to the driver. Low to high transition means to step)
|
||||
/// \param[in] pin2 Arduino digital pin number for motor pin 2. Defaults
|
||||
/// to pin 3. For a AccelStepper::DRIVER (interface==1),
|
||||
/// this is the Direction input the driver. High means forward.
|
||||
/// \param[in] pin3 Arduino digital pin number for motor pin 3. Defaults
|
||||
/// to pin 4.
|
||||
/// \param[in] pin4 Arduino digital pin number for motor pin 4. Defaults
|
||||
/// to pin 5.
|
||||
/// \param[in] enable If this is true (the default), enableOutputs() will be called to enable
|
||||
/// the output pins at construction time.
|
||||
AccelStepper(uint8_t interface = AccelStepper::FULL4WIRE, uint8_t pin1 = 2, uint8_t pin2 = 3, uint8_t pin3 = 4, uint8_t pin4 = 5, bool enable = true);
|
||||
|
||||
/// Alternate Constructor which will call your own functions for forward and backward steps.
|
||||
/// You can have multiple simultaneous steppers, all moving
|
||||
/// at different speeds and accelerations, provided you call their run()
|
||||
/// functions at frequent enough intervals. Current Position is set to 0, target
|
||||
/// position is set to 0. MaxSpeed and Acceleration default to 1.0.
|
||||
/// Any motor initialization should happen before hand, no pins are used or initialized.
|
||||
/// \param[in] forward void-returning procedure that will make a forward step
|
||||
/// \param[in] backward void-returning procedure that will make a backward step
|
||||
AccelStepper(void (*forward)(), void (*backward)());
|
||||
|
||||
/// Set the target position. The run() function will try to move the motor (at most one step per call)
|
||||
/// from the current position to the target position set by the most
|
||||
/// recent call to this function. Caution: moveTo() also recalculates the speed for the next step.
|
||||
/// If you are trying to use constant speed movements, you should call setSpeed() after calling moveTo().
|
||||
/// \param[in] absolute The desired absolute position. Negative is
|
||||
/// anticlockwise from the 0 position.
|
||||
void moveTo(long absolute);
|
||||
|
||||
/// Set the target position relative to the current position
|
||||
/// \param[in] relative The desired position relative to the current position. Negative is
|
||||
/// anticlockwise from the current position.
|
||||
void move(long relative);
|
||||
|
||||
/// Poll the motor and step it if a step is due, implementing
|
||||
/// accelerations and decelerations to acheive the target position. You must call this as
|
||||
/// frequently as possible, but at least once per minimum step time interval,
|
||||
/// preferably in your main loop. Note that each call to run() will make at most one step, and then only when a step is due,
|
||||
/// based on the current speed and the time since the last step.
|
||||
/// \return true if the motor is still running to the target position.
|
||||
boolean run();
|
||||
|
||||
/// Poll the motor and step it if a step is due, implementing a constant
|
||||
/// speed as set by the most recent call to setSpeed(). You must call this as
|
||||
/// frequently as possible, but at least once per step interval,
|
||||
/// \return true if the motor was stepped.
|
||||
boolean runSpeed();
|
||||
|
||||
/// Sets the maximum permitted speed. The run() function will accelerate
|
||||
/// up to the speed set by this function.
|
||||
/// Caution: the maximum speed achievable depends on your processor and clock speed.
|
||||
/// The default maxSpeed is 1.0 steps per second.
|
||||
/// \param[in] speed The desired maximum speed in steps per second. Must
|
||||
/// be > 0. Caution: Speeds that exceed the maximum speed supported by the processor may
|
||||
/// Result in non-linear accelerations and decelerations.
|
||||
void setMaxSpeed(float speed);
|
||||
|
||||
/// returns the maximum speed configured for this stepper
|
||||
/// that was previously set by setMaxSpeed();
|
||||
/// \return The currently configured maximum speed
|
||||
float maxSpeed();
|
||||
|
||||
/// Sets the acceleration/deceleration rate.
|
||||
/// \param[in] acceleration The desired acceleration in steps per second
|
||||
/// per second. Must be > 0.0. This is an expensive call since it requires a square
|
||||
/// root to be calculated. Dont call more ofthen than needed
|
||||
void setAcceleration(float acceleration);
|
||||
|
||||
/// Sets the desired constant speed for use with runSpeed().
|
||||
/// \param[in] speed The desired constant speed in steps per
|
||||
/// second. Positive is clockwise. Speeds of more than 1000 steps per
|
||||
/// second are unreliable. Very slow speeds may be set (eg 0.00027777 for
|
||||
/// once per hour, approximately. Speed accuracy depends on the Arduino
|
||||
/// crystal. Jitter depends on how frequently you call the runSpeed() function.
|
||||
/// The speed will be limited by the current value of setMaxSpeed()
|
||||
void setSpeed(float speed);
|
||||
|
||||
/// The most recently set speed
|
||||
/// \return the most recent speed in steps per second
|
||||
float speed();
|
||||
|
||||
/// The distance from the current position to the target position.
|
||||
/// \return the distance from the current position to the target position
|
||||
/// in steps. Positive is clockwise from the current position.
|
||||
long distanceToGo();
|
||||
|
||||
/// The most recently set target position.
|
||||
/// \return the target position
|
||||
/// in steps. Positive is clockwise from the 0 position.
|
||||
long targetPosition();
|
||||
|
||||
/// The currently motor position.
|
||||
/// \return the current motor position
|
||||
/// in steps. Positive is clockwise from the 0 position.
|
||||
long currentPosition();
|
||||
|
||||
/// Resets the current position of the motor, so that wherever the motor
|
||||
/// happens to be right now is considered to be the new 0 position. Useful
|
||||
/// for setting a zero position on a stepper after an initial hardware
|
||||
/// positioning move.
|
||||
/// Has the side effect of setting the current motor speed to 0.
|
||||
/// \param[in] position The position in steps of wherever the motor
|
||||
/// happens to be right now.
|
||||
void setCurrentPosition(long position);
|
||||
|
||||
/// Moves the motor (with acceleration/deceleration)
|
||||
/// to the target position and blocks until it is at
|
||||
/// position. Dont use this in event loops, since it blocks.
|
||||
void runToPosition();
|
||||
|
||||
/// Runs at the currently selected speed until the target position is reached
|
||||
/// Does not implement accelerations.
|
||||
/// \return true if it stepped
|
||||
boolean runSpeedToPosition();
|
||||
|
||||
/// Moves the motor (with acceleration/deceleration)
|
||||
/// to the new target position and blocks until it is at
|
||||
/// position. Dont use this in event loops, since it blocks.
|
||||
/// \param[in] position The new target position.
|
||||
void runToNewPosition(long position);
|
||||
|
||||
/// Sets a new target position that causes the stepper
|
||||
/// to stop as quickly as possible, using the current speed and acceleration parameters.
|
||||
void stop();
|
||||
|
||||
/// Disable motor pin outputs by setting them all LOW
|
||||
/// Depending on the design of your electronics this may turn off
|
||||
/// the power to the motor coils, saving power.
|
||||
/// This is useful to support Arduino low power modes: disable the outputs
|
||||
/// during sleep and then reenable with enableOutputs() before stepping
|
||||
/// again.
|
||||
/// If the enable Pin is defined, sets it to OUTPUT mode and clears the pin to disabled.
|
||||
virtual void disableOutputs();
|
||||
|
||||
/// Enable motor pin outputs by setting the motor pins to OUTPUT
|
||||
/// mode. Called automatically by the constructor.
|
||||
/// If the enable Pin is defined, sets it to OUTPUT mode and sets the pin to enabled.
|
||||
virtual void enableOutputs();
|
||||
|
||||
/// Sets the minimum pulse width allowed by the stepper driver. The minimum practical pulse width is
|
||||
/// approximately 20 microseconds. Times less than 20 microseconds
|
||||
/// will usually result in 20 microseconds or so.
|
||||
/// \param[in] minWidth The minimum pulse width in microseconds.
|
||||
void setMinPulseWidth(unsigned int minWidth);
|
||||
|
||||
/// Sets the enable pin number for stepper drivers.
|
||||
/// 0xFF indicates unused (default).
|
||||
/// Otherwise, if a pin is set, the pin will be turned on when
|
||||
/// enableOutputs() is called and switched off when disableOutputs()
|
||||
/// is called.
|
||||
/// \param[in] enablePin Arduino digital pin number for motor enable
|
||||
/// \sa setPinsInverted
|
||||
void setEnablePin(uint8_t enablePin = 0xff);
|
||||
|
||||
/// Sets the inversion for stepper driver pins
|
||||
/// \param[in] directionInvert True for inverted direction pin, false for non-inverted
|
||||
/// \param[in] stepInvert True for inverted step pin, false for non-inverted
|
||||
/// \param[in] enableInvert True for inverted enable pin, false (default) for non-inverted
|
||||
void setPinsInverted(bool directionInvert = false, bool stepInvert = false, bool enableInvert = false);
|
||||
|
||||
/// Sets the inversion for 2, 3 and 4 wire stepper pins
|
||||
/// \param[in] pin1Invert True for inverted pin1, false for non-inverted
|
||||
/// \param[in] pin2Invert True for inverted pin2, false for non-inverted
|
||||
/// \param[in] pin3Invert True for inverted pin3, false for non-inverted
|
||||
/// \param[in] pin4Invert True for inverted pin4, false for non-inverted
|
||||
/// \param[in] enableInvert True for inverted enable pin, false (default) for non-inverted
|
||||
void setPinsInverted(bool pin1Invert, bool pin2Invert, bool pin3Invert, bool pin4Invert, bool enableInvert);
|
||||
|
||||
/// Checks to see if the motor is currently running to a target
|
||||
/// \return true if the speed is not zero or not at the target position
|
||||
bool isRunning();
|
||||
|
||||
protected:
|
||||
|
||||
/// \brief Direction indicator
|
||||
/// Symbolic names for the direction the motor is turning
|
||||
typedef enum
|
||||
{
|
||||
DIRECTION_CCW = 0, ///< Counter-Clockwise
|
||||
DIRECTION_CW = 1 ///< Clockwise
|
||||
} Direction;
|
||||
|
||||
/// Forces the library to compute a new instantaneous speed and set that as
|
||||
/// the current speed. It is called by
|
||||
/// the library:
|
||||
/// \li after each step
|
||||
/// \li after change to maxSpeed through setMaxSpeed()
|
||||
/// \li after change to acceleration through setAcceleration()
|
||||
/// \li after change to target position (relative or absolute) through
|
||||
/// move() or moveTo()
|
||||
void computeNewSpeed();
|
||||
|
||||
/// Low level function to set the motor output pins
|
||||
/// bit 0 of the mask corresponds to _pin[0]
|
||||
/// bit 1 of the mask corresponds to _pin[1]
|
||||
/// You can override this to impment, for example serial chip output insted of using the
|
||||
/// output pins directly
|
||||
virtual void setOutputPins(uint8_t mask);
|
||||
|
||||
/// Called to execute a step. Only called when a new step is
|
||||
/// required. Subclasses may override to implement new stepping
|
||||
/// interfaces. The default calls step1(), step2(), step4() or step8() depending on the
|
||||
/// number of pins defined for the stepper.
|
||||
/// \param[in] step The current step phase number (0 to 7)
|
||||
virtual void step(long step);
|
||||
|
||||
/// Called to execute a step using stepper functions (pins = 0) Only called when a new step is
|
||||
/// required. Calls _forward() or _backward() to perform the step
|
||||
/// \param[in] step The current step phase number (0 to 7)
|
||||
virtual void step0(long step);
|
||||
|
||||
/// Called to execute a step on a stepper driver (ie where pins == 1). Only called when a new step is
|
||||
/// required. Subclasses may override to implement new stepping
|
||||
/// interfaces. The default sets or clears the outputs of Step pin1 to step,
|
||||
/// and sets the output of _pin2 to the desired direction. The Step pin (_pin1) is pulsed for 1 microsecond
|
||||
/// which is the minimum STEP pulse width for the 3967 driver.
|
||||
/// \param[in] step The current step phase number (0 to 7)
|
||||
virtual void step1(long step);
|
||||
|
||||
/// Called to execute a step on a 2 pin motor. Only called when a new step is
|
||||
/// required. Subclasses may override to implement new stepping
|
||||
/// interfaces. The default sets or clears the outputs of pin1 and pin2
|
||||
/// \param[in] step The current step phase number (0 to 7)
|
||||
virtual void step2(long step);
|
||||
|
||||
/// Called to execute a step on a 3 pin motor, such as HDD spindle. Only called when a new step is
|
||||
/// required. Subclasses may override to implement new stepping
|
||||
/// interfaces. The default sets or clears the outputs of pin1, pin2,
|
||||
/// pin3
|
||||
/// \param[in] step The current step phase number (0 to 7)
|
||||
virtual void step3(long step);
|
||||
|
||||
/// Called to execute a step on a 4 pin motor. Only called when a new step is
|
||||
/// required. Subclasses may override to implement new stepping
|
||||
/// interfaces. The default sets or clears the outputs of pin1, pin2,
|
||||
/// pin3, pin4.
|
||||
/// \param[in] step The current step phase number (0 to 7)
|
||||
virtual void step4(long step);
|
||||
|
||||
/// Called to execute a step on a 3 pin motor, such as HDD spindle. Only called when a new step is
|
||||
/// required. Subclasses may override to implement new stepping
|
||||
/// interfaces. The default sets or clears the outputs of pin1, pin2,
|
||||
/// pin3
|
||||
/// \param[in] step The current step phase number (0 to 7)
|
||||
virtual void step6(long step);
|
||||
|
||||
/// Called to execute a step on a 4 pin half-steper motor. Only called when a new step is
|
||||
/// required. Subclasses may override to implement new stepping
|
||||
/// interfaces. The default sets or clears the outputs of pin1, pin2,
|
||||
/// pin3, pin4.
|
||||
/// \param[in] step The current step phase number (0 to 7)
|
||||
virtual void step8(long step);
|
||||
|
||||
/// Current direction motor is spinning in
|
||||
/// Protected because some peoples subclasses need it to be so
|
||||
boolean _direction; // 1 == CW
|
||||
|
||||
private:
|
||||
/// Number of pins on the stepper motor. Permits 2 or 4. 2 pins is a
|
||||
/// bipolar, and 4 pins is a unipolar.
|
||||
uint8_t _interface; // 0, 1, 2, 4, 8, See MotorInterfaceType
|
||||
|
||||
/// Arduino pin number assignments for the 2 or 4 pins required to interface to the
|
||||
/// stepper motor or driver
|
||||
uint8_t _pin[4];
|
||||
|
||||
/// Whether the _pins is inverted or not
|
||||
uint8_t _pinInverted[4];
|
||||
|
||||
/// The current absolution position in steps.
|
||||
long _currentPos; // Steps
|
||||
|
||||
/// The target position in steps. The AccelStepper library will move the
|
||||
/// motor from the _currentPos to the _targetPos, taking into account the
|
||||
/// max speed, acceleration and deceleration
|
||||
long _targetPos; // Steps
|
||||
|
||||
/// The current motos speed in steps per second
|
||||
/// Positive is clockwise
|
||||
float _speed; // Steps per second
|
||||
|
||||
/// The maximum permitted speed in steps per second. Must be > 0.
|
||||
float _maxSpeed;
|
||||
|
||||
/// The acceleration to use to accelerate or decelerate the motor in steps
|
||||
/// per second per second. Must be > 0
|
||||
float _acceleration;
|
||||
float _sqrt_twoa; // Precomputed sqrt(2*_acceleration)
|
||||
|
||||
/// The current interval between steps in microseconds.
|
||||
/// 0 means the motor is currently stopped with _speed == 0
|
||||
unsigned long _stepInterval;
|
||||
|
||||
/// The last step time in microseconds
|
||||
unsigned long _lastStepTime;
|
||||
|
||||
/// The minimum allowed pulse width in microseconds
|
||||
unsigned int _minPulseWidth;
|
||||
|
||||
/// Is the direction pin inverted?
|
||||
///bool _dirInverted; /// Moved to _pinInverted[1]
|
||||
|
||||
/// Is the step pin inverted?
|
||||
///bool _stepInverted; /// Moved to _pinInverted[0]
|
||||
|
||||
/// Is the enable pin inverted?
|
||||
bool _enableInverted;
|
||||
|
||||
/// Enable pin for stepper driver, or 0xFF if unused.
|
||||
uint8_t _enablePin;
|
||||
|
||||
/// The pointer to a forward-step procedure
|
||||
void (*_forward)();
|
||||
|
||||
/// The pointer to a backward-step procedure
|
||||
void (*_backward)();
|
||||
|
||||
/// The step counter for speed calculations
|
||||
long _n;
|
||||
|
||||
/// Initial step size in microseconds
|
||||
float _c0;
|
||||
|
||||
/// Last step size in microseconds
|
||||
float _cn;
|
||||
|
||||
/// Min step size in microseconds based on maxSpeed
|
||||
float _cmin; // at max speed
|
||||
|
||||
};
|
||||
|
||||
/// @example Random.pde
|
||||
/// Make a single stepper perform random changes in speed, position and acceleration
|
||||
|
||||
/// @example Overshoot.pde
|
||||
/// Check overshoot handling
|
||||
/// which sets a new target position and then waits until the stepper has
|
||||
/// achieved it. This is used for testing the handling of overshoots
|
||||
|
||||
/// @example MultipleSteppers.pde
|
||||
/// Shows how to multiple simultaneous steppers
|
||||
/// Runs one stepper forwards and backwards, accelerating and decelerating
|
||||
/// at the limits. Runs other steppers at the same time
|
||||
|
||||
/// @example ConstantSpeed.pde
|
||||
/// Shows how to run AccelStepper in the simplest,
|
||||
/// fixed speed mode with no accelerations
|
||||
|
||||
/// @example Blocking.pde
|
||||
/// Shows how to use the blocking call runToNewPosition
|
||||
/// Which sets a new target position and then waits until the stepper has
|
||||
/// achieved it.
|
||||
|
||||
/// @example AFMotor_MultiStepper.pde
|
||||
/// Control both Stepper motors at the same time with different speeds
|
||||
/// and accelerations.
|
||||
|
||||
/// @example AFMotor_ConstantSpeed.pde
|
||||
/// Shows how to run AccelStepper in the simplest,
|
||||
/// fixed speed mode with no accelerations
|
||||
|
||||
/// @example ProportionalControl.pde
|
||||
/// Make a single stepper follow the analog value read from a pot or whatever
|
||||
/// The stepper will move at a constant speed to each newly set posiiton,
|
||||
/// depending on the value of the pot.
|
||||
|
||||
/// @example Bounce.pde
|
||||
/// Make a single stepper bounce from one limit to another, observing
|
||||
/// accelrations at each end of travel
|
||||
|
||||
/// @example Quickstop.pde
|
||||
/// Check stop handling.
|
||||
/// Calls stop() while the stepper is travelling at full speed, causing
|
||||
/// the stepper to stop as quickly as possible, within the constraints of the
|
||||
/// current acceleration.
|
||||
|
||||
/// @example MotorShield.pde
|
||||
/// Shows how to use AccelStepper to control a 3-phase motor, such as a HDD spindle motor
|
||||
/// using the Adafruit Motor Shield http://www.ladyada.net/make/mshield/index.html.
|
||||
|
||||
/// @example DualMotorShield.pde
|
||||
/// Shows how to use AccelStepper to control 2 x 2 phase steppers using the
|
||||
/// Itead Studio Arduino Dual Stepper Motor Driver Shield
|
||||
/// model IM120417015
|
||||
|
||||
#endif
|
||||
17
arduino-cli/libraries/AccelStepper/LICENSE
Normal file
17
arduino-cli/libraries/AccelStepper/LICENSE
Normal file
@@ -0,0 +1,17 @@
|
||||
This software is Copyright (C) 2008 Mike McCauley. Use is subject to license
|
||||
conditions. The main licensing options available are GPL V2 or Commercial:
|
||||
|
||||
Open Source Licensing GPL V2
|
||||
|
||||
This is the appropriate option if you want to share the source code of your
|
||||
application with everyone you distribute it to, and you also want to give them
|
||||
the right to share who uses it. If you wish to use this software under Open
|
||||
Source Licensing, you must contribute all your source code to the open source
|
||||
community in accordance with the GPL Version 2 when your application is
|
||||
distributed. See http://www.gnu.org/copyleft/gpl.html
|
||||
|
||||
Commercial Licensing
|
||||
|
||||
This is the appropriate option if you are creating proprietary applications
|
||||
and you are not prepared to distribute and share the source code of your
|
||||
application. Contact info@open.com.au for details.
|
||||
38
arduino-cli/libraries/AccelStepper/MANIFEST
Normal file
38
arduino-cli/libraries/AccelStepper/MANIFEST
Normal file
@@ -0,0 +1,38 @@
|
||||
AccelStepper/Makefile
|
||||
AccelStepper/AccelStepper.h
|
||||
AccelStepper/AccelStepper.cpp
|
||||
AccelStepper/MultiStepper.h
|
||||
AccelStepper/MultiStepper.cpp
|
||||
AccelStepper/MANIFEST
|
||||
AccelStepper/LICENSE
|
||||
AccelStepper/project.cfg
|
||||
AccelStepper/keywords.txt
|
||||
AccelStepper/doc
|
||||
AccelStepper/examples/Blocking/Blocking.pde
|
||||
AccelStepper/examples/MultipleSteppers/MultipleSteppers.pde
|
||||
AccelStepper/examples/Overshoot/Overshoot.pde
|
||||
AccelStepper/examples/ConstantSpeed/ConstantSpeed.pde
|
||||
AccelStepper/examples/Random/Random.pde
|
||||
AccelStepper/examples/AFMotor_ConstantSpeed/AFMotor_ConstantSpeed.pde
|
||||
AccelStepper/examples/AFMotor_MultiStepper/AFMotor_MultiStepper.pde
|
||||
AccelStepper/examples/ProportionalControl/ProportionalControl.pde
|
||||
AccelStepper/examples/Bounce/Bounce.pde
|
||||
AccelStepper/examples/Quickstop/Quickstop.pde
|
||||
AccelStepper/examples/MotorShield/MotorShield.pde
|
||||
AccelStepper/examples/DualMotorShield/DualMotorShield.pde
|
||||
AccelStepper/examples/MultiStepper/MultiStepper.pde
|
||||
AccelStepper/doc
|
||||
AccelStepper/doc/index.html
|
||||
AccelStepper/doc/functions.html
|
||||
AccelStepper/doc/annotated.html
|
||||
AccelStepper/doc/tab_l.gif
|
||||
AccelStepper/doc/tabs.css
|
||||
AccelStepper/doc/files.html
|
||||
AccelStepper/doc/classAccelStepper-members.html
|
||||
AccelStepper/doc/doxygen.css
|
||||
AccelStepper/doc/AccelStepper_8h-source.html
|
||||
AccelStepper/doc/tab_r.gif
|
||||
AccelStepper/doc/doxygen.png
|
||||
AccelStepper/doc/tab_b.gif
|
||||
AccelStepper/doc/functions_func.html
|
||||
AccelStepper/doc/classAccelStepper.html
|
||||
30
arduino-cli/libraries/AccelStepper/Makefile
Normal file
30
arduino-cli/libraries/AccelStepper/Makefile
Normal file
@@ -0,0 +1,30 @@
|
||||
# Makefile
|
||||
#
|
||||
# Makefile for the Arduino AccelStepper project
|
||||
#
|
||||
# Author: Mike McCauley (mikem@airspayce.com)
|
||||
# Copyright (C) 2010 Mike McCauley
|
||||
# $Id: Makefile,v 1.6 2015/08/25 04:57:29 mikem Exp mikem $
|
||||
|
||||
PROJNAME = AccelStepper
|
||||
VERSION_MAJOR = 1
|
||||
VERSION_MINOR = 59
|
||||
|
||||
DISTFILE = $(PROJNAME)-$(VERSION_MAJOR).$(VERSION_MINOR).zip
|
||||
|
||||
all: versioning doxygen dist upload
|
||||
|
||||
versioning:
|
||||
sed -i.bak -e 's/AccelStepper-.*\.zip/$(DISTFILE)/' AccelStepper.h
|
||||
|
||||
doxygen:
|
||||
doxygen project.cfg
|
||||
|
||||
ci:
|
||||
(cd ..;ci -l `cat $(PROJNAME)/MANIFEST`)
|
||||
|
||||
dist:
|
||||
(cd ..; zip $(PROJNAME)/$(DISTFILE) `cat $(PROJNAME)/MANIFEST`)
|
||||
|
||||
upload:
|
||||
rsync -avz $(DISTFILE) doc/ www.airspayce.com:public_html/mikem/arduino/$(PROJNAME)
|
||||
73
arduino-cli/libraries/AccelStepper/MultiStepper.cpp
Normal file
73
arduino-cli/libraries/AccelStepper/MultiStepper.cpp
Normal file
@@ -0,0 +1,73 @@
|
||||
// MultiStepper.cpp
|
||||
//
|
||||
// Copyright (C) 2015 Mike McCauley
|
||||
// $Id: MultiStepper.cpp,v 1.2 2015/10/04 05:16:38 mikem Exp $
|
||||
|
||||
#include "MultiStepper.h"
|
||||
#include "AccelStepper.h"
|
||||
|
||||
MultiStepper::MultiStepper()
|
||||
: _num_steppers(0)
|
||||
{
|
||||
}
|
||||
|
||||
boolean MultiStepper::addStepper(AccelStepper& stepper)
|
||||
{
|
||||
if (_num_steppers >= MULTISTEPPER_MAX_STEPPERS)
|
||||
return false; // No room for more
|
||||
_steppers[_num_steppers++] = &stepper;
|
||||
return true;
|
||||
}
|
||||
|
||||
void MultiStepper::moveTo(long absolute[])
|
||||
{
|
||||
// First find the stepper that will take the longest time to move
|
||||
float longestTime = 0.0;
|
||||
|
||||
uint8_t i;
|
||||
for (i = 0; i < _num_steppers; i++)
|
||||
{
|
||||
long thisDistance = absolute[i] - _steppers[i]->currentPosition();
|
||||
float thisTime = abs(thisDistance) / _steppers[i]->maxSpeed();
|
||||
|
||||
if (thisTime > longestTime)
|
||||
longestTime = thisTime;
|
||||
}
|
||||
|
||||
if (longestTime > 0.0)
|
||||
{
|
||||
// Now work out a new max speed for each stepper so they will all
|
||||
// arrived at the same time of longestTime
|
||||
for (i = 0; i < _num_steppers; i++)
|
||||
{
|
||||
long thisDistance = absolute[i] - _steppers[i]->currentPosition();
|
||||
float thisSpeed = thisDistance / longestTime;
|
||||
_steppers[i]->moveTo(absolute[i]); // New target position (resets speed)
|
||||
_steppers[i]->setSpeed(thisSpeed); // New speed
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Returns true if any motor is still running to the target position.
|
||||
boolean MultiStepper::run()
|
||||
{
|
||||
uint8_t i;
|
||||
boolean ret = false;
|
||||
for (i = 0; i < _num_steppers; i++)
|
||||
{
|
||||
if ( _steppers[i]->distanceToGo() != 0)
|
||||
{
|
||||
_steppers[i]->runSpeed();
|
||||
ret = true;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Blocks until all steppers reach their target position and are stopped
|
||||
void MultiStepper::runSpeedToPosition()
|
||||
{
|
||||
while (run())
|
||||
;
|
||||
}
|
||||
|
||||
78
arduino-cli/libraries/AccelStepper/MultiStepper.h
Normal file
78
arduino-cli/libraries/AccelStepper/MultiStepper.h
Normal file
@@ -0,0 +1,78 @@
|
||||
// MultiStepper.h
|
||||
|
||||
#ifndef MultiStepper_h
|
||||
#define MultiStepper_h
|
||||
|
||||
#include <stdlib.h>
|
||||
#if ARDUINO >= 100
|
||||
#include <Arduino.h>
|
||||
#else
|
||||
#include <WProgram.h>
|
||||
#include <wiring.h>
|
||||
#endif
|
||||
|
||||
#define MULTISTEPPER_MAX_STEPPERS 10
|
||||
|
||||
class AccelStepper;
|
||||
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
/// \class MultiStepper MultiStepper.h <MultiStepper.h>
|
||||
/// \brief Operate multiple AccelSteppers in a co-ordinated fashion
|
||||
///
|
||||
/// This class can manage multiple AccelSteppers (up to MULTISTEPPER_MAX_STEPPERS = 10),
|
||||
/// and cause them all to move
|
||||
/// to selected positions at such a (constant) speed that they all arrive at their
|
||||
/// target position at the same time. This can be used to support devices with multiple steppers
|
||||
/// on say multiple axes to cause linear diagonal motion. Suitable for use with X-Y plotters, flatbeds,
|
||||
/// 3D printers etc
|
||||
/// to get linear straight line movement between arbitrary 2d (or 3d or ...) positions.
|
||||
///
|
||||
/// Caution: only constant speed stepper motion is supported: acceleration and deceleration is not supported
|
||||
/// All the steppers managed by MultiStepper will step at a constant speed to their
|
||||
/// target (albeit perhaps different speeds for each stepper).
|
||||
class MultiStepper
|
||||
{
|
||||
public:
|
||||
/// Constructor
|
||||
MultiStepper();
|
||||
|
||||
/// Add a stepper to the set of managed steppers
|
||||
/// There is an upper limit of MULTISTEPPER_MAX_STEPPERS = 10 to the number of steppers that can be managed
|
||||
/// \param[in] stepper Reference to a stepper to add to the managed list
|
||||
/// \return true if successful. false if the number of managed steppers would exceed MULTISTEPPER_MAX_STEPPERS
|
||||
boolean addStepper(AccelStepper& stepper);
|
||||
|
||||
/// Set the target positions of all managed steppers
|
||||
/// according to a coordinate array.
|
||||
/// New speeds will be computed for each stepper so they will all arrive at their
|
||||
/// respective targets at very close to the same time.
|
||||
/// \param[in] absolute An array of desired absolute stepper positions. absolute[0] will be used to set
|
||||
/// the absolute position of the first stepper added by addStepper() etc. The array must be at least as long as
|
||||
/// the number of steppers that have been added by addStepper, else results are undefined.
|
||||
void moveTo(long absolute[]);
|
||||
|
||||
/// Calls runSpeed() on all the managed steppers
|
||||
/// that have not acheived their target position.
|
||||
/// \return true if any stepper is still in the process of running to its target position.
|
||||
boolean run();
|
||||
|
||||
/// Runs all managed steppers until they acheived their target position.
|
||||
/// Blocks until all that position is acheived. If you dont
|
||||
/// want blocking consider using run() instead.
|
||||
void runSpeedToPosition();
|
||||
|
||||
private:
|
||||
/// Array of pointers to the steppers we are controlling.
|
||||
/// Fills from 0 onwards
|
||||
AccelStepper* _steppers[MULTISTEPPER_MAX_STEPPERS];
|
||||
|
||||
/// Number of steppers we are controlling and the number
|
||||
/// of steppers in _steppers[]
|
||||
uint8_t _num_steppers;
|
||||
};
|
||||
|
||||
/// @example MultiStepper.pde
|
||||
/// Use MultiStepper class to manage multiple steppers and make them all move to
|
||||
/// the same position at the same time for linear 2d (or 3d) motion.
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,420 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||
<html><head><meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
|
||||
<title>AccelStepper: AccelStepper.h Source File</title>
|
||||
<link href="doxygen.css" rel="stylesheet" type="text/css">
|
||||
<link href="tabs.css" rel="stylesheet" type="text/css">
|
||||
</head><body>
|
||||
<!-- Generated by Doxygen 1.5.6 -->
|
||||
<div class="navigation" id="top">
|
||||
<div class="tabs">
|
||||
<ul>
|
||||
<li><a href="index.html"><span>Main Page</span></a></li>
|
||||
<li><a href="annotated.html"><span>Classes</span></a></li>
|
||||
<li class="current"><a href="files.html"><span>Files</span></a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<h1>AccelStepper.h</h1><div class="fragment"><pre class="fragment"><a name="l00001"></a>00001 <span class="comment">// AccelStepper.h</span>
|
||||
<a name="l00002"></a>00002 <span class="comment">//</span><span class="comment"></span>
|
||||
<a name="l00003"></a>00003 <span class="comment">/// \mainpage AccelStepper library for Arduino</span>
|
||||
<a name="l00004"></a>00004 <span class="comment">///</span>
|
||||
<a name="l00005"></a>00005 <span class="comment">/// This is the Arduino AccelStepper library.</span>
|
||||
<a name="l00006"></a>00006 <span class="comment">/// It provides an object-oriented interface for 2 or 4 pin stepper motors.</span>
|
||||
<a name="l00007"></a>00007 <span class="comment">///</span>
|
||||
<a name="l00008"></a>00008 <span class="comment">/// The standard Arduino IDE includes the Stepper library</span>
|
||||
<a name="l00009"></a>00009 <span class="comment">/// (http://arduino.cc/en/Reference/Stepper) for stepper motors. It is</span>
|
||||
<a name="l00010"></a>00010 <span class="comment">/// perfectly adequate for simple, single motor applications.</span>
|
||||
<a name="l00011"></a>00011 <span class="comment">///</span>
|
||||
<a name="l00012"></a>00012 <span class="comment">/// AccelStepper significantly improves on the standard Arduino Stepper library in several ways:</span>
|
||||
<a name="l00013"></a>00013 <span class="comment">/// \li Supports acceleration and deceleration</span>
|
||||
<a name="l00014"></a>00014 <span class="comment">/// \li Supports multiple simultaneous steppers, with independent concurrent stepping on each stepper</span>
|
||||
<a name="l00015"></a>00015 <span class="comment">/// \li API functions never delay() or block</span>
|
||||
<a name="l00016"></a>00016 <span class="comment">/// \li Supports 2 and 4 wire steppers, plus 4 wire half steppers.</span>
|
||||
<a name="l00017"></a>00017 <span class="comment">/// \li Supports alternate stepping functions to enable support of AFMotor (https://github.com/adafruit/Adafruit-Motor-Shield-library)</span>
|
||||
<a name="l00018"></a>00018 <span class="comment">/// \li Supports stepper drivers such as the Sparkfun EasyDriver (based on 3967 driver chip)</span>
|
||||
<a name="l00019"></a>00019 <span class="comment">/// \li Very slow speeds are supported</span>
|
||||
<a name="l00020"></a>00020 <span class="comment">/// \li Extensive API</span>
|
||||
<a name="l00021"></a>00021 <span class="comment">/// \li Subclass support</span>
|
||||
<a name="l00022"></a>00022 <span class="comment">///</span>
|
||||
<a name="l00023"></a>00023 <span class="comment">/// The latest version of this documentation can be downloaded from </span>
|
||||
<a name="l00024"></a>00024 <span class="comment">/// http://www.open.com.au/mikem/arduino/AccelStepper</span>
|
||||
<a name="l00025"></a>00025 <span class="comment">///</span>
|
||||
<a name="l00026"></a>00026 <span class="comment">/// Example Arduino programs are included to show the main modes of use.</span>
|
||||
<a name="l00027"></a>00027 <span class="comment">///</span>
|
||||
<a name="l00028"></a>00028 <span class="comment">/// The version of the package that this documentation refers to can be downloaded </span>
|
||||
<a name="l00029"></a>00029 <span class="comment">/// from http://www.open.com.au/mikem/arduino/AccelStepper/AccelStepper-1.11.zip</span>
|
||||
<a name="l00030"></a>00030 <span class="comment">/// You can find the latest version at http://www.open.com.au/mikem/arduino/AccelStepper</span>
|
||||
<a name="l00031"></a>00031 <span class="comment">///</span>
|
||||
<a name="l00032"></a>00032 <span class="comment">/// Tested on Arduino Diecimila and Mega with arduino-0018 & arduino-0021 </span>
|
||||
<a name="l00033"></a>00033 <span class="comment">/// on OpenSuSE 11.1 and avr-libc-1.6.1-1.15,</span>
|
||||
<a name="l00034"></a>00034 <span class="comment">/// cross-avr-binutils-2.19-9.1, cross-avr-gcc-4.1.3_20080612-26.5.</span>
|
||||
<a name="l00035"></a>00035 <span class="comment">///</span>
|
||||
<a name="l00036"></a>00036 <span class="comment">/// \par Installation</span>
|
||||
<a name="l00037"></a>00037 <span class="comment">/// Install in the usual way: unzip the distribution zip file to the libraries</span>
|
||||
<a name="l00038"></a>00038 <span class="comment">/// sub-folder of your sketchbook. </span>
|
||||
<a name="l00039"></a>00039 <span class="comment">///</span>
|
||||
<a name="l00040"></a>00040 <span class="comment">/// This software is Copyright (C) 2010 Mike McCauley. Use is subject to license</span>
|
||||
<a name="l00041"></a>00041 <span class="comment">/// conditions. The main licensing options available are GPL V2 or Commercial:</span>
|
||||
<a name="l00042"></a>00042 <span class="comment">/// </span>
|
||||
<a name="l00043"></a>00043 <span class="comment">/// \par Open Source Licensing GPL V2</span>
|
||||
<a name="l00044"></a>00044 <span class="comment">/// This is the appropriate option if you want to share the source code of your</span>
|
||||
<a name="l00045"></a>00045 <span class="comment">/// application with everyone you distribute it to, and you also want to give them</span>
|
||||
<a name="l00046"></a>00046 <span class="comment">/// the right to share who uses it. If you wish to use this software under Open</span>
|
||||
<a name="l00047"></a>00047 <span class="comment">/// Source Licensing, you must contribute all your source code to the open source</span>
|
||||
<a name="l00048"></a>00048 <span class="comment">/// community in accordance with the GPL Version 2 when your application is</span>
|
||||
<a name="l00049"></a>00049 <span class="comment">/// distributed. See http://www.gnu.org/copyleft/gpl.html</span>
|
||||
<a name="l00050"></a>00050 <span class="comment">/// </span>
|
||||
<a name="l00051"></a>00051 <span class="comment">/// \par Commercial Licensing</span>
|
||||
<a name="l00052"></a>00052 <span class="comment">/// This is the appropriate option if you are creating proprietary applications</span>
|
||||
<a name="l00053"></a>00053 <span class="comment">/// and you are not prepared to distribute and share the source code of your</span>
|
||||
<a name="l00054"></a>00054 <span class="comment">/// application. Contact info@open.com.au for details.</span>
|
||||
<a name="l00055"></a>00055 <span class="comment">///</span>
|
||||
<a name="l00056"></a>00056 <span class="comment">/// \par Revision History</span>
|
||||
<a name="l00057"></a>00057 <span class="comment">/// \version 1.0 Initial release</span>
|
||||
<a name="l00058"></a>00058 <span class="comment">///</span>
|
||||
<a name="l00059"></a>00059 <span class="comment">/// \version 1.1 Added speed() function to get the current speed.</span>
|
||||
<a name="l00060"></a>00060 <span class="comment">/// \version 1.2 Added runSpeedToPosition() submitted by Gunnar Arndt.</span>
|
||||
<a name="l00061"></a>00061 <span class="comment">/// \version 1.3 Added support for stepper drivers (ie with Step and Direction inputs) with _pins == 1</span>
|
||||
<a name="l00062"></a>00062 <span class="comment">/// \version 1.4 Added functional contructor to support AFMotor, contributed by Limor, with example sketches.</span>
|
||||
<a name="l00063"></a>00063 <span class="comment">/// \version 1.5 Improvements contributed by Peter Mousley: Use of microsecond steps and other speed improvements</span>
|
||||
<a name="l00064"></a>00064 <span class="comment">/// to increase max stepping speed to about 4kHz. New option for user to set the min allowed pulse width.</span>
|
||||
<a name="l00065"></a>00065 <span class="comment">/// Added checks for already running at max speed and skip further calcs if so. </span>
|
||||
<a name="l00066"></a>00066 <span class="comment">/// \version 1.6 Fixed a problem with wrapping of microsecond stepping that could cause stepping to hang. </span>
|
||||
<a name="l00067"></a>00067 <span class="comment">/// Reported by Sandy Noble.</span>
|
||||
<a name="l00068"></a>00068 <span class="comment">/// Removed redundant _lastRunTime member.</span>
|
||||
<a name="l00069"></a>00069 <span class="comment">/// \version 1.7 Fixed a bug where setCurrentPosition() did always work as expected. Reported by Peter Linhart.</span>
|
||||
<a name="l00070"></a>00070 <span class="comment">/// Reported by Sandy Noble.</span>
|
||||
<a name="l00071"></a>00071 <span class="comment">/// Removed redundant _lastRunTime member.</span>
|
||||
<a name="l00072"></a>00072 <span class="comment">/// \version 1.8 Added support for 4 pin half-steppers, requested by Harvey Moon</span>
|
||||
<a name="l00073"></a>00073 <span class="comment">/// \version 1.9 setCurrentPosition() now also sets motor speed to 0.</span>
|
||||
<a name="l00074"></a>00074 <span class="comment">/// \version 1.10 Builds on Arduino 1.0</span>
|
||||
<a name="l00075"></a>00075 <span class="comment">/// \version 1.11 Improvments from Michael Ellison:</span>
|
||||
<a name="l00076"></a>00076 <span class="comment">/// Added optional enable line support for stepper drivers</span>
|
||||
<a name="l00077"></a>00077 <span class="comment">/// Added inversion for step/direction/enable lines for stepper drivers</span>
|
||||
<a name="l00078"></a>00078 <span class="comment">///</span>
|
||||
<a name="l00079"></a>00079 <span class="comment">/// \author Mike McCauley (mikem@open.com.au)</span>
|
||||
<a name="l00080"></a>00080 <span class="comment"></span><span class="comment">// Copyright (C) 2009 Mike McCauley</span>
|
||||
<a name="l00081"></a>00081 <span class="comment">// $Id: AccelStepper.h,v 1.5 2011/03/21 00:42:15 mikem Exp mikem $</span>
|
||||
<a name="l00082"></a>00082
|
||||
<a name="l00083"></a>00083 <span class="preprocessor">#ifndef AccelStepper_h</span>
|
||||
<a name="l00084"></a>00084 <span class="preprocessor"></span><span class="preprocessor">#define AccelStepper_h</span>
|
||||
<a name="l00085"></a>00085 <span class="preprocessor"></span>
|
||||
<a name="l00086"></a>00086 <span class="preprocessor">#include <stdlib.h></span>
|
||||
<a name="l00087"></a>00087 <span class="preprocessor">#if ARDUINO >= 100</span>
|
||||
<a name="l00088"></a>00088 <span class="preprocessor"></span><span class="preprocessor">#include <Arduino.h></span>
|
||||
<a name="l00089"></a>00089 <span class="preprocessor">#else</span>
|
||||
<a name="l00090"></a>00090 <span class="preprocessor"></span><span class="preprocessor">#include <wiring.h></span>
|
||||
<a name="l00091"></a>00091 <span class="preprocessor">#endif</span>
|
||||
<a name="l00092"></a>00092 <span class="preprocessor"></span>
|
||||
<a name="l00093"></a>00093 <span class="comment">// These defs cause trouble on some versions of Arduino</span>
|
||||
<a name="l00094"></a>00094 <span class="preprocessor">#undef round</span>
|
||||
<a name="l00095"></a>00095 <span class="preprocessor"></span><span class="comment"></span>
|
||||
<a name="l00096"></a>00096 <span class="comment">/////////////////////////////////////////////////////////////////////</span>
|
||||
<a name="l00097"></a>00097 <span class="comment">/// \class AccelStepper AccelStepper.h <AccelStepper.h></span>
|
||||
<a name="l00098"></a>00098 <span class="comment">/// \brief Support for stepper motors with acceleration etc.</span>
|
||||
<a name="l00099"></a>00099 <span class="comment">///</span>
|
||||
<a name="l00100"></a>00100 <span class="comment">/// This defines a single 2 or 4 pin stepper motor, or stepper moter with fdriver chip, with optional</span>
|
||||
<a name="l00101"></a>00101 <span class="comment">/// acceleration, deceleration, absolute positioning commands etc. Multiple</span>
|
||||
<a name="l00102"></a>00102 <span class="comment">/// simultaneous steppers are supported, all moving </span>
|
||||
<a name="l00103"></a>00103 <span class="comment">/// at different speeds and accelerations. </span>
|
||||
<a name="l00104"></a>00104 <span class="comment">///</span>
|
||||
<a name="l00105"></a>00105 <span class="comment">/// \par Operation</span>
|
||||
<a name="l00106"></a>00106 <span class="comment">/// This module operates by computing a step time in microseconds. The step</span>
|
||||
<a name="l00107"></a>00107 <span class="comment">/// time is recomputed after each step and after speed and acceleration</span>
|
||||
<a name="l00108"></a>00108 <span class="comment">/// parameters are changed by the caller. The time of each step is recorded in</span>
|
||||
<a name="l00109"></a>00109 <span class="comment">/// microseconds. The run() function steps the motor if a new step is due.</span>
|
||||
<a name="l00110"></a>00110 <span class="comment">/// The run() function must be called frequently until the motor is in the</span>
|
||||
<a name="l00111"></a>00111 <span class="comment">/// desired position, after which time run() will do nothing.</span>
|
||||
<a name="l00112"></a>00112 <span class="comment">///</span>
|
||||
<a name="l00113"></a>00113 <span class="comment">/// \par Positioning</span>
|
||||
<a name="l00114"></a>00114 <span class="comment">/// Positions are specified by a signed long integer. At</span>
|
||||
<a name="l00115"></a>00115 <span class="comment">/// construction time, the current position of the motor is consider to be 0. Positive</span>
|
||||
<a name="l00116"></a>00116 <span class="comment">/// positions are clockwise from the initial position; negative positions are</span>
|
||||
<a name="l00117"></a>00117 <span class="comment">/// anticlockwise. The curent position can be altered for instance after</span>
|
||||
<a name="l00118"></a>00118 <span class="comment">/// initialization positioning.</span>
|
||||
<a name="l00119"></a>00119 <span class="comment">///</span>
|
||||
<a name="l00120"></a>00120 <span class="comment">/// \par Caveats</span>
|
||||
<a name="l00121"></a>00121 <span class="comment">/// This is an open loop controller: If the motor stalls or is oversped,</span>
|
||||
<a name="l00122"></a>00122 <span class="comment">/// AccelStepper will not have a correct </span>
|
||||
<a name="l00123"></a>00123 <span class="comment">/// idea of where the motor really is (since there is no feedback of the motor's</span>
|
||||
<a name="l00124"></a>00124 <span class="comment">/// real position. We only know where we _think_ it is, relative to the</span>
|
||||
<a name="l00125"></a>00125 <span class="comment">/// initial starting point).</span>
|
||||
<a name="l00126"></a>00126 <span class="comment">///</span>
|
||||
<a name="l00127"></a>00127 <span class="comment">/// The fastest motor speed that can be reliably supported is 4000 steps per</span>
|
||||
<a name="l00128"></a>00128 <span class="comment">/// second (4 kHz) at a clock frequency of 16 MHz. However, any speed less than that</span>
|
||||
<a name="l00129"></a>00129 <span class="comment">/// down to very slow speeds (much less than one per second) are also supported,</span>
|
||||
<a name="l00130"></a>00130 <span class="comment">/// provided the run() function is called frequently enough to step the motor</span>
|
||||
<a name="l00131"></a>00131 <span class="comment">/// whenever required for the speed set.</span>
|
||||
<a name="l00132"></a><a class="code" href="classAccelStepper.html">00132</a> <span class="comment"></span><span class="keyword">class </span><a class="code" href="classAccelStepper.html" title="Support for stepper motors with acceleration etc.">AccelStepper</a>
|
||||
<a name="l00133"></a>00133 {
|
||||
<a name="l00134"></a>00134 <span class="keyword">public</span>:<span class="comment"></span>
|
||||
<a name="l00135"></a>00135 <span class="comment"> /// Constructor. You can have multiple simultaneous steppers, all moving</span>
|
||||
<a name="l00136"></a>00136 <span class="comment"> /// at different speeds and accelerations, provided you call their run()</span>
|
||||
<a name="l00137"></a>00137 <span class="comment"> /// functions at frequent enough intervals. Current Position is set to 0, target</span>
|
||||
<a name="l00138"></a>00138 <span class="comment"> /// position is set to 0. MaxSpeed and Acceleration default to 1.0.</span>
|
||||
<a name="l00139"></a>00139 <span class="comment"> /// The motor pins will be initialised to OUTPUT mode during the</span>
|
||||
<a name="l00140"></a>00140 <span class="comment"> /// constructor by a call to enableOutputs().</span>
|
||||
<a name="l00141"></a>00141 <span class="comment"> /// \param[in] pins Number of pins to interface to. 1, 2 or 4 are</span>
|
||||
<a name="l00142"></a>00142 <span class="comment"> /// supported. 1 means a stepper driver (with Step and Direction pins).</span>
|
||||
<a name="l00143"></a>00143 <span class="comment"> /// If an enable line is also needed, call setEnablePin() after construction.</span>
|
||||
<a name="l00144"></a>00144 <span class="comment"> /// You may also invert the pins using setPinsInverted().</span>
|
||||
<a name="l00145"></a>00145 <span class="comment"> /// 2 means a 2 wire stepper. 4 means a 4 wire stepper. 8 means a 4 wire half stepper</span>
|
||||
<a name="l00146"></a>00146 <span class="comment"> /// Defaults to 4 pins.</span>
|
||||
<a name="l00147"></a>00147 <span class="comment"> /// \param[in] pin1 Arduino digital pin number for motor pin 1. Defaults</span>
|
||||
<a name="l00148"></a>00148 <span class="comment"> /// to pin 2. For a driver (pins==1), this is the Step input to the driver. Low to high transition means to step)</span>
|
||||
<a name="l00149"></a>00149 <span class="comment"> /// \param[in] pin2 Arduino digital pin number for motor pin 2. Defaults</span>
|
||||
<a name="l00150"></a>00150 <span class="comment"> /// to pin 3. For a driver (pins==1), this is the Direction input the driver. High means forward.</span>
|
||||
<a name="l00151"></a>00151 <span class="comment"> /// \param[in] pin3 Arduino digital pin number for motor pin 3. Defaults</span>
|
||||
<a name="l00152"></a>00152 <span class="comment"> /// to pin 4.</span>
|
||||
<a name="l00153"></a>00153 <span class="comment"> /// \param[in] pin4 Arduino digital pin number for motor pin 4. Defaults</span>
|
||||
<a name="l00154"></a>00154 <span class="comment"> /// to pin 5.</span>
|
||||
<a name="l00155"></a>00155 <span class="comment"></span> <a class="code" href="classAccelStepper.html#a1290897df35915069e5eca9d034038c">AccelStepper</a>(uint8_t pins = 4, uint8_t pin1 = 2, uint8_t pin2 = 3, uint8_t pin3 = 4, uint8_t pin4 = 5);
|
||||
<a name="l00156"></a>00156 <span class="comment"></span>
|
||||
<a name="l00157"></a>00157 <span class="comment"> /// Alternate Constructor which will call your own functions for forward and backward steps. </span>
|
||||
<a name="l00158"></a>00158 <span class="comment"> /// You can have multiple simultaneous steppers, all moving</span>
|
||||
<a name="l00159"></a>00159 <span class="comment"> /// at different speeds and accelerations, provided you call their run()</span>
|
||||
<a name="l00160"></a>00160 <span class="comment"> /// functions at frequent enough intervals. Current Position is set to 0, target</span>
|
||||
<a name="l00161"></a>00161 <span class="comment"> /// position is set to 0. MaxSpeed and Acceleration default to 1.0.</span>
|
||||
<a name="l00162"></a>00162 <span class="comment"> /// Any motor initialization should happen before hand, no pins are used or initialized.</span>
|
||||
<a name="l00163"></a>00163 <span class="comment"> /// \param[in] forward void-returning procedure that will make a forward step</span>
|
||||
<a name="l00164"></a>00164 <span class="comment"> /// \param[in] backward void-returning procedure that will make a backward step</span>
|
||||
<a name="l00165"></a>00165 <span class="comment"></span> <a class="code" href="classAccelStepper.html#a1290897df35915069e5eca9d034038c">AccelStepper</a>(<span class="keywordtype">void</span> (*forward)(), <span class="keywordtype">void</span> (*backward)());
|
||||
<a name="l00166"></a>00166 <span class="comment"></span>
|
||||
<a name="l00167"></a>00167 <span class="comment"> /// Set the target position. The run() function will try to move the motor</span>
|
||||
<a name="l00168"></a>00168 <span class="comment"> /// from the current position to the target position set by the most</span>
|
||||
<a name="l00169"></a>00169 <span class="comment"> /// recent call to this function.</span>
|
||||
<a name="l00170"></a>00170 <span class="comment"> /// \param[in] absolute The desired absolute position. Negative is</span>
|
||||
<a name="l00171"></a>00171 <span class="comment"> /// anticlockwise from the 0 position.</span>
|
||||
<a name="l00172"></a>00172 <span class="comment"></span> <span class="keywordtype">void</span> <a class="code" href="classAccelStepper.html#ce236ede35f87c63d18da25810ec9736">moveTo</a>(<span class="keywordtype">long</span> absolute);
|
||||
<a name="l00173"></a>00173 <span class="comment"></span>
|
||||
<a name="l00174"></a>00174 <span class="comment"> /// Set the target position relative to the current position</span>
|
||||
<a name="l00175"></a>00175 <span class="comment"> /// \param[in] relative The desired position relative to the current position. Negative is</span>
|
||||
<a name="l00176"></a>00176 <span class="comment"> /// anticlockwise from the current position.</span>
|
||||
<a name="l00177"></a>00177 <span class="comment"></span> <span class="keywordtype">void</span> <a class="code" href="classAccelStepper.html#68942c66e78fb7f7b5f0cdade6eb7f06">move</a>(<span class="keywordtype">long</span> relative);
|
||||
<a name="l00178"></a>00178 <span class="comment"></span>
|
||||
<a name="l00179"></a>00179 <span class="comment"> /// Poll the motor and step it if a step is due, implementing</span>
|
||||
<a name="l00180"></a>00180 <span class="comment"> /// accelerations and decelerations to achive the ratget position. You must call this as</span>
|
||||
<a name="l00181"></a>00181 <span class="comment"> /// fequently as possible, but at least once per minimum step interval,</span>
|
||||
<a name="l00182"></a>00182 <span class="comment"> /// preferably in your main loop.</span>
|
||||
<a name="l00183"></a>00183 <span class="comment"> /// \return true if the motor is at the target position.</span>
|
||||
<a name="l00184"></a>00184 <span class="comment"></span> <span class="keywordtype">boolean</span> <a class="code" href="classAccelStepper.html#608b2395b64ac15451d16d0371fe13ce">run</a>();
|
||||
<a name="l00185"></a>00185 <span class="comment"></span>
|
||||
<a name="l00186"></a>00186 <span class="comment"> /// Poll the motor and step it if a step is due, implmenting a constant</span>
|
||||
<a name="l00187"></a>00187 <span class="comment"> /// speed as set by the most recent call to setSpeed().</span>
|
||||
<a name="l00188"></a>00188 <span class="comment"> /// \return true if the motor was stepped.</span>
|
||||
<a name="l00189"></a>00189 <span class="comment"></span> <span class="keywordtype">boolean</span> <a class="code" href="classAccelStepper.html#a4a6bdf99f698284faaeb5542b0b7514">runSpeed</a>();
|
||||
<a name="l00190"></a>00190 <span class="comment"></span>
|
||||
<a name="l00191"></a>00191 <span class="comment"> /// Sets the maximum permitted speed. the run() function will accelerate</span>
|
||||
<a name="l00192"></a>00192 <span class="comment"> /// up to the speed set by this function.</span>
|
||||
<a name="l00193"></a>00193 <span class="comment"> /// \param[in] speed The desired maximum speed in steps per second. Must</span>
|
||||
<a name="l00194"></a>00194 <span class="comment"> /// be > 0. Speeds of more than 1000 steps per second are unreliable. </span>
|
||||
<a name="l00195"></a>00195 <span class="comment"></span> <span class="keywordtype">void</span> <a class="code" href="classAccelStepper.html#bee8d466229b87accba33d6ec929c18f">setMaxSpeed</a>(<span class="keywordtype">float</span> <a class="code" href="classAccelStepper.html#4f0989d0ae264e7eadfe1fa720769fb6">speed</a>);
|
||||
<a name="l00196"></a>00196 <span class="comment"></span>
|
||||
<a name="l00197"></a>00197 <span class="comment"> /// Sets the acceleration and deceleration parameter.</span>
|
||||
<a name="l00198"></a>00198 <span class="comment"> /// \param[in] acceleration The desired acceleration in steps per second</span>
|
||||
<a name="l00199"></a>00199 <span class="comment"> /// per second. Must be > 0.</span>
|
||||
<a name="l00200"></a>00200 <span class="comment"></span> <span class="keywordtype">void</span> <a class="code" href="classAccelStepper.html#dfb19e3cd2a028a1fe78131787604fd1">setAcceleration</a>(<span class="keywordtype">float</span> acceleration);
|
||||
<a name="l00201"></a>00201 <span class="comment"></span>
|
||||
<a name="l00202"></a>00202 <span class="comment"> /// Sets the desired constant speed for use with runSpeed().</span>
|
||||
<a name="l00203"></a>00203 <span class="comment"> /// \param[in] speed The desired constant speed in steps per</span>
|
||||
<a name="l00204"></a>00204 <span class="comment"> /// second. Positive is clockwise. Speeds of more than 1000 steps per</span>
|
||||
<a name="l00205"></a>00205 <span class="comment"> /// second are unreliable. Very slow speeds may be set (eg 0.00027777 for</span>
|
||||
<a name="l00206"></a>00206 <span class="comment"> /// once per hour, approximately. Speed accuracy depends on the Arduino</span>
|
||||
<a name="l00207"></a>00207 <span class="comment"> /// crystal. Jitter depends on how frequently you call the runSpeed() function.</span>
|
||||
<a name="l00208"></a>00208 <span class="comment"></span> <span class="keywordtype">void</span> <a class="code" href="classAccelStepper.html#e79c49ad69d5ccc9da0ee691fa4ca235">setSpeed</a>(<span class="keywordtype">float</span> speed);
|
||||
<a name="l00209"></a>00209 <span class="comment"></span>
|
||||
<a name="l00210"></a>00210 <span class="comment"> /// The most recently set speed</span>
|
||||
<a name="l00211"></a>00211 <span class="comment"> /// \return the most recent speed in steps per second</span>
|
||||
<a name="l00212"></a>00212 <span class="comment"></span> <span class="keywordtype">float</span> <a class="code" href="classAccelStepper.html#4f0989d0ae264e7eadfe1fa720769fb6">speed</a>();
|
||||
<a name="l00213"></a>00213 <span class="comment"></span>
|
||||
<a name="l00214"></a>00214 <span class="comment"> /// The distance from the current position to the target position.</span>
|
||||
<a name="l00215"></a>00215 <span class="comment"> /// \return the distance from the current position to the target position</span>
|
||||
<a name="l00216"></a>00216 <span class="comment"> /// in steps. Positive is clockwise from the current position.</span>
|
||||
<a name="l00217"></a>00217 <span class="comment"></span> <span class="keywordtype">long</span> <a class="code" href="classAccelStepper.html#748665c3962e66fbc0e9373eb14c69c1">distanceToGo</a>();
|
||||
<a name="l00218"></a>00218 <span class="comment"></span>
|
||||
<a name="l00219"></a>00219 <span class="comment"> /// The most recently set target position.</span>
|
||||
<a name="l00220"></a>00220 <span class="comment"> /// \return the target position</span>
|
||||
<a name="l00221"></a>00221 <span class="comment"> /// in steps. Positive is clockwise from the 0 position.</span>
|
||||
<a name="l00222"></a>00222 <span class="comment"></span> <span class="keywordtype">long</span> <a class="code" href="classAccelStepper.html#96685e0945b7cf75d5959da679cd911e">targetPosition</a>();
|
||||
<a name="l00223"></a>00223
|
||||
<a name="l00224"></a>00224 <span class="comment"></span>
|
||||
<a name="l00225"></a>00225 <span class="comment"> /// The currently motor position.</span>
|
||||
<a name="l00226"></a>00226 <span class="comment"> /// \return the current motor position</span>
|
||||
<a name="l00227"></a>00227 <span class="comment"> /// in steps. Positive is clockwise from the 0 position.</span>
|
||||
<a name="l00228"></a>00228 <span class="comment"></span> <span class="keywordtype">long</span> <a class="code" href="classAccelStepper.html#5dce13ab2a1b02b8f443318886bf6fc5">currentPosition</a>();
|
||||
<a name="l00229"></a>00229 <span class="comment"></span>
|
||||
<a name="l00230"></a>00230 <span class="comment"> /// Resets the current position of the motor, so that wherever the motor</span>
|
||||
<a name="l00231"></a>00231 <span class="comment"> /// happens to be right now is considered to be the new 0 position. Useful</span>
|
||||
<a name="l00232"></a>00232 <span class="comment"> /// for setting a zero position on a stepper after an initial hardware</span>
|
||||
<a name="l00233"></a>00233 <span class="comment"> /// positioning move.</span>
|
||||
<a name="l00234"></a>00234 <span class="comment"> /// Has the side effect of setting the current motor speed to 0.</span>
|
||||
<a name="l00235"></a>00235 <span class="comment"> /// \param[in] position The position in steps of wherever the motor</span>
|
||||
<a name="l00236"></a>00236 <span class="comment"> /// happens to be right now.</span>
|
||||
<a name="l00237"></a>00237 <span class="comment"></span> <span class="keywordtype">void</span> <a class="code" href="classAccelStepper.html#9d917f014317fb9d3b5dc14e66f6c689">setCurrentPosition</a>(<span class="keywordtype">long</span> position);
|
||||
<a name="l00238"></a>00238 <span class="comment"></span>
|
||||
<a name="l00239"></a>00239 <span class="comment"> /// Moves the motor to the target position and blocks until it is at</span>
|
||||
<a name="l00240"></a>00240 <span class="comment"> /// position. Dont use this in event loops, since it blocks.</span>
|
||||
<a name="l00241"></a>00241 <span class="comment"></span> <span class="keywordtype">void</span> <a class="code" href="classAccelStepper.html#344f58fef8cc34ac5aa75ba4b665d21c">runToPosition</a>();
|
||||
<a name="l00242"></a>00242 <span class="comment"></span>
|
||||
<a name="l00243"></a>00243 <span class="comment"> /// Runs at the currently selected speed until the target position is reached</span>
|
||||
<a name="l00244"></a>00244 <span class="comment"> /// Does not implement accelerations.</span>
|
||||
<a name="l00245"></a>00245 <span class="comment"></span> <span class="keywordtype">boolean</span> <a class="code" href="classAccelStepper.html#9270d20336e76ac1fd5bcd5b9c34f301">runSpeedToPosition</a>();
|
||||
<a name="l00246"></a>00246 <span class="comment"></span>
|
||||
<a name="l00247"></a>00247 <span class="comment"> /// Moves the motor to the new target position and blocks until it is at</span>
|
||||
<a name="l00248"></a>00248 <span class="comment"> /// position. Dont use this in event loops, since it blocks.</span>
|
||||
<a name="l00249"></a>00249 <span class="comment"> /// \param[in] position The new target position.</span>
|
||||
<a name="l00250"></a>00250 <span class="comment"></span> <span class="keywordtype">void</span> <a class="code" href="classAccelStepper.html#176c5d2e4c2f21e9e92b12e39a6f0e67">runToNewPosition</a>(<span class="keywordtype">long</span> position);
|
||||
<a name="l00251"></a>00251 <span class="comment"></span>
|
||||
<a name="l00252"></a>00252 <span class="comment"> /// Disable motor pin outputs by setting them all LOW</span>
|
||||
<a name="l00253"></a>00253 <span class="comment"> /// Depending on the design of your electronics this may turn off</span>
|
||||
<a name="l00254"></a>00254 <span class="comment"> /// the power to the motor coils, saving power.</span>
|
||||
<a name="l00255"></a>00255 <span class="comment"> /// This is useful to support Arduino low power modes: disable the outputs</span>
|
||||
<a name="l00256"></a>00256 <span class="comment"> /// during sleep and then reenable with enableOutputs() before stepping</span>
|
||||
<a name="l00257"></a>00257 <span class="comment"> /// again.</span>
|
||||
<a name="l00258"></a>00258 <span class="comment"></span> <span class="keywordtype">void</span> <a class="code" href="classAccelStepper.html#3591e29a236e2935afd7f64ff6c22006">disableOutputs</a>();
|
||||
<a name="l00259"></a>00259 <span class="comment"></span>
|
||||
<a name="l00260"></a>00260 <span class="comment"> /// Enable motor pin outputs by setting the motor pins to OUTPUT</span>
|
||||
<a name="l00261"></a>00261 <span class="comment"> /// mode. Called automatically by the constructor.</span>
|
||||
<a name="l00262"></a>00262 <span class="comment"></span> <span class="keywordtype">void</span> <a class="code" href="classAccelStepper.html#a279a50d30d0413f570c692cff071643">enableOutputs</a>();
|
||||
<a name="l00263"></a>00263 <span class="comment"></span>
|
||||
<a name="l00264"></a>00264 <span class="comment"> /// Sets the minimum pulse width allowed by the stepper driver.</span>
|
||||
<a name="l00265"></a>00265 <span class="comment"> /// \param[in] minWidth The minimum pulse width in microseconds.</span>
|
||||
<a name="l00266"></a>00266 <span class="comment"></span> <span class="keywordtype">void</span> <a class="code" href="classAccelStepper.html#f4d3818e691dad5dc518308796ccf154">setMinPulseWidth</a>(<span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> minWidth);
|
||||
<a name="l00267"></a>00267 <span class="comment"></span>
|
||||
<a name="l00268"></a>00268 <span class="comment"> /// Sets the enable pin number for stepper drivers.</span>
|
||||
<a name="l00269"></a>00269 <span class="comment"> /// 0xFF indicates unused (default).</span>
|
||||
<a name="l00270"></a>00270 <span class="comment"> /// Otherwise, if a pin is set, the pin will be turned on when </span>
|
||||
<a name="l00271"></a>00271 <span class="comment"> /// enableOutputs() is called and switched off when disableOutputs() </span>
|
||||
<a name="l00272"></a>00272 <span class="comment"> /// is called.</span>
|
||||
<a name="l00273"></a>00273 <span class="comment"> /// \param[in] enablePin Arduino digital pin number for motor enable</span>
|
||||
<a name="l00274"></a>00274 <span class="comment"> /// \sa setPinsInverted</span>
|
||||
<a name="l00275"></a>00275 <span class="comment"></span> <span class="keywordtype">void</span> <a class="code" href="classAccelStepper.html#56a81c5f00d02ca19646718e88e974c0">setEnablePin</a>(uint8_t enablePin = 0xff);
|
||||
<a name="l00276"></a>00276 <span class="comment"></span>
|
||||
<a name="l00277"></a>00277 <span class="comment"> /// Sets the inversion for stepper driver pins</span>
|
||||
<a name="l00278"></a>00278 <span class="comment"> /// \param[in] direction True for inverted direction pin, false for non-inverted</span>
|
||||
<a name="l00279"></a>00279 <span class="comment"> /// \param[in] step True for inverted step pin, false for non-inverted</span>
|
||||
<a name="l00280"></a>00280 <span class="comment"> /// \param[in] enable True for inverted enable pin, false (default) for non-inverted</span>
|
||||
<a name="l00281"></a>00281 <span class="comment"></span> <span class="keywordtype">void</span> <a class="code" href="classAccelStepper.html#797b4bdb580d4ca7a1cfeabe3df0de35">setPinsInverted</a>(<span class="keywordtype">bool</span> direction, <span class="keywordtype">bool</span> <a class="code" href="classAccelStepper.html#3c9a220819d2451f79ff8a0c0a395b9f">step</a>, <span class="keywordtype">bool</span> enable = <span class="keyword">false</span>);
|
||||
<a name="l00282"></a>00282
|
||||
<a name="l00283"></a>00283 <span class="keyword">protected</span>:
|
||||
<a name="l00284"></a>00284 <span class="comment"></span>
|
||||
<a name="l00285"></a>00285 <span class="comment"> /// Forces the library to compute a new instantaneous speed and set that as</span>
|
||||
<a name="l00286"></a>00286 <span class="comment"> /// the current speed. Calls</span>
|
||||
<a name="l00287"></a>00287 <span class="comment"> /// desiredSpeed(), which can be overridden by subclasses. It is called by</span>
|
||||
<a name="l00288"></a>00288 <span class="comment"> /// the library:</span>
|
||||
<a name="l00289"></a>00289 <span class="comment"> /// \li after each step</span>
|
||||
<a name="l00290"></a>00290 <span class="comment"> /// \li after change to maxSpeed through setMaxSpeed()</span>
|
||||
<a name="l00291"></a>00291 <span class="comment"> /// \li after change to acceleration through setAcceleration()</span>
|
||||
<a name="l00292"></a>00292 <span class="comment"> /// \li after change to target position (relative or absolute) through</span>
|
||||
<a name="l00293"></a>00293 <span class="comment"> /// move() or moveTo()</span>
|
||||
<a name="l00294"></a>00294 <span class="comment"></span> <span class="keywordtype">void</span> <a class="code" href="classAccelStepper.html#ffbee789b5c19165846cf0409860ae79">computeNewSpeed</a>();
|
||||
<a name="l00295"></a>00295 <span class="comment"></span>
|
||||
<a name="l00296"></a>00296 <span class="comment"> /// Called to execute a step. Only called when a new step is</span>
|
||||
<a name="l00297"></a>00297 <span class="comment"> /// required. Subclasses may override to implement new stepping</span>
|
||||
<a name="l00298"></a>00298 <span class="comment"> /// interfaces. The default calls step1(), step2(), step4() or step8() depending on the</span>
|
||||
<a name="l00299"></a>00299 <span class="comment"> /// number of pins defined for the stepper.</span>
|
||||
<a name="l00300"></a>00300 <span class="comment"> /// \param[in] step The current step phase number (0 to 7)</span>
|
||||
<a name="l00301"></a>00301 <span class="comment"></span> <span class="keyword">virtual</span> <span class="keywordtype">void</span> <a class="code" href="classAccelStepper.html#3c9a220819d2451f79ff8a0c0a395b9f">step</a>(uint8_t step);
|
||||
<a name="l00302"></a>00302 <span class="comment"></span>
|
||||
<a name="l00303"></a>00303 <span class="comment"> /// Called to execute a step using stepper functions (pins = 0) Only called when a new step is</span>
|
||||
<a name="l00304"></a>00304 <span class="comment"> /// required. Calls _forward() or _backward() to perform the step</span>
|
||||
<a name="l00305"></a>00305 <span class="comment"></span> <span class="keyword">virtual</span> <span class="keywordtype">void</span> <a class="code" href="classAccelStepper.html#889f109756aa4c0a2feefebd8081a337">step0</a>(<span class="keywordtype">void</span>);
|
||||
<a name="l00306"></a>00306 <span class="comment"></span>
|
||||
<a name="l00307"></a>00307 <span class="comment"> /// Called to execute a step on a stepper drover (ie where pins == 1). Only called when a new step is</span>
|
||||
<a name="l00308"></a>00308 <span class="comment"> /// required. Subclasses may override to implement new stepping</span>
|
||||
<a name="l00309"></a>00309 <span class="comment"> /// interfaces. The default sets or clears the outputs of Step pin1 to step, </span>
|
||||
<a name="l00310"></a>00310 <span class="comment"> /// and sets the output of _pin2 to the desired direction. The Step pin (_pin1) is pulsed for 1 microsecond</span>
|
||||
<a name="l00311"></a>00311 <span class="comment"> /// which is the minimum STEP pulse width for the 3967 driver.</span>
|
||||
<a name="l00312"></a>00312 <span class="comment"> /// \param[in] step The current step phase number (0 to 7)</span>
|
||||
<a name="l00313"></a>00313 <span class="comment"></span> <span class="keyword">virtual</span> <span class="keywordtype">void</span> <a class="code" href="classAccelStepper.html#cc64254ea242b53588e948335fd9305f">step1</a>(uint8_t step);
|
||||
<a name="l00314"></a>00314 <span class="comment"></span>
|
||||
<a name="l00315"></a>00315 <span class="comment"> /// Called to execute a step on a 2 pin motor. Only called when a new step is</span>
|
||||
<a name="l00316"></a>00316 <span class="comment"> /// required. Subclasses may override to implement new stepping</span>
|
||||
<a name="l00317"></a>00317 <span class="comment"> /// interfaces. The default sets or clears the outputs of pin1 and pin2</span>
|
||||
<a name="l00318"></a>00318 <span class="comment"> /// \param[in] step The current step phase number (0 to 7)</span>
|
||||
<a name="l00319"></a>00319 <span class="comment"></span> <span class="keyword">virtual</span> <span class="keywordtype">void</span> <a class="code" href="classAccelStepper.html#88f11bf6361fe002585f731d34fe2e8b">step2</a>(uint8_t step);
|
||||
<a name="l00320"></a>00320 <span class="comment"></span>
|
||||
<a name="l00321"></a>00321 <span class="comment"> /// Called to execute a step on a 4 pin motor. Only called when a new step is</span>
|
||||
<a name="l00322"></a>00322 <span class="comment"> /// required. Subclasses may override to implement new stepping</span>
|
||||
<a name="l00323"></a>00323 <span class="comment"> /// interfaces. The default sets or clears the outputs of pin1, pin2,</span>
|
||||
<a name="l00324"></a>00324 <span class="comment"> /// pin3, pin4.</span>
|
||||
<a name="l00325"></a>00325 <span class="comment"> /// \param[in] step The current step phase number (0 to 7)</span>
|
||||
<a name="l00326"></a>00326 <span class="comment"></span> <span class="keyword">virtual</span> <span class="keywordtype">void</span> <a class="code" href="classAccelStepper.html#49e448d179bbe4e0f8003a3f9993789d">step4</a>(uint8_t step);
|
||||
<a name="l00327"></a>00327 <span class="comment"></span>
|
||||
<a name="l00328"></a>00328 <span class="comment"> /// Called to execute a step on a 4 pin half-steper motor. Only called when a new step is</span>
|
||||
<a name="l00329"></a>00329 <span class="comment"> /// required. Subclasses may override to implement new stepping</span>
|
||||
<a name="l00330"></a>00330 <span class="comment"> /// interfaces. The default sets or clears the outputs of pin1, pin2,</span>
|
||||
<a name="l00331"></a>00331 <span class="comment"> /// pin3, pin4.</span>
|
||||
<a name="l00332"></a>00332 <span class="comment"> /// \param[in] step The current step phase number (0 to 7)</span>
|
||||
<a name="l00333"></a>00333 <span class="comment"></span> <span class="keyword">virtual</span> <span class="keywordtype">void</span> <a class="code" href="classAccelStepper.html#5b33d1088e2beaf2176c42b08fb675ea">step8</a>(uint8_t step);
|
||||
<a name="l00334"></a>00334 <span class="comment"></span>
|
||||
<a name="l00335"></a>00335 <span class="comment"> /// Compute and return the desired speed. The default algorithm uses</span>
|
||||
<a name="l00336"></a>00336 <span class="comment"> /// maxSpeed, acceleration and the current speed to set a new speed to</span>
|
||||
<a name="l00337"></a>00337 <span class="comment"> /// move the motor from teh current position to the target</span>
|
||||
<a name="l00338"></a>00338 <span class="comment"> /// position. Subclasses may override this to provide an alternate</span>
|
||||
<a name="l00339"></a>00339 <span class="comment"> /// algorithm (but do not block). Called by computeNewSpeed whenever a new speed neds to be</span>
|
||||
<a name="l00340"></a>00340 <span class="comment"> /// computed. </span>
|
||||
<a name="l00341"></a>00341 <span class="comment"></span> <span class="keyword">virtual</span> <span class="keywordtype">float</span> <a class="code" href="classAccelStepper.html#6e4bd79c395e69beee31d76d0d3287e4">desiredSpeed</a>();
|
||||
<a name="l00342"></a>00342
|
||||
<a name="l00343"></a>00343 <span class="keyword">private</span>:<span class="comment"></span>
|
||||
<a name="l00344"></a>00344 <span class="comment"> /// Number of pins on the stepper motor. Permits 2 or 4. 2 pins is a</span>
|
||||
<a name="l00345"></a>00345 <span class="comment"> /// bipolar, and 4 pins is a unipolar.</span>
|
||||
<a name="l00346"></a>00346 <span class="comment"></span> uint8_t _pins; <span class="comment">// 2 or 4</span>
|
||||
<a name="l00347"></a>00347 <span class="comment"></span>
|
||||
<a name="l00348"></a>00348 <span class="comment"> /// Arduino pin number for the 2 or 4 pins required to interface to the</span>
|
||||
<a name="l00349"></a>00349 <span class="comment"> /// stepper motor.</span>
|
||||
<a name="l00350"></a>00350 <span class="comment"></span> uint8_t _pin1, _pin2, _pin3, _pin4;
|
||||
<a name="l00351"></a>00351 <span class="comment"></span>
|
||||
<a name="l00352"></a>00352 <span class="comment"> /// The current absolution position in steps.</span>
|
||||
<a name="l00353"></a>00353 <span class="comment"></span> <span class="keywordtype">long</span> _currentPos; <span class="comment">// Steps</span>
|
||||
<a name="l00354"></a>00354 <span class="comment"></span>
|
||||
<a name="l00355"></a>00355 <span class="comment"> /// The target position in steps. The AccelStepper library will move the</span>
|
||||
<a name="l00356"></a>00356 <span class="comment"> /// motor from the _currentPos to the _targetPos, taking into account the</span>
|
||||
<a name="l00357"></a>00357 <span class="comment"> /// max speed, acceleration and deceleration</span>
|
||||
<a name="l00358"></a>00358 <span class="comment"></span> <span class="keywordtype">long</span> _targetPos; <span class="comment">// Steps</span>
|
||||
<a name="l00359"></a>00359 <span class="comment"></span>
|
||||
<a name="l00360"></a>00360 <span class="comment"> /// The current motos speed in steps per second</span>
|
||||
<a name="l00361"></a>00361 <span class="comment"> /// Positive is clockwise</span>
|
||||
<a name="l00362"></a>00362 <span class="comment"></span> <span class="keywordtype">float</span> _speed; <span class="comment">// Steps per second</span>
|
||||
<a name="l00363"></a>00363 <span class="comment"></span>
|
||||
<a name="l00364"></a>00364 <span class="comment"> /// The maximum permitted speed in steps per second. Must be > 0.</span>
|
||||
<a name="l00365"></a>00365 <span class="comment"></span> <span class="keywordtype">float</span> _maxSpeed;
|
||||
<a name="l00366"></a>00366 <span class="comment"></span>
|
||||
<a name="l00367"></a>00367 <span class="comment"> /// The acceleration to use to accelerate or decelerate the motor in steps</span>
|
||||
<a name="l00368"></a>00368 <span class="comment"> /// per second per second. Must be > 0</span>
|
||||
<a name="l00369"></a>00369 <span class="comment"></span> <span class="keywordtype">float</span> _acceleration;
|
||||
<a name="l00370"></a>00370 <span class="comment"></span>
|
||||
<a name="l00371"></a>00371 <span class="comment"> /// The current interval between steps in microseconds</span>
|
||||
<a name="l00372"></a>00372 <span class="comment"></span> <span class="keywordtype">unsigned</span> <span class="keywordtype">long</span> _stepInterval;
|
||||
<a name="l00373"></a>00373 <span class="comment"></span>
|
||||
<a name="l00374"></a>00374 <span class="comment"> /// The last step time in microseconds</span>
|
||||
<a name="l00375"></a>00375 <span class="comment"></span> <span class="keywordtype">unsigned</span> <span class="keywordtype">long</span> _lastStepTime;
|
||||
<a name="l00376"></a>00376 <span class="comment"></span>
|
||||
<a name="l00377"></a>00377 <span class="comment"> /// The minimum allowed pulse width in microseconds</span>
|
||||
<a name="l00378"></a>00378 <span class="comment"></span> <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> _minPulseWidth;
|
||||
<a name="l00379"></a>00379 <span class="comment"></span>
|
||||
<a name="l00380"></a>00380 <span class="comment"> /// Is the direction pin inverted?</span>
|
||||
<a name="l00381"></a>00381 <span class="comment"></span> <span class="keywordtype">bool</span> _dirInverted;
|
||||
<a name="l00382"></a>00382 <span class="comment"></span>
|
||||
<a name="l00383"></a>00383 <span class="comment"> /// Is the step pin inverted?</span>
|
||||
<a name="l00384"></a>00384 <span class="comment"></span> <span class="keywordtype">bool</span> _stepInverted;
|
||||
<a name="l00385"></a>00385 <span class="comment"></span>
|
||||
<a name="l00386"></a>00386 <span class="comment"> /// Is the enable pin inverted?</span>
|
||||
<a name="l00387"></a>00387 <span class="comment"></span> <span class="keywordtype">bool</span> _enableInverted;
|
||||
<a name="l00388"></a>00388 <span class="comment"></span>
|
||||
<a name="l00389"></a>00389 <span class="comment"> /// Enable pin for stepper driver, or 0xFF if unused.</span>
|
||||
<a name="l00390"></a>00390 <span class="comment"></span> uint8_t _enablePin;
|
||||
<a name="l00391"></a>00391
|
||||
<a name="l00392"></a>00392 <span class="comment">// The pointer to a forward-step procedure</span>
|
||||
<a name="l00393"></a>00393 void (*_forward)();
|
||||
<a name="l00394"></a>00394
|
||||
<a name="l00395"></a>00395 <span class="comment">// The pointer to a backward-step procedure</span>
|
||||
<a name="l00396"></a>00396 void (*_backward)();
|
||||
<a name="l00397"></a>00397 };
|
||||
<a name="l00398"></a>00398
|
||||
<a name="l00399"></a>00399 <span class="preprocessor">#endif </span>
|
||||
</pre></div></div>
|
||||
<hr size="1"><address style="text-align: right;"><small>Generated on Sun Jan 8 17:27:41 2012 for AccelStepper by
|
||||
<a href="http://www.doxygen.org/index.html">
|
||||
<img src="doxygen.png" alt="doxygen" align="middle" border="0"></a> 1.5.6 </small></address>
|
||||
</body>
|
||||
</html>
|
||||
58
arduino-cli/libraries/AccelStepper/doc/annotated.html
Normal file
58
arduino-cli/libraries/AccelStepper/doc/annotated.html
Normal file
@@ -0,0 +1,58 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=9"/>
|
||||
<meta name="generator" content="Doxygen 1.8.13"/>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1"/>
|
||||
<title>AccelStepper: Class List</title>
|
||||
<link href="tabs.css" rel="stylesheet" type="text/css"/>
|
||||
<script type="text/javascript" src="jquery.js"></script>
|
||||
<script type="text/javascript" src="dynsections.js"></script>
|
||||
<link href="doxygen.css" rel="stylesheet" type="text/css" />
|
||||
</head>
|
||||
<body>
|
||||
<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
|
||||
<div id="titlearea">
|
||||
<table cellspacing="0" cellpadding="0">
|
||||
<tbody>
|
||||
<tr style="height: 56px;">
|
||||
<td id="projectalign" style="padding-left: 0.5em;">
|
||||
<div id="projectname">AccelStepper
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<!-- end header part -->
|
||||
<!-- Generated by Doxygen 1.8.13 -->
|
||||
<script type="text/javascript" src="menudata.js"></script>
|
||||
<script type="text/javascript" src="menu.js"></script>
|
||||
<script type="text/javascript">
|
||||
$(function() {
|
||||
initMenu('',false,false,'search.php','Search');
|
||||
});
|
||||
</script>
|
||||
<div id="main-nav"></div>
|
||||
</div><!-- top -->
|
||||
<div class="header">
|
||||
<div class="headertitle">
|
||||
<div class="title">Class List</div> </div>
|
||||
</div><!--header-->
|
||||
<div class="contents">
|
||||
<div class="textblock">Here are the classes, structs, unions and interfaces with brief descriptions:</div><div class="directory">
|
||||
<table class="directory">
|
||||
<tr id="row_0_" class="even"><td class="entry"><span style="width:16px;display:inline-block;"> </span><span class="icona"><span class="icon">C</span></span><a class="el" href="classAccelStepper.html" target="_self">AccelStepper</a></td><td class="desc">Support for stepper motors with acceleration etc </td></tr>
|
||||
<tr id="row_1_"><td class="entry"><span style="width:16px;display:inline-block;"> </span><span class="icona"><span class="icon">C</span></span><a class="el" href="classMultiStepper.html" target="_self">MultiStepper</a></td><td class="desc">Operate multiple AccelSteppers in a co-ordinated fashion </td></tr>
|
||||
</table>
|
||||
</div><!-- directory -->
|
||||
</div><!-- contents -->
|
||||
<!-- start footer part -->
|
||||
<hr class="footer"/><address class="footer"><small>
|
||||
Generated by  <a href="http://www.doxygen.org/index.html">
|
||||
<img class="footer" src="doxygen.png" alt="doxygen"/>
|
||||
</a> 1.8.13
|
||||
</small></address>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,103 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=9"/>
|
||||
<meta name="generator" content="Doxygen 1.8.13"/>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1"/>
|
||||
<title>AccelStepper: Member List</title>
|
||||
<link href="tabs.css" rel="stylesheet" type="text/css"/>
|
||||
<script type="text/javascript" src="jquery.js"></script>
|
||||
<script type="text/javascript" src="dynsections.js"></script>
|
||||
<link href="doxygen.css" rel="stylesheet" type="text/css" />
|
||||
</head>
|
||||
<body>
|
||||
<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
|
||||
<div id="titlearea">
|
||||
<table cellspacing="0" cellpadding="0">
|
||||
<tbody>
|
||||
<tr style="height: 56px;">
|
||||
<td id="projectalign" style="padding-left: 0.5em;">
|
||||
<div id="projectname">AccelStepper
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<!-- end header part -->
|
||||
<!-- Generated by Doxygen 1.8.13 -->
|
||||
<script type="text/javascript" src="menudata.js"></script>
|
||||
<script type="text/javascript" src="menu.js"></script>
|
||||
<script type="text/javascript">
|
||||
$(function() {
|
||||
initMenu('',false,false,'search.php','Search');
|
||||
});
|
||||
</script>
|
||||
<div id="main-nav"></div>
|
||||
</div><!-- top -->
|
||||
<div class="header">
|
||||
<div class="headertitle">
|
||||
<div class="title">AccelStepper Member List</div> </div>
|
||||
</div><!--header-->
|
||||
<div class="contents">
|
||||
|
||||
<p>This is the complete list of members for <a class="el" href="classAccelStepper.html">AccelStepper</a>, including all inherited members.</p>
|
||||
<table class="directory">
|
||||
<tr class="even"><td class="entry"><a class="el" href="classAccelStepper.html#a35162cdf8ed9a98f98984c177d5ade58">_direction</a></td><td class="entry"><a class="el" href="classAccelStepper.html">AccelStepper</a></td><td class="entry"><span class="mlabel">protected</span></td></tr>
|
||||
<tr><td class="entry"><a class="el" href="classAccelStepper.html#a3bc75bd6571b98a6177838ca81ac39ab">AccelStepper</a>(uint8_t interface=AccelStepper::FULL4WIRE, uint8_t pin1=2, uint8_t pin2=3, uint8_t pin3=4, uint8_t pin4=5, bool enable=true)</td><td class="entry"><a class="el" href="classAccelStepper.html">AccelStepper</a></td><td class="entry"></td></tr>
|
||||
<tr class="even"><td class="entry"><a class="el" href="classAccelStepper.html#afa3061ce813303a8f2fa206ee8d012bd">AccelStepper</a>(void(*forward)(), void(*backward)())</td><td class="entry"><a class="el" href="classAccelStepper.html">AccelStepper</a></td><td class="entry"></td></tr>
|
||||
<tr><td class="entry"><a class="el" href="classAccelStepper.html#affbee789b5c19165846cf0409860ae79">computeNewSpeed</a>()</td><td class="entry"><a class="el" href="classAccelStepper.html">AccelStepper</a></td><td class="entry"><span class="mlabel">protected</span></td></tr>
|
||||
<tr class="even"><td class="entry"><a class="el" href="classAccelStepper.html#a5dce13ab2a1b02b8f443318886bf6fc5">currentPosition</a>()</td><td class="entry"><a class="el" href="classAccelStepper.html">AccelStepper</a></td><td class="entry"></td></tr>
|
||||
<tr><td class="entry"><a class="el" href="classAccelStepper.html#a7468f91a925c689c3ba250f8d074d228">Direction</a> enum name</td><td class="entry"><a class="el" href="classAccelStepper.html">AccelStepper</a></td><td class="entry"><span class="mlabel">protected</span></td></tr>
|
||||
<tr class="even"><td class="entry"><a class="el" href="classAccelStepper.html#a7468f91a925c689c3ba250f8d074d228a6959a4549f734bd771d418f995ba4fb4">DIRECTION_CCW</a> enum value</td><td class="entry"><a class="el" href="classAccelStepper.html">AccelStepper</a></td><td class="entry"><span class="mlabel">protected</span></td></tr>
|
||||
<tr><td class="entry"><a class="el" href="classAccelStepper.html#a7468f91a925c689c3ba250f8d074d228ad604e0047f7cb47662c5a1cf6999337c">DIRECTION_CW</a> enum value</td><td class="entry"><a class="el" href="classAccelStepper.html">AccelStepper</a></td><td class="entry"><span class="mlabel">protected</span></td></tr>
|
||||
<tr class="even"><td class="entry"><a class="el" href="classAccelStepper.html#a3591e29a236e2935afd7f64ff6c22006">disableOutputs</a>()</td><td class="entry"><a class="el" href="classAccelStepper.html">AccelStepper</a></td><td class="entry"><span class="mlabel">virtual</span></td></tr>
|
||||
<tr><td class="entry"><a class="el" href="classAccelStepper.html#a748665c3962e66fbc0e9373eb14c69c1">distanceToGo</a>()</td><td class="entry"><a class="el" href="classAccelStepper.html">AccelStepper</a></td><td class="entry"></td></tr>
|
||||
<tr class="even"><td class="entry"><a class="el" href="classAccelStepper.html#a73bdecf1273d98d8c5fbcb764cabeea5ac3523e4cf6763ba518d16fec3708ef23">DRIVER</a> enum value</td><td class="entry"><a class="el" href="classAccelStepper.html">AccelStepper</a></td><td class="entry"></td></tr>
|
||||
<tr><td class="entry"><a class="el" href="classAccelStepper.html#aa279a50d30d0413f570c692cff071643">enableOutputs</a>()</td><td class="entry"><a class="el" href="classAccelStepper.html">AccelStepper</a></td><td class="entry"><span class="mlabel">virtual</span></td></tr>
|
||||
<tr class="even"><td class="entry"><a class="el" href="classAccelStepper.html#a73bdecf1273d98d8c5fbcb764cabeea5a62a305b52f749ff8c89138273fbb012d">FULL2WIRE</a> enum value</td><td class="entry"><a class="el" href="classAccelStepper.html">AccelStepper</a></td><td class="entry"></td></tr>
|
||||
<tr><td class="entry"><a class="el" href="classAccelStepper.html#a73bdecf1273d98d8c5fbcb764cabeea5a0b8eea5cf0f8ce70b1959d2977ccc996">FULL3WIRE</a> enum value</td><td class="entry"><a class="el" href="classAccelStepper.html">AccelStepper</a></td><td class="entry"></td></tr>
|
||||
<tr class="even"><td class="entry"><a class="el" href="classAccelStepper.html#a73bdecf1273d98d8c5fbcb764cabeea5adedd394a375190a3df8d4519c0d4dc2f">FULL4WIRE</a> enum value</td><td class="entry"><a class="el" href="classAccelStepper.html">AccelStepper</a></td><td class="entry"></td></tr>
|
||||
<tr><td class="entry"><a class="el" href="classAccelStepper.html#a73bdecf1273d98d8c5fbcb764cabeea5af5bb99ad9d67ad2d85f840e3abcfe068">FUNCTION</a> enum value</td><td class="entry"><a class="el" href="classAccelStepper.html">AccelStepper</a></td><td class="entry"></td></tr>
|
||||
<tr class="even"><td class="entry"><a class="el" href="classAccelStepper.html#a73bdecf1273d98d8c5fbcb764cabeea5a00c2387a5af43d8e97639699ab7a5c7f">HALF3WIRE</a> enum value</td><td class="entry"><a class="el" href="classAccelStepper.html">AccelStepper</a></td><td class="entry"></td></tr>
|
||||
<tr><td class="entry"><a class="el" href="classAccelStepper.html#a73bdecf1273d98d8c5fbcb764cabeea5aecc0900c55b777d2e885581b8c434b07">HALF4WIRE</a> enum value</td><td class="entry"><a class="el" href="classAccelStepper.html">AccelStepper</a></td><td class="entry"></td></tr>
|
||||
<tr class="even"><td class="entry"><a class="el" href="classAccelStepper.html#a3a60cc0b962f8ceb81ee1e6f36443ceb">isRunning</a>()</td><td class="entry"><a class="el" href="classAccelStepper.html">AccelStepper</a></td><td class="entry"></td></tr>
|
||||
<tr><td class="entry"><a class="el" href="classAccelStepper.html#a6123a1dfb4495d8bd2646288eae60d7f">maxSpeed</a>()</td><td class="entry"><a class="el" href="classAccelStepper.html">AccelStepper</a></td><td class="entry"></td></tr>
|
||||
<tr class="even"><td class="entry"><a class="el" href="classAccelStepper.html#a73bdecf1273d98d8c5fbcb764cabeea5">MotorInterfaceType</a> enum name</td><td class="entry"><a class="el" href="classAccelStepper.html">AccelStepper</a></td><td class="entry"></td></tr>
|
||||
<tr><td class="entry"><a class="el" href="classAccelStepper.html#a68942c66e78fb7f7b5f0cdade6eb7f06">move</a>(long relative)</td><td class="entry"><a class="el" href="classAccelStepper.html">AccelStepper</a></td><td class="entry"></td></tr>
|
||||
<tr class="even"><td class="entry"><a class="el" href="classAccelStepper.html#ace236ede35f87c63d18da25810ec9736">moveTo</a>(long absolute)</td><td class="entry"><a class="el" href="classAccelStepper.html">AccelStepper</a></td><td class="entry"></td></tr>
|
||||
<tr><td class="entry"><a class="el" href="classAccelStepper.html#a608b2395b64ac15451d16d0371fe13ce">run</a>()</td><td class="entry"><a class="el" href="classAccelStepper.html">AccelStepper</a></td><td class="entry"></td></tr>
|
||||
<tr class="even"><td class="entry"><a class="el" href="classAccelStepper.html#aa4a6bdf99f698284faaeb5542b0b7514">runSpeed</a>()</td><td class="entry"><a class="el" href="classAccelStepper.html">AccelStepper</a></td><td class="entry"></td></tr>
|
||||
<tr><td class="entry"><a class="el" href="classAccelStepper.html#a9270d20336e76ac1fd5bcd5b9c34f301">runSpeedToPosition</a>()</td><td class="entry"><a class="el" href="classAccelStepper.html">AccelStepper</a></td><td class="entry"></td></tr>
|
||||
<tr class="even"><td class="entry"><a class="el" href="classAccelStepper.html#a176c5d2e4c2f21e9e92b12e39a6f0e67">runToNewPosition</a>(long position)</td><td class="entry"><a class="el" href="classAccelStepper.html">AccelStepper</a></td><td class="entry"></td></tr>
|
||||
<tr><td class="entry"><a class="el" href="classAccelStepper.html#a344f58fef8cc34ac5aa75ba4b665d21c">runToPosition</a>()</td><td class="entry"><a class="el" href="classAccelStepper.html">AccelStepper</a></td><td class="entry"></td></tr>
|
||||
<tr class="even"><td class="entry"><a class="el" href="classAccelStepper.html#adfb19e3cd2a028a1fe78131787604fd1">setAcceleration</a>(float acceleration)</td><td class="entry"><a class="el" href="classAccelStepper.html">AccelStepper</a></td><td class="entry"></td></tr>
|
||||
<tr><td class="entry"><a class="el" href="classAccelStepper.html#a9d917f014317fb9d3b5dc14e66f6c689">setCurrentPosition</a>(long position)</td><td class="entry"><a class="el" href="classAccelStepper.html">AccelStepper</a></td><td class="entry"></td></tr>
|
||||
<tr class="even"><td class="entry"><a class="el" href="classAccelStepper.html#a56a81c5f00d02ca19646718e88e974c0">setEnablePin</a>(uint8_t enablePin=0xff)</td><td class="entry"><a class="el" href="classAccelStepper.html">AccelStepper</a></td><td class="entry"></td></tr>
|
||||
<tr><td class="entry"><a class="el" href="classAccelStepper.html#abee8d466229b87accba33d6ec929c18f">setMaxSpeed</a>(float speed)</td><td class="entry"><a class="el" href="classAccelStepper.html">AccelStepper</a></td><td class="entry"></td></tr>
|
||||
<tr class="even"><td class="entry"><a class="el" href="classAccelStepper.html#af4d3818e691dad5dc518308796ccf154">setMinPulseWidth</a>(unsigned int minWidth)</td><td class="entry"><a class="el" href="classAccelStepper.html">AccelStepper</a></td><td class="entry"></td></tr>
|
||||
<tr><td class="entry"><a class="el" href="classAccelStepper.html#af3c2516b6ce7c1ecbc2004107bb2a9ce">setOutputPins</a>(uint8_t mask)</td><td class="entry"><a class="el" href="classAccelStepper.html">AccelStepper</a></td><td class="entry"><span class="mlabel">protected</span><span class="mlabel">virtual</span></td></tr>
|
||||
<tr class="even"><td class="entry"><a class="el" href="classAccelStepper.html#ac62cae590c2f9c303519a3a1c4adc8ab">setPinsInverted</a>(bool directionInvert=false, bool stepInvert=false, bool enableInvert=false)</td><td class="entry"><a class="el" href="classAccelStepper.html">AccelStepper</a></td><td class="entry"></td></tr>
|
||||
<tr><td class="entry"><a class="el" href="classAccelStepper.html#a38298ac2dd852fb22259f6c4bbe08c94">setPinsInverted</a>(bool pin1Invert, bool pin2Invert, bool pin3Invert, bool pin4Invert, bool enableInvert)</td><td class="entry"><a class="el" href="classAccelStepper.html">AccelStepper</a></td><td class="entry"></td></tr>
|
||||
<tr class="even"><td class="entry"><a class="el" href="classAccelStepper.html#ae79c49ad69d5ccc9da0ee691fa4ca235">setSpeed</a>(float speed)</td><td class="entry"><a class="el" href="classAccelStepper.html">AccelStepper</a></td><td class="entry"></td></tr>
|
||||
<tr><td class="entry"><a class="el" href="classAccelStepper.html#a4f0989d0ae264e7eadfe1fa720769fb6">speed</a>()</td><td class="entry"><a class="el" href="classAccelStepper.html">AccelStepper</a></td><td class="entry"></td></tr>
|
||||
<tr class="even"><td class="entry"><a class="el" href="classAccelStepper.html#a8a419121702399d8ac66df4cc47481f4">step</a>(long step)</td><td class="entry"><a class="el" href="classAccelStepper.html">AccelStepper</a></td><td class="entry"><span class="mlabel">protected</span><span class="mlabel">virtual</span></td></tr>
|
||||
<tr><td class="entry"><a class="el" href="classAccelStepper.html#aa2913db789e6fa05756579ff82fe6e7e">step0</a>(long step)</td><td class="entry"><a class="el" href="classAccelStepper.html">AccelStepper</a></td><td class="entry"><span class="mlabel">protected</span><span class="mlabel">virtual</span></td></tr>
|
||||
<tr class="even"><td class="entry"><a class="el" href="classAccelStepper.html#a63ef416bc039da539294e84a41e7d7dc">step1</a>(long step)</td><td class="entry"><a class="el" href="classAccelStepper.html">AccelStepper</a></td><td class="entry"><span class="mlabel">protected</span><span class="mlabel">virtual</span></td></tr>
|
||||
<tr><td class="entry"><a class="el" href="classAccelStepper.html#a674e48a6bf99e7ad1f013c1e4414565a">step2</a>(long step)</td><td class="entry"><a class="el" href="classAccelStepper.html">AccelStepper</a></td><td class="entry"><span class="mlabel">protected</span><span class="mlabel">virtual</span></td></tr>
|
||||
<tr class="even"><td class="entry"><a class="el" href="classAccelStepper.html#ad73c61aade2e10243dfb02aefa7ab8fd">step3</a>(long step)</td><td class="entry"><a class="el" href="classAccelStepper.html">AccelStepper</a></td><td class="entry"><span class="mlabel">protected</span><span class="mlabel">virtual</span></td></tr>
|
||||
<tr><td class="entry"><a class="el" href="classAccelStepper.html#a8910bd9218a54dfb7e2372a6d0bcca0c">step4</a>(long step)</td><td class="entry"><a class="el" href="classAccelStepper.html">AccelStepper</a></td><td class="entry"><span class="mlabel">protected</span><span class="mlabel">virtual</span></td></tr>
|
||||
<tr class="even"><td class="entry"><a class="el" href="classAccelStepper.html#a4b0faf1ebc0c584ab606c0c0f66986b0">step6</a>(long step)</td><td class="entry"><a class="el" href="classAccelStepper.html">AccelStepper</a></td><td class="entry"><span class="mlabel">protected</span><span class="mlabel">virtual</span></td></tr>
|
||||
<tr><td class="entry"><a class="el" href="classAccelStepper.html#aa909c6c3fcd3ea4b3ee1aa8b4d0f7e87">step8</a>(long step)</td><td class="entry"><a class="el" href="classAccelStepper.html">AccelStepper</a></td><td class="entry"><span class="mlabel">protected</span><span class="mlabel">virtual</span></td></tr>
|
||||
<tr class="even"><td class="entry"><a class="el" href="classAccelStepper.html#a638817b85aed9d5cd15c76a76c00aced">stop</a>()</td><td class="entry"><a class="el" href="classAccelStepper.html">AccelStepper</a></td><td class="entry"></td></tr>
|
||||
<tr><td class="entry"><a class="el" href="classAccelStepper.html#a96685e0945b7cf75d5959da679cd911e">targetPosition</a>()</td><td class="entry"><a class="el" href="classAccelStepper.html">AccelStepper</a></td><td class="entry"></td></tr>
|
||||
</table></div><!-- contents -->
|
||||
<!-- start footer part -->
|
||||
<hr class="footer"/><address class="footer"><small>
|
||||
Generated by  <a href="http://www.doxygen.org/index.html">
|
||||
<img class="footer" src="doxygen.png" alt="doxygen"/>
|
||||
</a> 1.8.13
|
||||
</small></address>
|
||||
</body>
|
||||
</html>
|
||||
1344
arduino-cli/libraries/AccelStepper/doc/classAccelStepper.html
Normal file
1344
arduino-cli/libraries/AccelStepper/doc/classAccelStepper.html
Normal file
File diff suppressed because it is too large
Load Diff
1596
arduino-cli/libraries/AccelStepper/doc/doxygen.css
Normal file
1596
arduino-cli/libraries/AccelStepper/doc/doxygen.css
Normal file
File diff suppressed because it is too large
Load Diff
BIN
arduino-cli/libraries/AccelStepper/doc/doxygen.png
Normal file
BIN
arduino-cli/libraries/AccelStepper/doc/doxygen.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 3.7 KiB |
58
arduino-cli/libraries/AccelStepper/doc/files.html
Normal file
58
arduino-cli/libraries/AccelStepper/doc/files.html
Normal file
@@ -0,0 +1,58 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=9"/>
|
||||
<meta name="generator" content="Doxygen 1.8.13"/>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1"/>
|
||||
<title>AccelStepper: File List</title>
|
||||
<link href="tabs.css" rel="stylesheet" type="text/css"/>
|
||||
<script type="text/javascript" src="jquery.js"></script>
|
||||
<script type="text/javascript" src="dynsections.js"></script>
|
||||
<link href="doxygen.css" rel="stylesheet" type="text/css" />
|
||||
</head>
|
||||
<body>
|
||||
<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
|
||||
<div id="titlearea">
|
||||
<table cellspacing="0" cellpadding="0">
|
||||
<tbody>
|
||||
<tr style="height: 56px;">
|
||||
<td id="projectalign" style="padding-left: 0.5em;">
|
||||
<div id="projectname">AccelStepper
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<!-- end header part -->
|
||||
<!-- Generated by Doxygen 1.8.13 -->
|
||||
<script type="text/javascript" src="menudata.js"></script>
|
||||
<script type="text/javascript" src="menu.js"></script>
|
||||
<script type="text/javascript">
|
||||
$(function() {
|
||||
initMenu('',false,false,'search.php','Search');
|
||||
});
|
||||
</script>
|
||||
<div id="main-nav"></div>
|
||||
</div><!-- top -->
|
||||
<div class="header">
|
||||
<div class="headertitle">
|
||||
<div class="title">File List</div> </div>
|
||||
</div><!--header-->
|
||||
<div class="contents">
|
||||
<div class="textblock">Here is a list of all documented files with brief descriptions:</div><div class="directory">
|
||||
<table class="directory">
|
||||
<tr id="row_0_" class="even"><td class="entry"><span style="width:16px;display:inline-block;"> </span><a href="AccelStepper_8h_source.html"><span class="icondoc"></span></a><b>AccelStepper.h</b></td><td class="desc"></td></tr>
|
||||
<tr id="row_1_"><td class="entry"><span style="width:16px;display:inline-block;"> </span><a href="MultiStepper_8h_source.html"><span class="icondoc"></span></a><b>MultiStepper.h</b></td><td class="desc"></td></tr>
|
||||
</table>
|
||||
</div><!-- directory -->
|
||||
</div><!-- contents -->
|
||||
<!-- start footer part -->
|
||||
<hr class="footer"/><address class="footer"><small>
|
||||
Generated by  <a href="http://www.doxygen.org/index.html">
|
||||
<img class="footer" src="doxygen.png" alt="doxygen"/>
|
||||
</a> 1.8.13
|
||||
</small></address>
|
||||
</body>
|
||||
</html>
|
||||
243
arduino-cli/libraries/AccelStepper/doc/functions.html
Normal file
243
arduino-cli/libraries/AccelStepper/doc/functions.html
Normal file
@@ -0,0 +1,243 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=9"/>
|
||||
<meta name="generator" content="Doxygen 1.8.13"/>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1"/>
|
||||
<title>AccelStepper: Class Members</title>
|
||||
<link href="tabs.css" rel="stylesheet" type="text/css"/>
|
||||
<script type="text/javascript" src="jquery.js"></script>
|
||||
<script type="text/javascript" src="dynsections.js"></script>
|
||||
<link href="doxygen.css" rel="stylesheet" type="text/css" />
|
||||
</head>
|
||||
<body>
|
||||
<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
|
||||
<div id="titlearea">
|
||||
<table cellspacing="0" cellpadding="0">
|
||||
<tbody>
|
||||
<tr style="height: 56px;">
|
||||
<td id="projectalign" style="padding-left: 0.5em;">
|
||||
<div id="projectname">AccelStepper
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<!-- end header part -->
|
||||
<!-- Generated by Doxygen 1.8.13 -->
|
||||
<script type="text/javascript" src="menudata.js"></script>
|
||||
<script type="text/javascript" src="menu.js"></script>
|
||||
<script type="text/javascript">
|
||||
$(function() {
|
||||
initMenu('',false,false,'search.php','Search');
|
||||
});
|
||||
</script>
|
||||
<div id="main-nav"></div>
|
||||
</div><!-- top -->
|
||||
<div class="contents">
|
||||
<div class="textblock">Here is a list of all documented class members with links to the class documentation for each member:</div>
|
||||
|
||||
<h3><a id="index__"></a>- _ -</h3><ul>
|
||||
<li>_direction
|
||||
: <a class="el" href="classAccelStepper.html#a35162cdf8ed9a98f98984c177d5ade58">AccelStepper</a>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
|
||||
<h3><a id="index_a"></a>- a -</h3><ul>
|
||||
<li>AccelStepper()
|
||||
: <a class="el" href="classAccelStepper.html#a3bc75bd6571b98a6177838ca81ac39ab">AccelStepper</a>
|
||||
</li>
|
||||
<li>addStepper()
|
||||
: <a class="el" href="classMultiStepper.html#a383d8486e17ad9de9f1bafcbd9aa52ee">MultiStepper</a>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
|
||||
<h3><a id="index_c"></a>- c -</h3><ul>
|
||||
<li>computeNewSpeed()
|
||||
: <a class="el" href="classAccelStepper.html#affbee789b5c19165846cf0409860ae79">AccelStepper</a>
|
||||
</li>
|
||||
<li>currentPosition()
|
||||
: <a class="el" href="classAccelStepper.html#a5dce13ab2a1b02b8f443318886bf6fc5">AccelStepper</a>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
|
||||
<h3><a id="index_d"></a>- d -</h3><ul>
|
||||
<li>Direction
|
||||
: <a class="el" href="classAccelStepper.html#a7468f91a925c689c3ba250f8d074d228">AccelStepper</a>
|
||||
</li>
|
||||
<li>DIRECTION_CCW
|
||||
: <a class="el" href="classAccelStepper.html#a7468f91a925c689c3ba250f8d074d228a6959a4549f734bd771d418f995ba4fb4">AccelStepper</a>
|
||||
</li>
|
||||
<li>DIRECTION_CW
|
||||
: <a class="el" href="classAccelStepper.html#a7468f91a925c689c3ba250f8d074d228ad604e0047f7cb47662c5a1cf6999337c">AccelStepper</a>
|
||||
</li>
|
||||
<li>disableOutputs()
|
||||
: <a class="el" href="classAccelStepper.html#a3591e29a236e2935afd7f64ff6c22006">AccelStepper</a>
|
||||
</li>
|
||||
<li>distanceToGo()
|
||||
: <a class="el" href="classAccelStepper.html#a748665c3962e66fbc0e9373eb14c69c1">AccelStepper</a>
|
||||
</li>
|
||||
<li>DRIVER
|
||||
: <a class="el" href="classAccelStepper.html#a73bdecf1273d98d8c5fbcb764cabeea5ac3523e4cf6763ba518d16fec3708ef23">AccelStepper</a>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
|
||||
<h3><a id="index_e"></a>- e -</h3><ul>
|
||||
<li>enableOutputs()
|
||||
: <a class="el" href="classAccelStepper.html#aa279a50d30d0413f570c692cff071643">AccelStepper</a>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
|
||||
<h3><a id="index_f"></a>- f -</h3><ul>
|
||||
<li>FULL2WIRE
|
||||
: <a class="el" href="classAccelStepper.html#a73bdecf1273d98d8c5fbcb764cabeea5a62a305b52f749ff8c89138273fbb012d">AccelStepper</a>
|
||||
</li>
|
||||
<li>FULL3WIRE
|
||||
: <a class="el" href="classAccelStepper.html#a73bdecf1273d98d8c5fbcb764cabeea5a0b8eea5cf0f8ce70b1959d2977ccc996">AccelStepper</a>
|
||||
</li>
|
||||
<li>FULL4WIRE
|
||||
: <a class="el" href="classAccelStepper.html#a73bdecf1273d98d8c5fbcb764cabeea5adedd394a375190a3df8d4519c0d4dc2f">AccelStepper</a>
|
||||
</li>
|
||||
<li>FUNCTION
|
||||
: <a class="el" href="classAccelStepper.html#a73bdecf1273d98d8c5fbcb764cabeea5af5bb99ad9d67ad2d85f840e3abcfe068">AccelStepper</a>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
|
||||
<h3><a id="index_h"></a>- h -</h3><ul>
|
||||
<li>HALF3WIRE
|
||||
: <a class="el" href="classAccelStepper.html#a73bdecf1273d98d8c5fbcb764cabeea5a00c2387a5af43d8e97639699ab7a5c7f">AccelStepper</a>
|
||||
</li>
|
||||
<li>HALF4WIRE
|
||||
: <a class="el" href="classAccelStepper.html#a73bdecf1273d98d8c5fbcb764cabeea5aecc0900c55b777d2e885581b8c434b07">AccelStepper</a>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
|
||||
<h3><a id="index_i"></a>- i -</h3><ul>
|
||||
<li>isRunning()
|
||||
: <a class="el" href="classAccelStepper.html#a3a60cc0b962f8ceb81ee1e6f36443ceb">AccelStepper</a>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
|
||||
<h3><a id="index_m"></a>- m -</h3><ul>
|
||||
<li>maxSpeed()
|
||||
: <a class="el" href="classAccelStepper.html#a6123a1dfb4495d8bd2646288eae60d7f">AccelStepper</a>
|
||||
</li>
|
||||
<li>MotorInterfaceType
|
||||
: <a class="el" href="classAccelStepper.html#a73bdecf1273d98d8c5fbcb764cabeea5">AccelStepper</a>
|
||||
</li>
|
||||
<li>move()
|
||||
: <a class="el" href="classAccelStepper.html#a68942c66e78fb7f7b5f0cdade6eb7f06">AccelStepper</a>
|
||||
</li>
|
||||
<li>moveTo()
|
||||
: <a class="el" href="classAccelStepper.html#ace236ede35f87c63d18da25810ec9736">AccelStepper</a>
|
||||
, <a class="el" href="classMultiStepper.html#a291fec32a79390b6eb00296cffac49ee">MultiStepper</a>
|
||||
</li>
|
||||
<li>MultiStepper()
|
||||
: <a class="el" href="classMultiStepper.html#a14c0c1c0f55e5bbdc4971730e32304c2">MultiStepper</a>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
|
||||
<h3><a id="index_r"></a>- r -</h3><ul>
|
||||
<li>run()
|
||||
: <a class="el" href="classAccelStepper.html#a608b2395b64ac15451d16d0371fe13ce">AccelStepper</a>
|
||||
, <a class="el" href="classMultiStepper.html#a26c2f53b1e7ddf5d5dfb333f6fb7fb92">MultiStepper</a>
|
||||
</li>
|
||||
<li>runSpeed()
|
||||
: <a class="el" href="classAccelStepper.html#aa4a6bdf99f698284faaeb5542b0b7514">AccelStepper</a>
|
||||
</li>
|
||||
<li>runSpeedToPosition()
|
||||
: <a class="el" href="classAccelStepper.html#a9270d20336e76ac1fd5bcd5b9c34f301">AccelStepper</a>
|
||||
, <a class="el" href="classMultiStepper.html#a2592f55864ce3ace125944db624317bc">MultiStepper</a>
|
||||
</li>
|
||||
<li>runToNewPosition()
|
||||
: <a class="el" href="classAccelStepper.html#a176c5d2e4c2f21e9e92b12e39a6f0e67">AccelStepper</a>
|
||||
</li>
|
||||
<li>runToPosition()
|
||||
: <a class="el" href="classAccelStepper.html#a344f58fef8cc34ac5aa75ba4b665d21c">AccelStepper</a>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
|
||||
<h3><a id="index_s"></a>- s -</h3><ul>
|
||||
<li>setAcceleration()
|
||||
: <a class="el" href="classAccelStepper.html#adfb19e3cd2a028a1fe78131787604fd1">AccelStepper</a>
|
||||
</li>
|
||||
<li>setCurrentPosition()
|
||||
: <a class="el" href="classAccelStepper.html#a9d917f014317fb9d3b5dc14e66f6c689">AccelStepper</a>
|
||||
</li>
|
||||
<li>setEnablePin()
|
||||
: <a class="el" href="classAccelStepper.html#a56a81c5f00d02ca19646718e88e974c0">AccelStepper</a>
|
||||
</li>
|
||||
<li>setMaxSpeed()
|
||||
: <a class="el" href="classAccelStepper.html#abee8d466229b87accba33d6ec929c18f">AccelStepper</a>
|
||||
</li>
|
||||
<li>setMinPulseWidth()
|
||||
: <a class="el" href="classAccelStepper.html#af4d3818e691dad5dc518308796ccf154">AccelStepper</a>
|
||||
</li>
|
||||
<li>setOutputPins()
|
||||
: <a class="el" href="classAccelStepper.html#af3c2516b6ce7c1ecbc2004107bb2a9ce">AccelStepper</a>
|
||||
</li>
|
||||
<li>setPinsInverted()
|
||||
: <a class="el" href="classAccelStepper.html#ac62cae590c2f9c303519a3a1c4adc8ab">AccelStepper</a>
|
||||
</li>
|
||||
<li>setSpeed()
|
||||
: <a class="el" href="classAccelStepper.html#ae79c49ad69d5ccc9da0ee691fa4ca235">AccelStepper</a>
|
||||
</li>
|
||||
<li>speed()
|
||||
: <a class="el" href="classAccelStepper.html#a4f0989d0ae264e7eadfe1fa720769fb6">AccelStepper</a>
|
||||
</li>
|
||||
<li>step()
|
||||
: <a class="el" href="classAccelStepper.html#a8a419121702399d8ac66df4cc47481f4">AccelStepper</a>
|
||||
</li>
|
||||
<li>step0()
|
||||
: <a class="el" href="classAccelStepper.html#aa2913db789e6fa05756579ff82fe6e7e">AccelStepper</a>
|
||||
</li>
|
||||
<li>step1()
|
||||
: <a class="el" href="classAccelStepper.html#a63ef416bc039da539294e84a41e7d7dc">AccelStepper</a>
|
||||
</li>
|
||||
<li>step2()
|
||||
: <a class="el" href="classAccelStepper.html#a674e48a6bf99e7ad1f013c1e4414565a">AccelStepper</a>
|
||||
</li>
|
||||
<li>step3()
|
||||
: <a class="el" href="classAccelStepper.html#ad73c61aade2e10243dfb02aefa7ab8fd">AccelStepper</a>
|
||||
</li>
|
||||
<li>step4()
|
||||
: <a class="el" href="classAccelStepper.html#a8910bd9218a54dfb7e2372a6d0bcca0c">AccelStepper</a>
|
||||
</li>
|
||||
<li>step6()
|
||||
: <a class="el" href="classAccelStepper.html#a4b0faf1ebc0c584ab606c0c0f66986b0">AccelStepper</a>
|
||||
</li>
|
||||
<li>step8()
|
||||
: <a class="el" href="classAccelStepper.html#aa909c6c3fcd3ea4b3ee1aa8b4d0f7e87">AccelStepper</a>
|
||||
</li>
|
||||
<li>stop()
|
||||
: <a class="el" href="classAccelStepper.html#a638817b85aed9d5cd15c76a76c00aced">AccelStepper</a>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
|
||||
<h3><a id="index_t"></a>- t -</h3><ul>
|
||||
<li>targetPosition()
|
||||
: <a class="el" href="classAccelStepper.html#a96685e0945b7cf75d5959da679cd911e">AccelStepper</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div><!-- contents -->
|
||||
<!-- start footer part -->
|
||||
<hr class="footer"/><address class="footer"><small>
|
||||
Generated by  <a href="http://www.doxygen.org/index.html">
|
||||
<img class="footer" src="doxygen.png" alt="doxygen"/>
|
||||
</a> 1.8.13
|
||||
</small></address>
|
||||
</body>
|
||||
</html>
|
||||
195
arduino-cli/libraries/AccelStepper/doc/functions_func.html
Normal file
195
arduino-cli/libraries/AccelStepper/doc/functions_func.html
Normal file
@@ -0,0 +1,195 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=9"/>
|
||||
<meta name="generator" content="Doxygen 1.8.13"/>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1"/>
|
||||
<title>AccelStepper: Class Members - Functions</title>
|
||||
<link href="tabs.css" rel="stylesheet" type="text/css"/>
|
||||
<script type="text/javascript" src="jquery.js"></script>
|
||||
<script type="text/javascript" src="dynsections.js"></script>
|
||||
<link href="doxygen.css" rel="stylesheet" type="text/css" />
|
||||
</head>
|
||||
<body>
|
||||
<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
|
||||
<div id="titlearea">
|
||||
<table cellspacing="0" cellpadding="0">
|
||||
<tbody>
|
||||
<tr style="height: 56px;">
|
||||
<td id="projectalign" style="padding-left: 0.5em;">
|
||||
<div id="projectname">AccelStepper
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<!-- end header part -->
|
||||
<!-- Generated by Doxygen 1.8.13 -->
|
||||
<script type="text/javascript" src="menudata.js"></script>
|
||||
<script type="text/javascript" src="menu.js"></script>
|
||||
<script type="text/javascript">
|
||||
$(function() {
|
||||
initMenu('',false,false,'search.php','Search');
|
||||
});
|
||||
</script>
|
||||
<div id="main-nav"></div>
|
||||
</div><!-- top -->
|
||||
<div class="contents">
|
||||
 
|
||||
|
||||
<h3><a id="index_a"></a>- a -</h3><ul>
|
||||
<li>AccelStepper()
|
||||
: <a class="el" href="classAccelStepper.html#a3bc75bd6571b98a6177838ca81ac39ab">AccelStepper</a>
|
||||
</li>
|
||||
<li>addStepper()
|
||||
: <a class="el" href="classMultiStepper.html#a383d8486e17ad9de9f1bafcbd9aa52ee">MultiStepper</a>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
|
||||
<h3><a id="index_c"></a>- c -</h3><ul>
|
||||
<li>computeNewSpeed()
|
||||
: <a class="el" href="classAccelStepper.html#affbee789b5c19165846cf0409860ae79">AccelStepper</a>
|
||||
</li>
|
||||
<li>currentPosition()
|
||||
: <a class="el" href="classAccelStepper.html#a5dce13ab2a1b02b8f443318886bf6fc5">AccelStepper</a>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
|
||||
<h3><a id="index_d"></a>- d -</h3><ul>
|
||||
<li>disableOutputs()
|
||||
: <a class="el" href="classAccelStepper.html#a3591e29a236e2935afd7f64ff6c22006">AccelStepper</a>
|
||||
</li>
|
||||
<li>distanceToGo()
|
||||
: <a class="el" href="classAccelStepper.html#a748665c3962e66fbc0e9373eb14c69c1">AccelStepper</a>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
|
||||
<h3><a id="index_e"></a>- e -</h3><ul>
|
||||
<li>enableOutputs()
|
||||
: <a class="el" href="classAccelStepper.html#aa279a50d30d0413f570c692cff071643">AccelStepper</a>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
|
||||
<h3><a id="index_i"></a>- i -</h3><ul>
|
||||
<li>isRunning()
|
||||
: <a class="el" href="classAccelStepper.html#a3a60cc0b962f8ceb81ee1e6f36443ceb">AccelStepper</a>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
|
||||
<h3><a id="index_m"></a>- m -</h3><ul>
|
||||
<li>maxSpeed()
|
||||
: <a class="el" href="classAccelStepper.html#a6123a1dfb4495d8bd2646288eae60d7f">AccelStepper</a>
|
||||
</li>
|
||||
<li>move()
|
||||
: <a class="el" href="classAccelStepper.html#a68942c66e78fb7f7b5f0cdade6eb7f06">AccelStepper</a>
|
||||
</li>
|
||||
<li>moveTo()
|
||||
: <a class="el" href="classAccelStepper.html#ace236ede35f87c63d18da25810ec9736">AccelStepper</a>
|
||||
, <a class="el" href="classMultiStepper.html#a291fec32a79390b6eb00296cffac49ee">MultiStepper</a>
|
||||
</li>
|
||||
<li>MultiStepper()
|
||||
: <a class="el" href="classMultiStepper.html#a14c0c1c0f55e5bbdc4971730e32304c2">MultiStepper</a>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
|
||||
<h3><a id="index_r"></a>- r -</h3><ul>
|
||||
<li>run()
|
||||
: <a class="el" href="classAccelStepper.html#a608b2395b64ac15451d16d0371fe13ce">AccelStepper</a>
|
||||
, <a class="el" href="classMultiStepper.html#a26c2f53b1e7ddf5d5dfb333f6fb7fb92">MultiStepper</a>
|
||||
</li>
|
||||
<li>runSpeed()
|
||||
: <a class="el" href="classAccelStepper.html#aa4a6bdf99f698284faaeb5542b0b7514">AccelStepper</a>
|
||||
</li>
|
||||
<li>runSpeedToPosition()
|
||||
: <a class="el" href="classAccelStepper.html#a9270d20336e76ac1fd5bcd5b9c34f301">AccelStepper</a>
|
||||
, <a class="el" href="classMultiStepper.html#a2592f55864ce3ace125944db624317bc">MultiStepper</a>
|
||||
</li>
|
||||
<li>runToNewPosition()
|
||||
: <a class="el" href="classAccelStepper.html#a176c5d2e4c2f21e9e92b12e39a6f0e67">AccelStepper</a>
|
||||
</li>
|
||||
<li>runToPosition()
|
||||
: <a class="el" href="classAccelStepper.html#a344f58fef8cc34ac5aa75ba4b665d21c">AccelStepper</a>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
|
||||
<h3><a id="index_s"></a>- s -</h3><ul>
|
||||
<li>setAcceleration()
|
||||
: <a class="el" href="classAccelStepper.html#adfb19e3cd2a028a1fe78131787604fd1">AccelStepper</a>
|
||||
</li>
|
||||
<li>setCurrentPosition()
|
||||
: <a class="el" href="classAccelStepper.html#a9d917f014317fb9d3b5dc14e66f6c689">AccelStepper</a>
|
||||
</li>
|
||||
<li>setEnablePin()
|
||||
: <a class="el" href="classAccelStepper.html#a56a81c5f00d02ca19646718e88e974c0">AccelStepper</a>
|
||||
</li>
|
||||
<li>setMaxSpeed()
|
||||
: <a class="el" href="classAccelStepper.html#abee8d466229b87accba33d6ec929c18f">AccelStepper</a>
|
||||
</li>
|
||||
<li>setMinPulseWidth()
|
||||
: <a class="el" href="classAccelStepper.html#af4d3818e691dad5dc518308796ccf154">AccelStepper</a>
|
||||
</li>
|
||||
<li>setOutputPins()
|
||||
: <a class="el" href="classAccelStepper.html#af3c2516b6ce7c1ecbc2004107bb2a9ce">AccelStepper</a>
|
||||
</li>
|
||||
<li>setPinsInverted()
|
||||
: <a class="el" href="classAccelStepper.html#a38298ac2dd852fb22259f6c4bbe08c94">AccelStepper</a>
|
||||
</li>
|
||||
<li>setSpeed()
|
||||
: <a class="el" href="classAccelStepper.html#ae79c49ad69d5ccc9da0ee691fa4ca235">AccelStepper</a>
|
||||
</li>
|
||||
<li>speed()
|
||||
: <a class="el" href="classAccelStepper.html#a4f0989d0ae264e7eadfe1fa720769fb6">AccelStepper</a>
|
||||
</li>
|
||||
<li>step()
|
||||
: <a class="el" href="classAccelStepper.html#a8a419121702399d8ac66df4cc47481f4">AccelStepper</a>
|
||||
</li>
|
||||
<li>step0()
|
||||
: <a class="el" href="classAccelStepper.html#aa2913db789e6fa05756579ff82fe6e7e">AccelStepper</a>
|
||||
</li>
|
||||
<li>step1()
|
||||
: <a class="el" href="classAccelStepper.html#a63ef416bc039da539294e84a41e7d7dc">AccelStepper</a>
|
||||
</li>
|
||||
<li>step2()
|
||||
: <a class="el" href="classAccelStepper.html#a674e48a6bf99e7ad1f013c1e4414565a">AccelStepper</a>
|
||||
</li>
|
||||
<li>step3()
|
||||
: <a class="el" href="classAccelStepper.html#ad73c61aade2e10243dfb02aefa7ab8fd">AccelStepper</a>
|
||||
</li>
|
||||
<li>step4()
|
||||
: <a class="el" href="classAccelStepper.html#a8910bd9218a54dfb7e2372a6d0bcca0c">AccelStepper</a>
|
||||
</li>
|
||||
<li>step6()
|
||||
: <a class="el" href="classAccelStepper.html#a4b0faf1ebc0c584ab606c0c0f66986b0">AccelStepper</a>
|
||||
</li>
|
||||
<li>step8()
|
||||
: <a class="el" href="classAccelStepper.html#aa909c6c3fcd3ea4b3ee1aa8b4d0f7e87">AccelStepper</a>
|
||||
</li>
|
||||
<li>stop()
|
||||
: <a class="el" href="classAccelStepper.html#a638817b85aed9d5cd15c76a76c00aced">AccelStepper</a>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
|
||||
<h3><a id="index_t"></a>- t -</h3><ul>
|
||||
<li>targetPosition()
|
||||
: <a class="el" href="classAccelStepper.html#a96685e0945b7cf75d5959da679cd911e">AccelStepper</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div><!-- contents -->
|
||||
<!-- start footer part -->
|
||||
<hr class="footer"/><address class="footer"><small>
|
||||
Generated by  <a href="http://www.doxygen.org/index.html">
|
||||
<img class="footer" src="doxygen.png" alt="doxygen"/>
|
||||
</a> 1.8.13
|
||||
</small></address>
|
||||
</body>
|
||||
</html>
|
||||
222
arduino-cli/libraries/AccelStepper/doc/index.html
Normal file
222
arduino-cli/libraries/AccelStepper/doc/index.html
Normal file
@@ -0,0 +1,222 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=9"/>
|
||||
<meta name="generator" content="Doxygen 1.8.13"/>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1"/>
|
||||
<title>AccelStepper: AccelStepper library for Arduino</title>
|
||||
<link href="tabs.css" rel="stylesheet" type="text/css"/>
|
||||
<script type="text/javascript" src="jquery.js"></script>
|
||||
<script type="text/javascript" src="dynsections.js"></script>
|
||||
<link href="doxygen.css" rel="stylesheet" type="text/css" />
|
||||
</head>
|
||||
<body>
|
||||
<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
|
||||
<div id="titlearea">
|
||||
<table cellspacing="0" cellpadding="0">
|
||||
<tbody>
|
||||
<tr style="height: 56px;">
|
||||
<td id="projectalign" style="padding-left: 0.5em;">
|
||||
<div id="projectname">AccelStepper
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<!-- end header part -->
|
||||
<!-- Generated by Doxygen 1.8.13 -->
|
||||
<script type="text/javascript" src="menudata.js"></script>
|
||||
<script type="text/javascript" src="menu.js"></script>
|
||||
<script type="text/javascript">
|
||||
$(function() {
|
||||
initMenu('',false,false,'search.php','Search');
|
||||
});
|
||||
</script>
|
||||
<div id="main-nav"></div>
|
||||
</div><!-- top -->
|
||||
<div class="header">
|
||||
<div class="headertitle">
|
||||
<div class="title"><a class="el" href="classAccelStepper.html" title="Support for stepper motors with acceleration etc. ">AccelStepper</a> library for Arduino </div> </div>
|
||||
</div><!--header-->
|
||||
<div class="contents">
|
||||
<div class="textblock"><p>This is the Arduino <a class="el" href="classAccelStepper.html" title="Support for stepper motors with acceleration etc. ">AccelStepper</a> library. It provides an object-oriented interface for 2, 3 or 4 pin stepper motors and motor drivers.</p>
|
||||
<p>The standard Arduino IDE includes the Stepper library (<a href="http://arduino.cc/en/Reference/Stepper">http://arduino.cc/en/Reference/Stepper</a>) for stepper motors. It is perfectly adequate for simple, single motor applications.</p>
|
||||
<p><a class="el" href="classAccelStepper.html" title="Support for stepper motors with acceleration etc. ">AccelStepper</a> significantly improves on the standard Arduino Stepper library in several ways: </p><ul>
|
||||
<li>Supports acceleration and deceleration </li>
|
||||
<li>Supports multiple simultaneous steppers, with independent concurrent stepping on each stepper </li>
|
||||
<li>API functions never delay() or block </li>
|
||||
<li>Supports 2, 3 and 4 wire steppers, plus 3 and 4 wire half steppers. </li>
|
||||
<li>Supports alternate stepping functions to enable support of AFMotor (<a href="https://github.com/adafruit/Adafruit-Motor-Shield-library">https://github.com/adafruit/Adafruit-Motor-Shield-library</a>) </li>
|
||||
<li>Supports stepper drivers such as the Sparkfun EasyDriver (based on 3967 driver chip) </li>
|
||||
<li>Very slow speeds are supported </li>
|
||||
<li>Extensive API </li>
|
||||
<li>Subclass support</li>
|
||||
</ul>
|
||||
<p>The latest version of this documentation can be downloaded from <a href="http://www.airspayce.com/mikem/arduino/AccelStepper">http://www.airspayce.com/mikem/arduino/AccelStepper</a> The version of the package that this documentation refers to can be downloaded from <a href="http://www.airspayce.com/mikem/arduino/AccelStepper/AccelStepper-1.59.zip">http://www.airspayce.com/mikem/arduino/AccelStepper/AccelStepper-1.59.zip</a></p>
|
||||
<p>Example Arduino programs are included to show the main modes of use.</p>
|
||||
<p>You can also find online help and discussion at <a href="http://groups.google.com/group/accelstepper">http://groups.google.com/group/accelstepper</a> Please use that group for all questions and discussions on this topic. Do not contact the author directly, unless it is to discuss commercial licensing. Before asking a question or reporting a bug, please read</p><ul>
|
||||
<li><a href="http://en.wikipedia.org/wiki/Wikipedia:Reference_desk/How_to_ask_a_software_question">http://en.wikipedia.org/wiki/Wikipedia:Reference_desk/How_to_ask_a_software_question</a></li>
|
||||
<li><a href="http://www.catb.org/esr/faqs/smart-questions.html">http://www.catb.org/esr/faqs/smart-questions.html</a></li>
|
||||
<li><a href="http://www.chiark.greenend.org.uk/~shgtatham/bugs.html">http://www.chiark.greenend.org.uk/~shgtatham/bugs.html</a></li>
|
||||
</ul>
|
||||
<p>Tested on Arduino Diecimila and Mega with arduino-0018 & arduino-0021 on OpenSuSE 11.1 and avr-libc-1.6.1-1.15, cross-avr-binutils-2.19-9.1, cross-avr-gcc-4.1.3_20080612-26.5. Tested on Teensy <a href="http://www.pjrc.com/teensy">http://www.pjrc.com/teensy</a> including Teensy 3.1 built using Arduino IDE 1.0.5 with teensyduino addon 1.18 and later.</p>
|
||||
<dl class="section user"><dt>Installation</dt><dd></dd></dl>
|
||||
<p>Install in the usual way: unzip the distribution zip file to the libraries sub-folder of your sketchbook.</p>
|
||||
<dl class="section user"><dt>Theory</dt><dd></dd></dl>
|
||||
<p>This code uses speed calculations as described in "Generate stepper-motor speed profiles in real time" by David Austin <a href="http://fab.cba.mit.edu/classes/MIT/961.09/projects/i0/Stepper_Motor_Speed_Profile.pdf">http://fab.cba.mit.edu/classes/MIT/961.09/projects/i0/Stepper_Motor_Speed_Profile.pdf</a> or <a href="http://www.embedded.com/design/mcus-processors-and-socs/4006438/Generate-stepper-motor-speed-profiles-in-real-time">http://www.embedded.com/design/mcus-processors-and-socs/4006438/Generate-stepper-motor-speed-profiles-in-real-time</a> or <a href="http://web.archive.org/web/20140705143928/http://fab.cba.mit.edu/classes/MIT/961.09/projects/i0/Stepper_Motor_Speed_Profile.pdf">http://web.archive.org/web/20140705143928/http://fab.cba.mit.edu/classes/MIT/961.09/projects/i0/Stepper_Motor_Speed_Profile.pdf</a> with the exception that <a class="el" href="classAccelStepper.html" title="Support for stepper motors with acceleration etc. ">AccelStepper</a> uses steps per second rather than radians per second (because we dont know the step angle of the motor) An initial step interval is calculated for the first step, based on the desired acceleration On subsequent steps, shorter step intervals are calculated based on the previous step until max speed is achieved.</p>
|
||||
<dl class="section user"><dt>Adafruit Motor Shield V2</dt><dd></dd></dl>
|
||||
<p>The included examples AFMotor_* are for Adafruit Motor Shield V1 and do not work with Adafruit Motor Shield V2. See <a href="https://github.com/adafruit/Adafruit_Motor_Shield_V2_Library">https://github.com/adafruit/Adafruit_Motor_Shield_V2_Library</a> for examples that work with Adafruit Motor Shield V2.</p>
|
||||
<dl class="section user"><dt>Donations</dt><dd></dd></dl>
|
||||
<p>This library is offered under a free GPL license for those who want to use it that way. We try hard to keep it up to date, fix bugs and to provide free support. If this library has helped you save time or money, please consider donating at <a href="http://www.airspayce.com">http://www.airspayce.com</a> or here:</p>
|
||||
<p> <form action="https://www.paypal.com/cgi-bin/webscr" method="post"><input type="hidden" name="cmd" value="_donations" /> <input type="hidden" name="business" value="mikem@airspayce.com" /> <input type="hidden" name="lc" value="AU" /> <input type="hidden" name="item_name" value="Airspayce" /> <input type="hidden" name="item_number" value="AccelStepper" /> <input type="hidden" name="currency_code" value="USD" /> <input type="hidden" name="bn" value="PP-DonationsBF:btn_donateCC_LG.gif:NonHosted" /> <input type="image" alt="PayPal — The safer, easier way to pay online." name="submit" src="https://www.paypalobjects.com/en_AU/i/btn/btn_donateCC_LG.gif" /> <img alt="" src="https://www.paypalobjects.com/en_AU/i/scr/pixel.gif" width="1" height="1" border="0" /></form> </p>
|
||||
<dl class="section user"><dt>Trademarks</dt><dd></dd></dl>
|
||||
<p><a class="el" href="classAccelStepper.html" title="Support for stepper motors with acceleration etc. ">AccelStepper</a> is a trademark of AirSpayce Pty Ltd. The <a class="el" href="classAccelStepper.html" title="Support for stepper motors with acceleration etc. ">AccelStepper</a> mark was first used on April 26 2010 for international trade, and is used only in relation to motor control hardware and software. It is not to be confused with any other similar marks covering other goods and services.</p>
|
||||
<dl class="section user"><dt>Copyright</dt><dd></dd></dl>
|
||||
<p>This software is Copyright (C) 2010-2018 Mike McCauley. Use is subject to license conditions. The main licensing options available are GPL V2 or Commercial:</p>
|
||||
<dl class="section user"><dt>Open Source Licensing GPL V2</dt><dd>This is the appropriate option if you want to share the source code of your application with everyone you distribute it to, and you also want to give them the right to share who uses it. If you wish to use this software under Open Source Licensing, you must contribute all your source code to the open source community in accordance with the GPL Version 2 when your application is distributed. See <a href="https://www.gnu.org/licenses/gpl-2.0.html">https://www.gnu.org/licenses/gpl-2.0.html</a></dd></dl>
|
||||
<dl class="section user"><dt>Commercial Licensing</dt><dd>This is the appropriate option if you are creating proprietary applications and you are not prepared to distribute and share the source code of your application. To purchase a commercial license, contact <a href="#" onclick="location.href='mai'+'lto:'+'inf'+'o@'+'air'+'sp'+'ayc'+'e.'+'com'; return false;">info@<span style="display: none;">.nosp@m.</span>airs<span style="display: none;">.nosp@m.</span>payce<span style="display: none;">.nosp@m.</span>.com</a></dd></dl>
|
||||
<dl class="section user"><dt>Revision History</dt><dd></dd></dl>
|
||||
<dl class="section version"><dt>Version</dt><dd>1.0 Initial release</dd>
|
||||
<dd>
|
||||
1.1 Added speed() function to get the current speed. </dd>
|
||||
<dd>
|
||||
1.2 Added runSpeedToPosition() submitted by Gunnar Arndt. </dd>
|
||||
<dd>
|
||||
1.3 Added support for stepper drivers (ie with Step and Direction inputs) with _pins == 1 </dd>
|
||||
<dd>
|
||||
1.4 Added functional contructor to support AFMotor, contributed by Limor, with example sketches. </dd>
|
||||
<dd>
|
||||
1.5 Improvements contributed by Peter Mousley: Use of microsecond steps and other speed improvements to increase max stepping speed to about 4kHz. New option for user to set the min allowed pulse width. Added checks for already running at max speed and skip further calcs if so. </dd>
|
||||
<dd>
|
||||
1.6 Fixed a problem with wrapping of microsecond stepping that could cause stepping to hang. Reported by Sandy Noble. Removed redundant _lastRunTime member. </dd>
|
||||
<dd>
|
||||
1.7 Fixed a bug where setCurrentPosition() did not always work as expected. Reported by Peter Linhart. </dd>
|
||||
<dd>
|
||||
1.8 Added support for 4 pin half-steppers, requested by Harvey Moon </dd>
|
||||
<dd>
|
||||
1.9 setCurrentPosition() now also sets motor speed to 0. </dd>
|
||||
<dd>
|
||||
1.10 Builds on Arduino 1.0 </dd>
|
||||
<dd>
|
||||
1.11 Improvments from Michael Ellison: Added optional enable line support for stepper drivers Added inversion for step/direction/enable lines for stepper drivers </dd>
|
||||
<dd>
|
||||
1.12 Announce Google Group </dd>
|
||||
<dd>
|
||||
1.13 Improvements to speed calculation. Cost of calculation is now less in the worst case, and more or less constant in all cases. This should result in slightly beter high speed performance, and reduce anomalous speed glitches when other steppers are accelerating. However, its hard to see how to replace the sqrt() required at the very first step from 0 speed. </dd>
|
||||
<dd>
|
||||
1.14 Fixed a problem with compiling under arduino 0021 reported by EmbeddedMan </dd>
|
||||
<dd>
|
||||
1.15 Fixed a problem with runSpeedToPosition which did not correctly handle running backwards to a smaller target position. Added examples </dd>
|
||||
<dd>
|
||||
1.16 Fixed some cases in the code where abs() was used instead of fabs(). </dd>
|
||||
<dd>
|
||||
1.17 Added example ProportionalControl </dd>
|
||||
<dd>
|
||||
1.18 Fixed a problem: If one calls the funcion runSpeed() when Speed is zero, it makes steps without counting. reported by Friedrich, Klappenbach. </dd>
|
||||
<dd>
|
||||
1.19 Added MotorInterfaceType and symbolic names for the number of pins to use for the motor interface. Updated examples to suit. Replaced individual pin assignment variables _pin1, _pin2 etc with array _pin[4]. _pins member changed to _interface. Added _pinInverted array to simplify pin inversion operations. Added new function setOutputPins() which sets the motor output pins. It can be overridden in order to provide, say, serial output instead of parallel output Some refactoring and code size reduction. </dd>
|
||||
<dd>
|
||||
1.20 Improved documentation and examples to show need for correctly specifying <a class="el" href="classAccelStepper.html#a73bdecf1273d98d8c5fbcb764cabeea5adedd394a375190a3df8d4519c0d4dc2f" title="4 wire full stepper, 4 motor pins required ">AccelStepper::FULL4WIRE</a> and friends. </dd>
|
||||
<dd>
|
||||
1.21 Fixed a problem where desiredSpeed could compute the wrong step acceleration when _speed was small but non-zero. Reported by Brian Schmalz. Precompute sqrt_twoa to improve performance and max possible stepping speed </dd>
|
||||
<dd>
|
||||
1.22 Added Bounce.pde example Fixed a problem where calling moveTo(), setMaxSpeed(), setAcceleration() more frequently than the step time, even with the same values, would interfere with speed calcs. Now a new speed is computed only if there was a change in the set value. Reported by Brian Schmalz. </dd>
|
||||
<dd>
|
||||
1.23 Rewrite of the speed algorithms in line with <a href="http://fab.cba.mit.edu/classes/MIT/961.09/projects/i0/Stepper_Motor_Speed_Profile.pdf">http://fab.cba.mit.edu/classes/MIT/961.09/projects/i0/Stepper_Motor_Speed_Profile.pdf</a> Now expect smoother and more linear accelerations and decelerations. The desiredSpeed() function was removed. </dd>
|
||||
<dd>
|
||||
1.24 Fixed a problem introduced in 1.23: with runToPosition, which did never returned </dd>
|
||||
<dd>
|
||||
1.25 Now ignore attempts to set acceleration to 0.0 </dd>
|
||||
<dd>
|
||||
1.26 Fixed a problem where certina combinations of speed and accelration could cause oscillation about the target position. </dd>
|
||||
<dd>
|
||||
1.27 Added stop() function to stop as fast as possible with current acceleration parameters. Also added new Quickstop example showing its use. </dd>
|
||||
<dd>
|
||||
1.28 Fixed another problem where certain combinations of speed and acceleration could cause oscillation about the target position. Added support for 3 wire full and half steppers such as Hard Disk Drive spindle. Contributed by Yuri Ivatchkovitch. </dd>
|
||||
<dd>
|
||||
1.29 Fixed a problem that could cause a DRIVER stepper to continually step with some sketches. Reported by Vadim. </dd>
|
||||
<dd>
|
||||
1.30 Fixed a problem that could cause stepper to back up a few steps at the end of accelerated travel with certain speeds. Reported and patched by jolo. </dd>
|
||||
<dd>
|
||||
1.31 Updated author and distribution location details to airspayce.com </dd>
|
||||
<dd>
|
||||
1.32 Fixed a problem with enableOutputs() and setEnablePin on Arduino Due that prevented the enable pin changing stae correctly. Reported by Duane Bishop. </dd>
|
||||
<dd>
|
||||
1.33 Fixed an error in example AFMotor_ConstantSpeed.pde did not setMaxSpeed(); Fixed a problem that caused incorrect pin sequencing of FULL3WIRE and HALF3WIRE. Unfortunately this meant changing the signature for all step*() functions. Added example MotorShield, showing how to use AdaFruit Motor Shield to control a 3 phase motor such as a HDD spindle motor (and without using the AFMotor library. </dd>
|
||||
<dd>
|
||||
1.34 Added setPinsInverted(bool pin1Invert, bool pin2Invert, bool pin3Invert, bool pin4Invert, bool enableInvert) to allow inversion of 2, 3 and 4 wire stepper pins. Requested by Oleg. </dd>
|
||||
<dd>
|
||||
1.35 Removed default args from setPinsInverted(bool, bool, bool, bool, bool) to prevent ambiguity with setPinsInverted(bool, bool, bool). Reported by Mac Mac. </dd>
|
||||
<dd>
|
||||
1.36 Changed enableOutputs() and disableOutputs() to be virtual so can be overridden. Added new optional argument 'enable' to constructor, which allows you toi disable the automatic enabling of outputs at construction time. Suggested by Guido. </dd>
|
||||
<dd>
|
||||
1.37 Fixed a problem with step1 that could cause a rogue step in the wrong direction (or not, depending on the setup-time requirements of the connected hardware). Reported by Mark Tillotson. </dd>
|
||||
<dd>
|
||||
1.38 run() function incorrectly always returned true. Updated function and doc so it returns true if the motor is still running to the target position. </dd>
|
||||
<dd>
|
||||
1.39 Updated typos in keywords.txt, courtesey Jon Magill. </dd>
|
||||
<dd>
|
||||
1.40 Updated documentation, including testing on Teensy 3.1 </dd>
|
||||
<dd>
|
||||
1.41 Fixed an error in the acceleration calculations, resulting in acceleration of haldf the intended value </dd>
|
||||
<dd>
|
||||
1.42 Improved support for FULL3WIRE and HALF3WIRE output pins. These changes were in Yuri's original contribution but did not make it into production.<br />
|
||||
</dd>
|
||||
<dd>
|
||||
1.43 Added DualMotorShield example. Shows how to use <a class="el" href="classAccelStepper.html" title="Support for stepper motors with acceleration etc. ">AccelStepper</a> to control 2 x 2 phase steppers using the Itead Studio Arduino Dual Stepper Motor Driver Shield model IM120417015.<br />
|
||||
</dd>
|
||||
<dd>
|
||||
1.44 examples/DualMotorShield/DualMotorShield.ino examples/DualMotorShield/DualMotorShield.pde was missing from the distribution.<br />
|
||||
</dd>
|
||||
<dd>
|
||||
1.45 Fixed a problem where if setAcceleration was not called, there was no default acceleration. Reported by Michael Newman.<br />
|
||||
</dd>
|
||||
<dd>
|
||||
1.45 Fixed inaccuracy in acceleration rate by using Equation 15, suggested by Sebastian Gracki.<br />
|
||||
Performance improvements in runSpeed suggested by Jaakko Fagerlund.<br />
|
||||
</dd>
|
||||
<dd>
|
||||
1.46 Fixed error in documentation for runToPosition(). Reinstated time calculations in runSpeed() since new version is reported not to work correctly under some circumstances. Reported by Oleg V Gavva.<br />
|
||||
</dd>
|
||||
<dd>
|
||||
1.48 2015-08-25 Added new class <a class="el" href="classMultiStepper.html" title="Operate multiple AccelSteppers in a co-ordinated fashion. ">MultiStepper</a> that can manage multiple AccelSteppers, and cause them all to move to selected positions at such a (constant) speed that they all arrive at their target position at the same time. Suitable for X-Y flatbeds etc.<br />
|
||||
Added new method maxSpeed() to <a class="el" href="classAccelStepper.html" title="Support for stepper motors with acceleration etc. ">AccelStepper</a> to return the currently configured maxSpeed.<br />
|
||||
</dd>
|
||||
<dd>
|
||||
1.49 2016-01-02 Testing with VID28 series instrument stepper motors and EasyDriver. OK, although with light pointers and slow speeds like 180 full steps per second the motor movement can be erratic, probably due to some mechanical resonance. Best to accelerate through this speed.<br />
|
||||
Added isRunning().<br />
|
||||
</dd>
|
||||
<dd>
|
||||
1.50 2016-02-25 <a class="el" href="classAccelStepper.html#a3591e29a236e2935afd7f64ff6c22006">AccelStepper::disableOutputs</a> now sets the enable pion to OUTPUT mode if the enable pin is defined. Patch from Piet De Jong.<br />
|
||||
Added notes about the fact that AFMotor_* examples do not work with Adafruit Motor Shield V2.<br />
|
||||
</dd>
|
||||
<dd>
|
||||
1.51 2016-03-24 Fixed a problem reported by gregor: when resetting the stepper motor position using setCurrentPosition() the stepper speed is reset by setting _stepInterval to 0, but _speed is not reset. this results in the stepper motor not starting again when calling setSpeed() with the same speed the stepper was set to before. </dd>
|
||||
<dd>
|
||||
1.52 2016-08-09 Added <a class="el" href="classMultiStepper.html" title="Operate multiple AccelSteppers in a co-ordinated fashion. ">MultiStepper</a> to keywords.txt. Improvements to efficiency of <a class="el" href="classAccelStepper.html#aa4a6bdf99f698284faaeb5542b0b7514">AccelStepper::runSpeed()</a> as suggested by David Grayson. Improvements to speed accuracy as suggested by David Grayson. </dd>
|
||||
<dd>
|
||||
1.53 2016-08-14 Backed out Improvements to speed accuracy from 1.52 as it did not work correctly. </dd>
|
||||
<dd>
|
||||
1.54 2017-01-24 Fixed some warnings about unused arguments. </dd>
|
||||
<dd>
|
||||
1.55 2017-01-25 Fixed another warning in MultiStepper.cpp </dd>
|
||||
<dd>
|
||||
1.56 2017-02-03 Fixed minor documentation error with DIRECTION_CCW and DIRECTION_CW. Reported by David Mutterer. Added link to Binpress commercial license purchasing. </dd>
|
||||
<dd>
|
||||
1.57 2017-03-28 _direction moved to protected at the request of Rudy Ercek. setMaxSpeed() and setAcceleration() now correct negative values to be positive. </dd>
|
||||
<dd>
|
||||
1.58 2018-04-13 Add initialisation for _enableInverted in constructor. </dd>
|
||||
<dd>
|
||||
1.59 2018-08-28 Update commercial licensing, remove binpress.</dd></dl>
|
||||
<dl class="section author"><dt>Author</dt><dd>Mike McCauley (<a href="#" onclick="location.href='mai'+'lto:'+'mik'+'em'+'@ai'+'rs'+'pay'+'ce'+'.co'+'m'; return false;">mikem<span style="display: none;">.nosp@m.</span>@air<span style="display: none;">.nosp@m.</span>spayc<span style="display: none;">.nosp@m.</span>e.co<span style="display: none;">.nosp@m.</span>m</a>) DO NOT CONTACT THE AUTHOR DIRECTLY: USE THE LISTS </dd></dl>
|
||||
</div></div><!-- contents -->
|
||||
<!-- start footer part -->
|
||||
<hr class="footer"/><address class="footer"><small>
|
||||
Generated by  <a href="http://www.doxygen.org/index.html">
|
||||
<img class="footer" src="doxygen.png" alt="doxygen"/>
|
||||
</a> 1.8.13
|
||||
</small></address>
|
||||
</body>
|
||||
</html>
|
||||
BIN
arduino-cli/libraries/AccelStepper/doc/tab_b.gif
Normal file
BIN
arduino-cli/libraries/AccelStepper/doc/tab_b.gif
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 35 B |
BIN
arduino-cli/libraries/AccelStepper/doc/tab_l.gif
Normal file
BIN
arduino-cli/libraries/AccelStepper/doc/tab_l.gif
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 706 B |
BIN
arduino-cli/libraries/AccelStepper/doc/tab_r.gif
Normal file
BIN
arduino-cli/libraries/AccelStepper/doc/tab_r.gif
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.5 KiB |
1
arduino-cli/libraries/AccelStepper/doc/tabs.css
Normal file
1
arduino-cli/libraries/AccelStepper/doc/tabs.css
Normal file
File diff suppressed because one or more lines are too long
@@ -0,0 +1,40 @@
|
||||
// AFMotor_ConstantSpeed.pde
|
||||
// -*- mode: C++ -*-
|
||||
//
|
||||
// Shows how to run AccelStepper in the simplest,
|
||||
// fixed speed mode with no accelerations
|
||||
// Requires the AFMotor library
|
||||
// (https://github.com/adafruit/Adafruit-Motor-Shield-library)
|
||||
// Caution, does not work with Adafruit Motor Shield V2
|
||||
// See https://github.com/adafruit/Adafruit_Motor_Shield_V2_Library
|
||||
// for examples that work with Adafruit Motor Shield V2.
|
||||
|
||||
#include <AccelStepper.h>
|
||||
#include <AFMotor.h>
|
||||
|
||||
AF_Stepper motor1(200, 1);
|
||||
|
||||
|
||||
// you can change these to DOUBLE or INTERLEAVE or MICROSTEP!
|
||||
void forwardstep() {
|
||||
motor1.onestep(FORWARD, SINGLE);
|
||||
}
|
||||
void backwardstep() {
|
||||
motor1.onestep(BACKWARD, SINGLE);
|
||||
}
|
||||
|
||||
AccelStepper stepper(forwardstep, backwardstep); // use functions to step
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(9600); // set up Serial library at 9600 bps
|
||||
Serial.println("Stepper test!");
|
||||
|
||||
stepper.setMaxSpeed(50);
|
||||
stepper.setSpeed(50);
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
stepper.runSpeed();
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
// AFMotor_MultiStepper.pde
|
||||
// -*- mode: C++ -*-
|
||||
//
|
||||
// Control both Stepper motors at the same time with different speeds
|
||||
// and accelerations.
|
||||
// Requires the AFMotor library (https://github.com/adafruit/Adafruit-Motor-Shield-library)
|
||||
// Caution, does not work with Adafruit Motor Shield V2
|
||||
// See https://github.com/adafruit/Adafruit_Motor_Shield_V2_Library
|
||||
// for examples that work with Adafruit Motor Shield V2.
|
||||
|
||||
#include <AccelStepper.h>
|
||||
#include <AFMotor.h>
|
||||
|
||||
// two stepper motors one on each port
|
||||
AF_Stepper motor1(200, 1);
|
||||
AF_Stepper motor2(200, 2);
|
||||
|
||||
// you can change these to DOUBLE or INTERLEAVE or MICROSTEP!
|
||||
// wrappers for the first motor!
|
||||
void forwardstep1() {
|
||||
motor1.onestep(FORWARD, SINGLE);
|
||||
}
|
||||
void backwardstep1() {
|
||||
motor1.onestep(BACKWARD, SINGLE);
|
||||
}
|
||||
// wrappers for the second motor!
|
||||
void forwardstep2() {
|
||||
motor2.onestep(FORWARD, SINGLE);
|
||||
}
|
||||
void backwardstep2() {
|
||||
motor2.onestep(BACKWARD, SINGLE);
|
||||
}
|
||||
|
||||
// Motor shield has two motor ports, now we'll wrap them in an AccelStepper object
|
||||
AccelStepper stepper1(forwardstep1, backwardstep1);
|
||||
AccelStepper stepper2(forwardstep2, backwardstep2);
|
||||
|
||||
void setup()
|
||||
{
|
||||
stepper1.setMaxSpeed(200.0);
|
||||
stepper1.setAcceleration(100.0);
|
||||
stepper1.moveTo(24);
|
||||
|
||||
stepper2.setMaxSpeed(300.0);
|
||||
stepper2.setAcceleration(100.0);
|
||||
stepper2.moveTo(1000000);
|
||||
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
// Change direction at the limits
|
||||
if (stepper1.distanceToGo() == 0)
|
||||
stepper1.moveTo(-stepper1.currentPosition());
|
||||
stepper1.run();
|
||||
stepper2.run();
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
// Blocking.pde
|
||||
// -*- mode: C++ -*-
|
||||
//
|
||||
// Shows how to use the blocking call runToNewPosition
|
||||
// Which sets a new target position and then waits until the stepper has
|
||||
// achieved it.
|
||||
//
|
||||
// Copyright (C) 2009 Mike McCauley
|
||||
// $Id: Blocking.pde,v 1.1 2011/01/05 01:51:01 mikem Exp mikem $
|
||||
|
||||
#include <AccelStepper.h>
|
||||
|
||||
// Define a stepper and the pins it will use
|
||||
AccelStepper stepper; // Defaults to AccelStepper::FULL4WIRE (4 pins) on 2, 3, 4, 5
|
||||
|
||||
void setup()
|
||||
{
|
||||
stepper.setMaxSpeed(200.0);
|
||||
stepper.setAcceleration(100.0);
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
stepper.runToNewPosition(0);
|
||||
stepper.runToNewPosition(500);
|
||||
stepper.runToNewPosition(100);
|
||||
stepper.runToNewPosition(120);
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
// Bounce.pde
|
||||
// -*- mode: C++ -*-
|
||||
//
|
||||
// Make a single stepper bounce from one limit to another
|
||||
//
|
||||
// Copyright (C) 2012 Mike McCauley
|
||||
// $Id: Random.pde,v 1.1 2011/01/05 01:51:01 mikem Exp mikem $
|
||||
|
||||
#include <AccelStepper.h>
|
||||
|
||||
// Define a stepper and the pins it will use
|
||||
AccelStepper stepper; // Defaults to AccelStepper::FULL4WIRE (4 pins) on 2, 3, 4, 5
|
||||
|
||||
void setup()
|
||||
{
|
||||
// Change these to suit your stepper if you want
|
||||
stepper.setMaxSpeed(100);
|
||||
stepper.setAcceleration(20);
|
||||
stepper.moveTo(500);
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
// If at the end of travel go to the other end
|
||||
if (stepper.distanceToGo() == 0)
|
||||
stepper.moveTo(-stepper.currentPosition());
|
||||
|
||||
stepper.run();
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
// ConstantSpeed.pde
|
||||
// -*- mode: C++ -*-
|
||||
//
|
||||
// Shows how to run AccelStepper in the simplest,
|
||||
// fixed speed mode with no accelerations
|
||||
/// \author Mike McCauley (mikem@airspayce.com)
|
||||
// Copyright (C) 2009 Mike McCauley
|
||||
// $Id: ConstantSpeed.pde,v 1.1 2011/01/05 01:51:01 mikem Exp mikem $
|
||||
|
||||
#include <AccelStepper.h>
|
||||
|
||||
AccelStepper stepper; // Defaults to AccelStepper::FULL4WIRE (4 pins) on 2, 3, 4, 5
|
||||
|
||||
void setup()
|
||||
{
|
||||
stepper.setMaxSpeed(1000);
|
||||
stepper.setSpeed(50);
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
stepper.runSpeed();
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
// DualMotorShield.pde
|
||||
// -*- mode: C++ -*-
|
||||
//
|
||||
// Shows how to run 2 simultaneous steppers
|
||||
// using the Itead Studio Arduino Dual Stepper Motor Driver Shield
|
||||
// model IM120417015
|
||||
// This shield is capable of driving 2 steppers at
|
||||
// currents of up to 750mA
|
||||
// and voltages up to 30V
|
||||
// Runs both steppers forwards and backwards, accelerating and decelerating
|
||||
// at the limits.
|
||||
//
|
||||
// Copyright (C) 2014 Mike McCauley
|
||||
// $Id: $
|
||||
|
||||
#include <AccelStepper.h>
|
||||
|
||||
// The X Stepper pins
|
||||
#define STEPPER1_DIR_PIN 3
|
||||
#define STEPPER1_STEP_PIN 2
|
||||
// The Y stepper pins
|
||||
#define STEPPER2_DIR_PIN 7
|
||||
#define STEPPER2_STEP_PIN 6
|
||||
|
||||
// Define some steppers and the pins the will use
|
||||
AccelStepper stepper1(AccelStepper::DRIVER, STEPPER1_STEP_PIN, STEPPER1_DIR_PIN);
|
||||
AccelStepper stepper2(AccelStepper::DRIVER, STEPPER2_STEP_PIN, STEPPER2_DIR_PIN);
|
||||
|
||||
void setup()
|
||||
{
|
||||
stepper1.setMaxSpeed(200.0);
|
||||
stepper1.setAcceleration(200.0);
|
||||
stepper1.moveTo(100);
|
||||
|
||||
stepper2.setMaxSpeed(100.0);
|
||||
stepper2.setAcceleration(100.0);
|
||||
stepper2.moveTo(100);
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
// Change direction at the limits
|
||||
if (stepper1.distanceToGo() == 0)
|
||||
stepper1.moveTo(-stepper1.currentPosition());
|
||||
if (stepper2.distanceToGo() == 0)
|
||||
stepper2.moveTo(-stepper2.currentPosition());
|
||||
stepper1.run();
|
||||
stepper2.run();
|
||||
}
|
||||
@@ -0,0 +1,103 @@
|
||||
// AFMotor_ConstantSpeed.pde
|
||||
// -*- mode: C++ -*-
|
||||
//
|
||||
// Shows how to use AccelStepper to control a 3-phase motor, such as a HDD spindle motor
|
||||
// using the Adafruit Motor Shield
|
||||
// http://www.ladyada.net/make/mshield/index.html.
|
||||
// Create a subclass of AccelStepper which controls the motor pins via the
|
||||
// Motor Shield serial-to-parallel interface
|
||||
|
||||
#include <AccelStepper.h>
|
||||
|
||||
// Arduino pin names for interface to 74HCT595 latch
|
||||
// on Adafruit Motor Shield
|
||||
#define MOTORLATCH 12
|
||||
#define MOTORCLK 4
|
||||
#define MOTORENABLE 7
|
||||
#define MOTORDATA 8
|
||||
|
||||
// PWM pins, also used to enable motor outputs
|
||||
#define PWM0A 5
|
||||
#define PWM0B 6
|
||||
#define PWM1A 9
|
||||
#define PWM1B 10
|
||||
#define PWM2A 11
|
||||
#define PWM2B 3
|
||||
|
||||
|
||||
// The main purpose of this class is to override setOutputPins to work with Adafruit Motor Shield
|
||||
class AFMotorShield : public AccelStepper
|
||||
{
|
||||
public:
|
||||
AFMotorShield(uint8_t interface = AccelStepper::FULL4WIRE, uint8_t pin1 = 2, uint8_t pin2 = 3, uint8_t pin3 = 4, uint8_t pin4 = 5);
|
||||
|
||||
virtual void setOutputPins(uint8_t mask);
|
||||
};
|
||||
|
||||
|
||||
AFMotorShield::AFMotorShield(uint8_t interface, uint8_t pin1, uint8_t pin2, uint8_t pin3, uint8_t pin4)
|
||||
: AccelStepper(interface, pin1, pin2, pin3, pin4)
|
||||
{
|
||||
// Enable motor control serial to parallel latch
|
||||
pinMode(MOTORLATCH, OUTPUT);
|
||||
pinMode(MOTORENABLE, OUTPUT);
|
||||
pinMode(MOTORDATA, OUTPUT);
|
||||
pinMode(MOTORCLK, OUTPUT);
|
||||
digitalWrite(MOTORENABLE, LOW);
|
||||
|
||||
// enable both H bridges on motor 1
|
||||
pinMode(PWM2A, OUTPUT);
|
||||
pinMode(PWM2B, OUTPUT);
|
||||
pinMode(PWM0A, OUTPUT);
|
||||
pinMode(PWM0B, OUTPUT);
|
||||
digitalWrite(PWM2A, HIGH);
|
||||
digitalWrite(PWM2B, HIGH);
|
||||
digitalWrite(PWM0A, HIGH);
|
||||
digitalWrite(PWM0B, HIGH);
|
||||
|
||||
setOutputPins(0); // Reset
|
||||
};
|
||||
|
||||
// Use the AF Motor Shield serial-to-parallel to set the state of the motor pins
|
||||
// Caution: the mapping of AccelStepper pins to AF motor outputs is not
|
||||
// obvious:
|
||||
// AccelStepper Motor Shield output
|
||||
// pin1 M4A
|
||||
// pin2 M1A
|
||||
// pin3 M2A
|
||||
// pin4 M3A
|
||||
// Caution this is pretty slow and limits the max speed of the motor to about 500/3 rpm
|
||||
void AFMotorShield::setOutputPins(uint8_t mask)
|
||||
{
|
||||
uint8_t i;
|
||||
|
||||
digitalWrite(MOTORLATCH, LOW);
|
||||
digitalWrite(MOTORDATA, LOW);
|
||||
|
||||
for (i=0; i<8; i++)
|
||||
{
|
||||
digitalWrite(MOTORCLK, LOW);
|
||||
|
||||
if (mask & _BV(7-i))
|
||||
digitalWrite(MOTORDATA, HIGH);
|
||||
else
|
||||
digitalWrite(MOTORDATA, LOW);
|
||||
|
||||
digitalWrite(MOTORCLK, HIGH);
|
||||
}
|
||||
digitalWrite(MOTORLATCH, HIGH);
|
||||
}
|
||||
|
||||
AFMotorShield stepper(AccelStepper::HALF3WIRE, 0, 0, 0, 0); // 3 phase HDD spindle drive
|
||||
|
||||
void setup()
|
||||
{
|
||||
stepper.setMaxSpeed(500); // divide by 3 to get rpm
|
||||
stepper.setAcceleration(80);
|
||||
stepper.moveTo(10000000);
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
stepper.run();
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
// MultiStepper.pde
|
||||
// -*- mode: C++ -*-
|
||||
// Use MultiStepper class to manage multiple steppers and make them all move to
|
||||
// the same position at the same time for linear 2d (or 3d) motion.
|
||||
|
||||
#include <AccelStepper.h>
|
||||
#include <MultiStepper.h>
|
||||
|
||||
// EG X-Y position bed driven by 2 steppers
|
||||
// Alas its not possible to build an array of these with different pins for each :-(
|
||||
AccelStepper stepper1(AccelStepper::FULL4WIRE, 2, 3, 4, 5);
|
||||
AccelStepper stepper2(AccelStepper::FULL4WIRE, 8, 9, 10, 11);
|
||||
|
||||
// Up to 10 steppers can be handled as a group by MultiStepper
|
||||
MultiStepper steppers;
|
||||
|
||||
void setup() {
|
||||
Serial.begin(9600);
|
||||
|
||||
// Configure each stepper
|
||||
stepper1.setMaxSpeed(100);
|
||||
stepper2.setMaxSpeed(100);
|
||||
|
||||
// Then give them to MultiStepper to manage
|
||||
steppers.addStepper(stepper1);
|
||||
steppers.addStepper(stepper2);
|
||||
}
|
||||
|
||||
void loop() {
|
||||
long positions[2]; // Array of desired stepper positions
|
||||
|
||||
positions[0] = 1000;
|
||||
positions[1] = 50;
|
||||
steppers.moveTo(positions);
|
||||
steppers.runSpeedToPosition(); // Blocks until all are in position
|
||||
delay(1000);
|
||||
|
||||
// Move to a different coordinate
|
||||
positions[0] = -100;
|
||||
positions[1] = 100;
|
||||
steppers.moveTo(positions);
|
||||
steppers.runSpeedToPosition(); // Blocks until all are in position
|
||||
delay(1000);
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
// MultiStepper.pde
|
||||
// -*- mode: C++ -*-
|
||||
//
|
||||
// Shows how to multiple simultaneous steppers
|
||||
// Runs one stepper forwards and backwards, accelerating and decelerating
|
||||
// at the limits. Runs other steppers at the same time
|
||||
//
|
||||
// Copyright (C) 2009 Mike McCauley
|
||||
// $Id: MultiStepper.pde,v 1.1 2011/01/05 01:51:01 mikem Exp mikem $
|
||||
|
||||
#include <AccelStepper.h>
|
||||
|
||||
// Define some steppers and the pins the will use
|
||||
AccelStepper stepper1; // Defaults to AccelStepper::FULL4WIRE (4 pins) on 2, 3, 4, 5
|
||||
AccelStepper stepper2(AccelStepper::FULL4WIRE, 6, 7, 8, 9);
|
||||
AccelStepper stepper3(AccelStepper::FULL2WIRE, 10, 11);
|
||||
|
||||
void setup()
|
||||
{
|
||||
stepper1.setMaxSpeed(200.0);
|
||||
stepper1.setAcceleration(100.0);
|
||||
stepper1.moveTo(24);
|
||||
|
||||
stepper2.setMaxSpeed(300.0);
|
||||
stepper2.setAcceleration(100.0);
|
||||
stepper2.moveTo(1000000);
|
||||
|
||||
stepper3.setMaxSpeed(300.0);
|
||||
stepper3.setAcceleration(100.0);
|
||||
stepper3.moveTo(1000000);
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
// Change direction at the limits
|
||||
if (stepper1.distanceToGo() == 0)
|
||||
stepper1.moveTo(-stepper1.currentPosition());
|
||||
stepper1.run();
|
||||
stepper2.run();
|
||||
stepper3.run();
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
// Overshoot.pde
|
||||
// -*- mode: C++ -*-
|
||||
//
|
||||
// Check overshoot handling
|
||||
// which sets a new target position and then waits until the stepper has
|
||||
// achieved it. This is used for testing the handling of overshoots
|
||||
//
|
||||
// Copyright (C) 2009 Mike McCauley
|
||||
// $Id: Overshoot.pde,v 1.1 2011/01/05 01:51:01 mikem Exp mikem $
|
||||
|
||||
#include <AccelStepper.h>
|
||||
|
||||
// Define a stepper and the pins it will use
|
||||
AccelStepper stepper; // Defaults to AccelStepper::FULL4WIRE (4 pins) on 2, 3, 4, 5
|
||||
|
||||
void setup()
|
||||
{
|
||||
stepper.setMaxSpeed(150);
|
||||
stepper.setAcceleration(100);
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
stepper.moveTo(500);
|
||||
while (stepper.currentPosition() != 300) // Full speed up to 300
|
||||
stepper.run();
|
||||
stepper.runToNewPosition(0); // Cause an overshoot then back to 0
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
// ProportionalControl.pde
|
||||
// -*- mode: C++ -*-
|
||||
//
|
||||
// Make a single stepper follow the analog value read from a pot or whatever
|
||||
// The stepper will move at a constant speed to each newly set posiiton,
|
||||
// depending on the value of the pot.
|
||||
//
|
||||
// Copyright (C) 2012 Mike McCauley
|
||||
// $Id: ProportionalControl.pde,v 1.1 2011/01/05 01:51:01 mikem Exp mikem $
|
||||
|
||||
#include <AccelStepper.h>
|
||||
|
||||
// Define a stepper and the pins it will use
|
||||
AccelStepper stepper; // Defaults to AccelStepper::FULL4WIRE (4 pins) on 2, 3, 4, 5
|
||||
|
||||
// This defines the analog input pin for reading the control voltage
|
||||
// Tested with a 10k linear pot between 5v and GND
|
||||
#define ANALOG_IN A0
|
||||
|
||||
void setup()
|
||||
{
|
||||
stepper.setMaxSpeed(1000);
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
// Read new position
|
||||
int analog_in = analogRead(ANALOG_IN);
|
||||
stepper.moveTo(analog_in);
|
||||
stepper.setSpeed(100);
|
||||
stepper.runSpeedToPosition();
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
// Quickstop.pde
|
||||
// -*- mode: C++ -*-
|
||||
//
|
||||
// Check stop handling.
|
||||
// Calls stop() while the stepper is travelling at full speed, causing
|
||||
// the stepper to stop as quickly as possible, within the constraints of the
|
||||
// current acceleration.
|
||||
//
|
||||
// Copyright (C) 2012 Mike McCauley
|
||||
// $Id: $
|
||||
|
||||
#include <AccelStepper.h>
|
||||
|
||||
// Define a stepper and the pins it will use
|
||||
AccelStepper stepper; // Defaults to AccelStepper::FULL4WIRE (4 pins) on 2, 3, 4, 5
|
||||
|
||||
void setup()
|
||||
{
|
||||
stepper.setMaxSpeed(150);
|
||||
stepper.setAcceleration(100);
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
stepper.moveTo(500);
|
||||
while (stepper.currentPosition() != 300) // Full speed up to 300
|
||||
stepper.run();
|
||||
stepper.stop(); // Stop as fast as possible: sets new target
|
||||
stepper.runToPosition();
|
||||
// Now stopped after quickstop
|
||||
|
||||
// Now go backwards
|
||||
stepper.moveTo(-500);
|
||||
while (stepper.currentPosition() != 0) // Full speed basck to 0
|
||||
stepper.run();
|
||||
stepper.stop(); // Stop as fast as possible: sets new target
|
||||
stepper.runToPosition();
|
||||
// Now stopped after quickstop
|
||||
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
// Random.pde
|
||||
// -*- mode: C++ -*-
|
||||
//
|
||||
// Make a single stepper perform random changes in speed, position and acceleration
|
||||
//
|
||||
// Copyright (C) 2009 Mike McCauley
|
||||
// $Id: Random.pde,v 1.1 2011/01/05 01:51:01 mikem Exp mikem $
|
||||
|
||||
#include <AccelStepper.h>
|
||||
|
||||
// Define a stepper and the pins it will use
|
||||
AccelStepper stepper; // Defaults to AccelStepper::FULL4WIRE (4 pins) on 2, 3, 4, 5
|
||||
|
||||
void setup()
|
||||
{
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
if (stepper.distanceToGo() == 0)
|
||||
{
|
||||
// Random change to speed, position and acceleration
|
||||
// Make sure we dont get 0 speed or accelerations
|
||||
delay(1000);
|
||||
stepper.moveTo(rand() % 200);
|
||||
stepper.setMaxSpeed((rand() % 200) + 1);
|
||||
stepper.setAcceleration((rand() % 200) + 1);
|
||||
}
|
||||
stepper.run();
|
||||
}
|
||||
41
arduino-cli/libraries/AccelStepper/keywords.txt
Normal file
41
arduino-cli/libraries/AccelStepper/keywords.txt
Normal file
@@ -0,0 +1,41 @@
|
||||
#######################################
|
||||
# Syntax Coloring Map For AccelStepper
|
||||
#######################################
|
||||
|
||||
#######################################
|
||||
# Datatypes (KEYWORD1)
|
||||
#######################################
|
||||
|
||||
AccelStepper KEYWORD1
|
||||
MultiStepper KEYWORD1
|
||||
|
||||
#######################################
|
||||
# Methods and Functions (KEYWORD2)
|
||||
#######################################
|
||||
|
||||
moveTo KEYWORD2
|
||||
move KEYWORD2
|
||||
run KEYWORD2
|
||||
runSpeed KEYWORD2
|
||||
setMaxSpeed KEYWORD2
|
||||
setAcceleration KEYWORD2
|
||||
setSpeed KEYWORD2
|
||||
speed KEYWORD2
|
||||
distanceToGo KEYWORD2
|
||||
targetPosition KEYWORD2
|
||||
currentPosition KEYWORD2
|
||||
setCurrentPosition KEYWORD2
|
||||
runToPosition KEYWORD2
|
||||
runSpeedToPosition KEYWORD2
|
||||
runToNewPosition KEYWORD2
|
||||
stop KEYWORD2
|
||||
disableOutputs KEYWORD2
|
||||
enableOutputs KEYWORD2
|
||||
setMinPulseWidth KEYWORD2
|
||||
setEnablePin KEYWORD2
|
||||
setPinsInverted KEYWORD2
|
||||
maxSpeed KEYWORD2
|
||||
#######################################
|
||||
# Constants (LITERAL1)
|
||||
#######################################
|
||||
|
||||
2280
arduino-cli/libraries/AccelStepper/project.cfg
Normal file
2280
arduino-cli/libraries/AccelStepper/project.cfg
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,656 @@
|
||||
// AccelStepper_74HC595.cpp
|
||||
//
|
||||
// Copyright (C) 2009-2013 Mike McCauley
|
||||
// $Id: AccelStepper_74HC595.cpp,v 1.23 2016/08/09 00:39:10 mikem Exp $
|
||||
|
||||
#include "AccelStepper_74HC595.h"
|
||||
#include "ShiftRegister74HC595.h"
|
||||
#if 0
|
||||
// Some debugging assistance
|
||||
void dump(uint8_t* p, int l)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < l; i++)
|
||||
{
|
||||
Serial.print(p[i], HEX);
|
||||
Serial.print(" ");
|
||||
}
|
||||
Serial.println("");
|
||||
}
|
||||
#endif
|
||||
|
||||
void AccelStepper_74HC595::moveTo(long absolute)
|
||||
{
|
||||
if (_targetPos != absolute)
|
||||
{
|
||||
_targetPos = absolute;
|
||||
computeNewSpeed();
|
||||
// compute new n?
|
||||
}
|
||||
}
|
||||
|
||||
void AccelStepper_74HC595::move(long relative)
|
||||
{
|
||||
moveTo(_currentPos + relative);
|
||||
}
|
||||
|
||||
// Implements steps according to the current step interval
|
||||
// You must call this at least once per step
|
||||
// returns true if a step occurred
|
||||
boolean AccelStepper_74HC595::runSpeed()
|
||||
{
|
||||
// Dont do anything unless we actually have a step interval
|
||||
if (!_stepInterval)
|
||||
return false;
|
||||
|
||||
unsigned long time = micros();
|
||||
if (time - _lastStepTime >= _stepInterval)
|
||||
{
|
||||
if (_direction == DIRECTION_CW)
|
||||
{
|
||||
// Clockwise
|
||||
_currentPos += 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Anticlockwise
|
||||
_currentPos -= 1;
|
||||
}
|
||||
step(_currentPos);
|
||||
|
||||
_lastStepTime = time; // Caution: does not account for costs in step()
|
||||
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
long AccelStepper_74HC595::distanceToGo()
|
||||
{
|
||||
return _targetPos - _currentPos;
|
||||
}
|
||||
|
||||
long AccelStepper_74HC595::targetPosition()
|
||||
{
|
||||
return _targetPos;
|
||||
}
|
||||
|
||||
long AccelStepper_74HC595::currentPosition()
|
||||
{
|
||||
return _currentPos;
|
||||
}
|
||||
|
||||
// Useful during initialisations or after initial positioning
|
||||
// Sets speed to 0
|
||||
void AccelStepper_74HC595::setCurrentPosition(long position)
|
||||
{
|
||||
_targetPos = _currentPos = position;
|
||||
_n = 0;
|
||||
_stepInterval = 0;
|
||||
_speed = 0.0;
|
||||
}
|
||||
|
||||
void AccelStepper_74HC595::computeNewSpeed()
|
||||
{
|
||||
long distanceTo = distanceToGo(); // +ve is clockwise from curent location
|
||||
|
||||
long stepsToStop = (long)((_speed * _speed) / (2.0 * _acceleration)); // Equation 16
|
||||
|
||||
if (distanceTo == 0 && stepsToStop <= 1)
|
||||
{
|
||||
// We are at the target and its time to stop
|
||||
_stepInterval = 0;
|
||||
_speed = 0.0;
|
||||
_n = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
if (distanceTo > 0)
|
||||
{
|
||||
// We are anticlockwise from the target
|
||||
// Need to go clockwise from here, maybe decelerate now
|
||||
if (_n > 0)
|
||||
{
|
||||
// Currently accelerating, need to decel now? Or maybe going the wrong way?
|
||||
if ((stepsToStop >= distanceTo) || _direction == DIRECTION_CCW)
|
||||
_n = -stepsToStop; // Start deceleration
|
||||
}
|
||||
else if (_n < 0)
|
||||
{
|
||||
// Currently decelerating, need to accel again?
|
||||
if ((stepsToStop < distanceTo) && _direction == DIRECTION_CW)
|
||||
_n = -_n; // Start accceleration
|
||||
}
|
||||
}
|
||||
else if (distanceTo < 0)
|
||||
{
|
||||
// We are clockwise from the target
|
||||
// Need to go anticlockwise from here, maybe decelerate
|
||||
if (_n > 0)
|
||||
{
|
||||
// Currently accelerating, need to decel now? Or maybe going the wrong way?
|
||||
if ((stepsToStop >= -distanceTo) || _direction == DIRECTION_CW)
|
||||
_n = -stepsToStop; // Start deceleration
|
||||
}
|
||||
else if (_n < 0)
|
||||
{
|
||||
// Currently decelerating, need to accel again?
|
||||
if ((stepsToStop < -distanceTo) && _direction == DIRECTION_CCW)
|
||||
_n = -_n; // Start accceleration
|
||||
}
|
||||
}
|
||||
|
||||
// Need to accelerate or decelerate
|
||||
if (_n == 0)
|
||||
{
|
||||
// First step from stopped
|
||||
_cn = _c0;
|
||||
_direction = (distanceTo > 0) ? DIRECTION_CW : DIRECTION_CCW;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Subsequent step. Works for accel (n is +_ve) and decel (n is -ve).
|
||||
_cn = _cn - ((2.0 * _cn) / ((4.0 * _n) + 1)); // Equation 13
|
||||
_cn = max(_cn, _cmin);
|
||||
}
|
||||
_n++;
|
||||
_stepInterval = _cn;
|
||||
_speed = 1000000.0 / _cn;
|
||||
if (_direction == DIRECTION_CCW)
|
||||
_speed = -_speed;
|
||||
|
||||
#if 0
|
||||
Serial.println(_speed);
|
||||
Serial.println(_acceleration);
|
||||
Serial.println(_cn);
|
||||
Serial.println(_c0);
|
||||
Serial.println(_n);
|
||||
Serial.println(_stepInterval);
|
||||
Serial.println(distanceTo);
|
||||
Serial.println(stepsToStop);
|
||||
Serial.println("-----");
|
||||
#endif
|
||||
}
|
||||
|
||||
// Run the motor to implement speed and acceleration in order to proceed to the target position
|
||||
// You must call this at least once per step, preferably in your main loop
|
||||
// If the motor is in the desired position, the cost is very small
|
||||
// returns true if the motor is still running to the target position.
|
||||
boolean AccelStepper_74HC595::run()
|
||||
{
|
||||
if (runSpeed())
|
||||
computeNewSpeed();
|
||||
return _speed != 0.0 || distanceToGo() != 0;
|
||||
}
|
||||
|
||||
AccelStepper_74HC595::AccelStepper_74HC595(ShiftRegister74HC595 *device, uint8_t interface, uint8_t pin1, uint8_t pin2, uint8_t pin3, uint8_t pin4, bool enable)
|
||||
{
|
||||
_device = device;
|
||||
_interface = interface;
|
||||
_currentPos = 0;
|
||||
_targetPos = 0;
|
||||
_speed = 0.0;
|
||||
_maxSpeed = 1.0;
|
||||
_acceleration = 0.0;
|
||||
_sqrt_twoa = 1.0;
|
||||
_stepInterval = 0;
|
||||
_minPulseWidth = 1;
|
||||
_enablePin = 0xff;
|
||||
_lastStepTime = 0;
|
||||
_pin[0] = pin1;
|
||||
_pin[1] = pin2;
|
||||
_pin[2] = pin3;
|
||||
_pin[3] = pin4;
|
||||
_enableInverted = false;
|
||||
|
||||
// NEW
|
||||
_n = 0;
|
||||
_c0 = 0.0;
|
||||
_cn = 0.0;
|
||||
_cmin = 1.0;
|
||||
_direction = DIRECTION_CCW;
|
||||
|
||||
int i;
|
||||
for (i = 0; i < 4; i++)
|
||||
_pinInverted[i] = 0;
|
||||
if (enable)
|
||||
enableOutputs();
|
||||
// Some reasonable default
|
||||
setAcceleration(1);
|
||||
}
|
||||
|
||||
/*
|
||||
AccelStepper_74HC595::AccelStepper_74HC595(void (*forward)(), void (*backward)())
|
||||
{
|
||||
_interface = 0;
|
||||
_currentPos = 0;
|
||||
_targetPos = 0;
|
||||
_speed = 0.0;
|
||||
_maxSpeed = 1.0;
|
||||
_acceleration = 0.0;
|
||||
_sqrt_twoa = 1.0;
|
||||
_stepInterval = 0;
|
||||
_minPulseWidth = 1;
|
||||
_enablePin = 0xff;
|
||||
_lastStepTime = 0;
|
||||
_pin[0] = 0;
|
||||
_pin[1] = 0;
|
||||
_pin[2] = 0;
|
||||
_pin[3] = 0;
|
||||
_forward = forward;
|
||||
_backward = backward;
|
||||
|
||||
// NEW
|
||||
_n = 0;
|
||||
_c0 = 0.0;
|
||||
_cn = 0.0;
|
||||
_cmin = 1.0;
|
||||
_direction = DIRECTION_CCW;
|
||||
|
||||
int i;
|
||||
for (i = 0; i < 4; i++)
|
||||
_pinInverted[i] = 0;
|
||||
// Some reasonable default
|
||||
setAcceleration(1);
|
||||
}
|
||||
*/
|
||||
|
||||
void AccelStepper_74HC595::setMaxSpeed(float speed)
|
||||
{
|
||||
if (speed < 0.0)
|
||||
speed = -speed;
|
||||
if (_maxSpeed != speed)
|
||||
{
|
||||
_maxSpeed = speed;
|
||||
_cmin = 1000000.0 / speed;
|
||||
// Recompute _n from current speed and adjust speed if accelerating or cruising
|
||||
if (_n > 0)
|
||||
{
|
||||
_n = (long)((_speed * _speed) / (2.0 * _acceleration)); // Equation 16
|
||||
computeNewSpeed();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
float AccelStepper_74HC595::maxSpeed()
|
||||
{
|
||||
return _maxSpeed;
|
||||
}
|
||||
|
||||
void AccelStepper_74HC595::setAcceleration(float acceleration)
|
||||
{
|
||||
if (acceleration == 0.0)
|
||||
return;
|
||||
if (acceleration < 0.0)
|
||||
acceleration = -acceleration;
|
||||
if (_acceleration != acceleration)
|
||||
{
|
||||
// Recompute _n per Equation 17
|
||||
_n = _n * (_acceleration / acceleration);
|
||||
// New c0 per Equation 7, with correction per Equation 15
|
||||
_c0 = 0.676 * sqrt(2.0 / acceleration) * 1000000.0; // Equation 15
|
||||
_acceleration = acceleration;
|
||||
computeNewSpeed();
|
||||
}
|
||||
}
|
||||
|
||||
void AccelStepper_74HC595::setSpeed(float speed)
|
||||
{
|
||||
if (speed == _speed)
|
||||
return;
|
||||
speed = constrain(speed, -_maxSpeed, _maxSpeed);
|
||||
if (speed == 0.0)
|
||||
_stepInterval = 0;
|
||||
else
|
||||
{
|
||||
_stepInterval = fabs(1000000.0 / speed);
|
||||
_direction = (speed > 0.0) ? DIRECTION_CW : DIRECTION_CCW;
|
||||
}
|
||||
_speed = speed;
|
||||
}
|
||||
|
||||
float AccelStepper_74HC595::speed()
|
||||
{
|
||||
return _speed;
|
||||
}
|
||||
|
||||
// Subclasses can override
|
||||
void AccelStepper_74HC595::step(long step)
|
||||
{
|
||||
switch (_interface)
|
||||
{
|
||||
case FUNCTION:
|
||||
step0(step);
|
||||
break;
|
||||
|
||||
case DRIVER:
|
||||
step1(step);
|
||||
break;
|
||||
|
||||
case FULL2WIRE:
|
||||
step2(step);
|
||||
break;
|
||||
|
||||
case FULL3WIRE:
|
||||
step3(step);
|
||||
break;
|
||||
|
||||
case FULL4WIRE:
|
||||
step4(step);
|
||||
break;
|
||||
|
||||
case HALF3WIRE:
|
||||
step6(step);
|
||||
break;
|
||||
|
||||
case HALF4WIRE:
|
||||
step8(step);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// You might want to override this to implement eg serial output
|
||||
// bit 0 of the mask corresponds to _pin[0]
|
||||
// bit 1 of the mask corresponds to _pin[1]
|
||||
// ....
|
||||
void AccelStepper_74HC595::setOutputPins(uint8_t mask)
|
||||
{
|
||||
uint8_t numpins = 2;
|
||||
if (_interface == FULL4WIRE || _interface == HALF4WIRE)
|
||||
numpins = 4;
|
||||
else if (_interface == FULL3WIRE || _interface == HALF3WIRE)
|
||||
numpins = 3;
|
||||
uint8_t i;
|
||||
for (i = 0; i < numpins; i++)
|
||||
//_device->set(0, HIGH)
|
||||
_device->set(_pin[i], (mask & (1 << i)) ? (HIGH ^ _pinInverted[i]) : (LOW ^ _pinInverted[i]));
|
||||
}
|
||||
|
||||
// 0 pin step function (ie for functional usage)
|
||||
void AccelStepper_74HC595::step0(long step)
|
||||
{
|
||||
(void)(step); // Unused
|
||||
if (_speed > 0)
|
||||
_forward();
|
||||
else
|
||||
_backward();
|
||||
}
|
||||
|
||||
// 1 pin step function (ie for stepper drivers)
|
||||
// This is passed the current step number (0 to 7)
|
||||
// Subclasses can override
|
||||
void AccelStepper_74HC595::step1(long step)
|
||||
{
|
||||
(void)(step); // Unused
|
||||
|
||||
// _pin[0] is step, _pin[1] is direction
|
||||
setOutputPins(_direction ? 0b10 : 0b00); // Set direction first else get rogue pulses
|
||||
setOutputPins(_direction ? 0b11 : 0b01); // step HIGH
|
||||
// Caution 200ns setup time
|
||||
// Delay the minimum allowed pulse width
|
||||
delayMicroseconds(_minPulseWidth);
|
||||
setOutputPins(_direction ? 0b10 : 0b00); // step LOW
|
||||
}
|
||||
|
||||
|
||||
// 2 pin step function
|
||||
// This is passed the current step number (0 to 7)
|
||||
// Subclasses can override
|
||||
void AccelStepper_74HC595::step2(long step)
|
||||
{
|
||||
switch (step & 0x3)
|
||||
{
|
||||
case 0: /* 01 */
|
||||
setOutputPins(0b10);
|
||||
break;
|
||||
|
||||
case 1: /* 11 */
|
||||
setOutputPins(0b11);
|
||||
break;
|
||||
|
||||
case 2: /* 10 */
|
||||
setOutputPins(0b01);
|
||||
break;
|
||||
|
||||
case 3: /* 00 */
|
||||
setOutputPins(0b00);
|
||||
break;
|
||||
}
|
||||
}
|
||||
// 3 pin step function
|
||||
// This is passed the current step number (0 to 7)
|
||||
// Subclasses can override
|
||||
void AccelStepper_74HC595::step3(long step)
|
||||
{
|
||||
switch (step % 3)
|
||||
{
|
||||
case 0: // 100
|
||||
setOutputPins(0b100);
|
||||
break;
|
||||
|
||||
case 1: // 001
|
||||
setOutputPins(0b001);
|
||||
break;
|
||||
|
||||
case 2: //010
|
||||
setOutputPins(0b010);
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// 4 pin step function for half stepper
|
||||
// This is passed the current step number (0 to 7)
|
||||
// Subclasses can override
|
||||
void AccelStepper_74HC595::step4(long step)
|
||||
{
|
||||
switch (step & 0x3)
|
||||
{
|
||||
case 0: // 1010
|
||||
setOutputPins(0b0101);
|
||||
break;
|
||||
|
||||
case 1: // 0110
|
||||
setOutputPins(0b0110);
|
||||
break;
|
||||
|
||||
case 2: //0101
|
||||
setOutputPins(0b1010);
|
||||
break;
|
||||
|
||||
case 3: //1001
|
||||
setOutputPins(0b1001);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// 3 pin half step function
|
||||
// This is passed the current step number (0 to 7)
|
||||
// Subclasses can override
|
||||
void AccelStepper_74HC595::step6(long step)
|
||||
{
|
||||
switch (step % 6)
|
||||
{
|
||||
case 0: // 100
|
||||
setOutputPins(0b100);
|
||||
break;
|
||||
|
||||
case 1: // 101
|
||||
setOutputPins(0b101);
|
||||
break;
|
||||
|
||||
case 2: // 001
|
||||
setOutputPins(0b001);
|
||||
break;
|
||||
|
||||
case 3: // 011
|
||||
setOutputPins(0b011);
|
||||
break;
|
||||
|
||||
case 4: // 010
|
||||
setOutputPins(0b010);
|
||||
break;
|
||||
|
||||
case 5: // 011
|
||||
setOutputPins(0b110);
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// 4 pin half step function
|
||||
// This is passed the current step number (0 to 7)
|
||||
// Subclasses can override
|
||||
void AccelStepper_74HC595::step8(long step)
|
||||
{
|
||||
switch (step & 0x7)
|
||||
{
|
||||
case 0: // 1000
|
||||
setOutputPins(0b0001);
|
||||
break;
|
||||
|
||||
case 1: // 1010
|
||||
setOutputPins(0b0101);
|
||||
break;
|
||||
|
||||
case 2: // 0010
|
||||
setOutputPins(0b0100);
|
||||
break;
|
||||
|
||||
case 3: // 0110
|
||||
setOutputPins(0b0110);
|
||||
break;
|
||||
|
||||
case 4: // 0100
|
||||
setOutputPins(0b0010);
|
||||
break;
|
||||
|
||||
case 5: //0101
|
||||
setOutputPins(0b1010);
|
||||
break;
|
||||
|
||||
case 6: // 0001
|
||||
setOutputPins(0b1000);
|
||||
break;
|
||||
|
||||
case 7: //1001
|
||||
setOutputPins(0b1001);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Prevents power consumption on the outputs
|
||||
void AccelStepper_74HC595::disableOutputs()
|
||||
{
|
||||
if (! _interface) return;
|
||||
|
||||
setOutputPins(0); // Handles inversion automatically
|
||||
if (_enablePin != 0xff)
|
||||
{
|
||||
//pinMode(_enablePin, OUTPUT);
|
||||
_device->set(_enablePin, LOW ^ _enableInverted);
|
||||
}
|
||||
}
|
||||
|
||||
void AccelStepper_74HC595::enableOutputs()
|
||||
{
|
||||
if (! _interface)
|
||||
return;
|
||||
|
||||
//pinMode(_pin[0], OUTPUT);
|
||||
//pinMode(_pin[1], OUTPUT);
|
||||
//if (_interface == FULL4WIRE || _interface == HALF4WIRE)
|
||||
//{
|
||||
//pinMode(_pin[2], OUTPUT);
|
||||
//pinMode(_pin[3], OUTPUT);
|
||||
//}
|
||||
//else if (_interface == FULL3WIRE || _interface == HALF3WIRE)
|
||||
//{
|
||||
//pinMode(_pin[2], OUTPUT);
|
||||
//}
|
||||
|
||||
if (_enablePin != 0xff)
|
||||
{
|
||||
//pinMode(_enablePin, OUTPUT);
|
||||
_device->set(_enablePin, HIGH ^ _enableInverted);
|
||||
}
|
||||
}
|
||||
|
||||
void AccelStepper_74HC595::setMinPulseWidth(unsigned int minWidth)
|
||||
{
|
||||
_minPulseWidth = minWidth;
|
||||
}
|
||||
|
||||
void AccelStepper_74HC595::setEnablePin(uint8_t enablePin)
|
||||
{
|
||||
_enablePin = enablePin;
|
||||
|
||||
// This happens after construction, so init pin now.
|
||||
if (_enablePin != 0xff)
|
||||
{
|
||||
//pinMode(_enablePin, OUTPUT);
|
||||
_device->set(_enablePin, HIGH ^ _enableInverted);
|
||||
}
|
||||
}
|
||||
|
||||
void AccelStepper_74HC595::setPinsInverted(bool directionInvert, bool stepInvert, bool enableInvert)
|
||||
{
|
||||
_pinInverted[0] = stepInvert;
|
||||
_pinInverted[1] = directionInvert;
|
||||
_enableInverted = enableInvert;
|
||||
}
|
||||
|
||||
void AccelStepper_74HC595::setPinsInverted(bool pin1Invert, bool pin2Invert, bool pin3Invert, bool pin4Invert, bool enableInvert)
|
||||
{
|
||||
_pinInverted[0] = pin1Invert;
|
||||
_pinInverted[1] = pin2Invert;
|
||||
_pinInverted[2] = pin3Invert;
|
||||
_pinInverted[3] = pin4Invert;
|
||||
_enableInverted = enableInvert;
|
||||
}
|
||||
|
||||
// Blocks until the target position is reached and stopped
|
||||
void AccelStepper_74HC595::runToPosition()
|
||||
{
|
||||
while (run())
|
||||
;
|
||||
}
|
||||
|
||||
boolean AccelStepper_74HC595::runSpeedToPosition()
|
||||
{
|
||||
if (_targetPos == _currentPos)
|
||||
return false;
|
||||
if (_targetPos >_currentPos)
|
||||
_direction = DIRECTION_CW;
|
||||
else
|
||||
_direction = DIRECTION_CCW;
|
||||
return runSpeed();
|
||||
}
|
||||
|
||||
// Blocks until the new target position is reached
|
||||
void AccelStepper_74HC595::runToNewPosition(long position)
|
||||
{
|
||||
moveTo(position);
|
||||
runToPosition();
|
||||
}
|
||||
|
||||
void AccelStepper_74HC595::stop()
|
||||
{
|
||||
if (_speed != 0.0)
|
||||
{
|
||||
long stepsToStop = (long)((_speed * _speed) / (2.0 * _acceleration)) + 1; // Equation 16 (+integer rounding)
|
||||
if (_speed > 0)
|
||||
move(stepsToStop);
|
||||
else
|
||||
move(-stepsToStop);
|
||||
}
|
||||
}
|
||||
|
||||
bool AccelStepper_74HC595::isRunning()
|
||||
{
|
||||
return !(_speed == 0.0 && _targetPos == _currentPos);
|
||||
}
|
||||
@@ -0,0 +1,735 @@
|
||||
// AccelStepper_74HC595.h
|
||||
//
|
||||
/// \mainpage AccelStepper_74HC595 library for Arduino
|
||||
///
|
||||
/// This is the Arduino AccelStepper_74HC595 library.
|
||||
/// It provides an object-oriented interface for 2, 3 or 4 pin stepper motors and motor drivers.
|
||||
///
|
||||
/// The standard Arduino IDE includes the Stepper library
|
||||
/// (http://arduino.cc/en/Reference/Stepper) for stepper motors. It is
|
||||
/// perfectly adequate for simple, single motor applications.
|
||||
///
|
||||
/// AccelStepper_74HC595 significantly improves on the standard Arduino Stepper library in several ways:
|
||||
/// \li Supports acceleration and deceleration
|
||||
/// \li Supports multiple simultaneous steppers, with independent concurrent stepping on each stepper
|
||||
/// \li API functions never delay() or block
|
||||
/// \li Supports 2, 3 and 4 wire steppers, plus 3 and 4 wire half steppers.
|
||||
/// \li Supports alternate stepping functions to enable support of AFMotor (https://github.com/adafruit/Adafruit-Motor-Shield-library)
|
||||
/// \li Supports stepper drivers such as the Sparkfun EasyDriver (based on 3967 driver chip)
|
||||
/// \li Very slow speeds are supported
|
||||
/// \li Extensive API
|
||||
/// \li Subclass support
|
||||
///
|
||||
/// The latest version of this documentation can be downloaded from
|
||||
/// http://www.airspayce.com/mikem/arduino/AccelStepper_74HC595
|
||||
/// The version of the package that this documentation refers to can be downloaded
|
||||
/// from http://www.airspayce.com/mikem/arduino/AccelStepper_74HC595/AccelStepper_74HC595-1.59.zip
|
||||
///
|
||||
/// Example Arduino programs are included to show the main modes of use.
|
||||
///
|
||||
/// You can also find online help and discussion at http://groups.google.com/group/accelstepper
|
||||
/// Please use that group for all questions and discussions on this topic.
|
||||
/// Do not contact the author directly, unless it is to discuss commercial licensing.
|
||||
/// Before asking a question or reporting a bug, please read
|
||||
/// - http://en.wikipedia.org/wiki/Wikipedia:Reference_desk/How_to_ask_a_software_question
|
||||
/// - http://www.catb.org/esr/faqs/smart-questions.html
|
||||
/// - http://www.chiark.greenend.org.uk/~shgtatham/bugs.html
|
||||
///
|
||||
/// Tested on Arduino Diecimila and Mega with arduino-0018 & arduino-0021
|
||||
/// on OpenSuSE 11.1 and avr-libc-1.6.1-1.15,
|
||||
/// cross-avr-binutils-2.19-9.1, cross-avr-gcc-4.1.3_20080612-26.5.
|
||||
/// Tested on Teensy http://www.pjrc.com/teensy including Teensy 3.1 built using Arduino IDE 1.0.5 with
|
||||
/// teensyduino addon 1.18 and later.
|
||||
///
|
||||
/// \par Installation
|
||||
///
|
||||
/// Install in the usual way: unzip the distribution zip file to the libraries
|
||||
/// sub-folder of your sketchbook.
|
||||
///
|
||||
/// \par Theory
|
||||
///
|
||||
/// This code uses speed calculations as described in
|
||||
/// "Generate stepper-motor speed profiles in real time" by David Austin
|
||||
/// http://fab.cba.mit.edu/classes/MIT/961.09/projects/i0/Stepper_Motor_Speed_Profile.pdf or
|
||||
/// http://www.embedded.com/design/mcus-processors-and-socs/4006438/Generate-stepper-motor-speed-profiles-in-real-time or
|
||||
/// http://web.archive.org/web/20140705143928/http://fab.cba.mit.edu/classes/MIT/961.09/projects/i0/Stepper_Motor_Speed_Profile.pdf
|
||||
/// with the exception that AccelStepper_74HC595 uses steps per second rather than radians per second
|
||||
/// (because we dont know the step angle of the motor)
|
||||
/// An initial step interval is calculated for the first step, based on the desired acceleration
|
||||
/// On subsequent steps, shorter step intervals are calculated based
|
||||
/// on the previous step until max speed is achieved.
|
||||
///
|
||||
/// \par Adafruit Motor Shield V2
|
||||
///
|
||||
/// The included examples AFMotor_* are for Adafruit Motor Shield V1 and do not work with Adafruit Motor Shield V2.
|
||||
/// See https://github.com/adafruit/Adafruit_Motor_Shield_V2_Library for examples that work with Adafruit Motor Shield V2.
|
||||
///
|
||||
/// \par Donations
|
||||
///
|
||||
/// This library is offered under a free GPL license for those who want to use it that way.
|
||||
/// We try hard to keep it up to date, fix bugs
|
||||
/// and to provide free support. If this library has helped you save time or money, please consider donating at
|
||||
/// http://www.airspayce.com or here:
|
||||
///
|
||||
/// \htmlonly <form action="https://www.paypal.com/cgi-bin/webscr" method="post"><input type="hidden" name="cmd" value="_donations" /> <input type="hidden" name="business" value="mikem@airspayce.com" /> <input type="hidden" name="lc" value="AU" /> <input type="hidden" name="item_name" value="Airspayce" /> <input type="hidden" name="item_number" value="AccelStepper_74HC595" /> <input type="hidden" name="currency_code" value="USD" /> <input type="hidden" name="bn" value="PP-DonationsBF:btn_donateCC_LG.gif:NonHosted" /> <input type="image" alt="PayPal — The safer, easier way to pay online." name="submit" src="https://www.paypalobjects.com/en_AU/i/btn/btn_donateCC_LG.gif" /> <img alt="" src="https://www.paypalobjects.com/en_AU/i/scr/pixel.gif" width="1" height="1" border="0" /></form> \endhtmlonly
|
||||
///
|
||||
/// \par Trademarks
|
||||
///
|
||||
/// AccelStepper_74HC595 is a trademark of AirSpayce Pty Ltd. The AccelStepper_74HC595 mark was first used on April 26 2010 for
|
||||
/// international trade, and is used only in relation to motor control hardware and software.
|
||||
/// It is not to be confused with any other similar marks covering other goods and services.
|
||||
///
|
||||
/// \par Copyright
|
||||
///
|
||||
/// This software is Copyright (C) 2010-2018 Mike McCauley. Use is subject to license
|
||||
/// conditions. The main licensing options available are GPL V2 or Commercial:
|
||||
///
|
||||
/// \par Open Source Licensing GPL V2
|
||||
/// This is the appropriate option if you want to share the source code of your
|
||||
/// application with everyone you distribute it to, and you also want to give them
|
||||
/// the right to share who uses it. If you wish to use this software under Open
|
||||
/// Source Licensing, you must contribute all your source code to the open source
|
||||
/// community in accordance with the GPL Version 2 when your application is
|
||||
/// distributed. See https://www.gnu.org/licenses/gpl-2.0.html
|
||||
///
|
||||
/// \par Commercial Licensing
|
||||
/// This is the appropriate option if you are creating proprietary applications
|
||||
/// and you are not prepared to distribute and share the source code of your
|
||||
/// application. To purchase a commercial license, contact info@airspayce.com
|
||||
///
|
||||
/// \par Revision History
|
||||
/// \version 1.0 Initial release
|
||||
///
|
||||
/// \version 1.1 Added speed() function to get the current speed.
|
||||
/// \version 1.2 Added runSpeedToPosition() submitted by Gunnar Arndt.
|
||||
/// \version 1.3 Added support for stepper drivers (ie with Step and Direction inputs) with _pins == 1
|
||||
/// \version 1.4 Added functional contructor to support AFMotor, contributed by Limor, with example sketches.
|
||||
/// \version 1.5 Improvements contributed by Peter Mousley: Use of microsecond steps and other speed improvements
|
||||
/// to increase max stepping speed to about 4kHz. New option for user to set the min allowed pulse width.
|
||||
/// Added checks for already running at max speed and skip further calcs if so.
|
||||
/// \version 1.6 Fixed a problem with wrapping of microsecond stepping that could cause stepping to hang.
|
||||
/// Reported by Sandy Noble.
|
||||
/// Removed redundant _lastRunTime member.
|
||||
/// \version 1.7 Fixed a bug where setCurrentPosition() did not always work as expected.
|
||||
/// Reported by Peter Linhart.
|
||||
/// \version 1.8 Added support for 4 pin half-steppers, requested by Harvey Moon
|
||||
/// \version 1.9 setCurrentPosition() now also sets motor speed to 0.
|
||||
/// \version 1.10 Builds on Arduino 1.0
|
||||
/// \version 1.11 Improvments from Michael Ellison:
|
||||
/// Added optional enable line support for stepper drivers
|
||||
/// Added inversion for step/direction/enable lines for stepper drivers
|
||||
/// \version 1.12 Announce Google Group
|
||||
/// \version 1.13 Improvements to speed calculation. Cost of calculation is now less in the worst case,
|
||||
/// and more or less constant in all cases. This should result in slightly beter high speed performance, and
|
||||
/// reduce anomalous speed glitches when other steppers are accelerating.
|
||||
/// However, its hard to see how to replace the sqrt() required at the very first step from 0 speed.
|
||||
/// \version 1.14 Fixed a problem with compiling under arduino 0021 reported by EmbeddedMan
|
||||
/// \version 1.15 Fixed a problem with runSpeedToPosition which did not correctly handle
|
||||
/// running backwards to a smaller target position. Added examples
|
||||
/// \version 1.16 Fixed some cases in the code where abs() was used instead of fabs().
|
||||
/// \version 1.17 Added example ProportionalControl
|
||||
/// \version 1.18 Fixed a problem: If one calls the funcion runSpeed() when Speed is zero, it makes steps
|
||||
/// without counting. reported by Friedrich, Klappenbach.
|
||||
/// \version 1.19 Added MotorInterfaceType and symbolic names for the number of pins to use
|
||||
/// for the motor interface. Updated examples to suit.
|
||||
/// Replaced individual pin assignment variables _pin1, _pin2 etc with array _pin[4].
|
||||
/// _pins member changed to _interface.
|
||||
/// Added _pinInverted array to simplify pin inversion operations.
|
||||
/// Added new function setOutputPins() which sets the motor output pins.
|
||||
/// It can be overridden in order to provide, say, serial output instead of parallel output
|
||||
/// Some refactoring and code size reduction.
|
||||
/// \version 1.20 Improved documentation and examples to show need for correctly
|
||||
/// specifying AccelStepper_74HC595::FULL4WIRE and friends.
|
||||
/// \version 1.21 Fixed a problem where desiredSpeed could compute the wrong step acceleration
|
||||
/// when _speed was small but non-zero. Reported by Brian Schmalz.
|
||||
/// Precompute sqrt_twoa to improve performance and max possible stepping speed
|
||||
/// \version 1.22 Added Bounce.pde example
|
||||
/// Fixed a problem where calling moveTo(), setMaxSpeed(), setAcceleration() more
|
||||
/// frequently than the step time, even
|
||||
/// with the same values, would interfere with speed calcs. Now a new speed is computed
|
||||
/// only if there was a change in the set value. Reported by Brian Schmalz.
|
||||
/// \version 1.23 Rewrite of the speed algorithms in line with
|
||||
/// http://fab.cba.mit.edu/classes/MIT/961.09/projects/i0/Stepper_Motor_Speed_Profile.pdf
|
||||
/// Now expect smoother and more linear accelerations and decelerations. The desiredSpeed()
|
||||
/// function was removed.
|
||||
/// \version 1.24 Fixed a problem introduced in 1.23: with runToPosition, which did never returned
|
||||
/// \version 1.25 Now ignore attempts to set acceleration to 0.0
|
||||
/// \version 1.26 Fixed a problem where certina combinations of speed and accelration could cause
|
||||
/// oscillation about the target position.
|
||||
/// \version 1.27 Added stop() function to stop as fast as possible with current acceleration parameters.
|
||||
/// Also added new Quickstop example showing its use.
|
||||
/// \version 1.28 Fixed another problem where certain combinations of speed and acceleration could cause
|
||||
/// oscillation about the target position.
|
||||
/// Added support for 3 wire full and half steppers such as Hard Disk Drive spindle.
|
||||
/// Contributed by Yuri Ivatchkovitch.
|
||||
/// \version 1.29 Fixed a problem that could cause a DRIVER stepper to continually step
|
||||
/// with some sketches. Reported by Vadim.
|
||||
/// \version 1.30 Fixed a problem that could cause stepper to back up a few steps at the end of
|
||||
/// accelerated travel with certain speeds. Reported and patched by jolo.
|
||||
/// \version 1.31 Updated author and distribution location details to airspayce.com
|
||||
/// \version 1.32 Fixed a problem with enableOutputs() and setEnablePin on Arduino Due that
|
||||
/// prevented the enable pin changing stae correctly. Reported by Duane Bishop.
|
||||
/// \version 1.33 Fixed an error in example AFMotor_ConstantSpeed.pde did not setMaxSpeed();
|
||||
/// Fixed a problem that caused incorrect pin sequencing of FULL3WIRE and HALF3WIRE.
|
||||
/// Unfortunately this meant changing the signature for all step*() functions.
|
||||
/// Added example MotorShield, showing how to use AdaFruit Motor Shield to control
|
||||
/// a 3 phase motor such as a HDD spindle motor (and without using the AFMotor library.
|
||||
/// \version 1.34 Added setPinsInverted(bool pin1Invert, bool pin2Invert, bool pin3Invert, bool pin4Invert, bool enableInvert)
|
||||
/// to allow inversion of 2, 3 and 4 wire stepper pins. Requested by Oleg.
|
||||
/// \version 1.35 Removed default args from setPinsInverted(bool, bool, bool, bool, bool) to prevent ambiguity with
|
||||
/// setPinsInverted(bool, bool, bool). Reported by Mac Mac.
|
||||
/// \version 1.36 Changed enableOutputs() and disableOutputs() to be virtual so can be overridden.
|
||||
/// Added new optional argument 'enable' to constructor, which allows you toi disable the
|
||||
/// automatic enabling of outputs at construction time. Suggested by Guido.
|
||||
/// \version 1.37 Fixed a problem with step1 that could cause a rogue step in the
|
||||
/// wrong direction (or not,
|
||||
/// depending on the setup-time requirements of the connected hardware).
|
||||
/// Reported by Mark Tillotson.
|
||||
/// \version 1.38 run() function incorrectly always returned true. Updated function and doc so it returns true
|
||||
/// if the motor is still running to the target position.
|
||||
/// \version 1.39 Updated typos in keywords.txt, courtesey Jon Magill.
|
||||
/// \version 1.40 Updated documentation, including testing on Teensy 3.1
|
||||
/// \version 1.41 Fixed an error in the acceleration calculations, resulting in acceleration of haldf the intended value
|
||||
/// \version 1.42 Improved support for FULL3WIRE and HALF3WIRE output pins. These changes were in Yuri's original
|
||||
/// contribution but did not make it into production.<br>
|
||||
/// \version 1.43 Added DualMotorShield example. Shows how to use AccelStepper_74HC595 to control 2 x 2 phase steppers using the
|
||||
/// Itead Studio Arduino Dual Stepper Motor Driver Shield model IM120417015.<br>
|
||||
/// \version 1.44 examples/DualMotorShield/DualMotorShield.ino examples/DualMotorShield/DualMotorShield.pde
|
||||
/// was missing from the distribution.<br>
|
||||
/// \version 1.45 Fixed a problem where if setAcceleration was not called, there was no default
|
||||
/// acceleration. Reported by Michael Newman.<br>
|
||||
/// \version 1.45 Fixed inaccuracy in acceleration rate by using Equation 15, suggested by Sebastian Gracki.<br>
|
||||
/// Performance improvements in runSpeed suggested by Jaakko Fagerlund.<br>
|
||||
/// \version 1.46 Fixed error in documentation for runToPosition().
|
||||
/// Reinstated time calculations in runSpeed() since new version is reported
|
||||
/// not to work correctly under some circumstances. Reported by Oleg V Gavva.<br>
|
||||
/// \version 1.48 2015-08-25
|
||||
/// Added new class MultiStepper that can manage multiple AccelStepper_74HC595s,
|
||||
/// and cause them all to move
|
||||
/// to selected positions at such a (constant) speed that they all arrive at their
|
||||
/// target position at the same time. Suitable for X-Y flatbeds etc.<br>
|
||||
/// Added new method maxSpeed() to AccelStepper_74HC595 to return the currently configured maxSpeed.<br>
|
||||
/// \version 1.49 2016-01-02
|
||||
/// Testing with VID28 series instrument stepper motors and EasyDriver.
|
||||
/// OK, although with light pointers
|
||||
/// and slow speeds like 180 full steps per second the motor movement can be erratic,
|
||||
/// probably due to some mechanical resonance. Best to accelerate through this speed.<br>
|
||||
/// Added isRunning().<br>
|
||||
/// \version 1.50 2016-02-25
|
||||
/// AccelStepper_74HC595::disableOutputs now sets the enable pion to OUTPUT mode if the enable pin is defined.
|
||||
/// Patch from Piet De Jong.<br>
|
||||
/// Added notes about the fact that AFMotor_* examples do not work with Adafruit Motor Shield V2.<br>
|
||||
/// \version 1.51 2016-03-24
|
||||
/// Fixed a problem reported by gregor: when resetting the stepper motor position using setCurrentPosition() the
|
||||
/// stepper speed is reset by setting _stepInterval to 0, but _speed is not
|
||||
/// reset. this results in the stepper motor not starting again when calling
|
||||
/// setSpeed() with the same speed the stepper was set to before.
|
||||
/// \version 1.52 2016-08-09
|
||||
/// Added MultiStepper to keywords.txt.
|
||||
/// Improvements to efficiency of AccelStepper_74HC595::runSpeed() as suggested by David Grayson.
|
||||
/// Improvements to speed accuracy as suggested by David Grayson.
|
||||
/// \version 1.53 2016-08-14
|
||||
/// Backed out Improvements to speed accuracy from 1.52 as it did not work correctly.
|
||||
/// \version 1.54 2017-01-24
|
||||
/// Fixed some warnings about unused arguments.
|
||||
/// \version 1.55 2017-01-25
|
||||
/// Fixed another warning in MultiStepper.cpp
|
||||
/// \version 1.56 2017-02-03
|
||||
/// Fixed minor documentation error with DIRECTION_CCW and DIRECTION_CW. Reported by David Mutterer.
|
||||
/// Added link to Binpress commercial license purchasing.
|
||||
/// \version 1.57 2017-03-28
|
||||
/// _direction moved to protected at the request of Rudy Ercek.
|
||||
/// setMaxSpeed() and setAcceleration() now correct negative values to be positive.
|
||||
/// \version 1.58 2018-04-13
|
||||
/// Add initialisation for _enableInverted in constructor.
|
||||
/// \version 1.59 2018-08-28
|
||||
/// Update commercial licensing, remove binpress.
|
||||
///
|
||||
/// \author Mike McCauley (mikem@airspayce.com) DO NOT CONTACT THE AUTHOR DIRECTLY: USE THE LISTS
|
||||
// Copyright (C) 2009-2013 Mike McCauley
|
||||
// $Id: AccelStepper_74HC595.h,v 1.27 2016/08/14 10:26:54 mikem Exp mikem $
|
||||
|
||||
#ifndef AccelStepper_74HC595_h
|
||||
#define AccelStepper_74HC595_h
|
||||
#include "ShiftRegister74HC595.h"
|
||||
#include <stdlib.h>
|
||||
#if ARDUINO >= 100
|
||||
#include <Arduino.h>
|
||||
#else
|
||||
#include <WProgram.h>
|
||||
#include <wiring.h>
|
||||
#endif
|
||||
|
||||
// These defs cause trouble on some versions of Arduino
|
||||
#undef round
|
||||
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
/// \class AccelStepper_74HC595 AccelStepper_74HC595.h <AccelStepper_74HC595.h>
|
||||
/// \brief Support for stepper motors with acceleration etc.
|
||||
///
|
||||
/// This defines a single 2 or 4 pin stepper motor, or stepper moter with fdriver chip, with optional
|
||||
/// acceleration, deceleration, absolute positioning commands etc. Multiple
|
||||
/// simultaneous steppers are supported, all moving
|
||||
/// at different speeds and accelerations.
|
||||
///
|
||||
/// \par Operation
|
||||
/// This module operates by computing a step time in microseconds. The step
|
||||
/// time is recomputed after each step and after speed and acceleration
|
||||
/// parameters are changed by the caller. The time of each step is recorded in
|
||||
/// microseconds. The run() function steps the motor once if a new step is due.
|
||||
/// The run() function must be called frequently until the motor is in the
|
||||
/// desired position, after which time run() will do nothing.
|
||||
///
|
||||
/// \par Positioning
|
||||
/// Positions are specified by a signed long integer. At
|
||||
/// construction time, the current position of the motor is consider to be 0. Positive
|
||||
/// positions are clockwise from the initial position; negative positions are
|
||||
/// anticlockwise. The current position can be altered for instance after
|
||||
/// initialization positioning.
|
||||
///
|
||||
/// \par Caveats
|
||||
/// This is an open loop controller: If the motor stalls or is oversped,
|
||||
/// AccelStepper_74HC595 will not have a correct
|
||||
/// idea of where the motor really is (since there is no feedback of the motor's
|
||||
/// real position. We only know where we _think_ it is, relative to the
|
||||
/// initial starting point).
|
||||
///
|
||||
/// \par Performance
|
||||
/// The fastest motor speed that can be reliably supported is about 4000 steps per
|
||||
/// second at a clock frequency of 16 MHz on Arduino such as Uno etc.
|
||||
/// Faster processors can support faster stepping speeds.
|
||||
/// However, any speed less than that
|
||||
/// down to very slow speeds (much less than one per second) are also supported,
|
||||
/// provided the run() function is called frequently enough to step the motor
|
||||
/// whenever required for the speed set.
|
||||
/// Calling setAcceleration() is expensive,
|
||||
/// since it requires a square root to be calculated.
|
||||
///
|
||||
/// Gregor Christandl reports that with an Arduino Due and a simple test program,
|
||||
/// he measured 43163 steps per second using runSpeed(),
|
||||
/// and 16214 steps per second using run();
|
||||
class AccelStepper_74HC595
|
||||
{
|
||||
public:
|
||||
/// \brief Symbolic names for number of pins.
|
||||
/// Use this in the pins argument the AccelStepper_74HC595 constructor to
|
||||
/// provide a symbolic name for the number of pins
|
||||
/// to use.
|
||||
typedef enum
|
||||
{
|
||||
FUNCTION = 0, ///< Use the functional interface, implementing your own driver functions (internal use only)
|
||||
DRIVER = 1, ///< Stepper Driver, 2 driver pins required
|
||||
FULL2WIRE = 2, ///< 2 wire stepper, 2 motor pins required
|
||||
FULL3WIRE = 3, ///< 3 wire stepper, such as HDD spindle, 3 motor pins required
|
||||
FULL4WIRE = 4, ///< 4 wire full stepper, 4 motor pins required
|
||||
HALF3WIRE = 6, ///< 3 wire half stepper, such as HDD spindle, 3 motor pins required
|
||||
HALF4WIRE = 8 ///< 4 wire half stepper, 4 motor pins required
|
||||
} MotorInterfaceType;
|
||||
|
||||
/// Constructor. You can have multiple simultaneous steppers, all moving
|
||||
/// at different speeds and accelerations, provided you call their run()
|
||||
/// functions at frequent enough intervals. Current Position is set to 0, target
|
||||
/// position is set to 0. MaxSpeed and Acceleration default to 1.0.
|
||||
/// The motor pins will be initialised to OUTPUT mode during the
|
||||
/// constructor by a call to enableOutputs().
|
||||
/// \param[in] interface Number of pins to interface to. Integer values are
|
||||
/// supported, but it is preferred to use the \ref MotorInterfaceType symbolic names.
|
||||
/// AccelStepper_74HC595::DRIVER (1) means a stepper driver (with Step and Direction pins).
|
||||
/// If an enable line is also needed, call setEnablePin() after construction.
|
||||
/// You may also invert the pins using setPinsInverted().
|
||||
/// AccelStepper_74HC595::FULL2WIRE (2) means a 2 wire stepper (2 pins required).
|
||||
/// AccelStepper_74HC595::FULL3WIRE (3) means a 3 wire stepper, such as HDD spindle (3 pins required).
|
||||
/// AccelStepper_74HC595::FULL4WIRE (4) means a 4 wire stepper (4 pins required).
|
||||
/// AccelStepper_74HC595::HALF3WIRE (6) means a 3 wire half stepper, such as HDD spindle (3 pins required)
|
||||
/// AccelStepper_74HC595::HALF4WIRE (8) means a 4 wire half stepper (4 pins required)
|
||||
/// Defaults to AccelStepper_74HC595::FULL4WIRE (4) pins.
|
||||
/// \param[in] pin1 Arduino digital pin number for motor pin 1. Defaults
|
||||
/// to pin 2. For a AccelStepper_74HC595::DRIVER (interface==1),
|
||||
/// this is the Step input to the driver. Low to high transition means to step)
|
||||
/// \param[in] pin2 Arduino digital pin number for motor pin 2. Defaults
|
||||
/// to pin 3. For a AccelStepper_74HC595::DRIVER (interface==1),
|
||||
/// this is the Direction input the driver. High means forward.
|
||||
/// \param[in] pin3 Arduino digital pin number for motor pin 3. Defaults
|
||||
/// to pin 4.
|
||||
/// \param[in] pin4 Arduino digital pin number for motor pin 4. Defaults
|
||||
/// to pin 5.
|
||||
/// \param[in] enable If this is true (the default), enableOutputs() will be called to enable
|
||||
/// the output pins at construction time.
|
||||
AccelStepper_74HC595(ShiftRegister74HC595 *device, uint8_t interface = AccelStepper_74HC595::FULL4WIRE, uint8_t pin1 = 2, uint8_t pin2 = 3, uint8_t pin3 = 4, uint8_t pin4 = 5, bool enable = true);
|
||||
|
||||
/// Alternate Constructor which will call your own functions for forward and backward steps.
|
||||
/// You can have multiple simultaneous steppers, all moving
|
||||
/// at different speeds and accelerations, provided you call their run()
|
||||
/// functions at frequent enough intervals. Current Position is set to 0, target
|
||||
/// position is set to 0. MaxSpeed and Acceleration default to 1.0.
|
||||
/// Any motor initialization should happen before hand, no pins are used or initialized.
|
||||
/// \param[in] forward void-returning procedure that will make a forward step
|
||||
/// \param[in] backward void-returning procedure that will make a backward step
|
||||
//AccelStepper_74HC595(void (*forward)(), void (*backward)());
|
||||
|
||||
/// Set the target position. The run() function will try to move the motor (at most one step per call)
|
||||
/// from the current position to the target position set by the most
|
||||
/// recent call to this function. Caution: moveTo() also recalculates the speed for the next step.
|
||||
/// If you are trying to use constant speed movements, you should call setSpeed() after calling moveTo().
|
||||
/// \param[in] absolute The desired absolute position. Negative is
|
||||
/// anticlockwise from the 0 position.
|
||||
void moveTo(long absolute);
|
||||
|
||||
/// Set the target position relative to the current position
|
||||
/// \param[in] relative The desired position relative to the current position. Negative is
|
||||
/// anticlockwise from the current position.
|
||||
void move(long relative);
|
||||
|
||||
/// Poll the motor and step it if a step is due, implementing
|
||||
/// accelerations and decelerations to acheive the target position. You must call this as
|
||||
/// frequently as possible, but at least once per minimum step time interval,
|
||||
/// preferably in your main loop. Note that each call to run() will make at most one step, and then only when a step is due,
|
||||
/// based on the current speed and the time since the last step.
|
||||
/// \return true if the motor is still running to the target position.
|
||||
boolean run();
|
||||
|
||||
/// Poll the motor and step it if a step is due, implementing a constant
|
||||
/// speed as set by the most recent call to setSpeed(). You must call this as
|
||||
/// frequently as possible, but at least once per step interval,
|
||||
/// \return true if the motor was stepped.
|
||||
boolean runSpeed();
|
||||
|
||||
/// Sets the maximum permitted speed. The run() function will accelerate
|
||||
/// up to the speed set by this function.
|
||||
/// Caution: the maximum speed achievable depends on your processor and clock speed.
|
||||
/// The default maxSpeed is 1.0 steps per second.
|
||||
/// \param[in] speed The desired maximum speed in steps per second. Must
|
||||
/// be > 0. Caution: Speeds that exceed the maximum speed supported by the processor may
|
||||
/// Result in non-linear accelerations and decelerations.
|
||||
void setMaxSpeed(float speed);
|
||||
|
||||
/// returns the maximum speed configured for this stepper
|
||||
/// that was previously set by setMaxSpeed();
|
||||
/// \return The currently configured maximum speed
|
||||
float maxSpeed();
|
||||
|
||||
/// Sets the acceleration/deceleration rate.
|
||||
/// \param[in] acceleration The desired acceleration in steps per second
|
||||
/// per second. Must be > 0.0. This is an expensive call since it requires a square
|
||||
/// root to be calculated. Dont call more ofthen than needed
|
||||
void setAcceleration(float acceleration);
|
||||
|
||||
/// Sets the desired constant speed for use with runSpeed().
|
||||
/// \param[in] speed The desired constant speed in steps per
|
||||
/// second. Positive is clockwise. Speeds of more than 1000 steps per
|
||||
/// second are unreliable. Very slow speeds may be set (eg 0.00027777 for
|
||||
/// once per hour, approximately. Speed accuracy depends on the Arduino
|
||||
/// crystal. Jitter depends on how frequently you call the runSpeed() function.
|
||||
/// The speed will be limited by the current value of setMaxSpeed()
|
||||
void setSpeed(float speed);
|
||||
|
||||
/// The most recently set speed
|
||||
/// \return the most recent speed in steps per second
|
||||
float speed();
|
||||
|
||||
/// The distance from the current position to the target position.
|
||||
/// \return the distance from the current position to the target position
|
||||
/// in steps. Positive is clockwise from the current position.
|
||||
long distanceToGo();
|
||||
|
||||
/// The most recently set target position.
|
||||
/// \return the target position
|
||||
/// in steps. Positive is clockwise from the 0 position.
|
||||
long targetPosition();
|
||||
|
||||
/// The currently motor position.
|
||||
/// \return the current motor position
|
||||
/// in steps. Positive is clockwise from the 0 position.
|
||||
long currentPosition();
|
||||
|
||||
/// Resets the current position of the motor, so that wherever the motor
|
||||
/// happens to be right now is considered to be the new 0 position. Useful
|
||||
/// for setting a zero position on a stepper after an initial hardware
|
||||
/// positioning move.
|
||||
/// Has the side effect of setting the current motor speed to 0.
|
||||
/// \param[in] position The position in steps of wherever the motor
|
||||
/// happens to be right now.
|
||||
void setCurrentPosition(long position);
|
||||
|
||||
/// Moves the motor (with acceleration/deceleration)
|
||||
/// to the target position and blocks until it is at
|
||||
/// position. Dont use this in event loops, since it blocks.
|
||||
void runToPosition();
|
||||
|
||||
/// Runs at the currently selected speed until the target position is reached
|
||||
/// Does not implement accelerations.
|
||||
/// \return true if it stepped
|
||||
boolean runSpeedToPosition();
|
||||
|
||||
/// Moves the motor (with acceleration/deceleration)
|
||||
/// to the new target position and blocks until it is at
|
||||
/// position. Dont use this in event loops, since it blocks.
|
||||
/// \param[in] position The new target position.
|
||||
void runToNewPosition(long position);
|
||||
|
||||
/// Sets a new target position that causes the stepper
|
||||
/// to stop as quickly as possible, using the current speed and acceleration parameters.
|
||||
void stop();
|
||||
|
||||
/// Disable motor pin outputs by setting them all LOW
|
||||
/// Depending on the design of your electronics this may turn off
|
||||
/// the power to the motor coils, saving power.
|
||||
/// This is useful to support Arduino low power modes: disable the outputs
|
||||
/// during sleep and then reenable with enableOutputs() before stepping
|
||||
/// again.
|
||||
/// If the enable Pin is defined, sets it to OUTPUT mode and clears the pin to disabled.
|
||||
virtual void disableOutputs();
|
||||
|
||||
/// Enable motor pin outputs by setting the motor pins to OUTPUT
|
||||
/// mode. Called automatically by the constructor.
|
||||
/// If the enable Pin is defined, sets it to OUTPUT mode and sets the pin to enabled.
|
||||
virtual void enableOutputs();
|
||||
|
||||
/// Sets the minimum pulse width allowed by the stepper driver. The minimum practical pulse width is
|
||||
/// approximately 20 microseconds. Times less than 20 microseconds
|
||||
/// will usually result in 20 microseconds or so.
|
||||
/// \param[in] minWidth The minimum pulse width in microseconds.
|
||||
void setMinPulseWidth(unsigned int minWidth);
|
||||
|
||||
/// Sets the enable pin number for stepper drivers.
|
||||
/// 0xFF indicates unused (default).
|
||||
/// Otherwise, if a pin is set, the pin will be turned on when
|
||||
/// enableOutputs() is called and switched off when disableOutputs()
|
||||
/// is called.
|
||||
/// \param[in] enablePin Arduino digital pin number for motor enable
|
||||
/// \sa setPinsInverted
|
||||
void setEnablePin(uint8_t enablePin = 0xff);
|
||||
|
||||
/// Sets the inversion for stepper driver pins
|
||||
/// \param[in] directionInvert True for inverted direction pin, false for non-inverted
|
||||
/// \param[in] stepInvert True for inverted step pin, false for non-inverted
|
||||
/// \param[in] enableInvert True for inverted enable pin, false (default) for non-inverted
|
||||
void setPinsInverted(bool directionInvert = false, bool stepInvert = false, bool enableInvert = false);
|
||||
|
||||
/// Sets the inversion for 2, 3 and 4 wire stepper pins
|
||||
/// \param[in] pin1Invert True for inverted pin1, false for non-inverted
|
||||
/// \param[in] pin2Invert True for inverted pin2, false for non-inverted
|
||||
/// \param[in] pin3Invert True for inverted pin3, false for non-inverted
|
||||
/// \param[in] pin4Invert True for inverted pin4, false for non-inverted
|
||||
/// \param[in] enableInvert True for inverted enable pin, false (default) for non-inverted
|
||||
void setPinsInverted(bool pin1Invert, bool pin2Invert, bool pin3Invert, bool pin4Invert, bool enableInvert);
|
||||
|
||||
/// Checks to see if the motor is currently running to a target
|
||||
/// \return true if the speed is not zero or not at the target position
|
||||
bool isRunning();
|
||||
|
||||
protected:
|
||||
|
||||
/// \brief Direction indicator
|
||||
/// Symbolic names for the direction the motor is turning
|
||||
typedef enum
|
||||
{
|
||||
DIRECTION_CCW = 0, ///< Counter-Clockwise
|
||||
DIRECTION_CW = 1 ///< Clockwise
|
||||
} Direction;
|
||||
|
||||
/// Forces the library to compute a new instantaneous speed and set that as
|
||||
/// the current speed. It is called by
|
||||
/// the library:
|
||||
/// \li after each step
|
||||
/// \li after change to maxSpeed through setMaxSpeed()
|
||||
/// \li after change to acceleration through setAcceleration()
|
||||
/// \li after change to target position (relative or absolute) through
|
||||
/// move() or moveTo()
|
||||
void computeNewSpeed();
|
||||
|
||||
/// Low level function to set the motor output pins
|
||||
/// bit 0 of the mask corresponds to _pin[0]
|
||||
/// bit 1 of the mask corresponds to _pin[1]
|
||||
/// You can override this to impment, for example serial chip output insted of using the
|
||||
/// output pins directly
|
||||
virtual void setOutputPins(uint8_t mask);
|
||||
|
||||
/// Called to execute a step. Only called when a new step is
|
||||
/// required. Subclasses may override to implement new stepping
|
||||
/// interfaces. The default calls step1(), step2(), step4() or step8() depending on the
|
||||
/// number of pins defined for the stepper.
|
||||
/// \param[in] step The current step phase number (0 to 7)
|
||||
virtual void step(long step);
|
||||
|
||||
/// Called to execute a step using stepper functions (pins = 0) Only called when a new step is
|
||||
/// required. Calls _forward() or _backward() to perform the step
|
||||
/// \param[in] step The current step phase number (0 to 7)
|
||||
virtual void step0(long step);
|
||||
|
||||
/// Called to execute a step on a stepper driver (ie where pins == 1). Only called when a new step is
|
||||
/// required. Subclasses may override to implement new stepping
|
||||
/// interfaces. The default sets or clears the outputs of Step pin1 to step,
|
||||
/// and sets the output of _pin2 to the desired direction. The Step pin (_pin1) is pulsed for 1 microsecond
|
||||
/// which is the minimum STEP pulse width for the 3967 driver.
|
||||
/// \param[in] step The current step phase number (0 to 7)
|
||||
virtual void step1(long step);
|
||||
|
||||
/// Called to execute a step on a 2 pin motor. Only called when a new step is
|
||||
/// required. Subclasses may override to implement new stepping
|
||||
/// interfaces. The default sets or clears the outputs of pin1 and pin2
|
||||
/// \param[in] step The current step phase number (0 to 7)
|
||||
virtual void step2(long step);
|
||||
|
||||
/// Called to execute a step on a 3 pin motor, such as HDD spindle. Only called when a new step is
|
||||
/// required. Subclasses may override to implement new stepping
|
||||
/// interfaces. The default sets or clears the outputs of pin1, pin2,
|
||||
/// pin3
|
||||
/// \param[in] step The current step phase number (0 to 7)
|
||||
virtual void step3(long step);
|
||||
|
||||
/// Called to execute a step on a 4 pin motor. Only called when a new step is
|
||||
/// required. Subclasses may override to implement new stepping
|
||||
/// interfaces. The default sets or clears the outputs of pin1, pin2,
|
||||
/// pin3, pin4.
|
||||
/// \param[in] step The current step phase number (0 to 7)
|
||||
virtual void step4(long step);
|
||||
|
||||
/// Called to execute a step on a 3 pin motor, such as HDD spindle. Only called when a new step is
|
||||
/// required. Subclasses may override to implement new stepping
|
||||
/// interfaces. The default sets or clears the outputs of pin1, pin2,
|
||||
/// pin3
|
||||
/// \param[in] step The current step phase number (0 to 7)
|
||||
virtual void step6(long step);
|
||||
|
||||
/// Called to execute a step on a 4 pin half-steper motor. Only called when a new step is
|
||||
/// required. Subclasses may override to implement new stepping
|
||||
/// interfaces. The default sets or clears the outputs of pin1, pin2,
|
||||
/// pin3, pin4.
|
||||
/// \param[in] step The current step phase number (0 to 7)
|
||||
virtual void step8(long step);
|
||||
|
||||
/// Current direction motor is spinning in
|
||||
/// Protected because some peoples subclasses need it to be so
|
||||
boolean _direction; // 1 == CW
|
||||
|
||||
private:
|
||||
ShiftRegister74HC595 *_device;
|
||||
/// Number of pins on the stepper motor. Permits 2 or 4. 2 pins is a
|
||||
/// bipolar, and 4 pins is a unipolar.
|
||||
uint8_t _interface; // 0, 1, 2, 4, 8, See MotorInterfaceType
|
||||
|
||||
/// Arduino pin number assignments for the 2 or 4 pins required to interface to the
|
||||
/// stepper motor or driver
|
||||
uint8_t _pin[4];
|
||||
|
||||
/// Whether the _pins is inverted or not
|
||||
uint8_t _pinInverted[4];
|
||||
|
||||
/// The current absolution position in steps.
|
||||
long _currentPos; // Steps
|
||||
|
||||
/// The target position in steps. The AccelStepper_74HC595 library will move the
|
||||
/// motor from the _currentPos to the _targetPos, taking into account the
|
||||
/// max speed, acceleration and deceleration
|
||||
long _targetPos; // Steps
|
||||
|
||||
/// The current motos speed in steps per second
|
||||
/// Positive is clockwise
|
||||
float _speed; // Steps per second
|
||||
|
||||
/// The maximum permitted speed in steps per second. Must be > 0.
|
||||
float _maxSpeed;
|
||||
|
||||
/// The acceleration to use to accelerate or decelerate the motor in steps
|
||||
/// per second per second. Must be > 0
|
||||
float _acceleration;
|
||||
float _sqrt_twoa; // Precomputed sqrt(2*_acceleration)
|
||||
|
||||
/// The current interval between steps in microseconds.
|
||||
/// 0 means the motor is currently stopped with _speed == 0
|
||||
unsigned long _stepInterval;
|
||||
|
||||
/// The last step time in microseconds
|
||||
unsigned long _lastStepTime;
|
||||
|
||||
/// The minimum allowed pulse width in microseconds
|
||||
unsigned int _minPulseWidth;
|
||||
|
||||
/// Is the direction pin inverted?
|
||||
///bool _dirInverted; /// Moved to _pinInverted[1]
|
||||
|
||||
/// Is the step pin inverted?
|
||||
///bool _stepInverted; /// Moved to _pinInverted[0]
|
||||
|
||||
/// Is the enable pin inverted?
|
||||
bool _enableInverted;
|
||||
|
||||
/// Enable pin for stepper driver, or 0xFF if unused.
|
||||
uint8_t _enablePin;
|
||||
|
||||
/// The pointer to a forward-step procedure
|
||||
void (*_forward)();
|
||||
|
||||
/// The pointer to a backward-step procedure
|
||||
void (*_backward)();
|
||||
|
||||
/// The step counter for speed calculations
|
||||
long _n;
|
||||
|
||||
/// Initial step size in microseconds
|
||||
float _c0;
|
||||
|
||||
/// Last step size in microseconds
|
||||
float _cn;
|
||||
|
||||
/// Min step size in microseconds based on maxSpeed
|
||||
float _cmin; // at max speed
|
||||
|
||||
};
|
||||
|
||||
/// @example Random.pde
|
||||
/// Make a single stepper perform random changes in speed, position and acceleration
|
||||
|
||||
/// @example Overshoot.pde
|
||||
/// Check overshoot handling
|
||||
/// which sets a new target position and then waits until the stepper has
|
||||
/// achieved it. This is used for testing the handling of overshoots
|
||||
|
||||
/// @example MultipleSteppers.pde
|
||||
/// Shows how to multiple simultaneous steppers
|
||||
/// Runs one stepper forwards and backwards, accelerating and decelerating
|
||||
/// at the limits. Runs other steppers at the same time
|
||||
|
||||
/// @example ConstantSpeed.pde
|
||||
/// Shows how to run AccelStepper_74HC595 in the simplest,
|
||||
/// fixed speed mode with no accelerations
|
||||
|
||||
/// @example Blocking.pde
|
||||
/// Shows how to use the blocking call runToNewPosition
|
||||
/// Which sets a new target position and then waits until the stepper has
|
||||
/// achieved it.
|
||||
|
||||
/// @example AFMotor_MultiStepper.pde
|
||||
/// Control both Stepper motors at the same time with different speeds
|
||||
/// and accelerations.
|
||||
|
||||
/// @example AFMotor_ConstantSpeed.pde
|
||||
/// Shows how to run AccelStepper_74HC595 in the simplest,
|
||||
/// fixed speed mode with no accelerations
|
||||
|
||||
/// @example ProportionalControl.pde
|
||||
/// Make a single stepper follow the analog value read from a pot or whatever
|
||||
/// The stepper will move at a constant speed to each newly set posiiton,
|
||||
/// depending on the value of the pot.
|
||||
|
||||
/// @example Bounce.pde
|
||||
/// Make a single stepper bounce from one limit to another, observing
|
||||
/// accelrations at each end of travel
|
||||
|
||||
/// @example Quickstop.pde
|
||||
/// Check stop handling.
|
||||
/// Calls stop() while the stepper is travelling at full speed, causing
|
||||
/// the stepper to stop as quickly as possible, within the constraints of the
|
||||
/// current acceleration.
|
||||
|
||||
/// @example MotorShield.pde
|
||||
/// Shows how to use AccelStepper_74HC595 to control a 3-phase motor, such as a HDD spindle motor
|
||||
/// using the Adafruit Motor Shield http://www.ladyada.net/make/mshield/index.html.
|
||||
|
||||
/// @example DualMotorShield.pde
|
||||
/// Shows how to use AccelStepper_74HC595 to control 2 x 2 phase steppers using the
|
||||
/// Itead Studio Arduino Dual Stepper Motor Driver Shield
|
||||
/// model IM120417015
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,73 @@
|
||||
// MultiStepper_74HC595.cpp
|
||||
//
|
||||
// Copyright (C) 2015 Mike McCauley
|
||||
// $Id: MultiStepper_74HC595.cpp,v 1.2 2015/10/04 05:16:38 mikem Exp $
|
||||
|
||||
#include "MultiStepper_74HC595.h"
|
||||
#include "AccelStepper_74HC595.h"
|
||||
|
||||
MultiStepper_74HC595::MultiStepper_74HC595()
|
||||
: _num_steppers(0)
|
||||
{
|
||||
}
|
||||
|
||||
boolean MultiStepper_74HC595::addStepper(AccelStepper_74HC595& stepper)
|
||||
{
|
||||
if (_num_steppers >= MULTISTEPPER_MAX_STEPPERS)
|
||||
return false; // No room for more
|
||||
_steppers[_num_steppers++] = &stepper;
|
||||
return true;
|
||||
}
|
||||
|
||||
void MultiStepper_74HC595::moveTo(long absolute[])
|
||||
{
|
||||
// First find the stepper that will take the longest time to move
|
||||
float longestTime = 0.0;
|
||||
|
||||
uint8_t i;
|
||||
for (i = 0; i < _num_steppers; i++)
|
||||
{
|
||||
long thisDistance = absolute[i] - _steppers[i]->currentPosition();
|
||||
float thisTime = abs(thisDistance) / _steppers[i]->maxSpeed();
|
||||
|
||||
if (thisTime > longestTime)
|
||||
longestTime = thisTime;
|
||||
}
|
||||
|
||||
if (longestTime > 0.0)
|
||||
{
|
||||
// Now work out a new max speed for each stepper so they will all
|
||||
// arrived at the same time of longestTime
|
||||
for (i = 0; i < _num_steppers; i++)
|
||||
{
|
||||
long thisDistance = absolute[i] - _steppers[i]->currentPosition();
|
||||
float thisSpeed = thisDistance / longestTime;
|
||||
_steppers[i]->moveTo(absolute[i]); // New target position (resets speed)
|
||||
_steppers[i]->setSpeed(thisSpeed); // New speed
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Returns true if any motor is still running to the target position.
|
||||
boolean MultiStepper_74HC595::run()
|
||||
{
|
||||
uint8_t i;
|
||||
boolean ret = false;
|
||||
for (i = 0; i < _num_steppers; i++)
|
||||
{
|
||||
if ( _steppers[i]->distanceToGo() != 0)
|
||||
{
|
||||
_steppers[i]->runSpeed();
|
||||
ret = true;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Blocks until all steppers reach their target position and are stopped
|
||||
void MultiStepper_74HC595::runSpeedToPosition()
|
||||
{
|
||||
while (run())
|
||||
;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,78 @@
|
||||
// MultiStepper_74HC595.h
|
||||
|
||||
#ifndef MultiStepper_74HC595_h
|
||||
#define MultiStepper_74HC595_h
|
||||
|
||||
#include <stdlib.h>
|
||||
#if ARDUINO >= 100
|
||||
#include <Arduino.h>
|
||||
#else
|
||||
#include <WProgram.h>
|
||||
#include <wiring.h>
|
||||
#endif
|
||||
|
||||
#define MULTISTEPPER_MAX_STEPPERS 10
|
||||
|
||||
class AccelStepper_74HC595;
|
||||
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
/// \class MultiStepper_74HC595 MultiStepper_74HC595.h <MultiStepper_74HC595.h>
|
||||
/// \brief Operate multiple AccelStepper_74HC595s in a co-ordinated fashion
|
||||
///
|
||||
/// This class can manage multiple AccelStepper_74HC595s (up to MULTISTEPPER_MAX_STEPPERS = 10),
|
||||
/// and cause them all to move
|
||||
/// to selected positions at such a (constant) speed that they all arrive at their
|
||||
/// target position at the same time. This can be used to support devices with multiple steppers
|
||||
/// on say multiple axes to cause linear diagonal motion. Suitable for use with X-Y plotters, flatbeds,
|
||||
/// 3D printers etc
|
||||
/// to get linear straight line movement between arbitrary 2d (or 3d or ...) positions.
|
||||
///
|
||||
/// Caution: only constant speed stepper motion is supported: acceleration and deceleration is not supported
|
||||
/// All the steppers managed by MultiStepper_74HC595 will step at a constant speed to their
|
||||
/// target (albeit perhaps different speeds for each stepper).
|
||||
class MultiStepper_74HC595
|
||||
{
|
||||
public:
|
||||
/// Constructor
|
||||
MultiStepper_74HC595();
|
||||
|
||||
/// Add a stepper to the set of managed steppers
|
||||
/// There is an upper limit of MULTISTEPPER_MAX_STEPPERS = 10 to the number of steppers that can be managed
|
||||
/// \param[in] stepper Reference to a stepper to add to the managed list
|
||||
/// \return true if successful. false if the number of managed steppers would exceed MULTISTEPPER_MAX_STEPPERS
|
||||
boolean addStepper(AccelStepper_74HC595& stepper);
|
||||
|
||||
/// Set the target positions of all managed steppers
|
||||
/// according to a coordinate array.
|
||||
/// New speeds will be computed for each stepper so they will all arrive at their
|
||||
/// respective targets at very close to the same time.
|
||||
/// \param[in] absolute An array of desired absolute stepper positions. absolute[0] will be used to set
|
||||
/// the absolute position of the first stepper added by addStepper() etc. The array must be at least as long as
|
||||
/// the number of steppers that have been added by addStepper, else results are undefined.
|
||||
void moveTo(long absolute[]);
|
||||
|
||||
/// Calls runSpeed() on all the managed steppers
|
||||
/// that have not acheived their target position.
|
||||
/// \return true if any stepper is still in the process of running to its target position.
|
||||
boolean run();
|
||||
|
||||
/// Runs all managed steppers until they acheived their target position.
|
||||
/// Blocks until all that position is acheived. If you dont
|
||||
/// want blocking consider using run() instead.
|
||||
void runSpeedToPosition();
|
||||
|
||||
private:
|
||||
/// Array of pointers to the steppers we are controlling.
|
||||
/// Fills from 0 onwards
|
||||
AccelStepper_74HC595* _steppers[MULTISTEPPER_MAX_STEPPERS];
|
||||
|
||||
/// Number of steppers we are controlling and the number
|
||||
/// of steppers in _steppers[]
|
||||
uint8_t _num_steppers;
|
||||
};
|
||||
|
||||
/// @example MultiStepper_74HC595.pde
|
||||
/// Use MultiStepper_74HC595 class to manage multiple steppers and make them all move to
|
||||
/// the same position at the same time for linear 2d (or 3d) motion.
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,625 @@
|
||||
// AccelStepper_MCP23017.cpp
|
||||
//
|
||||
// Copyright (C) 2009-2013 Mike McCauley
|
||||
// $Id: AccelStepper_MCP23017.cpp,v 1.23 2016/08/09 00:39:10 mikem Exp $
|
||||
#include <Wire.h>
|
||||
#include "Adafruit_MCP23017.h"
|
||||
#include "AccelStepper_MCP23017.h"
|
||||
|
||||
#if 0
|
||||
// Some debugging assistance
|
||||
void dump(uint8_t* p, int l)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < l; i++)
|
||||
{
|
||||
Serial.print(p[i], HEX);
|
||||
Serial.print(" ");
|
||||
}
|
||||
Serial.println("");
|
||||
}
|
||||
#endif
|
||||
|
||||
void AccelStepper_MCP23017::moveTo(long absolute)
|
||||
{
|
||||
if (_targetPos != absolute)
|
||||
{
|
||||
_targetPos = absolute;
|
||||
computeNewSpeed();
|
||||
// compute new n?
|
||||
}
|
||||
}
|
||||
|
||||
void AccelStepper_MCP23017::move(long relative)
|
||||
{
|
||||
moveTo(_currentPos + relative);
|
||||
}
|
||||
|
||||
// Implements steps according to the current step interval
|
||||
// You must call this at least once per step
|
||||
// returns true if a step occurred
|
||||
boolean AccelStepper_MCP23017::runSpeed()
|
||||
{
|
||||
// Dont do anything unless we actually have a step interval
|
||||
if (!_stepInterval)
|
||||
return false;
|
||||
|
||||
unsigned long time = micros();
|
||||
if (time - _lastStepTime >= _stepInterval)
|
||||
{
|
||||
if (_direction == DIRECTION_CW)
|
||||
{
|
||||
// Clockwise
|
||||
_currentPos += 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Anticlockwise
|
||||
_currentPos -= 1;
|
||||
}
|
||||
step(_currentPos);
|
||||
|
||||
_lastStepTime = time; // Caution: does not account for costs in step()
|
||||
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
long AccelStepper_MCP23017::distanceToGo()
|
||||
{
|
||||
return _targetPos - _currentPos;
|
||||
}
|
||||
|
||||
long AccelStepper_MCP23017::targetPosition()
|
||||
{
|
||||
return _targetPos;
|
||||
}
|
||||
|
||||
long AccelStepper_MCP23017::currentPosition()
|
||||
{
|
||||
return _currentPos;
|
||||
}
|
||||
|
||||
// Useful during initialisations or after initial positioning
|
||||
// Sets speed to 0
|
||||
void AccelStepper_MCP23017::setCurrentPosition(long position)
|
||||
{
|
||||
_targetPos = _currentPos = position;
|
||||
_n = 0;
|
||||
_stepInterval = 0;
|
||||
_speed = 0.0;
|
||||
}
|
||||
|
||||
void AccelStepper_MCP23017::computeNewSpeed()
|
||||
{
|
||||
long distanceTo = distanceToGo(); // +ve is clockwise from curent location
|
||||
|
||||
long stepsToStop = (long)((_speed * _speed) / (2.0 * _acceleration)); // Equation 16
|
||||
|
||||
if (distanceTo == 0 && stepsToStop <= 1)
|
||||
{
|
||||
// We are at the target and its time to stop
|
||||
_stepInterval = 0;
|
||||
_speed = 0.0;
|
||||
_n = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
if (distanceTo > 0)
|
||||
{
|
||||
// We are anticlockwise from the target
|
||||
// Need to go clockwise from here, maybe decelerate now
|
||||
if (_n > 0)
|
||||
{
|
||||
// Currently accelerating, need to decel now? Or maybe going the wrong way?
|
||||
if ((stepsToStop >= distanceTo) || _direction == DIRECTION_CCW)
|
||||
_n = -stepsToStop; // Start deceleration
|
||||
}
|
||||
else if (_n < 0)
|
||||
{
|
||||
// Currently decelerating, need to accel again?
|
||||
if ((stepsToStop < distanceTo) && _direction == DIRECTION_CW)
|
||||
_n = -_n; // Start accceleration
|
||||
}
|
||||
}
|
||||
else if (distanceTo < 0)
|
||||
{
|
||||
// We are clockwise from the target
|
||||
// Need to go anticlockwise from here, maybe decelerate
|
||||
if (_n > 0)
|
||||
{
|
||||
// Currently accelerating, need to decel now? Or maybe going the wrong way?
|
||||
if ((stepsToStop >= -distanceTo) || _direction == DIRECTION_CW)
|
||||
_n = -stepsToStop; // Start deceleration
|
||||
}
|
||||
else if (_n < 0)
|
||||
{
|
||||
// Currently decelerating, need to accel again?
|
||||
if ((stepsToStop < -distanceTo) && _direction == DIRECTION_CCW)
|
||||
_n = -_n; // Start accceleration
|
||||
}
|
||||
}
|
||||
|
||||
// Need to accelerate or decelerate
|
||||
if (_n == 0)
|
||||
{
|
||||
// First step from stopped
|
||||
_cn = _c0;
|
||||
_direction = (distanceTo > 0) ? DIRECTION_CW : DIRECTION_CCW;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Subsequent step. Works for accel (n is +_ve) and decel (n is -ve).
|
||||
_cn = _cn - ((2.0 * _cn) / ((4.0 * _n) + 1)); // Equation 13
|
||||
_cn = max(_cn, _cmin);
|
||||
}
|
||||
_n++;
|
||||
_stepInterval = _cn;
|
||||
_speed = 1000000.0 / _cn;
|
||||
if (_direction == DIRECTION_CCW)
|
||||
_speed = -_speed;
|
||||
|
||||
#if 0
|
||||
Serial.println(_speed);
|
||||
Serial.println(_acceleration);
|
||||
Serial.println(_cn);
|
||||
Serial.println(_c0);
|
||||
Serial.println(_n);
|
||||
Serial.println(_stepInterval);
|
||||
Serial.println(distanceTo);
|
||||
Serial.println(stepsToStop);
|
||||
Serial.println("-----");
|
||||
#endif
|
||||
}
|
||||
|
||||
// Run the motor to implement speed and acceleration in order to proceed to the target position
|
||||
// You must call this at least once per step, preferably in your main loop
|
||||
// If the motor is in the desired position, the cost is very small
|
||||
// returns true if the motor is still running to the target position.
|
||||
boolean AccelStepper_MCP23017::run()
|
||||
{
|
||||
if (runSpeed())
|
||||
computeNewSpeed();
|
||||
return _speed != 0.0 || distanceToGo() != 0;
|
||||
}
|
||||
|
||||
AccelStepper_MCP23017::AccelStepper_MCP23017(Adafruit_MCP23017 *device, uint8_t interface, uint8_t pin1, uint8_t pin2, uint8_t pin3, uint8_t pin4, bool enable)
|
||||
{
|
||||
_device = device;
|
||||
//_device->begin(0x20);
|
||||
//_device->pinMode(pin1, OUTPUT);
|
||||
//_device->pinMode(pin2, OUTPUT);
|
||||
//_device->pinMode(pin3, OUTPUT);
|
||||
//_device->pinMode(pin4, OUTPUT);
|
||||
_interface = interface;
|
||||
_currentPos = 0;
|
||||
_targetPos = 0;
|
||||
_speed = 0.0;
|
||||
_maxSpeed = 1.0;
|
||||
_acceleration = 0.0;
|
||||
_sqrt_twoa = 1.0;
|
||||
_stepInterval = 0;
|
||||
_minPulseWidth = 1;
|
||||
_enablePin = 0xff;
|
||||
_lastStepTime = 0;
|
||||
_pin[0] = pin1;
|
||||
_pin[1] = pin2;
|
||||
_pin[2] = pin3;
|
||||
_pin[3] = pin4;
|
||||
_enableInverted = false;
|
||||
|
||||
// NEW
|
||||
_n = 0;
|
||||
_c0 = 0.0;
|
||||
_cn = 0.0;
|
||||
_cmin = 1.0;
|
||||
_direction = DIRECTION_CCW;
|
||||
|
||||
int i;
|
||||
for (i = 0; i < 4; i++)
|
||||
_pinInverted[i] = 0;
|
||||
if (enable)
|
||||
enableOutputs();
|
||||
// Some reasonable default
|
||||
setAcceleration(1);
|
||||
}
|
||||
|
||||
void AccelStepper_MCP23017::setMaxSpeed(float speed)
|
||||
{
|
||||
if (speed < 0.0)
|
||||
speed = -speed;
|
||||
if (_maxSpeed != speed)
|
||||
{
|
||||
_maxSpeed = speed;
|
||||
_cmin = 1000000.0 / speed;
|
||||
// Recompute _n from current speed and adjust speed if accelerating or cruising
|
||||
if (_n > 0)
|
||||
{
|
||||
_n = (long)((_speed * _speed) / (2.0 * _acceleration)); // Equation 16
|
||||
computeNewSpeed();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
float AccelStepper_MCP23017::maxSpeed()
|
||||
{
|
||||
return _maxSpeed;
|
||||
}
|
||||
|
||||
void AccelStepper_MCP23017::setAcceleration(float acceleration)
|
||||
{
|
||||
if (acceleration == 0.0)
|
||||
return;
|
||||
if (acceleration < 0.0)
|
||||
acceleration = -acceleration;
|
||||
if (_acceleration != acceleration)
|
||||
{
|
||||
// Recompute _n per Equation 17
|
||||
_n = _n * (_acceleration / acceleration);
|
||||
// New c0 per Equation 7, with correction per Equation 15
|
||||
_c0 = 0.676 * sqrt(2.0 / acceleration) * 1000000.0; // Equation 15
|
||||
_acceleration = acceleration;
|
||||
computeNewSpeed();
|
||||
}
|
||||
}
|
||||
|
||||
void AccelStepper_MCP23017::setSpeed(float speed)
|
||||
{
|
||||
if (speed == _speed)
|
||||
return;
|
||||
speed = constrain(speed, -_maxSpeed, _maxSpeed);
|
||||
if (speed == 0.0)
|
||||
_stepInterval = 0;
|
||||
else
|
||||
{
|
||||
_stepInterval = fabs(1000000.0 / speed);
|
||||
_direction = (speed > 0.0) ? DIRECTION_CW : DIRECTION_CCW;
|
||||
}
|
||||
_speed = speed;
|
||||
}
|
||||
|
||||
float AccelStepper_MCP23017::speed()
|
||||
{
|
||||
return _speed;
|
||||
}
|
||||
|
||||
// Subclasses can override
|
||||
void AccelStepper_MCP23017::step(long step)
|
||||
{
|
||||
switch (_interface)
|
||||
{
|
||||
case FUNCTION:
|
||||
step0(step);
|
||||
break;
|
||||
|
||||
case DRIVER:
|
||||
step1(step);
|
||||
break;
|
||||
|
||||
case FULL2WIRE:
|
||||
step2(step);
|
||||
break;
|
||||
|
||||
case FULL3WIRE:
|
||||
step3(step);
|
||||
break;
|
||||
|
||||
case FULL4WIRE:
|
||||
step4(step);
|
||||
break;
|
||||
|
||||
case HALF3WIRE:
|
||||
step6(step);
|
||||
break;
|
||||
|
||||
case HALF4WIRE:
|
||||
step8(step);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// You might want to override this to implement eg serial output
|
||||
// bit 0 of the mask corresponds to _pin[0]
|
||||
// bit 1 of the mask corresponds to _pin[1]
|
||||
// ....
|
||||
void AccelStepper_MCP23017::setOutputPins(uint8_t mask)
|
||||
{
|
||||
uint8_t numpins = 2;
|
||||
if (_interface == FULL4WIRE || _interface == HALF4WIRE)
|
||||
numpins = 4;
|
||||
else if (_interface == FULL3WIRE || _interface == HALF3WIRE)
|
||||
numpins = 3;
|
||||
uint8_t i;
|
||||
for (i = 0; i < numpins; i++)
|
||||
_device->digitalWrite(_pin[i], (mask & (1 << i)) ? (HIGH ^ _pinInverted[i]) : (LOW ^ _pinInverted[i]));
|
||||
}
|
||||
|
||||
// 0 pin step function (ie for functional usage)
|
||||
void AccelStepper_MCP23017::step0(long step)
|
||||
{
|
||||
(void)(step); // Unused
|
||||
if (_speed > 0)
|
||||
_forward();
|
||||
else
|
||||
_backward();
|
||||
}
|
||||
|
||||
// 1 pin step function (ie for stepper drivers)
|
||||
// This is passed the current step number (0 to 7)
|
||||
// Subclasses can override
|
||||
void AccelStepper_MCP23017::step1(long step)
|
||||
{
|
||||
(void)(step); // Unused
|
||||
|
||||
// _pin[0] is step, _pin[1] is direction
|
||||
setOutputPins(_direction ? 0b10 : 0b00); // Set direction first else get rogue pulses
|
||||
setOutputPins(_direction ? 0b11 : 0b01); // step HIGH
|
||||
// Caution 200ns setup time
|
||||
// Delay the minimum allowed pulse width
|
||||
delayMicroseconds(_minPulseWidth);
|
||||
setOutputPins(_direction ? 0b10 : 0b00); // step LOW
|
||||
}
|
||||
|
||||
|
||||
// 2 pin step function
|
||||
// This is passed the current step number (0 to 7)
|
||||
// Subclasses can override
|
||||
void AccelStepper_MCP23017::step2(long step)
|
||||
{
|
||||
switch (step & 0x3)
|
||||
{
|
||||
case 0: /* 01 */
|
||||
setOutputPins(0b10);
|
||||
break;
|
||||
|
||||
case 1: /* 11 */
|
||||
setOutputPins(0b11);
|
||||
break;
|
||||
|
||||
case 2: /* 10 */
|
||||
setOutputPins(0b01);
|
||||
break;
|
||||
|
||||
case 3: /* 00 */
|
||||
setOutputPins(0b00);
|
||||
break;
|
||||
}
|
||||
}
|
||||
// 3 pin step function
|
||||
// This is passed the current step number (0 to 7)
|
||||
// Subclasses can override
|
||||
void AccelStepper_MCP23017::step3(long step)
|
||||
{
|
||||
switch (step % 3)
|
||||
{
|
||||
case 0: // 100
|
||||
setOutputPins(0b100);
|
||||
break;
|
||||
|
||||
case 1: // 001
|
||||
setOutputPins(0b001);
|
||||
break;
|
||||
|
||||
case 2: //010
|
||||
setOutputPins(0b010);
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// 4 pin step function for half stepper
|
||||
// This is passed the current step number (0 to 7)
|
||||
// Subclasses can override
|
||||
void AccelStepper_MCP23017::step4(long step)
|
||||
{
|
||||
switch (step & 0x3)
|
||||
{
|
||||
case 0: // 1010
|
||||
setOutputPins(0b0101);
|
||||
break;
|
||||
|
||||
case 1: // 0110
|
||||
setOutputPins(0b0110);
|
||||
break;
|
||||
|
||||
case 2: //0101
|
||||
setOutputPins(0b1010);
|
||||
break;
|
||||
|
||||
case 3: //1001
|
||||
setOutputPins(0b1001);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// 3 pin half step function
|
||||
// This is passed the current step number (0 to 7)
|
||||
// Subclasses can override
|
||||
void AccelStepper_MCP23017::step6(long step)
|
||||
{
|
||||
switch (step % 6)
|
||||
{
|
||||
case 0: // 100
|
||||
setOutputPins(0b100);
|
||||
break;
|
||||
|
||||
case 1: // 101
|
||||
setOutputPins(0b101);
|
||||
break;
|
||||
|
||||
case 2: // 001
|
||||
setOutputPins(0b001);
|
||||
break;
|
||||
|
||||
case 3: // 011
|
||||
setOutputPins(0b011);
|
||||
break;
|
||||
|
||||
case 4: // 010
|
||||
setOutputPins(0b010);
|
||||
break;
|
||||
|
||||
case 5: // 011
|
||||
setOutputPins(0b110);
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// 4 pin half step function
|
||||
// This is passed the current step number (0 to 7)
|
||||
// Subclasses can override
|
||||
void AccelStepper_MCP23017::step8(long step)
|
||||
{
|
||||
switch (step & 0x7)
|
||||
{
|
||||
case 0: // 1000
|
||||
setOutputPins(0b0001);
|
||||
break;
|
||||
|
||||
case 1: // 1010
|
||||
setOutputPins(0b0101);
|
||||
break;
|
||||
|
||||
case 2: // 0010
|
||||
setOutputPins(0b0100);
|
||||
break;
|
||||
|
||||
case 3: // 0110
|
||||
setOutputPins(0b0110);
|
||||
break;
|
||||
|
||||
case 4: // 0100
|
||||
setOutputPins(0b0010);
|
||||
break;
|
||||
|
||||
case 5: //0101
|
||||
setOutputPins(0b1010);
|
||||
break;
|
||||
|
||||
case 6: // 0001
|
||||
setOutputPins(0b1000);
|
||||
break;
|
||||
|
||||
case 7: //1001
|
||||
setOutputPins(0b1001);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Prevents power consumption on the outputs
|
||||
void AccelStepper_MCP23017::disableOutputs()
|
||||
{
|
||||
if (! _interface) return;
|
||||
|
||||
setOutputPins(0); // Handles inversion automatically
|
||||
if (_enablePin != 0xff)
|
||||
{
|
||||
//_device->pinMode(_enablePin, OUTPUT);
|
||||
_device->digitalWrite(_enablePin, LOW ^ _enableInverted);
|
||||
}
|
||||
}
|
||||
|
||||
void AccelStepper_MCP23017::enableOutputs()
|
||||
{
|
||||
if (! _interface)
|
||||
return;
|
||||
|
||||
//_device->pinMode(_pin[0], OUTPUT);
|
||||
//_device->pinMode(_pin[1], OUTPUT);
|
||||
//if (_interface == FULL4WIRE || _interface == HALF4WIRE)
|
||||
//{
|
||||
// _device->pinMode(_pin[2], OUTPUT);
|
||||
// _device->pinMode(_pin[3], OUTPUT);
|
||||
//}
|
||||
//else if (_interface == FULL3WIRE || _interface == HALF3WIRE)
|
||||
//{
|
||||
// _device->pinMode(_pin[2], OUTPUT);
|
||||
//}
|
||||
|
||||
if (_enablePin != 0xff)
|
||||
{
|
||||
//_device->pinMode(_enablePin, OUTPUT);
|
||||
_device->digitalWrite(_enablePin, HIGH ^ _enableInverted);
|
||||
}
|
||||
}
|
||||
|
||||
void AccelStepper_MCP23017::setMinPulseWidth(unsigned int minWidth)
|
||||
{
|
||||
_minPulseWidth = minWidth;
|
||||
}
|
||||
|
||||
void AccelStepper_MCP23017::setEnablePin(uint8_t enablePin)
|
||||
{
|
||||
_enablePin = enablePin;
|
||||
|
||||
// This happens after construction, so init pin now.
|
||||
if (_enablePin != 0xff)
|
||||
{
|
||||
//_device->pinMode(_enablePin, OUTPUT);
|
||||
_device->digitalWrite(_enablePin, HIGH ^ _enableInverted);
|
||||
}
|
||||
}
|
||||
|
||||
void AccelStepper_MCP23017::setPinsInverted(bool directionInvert, bool stepInvert, bool enableInvert)
|
||||
{
|
||||
_pinInverted[0] = stepInvert;
|
||||
_pinInverted[1] = directionInvert;
|
||||
_enableInverted = enableInvert;
|
||||
}
|
||||
|
||||
void AccelStepper_MCP23017::setPinsInverted(bool pin1Invert, bool pin2Invert, bool pin3Invert, bool pin4Invert, bool enableInvert)
|
||||
{
|
||||
_pinInverted[0] = pin1Invert;
|
||||
_pinInverted[1] = pin2Invert;
|
||||
_pinInverted[2] = pin3Invert;
|
||||
_pinInverted[3] = pin4Invert;
|
||||
_enableInverted = enableInvert;
|
||||
}
|
||||
|
||||
// Blocks until the target position is reached and stopped
|
||||
void AccelStepper_MCP23017::runToPosition()
|
||||
{
|
||||
while (run())
|
||||
;
|
||||
}
|
||||
|
||||
boolean AccelStepper_MCP23017::runSpeedToPosition()
|
||||
{
|
||||
if (_targetPos == _currentPos)
|
||||
return false;
|
||||
if (_targetPos >_currentPos)
|
||||
_direction = DIRECTION_CW;
|
||||
else
|
||||
_direction = DIRECTION_CCW;
|
||||
return runSpeed();
|
||||
}
|
||||
|
||||
// Blocks until the new target position is reached
|
||||
void AccelStepper_MCP23017::runToNewPosition(long position)
|
||||
{
|
||||
moveTo(position);
|
||||
runToPosition();
|
||||
}
|
||||
|
||||
void AccelStepper_MCP23017::stop()
|
||||
{
|
||||
if (_speed != 0.0)
|
||||
{
|
||||
long stepsToStop = (long)((_speed * _speed) / (2.0 * _acceleration)) + 1; // Equation 16 (+integer rounding)
|
||||
if (_speed > 0)
|
||||
move(stepsToStop);
|
||||
else
|
||||
move(-stepsToStop);
|
||||
}
|
||||
}
|
||||
|
||||
bool AccelStepper_MCP23017::isRunning()
|
||||
{
|
||||
return !(_speed == 0.0 && _targetPos == _currentPos);
|
||||
}
|
||||
@@ -0,0 +1,735 @@
|
||||
// AccelStepper_MCP23017.h
|
||||
//
|
||||
/// \mainpage AccelStepper_MCP23017 library for Arduino
|
||||
///
|
||||
/// This is the Arduino AccelStepper_MCP23017 library.
|
||||
/// It provides an object-oriented interface for 2, 3 or 4 pin stepper motors and motor drivers.
|
||||
///
|
||||
/// The standard Arduino IDE includes the Stepper library
|
||||
/// (http://arduino.cc/en/Reference/Stepper) for stepper motors. It is
|
||||
/// perfectly adequate for simple, single motor applications.
|
||||
///
|
||||
/// AccelStepper_MCP23017 significantly improves on the standard Arduino Stepper library in several ways:
|
||||
/// \li Supports acceleration and deceleration
|
||||
/// \li Supports multiple simultaneous steppers, with independent concurrent stepping on each stepper
|
||||
/// \li API functions never delay() or block
|
||||
/// \li Supports 2, 3 and 4 wire steppers, plus 3 and 4 wire half steppers.
|
||||
/// \li Supports alternate stepping functions to enable support of AFMotor (https://github.com/adafruit/Adafruit-Motor-Shield-library)
|
||||
/// \li Supports stepper drivers such as the Sparkfun EasyDriver (based on 3967 driver chip)
|
||||
/// \li Very slow speeds are supported
|
||||
/// \li Extensive API
|
||||
/// \li Subclass support
|
||||
///
|
||||
/// The latest version of this documentation can be downloaded from
|
||||
/// http://www.airspayce.com/mikem/arduino/AccelStepper_MCP23017
|
||||
/// The version of the package that this documentation refers to can be downloaded
|
||||
/// from http://www.airspayce.com/mikem/arduino/AccelStepper_MCP23017/AccelStepper_MCP23017-1.59.zip
|
||||
///
|
||||
/// Example Arduino programs are included to show the main modes of use.
|
||||
///
|
||||
/// You can also find online help and discussion at http://groups.google.com/group/accelstepper
|
||||
/// Please use that group for all questions and discussions on this topic.
|
||||
/// Do not contact the author directly, unless it is to discuss commercial licensing.
|
||||
/// Before asking a question or reporting a bug, please read
|
||||
/// - http://en.wikipedia.org/wiki/Wikipedia:Reference_desk/How_to_ask_a_software_question
|
||||
/// - http://www.catb.org/esr/faqs/smart-questions.html
|
||||
/// - http://www.chiark.greenend.org.uk/~shgtatham/bugs.html
|
||||
///
|
||||
/// Tested on Arduino Diecimila and Mega with arduino-0018 & arduino-0021
|
||||
/// on OpenSuSE 11.1 and avr-libc-1.6.1-1.15,
|
||||
/// cross-avr-binutils-2.19-9.1, cross-avr-gcc-4.1.3_20080612-26.5.
|
||||
/// Tested on Teensy http://www.pjrc.com/teensy including Teensy 3.1 built using Arduino IDE 1.0.5 with
|
||||
/// teensyduino addon 1.18 and later.
|
||||
///
|
||||
/// \par Installation
|
||||
///
|
||||
/// Install in the usual way: unzip the distribution zip file to the libraries
|
||||
/// sub-folder of your sketchbook.
|
||||
///
|
||||
/// \par Theory
|
||||
///
|
||||
/// This code uses speed calculations as described in
|
||||
/// "Generate stepper-motor speed profiles in real time" by David Austin
|
||||
/// http://fab.cba.mit.edu/classes/MIT/961.09/projects/i0/Stepper_Motor_Speed_Profile.pdf or
|
||||
/// http://www.embedded.com/design/mcus-processors-and-socs/4006438/Generate-stepper-motor-speed-profiles-in-real-time or
|
||||
/// http://web.archive.org/web/20140705143928/http://fab.cba.mit.edu/classes/MIT/961.09/projects/i0/Stepper_Motor_Speed_Profile.pdf
|
||||
/// with the exception that AccelStepper_MCP23017 uses steps per second rather than radians per second
|
||||
/// (because we dont know the step angle of the motor)
|
||||
/// An initial step interval is calculated for the first step, based on the desired acceleration
|
||||
/// On subsequent steps, shorter step intervals are calculated based
|
||||
/// on the previous step until max speed is achieved.
|
||||
///
|
||||
/// \par Adafruit Motor Shield V2
|
||||
///
|
||||
/// The included examples AFMotor_* are for Adafruit Motor Shield V1 and do not work with Adafruit Motor Shield V2.
|
||||
/// See https://github.com/adafruit/Adafruit_Motor_Shield_V2_Library for examples that work with Adafruit Motor Shield V2.
|
||||
///
|
||||
/// \par Donations
|
||||
///
|
||||
/// This library is offered under a free GPL license for those who want to use it that way.
|
||||
/// We try hard to keep it up to date, fix bugs
|
||||
/// and to provide free support. If this library has helped you save time or money, please consider donating at
|
||||
/// http://www.airspayce.com or here:
|
||||
///
|
||||
/// \htmlonly <form action="https://www.paypal.com/cgi-bin/webscr" method="post"><input type="hidden" name="cmd" value="_donations" /> <input type="hidden" name="business" value="mikem@airspayce.com" /> <input type="hidden" name="lc" value="AU" /> <input type="hidden" name="item_name" value="Airspayce" /> <input type="hidden" name="item_number" value="AccelStepper_MCP23017" /> <input type="hidden" name="currency_code" value="USD" /> <input type="hidden" name="bn" value="PP-DonationsBF:btn_donateCC_LG.gif:NonHosted" /> <input type="image" alt="PayPal — The safer, easier way to pay online." name="submit" src="https://www.paypalobjects.com/en_AU/i/btn/btn_donateCC_LG.gif" /> <img alt="" src="https://www.paypalobjects.com/en_AU/i/scr/pixel.gif" width="1" height="1" border="0" /></form> \endhtmlonly
|
||||
///
|
||||
/// \par Trademarks
|
||||
///
|
||||
/// AccelStepper_MCP23017 is a trademark of AirSpayce Pty Ltd. The AccelStepper_MCP23017 mark was first used on April 26 2010 for
|
||||
/// international trade, and is used only in relation to motor control hardware and software.
|
||||
/// It is not to be confused with any other similar marks covering other goods and services.
|
||||
///
|
||||
/// \par Copyright
|
||||
///
|
||||
/// This software is Copyright (C) 2010-2018 Mike McCauley. Use is subject to license
|
||||
/// conditions. The main licensing options available are GPL V2 or Commercial:
|
||||
///
|
||||
/// \par Open Source Licensing GPL V2
|
||||
/// This is the appropriate option if you want to share the source code of your
|
||||
/// application with everyone you distribute it to, and you also want to give them
|
||||
/// the right to share who uses it. If you wish to use this software under Open
|
||||
/// Source Licensing, you must contribute all your source code to the open source
|
||||
/// community in accordance with the GPL Version 2 when your application is
|
||||
/// distributed. See https://www.gnu.org/licenses/gpl-2.0.html
|
||||
///
|
||||
/// \par Commercial Licensing
|
||||
/// This is the appropriate option if you are creating proprietary applications
|
||||
/// and you are not prepared to distribute and share the source code of your
|
||||
/// application. To purchase a commercial license, contact info@airspayce.com
|
||||
///
|
||||
/// \par Revision History
|
||||
/// \version 1.0 Initial release
|
||||
///
|
||||
/// \version 1.1 Added speed() function to get the current speed.
|
||||
/// \version 1.2 Added runSpeedToPosition() submitted by Gunnar Arndt.
|
||||
/// \version 1.3 Added support for stepper drivers (ie with Step and Direction inputs) with _pins == 1
|
||||
/// \version 1.4 Added functional contructor to support AFMotor, contributed by Limor, with example sketches.
|
||||
/// \version 1.5 Improvements contributed by Peter Mousley: Use of microsecond steps and other speed improvements
|
||||
/// to increase max stepping speed to about 4kHz. New option for user to set the min allowed pulse width.
|
||||
/// Added checks for already running at max speed and skip further calcs if so.
|
||||
/// \version 1.6 Fixed a problem with wrapping of microsecond stepping that could cause stepping to hang.
|
||||
/// Reported by Sandy Noble.
|
||||
/// Removed redundant _lastRunTime member.
|
||||
/// \version 1.7 Fixed a bug where setCurrentPosition() did not always work as expected.
|
||||
/// Reported by Peter Linhart.
|
||||
/// \version 1.8 Added support for 4 pin half-steppers, requested by Harvey Moon
|
||||
/// \version 1.9 setCurrentPosition() now also sets motor speed to 0.
|
||||
/// \version 1.10 Builds on Arduino 1.0
|
||||
/// \version 1.11 Improvments from Michael Ellison:
|
||||
/// Added optional enable line support for stepper drivers
|
||||
/// Added inversion for step/direction/enable lines for stepper drivers
|
||||
/// \version 1.12 Announce Google Group
|
||||
/// \version 1.13 Improvements to speed calculation. Cost of calculation is now less in the worst case,
|
||||
/// and more or less constant in all cases. This should result in slightly beter high speed performance, and
|
||||
/// reduce anomalous speed glitches when other steppers are accelerating.
|
||||
/// However, its hard to see how to replace the sqrt() required at the very first step from 0 speed.
|
||||
/// \version 1.14 Fixed a problem with compiling under arduino 0021 reported by EmbeddedMan
|
||||
/// \version 1.15 Fixed a problem with runSpeedToPosition which did not correctly handle
|
||||
/// running backwards to a smaller target position. Added examples
|
||||
/// \version 1.16 Fixed some cases in the code where abs() was used instead of fabs().
|
||||
/// \version 1.17 Added example ProportionalControl
|
||||
/// \version 1.18 Fixed a problem: If one calls the funcion runSpeed() when Speed is zero, it makes steps
|
||||
/// without counting. reported by Friedrich, Klappenbach.
|
||||
/// \version 1.19 Added MotorInterfaceType and symbolic names for the number of pins to use
|
||||
/// for the motor interface. Updated examples to suit.
|
||||
/// Replaced individual pin assignment variables _pin1, _pin2 etc with array _pin[4].
|
||||
/// _pins member changed to _interface.
|
||||
/// Added _pinInverted array to simplify pin inversion operations.
|
||||
/// Added new function setOutputPins() which sets the motor output pins.
|
||||
/// It can be overridden in order to provide, say, serial output instead of parallel output
|
||||
/// Some refactoring and code size reduction.
|
||||
/// \version 1.20 Improved documentation and examples to show need for correctly
|
||||
/// specifying AccelStepper_MCP23017::FULL4WIRE and friends.
|
||||
/// \version 1.21 Fixed a problem where desiredSpeed could compute the wrong step acceleration
|
||||
/// when _speed was small but non-zero. Reported by Brian Schmalz.
|
||||
/// Precompute sqrt_twoa to improve performance and max possible stepping speed
|
||||
/// \version 1.22 Added Bounce.pde example
|
||||
/// Fixed a problem where calling moveTo(), setMaxSpeed(), setAcceleration() more
|
||||
/// frequently than the step time, even
|
||||
/// with the same values, would interfere with speed calcs. Now a new speed is computed
|
||||
/// only if there was a change in the set value. Reported by Brian Schmalz.
|
||||
/// \version 1.23 Rewrite of the speed algorithms in line with
|
||||
/// http://fab.cba.mit.edu/classes/MIT/961.09/projects/i0/Stepper_Motor_Speed_Profile.pdf
|
||||
/// Now expect smoother and more linear accelerations and decelerations. The desiredSpeed()
|
||||
/// function was removed.
|
||||
/// \version 1.24 Fixed a problem introduced in 1.23: with runToPosition, which did never returned
|
||||
/// \version 1.25 Now ignore attempts to set acceleration to 0.0
|
||||
/// \version 1.26 Fixed a problem where certina combinations of speed and accelration could cause
|
||||
/// oscillation about the target position.
|
||||
/// \version 1.27 Added stop() function to stop as fast as possible with current acceleration parameters.
|
||||
/// Also added new Quickstop example showing its use.
|
||||
/// \version 1.28 Fixed another problem where certain combinations of speed and acceleration could cause
|
||||
/// oscillation about the target position.
|
||||
/// Added support for 3 wire full and half steppers such as Hard Disk Drive spindle.
|
||||
/// Contributed by Yuri Ivatchkovitch.
|
||||
/// \version 1.29 Fixed a problem that could cause a DRIVER stepper to continually step
|
||||
/// with some sketches. Reported by Vadim.
|
||||
/// \version 1.30 Fixed a problem that could cause stepper to back up a few steps at the end of
|
||||
/// accelerated travel with certain speeds. Reported and patched by jolo.
|
||||
/// \version 1.31 Updated author and distribution location details to airspayce.com
|
||||
/// \version 1.32 Fixed a problem with enableOutputs() and setEnablePin on Arduino Due that
|
||||
/// prevented the enable pin changing stae correctly. Reported by Duane Bishop.
|
||||
/// \version 1.33 Fixed an error in example AFMotor_ConstantSpeed.pde did not setMaxSpeed();
|
||||
/// Fixed a problem that caused incorrect pin sequencing of FULL3WIRE and HALF3WIRE.
|
||||
/// Unfortunately this meant changing the signature for all step*() functions.
|
||||
/// Added example MotorShield, showing how to use AdaFruit Motor Shield to control
|
||||
/// a 3 phase motor such as a HDD spindle motor (and without using the AFMotor library.
|
||||
/// \version 1.34 Added setPinsInverted(bool pin1Invert, bool pin2Invert, bool pin3Invert, bool pin4Invert, bool enableInvert)
|
||||
/// to allow inversion of 2, 3 and 4 wire stepper pins. Requested by Oleg.
|
||||
/// \version 1.35 Removed default args from setPinsInverted(bool, bool, bool, bool, bool) to prevent ambiguity with
|
||||
/// setPinsInverted(bool, bool, bool). Reported by Mac Mac.
|
||||
/// \version 1.36 Changed enableOutputs() and disableOutputs() to be virtual so can be overridden.
|
||||
/// Added new optional argument 'enable' to constructor, which allows you toi disable the
|
||||
/// automatic enabling of outputs at construction time. Suggested by Guido.
|
||||
/// \version 1.37 Fixed a problem with step1 that could cause a rogue step in the
|
||||
/// wrong direction (or not,
|
||||
/// depending on the setup-time requirements of the connected hardware).
|
||||
/// Reported by Mark Tillotson.
|
||||
/// \version 1.38 run() function incorrectly always returned true. Updated function and doc so it returns true
|
||||
/// if the motor is still running to the target position.
|
||||
/// \version 1.39 Updated typos in keywords.txt, courtesey Jon Magill.
|
||||
/// \version 1.40 Updated documentation, including testing on Teensy 3.1
|
||||
/// \version 1.41 Fixed an error in the acceleration calculations, resulting in acceleration of haldf the intended value
|
||||
/// \version 1.42 Improved support for FULL3WIRE and HALF3WIRE output pins. These changes were in Yuri's original
|
||||
/// contribution but did not make it into production.<br>
|
||||
/// \version 1.43 Added DualMotorShield example. Shows how to use AccelStepper_MCP23017 to control 2 x 2 phase steppers using the
|
||||
/// Itead Studio Arduino Dual Stepper Motor Driver Shield model IM120417015.<br>
|
||||
/// \version 1.44 examples/DualMotorShield/DualMotorShield.ino examples/DualMotorShield/DualMotorShield.pde
|
||||
/// was missing from the distribution.<br>
|
||||
/// \version 1.45 Fixed a problem where if setAcceleration was not called, there was no default
|
||||
/// acceleration. Reported by Michael Newman.<br>
|
||||
/// \version 1.45 Fixed inaccuracy in acceleration rate by using Equation 15, suggested by Sebastian Gracki.<br>
|
||||
/// Performance improvements in runSpeed suggested by Jaakko Fagerlund.<br>
|
||||
/// \version 1.46 Fixed error in documentation for runToPosition().
|
||||
/// Reinstated time calculations in runSpeed() since new version is reported
|
||||
/// not to work correctly under some circumstances. Reported by Oleg V Gavva.<br>
|
||||
/// \version 1.48 2015-08-25
|
||||
/// Added new class MultiStepper that can manage multiple AccelStepper_MCP23017s,
|
||||
/// and cause them all to move
|
||||
/// to selected positions at such a (constant) speed that they all arrive at their
|
||||
/// target position at the same time. Suitable for X-Y flatbeds etc.<br>
|
||||
/// Added new method maxSpeed() to AccelStepper_MCP23017 to return the currently configured maxSpeed.<br>
|
||||
/// \version 1.49 2016-01-02
|
||||
/// Testing with VID28 series instrument stepper motors and EasyDriver.
|
||||
/// OK, although with light pointers
|
||||
/// and slow speeds like 180 full steps per second the motor movement can be erratic,
|
||||
/// probably due to some mechanical resonance. Best to accelerate through this speed.<br>
|
||||
/// Added isRunning().<br>
|
||||
/// \version 1.50 2016-02-25
|
||||
/// AccelStepper_MCP23017::disableOutputs now sets the enable pion to OUTPUT mode if the enable pin is defined.
|
||||
/// Patch from Piet De Jong.<br>
|
||||
/// Added notes about the fact that AFMotor_* examples do not work with Adafruit Motor Shield V2.<br>
|
||||
/// \version 1.51 2016-03-24
|
||||
/// Fixed a problem reported by gregor: when resetting the stepper motor position using setCurrentPosition() the
|
||||
/// stepper speed is reset by setting _stepInterval to 0, but _speed is not
|
||||
/// reset. this results in the stepper motor not starting again when calling
|
||||
/// setSpeed() with the same speed the stepper was set to before.
|
||||
/// \version 1.52 2016-08-09
|
||||
/// Added MultiStepper to keywords.txt.
|
||||
/// Improvements to efficiency of AccelStepper_MCP23017::runSpeed() as suggested by David Grayson.
|
||||
/// Improvements to speed accuracy as suggested by David Grayson.
|
||||
/// \version 1.53 2016-08-14
|
||||
/// Backed out Improvements to speed accuracy from 1.52 as it did not work correctly.
|
||||
/// \version 1.54 2017-01-24
|
||||
/// Fixed some warnings about unused arguments.
|
||||
/// \version 1.55 2017-01-25
|
||||
/// Fixed another warning in MultiStepper.cpp
|
||||
/// \version 1.56 2017-02-03
|
||||
/// Fixed minor documentation error with DIRECTION_CCW and DIRECTION_CW. Reported by David Mutterer.
|
||||
/// Added link to Binpress commercial license purchasing.
|
||||
/// \version 1.57 2017-03-28
|
||||
/// _direction moved to protected at the request of Rudy Ercek.
|
||||
/// setMaxSpeed() and setAcceleration() now correct negative values to be positive.
|
||||
/// \version 1.58 2018-04-13
|
||||
/// Add initialisation for _enableInverted in constructor.
|
||||
/// \version 1.59 2018-08-28
|
||||
/// Update commercial licensing, remove binpress.
|
||||
///
|
||||
/// \author Mike McCauley (mikem@airspayce.com) DO NOT CONTACT THE AUTHOR DIRECTLY: USE THE LISTS
|
||||
// Copyright (C) 2009-2013 Mike McCauley
|
||||
// $Id: AccelStepper_MCP23017.h,v 1.27 2016/08/14 10:26:54 mikem Exp mikem $
|
||||
|
||||
#ifndef AccelStepper_MCP23017_h
|
||||
#define AccelStepper_MCP23017_h
|
||||
#include <Wire.h>
|
||||
#include "Adafruit_MCP23017.h"
|
||||
#include <stdlib.h>
|
||||
#if ARDUINO >= 100
|
||||
#include <Arduino.h>
|
||||
#else
|
||||
#include <WProgram.h>
|
||||
#include <wiring.h>
|
||||
#endif
|
||||
|
||||
// These defs cause trouble on some versions of Arduino
|
||||
#undef round
|
||||
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
/// \class AccelStepper_MCP23017 AccelStepper_MCP23017.h <AccelStepper_MCP23017.h>
|
||||
/// \brief Support for stepper motors with acceleration etc.
|
||||
///
|
||||
/// This defines a single 2 or 4 pin stepper motor, or stepper moter with fdriver chip, with optional
|
||||
/// acceleration, deceleration, absolute positioning commands etc. Multiple
|
||||
/// simultaneous steppers are supported, all moving
|
||||
/// at different speeds and accelerations.
|
||||
///
|
||||
/// \par Operation
|
||||
/// This module operates by computing a step time in microseconds. The step
|
||||
/// time is recomputed after each step and after speed and acceleration
|
||||
/// parameters are changed by the caller. The time of each step is recorded in
|
||||
/// microseconds. The run() function steps the motor once if a new step is due.
|
||||
/// The run() function must be called frequently until the motor is in the
|
||||
/// desired position, after which time run() will do nothing.
|
||||
///
|
||||
/// \par Positioning
|
||||
/// Positions are specified by a signed long integer. At
|
||||
/// construction time, the current position of the motor is consider to be 0. Positive
|
||||
/// positions are clockwise from the initial position; negative positions are
|
||||
/// anticlockwise. The current position can be altered for instance after
|
||||
/// initialization positioning.
|
||||
///
|
||||
/// \par Caveats
|
||||
/// This is an open loop controller: If the motor stalls or is oversped,
|
||||
/// AccelStepper_MCP23017 will not have a correct
|
||||
/// idea of where the motor really is (since there is no feedback of the motor's
|
||||
/// real position. We only know where we _think_ it is, relative to the
|
||||
/// initial starting point).
|
||||
///
|
||||
/// \par Performance
|
||||
/// The fastest motor speed that can be reliably supported is about 4000 steps per
|
||||
/// second at a clock frequency of 16 MHz on Arduino such as Uno etc.
|
||||
/// Faster processors can support faster stepping speeds.
|
||||
/// However, any speed less than that
|
||||
/// down to very slow speeds (much less than one per second) are also supported,
|
||||
/// provided the run() function is called frequently enough to step the motor
|
||||
/// whenever required for the speed set.
|
||||
/// Calling setAcceleration() is expensive,
|
||||
/// since it requires a square root to be calculated.
|
||||
///
|
||||
/// Gregor Christandl reports that with an Arduino Due and a simple test program,
|
||||
/// he measured 43163 steps per second using runSpeed(),
|
||||
/// and 16214 steps per second using run();
|
||||
class AccelStepper_MCP23017
|
||||
{
|
||||
public:
|
||||
/// \brief Symbolic names for number of pins.
|
||||
/// Use this in the pins argument the AccelStepper_MCP23017 constructor to
|
||||
/// provide a symbolic name for the number of pins
|
||||
/// to use.
|
||||
typedef enum
|
||||
{
|
||||
FUNCTION = 0, ///< Use the functional interface, implementing your own driver functions (internal use only)
|
||||
DRIVER = 1, ///< Stepper Driver, 2 driver pins required
|
||||
FULL2WIRE = 2, ///< 2 wire stepper, 2 motor pins required
|
||||
FULL3WIRE = 3, ///< 3 wire stepper, such as HDD spindle, 3 motor pins required
|
||||
FULL4WIRE = 4, ///< 4 wire full stepper, 4 motor pins required
|
||||
HALF3WIRE = 6, ///< 3 wire half stepper, such as HDD spindle, 3 motor pins required
|
||||
HALF4WIRE = 8 ///< 4 wire half stepper, 4 motor pins required
|
||||
} MotorInterfaceType;
|
||||
|
||||
/// Constructor. You can have multiple simultaneous steppers, all moving
|
||||
/// at different speeds and accelerations, provided you call their run()
|
||||
/// functions at frequent enough intervals. Current Position is set to 0, target
|
||||
/// position is set to 0. MaxSpeed and Acceleration default to 1.0.
|
||||
/// The motor pins will be initialised to OUTPUT mode during the
|
||||
/// constructor by a call to enableOutputs().
|
||||
/// \param[in] interface Number of pins to interface to. Integer values are
|
||||
/// supported, but it is preferred to use the \ref MotorInterfaceType symbolic names.
|
||||
/// AccelStepper_MCP23017::DRIVER (1) means a stepper driver (with Step and Direction pins).
|
||||
/// If an enable line is also needed, call setEnablePin() after construction.
|
||||
/// You may also invert the pins using setPinsInverted().
|
||||
/// AccelStepper_MCP23017::FULL2WIRE (2) means a 2 wire stepper (2 pins required).
|
||||
/// AccelStepper_MCP23017::FULL3WIRE (3) means a 3 wire stepper, such as HDD spindle (3 pins required).
|
||||
/// AccelStepper_MCP23017::FULL4WIRE (4) means a 4 wire stepper (4 pins required).
|
||||
/// AccelStepper_MCP23017::HALF3WIRE (6) means a 3 wire half stepper, such as HDD spindle (3 pins required)
|
||||
/// AccelStepper_MCP23017::HALF4WIRE (8) means a 4 wire half stepper (4 pins required)
|
||||
/// Defaults to AccelStepper_MCP23017::FULL4WIRE (4) pins.
|
||||
/// \param[in] pin1 Arduino digital pin number for motor pin 1. Defaults
|
||||
/// to pin 2. For a AccelStepper_MCP23017::DRIVER (interface==1),
|
||||
/// this is the Step input to the driver. Low to high transition means to step)
|
||||
/// \param[in] pin2 Arduino digital pin number for motor pin 2. Defaults
|
||||
/// to pin 3. For a AccelStepper_MCP23017::DRIVER (interface==1),
|
||||
/// this is the Direction input the driver. High means forward.
|
||||
/// \param[in] pin3 Arduino digital pin number for motor pin 3. Defaults
|
||||
/// to pin 4.
|
||||
/// \param[in] pin4 Arduino digital pin number for motor pin 4. Defaults
|
||||
/// to pin 5.
|
||||
/// \param[in] enable If this is true (the default), enableOutputs() will be called to enable
|
||||
/// the output pins at construction time.
|
||||
AccelStepper_MCP23017(Adafruit_MCP23017 *device, uint8_t interface = AccelStepper_MCP23017::FULL4WIRE, uint8_t pin1 = 2, uint8_t pin2 = 3, uint8_t pin3 = 4, uint8_t pin4 = 5, bool enable = true);
|
||||
|
||||
/// Alternate Constructor which will call your own functions for forward and backward steps.
|
||||
/// You can have multiple simultaneous steppers, all moving
|
||||
/// at different speeds and accelerations, provided you call their run()
|
||||
/// functions at frequent enough intervals. Current Position is set to 0, target
|
||||
/// position is set to 0. MaxSpeed and Acceleration default to 1.0.
|
||||
/// Any motor initialization should happen before hand, no pins are used or initialized.
|
||||
/// \param[in] forward void-returning procedure that will make a forward step
|
||||
/// \param[in] backward void-returning procedure that will make a backward step
|
||||
|
||||
/// Set the target position. The run() function will try to move the motor (at most one step per call)
|
||||
/// from the current position to the target position set by the most
|
||||
/// recent call to this function. Caution: moveTo() also recalculates the speed for the next step.
|
||||
/// If you are trying to use constant speed movements, you should call setSpeed() after calling moveTo().
|
||||
/// \param[in] absolute The desired absolute position. Negative is
|
||||
/// anticlockwise from the 0 position.
|
||||
void moveTo(long absolute);
|
||||
|
||||
/// Set the target position relative to the current position
|
||||
/// \param[in] relative The desired position relative to the current position. Negative is
|
||||
/// anticlockwise from the current position.
|
||||
void move(long relative);
|
||||
|
||||
/// Poll the motor and step it if a step is due, implementing
|
||||
/// accelerations and decelerations to acheive the target position. You must call this as
|
||||
/// frequently as possible, but at least once per minimum step time interval,
|
||||
/// preferably in your main loop. Note that each call to run() will make at most one step, and then only when a step is due,
|
||||
/// based on the current speed and the time since the last step.
|
||||
/// \return true if the motor is still running to the target position.
|
||||
boolean run();
|
||||
|
||||
/// Poll the motor and step it if a step is due, implementing a constant
|
||||
/// speed as set by the most recent call to setSpeed(). You must call this as
|
||||
/// frequently as possible, but at least once per step interval,
|
||||
/// \return true if the motor was stepped.
|
||||
boolean runSpeed();
|
||||
|
||||
/// Sets the maximum permitted speed. The run() function will accelerate
|
||||
/// up to the speed set by this function.
|
||||
/// Caution: the maximum speed achievable depends on your processor and clock speed.
|
||||
/// The default maxSpeed is 1.0 steps per second.
|
||||
/// \param[in] speed The desired maximum speed in steps per second. Must
|
||||
/// be > 0. Caution: Speeds that exceed the maximum speed supported by the processor may
|
||||
/// Result in non-linear accelerations and decelerations.
|
||||
void setMaxSpeed(float speed);
|
||||
|
||||
/// returns the maximum speed configured for this stepper
|
||||
/// that was previously set by setMaxSpeed();
|
||||
/// \return The currently configured maximum speed
|
||||
float maxSpeed();
|
||||
|
||||
/// Sets the acceleration/deceleration rate.
|
||||
/// \param[in] acceleration The desired acceleration in steps per second
|
||||
/// per second. Must be > 0.0. This is an expensive call since it requires a square
|
||||
/// root to be calculated. Dont call more ofthen than needed
|
||||
void setAcceleration(float acceleration);
|
||||
|
||||
/// Sets the desired constant speed for use with runSpeed().
|
||||
/// \param[in] speed The desired constant speed in steps per
|
||||
/// second. Positive is clockwise. Speeds of more than 1000 steps per
|
||||
/// second are unreliable. Very slow speeds may be set (eg 0.00027777 for
|
||||
/// once per hour, approximately. Speed accuracy depends on the Arduino
|
||||
/// crystal. Jitter depends on how frequently you call the runSpeed() function.
|
||||
/// The speed will be limited by the current value of setMaxSpeed()
|
||||
void setSpeed(float speed);
|
||||
|
||||
/// The most recently set speed
|
||||
/// \return the most recent speed in steps per second
|
||||
float speed();
|
||||
|
||||
/// The distance from the current position to the target position.
|
||||
/// \return the distance from the current position to the target position
|
||||
/// in steps. Positive is clockwise from the current position.
|
||||
long distanceToGo();
|
||||
|
||||
/// The most recently set target position.
|
||||
/// \return the target position
|
||||
/// in steps. Positive is clockwise from the 0 position.
|
||||
long targetPosition();
|
||||
|
||||
/// The currently motor position.
|
||||
/// \return the current motor position
|
||||
/// in steps. Positive is clockwise from the 0 position.
|
||||
long currentPosition();
|
||||
|
||||
/// Resets the current position of the motor, so that wherever the motor
|
||||
/// happens to be right now is considered to be the new 0 position. Useful
|
||||
/// for setting a zero position on a stepper after an initial hardware
|
||||
/// positioning move.
|
||||
/// Has the side effect of setting the current motor speed to 0.
|
||||
/// \param[in] position The position in steps of wherever the motor
|
||||
/// happens to be right now.
|
||||
void setCurrentPosition(long position);
|
||||
|
||||
/// Moves the motor (with acceleration/deceleration)
|
||||
/// to the target position and blocks until it is at
|
||||
/// position. Dont use this in event loops, since it blocks.
|
||||
void runToPosition();
|
||||
|
||||
/// Runs at the currently selected speed until the target position is reached
|
||||
/// Does not implement accelerations.
|
||||
/// \return true if it stepped
|
||||
boolean runSpeedToPosition();
|
||||
|
||||
/// Moves the motor (with acceleration/deceleration)
|
||||
/// to the new target position and blocks until it is at
|
||||
/// position. Dont use this in event loops, since it blocks.
|
||||
/// \param[in] position The new target position.
|
||||
void runToNewPosition(long position);
|
||||
|
||||
/// Sets a new target position that causes the stepper
|
||||
/// to stop as quickly as possible, using the current speed and acceleration parameters.
|
||||
void stop();
|
||||
|
||||
/// Disable motor pin outputs by setting them all LOW
|
||||
/// Depending on the design of your electronics this may turn off
|
||||
/// the power to the motor coils, saving power.
|
||||
/// This is useful to support Arduino low power modes: disable the outputs
|
||||
/// during sleep and then reenable with enableOutputs() before stepping
|
||||
/// again.
|
||||
/// If the enable Pin is defined, sets it to OUTPUT mode and clears the pin to disabled.
|
||||
virtual void disableOutputs();
|
||||
|
||||
/// Enable motor pin outputs by setting the motor pins to OUTPUT
|
||||
/// mode. Called automatically by the constructor.
|
||||
/// If the enable Pin is defined, sets it to OUTPUT mode and sets the pin to enabled.
|
||||
virtual void enableOutputs();
|
||||
|
||||
/// Sets the minimum pulse width allowed by the stepper driver. The minimum practical pulse width is
|
||||
/// approximately 20 microseconds. Times less than 20 microseconds
|
||||
/// will usually result in 20 microseconds or so.
|
||||
/// \param[in] minWidth The minimum pulse width in microseconds.
|
||||
void setMinPulseWidth(unsigned int minWidth);
|
||||
|
||||
/// Sets the enable pin number for stepper drivers.
|
||||
/// 0xFF indicates unused (default).
|
||||
/// Otherwise, if a pin is set, the pin will be turned on when
|
||||
/// enableOutputs() is called and switched off when disableOutputs()
|
||||
/// is called.
|
||||
/// \param[in] enablePin Arduino digital pin number for motor enable
|
||||
/// \sa setPinsInverted
|
||||
void setEnablePin(uint8_t enablePin = 0xff);
|
||||
|
||||
/// Sets the inversion for stepper driver pins
|
||||
/// \param[in] directionInvert True for inverted direction pin, false for non-inverted
|
||||
/// \param[in] stepInvert True for inverted step pin, false for non-inverted
|
||||
/// \param[in] enableInvert True for inverted enable pin, false (default) for non-inverted
|
||||
void setPinsInverted(bool directionInvert = false, bool stepInvert = false, bool enableInvert = false);
|
||||
|
||||
/// Sets the inversion for 2, 3 and 4 wire stepper pins
|
||||
/// \param[in] pin1Invert True for inverted pin1, false for non-inverted
|
||||
/// \param[in] pin2Invert True for inverted pin2, false for non-inverted
|
||||
/// \param[in] pin3Invert True for inverted pin3, false for non-inverted
|
||||
/// \param[in] pin4Invert True for inverted pin4, false for non-inverted
|
||||
/// \param[in] enableInvert True for inverted enable pin, false (default) for non-inverted
|
||||
void setPinsInverted(bool pin1Invert, bool pin2Invert, bool pin3Invert, bool pin4Invert, bool enableInvert);
|
||||
|
||||
/// Checks to see if the motor is currently running to a target
|
||||
/// \return true if the speed is not zero or not at the target position
|
||||
bool isRunning();
|
||||
|
||||
protected:
|
||||
|
||||
/// \brief Direction indicator
|
||||
/// Symbolic names for the direction the motor is turning
|
||||
typedef enum
|
||||
{
|
||||
DIRECTION_CCW = 0, ///< Counter-Clockwise
|
||||
DIRECTION_CW = 1 ///< Clockwise
|
||||
} Direction;
|
||||
|
||||
/// Forces the library to compute a new instantaneous speed and set that as
|
||||
/// the current speed. It is called by
|
||||
/// the library:
|
||||
/// \li after each step
|
||||
/// \li after change to maxSpeed through setMaxSpeed()
|
||||
/// \li after change to acceleration through setAcceleration()
|
||||
/// \li after change to target position (relative or absolute) through
|
||||
/// move() or moveTo()
|
||||
void computeNewSpeed();
|
||||
|
||||
/// Low level function to set the motor output pins
|
||||
/// bit 0 of the mask corresponds to _pin[0]
|
||||
/// bit 1 of the mask corresponds to _pin[1]
|
||||
/// You can override this to impment, for example serial chip output insted of using the
|
||||
/// output pins directly
|
||||
virtual void setOutputPins(uint8_t mask);
|
||||
|
||||
/// Called to execute a step. Only called when a new step is
|
||||
/// required. Subclasses may override to implement new stepping
|
||||
/// interfaces. The default calls step1(), step2(), step4() or step8() depending on the
|
||||
/// number of pins defined for the stepper.
|
||||
/// \param[in] step The current step phase number (0 to 7)
|
||||
virtual void step(long step);
|
||||
|
||||
/// Called to execute a step using stepper functions (pins = 0) Only called when a new step is
|
||||
/// required. Calls _forward() or _backward() to perform the step
|
||||
/// \param[in] step The current step phase number (0 to 7)
|
||||
virtual void step0(long step);
|
||||
|
||||
/// Called to execute a step on a stepper driver (ie where pins == 1). Only called when a new step is
|
||||
/// required. Subclasses may override to implement new stepping
|
||||
/// interfaces. The default sets or clears the outputs of Step pin1 to step,
|
||||
/// and sets the output of _pin2 to the desired direction. The Step pin (_pin1) is pulsed for 1 microsecond
|
||||
/// which is the minimum STEP pulse width for the 3967 driver.
|
||||
/// \param[in] step The current step phase number (0 to 7)
|
||||
virtual void step1(long step);
|
||||
|
||||
/// Called to execute a step on a 2 pin motor. Only called when a new step is
|
||||
/// required. Subclasses may override to implement new stepping
|
||||
/// interfaces. The default sets or clears the outputs of pin1 and pin2
|
||||
/// \param[in] step The current step phase number (0 to 7)
|
||||
virtual void step2(long step);
|
||||
|
||||
/// Called to execute a step on a 3 pin motor, such as HDD spindle. Only called when a new step is
|
||||
/// required. Subclasses may override to implement new stepping
|
||||
/// interfaces. The default sets or clears the outputs of pin1, pin2,
|
||||
/// pin3
|
||||
/// \param[in] step The current step phase number (0 to 7)
|
||||
virtual void step3(long step);
|
||||
|
||||
/// Called to execute a step on a 4 pin motor. Only called when a new step is
|
||||
/// required. Subclasses may override to implement new stepping
|
||||
/// interfaces. The default sets or clears the outputs of pin1, pin2,
|
||||
/// pin3, pin4.
|
||||
/// \param[in] step The current step phase number (0 to 7)
|
||||
virtual void step4(long step);
|
||||
|
||||
/// Called to execute a step on a 3 pin motor, such as HDD spindle. Only called when a new step is
|
||||
/// required. Subclasses may override to implement new stepping
|
||||
/// interfaces. The default sets or clears the outputs of pin1, pin2,
|
||||
/// pin3
|
||||
/// \param[in] step The current step phase number (0 to 7)
|
||||
virtual void step6(long step);
|
||||
|
||||
/// Called to execute a step on a 4 pin half-steper motor. Only called when a new step is
|
||||
/// required. Subclasses may override to implement new stepping
|
||||
/// interfaces. The default sets or clears the outputs of pin1, pin2,
|
||||
/// pin3, pin4.
|
||||
/// \param[in] step The current step phase number (0 to 7)
|
||||
virtual void step8(long step);
|
||||
|
||||
/// Current direction motor is spinning in
|
||||
/// Protected because some peoples subclasses need it to be so
|
||||
boolean _direction; // 1 == CW
|
||||
|
||||
private:
|
||||
Adafruit_MCP23017 *_device;
|
||||
/// Number of pins on the stepper motor. Permits 2 or 4. 2 pins is a
|
||||
/// bipolar, and 4 pins is a unipolar.
|
||||
uint8_t _interface; // 0, 1, 2, 4, 8, See MotorInterfaceType
|
||||
|
||||
/// Arduino pin number assignments for the 2 or 4 pins required to interface to the
|
||||
/// stepper motor or driver
|
||||
uint8_t _pin[4];
|
||||
|
||||
/// Whether the _pins is inverted or not
|
||||
uint8_t _pinInverted[4];
|
||||
|
||||
/// The current absolution position in steps.
|
||||
long _currentPos; // Steps
|
||||
|
||||
/// The target position in steps. The AccelStepper_MCP23017 library will move the
|
||||
/// motor from the _currentPos to the _targetPos, taking into account the
|
||||
/// max speed, acceleration and deceleration
|
||||
long _targetPos; // Steps
|
||||
|
||||
/// The current motos speed in steps per second
|
||||
/// Positive is clockwise
|
||||
float _speed; // Steps per second
|
||||
|
||||
/// The maximum permitted speed in steps per second. Must be > 0.
|
||||
float _maxSpeed;
|
||||
|
||||
/// The acceleration to use to accelerate or decelerate the motor in steps
|
||||
/// per second per second. Must be > 0
|
||||
float _acceleration;
|
||||
float _sqrt_twoa; // Precomputed sqrt(2*_acceleration)
|
||||
|
||||
/// The current interval between steps in microseconds.
|
||||
/// 0 means the motor is currently stopped with _speed == 0
|
||||
unsigned long _stepInterval;
|
||||
|
||||
/// The last step time in microseconds
|
||||
unsigned long _lastStepTime;
|
||||
|
||||
/// The minimum allowed pulse width in microseconds
|
||||
unsigned int _minPulseWidth;
|
||||
|
||||
/// Is the direction pin inverted?
|
||||
///bool _dirInverted; /// Moved to _pinInverted[1]
|
||||
|
||||
/// Is the step pin inverted?
|
||||
///bool _stepInverted; /// Moved to _pinInverted[0]
|
||||
|
||||
/// Is the enable pin inverted?
|
||||
bool _enableInverted;
|
||||
|
||||
/// Enable pin for stepper driver, or 0xFF if unused.
|
||||
uint8_t _enablePin;
|
||||
|
||||
/// The pointer to a forward-step procedure
|
||||
void (*_forward)();
|
||||
|
||||
/// The pointer to a backward-step procedure
|
||||
void (*_backward)();
|
||||
|
||||
/// The step counter for speed calculations
|
||||
long _n;
|
||||
|
||||
/// Initial step size in microseconds
|
||||
float _c0;
|
||||
|
||||
/// Last step size in microseconds
|
||||
float _cn;
|
||||
|
||||
/// Min step size in microseconds based on maxSpeed
|
||||
float _cmin; // at max speed
|
||||
|
||||
};
|
||||
|
||||
/// @example Random.pde
|
||||
/// Make a single stepper perform random changes in speed, position and acceleration
|
||||
|
||||
/// @example Overshoot.pde
|
||||
/// Check overshoot handling
|
||||
/// which sets a new target position and then waits until the stepper has
|
||||
/// achieved it. This is used for testing the handling of overshoots
|
||||
|
||||
/// @example MultipleSteppers.pde
|
||||
/// Shows how to multiple simultaneous steppers
|
||||
/// Runs one stepper forwards and backwards, accelerating and decelerating
|
||||
/// at the limits. Runs other steppers at the same time
|
||||
|
||||
/// @example ConstantSpeed.pde
|
||||
/// Shows how to run AccelStepper_MCP23017 in the simplest,
|
||||
/// fixed speed mode with no accelerations
|
||||
|
||||
/// @example Blocking.pde
|
||||
/// Shows how to use the blocking call runToNewPosition
|
||||
/// Which sets a new target position and then waits until the stepper has
|
||||
/// achieved it.
|
||||
|
||||
/// @example AFMotor_MultiStepper.pde
|
||||
/// Control both Stepper motors at the same time with different speeds
|
||||
/// and accelerations.
|
||||
|
||||
/// @example AFMotor_ConstantSpeed.pde
|
||||
/// Shows how to run AccelStepper_MCP23017 in the simplest,
|
||||
/// fixed speed mode with no accelerations
|
||||
|
||||
/// @example ProportionalControl.pde
|
||||
/// Make a single stepper follow the analog value read from a pot or whatever
|
||||
/// The stepper will move at a constant speed to each newly set posiiton,
|
||||
/// depending on the value of the pot.
|
||||
|
||||
/// @example Bounce.pde
|
||||
/// Make a single stepper bounce from one limit to another, observing
|
||||
/// accelrations at each end of travel
|
||||
|
||||
/// @example Quickstop.pde
|
||||
/// Check stop handling.
|
||||
/// Calls stop() while the stepper is travelling at full speed, causing
|
||||
/// the stepper to stop as quickly as possible, within the constraints of the
|
||||
/// current acceleration.
|
||||
|
||||
/// @example MotorShield.pde
|
||||
/// Shows how to use AccelStepper_MCP23017 to control a 3-phase motor, such as a HDD spindle motor
|
||||
/// using the Adafruit Motor Shield http://www.ladyada.net/make/mshield/index.html.
|
||||
|
||||
/// @example DualMotorShield.pde
|
||||
/// Shows how to use AccelStepper_MCP23017 to control 2 x 2 phase steppers using the
|
||||
/// Itead Studio Arduino Dual Stepper Motor Driver Shield
|
||||
/// model IM120417015
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,73 @@
|
||||
// MultiStepper_MCP23017.cpp
|
||||
//
|
||||
// Copyright (C) 2015 Mike McCauley
|
||||
// $Id: MultiStepper_MCP23017.cpp,v 1.2 2015/10/04 05:16:38 mikem Exp $
|
||||
|
||||
#include "MultiStepper_MCP23017.h"
|
||||
#include "AccelStepper_MCP23017.h"
|
||||
|
||||
MultiStepper_MCP23017::MultiStepper_MCP23017()
|
||||
: _num_steppers(0)
|
||||
{
|
||||
}
|
||||
|
||||
boolean MultiStepper_MCP23017::addStepper(AccelStepper_MCP23017& stepper)
|
||||
{
|
||||
if (_num_steppers >= MULTISTEPPER_MAX_STEPPERS)
|
||||
return false; // No room for more
|
||||
_steppers[_num_steppers++] = &stepper;
|
||||
return true;
|
||||
}
|
||||
|
||||
void MultiStepper_MCP23017::moveTo(long absolute[])
|
||||
{
|
||||
// First find the stepper that will take the longest time to move
|
||||
float longestTime = 0.0;
|
||||
|
||||
uint8_t i;
|
||||
for (i = 0; i < _num_steppers; i++)
|
||||
{
|
||||
long thisDistance = absolute[i] - _steppers[i]->currentPosition();
|
||||
float thisTime = abs(thisDistance) / _steppers[i]->maxSpeed();
|
||||
|
||||
if (thisTime > longestTime)
|
||||
longestTime = thisTime;
|
||||
}
|
||||
|
||||
if (longestTime > 0.0)
|
||||
{
|
||||
// Now work out a new max speed for each stepper so they will all
|
||||
// arrived at the same time of longestTime
|
||||
for (i = 0; i < _num_steppers; i++)
|
||||
{
|
||||
long thisDistance = absolute[i] - _steppers[i]->currentPosition();
|
||||
float thisSpeed = thisDistance / longestTime;
|
||||
_steppers[i]->moveTo(absolute[i]); // New target position (resets speed)
|
||||
_steppers[i]->setSpeed(thisSpeed); // New speed
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Returns true if any motor is still running to the target position.
|
||||
boolean MultiStepper_MCP23017::run()
|
||||
{
|
||||
uint8_t i;
|
||||
boolean ret = false;
|
||||
for (i = 0; i < _num_steppers; i++)
|
||||
{
|
||||
if ( _steppers[i]->distanceToGo() != 0)
|
||||
{
|
||||
_steppers[i]->runSpeed();
|
||||
ret = true;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Blocks until all steppers reach their target position and are stopped
|
||||
void MultiStepper_MCP23017::runSpeedToPosition()
|
||||
{
|
||||
while (run())
|
||||
;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,78 @@
|
||||
// MultiStepper_MCP23017.h
|
||||
|
||||
#ifndef MultiStepper_MCP23017_h
|
||||
#define MultiStepper_MCP23017_h
|
||||
|
||||
#include <stdlib.h>
|
||||
#if ARDUINO >= 100
|
||||
#include <Arduino.h>
|
||||
#else
|
||||
#include <WProgram.h>
|
||||
#include <wiring.h>
|
||||
#endif
|
||||
|
||||
#define MULTISTEPPER_MAX_STEPPERS 10
|
||||
|
||||
class AccelStepper_MCP23017;
|
||||
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
/// \class MultiStepper_MCP23017 MultiStepper_MCP23017.h <MultiStepper_MCP23017.h>
|
||||
/// \brief Operate multiple AccelStepper_MCP23017s in a co-ordinated fashion
|
||||
///
|
||||
/// This class can manage multiple AccelStepper_MCP23017s (up to MULTISTEPPER_MAX_STEPPERS = 10),
|
||||
/// and cause them all to move
|
||||
/// to selected positions at such a (constant) speed that they all arrive at their
|
||||
/// target position at the same time. This can be used to support devices with multiple steppers
|
||||
/// on say multiple axes to cause linear diagonal motion. Suitable for use with X-Y plotters, flatbeds,
|
||||
/// 3D printers etc
|
||||
/// to get linear straight line movement between arbitrary 2d (or 3d or ...) positions.
|
||||
///
|
||||
/// Caution: only constant speed stepper motion is supported: acceleration and deceleration is not supported
|
||||
/// All the steppers managed by MultiStepper_MCP23017 will step at a constant speed to their
|
||||
/// target (albeit perhaps different speeds for each stepper).
|
||||
class MultiStepper_MCP23017
|
||||
{
|
||||
public:
|
||||
/// Constructor
|
||||
MultiStepper_MCP23017();
|
||||
|
||||
/// Add a stepper to the set of managed steppers
|
||||
/// There is an upper limit of MULTISTEPPER_MAX_STEPPERS = 10 to the number of steppers that can be managed
|
||||
/// \param[in] stepper Reference to a stepper to add to the managed list
|
||||
/// \return true if successful. false if the number of managed steppers would exceed MULTISTEPPER_MAX_STEPPERS
|
||||
boolean addStepper(AccelStepper_MCP23017& stepper);
|
||||
|
||||
/// Set the target positions of all managed steppers
|
||||
/// according to a coordinate array.
|
||||
/// New speeds will be computed for each stepper so they will all arrive at their
|
||||
/// respective targets at very close to the same time.
|
||||
/// \param[in] absolute An array of desired absolute stepper positions. absolute[0] will be used to set
|
||||
/// the absolute position of the first stepper added by addStepper() etc. The array must be at least as long as
|
||||
/// the number of steppers that have been added by addStepper, else results are undefined.
|
||||
void moveTo(long absolute[]);
|
||||
|
||||
/// Calls runSpeed() on all the managed steppers
|
||||
/// that have not acheived their target position.
|
||||
/// \return true if any stepper is still in the process of running to its target position.
|
||||
boolean run();
|
||||
|
||||
/// Runs all managed steppers until they acheived their target position.
|
||||
/// Blocks until all that position is acheived. If you dont
|
||||
/// want blocking consider using run() instead.
|
||||
void runSpeedToPosition();
|
||||
|
||||
private:
|
||||
/// Array of pointers to the steppers we are controlling.
|
||||
/// Fills from 0 onwards
|
||||
AccelStepper_MCP23017* _steppers[MULTISTEPPER_MAX_STEPPERS];
|
||||
|
||||
/// Number of steppers we are controlling and the number
|
||||
/// of steppers in _steppers[]
|
||||
uint8_t _num_steppers;
|
||||
};
|
||||
|
||||
/// @example MultiStepper_MCP23017.pde
|
||||
/// Use MultiStepper_MCP23017 class to manage multiple steppers and make them all move to
|
||||
/// the same position at the same time for linear 2d (or 3d) motion.
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,625 @@
|
||||
// AccelStepper_MCP23017_Soft.cpp
|
||||
//
|
||||
// Copyright (C) 2009-2013 Mike McCauley
|
||||
// $Id: AccelStepper_MCP23017_Soft.cpp,v 1.23 2016/08/09 00:39:10 mikem Exp $
|
||||
#include <SoftwareWire.h>
|
||||
#include "Adafruit_MCP23017_Soft.h"
|
||||
#include "AccelStepper_MCP23017_Soft.h"
|
||||
|
||||
#if 0
|
||||
// Some debugging assistance
|
||||
void dump(uint8_t* p, int l)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < l; i++)
|
||||
{
|
||||
Serial.print(p[i], HEX);
|
||||
Serial.print(" ");
|
||||
}
|
||||
Serial.println("");
|
||||
}
|
||||
#endif
|
||||
|
||||
void AccelStepper_MCP23017_Soft::moveTo(long absolute)
|
||||
{
|
||||
if (_targetPos != absolute)
|
||||
{
|
||||
_targetPos = absolute;
|
||||
computeNewSpeed();
|
||||
// compute new n?
|
||||
}
|
||||
}
|
||||
|
||||
void AccelStepper_MCP23017_Soft::move(long relative)
|
||||
{
|
||||
moveTo(_currentPos + relative);
|
||||
}
|
||||
|
||||
// Implements steps according to the current step interval
|
||||
// You must call this at least once per step
|
||||
// returns true if a step occurred
|
||||
boolean AccelStepper_MCP23017_Soft::runSpeed()
|
||||
{
|
||||
// Dont do anything unless we actually have a step interval
|
||||
if (!_stepInterval)
|
||||
return false;
|
||||
|
||||
unsigned long time = micros();
|
||||
if (time - _lastStepTime >= _stepInterval)
|
||||
{
|
||||
if (_direction == DIRECTION_CW)
|
||||
{
|
||||
// Clockwise
|
||||
_currentPos += 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Anticlockwise
|
||||
_currentPos -= 1;
|
||||
}
|
||||
step(_currentPos);
|
||||
|
||||
_lastStepTime = time; // Caution: does not account for costs in step()
|
||||
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
long AccelStepper_MCP23017_Soft::distanceToGo()
|
||||
{
|
||||
return _targetPos - _currentPos;
|
||||
}
|
||||
|
||||
long AccelStepper_MCP23017_Soft::targetPosition()
|
||||
{
|
||||
return _targetPos;
|
||||
}
|
||||
|
||||
long AccelStepper_MCP23017_Soft::currentPosition()
|
||||
{
|
||||
return _currentPos;
|
||||
}
|
||||
|
||||
// Useful during initialisations or after initial positioning
|
||||
// Sets speed to 0
|
||||
void AccelStepper_MCP23017_Soft::setCurrentPosition(long position)
|
||||
{
|
||||
_targetPos = _currentPos = position;
|
||||
_n = 0;
|
||||
_stepInterval = 0;
|
||||
_speed = 0.0;
|
||||
}
|
||||
|
||||
void AccelStepper_MCP23017_Soft::computeNewSpeed()
|
||||
{
|
||||
long distanceTo = distanceToGo(); // +ve is clockwise from curent location
|
||||
|
||||
long stepsToStop = (long)((_speed * _speed) / (2.0 * _acceleration)); // Equation 16
|
||||
|
||||
if (distanceTo == 0 && stepsToStop <= 1)
|
||||
{
|
||||
// We are at the target and its time to stop
|
||||
_stepInterval = 0;
|
||||
_speed = 0.0;
|
||||
_n = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
if (distanceTo > 0)
|
||||
{
|
||||
// We are anticlockwise from the target
|
||||
// Need to go clockwise from here, maybe decelerate now
|
||||
if (_n > 0)
|
||||
{
|
||||
// Currently accelerating, need to decel now? Or maybe going the wrong way?
|
||||
if ((stepsToStop >= distanceTo) || _direction == DIRECTION_CCW)
|
||||
_n = -stepsToStop; // Start deceleration
|
||||
}
|
||||
else if (_n < 0)
|
||||
{
|
||||
// Currently decelerating, need to accel again?
|
||||
if ((stepsToStop < distanceTo) && _direction == DIRECTION_CW)
|
||||
_n = -_n; // Start accceleration
|
||||
}
|
||||
}
|
||||
else if (distanceTo < 0)
|
||||
{
|
||||
// We are clockwise from the target
|
||||
// Need to go anticlockwise from here, maybe decelerate
|
||||
if (_n > 0)
|
||||
{
|
||||
// Currently accelerating, need to decel now? Or maybe going the wrong way?
|
||||
if ((stepsToStop >= -distanceTo) || _direction == DIRECTION_CW)
|
||||
_n = -stepsToStop; // Start deceleration
|
||||
}
|
||||
else if (_n < 0)
|
||||
{
|
||||
// Currently decelerating, need to accel again?
|
||||
if ((stepsToStop < -distanceTo) && _direction == DIRECTION_CCW)
|
||||
_n = -_n; // Start accceleration
|
||||
}
|
||||
}
|
||||
|
||||
// Need to accelerate or decelerate
|
||||
if (_n == 0)
|
||||
{
|
||||
// First step from stopped
|
||||
_cn = _c0;
|
||||
_direction = (distanceTo > 0) ? DIRECTION_CW : DIRECTION_CCW;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Subsequent step. Works for accel (n is +_ve) and decel (n is -ve).
|
||||
_cn = _cn - ((2.0 * _cn) / ((4.0 * _n) + 1)); // Equation 13
|
||||
_cn = max(_cn, _cmin);
|
||||
}
|
||||
_n++;
|
||||
_stepInterval = _cn;
|
||||
_speed = 1000000.0 / _cn;
|
||||
if (_direction == DIRECTION_CCW)
|
||||
_speed = -_speed;
|
||||
|
||||
#if 0
|
||||
Serial.println(_speed);
|
||||
Serial.println(_acceleration);
|
||||
Serial.println(_cn);
|
||||
Serial.println(_c0);
|
||||
Serial.println(_n);
|
||||
Serial.println(_stepInterval);
|
||||
Serial.println(distanceTo);
|
||||
Serial.println(stepsToStop);
|
||||
Serial.println("-----");
|
||||
#endif
|
||||
}
|
||||
|
||||
// Run the motor to implement speed and acceleration in order to proceed to the target position
|
||||
// You must call this at least once per step, preferably in your main loop
|
||||
// If the motor is in the desired position, the cost is very small
|
||||
// returns true if the motor is still running to the target position.
|
||||
boolean AccelStepper_MCP23017_Soft::run()
|
||||
{
|
||||
if (runSpeed())
|
||||
computeNewSpeed();
|
||||
return _speed != 0.0 || distanceToGo() != 0;
|
||||
}
|
||||
|
||||
AccelStepper_MCP23017_Soft::AccelStepper_MCP23017_Soft(Adafruit_MCP23017_Soft *device, uint8_t interface, uint8_t pin1, uint8_t pin2, uint8_t pin3, uint8_t pin4, bool enable)
|
||||
{
|
||||
_device = device;
|
||||
//_device->begin(0x20);
|
||||
//_device->pinMode(pin1, OUTPUT);
|
||||
//_device->pinMode(pin2, OUTPUT);
|
||||
//_device->pinMode(pin3, OUTPUT);
|
||||
//_device->pinMode(pin4, OUTPUT);
|
||||
_interface = interface;
|
||||
_currentPos = 0;
|
||||
_targetPos = 0;
|
||||
_speed = 0.0;
|
||||
_maxSpeed = 1.0;
|
||||
_acceleration = 0.0;
|
||||
_sqrt_twoa = 1.0;
|
||||
_stepInterval = 0;
|
||||
_minPulseWidth = 1;
|
||||
_enablePin = 0xff;
|
||||
_lastStepTime = 0;
|
||||
_pin[0] = pin1;
|
||||
_pin[1] = pin2;
|
||||
_pin[2] = pin3;
|
||||
_pin[3] = pin4;
|
||||
_enableInverted = false;
|
||||
|
||||
// NEW
|
||||
_n = 0;
|
||||
_c0 = 0.0;
|
||||
_cn = 0.0;
|
||||
_cmin = 1.0;
|
||||
_direction = DIRECTION_CCW;
|
||||
|
||||
int i;
|
||||
for (i = 0; i < 4; i++)
|
||||
_pinInverted[i] = 0;
|
||||
if (enable)
|
||||
enableOutputs();
|
||||
// Some reasonable default
|
||||
setAcceleration(1);
|
||||
}
|
||||
|
||||
void AccelStepper_MCP23017_Soft::setMaxSpeed(float speed)
|
||||
{
|
||||
if (speed < 0.0)
|
||||
speed = -speed;
|
||||
if (_maxSpeed != speed)
|
||||
{
|
||||
_maxSpeed = speed;
|
||||
_cmin = 1000000.0 / speed;
|
||||
// Recompute _n from current speed and adjust speed if accelerating or cruising
|
||||
if (_n > 0)
|
||||
{
|
||||
_n = (long)((_speed * _speed) / (2.0 * _acceleration)); // Equation 16
|
||||
computeNewSpeed();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
float AccelStepper_MCP23017_Soft::maxSpeed()
|
||||
{
|
||||
return _maxSpeed;
|
||||
}
|
||||
|
||||
void AccelStepper_MCP23017_Soft::setAcceleration(float acceleration)
|
||||
{
|
||||
if (acceleration == 0.0)
|
||||
return;
|
||||
if (acceleration < 0.0)
|
||||
acceleration = -acceleration;
|
||||
if (_acceleration != acceleration)
|
||||
{
|
||||
// Recompute _n per Equation 17
|
||||
_n = _n * (_acceleration / acceleration);
|
||||
// New c0 per Equation 7, with correction per Equation 15
|
||||
_c0 = 0.676 * sqrt(2.0 / acceleration) * 1000000.0; // Equation 15
|
||||
_acceleration = acceleration;
|
||||
computeNewSpeed();
|
||||
}
|
||||
}
|
||||
|
||||
void AccelStepper_MCP23017_Soft::setSpeed(float speed)
|
||||
{
|
||||
if (speed == _speed)
|
||||
return;
|
||||
speed = constrain(speed, -_maxSpeed, _maxSpeed);
|
||||
if (speed == 0.0)
|
||||
_stepInterval = 0;
|
||||
else
|
||||
{
|
||||
_stepInterval = fabs(1000000.0 / speed);
|
||||
_direction = (speed > 0.0) ? DIRECTION_CW : DIRECTION_CCW;
|
||||
}
|
||||
_speed = speed;
|
||||
}
|
||||
|
||||
float AccelStepper_MCP23017_Soft::speed()
|
||||
{
|
||||
return _speed;
|
||||
}
|
||||
|
||||
// Subclasses can override
|
||||
void AccelStepper_MCP23017_Soft::step(long step)
|
||||
{
|
||||
switch (_interface)
|
||||
{
|
||||
case FUNCTION:
|
||||
step0(step);
|
||||
break;
|
||||
|
||||
case DRIVER:
|
||||
step1(step);
|
||||
break;
|
||||
|
||||
case FULL2WIRE:
|
||||
step2(step);
|
||||
break;
|
||||
|
||||
case FULL3WIRE:
|
||||
step3(step);
|
||||
break;
|
||||
|
||||
case FULL4WIRE:
|
||||
step4(step);
|
||||
break;
|
||||
|
||||
case HALF3WIRE:
|
||||
step6(step);
|
||||
break;
|
||||
|
||||
case HALF4WIRE:
|
||||
step8(step);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// You might want to override this to implement eg serial output
|
||||
// bit 0 of the mask corresponds to _pin[0]
|
||||
// bit 1 of the mask corresponds to _pin[1]
|
||||
// ....
|
||||
void AccelStepper_MCP23017_Soft::setOutputPins(uint8_t mask)
|
||||
{
|
||||
uint8_t numpins = 2;
|
||||
if (_interface == FULL4WIRE || _interface == HALF4WIRE)
|
||||
numpins = 4;
|
||||
else if (_interface == FULL3WIRE || _interface == HALF3WIRE)
|
||||
numpins = 3;
|
||||
uint8_t i;
|
||||
for (i = 0; i < numpins; i++)
|
||||
_device->digitalWrite(_pin[i], (mask & (1 << i)) ? (HIGH ^ _pinInverted[i]) : (LOW ^ _pinInverted[i]));
|
||||
}
|
||||
|
||||
// 0 pin step function (ie for functional usage)
|
||||
void AccelStepper_MCP23017_Soft::step0(long step)
|
||||
{
|
||||
(void)(step); // Unused
|
||||
if (_speed > 0)
|
||||
_forward();
|
||||
else
|
||||
_backward();
|
||||
}
|
||||
|
||||
// 1 pin step function (ie for stepper drivers)
|
||||
// This is passed the current step number (0 to 7)
|
||||
// Subclasses can override
|
||||
void AccelStepper_MCP23017_Soft::step1(long step)
|
||||
{
|
||||
(void)(step); // Unused
|
||||
|
||||
// _pin[0] is step, _pin[1] is direction
|
||||
setOutputPins(_direction ? 0b10 : 0b00); // Set direction first else get rogue pulses
|
||||
setOutputPins(_direction ? 0b11 : 0b01); // step HIGH
|
||||
// Caution 200ns setup time
|
||||
// Delay the minimum allowed pulse width
|
||||
delayMicroseconds(_minPulseWidth);
|
||||
setOutputPins(_direction ? 0b10 : 0b00); // step LOW
|
||||
}
|
||||
|
||||
|
||||
// 2 pin step function
|
||||
// This is passed the current step number (0 to 7)
|
||||
// Subclasses can override
|
||||
void AccelStepper_MCP23017_Soft::step2(long step)
|
||||
{
|
||||
switch (step & 0x3)
|
||||
{
|
||||
case 0: /* 01 */
|
||||
setOutputPins(0b10);
|
||||
break;
|
||||
|
||||
case 1: /* 11 */
|
||||
setOutputPins(0b11);
|
||||
break;
|
||||
|
||||
case 2: /* 10 */
|
||||
setOutputPins(0b01);
|
||||
break;
|
||||
|
||||
case 3: /* 00 */
|
||||
setOutputPins(0b00);
|
||||
break;
|
||||
}
|
||||
}
|
||||
// 3 pin step function
|
||||
// This is passed the current step number (0 to 7)
|
||||
// Subclasses can override
|
||||
void AccelStepper_MCP23017_Soft::step3(long step)
|
||||
{
|
||||
switch (step % 3)
|
||||
{
|
||||
case 0: // 100
|
||||
setOutputPins(0b100);
|
||||
break;
|
||||
|
||||
case 1: // 001
|
||||
setOutputPins(0b001);
|
||||
break;
|
||||
|
||||
case 2: //010
|
||||
setOutputPins(0b010);
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// 4 pin step function for half stepper
|
||||
// This is passed the current step number (0 to 7)
|
||||
// Subclasses can override
|
||||
void AccelStepper_MCP23017_Soft::step4(long step)
|
||||
{
|
||||
switch (step & 0x3)
|
||||
{
|
||||
case 0: // 1010
|
||||
setOutputPins(0b0101);
|
||||
break;
|
||||
|
||||
case 1: // 0110
|
||||
setOutputPins(0b0110);
|
||||
break;
|
||||
|
||||
case 2: //0101
|
||||
setOutputPins(0b1010);
|
||||
break;
|
||||
|
||||
case 3: //1001
|
||||
setOutputPins(0b1001);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// 3 pin half step function
|
||||
// This is passed the current step number (0 to 7)
|
||||
// Subclasses can override
|
||||
void AccelStepper_MCP23017_Soft::step6(long step)
|
||||
{
|
||||
switch (step % 6)
|
||||
{
|
||||
case 0: // 100
|
||||
setOutputPins(0b100);
|
||||
break;
|
||||
|
||||
case 1: // 101
|
||||
setOutputPins(0b101);
|
||||
break;
|
||||
|
||||
case 2: // 001
|
||||
setOutputPins(0b001);
|
||||
break;
|
||||
|
||||
case 3: // 011
|
||||
setOutputPins(0b011);
|
||||
break;
|
||||
|
||||
case 4: // 010
|
||||
setOutputPins(0b010);
|
||||
break;
|
||||
|
||||
case 5: // 011
|
||||
setOutputPins(0b110);
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// 4 pin half step function
|
||||
// This is passed the current step number (0 to 7)
|
||||
// Subclasses can override
|
||||
void AccelStepper_MCP23017_Soft::step8(long step)
|
||||
{
|
||||
switch (step & 0x7)
|
||||
{
|
||||
case 0: // 1000
|
||||
setOutputPins(0b0001);
|
||||
break;
|
||||
|
||||
case 1: // 1010
|
||||
setOutputPins(0b0101);
|
||||
break;
|
||||
|
||||
case 2: // 0010
|
||||
setOutputPins(0b0100);
|
||||
break;
|
||||
|
||||
case 3: // 0110
|
||||
setOutputPins(0b0110);
|
||||
break;
|
||||
|
||||
case 4: // 0100
|
||||
setOutputPins(0b0010);
|
||||
break;
|
||||
|
||||
case 5: //0101
|
||||
setOutputPins(0b1010);
|
||||
break;
|
||||
|
||||
case 6: // 0001
|
||||
setOutputPins(0b1000);
|
||||
break;
|
||||
|
||||
case 7: //1001
|
||||
setOutputPins(0b1001);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Prevents power consumption on the outputs
|
||||
void AccelStepper_MCP23017_Soft::disableOutputs()
|
||||
{
|
||||
if (! _interface) return;
|
||||
|
||||
setOutputPins(0); // Handles inversion automatically
|
||||
if (_enablePin != 0xff)
|
||||
{
|
||||
//_device->pinMode(_enablePin, OUTPUT);
|
||||
_device->digitalWrite(_enablePin, LOW ^ _enableInverted);
|
||||
}
|
||||
}
|
||||
|
||||
void AccelStepper_MCP23017_Soft::enableOutputs()
|
||||
{
|
||||
if (! _interface)
|
||||
return;
|
||||
|
||||
//_device->pinMode(_pin[0], OUTPUT);
|
||||
//_device->pinMode(_pin[1], OUTPUT);
|
||||
//if (_interface == FULL4WIRE || _interface == HALF4WIRE)
|
||||
//{
|
||||
// _device->pinMode(_pin[2], OUTPUT);
|
||||
// _device->pinMode(_pin[3], OUTPUT);
|
||||
//}
|
||||
//else if (_interface == FULL3WIRE || _interface == HALF3WIRE)
|
||||
//{
|
||||
// _device->pinMode(_pin[2], OUTPUT);
|
||||
//}
|
||||
|
||||
if (_enablePin != 0xff)
|
||||
{
|
||||
//_device->pinMode(_enablePin, OUTPUT);
|
||||
_device->digitalWrite(_enablePin, HIGH ^ _enableInverted);
|
||||
}
|
||||
}
|
||||
|
||||
void AccelStepper_MCP23017_Soft::setMinPulseWidth(unsigned int minWidth)
|
||||
{
|
||||
_minPulseWidth = minWidth;
|
||||
}
|
||||
|
||||
void AccelStepper_MCP23017_Soft::setEnablePin(uint8_t enablePin)
|
||||
{
|
||||
_enablePin = enablePin;
|
||||
|
||||
// This happens after construction, so init pin now.
|
||||
if (_enablePin != 0xff)
|
||||
{
|
||||
//_device->pinMode(_enablePin, OUTPUT);
|
||||
_device->digitalWrite(_enablePin, HIGH ^ _enableInverted);
|
||||
}
|
||||
}
|
||||
|
||||
void AccelStepper_MCP23017_Soft::setPinsInverted(bool directionInvert, bool stepInvert, bool enableInvert)
|
||||
{
|
||||
_pinInverted[0] = stepInvert;
|
||||
_pinInverted[1] = directionInvert;
|
||||
_enableInverted = enableInvert;
|
||||
}
|
||||
|
||||
void AccelStepper_MCP23017_Soft::setPinsInverted(bool pin1Invert, bool pin2Invert, bool pin3Invert, bool pin4Invert, bool enableInvert)
|
||||
{
|
||||
_pinInverted[0] = pin1Invert;
|
||||
_pinInverted[1] = pin2Invert;
|
||||
_pinInverted[2] = pin3Invert;
|
||||
_pinInverted[3] = pin4Invert;
|
||||
_enableInverted = enableInvert;
|
||||
}
|
||||
|
||||
// Blocks until the target position is reached and stopped
|
||||
void AccelStepper_MCP23017_Soft::runToPosition()
|
||||
{
|
||||
while (run())
|
||||
;
|
||||
}
|
||||
|
||||
boolean AccelStepper_MCP23017_Soft::runSpeedToPosition()
|
||||
{
|
||||
if (_targetPos == _currentPos)
|
||||
return false;
|
||||
if (_targetPos >_currentPos)
|
||||
_direction = DIRECTION_CW;
|
||||
else
|
||||
_direction = DIRECTION_CCW;
|
||||
return runSpeed();
|
||||
}
|
||||
|
||||
// Blocks until the new target position is reached
|
||||
void AccelStepper_MCP23017_Soft::runToNewPosition(long position)
|
||||
{
|
||||
moveTo(position);
|
||||
runToPosition();
|
||||
}
|
||||
|
||||
void AccelStepper_MCP23017_Soft::stop()
|
||||
{
|
||||
if (_speed != 0.0)
|
||||
{
|
||||
long stepsToStop = (long)((_speed * _speed) / (2.0 * _acceleration)) + 1; // Equation 16 (+integer rounding)
|
||||
if (_speed > 0)
|
||||
move(stepsToStop);
|
||||
else
|
||||
move(-stepsToStop);
|
||||
}
|
||||
}
|
||||
|
||||
bool AccelStepper_MCP23017_Soft::isRunning()
|
||||
{
|
||||
return !(_speed == 0.0 && _targetPos == _currentPos);
|
||||
}
|
||||
@@ -0,0 +1,735 @@
|
||||
// AccelStepper_MCP23017_Soft.h
|
||||
//
|
||||
/// \mainpage AccelStepper_MCP23017_Soft library for Arduino
|
||||
///
|
||||
/// This is the Arduino AccelStepper_MCP23017_Soft library.
|
||||
/// It provides an object-oriented interface for 2, 3 or 4 pin stepper motors and motor drivers.
|
||||
///
|
||||
/// The standard Arduino IDE includes the Stepper library
|
||||
/// (http://arduino.cc/en/Reference/Stepper) for stepper motors. It is
|
||||
/// perfectly adequate for simple, single motor applications.
|
||||
///
|
||||
/// AccelStepper_MCP23017_Soft significantly improves on the standard Arduino Stepper library in several ways:
|
||||
/// \li Supports acceleration and deceleration
|
||||
/// \li Supports multiple simultaneous steppers, with independent concurrent stepping on each stepper
|
||||
/// \li API functions never delay() or block
|
||||
/// \li Supports 2, 3 and 4 wire steppers, plus 3 and 4 wire half steppers.
|
||||
/// \li Supports alternate stepping functions to enable support of AFMotor (https://github.com/adafruit/Adafruit-Motor-Shield-library)
|
||||
/// \li Supports stepper drivers such as the Sparkfun EasyDriver (based on 3967 driver chip)
|
||||
/// \li Very slow speeds are supported
|
||||
/// \li Extensive API
|
||||
/// \li Subclass support
|
||||
///
|
||||
/// The latest version of this documentation can be downloaded from
|
||||
/// http://www.airspayce.com/mikem/arduino/AccelStepper_MCP23017_Soft
|
||||
/// The version of the package that this documentation refers to can be downloaded
|
||||
/// from http://www.airspayce.com/mikem/arduino/AccelStepper_MCP23017_Soft/AccelStepper_MCP23017_Soft-1.59.zip
|
||||
///
|
||||
/// Example Arduino programs are included to show the main modes of use.
|
||||
///
|
||||
/// You can also find online help and discussion at http://groups.google.com/group/accelstepper
|
||||
/// Please use that group for all questions and discussions on this topic.
|
||||
/// Do not contact the author directly, unless it is to discuss commercial licensing.
|
||||
/// Before asking a question or reporting a bug, please read
|
||||
/// - http://en.wikipedia.org/wiki/Wikipedia:Reference_desk/How_to_ask_a_software_question
|
||||
/// - http://www.catb.org/esr/faqs/smart-questions.html
|
||||
/// - http://www.chiark.greenend.org.uk/~shgtatham/bugs.html
|
||||
///
|
||||
/// Tested on Arduino Diecimila and Mega with arduino-0018 & arduino-0021
|
||||
/// on OpenSuSE 11.1 and avr-libc-1.6.1-1.15,
|
||||
/// cross-avr-binutils-2.19-9.1, cross-avr-gcc-4.1.3_20080612-26.5.
|
||||
/// Tested on Teensy http://www.pjrc.com/teensy including Teensy 3.1 built using Arduino IDE 1.0.5 with
|
||||
/// teensyduino addon 1.18 and later.
|
||||
///
|
||||
/// \par Installation
|
||||
///
|
||||
/// Install in the usual way: unzip the distribution zip file to the libraries
|
||||
/// sub-folder of your sketchbook.
|
||||
///
|
||||
/// \par Theory
|
||||
///
|
||||
/// This code uses speed calculations as described in
|
||||
/// "Generate stepper-motor speed profiles in real time" by David Austin
|
||||
/// http://fab.cba.mit.edu/classes/MIT/961.09/projects/i0/Stepper_Motor_Speed_Profile.pdf or
|
||||
/// http://www.embedded.com/design/mcus-processors-and-socs/4006438/Generate-stepper-motor-speed-profiles-in-real-time or
|
||||
/// http://web.archive.org/web/20140705143928/http://fab.cba.mit.edu/classes/MIT/961.09/projects/i0/Stepper_Motor_Speed_Profile.pdf
|
||||
/// with the exception that AccelStepper_MCP23017_Soft uses steps per second rather than radians per second
|
||||
/// (because we dont know the step angle of the motor)
|
||||
/// An initial step interval is calculated for the first step, based on the desired acceleration
|
||||
/// On subsequent steps, shorter step intervals are calculated based
|
||||
/// on the previous step until max speed is achieved.
|
||||
///
|
||||
/// \par Adafruit Motor Shield V2
|
||||
///
|
||||
/// The included examples AFMotor_* are for Adafruit Motor Shield V1 and do not work with Adafruit Motor Shield V2.
|
||||
/// See https://github.com/adafruit/Adafruit_Motor_Shield_V2_Library for examples that work with Adafruit Motor Shield V2.
|
||||
///
|
||||
/// \par Donations
|
||||
///
|
||||
/// This library is offered under a free GPL license for those who want to use it that way.
|
||||
/// We try hard to keep it up to date, fix bugs
|
||||
/// and to provide free support. If this library has helped you save time or money, please consider donating at
|
||||
/// http://www.airspayce.com or here:
|
||||
///
|
||||
/// \htmlonly <form action="https://www.paypal.com/cgi-bin/webscr" method="post"><input type="hidden" name="cmd" value="_donations" /> <input type="hidden" name="business" value="mikem@airspayce.com" /> <input type="hidden" name="lc" value="AU" /> <input type="hidden" name="item_name" value="Airspayce" /> <input type="hidden" name="item_number" value="AccelStepper_MCP23017_Soft" /> <input type="hidden" name="currency_code" value="USD" /> <input type="hidden" name="bn" value="PP-DonationsBF:btn_donateCC_LG.gif:NonHosted" /> <input type="image" alt="PayPal — The safer, easier way to pay online." name="submit" src="https://www.paypalobjects.com/en_AU/i/btn/btn_donateCC_LG.gif" /> <img alt="" src="https://www.paypalobjects.com/en_AU/i/scr/pixel.gif" width="1" height="1" border="0" /></form> \endhtmlonly
|
||||
///
|
||||
/// \par Trademarks
|
||||
///
|
||||
/// AccelStepper_MCP23017_Soft is a trademark of AirSpayce Pty Ltd. The AccelStepper_MCP23017_Soft mark was first used on April 26 2010 for
|
||||
/// international trade, and is used only in relation to motor control hardware and software.
|
||||
/// It is not to be confused with any other similar marks covering other goods and services.
|
||||
///
|
||||
/// \par Copyright
|
||||
///
|
||||
/// This software is Copyright (C) 2010-2018 Mike McCauley. Use is subject to license
|
||||
/// conditions. The main licensing options available are GPL V2 or Commercial:
|
||||
///
|
||||
/// \par Open Source Licensing GPL V2
|
||||
/// This is the appropriate option if you want to share the source code of your
|
||||
/// application with everyone you distribute it to, and you also want to give them
|
||||
/// the right to share who uses it. If you wish to use this software under Open
|
||||
/// Source Licensing, you must contribute all your source code to the open source
|
||||
/// community in accordance with the GPL Version 2 when your application is
|
||||
/// distributed. See https://www.gnu.org/licenses/gpl-2.0.html
|
||||
///
|
||||
/// \par Commercial Licensing
|
||||
/// This is the appropriate option if you are creating proprietary applications
|
||||
/// and you are not prepared to distribute and share the source code of your
|
||||
/// application. To purchase a commercial license, contact info@airspayce.com
|
||||
///
|
||||
/// \par Revision History
|
||||
/// \version 1.0 Initial release
|
||||
///
|
||||
/// \version 1.1 Added speed() function to get the current speed.
|
||||
/// \version 1.2 Added runSpeedToPosition() submitted by Gunnar Arndt.
|
||||
/// \version 1.3 Added support for stepper drivers (ie with Step and Direction inputs) with _pins == 1
|
||||
/// \version 1.4 Added functional contructor to support AFMotor, contributed by Limor, with example sketches.
|
||||
/// \version 1.5 Improvements contributed by Peter Mousley: Use of microsecond steps and other speed improvements
|
||||
/// to increase max stepping speed to about 4kHz. New option for user to set the min allowed pulse width.
|
||||
/// Added checks for already running at max speed and skip further calcs if so.
|
||||
/// \version 1.6 Fixed a problem with wrapping of microsecond stepping that could cause stepping to hang.
|
||||
/// Reported by Sandy Noble.
|
||||
/// Removed redundant _lastRunTime member.
|
||||
/// \version 1.7 Fixed a bug where setCurrentPosition() did not always work as expected.
|
||||
/// Reported by Peter Linhart.
|
||||
/// \version 1.8 Added support for 4 pin half-steppers, requested by Harvey Moon
|
||||
/// \version 1.9 setCurrentPosition() now also sets motor speed to 0.
|
||||
/// \version 1.10 Builds on Arduino 1.0
|
||||
/// \version 1.11 Improvments from Michael Ellison:
|
||||
/// Added optional enable line support for stepper drivers
|
||||
/// Added inversion for step/direction/enable lines for stepper drivers
|
||||
/// \version 1.12 Announce Google Group
|
||||
/// \version 1.13 Improvements to speed calculation. Cost of calculation is now less in the worst case,
|
||||
/// and more or less constant in all cases. This should result in slightly beter high speed performance, and
|
||||
/// reduce anomalous speed glitches when other steppers are accelerating.
|
||||
/// However, its hard to see how to replace the sqrt() required at the very first step from 0 speed.
|
||||
/// \version 1.14 Fixed a problem with compiling under arduino 0021 reported by EmbeddedMan
|
||||
/// \version 1.15 Fixed a problem with runSpeedToPosition which did not correctly handle
|
||||
/// running backwards to a smaller target position. Added examples
|
||||
/// \version 1.16 Fixed some cases in the code where abs() was used instead of fabs().
|
||||
/// \version 1.17 Added example ProportionalControl
|
||||
/// \version 1.18 Fixed a problem: If one calls the funcion runSpeed() when Speed is zero, it makes steps
|
||||
/// without counting. reported by Friedrich, Klappenbach.
|
||||
/// \version 1.19 Added MotorInterfaceType and symbolic names for the number of pins to use
|
||||
/// for the motor interface. Updated examples to suit.
|
||||
/// Replaced individual pin assignment variables _pin1, _pin2 etc with array _pin[4].
|
||||
/// _pins member changed to _interface.
|
||||
/// Added _pinInverted array to simplify pin inversion operations.
|
||||
/// Added new function setOutputPins() which sets the motor output pins.
|
||||
/// It can be overridden in order to provide, say, serial output instead of parallel output
|
||||
/// Some refactoring and code size reduction.
|
||||
/// \version 1.20 Improved documentation and examples to show need for correctly
|
||||
/// specifying AccelStepper_MCP23017_Soft::FULL4WIRE and friends.
|
||||
/// \version 1.21 Fixed a problem where desiredSpeed could compute the wrong step acceleration
|
||||
/// when _speed was small but non-zero. Reported by Brian Schmalz.
|
||||
/// Precompute sqrt_twoa to improve performance and max possible stepping speed
|
||||
/// \version 1.22 Added Bounce.pde example
|
||||
/// Fixed a problem where calling moveTo(), setMaxSpeed(), setAcceleration() more
|
||||
/// frequently than the step time, even
|
||||
/// with the same values, would interfere with speed calcs. Now a new speed is computed
|
||||
/// only if there was a change in the set value. Reported by Brian Schmalz.
|
||||
/// \version 1.23 Rewrite of the speed algorithms in line with
|
||||
/// http://fab.cba.mit.edu/classes/MIT/961.09/projects/i0/Stepper_Motor_Speed_Profile.pdf
|
||||
/// Now expect smoother and more linear accelerations and decelerations. The desiredSpeed()
|
||||
/// function was removed.
|
||||
/// \version 1.24 Fixed a problem introduced in 1.23: with runToPosition, which did never returned
|
||||
/// \version 1.25 Now ignore attempts to set acceleration to 0.0
|
||||
/// \version 1.26 Fixed a problem where certina combinations of speed and accelration could cause
|
||||
/// oscillation about the target position.
|
||||
/// \version 1.27 Added stop() function to stop as fast as possible with current acceleration parameters.
|
||||
/// Also added new Quickstop example showing its use.
|
||||
/// \version 1.28 Fixed another problem where certain combinations of speed and acceleration could cause
|
||||
/// oscillation about the target position.
|
||||
/// Added support for 3 wire full and half steppers such as Hard Disk Drive spindle.
|
||||
/// Contributed by Yuri Ivatchkovitch.
|
||||
/// \version 1.29 Fixed a problem that could cause a DRIVER stepper to continually step
|
||||
/// with some sketches. Reported by Vadim.
|
||||
/// \version 1.30 Fixed a problem that could cause stepper to back up a few steps at the end of
|
||||
/// accelerated travel with certain speeds. Reported and patched by jolo.
|
||||
/// \version 1.31 Updated author and distribution location details to airspayce.com
|
||||
/// \version 1.32 Fixed a problem with enableOutputs() and setEnablePin on Arduino Due that
|
||||
/// prevented the enable pin changing stae correctly. Reported by Duane Bishop.
|
||||
/// \version 1.33 Fixed an error in example AFMotor_ConstantSpeed.pde did not setMaxSpeed();
|
||||
/// Fixed a problem that caused incorrect pin sequencing of FULL3WIRE and HALF3WIRE.
|
||||
/// Unfortunately this meant changing the signature for all step*() functions.
|
||||
/// Added example MotorShield, showing how to use AdaFruit Motor Shield to control
|
||||
/// a 3 phase motor such as a HDD spindle motor (and without using the AFMotor library.
|
||||
/// \version 1.34 Added setPinsInverted(bool pin1Invert, bool pin2Invert, bool pin3Invert, bool pin4Invert, bool enableInvert)
|
||||
/// to allow inversion of 2, 3 and 4 wire stepper pins. Requested by Oleg.
|
||||
/// \version 1.35 Removed default args from setPinsInverted(bool, bool, bool, bool, bool) to prevent ambiguity with
|
||||
/// setPinsInverted(bool, bool, bool). Reported by Mac Mac.
|
||||
/// \version 1.36 Changed enableOutputs() and disableOutputs() to be virtual so can be overridden.
|
||||
/// Added new optional argument 'enable' to constructor, which allows you toi disable the
|
||||
/// automatic enabling of outputs at construction time. Suggested by Guido.
|
||||
/// \version 1.37 Fixed a problem with step1 that could cause a rogue step in the
|
||||
/// wrong direction (or not,
|
||||
/// depending on the setup-time requirements of the connected hardware).
|
||||
/// Reported by Mark Tillotson.
|
||||
/// \version 1.38 run() function incorrectly always returned true. Updated function and doc so it returns true
|
||||
/// if the motor is still running to the target position.
|
||||
/// \version 1.39 Updated typos in keywords.txt, courtesey Jon Magill.
|
||||
/// \version 1.40 Updated documentation, including testing on Teensy 3.1
|
||||
/// \version 1.41 Fixed an error in the acceleration calculations, resulting in acceleration of haldf the intended value
|
||||
/// \version 1.42 Improved support for FULL3WIRE and HALF3WIRE output pins. These changes were in Yuri's original
|
||||
/// contribution but did not make it into production.<br>
|
||||
/// \version 1.43 Added DualMotorShield example. Shows how to use AccelStepper_MCP23017_Soft to control 2 x 2 phase steppers using the
|
||||
/// Itead Studio Arduino Dual Stepper Motor Driver Shield model IM120417015.<br>
|
||||
/// \version 1.44 examples/DualMotorShield/DualMotorShield.ino examples/DualMotorShield/DualMotorShield.pde
|
||||
/// was missing from the distribution.<br>
|
||||
/// \version 1.45 Fixed a problem where if setAcceleration was not called, there was no default
|
||||
/// acceleration. Reported by Michael Newman.<br>
|
||||
/// \version 1.45 Fixed inaccuracy in acceleration rate by using Equation 15, suggested by Sebastian Gracki.<br>
|
||||
/// Performance improvements in runSpeed suggested by Jaakko Fagerlund.<br>
|
||||
/// \version 1.46 Fixed error in documentation for runToPosition().
|
||||
/// Reinstated time calculations in runSpeed() since new version is reported
|
||||
/// not to work correctly under some circumstances. Reported by Oleg V Gavva.<br>
|
||||
/// \version 1.48 2015-08-25
|
||||
/// Added new class MultiStepper that can manage multiple AccelStepper_MCP23017_Softs,
|
||||
/// and cause them all to move
|
||||
/// to selected positions at such a (constant) speed that they all arrive at their
|
||||
/// target position at the same time. Suitable for X-Y flatbeds etc.<br>
|
||||
/// Added new method maxSpeed() to AccelStepper_MCP23017_Soft to return the currently configured maxSpeed.<br>
|
||||
/// \version 1.49 2016-01-02
|
||||
/// Testing with VID28 series instrument stepper motors and EasyDriver.
|
||||
/// OK, although with light pointers
|
||||
/// and slow speeds like 180 full steps per second the motor movement can be erratic,
|
||||
/// probably due to some mechanical resonance. Best to accelerate through this speed.<br>
|
||||
/// Added isRunning().<br>
|
||||
/// \version 1.50 2016-02-25
|
||||
/// AccelStepper_MCP23017_Soft::disableOutputs now sets the enable pion to OUTPUT mode if the enable pin is defined.
|
||||
/// Patch from Piet De Jong.<br>
|
||||
/// Added notes about the fact that AFMotor_* examples do not work with Adafruit Motor Shield V2.<br>
|
||||
/// \version 1.51 2016-03-24
|
||||
/// Fixed a problem reported by gregor: when resetting the stepper motor position using setCurrentPosition() the
|
||||
/// stepper speed is reset by setting _stepInterval to 0, but _speed is not
|
||||
/// reset. this results in the stepper motor not starting again when calling
|
||||
/// setSpeed() with the same speed the stepper was set to before.
|
||||
/// \version 1.52 2016-08-09
|
||||
/// Added MultiStepper to keywords.txt.
|
||||
/// Improvements to efficiency of AccelStepper_MCP23017_Soft::runSpeed() as suggested by David Grayson.
|
||||
/// Improvements to speed accuracy as suggested by David Grayson.
|
||||
/// \version 1.53 2016-08-14
|
||||
/// Backed out Improvements to speed accuracy from 1.52 as it did not work correctly.
|
||||
/// \version 1.54 2017-01-24
|
||||
/// Fixed some warnings about unused arguments.
|
||||
/// \version 1.55 2017-01-25
|
||||
/// Fixed another warning in MultiStepper.cpp
|
||||
/// \version 1.56 2017-02-03
|
||||
/// Fixed minor documentation error with DIRECTION_CCW and DIRECTION_CW. Reported by David Mutterer.
|
||||
/// Added link to Binpress commercial license purchasing.
|
||||
/// \version 1.57 2017-03-28
|
||||
/// _direction moved to protected at the request of Rudy Ercek.
|
||||
/// setMaxSpeed() and setAcceleration() now correct negative values to be positive.
|
||||
/// \version 1.58 2018-04-13
|
||||
/// Add initialisation for _enableInverted in constructor.
|
||||
/// \version 1.59 2018-08-28
|
||||
/// Update commercial licensing, remove binpress.
|
||||
///
|
||||
/// \author Mike McCauley (mikem@airspayce.com) DO NOT CONTACT THE AUTHOR DIRECTLY: USE THE LISTS
|
||||
// Copyright (C) 2009-2013 Mike McCauley
|
||||
// $Id: AccelStepper_MCP23017_Soft.h,v 1.27 2016/08/14 10:26:54 mikem Exp mikem $
|
||||
|
||||
#ifndef AccelStepper_MCP23017_Soft_h
|
||||
#define AccelStepper_MCP23017_Soft_h
|
||||
#include <SoftwareWire.h>
|
||||
#include "Adafruit_MCP23017_Soft.h"
|
||||
#include <stdlib.h>
|
||||
#if ARDUINO >= 100
|
||||
#include <Arduino.h>
|
||||
#else
|
||||
#include <WProgram.h>
|
||||
#include <wiring.h>
|
||||
#endif
|
||||
|
||||
// These defs cause trouble on some versions of Arduino
|
||||
#undef round
|
||||
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
/// \class AccelStepper_MCP23017_Soft AccelStepper_MCP23017_Soft.h <AccelStepper_MCP23017_Soft.h>
|
||||
/// \brief Support for stepper motors with acceleration etc.
|
||||
///
|
||||
/// This defines a single 2 or 4 pin stepper motor, or stepper moter with fdriver chip, with optional
|
||||
/// acceleration, deceleration, absolute positioning commands etc. Multiple
|
||||
/// simultaneous steppers are supported, all moving
|
||||
/// at different speeds and accelerations.
|
||||
///
|
||||
/// \par Operation
|
||||
/// This module operates by computing a step time in microseconds. The step
|
||||
/// time is recomputed after each step and after speed and acceleration
|
||||
/// parameters are changed by the caller. The time of each step is recorded in
|
||||
/// microseconds. The run() function steps the motor once if a new step is due.
|
||||
/// The run() function must be called frequently until the motor is in the
|
||||
/// desired position, after which time run() will do nothing.
|
||||
///
|
||||
/// \par Positioning
|
||||
/// Positions are specified by a signed long integer. At
|
||||
/// construction time, the current position of the motor is consider to be 0. Positive
|
||||
/// positions are clockwise from the initial position; negative positions are
|
||||
/// anticlockwise. The current position can be altered for instance after
|
||||
/// initialization positioning.
|
||||
///
|
||||
/// \par Caveats
|
||||
/// This is an open loop controller: If the motor stalls or is oversped,
|
||||
/// AccelStepper_MCP23017_Soft will not have a correct
|
||||
/// idea of where the motor really is (since there is no feedback of the motor's
|
||||
/// real position. We only know where we _think_ it is, relative to the
|
||||
/// initial starting point).
|
||||
///
|
||||
/// \par Performance
|
||||
/// The fastest motor speed that can be reliably supported is about 4000 steps per
|
||||
/// second at a clock frequency of 16 MHz on Arduino such as Uno etc.
|
||||
/// Faster processors can support faster stepping speeds.
|
||||
/// However, any speed less than that
|
||||
/// down to very slow speeds (much less than one per second) are also supported,
|
||||
/// provided the run() function is called frequently enough to step the motor
|
||||
/// whenever required for the speed set.
|
||||
/// Calling setAcceleration() is expensive,
|
||||
/// since it requires a square root to be calculated.
|
||||
///
|
||||
/// Gregor Christandl reports that with an Arduino Due and a simple test program,
|
||||
/// he measured 43163 steps per second using runSpeed(),
|
||||
/// and 16214 steps per second using run();
|
||||
class AccelStepper_MCP23017_Soft
|
||||
{
|
||||
public:
|
||||
/// \brief Symbolic names for number of pins.
|
||||
/// Use this in the pins argument the AccelStepper_MCP23017_Soft constructor to
|
||||
/// provide a symbolic name for the number of pins
|
||||
/// to use.
|
||||
typedef enum
|
||||
{
|
||||
FUNCTION = 0, ///< Use the functional interface, implementing your own driver functions (internal use only)
|
||||
DRIVER = 1, ///< Stepper Driver, 2 driver pins required
|
||||
FULL2WIRE = 2, ///< 2 wire stepper, 2 motor pins required
|
||||
FULL3WIRE = 3, ///< 3 wire stepper, such as HDD spindle, 3 motor pins required
|
||||
FULL4WIRE = 4, ///< 4 wire full stepper, 4 motor pins required
|
||||
HALF3WIRE = 6, ///< 3 wire half stepper, such as HDD spindle, 3 motor pins required
|
||||
HALF4WIRE = 8 ///< 4 wire half stepper, 4 motor pins required
|
||||
} MotorInterfaceType;
|
||||
|
||||
/// Constructor. You can have multiple simultaneous steppers, all moving
|
||||
/// at different speeds and accelerations, provided you call their run()
|
||||
/// functions at frequent enough intervals. Current Position is set to 0, target
|
||||
/// position is set to 0. MaxSpeed and Acceleration default to 1.0.
|
||||
/// The motor pins will be initialised to OUTPUT mode during the
|
||||
/// constructor by a call to enableOutputs().
|
||||
/// \param[in] interface Number of pins to interface to. Integer values are
|
||||
/// supported, but it is preferred to use the \ref MotorInterfaceType symbolic names.
|
||||
/// AccelStepper_MCP23017_Soft::DRIVER (1) means a stepper driver (with Step and Direction pins).
|
||||
/// If an enable line is also needed, call setEnablePin() after construction.
|
||||
/// You may also invert the pins using setPinsInverted().
|
||||
/// AccelStepper_MCP23017_Soft::FULL2WIRE (2) means a 2 wire stepper (2 pins required).
|
||||
/// AccelStepper_MCP23017_Soft::FULL3WIRE (3) means a 3 wire stepper, such as HDD spindle (3 pins required).
|
||||
/// AccelStepper_MCP23017_Soft::FULL4WIRE (4) means a 4 wire stepper (4 pins required).
|
||||
/// AccelStepper_MCP23017_Soft::HALF3WIRE (6) means a 3 wire half stepper, such as HDD spindle (3 pins required)
|
||||
/// AccelStepper_MCP23017_Soft::HALF4WIRE (8) means a 4 wire half stepper (4 pins required)
|
||||
/// Defaults to AccelStepper_MCP23017_Soft::FULL4WIRE (4) pins.
|
||||
/// \param[in] pin1 Arduino digital pin number for motor pin 1. Defaults
|
||||
/// to pin 2. For a AccelStepper_MCP23017_Soft::DRIVER (interface==1),
|
||||
/// this is the Step input to the driver. Low to high transition means to step)
|
||||
/// \param[in] pin2 Arduino digital pin number for motor pin 2. Defaults
|
||||
/// to pin 3. For a AccelStepper_MCP23017_Soft::DRIVER (interface==1),
|
||||
/// this is the Direction input the driver. High means forward.
|
||||
/// \param[in] pin3 Arduino digital pin number for motor pin 3. Defaults
|
||||
/// to pin 4.
|
||||
/// \param[in] pin4 Arduino digital pin number for motor pin 4. Defaults
|
||||
/// to pin 5.
|
||||
/// \param[in] enable If this is true (the default), enableOutputs() will be called to enable
|
||||
/// the output pins at construction time.
|
||||
AccelStepper_MCP23017_Soft(Adafruit_MCP23017_Soft *device, uint8_t interface = AccelStepper_MCP23017_Soft::FULL4WIRE, uint8_t pin1 = 2, uint8_t pin2 = 3, uint8_t pin3 = 4, uint8_t pin4 = 5, bool enable = true);
|
||||
|
||||
/// Alternate Constructor which will call your own functions for forward and backward steps.
|
||||
/// You can have multiple simultaneous steppers, all moving
|
||||
/// at different speeds and accelerations, provided you call their run()
|
||||
/// functions at frequent enough intervals. Current Position is set to 0, target
|
||||
/// position is set to 0. MaxSpeed and Acceleration default to 1.0.
|
||||
/// Any motor initialization should happen before hand, no pins are used or initialized.
|
||||
/// \param[in] forward void-returning procedure that will make a forward step
|
||||
/// \param[in] backward void-returning procedure that will make a backward step
|
||||
|
||||
/// Set the target position. The run() function will try to move the motor (at most one step per call)
|
||||
/// from the current position to the target position set by the most
|
||||
/// recent call to this function. Caution: moveTo() also recalculates the speed for the next step.
|
||||
/// If you are trying to use constant speed movements, you should call setSpeed() after calling moveTo().
|
||||
/// \param[in] absolute The desired absolute position. Negative is
|
||||
/// anticlockwise from the 0 position.
|
||||
void moveTo(long absolute);
|
||||
|
||||
/// Set the target position relative to the current position
|
||||
/// \param[in] relative The desired position relative to the current position. Negative is
|
||||
/// anticlockwise from the current position.
|
||||
void move(long relative);
|
||||
|
||||
/// Poll the motor and step it if a step is due, implementing
|
||||
/// accelerations and decelerations to acheive the target position. You must call this as
|
||||
/// frequently as possible, but at least once per minimum step time interval,
|
||||
/// preferably in your main loop. Note that each call to run() will make at most one step, and then only when a step is due,
|
||||
/// based on the current speed and the time since the last step.
|
||||
/// \return true if the motor is still running to the target position.
|
||||
boolean run();
|
||||
|
||||
/// Poll the motor and step it if a step is due, implementing a constant
|
||||
/// speed as set by the most recent call to setSpeed(). You must call this as
|
||||
/// frequently as possible, but at least once per step interval,
|
||||
/// \return true if the motor was stepped.
|
||||
boolean runSpeed();
|
||||
|
||||
/// Sets the maximum permitted speed. The run() function will accelerate
|
||||
/// up to the speed set by this function.
|
||||
/// Caution: the maximum speed achievable depends on your processor and clock speed.
|
||||
/// The default maxSpeed is 1.0 steps per second.
|
||||
/// \param[in] speed The desired maximum speed in steps per second. Must
|
||||
/// be > 0. Caution: Speeds that exceed the maximum speed supported by the processor may
|
||||
/// Result in non-linear accelerations and decelerations.
|
||||
void setMaxSpeed(float speed);
|
||||
|
||||
/// returns the maximum speed configured for this stepper
|
||||
/// that was previously set by setMaxSpeed();
|
||||
/// \return The currently configured maximum speed
|
||||
float maxSpeed();
|
||||
|
||||
/// Sets the acceleration/deceleration rate.
|
||||
/// \param[in] acceleration The desired acceleration in steps per second
|
||||
/// per second. Must be > 0.0. This is an expensive call since it requires a square
|
||||
/// root to be calculated. Dont call more ofthen than needed
|
||||
void setAcceleration(float acceleration);
|
||||
|
||||
/// Sets the desired constant speed for use with runSpeed().
|
||||
/// \param[in] speed The desired constant speed in steps per
|
||||
/// second. Positive is clockwise. Speeds of more than 1000 steps per
|
||||
/// second are unreliable. Very slow speeds may be set (eg 0.00027777 for
|
||||
/// once per hour, approximately. Speed accuracy depends on the Arduino
|
||||
/// crystal. Jitter depends on how frequently you call the runSpeed() function.
|
||||
/// The speed will be limited by the current value of setMaxSpeed()
|
||||
void setSpeed(float speed);
|
||||
|
||||
/// The most recently set speed
|
||||
/// \return the most recent speed in steps per second
|
||||
float speed();
|
||||
|
||||
/// The distance from the current position to the target position.
|
||||
/// \return the distance from the current position to the target position
|
||||
/// in steps. Positive is clockwise from the current position.
|
||||
long distanceToGo();
|
||||
|
||||
/// The most recently set target position.
|
||||
/// \return the target position
|
||||
/// in steps. Positive is clockwise from the 0 position.
|
||||
long targetPosition();
|
||||
|
||||
/// The currently motor position.
|
||||
/// \return the current motor position
|
||||
/// in steps. Positive is clockwise from the 0 position.
|
||||
long currentPosition();
|
||||
|
||||
/// Resets the current position of the motor, so that wherever the motor
|
||||
/// happens to be right now is considered to be the new 0 position. Useful
|
||||
/// for setting a zero position on a stepper after an initial hardware
|
||||
/// positioning move.
|
||||
/// Has the side effect of setting the current motor speed to 0.
|
||||
/// \param[in] position The position in steps of wherever the motor
|
||||
/// happens to be right now.
|
||||
void setCurrentPosition(long position);
|
||||
|
||||
/// Moves the motor (with acceleration/deceleration)
|
||||
/// to the target position and blocks until it is at
|
||||
/// position. Dont use this in event loops, since it blocks.
|
||||
void runToPosition();
|
||||
|
||||
/// Runs at the currently selected speed until the target position is reached
|
||||
/// Does not implement accelerations.
|
||||
/// \return true if it stepped
|
||||
boolean runSpeedToPosition();
|
||||
|
||||
/// Moves the motor (with acceleration/deceleration)
|
||||
/// to the new target position and blocks until it is at
|
||||
/// position. Dont use this in event loops, since it blocks.
|
||||
/// \param[in] position The new target position.
|
||||
void runToNewPosition(long position);
|
||||
|
||||
/// Sets a new target position that causes the stepper
|
||||
/// to stop as quickly as possible, using the current speed and acceleration parameters.
|
||||
void stop();
|
||||
|
||||
/// Disable motor pin outputs by setting them all LOW
|
||||
/// Depending on the design of your electronics this may turn off
|
||||
/// the power to the motor coils, saving power.
|
||||
/// This is useful to support Arduino low power modes: disable the outputs
|
||||
/// during sleep and then reenable with enableOutputs() before stepping
|
||||
/// again.
|
||||
/// If the enable Pin is defined, sets it to OUTPUT mode and clears the pin to disabled.
|
||||
virtual void disableOutputs();
|
||||
|
||||
/// Enable motor pin outputs by setting the motor pins to OUTPUT
|
||||
/// mode. Called automatically by the constructor.
|
||||
/// If the enable Pin is defined, sets it to OUTPUT mode and sets the pin to enabled.
|
||||
virtual void enableOutputs();
|
||||
|
||||
/// Sets the minimum pulse width allowed by the stepper driver. The minimum practical pulse width is
|
||||
/// approximately 20 microseconds. Times less than 20 microseconds
|
||||
/// will usually result in 20 microseconds or so.
|
||||
/// \param[in] minWidth The minimum pulse width in microseconds.
|
||||
void setMinPulseWidth(unsigned int minWidth);
|
||||
|
||||
/// Sets the enable pin number for stepper drivers.
|
||||
/// 0xFF indicates unused (default).
|
||||
/// Otherwise, if a pin is set, the pin will be turned on when
|
||||
/// enableOutputs() is called and switched off when disableOutputs()
|
||||
/// is called.
|
||||
/// \param[in] enablePin Arduino digital pin number for motor enable
|
||||
/// \sa setPinsInverted
|
||||
void setEnablePin(uint8_t enablePin = 0xff);
|
||||
|
||||
/// Sets the inversion for stepper driver pins
|
||||
/// \param[in] directionInvert True for inverted direction pin, false for non-inverted
|
||||
/// \param[in] stepInvert True for inverted step pin, false for non-inverted
|
||||
/// \param[in] enableInvert True for inverted enable pin, false (default) for non-inverted
|
||||
void setPinsInverted(bool directionInvert = false, bool stepInvert = false, bool enableInvert = false);
|
||||
|
||||
/// Sets the inversion for 2, 3 and 4 wire stepper pins
|
||||
/// \param[in] pin1Invert True for inverted pin1, false for non-inverted
|
||||
/// \param[in] pin2Invert True for inverted pin2, false for non-inverted
|
||||
/// \param[in] pin3Invert True for inverted pin3, false for non-inverted
|
||||
/// \param[in] pin4Invert True for inverted pin4, false for non-inverted
|
||||
/// \param[in] enableInvert True for inverted enable pin, false (default) for non-inverted
|
||||
void setPinsInverted(bool pin1Invert, bool pin2Invert, bool pin3Invert, bool pin4Invert, bool enableInvert);
|
||||
|
||||
/// Checks to see if the motor is currently running to a target
|
||||
/// \return true if the speed is not zero or not at the target position
|
||||
bool isRunning();
|
||||
|
||||
protected:
|
||||
|
||||
/// \brief Direction indicator
|
||||
/// Symbolic names for the direction the motor is turning
|
||||
typedef enum
|
||||
{
|
||||
DIRECTION_CCW = 0, ///< Counter-Clockwise
|
||||
DIRECTION_CW = 1 ///< Clockwise
|
||||
} Direction;
|
||||
|
||||
/// Forces the library to compute a new instantaneous speed and set that as
|
||||
/// the current speed. It is called by
|
||||
/// the library:
|
||||
/// \li after each step
|
||||
/// \li after change to maxSpeed through setMaxSpeed()
|
||||
/// \li after change to acceleration through setAcceleration()
|
||||
/// \li after change to target position (relative or absolute) through
|
||||
/// move() or moveTo()
|
||||
void computeNewSpeed();
|
||||
|
||||
/// Low level function to set the motor output pins
|
||||
/// bit 0 of the mask corresponds to _pin[0]
|
||||
/// bit 1 of the mask corresponds to _pin[1]
|
||||
/// You can override this to impment, for example serial chip output insted of using the
|
||||
/// output pins directly
|
||||
virtual void setOutputPins(uint8_t mask);
|
||||
|
||||
/// Called to execute a step. Only called when a new step is
|
||||
/// required. Subclasses may override to implement new stepping
|
||||
/// interfaces. The default calls step1(), step2(), step4() or step8() depending on the
|
||||
/// number of pins defined for the stepper.
|
||||
/// \param[in] step The current step phase number (0 to 7)
|
||||
virtual void step(long step);
|
||||
|
||||
/// Called to execute a step using stepper functions (pins = 0) Only called when a new step is
|
||||
/// required. Calls _forward() or _backward() to perform the step
|
||||
/// \param[in] step The current step phase number (0 to 7)
|
||||
virtual void step0(long step);
|
||||
|
||||
/// Called to execute a step on a stepper driver (ie where pins == 1). Only called when a new step is
|
||||
/// required. Subclasses may override to implement new stepping
|
||||
/// interfaces. The default sets or clears the outputs of Step pin1 to step,
|
||||
/// and sets the output of _pin2 to the desired direction. The Step pin (_pin1) is pulsed for 1 microsecond
|
||||
/// which is the minimum STEP pulse width for the 3967 driver.
|
||||
/// \param[in] step The current step phase number (0 to 7)
|
||||
virtual void step1(long step);
|
||||
|
||||
/// Called to execute a step on a 2 pin motor. Only called when a new step is
|
||||
/// required. Subclasses may override to implement new stepping
|
||||
/// interfaces. The default sets or clears the outputs of pin1 and pin2
|
||||
/// \param[in] step The current step phase number (0 to 7)
|
||||
virtual void step2(long step);
|
||||
|
||||
/// Called to execute a step on a 3 pin motor, such as HDD spindle. Only called when a new step is
|
||||
/// required. Subclasses may override to implement new stepping
|
||||
/// interfaces. The default sets or clears the outputs of pin1, pin2,
|
||||
/// pin3
|
||||
/// \param[in] step The current step phase number (0 to 7)
|
||||
virtual void step3(long step);
|
||||
|
||||
/// Called to execute a step on a 4 pin motor. Only called when a new step is
|
||||
/// required. Subclasses may override to implement new stepping
|
||||
/// interfaces. The default sets or clears the outputs of pin1, pin2,
|
||||
/// pin3, pin4.
|
||||
/// \param[in] step The current step phase number (0 to 7)
|
||||
virtual void step4(long step);
|
||||
|
||||
/// Called to execute a step on a 3 pin motor, such as HDD spindle. Only called when a new step is
|
||||
/// required. Subclasses may override to implement new stepping
|
||||
/// interfaces. The default sets or clears the outputs of pin1, pin2,
|
||||
/// pin3
|
||||
/// \param[in] step The current step phase number (0 to 7)
|
||||
virtual void step6(long step);
|
||||
|
||||
/// Called to execute a step on a 4 pin half-steper motor. Only called when a new step is
|
||||
/// required. Subclasses may override to implement new stepping
|
||||
/// interfaces. The default sets or clears the outputs of pin1, pin2,
|
||||
/// pin3, pin4.
|
||||
/// \param[in] step The current step phase number (0 to 7)
|
||||
virtual void step8(long step);
|
||||
|
||||
/// Current direction motor is spinning in
|
||||
/// Protected because some peoples subclasses need it to be so
|
||||
boolean _direction; // 1 == CW
|
||||
|
||||
private:
|
||||
Adafruit_MCP23017_Soft *_device;
|
||||
/// Number of pins on the stepper motor. Permits 2 or 4. 2 pins is a
|
||||
/// bipolar, and 4 pins is a unipolar.
|
||||
uint8_t _interface; // 0, 1, 2, 4, 8, See MotorInterfaceType
|
||||
|
||||
/// Arduino pin number assignments for the 2 or 4 pins required to interface to the
|
||||
/// stepper motor or driver
|
||||
uint8_t _pin[4];
|
||||
|
||||
/// Whether the _pins is inverted or not
|
||||
uint8_t _pinInverted[4];
|
||||
|
||||
/// The current absolution position in steps.
|
||||
long _currentPos; // Steps
|
||||
|
||||
/// The target position in steps. The AccelStepper_MCP23017_Soft library will move the
|
||||
/// motor from the _currentPos to the _targetPos, taking into account the
|
||||
/// max speed, acceleration and deceleration
|
||||
long _targetPos; // Steps
|
||||
|
||||
/// The current motos speed in steps per second
|
||||
/// Positive is clockwise
|
||||
float _speed; // Steps per second
|
||||
|
||||
/// The maximum permitted speed in steps per second. Must be > 0.
|
||||
float _maxSpeed;
|
||||
|
||||
/// The acceleration to use to accelerate or decelerate the motor in steps
|
||||
/// per second per second. Must be > 0
|
||||
float _acceleration;
|
||||
float _sqrt_twoa; // Precomputed sqrt(2*_acceleration)
|
||||
|
||||
/// The current interval between steps in microseconds.
|
||||
/// 0 means the motor is currently stopped with _speed == 0
|
||||
unsigned long _stepInterval;
|
||||
|
||||
/// The last step time in microseconds
|
||||
unsigned long _lastStepTime;
|
||||
|
||||
/// The minimum allowed pulse width in microseconds
|
||||
unsigned int _minPulseWidth;
|
||||
|
||||
/// Is the direction pin inverted?
|
||||
///bool _dirInverted; /// Moved to _pinInverted[1]
|
||||
|
||||
/// Is the step pin inverted?
|
||||
///bool _stepInverted; /// Moved to _pinInverted[0]
|
||||
|
||||
/// Is the enable pin inverted?
|
||||
bool _enableInverted;
|
||||
|
||||
/// Enable pin for stepper driver, or 0xFF if unused.
|
||||
uint8_t _enablePin;
|
||||
|
||||
/// The pointer to a forward-step procedure
|
||||
void (*_forward)();
|
||||
|
||||
/// The pointer to a backward-step procedure
|
||||
void (*_backward)();
|
||||
|
||||
/// The step counter for speed calculations
|
||||
long _n;
|
||||
|
||||
/// Initial step size in microseconds
|
||||
float _c0;
|
||||
|
||||
/// Last step size in microseconds
|
||||
float _cn;
|
||||
|
||||
/// Min step size in microseconds based on maxSpeed
|
||||
float _cmin; // at max speed
|
||||
|
||||
};
|
||||
|
||||
/// @example Random.pde
|
||||
/// Make a single stepper perform random changes in speed, position and acceleration
|
||||
|
||||
/// @example Overshoot.pde
|
||||
/// Check overshoot handling
|
||||
/// which sets a new target position and then waits until the stepper has
|
||||
/// achieved it. This is used for testing the handling of overshoots
|
||||
|
||||
/// @example MultipleSteppers.pde
|
||||
/// Shows how to multiple simultaneous steppers
|
||||
/// Runs one stepper forwards and backwards, accelerating and decelerating
|
||||
/// at the limits. Runs other steppers at the same time
|
||||
|
||||
/// @example ConstantSpeed.pde
|
||||
/// Shows how to run AccelStepper_MCP23017_Soft in the simplest,
|
||||
/// fixed speed mode with no accelerations
|
||||
|
||||
/// @example Blocking.pde
|
||||
/// Shows how to use the blocking call runToNewPosition
|
||||
/// Which sets a new target position and then waits until the stepper has
|
||||
/// achieved it.
|
||||
|
||||
/// @example AFMotor_MultiStepper.pde
|
||||
/// Control both Stepper motors at the same time with different speeds
|
||||
/// and accelerations.
|
||||
|
||||
/// @example AFMotor_ConstantSpeed.pde
|
||||
/// Shows how to run AccelStepper_MCP23017_Soft in the simplest,
|
||||
/// fixed speed mode with no accelerations
|
||||
|
||||
/// @example ProportionalControl.pde
|
||||
/// Make a single stepper follow the analog value read from a pot or whatever
|
||||
/// The stepper will move at a constant speed to each newly set posiiton,
|
||||
/// depending on the value of the pot.
|
||||
|
||||
/// @example Bounce.pde
|
||||
/// Make a single stepper bounce from one limit to another, observing
|
||||
/// accelrations at each end of travel
|
||||
|
||||
/// @example Quickstop.pde
|
||||
/// Check stop handling.
|
||||
/// Calls stop() while the stepper is travelling at full speed, causing
|
||||
/// the stepper to stop as quickly as possible, within the constraints of the
|
||||
/// current acceleration.
|
||||
|
||||
/// @example MotorShield.pde
|
||||
/// Shows how to use AccelStepper_MCP23017_Soft to control a 3-phase motor, such as a HDD spindle motor
|
||||
/// using the Adafruit Motor Shield http://www.ladyada.net/make/mshield/index.html.
|
||||
|
||||
/// @example DualMotorShield.pde
|
||||
/// Shows how to use AccelStepper_MCP23017_Soft to control 2 x 2 phase steppers using the
|
||||
/// Itead Studio Arduino Dual Stepper Motor Driver Shield
|
||||
/// model IM120417015
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,73 @@
|
||||
// MultiStepper_MCP23017_Soft.cpp
|
||||
//
|
||||
// Copyright (C) 2015 Mike McCauley
|
||||
// $Id: MultiStepper_MCP23017_Soft.cpp,v 1.2 2015/10/04 05:16:38 mikem Exp $
|
||||
|
||||
#include "MultiStepper_MCP23017_Soft.h"
|
||||
#include "AccelStepper_MCP23017_Soft.h"
|
||||
|
||||
MultiStepper_MCP23017_Soft::MultiStepper_MCP23017_Soft()
|
||||
: _num_steppers(0)
|
||||
{
|
||||
}
|
||||
|
||||
boolean MultiStepper_MCP23017_Soft::addStepper(AccelStepper_MCP23017_Soft& stepper)
|
||||
{
|
||||
if (_num_steppers >= MULTISTEPPER_MAX_STEPPERS)
|
||||
return false; // No room for more
|
||||
_steppers[_num_steppers++] = &stepper;
|
||||
return true;
|
||||
}
|
||||
|
||||
void MultiStepper_MCP23017_Soft::moveTo(long absolute[])
|
||||
{
|
||||
// First find the stepper that will take the longest time to move
|
||||
float longestTime = 0.0;
|
||||
|
||||
uint8_t i;
|
||||
for (i = 0; i < _num_steppers; i++)
|
||||
{
|
||||
long thisDistance = absolute[i] - _steppers[i]->currentPosition();
|
||||
float thisTime = abs(thisDistance) / _steppers[i]->maxSpeed();
|
||||
|
||||
if (thisTime > longestTime)
|
||||
longestTime = thisTime;
|
||||
}
|
||||
|
||||
if (longestTime > 0.0)
|
||||
{
|
||||
// Now work out a new max speed for each stepper so they will all
|
||||
// arrived at the same time of longestTime
|
||||
for (i = 0; i < _num_steppers; i++)
|
||||
{
|
||||
long thisDistance = absolute[i] - _steppers[i]->currentPosition();
|
||||
float thisSpeed = thisDistance / longestTime;
|
||||
_steppers[i]->moveTo(absolute[i]); // New target position (resets speed)
|
||||
_steppers[i]->setSpeed(thisSpeed); // New speed
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Returns true if any motor is still running to the target position.
|
||||
boolean MultiStepper_MCP23017_Soft::run()
|
||||
{
|
||||
uint8_t i;
|
||||
boolean ret = false;
|
||||
for (i = 0; i < _num_steppers; i++)
|
||||
{
|
||||
if ( _steppers[i]->distanceToGo() != 0)
|
||||
{
|
||||
_steppers[i]->runSpeed();
|
||||
ret = true;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Blocks until all steppers reach their target position and are stopped
|
||||
void MultiStepper_MCP23017_Soft::runSpeedToPosition()
|
||||
{
|
||||
while (run())
|
||||
;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,78 @@
|
||||
// MultiStepper_MCP23017_Soft.h
|
||||
|
||||
#ifndef MultiStepper_MCP23017_Soft_h
|
||||
#define MultiStepper_MCP23017_Soft_h
|
||||
|
||||
#include <stdlib.h>
|
||||
#if ARDUINO >= 100
|
||||
#include <Arduino.h>
|
||||
#else
|
||||
#include <WProgram.h>
|
||||
#include <wiring.h>
|
||||
#endif
|
||||
|
||||
#define MULTISTEPPER_MAX_STEPPERS 10
|
||||
|
||||
class AccelStepper_MCP23017_Soft;
|
||||
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
/// \class MultiStepper_MCP23017_Soft MultiStepper_MCP23017_Soft.h <MultiStepper_MCP23017_Soft.h>
|
||||
/// \brief Operate multiple AccelStepper_MCP23017_Softs in a co-ordinated fashion
|
||||
///
|
||||
/// This class can manage multiple AccelStepper_MCP23017_Softs (up to MULTISTEPPER_MAX_STEPPERS = 10),
|
||||
/// and cause them all to move
|
||||
/// to selected positions at such a (constant) speed that they all arrive at their
|
||||
/// target position at the same time. This can be used to support devices with multiple steppers
|
||||
/// on say multiple axes to cause linear diagonal motion. Suitable for use with X-Y plotters, flatbeds,
|
||||
/// 3D printers etc
|
||||
/// to get linear straight line movement between arbitrary 2d (or 3d or ...) positions.
|
||||
///
|
||||
/// Caution: only constant speed stepper motion is supported: acceleration and deceleration is not supported
|
||||
/// All the steppers managed by MultiStepper_MCP23017_Soft will step at a constant speed to their
|
||||
/// target (albeit perhaps different speeds for each stepper).
|
||||
class MultiStepper_MCP23017_Soft
|
||||
{
|
||||
public:
|
||||
/// Constructor
|
||||
MultiStepper_MCP23017_Soft();
|
||||
|
||||
/// Add a stepper to the set of managed steppers
|
||||
/// There is an upper limit of MULTISTEPPER_MAX_STEPPERS = 10 to the number of steppers that can be managed
|
||||
/// \param[in] stepper Reference to a stepper to add to the managed list
|
||||
/// \return true if successful. false if the number of managed steppers would exceed MULTISTEPPER_MAX_STEPPERS
|
||||
boolean addStepper(AccelStepper_MCP23017_Soft& stepper);
|
||||
|
||||
/// Set the target positions of all managed steppers
|
||||
/// according to a coordinate array.
|
||||
/// New speeds will be computed for each stepper so they will all arrive at their
|
||||
/// respective targets at very close to the same time.
|
||||
/// \param[in] absolute An array of desired absolute stepper positions. absolute[0] will be used to set
|
||||
/// the absolute position of the first stepper added by addStepper() etc. The array must be at least as long as
|
||||
/// the number of steppers that have been added by addStepper, else results are undefined.
|
||||
void moveTo(long absolute[]);
|
||||
|
||||
/// Calls runSpeed() on all the managed steppers
|
||||
/// that have not acheived their target position.
|
||||
/// \return true if any stepper is still in the process of running to its target position.
|
||||
boolean run();
|
||||
|
||||
/// Runs all managed steppers until they acheived their target position.
|
||||
/// Blocks until all that position is acheived. If you dont
|
||||
/// want blocking consider using run() instead.
|
||||
void runSpeedToPosition();
|
||||
|
||||
private:
|
||||
/// Array of pointers to the steppers we are controlling.
|
||||
/// Fills from 0 onwards
|
||||
AccelStepper_MCP23017_Soft* _steppers[MULTISTEPPER_MAX_STEPPERS];
|
||||
|
||||
/// Number of steppers we are controlling and the number
|
||||
/// of steppers in _steppers[]
|
||||
uint8_t _num_steppers;
|
||||
};
|
||||
|
||||
/// @example MultiStepper_MCP23017_Soft.pde
|
||||
/// Use MultiStepper_MCP23017_Soft class to manage multiple steppers and make them all move to
|
||||
/// the same position at the same time for linear 2d (or 3d) motion.
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,625 @@
|
||||
// AccelStepper_PCF8574.cpp
|
||||
//
|
||||
// Copyright (C) 2009-2013 Mike McCauley
|
||||
// $Id: AccelStepper_PCF8574.cpp,v 1.23 2016/08/09 00:39:10 mikem Exp $
|
||||
#include <Wire.h>
|
||||
#include "PCF8574.h"
|
||||
#include "AccelStepper_PCF8574.h"
|
||||
|
||||
#if 0
|
||||
// Some debugging assistance
|
||||
void dump(uint8_t* p, int l)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < l; i++)
|
||||
{
|
||||
Serial.print(p[i], HEX);
|
||||
Serial.print(" ");
|
||||
}
|
||||
Serial.println("");
|
||||
}
|
||||
#endif
|
||||
|
||||
void AccelStepper_PCF8574::moveTo(long absolute)
|
||||
{
|
||||
if (_targetPos != absolute)
|
||||
{
|
||||
_targetPos = absolute;
|
||||
computeNewSpeed();
|
||||
// compute new n?
|
||||
}
|
||||
}
|
||||
|
||||
void AccelStepper_PCF8574::move(long relative)
|
||||
{
|
||||
moveTo(_currentPos + relative);
|
||||
}
|
||||
|
||||
// Implements steps according to the current step interval
|
||||
// You must call this at least once per step
|
||||
// returns true if a step occurred
|
||||
boolean AccelStepper_PCF8574::runSpeed()
|
||||
{
|
||||
// Dont do anything unless we actually have a step interval
|
||||
if (!_stepInterval)
|
||||
return false;
|
||||
|
||||
unsigned long time = micros();
|
||||
if (time - _lastStepTime >= _stepInterval)
|
||||
{
|
||||
if (_direction == DIRECTION_CW)
|
||||
{
|
||||
// Clockwise
|
||||
_currentPos += 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Anticlockwise
|
||||
_currentPos -= 1;
|
||||
}
|
||||
step(_currentPos);
|
||||
|
||||
_lastStepTime = time; // Caution: does not account for costs in step()
|
||||
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
long AccelStepper_PCF8574::distanceToGo()
|
||||
{
|
||||
return _targetPos - _currentPos;
|
||||
}
|
||||
|
||||
long AccelStepper_PCF8574::targetPosition()
|
||||
{
|
||||
return _targetPos;
|
||||
}
|
||||
|
||||
long AccelStepper_PCF8574::currentPosition()
|
||||
{
|
||||
return _currentPos;
|
||||
}
|
||||
|
||||
// Useful during initialisations or after initial positioning
|
||||
// Sets speed to 0
|
||||
void AccelStepper_PCF8574::setCurrentPosition(long position)
|
||||
{
|
||||
_targetPos = _currentPos = position;
|
||||
_n = 0;
|
||||
_stepInterval = 0;
|
||||
_speed = 0.0;
|
||||
}
|
||||
|
||||
void AccelStepper_PCF8574::computeNewSpeed()
|
||||
{
|
||||
long distanceTo = distanceToGo(); // +ve is clockwise from curent location
|
||||
|
||||
long stepsToStop = (long)((_speed * _speed) / (2.0 * _acceleration)); // Equation 16
|
||||
|
||||
if (distanceTo == 0 && stepsToStop <= 1)
|
||||
{
|
||||
// We are at the target and its time to stop
|
||||
_stepInterval = 0;
|
||||
_speed = 0.0;
|
||||
_n = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
if (distanceTo > 0)
|
||||
{
|
||||
// We are anticlockwise from the target
|
||||
// Need to go clockwise from here, maybe decelerate now
|
||||
if (_n > 0)
|
||||
{
|
||||
// Currently accelerating, need to decel now? Or maybe going the wrong way?
|
||||
if ((stepsToStop >= distanceTo) || _direction == DIRECTION_CCW)
|
||||
_n = -stepsToStop; // Start deceleration
|
||||
}
|
||||
else if (_n < 0)
|
||||
{
|
||||
// Currently decelerating, need to accel again?
|
||||
if ((stepsToStop < distanceTo) && _direction == DIRECTION_CW)
|
||||
_n = -_n; // Start accceleration
|
||||
}
|
||||
}
|
||||
else if (distanceTo < 0)
|
||||
{
|
||||
// We are clockwise from the target
|
||||
// Need to go anticlockwise from here, maybe decelerate
|
||||
if (_n > 0)
|
||||
{
|
||||
// Currently accelerating, need to decel now? Or maybe going the wrong way?
|
||||
if ((stepsToStop >= -distanceTo) || _direction == DIRECTION_CW)
|
||||
_n = -stepsToStop; // Start deceleration
|
||||
}
|
||||
else if (_n < 0)
|
||||
{
|
||||
// Currently decelerating, need to accel again?
|
||||
if ((stepsToStop < -distanceTo) && _direction == DIRECTION_CCW)
|
||||
_n = -_n; // Start accceleration
|
||||
}
|
||||
}
|
||||
|
||||
// Need to accelerate or decelerate
|
||||
if (_n == 0)
|
||||
{
|
||||
// First step from stopped
|
||||
_cn = _c0;
|
||||
_direction = (distanceTo > 0) ? DIRECTION_CW : DIRECTION_CCW;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Subsequent step. Works for accel (n is +_ve) and decel (n is -ve).
|
||||
_cn = _cn - ((2.0 * _cn) / ((4.0 * _n) + 1)); // Equation 13
|
||||
_cn = max(_cn, _cmin);
|
||||
}
|
||||
_n++;
|
||||
_stepInterval = _cn;
|
||||
_speed = 1000000.0 / _cn;
|
||||
if (_direction == DIRECTION_CCW)
|
||||
_speed = -_speed;
|
||||
|
||||
#if 0
|
||||
Serial.println(_speed);
|
||||
Serial.println(_acceleration);
|
||||
Serial.println(_cn);
|
||||
Serial.println(_c0);
|
||||
Serial.println(_n);
|
||||
Serial.println(_stepInterval);
|
||||
Serial.println(distanceTo);
|
||||
Serial.println(stepsToStop);
|
||||
Serial.println("-----");
|
||||
#endif
|
||||
}
|
||||
|
||||
// Run the motor to implement speed and acceleration in order to proceed to the target position
|
||||
// You must call this at least once per step, preferably in your main loop
|
||||
// If the motor is in the desired position, the cost is very small
|
||||
// returns true if the motor is still running to the target position.
|
||||
boolean AccelStepper_PCF8574::run()
|
||||
{
|
||||
if (runSpeed())
|
||||
computeNewSpeed();
|
||||
return _speed != 0.0 || distanceToGo() != 0;
|
||||
}
|
||||
|
||||
AccelStepper_PCF8574::AccelStepper_PCF8574(PCF8574 *device, uint8_t interface, uint8_t pin1, uint8_t pin2, uint8_t pin3, uint8_t pin4, bool enable)
|
||||
{
|
||||
_device = device;
|
||||
//_device->begin(0x20);
|
||||
//_device->pinMode(pin1, OUTPUT);
|
||||
//_device->pinMode(pin2, OUTPUT);
|
||||
//_device->pinMode(pin3, OUTPUT);
|
||||
//_device->pinMode(pin4, OUTPUT);
|
||||
_interface = interface;
|
||||
_currentPos = 0;
|
||||
_targetPos = 0;
|
||||
_speed = 0.0;
|
||||
_maxSpeed = 1.0;
|
||||
_acceleration = 0.0;
|
||||
_sqrt_twoa = 1.0;
|
||||
_stepInterval = 0;
|
||||
_minPulseWidth = 1;
|
||||
_enablePin = 0xff;
|
||||
_lastStepTime = 0;
|
||||
_pin[0] = pin1;
|
||||
_pin[1] = pin2;
|
||||
_pin[2] = pin3;
|
||||
_pin[3] = pin4;
|
||||
_enableInverted = false;
|
||||
|
||||
// NEW
|
||||
_n = 0;
|
||||
_c0 = 0.0;
|
||||
_cn = 0.0;
|
||||
_cmin = 1.0;
|
||||
_direction = DIRECTION_CCW;
|
||||
|
||||
int i;
|
||||
for (i = 0; i < 4; i++)
|
||||
_pinInverted[i] = 0;
|
||||
if (enable)
|
||||
enableOutputs();
|
||||
// Some reasonable default
|
||||
setAcceleration(1);
|
||||
}
|
||||
|
||||
void AccelStepper_PCF8574::setMaxSpeed(float speed)
|
||||
{
|
||||
if (speed < 0.0)
|
||||
speed = -speed;
|
||||
if (_maxSpeed != speed)
|
||||
{
|
||||
_maxSpeed = speed;
|
||||
_cmin = 1000000.0 / speed;
|
||||
// Recompute _n from current speed and adjust speed if accelerating or cruising
|
||||
if (_n > 0)
|
||||
{
|
||||
_n = (long)((_speed * _speed) / (2.0 * _acceleration)); // Equation 16
|
||||
computeNewSpeed();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
float AccelStepper_PCF8574::maxSpeed()
|
||||
{
|
||||
return _maxSpeed;
|
||||
}
|
||||
|
||||
void AccelStepper_PCF8574::setAcceleration(float acceleration)
|
||||
{
|
||||
if (acceleration == 0.0)
|
||||
return;
|
||||
if (acceleration < 0.0)
|
||||
acceleration = -acceleration;
|
||||
if (_acceleration != acceleration)
|
||||
{
|
||||
// Recompute _n per Equation 17
|
||||
_n = _n * (_acceleration / acceleration);
|
||||
// New c0 per Equation 7, with correction per Equation 15
|
||||
_c0 = 0.676 * sqrt(2.0 / acceleration) * 1000000.0; // Equation 15
|
||||
_acceleration = acceleration;
|
||||
computeNewSpeed();
|
||||
}
|
||||
}
|
||||
|
||||
void AccelStepper_PCF8574::setSpeed(float speed)
|
||||
{
|
||||
if (speed == _speed)
|
||||
return;
|
||||
speed = constrain(speed, -_maxSpeed, _maxSpeed);
|
||||
if (speed == 0.0)
|
||||
_stepInterval = 0;
|
||||
else
|
||||
{
|
||||
_stepInterval = fabs(1000000.0 / speed);
|
||||
_direction = (speed > 0.0) ? DIRECTION_CW : DIRECTION_CCW;
|
||||
}
|
||||
_speed = speed;
|
||||
}
|
||||
|
||||
float AccelStepper_PCF8574::speed()
|
||||
{
|
||||
return _speed;
|
||||
}
|
||||
|
||||
// Subclasses can override
|
||||
void AccelStepper_PCF8574::step(long step)
|
||||
{
|
||||
switch (_interface)
|
||||
{
|
||||
case FUNCTION:
|
||||
step0(step);
|
||||
break;
|
||||
|
||||
case DRIVER:
|
||||
step1(step);
|
||||
break;
|
||||
|
||||
case FULL2WIRE:
|
||||
step2(step);
|
||||
break;
|
||||
|
||||
case FULL3WIRE:
|
||||
step3(step);
|
||||
break;
|
||||
|
||||
case FULL4WIRE:
|
||||
step4(step);
|
||||
break;
|
||||
|
||||
case HALF3WIRE:
|
||||
step6(step);
|
||||
break;
|
||||
|
||||
case HALF4WIRE:
|
||||
step8(step);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// You might want to override this to implement eg serial output
|
||||
// bit 0 of the mask corresponds to _pin[0]
|
||||
// bit 1 of the mask corresponds to _pin[1]
|
||||
// ....
|
||||
void AccelStepper_PCF8574::setOutputPins(uint8_t mask)
|
||||
{
|
||||
uint8_t numpins = 2;
|
||||
if (_interface == FULL4WIRE || _interface == HALF4WIRE)
|
||||
numpins = 4;
|
||||
else if (_interface == FULL3WIRE || _interface == HALF3WIRE)
|
||||
numpins = 3;
|
||||
uint8_t i;
|
||||
for (i = 0; i < numpins; i++)
|
||||
_device->digitalWrite(_pin[i], (mask & (1 << i)) ? (HIGH ^ _pinInverted[i]) : (LOW ^ _pinInverted[i]));
|
||||
}
|
||||
|
||||
// 0 pin step function (ie for functional usage)
|
||||
void AccelStepper_PCF8574::step0(long step)
|
||||
{
|
||||
(void)(step); // Unused
|
||||
if (_speed > 0)
|
||||
_forward();
|
||||
else
|
||||
_backward();
|
||||
}
|
||||
|
||||
// 1 pin step function (ie for stepper drivers)
|
||||
// This is passed the current step number (0 to 7)
|
||||
// Subclasses can override
|
||||
void AccelStepper_PCF8574::step1(long step)
|
||||
{
|
||||
(void)(step); // Unused
|
||||
|
||||
// _pin[0] is step, _pin[1] is direction
|
||||
setOutputPins(_direction ? 0b10 : 0b00); // Set direction first else get rogue pulses
|
||||
setOutputPins(_direction ? 0b11 : 0b01); // step HIGH
|
||||
// Caution 200ns setup time
|
||||
// Delay the minimum allowed pulse width
|
||||
delayMicroseconds(_minPulseWidth);
|
||||
setOutputPins(_direction ? 0b10 : 0b00); // step LOW
|
||||
}
|
||||
|
||||
|
||||
// 2 pin step function
|
||||
// This is passed the current step number (0 to 7)
|
||||
// Subclasses can override
|
||||
void AccelStepper_PCF8574::step2(long step)
|
||||
{
|
||||
switch (step & 0x3)
|
||||
{
|
||||
case 0: /* 01 */
|
||||
setOutputPins(0b10);
|
||||
break;
|
||||
|
||||
case 1: /* 11 */
|
||||
setOutputPins(0b11);
|
||||
break;
|
||||
|
||||
case 2: /* 10 */
|
||||
setOutputPins(0b01);
|
||||
break;
|
||||
|
||||
case 3: /* 00 */
|
||||
setOutputPins(0b00);
|
||||
break;
|
||||
}
|
||||
}
|
||||
// 3 pin step function
|
||||
// This is passed the current step number (0 to 7)
|
||||
// Subclasses can override
|
||||
void AccelStepper_PCF8574::step3(long step)
|
||||
{
|
||||
switch (step % 3)
|
||||
{
|
||||
case 0: // 100
|
||||
setOutputPins(0b100);
|
||||
break;
|
||||
|
||||
case 1: // 001
|
||||
setOutputPins(0b001);
|
||||
break;
|
||||
|
||||
case 2: //010
|
||||
setOutputPins(0b010);
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// 4 pin step function for half stepper
|
||||
// This is passed the current step number (0 to 7)
|
||||
// Subclasses can override
|
||||
void AccelStepper_PCF8574::step4(long step)
|
||||
{
|
||||
switch (step & 0x3)
|
||||
{
|
||||
case 0: // 1010
|
||||
setOutputPins(0b0101);
|
||||
break;
|
||||
|
||||
case 1: // 0110
|
||||
setOutputPins(0b0110);
|
||||
break;
|
||||
|
||||
case 2: //0101
|
||||
setOutputPins(0b1010);
|
||||
break;
|
||||
|
||||
case 3: //1001
|
||||
setOutputPins(0b1001);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// 3 pin half step function
|
||||
// This is passed the current step number (0 to 7)
|
||||
// Subclasses can override
|
||||
void AccelStepper_PCF8574::step6(long step)
|
||||
{
|
||||
switch (step % 6)
|
||||
{
|
||||
case 0: // 100
|
||||
setOutputPins(0b100);
|
||||
break;
|
||||
|
||||
case 1: // 101
|
||||
setOutputPins(0b101);
|
||||
break;
|
||||
|
||||
case 2: // 001
|
||||
setOutputPins(0b001);
|
||||
break;
|
||||
|
||||
case 3: // 011
|
||||
setOutputPins(0b011);
|
||||
break;
|
||||
|
||||
case 4: // 010
|
||||
setOutputPins(0b010);
|
||||
break;
|
||||
|
||||
case 5: // 011
|
||||
setOutputPins(0b110);
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// 4 pin half step function
|
||||
// This is passed the current step number (0 to 7)
|
||||
// Subclasses can override
|
||||
void AccelStepper_PCF8574::step8(long step)
|
||||
{
|
||||
switch (step & 0x7)
|
||||
{
|
||||
case 0: // 1000
|
||||
setOutputPins(0b0001);
|
||||
break;
|
||||
|
||||
case 1: // 1010
|
||||
setOutputPins(0b0101);
|
||||
break;
|
||||
|
||||
case 2: // 0010
|
||||
setOutputPins(0b0100);
|
||||
break;
|
||||
|
||||
case 3: // 0110
|
||||
setOutputPins(0b0110);
|
||||
break;
|
||||
|
||||
case 4: // 0100
|
||||
setOutputPins(0b0010);
|
||||
break;
|
||||
|
||||
case 5: //0101
|
||||
setOutputPins(0b1010);
|
||||
break;
|
||||
|
||||
case 6: // 0001
|
||||
setOutputPins(0b1000);
|
||||
break;
|
||||
|
||||
case 7: //1001
|
||||
setOutputPins(0b1001);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Prevents power consumption on the outputs
|
||||
void AccelStepper_PCF8574::disableOutputs()
|
||||
{
|
||||
if (! _interface) return;
|
||||
|
||||
setOutputPins(0); // Handles inversion automatically
|
||||
if (_enablePin != 0xff)
|
||||
{
|
||||
//_device->pinMode(_enablePin, OUTPUT);
|
||||
_device->digitalWrite(_enablePin, LOW ^ _enableInverted);
|
||||
}
|
||||
}
|
||||
|
||||
void AccelStepper_PCF8574::enableOutputs()
|
||||
{
|
||||
if (! _interface)
|
||||
return;
|
||||
|
||||
//_device->pinMode(_pin[0], OUTPUT);
|
||||
//_device->pinMode(_pin[1], OUTPUT);
|
||||
//if (_interface == FULL4WIRE || _interface == HALF4WIRE)
|
||||
//{
|
||||
// _device->pinMode(_pin[2], OUTPUT);
|
||||
// _device->pinMode(_pin[3], OUTPUT);
|
||||
//}
|
||||
//else if (_interface == FULL3WIRE || _interface == HALF3WIRE)
|
||||
//{
|
||||
// _device->pinMode(_pin[2], OUTPUT);
|
||||
//}
|
||||
|
||||
if (_enablePin != 0xff)
|
||||
{
|
||||
//_device->pinMode(_enablePin, OUTPUT);
|
||||
_device->digitalWrite(_enablePin, HIGH ^ _enableInverted);
|
||||
}
|
||||
}
|
||||
|
||||
void AccelStepper_PCF8574::setMinPulseWidth(unsigned int minWidth)
|
||||
{
|
||||
_minPulseWidth = minWidth;
|
||||
}
|
||||
|
||||
void AccelStepper_PCF8574::setEnablePin(uint8_t enablePin)
|
||||
{
|
||||
_enablePin = enablePin;
|
||||
|
||||
// This happens after construction, so init pin now.
|
||||
if (_enablePin != 0xff)
|
||||
{
|
||||
//_device->pinMode(_enablePin, OUTPUT);
|
||||
_device->digitalWrite(_enablePin, HIGH ^ _enableInverted);
|
||||
}
|
||||
}
|
||||
|
||||
void AccelStepper_PCF8574::setPinsInverted(bool directionInvert, bool stepInvert, bool enableInvert)
|
||||
{
|
||||
_pinInverted[0] = stepInvert;
|
||||
_pinInverted[1] = directionInvert;
|
||||
_enableInverted = enableInvert;
|
||||
}
|
||||
|
||||
void AccelStepper_PCF8574::setPinsInverted(bool pin1Invert, bool pin2Invert, bool pin3Invert, bool pin4Invert, bool enableInvert)
|
||||
{
|
||||
_pinInverted[0] = pin1Invert;
|
||||
_pinInverted[1] = pin2Invert;
|
||||
_pinInverted[2] = pin3Invert;
|
||||
_pinInverted[3] = pin4Invert;
|
||||
_enableInverted = enableInvert;
|
||||
}
|
||||
|
||||
// Blocks until the target position is reached and stopped
|
||||
void AccelStepper_PCF8574::runToPosition()
|
||||
{
|
||||
while (run())
|
||||
;
|
||||
}
|
||||
|
||||
boolean AccelStepper_PCF8574::runSpeedToPosition()
|
||||
{
|
||||
if (_targetPos == _currentPos)
|
||||
return false;
|
||||
if (_targetPos >_currentPos)
|
||||
_direction = DIRECTION_CW;
|
||||
else
|
||||
_direction = DIRECTION_CCW;
|
||||
return runSpeed();
|
||||
}
|
||||
|
||||
// Blocks until the new target position is reached
|
||||
void AccelStepper_PCF8574::runToNewPosition(long position)
|
||||
{
|
||||
moveTo(position);
|
||||
runToPosition();
|
||||
}
|
||||
|
||||
void AccelStepper_PCF8574::stop()
|
||||
{
|
||||
if (_speed != 0.0)
|
||||
{
|
||||
long stepsToStop = (long)((_speed * _speed) / (2.0 * _acceleration)) + 1; // Equation 16 (+integer rounding)
|
||||
if (_speed > 0)
|
||||
move(stepsToStop);
|
||||
else
|
||||
move(-stepsToStop);
|
||||
}
|
||||
}
|
||||
|
||||
bool AccelStepper_PCF8574::isRunning()
|
||||
{
|
||||
return !(_speed == 0.0 && _targetPos == _currentPos);
|
||||
}
|
||||
@@ -0,0 +1,735 @@
|
||||
// AccelStepper_PCF8574.h
|
||||
//
|
||||
/// \mainpage AccelStepper_PCF8574 library for Arduino
|
||||
///
|
||||
/// This is the Arduino AccelStepper_PCF8574 library.
|
||||
/// It provides an object-oriented interface for 2, 3 or 4 pin stepper motors and motor drivers.
|
||||
///
|
||||
/// The standard Arduino IDE includes the Stepper library
|
||||
/// (http://arduino.cc/en/Reference/Stepper) for stepper motors. It is
|
||||
/// perfectly adequate for simple, single motor applications.
|
||||
///
|
||||
/// AccelStepper_PCF8574 significantly improves on the standard Arduino Stepper library in several ways:
|
||||
/// \li Supports acceleration and deceleration
|
||||
/// \li Supports multiple simultaneous steppers, with independent concurrent stepping on each stepper
|
||||
/// \li API functions never delay() or block
|
||||
/// \li Supports 2, 3 and 4 wire steppers, plus 3 and 4 wire half steppers.
|
||||
/// \li Supports alternate stepping functions to enable support of AFMotor (https://github.com/adafruit/Adafruit-Motor-Shield-library)
|
||||
/// \li Supports stepper drivers such as the Sparkfun EasyDriver (based on 3967 driver chip)
|
||||
/// \li Very slow speeds are supported
|
||||
/// \li Extensive API
|
||||
/// \li Subclass support
|
||||
///
|
||||
/// The latest version of this documentation can be downloaded from
|
||||
/// http://www.airspayce.com/mikem/arduino/AccelStepper_PCF8574
|
||||
/// The version of the package that this documentation refers to can be downloaded
|
||||
/// from http://www.airspayce.com/mikem/arduino/AccelStepper_PCF8574/AccelStepper_PCF8574-1.59.zip
|
||||
///
|
||||
/// Example Arduino programs are included to show the main modes of use.
|
||||
///
|
||||
/// You can also find online help and discussion at http://groups.google.com/group/accelstepper
|
||||
/// Please use that group for all questions and discussions on this topic.
|
||||
/// Do not contact the author directly, unless it is to discuss commercial licensing.
|
||||
/// Before asking a question or reporting a bug, please read
|
||||
/// - http://en.wikipedia.org/wiki/Wikipedia:Reference_desk/How_to_ask_a_software_question
|
||||
/// - http://www.catb.org/esr/faqs/smart-questions.html
|
||||
/// - http://www.chiark.greenend.org.uk/~shgtatham/bugs.html
|
||||
///
|
||||
/// Tested on Arduino Diecimila and Mega with arduino-0018 & arduino-0021
|
||||
/// on OpenSuSE 11.1 and avr-libc-1.6.1-1.15,
|
||||
/// cross-avr-binutils-2.19-9.1, cross-avr-gcc-4.1.3_20080612-26.5.
|
||||
/// Tested on Teensy http://www.pjrc.com/teensy including Teensy 3.1 built using Arduino IDE 1.0.5 with
|
||||
/// teensyduino addon 1.18 and later.
|
||||
///
|
||||
/// \par Installation
|
||||
///
|
||||
/// Install in the usual way: unzip the distribution zip file to the libraries
|
||||
/// sub-folder of your sketchbook.
|
||||
///
|
||||
/// \par Theory
|
||||
///
|
||||
/// This code uses speed calculations as described in
|
||||
/// "Generate stepper-motor speed profiles in real time" by David Austin
|
||||
/// http://fab.cba.mit.edu/classes/MIT/961.09/projects/i0/Stepper_Motor_Speed_Profile.pdf or
|
||||
/// http://www.embedded.com/design/mcus-processors-and-socs/4006438/Generate-stepper-motor-speed-profiles-in-real-time or
|
||||
/// http://web.archive.org/web/20140705143928/http://fab.cba.mit.edu/classes/MIT/961.09/projects/i0/Stepper_Motor_Speed_Profile.pdf
|
||||
/// with the exception that AccelStepper_PCF8574 uses steps per second rather than radians per second
|
||||
/// (because we dont know the step angle of the motor)
|
||||
/// An initial step interval is calculated for the first step, based on the desired acceleration
|
||||
/// On subsequent steps, shorter step intervals are calculated based
|
||||
/// on the previous step until max speed is achieved.
|
||||
///
|
||||
/// \par Adafruit Motor Shield V2
|
||||
///
|
||||
/// The included examples AFMotor_* are for Adafruit Motor Shield V1 and do not work with Adafruit Motor Shield V2.
|
||||
/// See https://github.com/adafruit/Adafruit_Motor_Shield_V2_Library for examples that work with Adafruit Motor Shield V2.
|
||||
///
|
||||
/// \par Donations
|
||||
///
|
||||
/// This library is offered under a free GPL license for those who want to use it that way.
|
||||
/// We try hard to keep it up to date, fix bugs
|
||||
/// and to provide free support. If this library has helped you save time or money, please consider donating at
|
||||
/// http://www.airspayce.com or here:
|
||||
///
|
||||
/// \htmlonly <form action="https://www.paypal.com/cgi-bin/webscr" method="post"><input type="hidden" name="cmd" value="_donations" /> <input type="hidden" name="business" value="mikem@airspayce.com" /> <input type="hidden" name="lc" value="AU" /> <input type="hidden" name="item_name" value="Airspayce" /> <input type="hidden" name="item_number" value="AccelStepper_PCF8574" /> <input type="hidden" name="currency_code" value="USD" /> <input type="hidden" name="bn" value="PP-DonationsBF:btn_donateCC_LG.gif:NonHosted" /> <input type="image" alt="PayPal — The safer, easier way to pay online." name="submit" src="https://www.paypalobjects.com/en_AU/i/btn/btn_donateCC_LG.gif" /> <img alt="" src="https://www.paypalobjects.com/en_AU/i/scr/pixel.gif" width="1" height="1" border="0" /></form> \endhtmlonly
|
||||
///
|
||||
/// \par Trademarks
|
||||
///
|
||||
/// AccelStepper_PCF8574 is a trademark of AirSpayce Pty Ltd. The AccelStepper_PCF8574 mark was first used on April 26 2010 for
|
||||
/// international trade, and is used only in relation to motor control hardware and software.
|
||||
/// It is not to be confused with any other similar marks covering other goods and services.
|
||||
///
|
||||
/// \par Copyright
|
||||
///
|
||||
/// This software is Copyright (C) 2010-2018 Mike McCauley. Use is subject to license
|
||||
/// conditions. The main licensing options available are GPL V2 or Commercial:
|
||||
///
|
||||
/// \par Open Source Licensing GPL V2
|
||||
/// This is the appropriate option if you want to share the source code of your
|
||||
/// application with everyone you distribute it to, and you also want to give them
|
||||
/// the right to share who uses it. If you wish to use this software under Open
|
||||
/// Source Licensing, you must contribute all your source code to the open source
|
||||
/// community in accordance with the GPL Version 2 when your application is
|
||||
/// distributed. See https://www.gnu.org/licenses/gpl-2.0.html
|
||||
///
|
||||
/// \par Commercial Licensing
|
||||
/// This is the appropriate option if you are creating proprietary applications
|
||||
/// and you are not prepared to distribute and share the source code of your
|
||||
/// application. To purchase a commercial license, contact info@airspayce.com
|
||||
///
|
||||
/// \par Revision History
|
||||
/// \version 1.0 Initial release
|
||||
///
|
||||
/// \version 1.1 Added speed() function to get the current speed.
|
||||
/// \version 1.2 Added runSpeedToPosition() submitted by Gunnar Arndt.
|
||||
/// \version 1.3 Added support for stepper drivers (ie with Step and Direction inputs) with _pins == 1
|
||||
/// \version 1.4 Added functional contructor to support AFMotor, contributed by Limor, with example sketches.
|
||||
/// \version 1.5 Improvements contributed by Peter Mousley: Use of microsecond steps and other speed improvements
|
||||
/// to increase max stepping speed to about 4kHz. New option for user to set the min allowed pulse width.
|
||||
/// Added checks for already running at max speed and skip further calcs if so.
|
||||
/// \version 1.6 Fixed a problem with wrapping of microsecond stepping that could cause stepping to hang.
|
||||
/// Reported by Sandy Noble.
|
||||
/// Removed redundant _lastRunTime member.
|
||||
/// \version 1.7 Fixed a bug where setCurrentPosition() did not always work as expected.
|
||||
/// Reported by Peter Linhart.
|
||||
/// \version 1.8 Added support for 4 pin half-steppers, requested by Harvey Moon
|
||||
/// \version 1.9 setCurrentPosition() now also sets motor speed to 0.
|
||||
/// \version 1.10 Builds on Arduino 1.0
|
||||
/// \version 1.11 Improvments from Michael Ellison:
|
||||
/// Added optional enable line support for stepper drivers
|
||||
/// Added inversion for step/direction/enable lines for stepper drivers
|
||||
/// \version 1.12 Announce Google Group
|
||||
/// \version 1.13 Improvements to speed calculation. Cost of calculation is now less in the worst case,
|
||||
/// and more or less constant in all cases. This should result in slightly beter high speed performance, and
|
||||
/// reduce anomalous speed glitches when other steppers are accelerating.
|
||||
/// However, its hard to see how to replace the sqrt() required at the very first step from 0 speed.
|
||||
/// \version 1.14 Fixed a problem with compiling under arduino 0021 reported by EmbeddedMan
|
||||
/// \version 1.15 Fixed a problem with runSpeedToPosition which did not correctly handle
|
||||
/// running backwards to a smaller target position. Added examples
|
||||
/// \version 1.16 Fixed some cases in the code where abs() was used instead of fabs().
|
||||
/// \version 1.17 Added example ProportionalControl
|
||||
/// \version 1.18 Fixed a problem: If one calls the funcion runSpeed() when Speed is zero, it makes steps
|
||||
/// without counting. reported by Friedrich, Klappenbach.
|
||||
/// \version 1.19 Added MotorInterfaceType and symbolic names for the number of pins to use
|
||||
/// for the motor interface. Updated examples to suit.
|
||||
/// Replaced individual pin assignment variables _pin1, _pin2 etc with array _pin[4].
|
||||
/// _pins member changed to _interface.
|
||||
/// Added _pinInverted array to simplify pin inversion operations.
|
||||
/// Added new function setOutputPins() which sets the motor output pins.
|
||||
/// It can be overridden in order to provide, say, serial output instead of parallel output
|
||||
/// Some refactoring and code size reduction.
|
||||
/// \version 1.20 Improved documentation and examples to show need for correctly
|
||||
/// specifying AccelStepper_PCF8574::FULL4WIRE and friends.
|
||||
/// \version 1.21 Fixed a problem where desiredSpeed could compute the wrong step acceleration
|
||||
/// when _speed was small but non-zero. Reported by Brian Schmalz.
|
||||
/// Precompute sqrt_twoa to improve performance and max possible stepping speed
|
||||
/// \version 1.22 Added Bounce.pde example
|
||||
/// Fixed a problem where calling moveTo(), setMaxSpeed(), setAcceleration() more
|
||||
/// frequently than the step time, even
|
||||
/// with the same values, would interfere with speed calcs. Now a new speed is computed
|
||||
/// only if there was a change in the set value. Reported by Brian Schmalz.
|
||||
/// \version 1.23 Rewrite of the speed algorithms in line with
|
||||
/// http://fab.cba.mit.edu/classes/MIT/961.09/projects/i0/Stepper_Motor_Speed_Profile.pdf
|
||||
/// Now expect smoother and more linear accelerations and decelerations. The desiredSpeed()
|
||||
/// function was removed.
|
||||
/// \version 1.24 Fixed a problem introduced in 1.23: with runToPosition, which did never returned
|
||||
/// \version 1.25 Now ignore attempts to set acceleration to 0.0
|
||||
/// \version 1.26 Fixed a problem where certina combinations of speed and accelration could cause
|
||||
/// oscillation about the target position.
|
||||
/// \version 1.27 Added stop() function to stop as fast as possible with current acceleration parameters.
|
||||
/// Also added new Quickstop example showing its use.
|
||||
/// \version 1.28 Fixed another problem where certain combinations of speed and acceleration could cause
|
||||
/// oscillation about the target position.
|
||||
/// Added support for 3 wire full and half steppers such as Hard Disk Drive spindle.
|
||||
/// Contributed by Yuri Ivatchkovitch.
|
||||
/// \version 1.29 Fixed a problem that could cause a DRIVER stepper to continually step
|
||||
/// with some sketches. Reported by Vadim.
|
||||
/// \version 1.30 Fixed a problem that could cause stepper to back up a few steps at the end of
|
||||
/// accelerated travel with certain speeds. Reported and patched by jolo.
|
||||
/// \version 1.31 Updated author and distribution location details to airspayce.com
|
||||
/// \version 1.32 Fixed a problem with enableOutputs() and setEnablePin on Arduino Due that
|
||||
/// prevented the enable pin changing stae correctly. Reported by Duane Bishop.
|
||||
/// \version 1.33 Fixed an error in example AFMotor_ConstantSpeed.pde did not setMaxSpeed();
|
||||
/// Fixed a problem that caused incorrect pin sequencing of FULL3WIRE and HALF3WIRE.
|
||||
/// Unfortunately this meant changing the signature for all step*() functions.
|
||||
/// Added example MotorShield, showing how to use AdaFruit Motor Shield to control
|
||||
/// a 3 phase motor such as a HDD spindle motor (and without using the AFMotor library.
|
||||
/// \version 1.34 Added setPinsInverted(bool pin1Invert, bool pin2Invert, bool pin3Invert, bool pin4Invert, bool enableInvert)
|
||||
/// to allow inversion of 2, 3 and 4 wire stepper pins. Requested by Oleg.
|
||||
/// \version 1.35 Removed default args from setPinsInverted(bool, bool, bool, bool, bool) to prevent ambiguity with
|
||||
/// setPinsInverted(bool, bool, bool). Reported by Mac Mac.
|
||||
/// \version 1.36 Changed enableOutputs() and disableOutputs() to be virtual so can be overridden.
|
||||
/// Added new optional argument 'enable' to constructor, which allows you toi disable the
|
||||
/// automatic enabling of outputs at construction time. Suggested by Guido.
|
||||
/// \version 1.37 Fixed a problem with step1 that could cause a rogue step in the
|
||||
/// wrong direction (or not,
|
||||
/// depending on the setup-time requirements of the connected hardware).
|
||||
/// Reported by Mark Tillotson.
|
||||
/// \version 1.38 run() function incorrectly always returned true. Updated function and doc so it returns true
|
||||
/// if the motor is still running to the target position.
|
||||
/// \version 1.39 Updated typos in keywords.txt, courtesey Jon Magill.
|
||||
/// \version 1.40 Updated documentation, including testing on Teensy 3.1
|
||||
/// \version 1.41 Fixed an error in the acceleration calculations, resulting in acceleration of haldf the intended value
|
||||
/// \version 1.42 Improved support for FULL3WIRE and HALF3WIRE output pins. These changes were in Yuri's original
|
||||
/// contribution but did not make it into production.<br>
|
||||
/// \version 1.43 Added DualMotorShield example. Shows how to use AccelStepper_PCF8574 to control 2 x 2 phase steppers using the
|
||||
/// Itead Studio Arduino Dual Stepper Motor Driver Shield model IM120417015.<br>
|
||||
/// \version 1.44 examples/DualMotorShield/DualMotorShield.ino examples/DualMotorShield/DualMotorShield.pde
|
||||
/// was missing from the distribution.<br>
|
||||
/// \version 1.45 Fixed a problem where if setAcceleration was not called, there was no default
|
||||
/// acceleration. Reported by Michael Newman.<br>
|
||||
/// \version 1.45 Fixed inaccuracy in acceleration rate by using Equation 15, suggested by Sebastian Gracki.<br>
|
||||
/// Performance improvements in runSpeed suggested by Jaakko Fagerlund.<br>
|
||||
/// \version 1.46 Fixed error in documentation for runToPosition().
|
||||
/// Reinstated time calculations in runSpeed() since new version is reported
|
||||
/// not to work correctly under some circumstances. Reported by Oleg V Gavva.<br>
|
||||
/// \version 1.48 2015-08-25
|
||||
/// Added new class MultiStepper that can manage multiple AccelStepper_PCF8574s,
|
||||
/// and cause them all to move
|
||||
/// to selected positions at such a (constant) speed that they all arrive at their
|
||||
/// target position at the same time. Suitable for X-Y flatbeds etc.<br>
|
||||
/// Added new method maxSpeed() to AccelStepper_PCF8574 to return the currently configured maxSpeed.<br>
|
||||
/// \version 1.49 2016-01-02
|
||||
/// Testing with VID28 series instrument stepper motors and EasyDriver.
|
||||
/// OK, although with light pointers
|
||||
/// and slow speeds like 180 full steps per second the motor movement can be erratic,
|
||||
/// probably due to some mechanical resonance. Best to accelerate through this speed.<br>
|
||||
/// Added isRunning().<br>
|
||||
/// \version 1.50 2016-02-25
|
||||
/// AccelStepper_PCF8574::disableOutputs now sets the enable pion to OUTPUT mode if the enable pin is defined.
|
||||
/// Patch from Piet De Jong.<br>
|
||||
/// Added notes about the fact that AFMotor_* examples do not work with Adafruit Motor Shield V2.<br>
|
||||
/// \version 1.51 2016-03-24
|
||||
/// Fixed a problem reported by gregor: when resetting the stepper motor position using setCurrentPosition() the
|
||||
/// stepper speed is reset by setting _stepInterval to 0, but _speed is not
|
||||
/// reset. this results in the stepper motor not starting again when calling
|
||||
/// setSpeed() with the same speed the stepper was set to before.
|
||||
/// \version 1.52 2016-08-09
|
||||
/// Added MultiStepper to keywords.txt.
|
||||
/// Improvements to efficiency of AccelStepper_PCF8574::runSpeed() as suggested by David Grayson.
|
||||
/// Improvements to speed accuracy as suggested by David Grayson.
|
||||
/// \version 1.53 2016-08-14
|
||||
/// Backed out Improvements to speed accuracy from 1.52 as it did not work correctly.
|
||||
/// \version 1.54 2017-01-24
|
||||
/// Fixed some warnings about unused arguments.
|
||||
/// \version 1.55 2017-01-25
|
||||
/// Fixed another warning in MultiStepper.cpp
|
||||
/// \version 1.56 2017-02-03
|
||||
/// Fixed minor documentation error with DIRECTION_CCW and DIRECTION_CW. Reported by David Mutterer.
|
||||
/// Added link to Binpress commercial license purchasing.
|
||||
/// \version 1.57 2017-03-28
|
||||
/// _direction moved to protected at the request of Rudy Ercek.
|
||||
/// setMaxSpeed() and setAcceleration() now correct negative values to be positive.
|
||||
/// \version 1.58 2018-04-13
|
||||
/// Add initialisation for _enableInverted in constructor.
|
||||
/// \version 1.59 2018-08-28
|
||||
/// Update commercial licensing, remove binpress.
|
||||
///
|
||||
/// \author Mike McCauley (mikem@airspayce.com) DO NOT CONTACT THE AUTHOR DIRECTLY: USE THE LISTS
|
||||
// Copyright (C) 2009-2013 Mike McCauley
|
||||
// $Id: AccelStepper_PCF8574.h,v 1.27 2016/08/14 10:26:54 mikem Exp mikem $
|
||||
|
||||
#ifndef AccelStepper_PCF8574_h
|
||||
#define AccelStepper_PCF8574_h
|
||||
#include <Wire.h>
|
||||
#include "PCF8574.h"
|
||||
#include <stdlib.h>
|
||||
#if ARDUINO >= 100
|
||||
#include <Arduino.h>
|
||||
#else
|
||||
#include <WProgram.h>
|
||||
#include <wiring.h>
|
||||
#endif
|
||||
|
||||
// These defs cause trouble on some versions of Arduino
|
||||
#undef round
|
||||
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
/// \class AccelStepper_PCF8574 AccelStepper_PCF8574.h <AccelStepper_PCF8574.h>
|
||||
/// \brief Support for stepper motors with acceleration etc.
|
||||
///
|
||||
/// This defines a single 2 or 4 pin stepper motor, or stepper moter with fdriver chip, with optional
|
||||
/// acceleration, deceleration, absolute positioning commands etc. Multiple
|
||||
/// simultaneous steppers are supported, all moving
|
||||
/// at different speeds and accelerations.
|
||||
///
|
||||
/// \par Operation
|
||||
/// This module operates by computing a step time in microseconds. The step
|
||||
/// time is recomputed after each step and after speed and acceleration
|
||||
/// parameters are changed by the caller. The time of each step is recorded in
|
||||
/// microseconds. The run() function steps the motor once if a new step is due.
|
||||
/// The run() function must be called frequently until the motor is in the
|
||||
/// desired position, after which time run() will do nothing.
|
||||
///
|
||||
/// \par Positioning
|
||||
/// Positions are specified by a signed long integer. At
|
||||
/// construction time, the current position of the motor is consider to be 0. Positive
|
||||
/// positions are clockwise from the initial position; negative positions are
|
||||
/// anticlockwise. The current position can be altered for instance after
|
||||
/// initialization positioning.
|
||||
///
|
||||
/// \par Caveats
|
||||
/// This is an open loop controller: If the motor stalls or is oversped,
|
||||
/// AccelStepper_PCF8574 will not have a correct
|
||||
/// idea of where the motor really is (since there is no feedback of the motor's
|
||||
/// real position. We only know where we _think_ it is, relative to the
|
||||
/// initial starting point).
|
||||
///
|
||||
/// \par Performance
|
||||
/// The fastest motor speed that can be reliably supported is about 4000 steps per
|
||||
/// second at a clock frequency of 16 MHz on Arduino such as Uno etc.
|
||||
/// Faster processors can support faster stepping speeds.
|
||||
/// However, any speed less than that
|
||||
/// down to very slow speeds (much less than one per second) are also supported,
|
||||
/// provided the run() function is called frequently enough to step the motor
|
||||
/// whenever required for the speed set.
|
||||
/// Calling setAcceleration() is expensive,
|
||||
/// since it requires a square root to be calculated.
|
||||
///
|
||||
/// Gregor Christandl reports that with an Arduino Due and a simple test program,
|
||||
/// he measured 43163 steps per second using runSpeed(),
|
||||
/// and 16214 steps per second using run();
|
||||
class AccelStepper_PCF8574
|
||||
{
|
||||
public:
|
||||
/// \brief Symbolic names for number of pins.
|
||||
/// Use this in the pins argument the AccelStepper_PCF8574 constructor to
|
||||
/// provide a symbolic name for the number of pins
|
||||
/// to use.
|
||||
typedef enum
|
||||
{
|
||||
FUNCTION = 0, ///< Use the functional interface, implementing your own driver functions (internal use only)
|
||||
DRIVER = 1, ///< Stepper Driver, 2 driver pins required
|
||||
FULL2WIRE = 2, ///< 2 wire stepper, 2 motor pins required
|
||||
FULL3WIRE = 3, ///< 3 wire stepper, such as HDD spindle, 3 motor pins required
|
||||
FULL4WIRE = 4, ///< 4 wire full stepper, 4 motor pins required
|
||||
HALF3WIRE = 6, ///< 3 wire half stepper, such as HDD spindle, 3 motor pins required
|
||||
HALF4WIRE = 8 ///< 4 wire half stepper, 4 motor pins required
|
||||
} MotorInterfaceType;
|
||||
|
||||
/// Constructor. You can have multiple simultaneous steppers, all moving
|
||||
/// at different speeds and accelerations, provided you call their run()
|
||||
/// functions at frequent enough intervals. Current Position is set to 0, target
|
||||
/// position is set to 0. MaxSpeed and Acceleration default to 1.0.
|
||||
/// The motor pins will be initialised to OUTPUT mode during the
|
||||
/// constructor by a call to enableOutputs().
|
||||
/// \param[in] interface Number of pins to interface to. Integer values are
|
||||
/// supported, but it is preferred to use the \ref MotorInterfaceType symbolic names.
|
||||
/// AccelStepper_PCF8574::DRIVER (1) means a stepper driver (with Step and Direction pins).
|
||||
/// If an enable line is also needed, call setEnablePin() after construction.
|
||||
/// You may also invert the pins using setPinsInverted().
|
||||
/// AccelStepper_PCF8574::FULL2WIRE (2) means a 2 wire stepper (2 pins required).
|
||||
/// AccelStepper_PCF8574::FULL3WIRE (3) means a 3 wire stepper, such as HDD spindle (3 pins required).
|
||||
/// AccelStepper_PCF8574::FULL4WIRE (4) means a 4 wire stepper (4 pins required).
|
||||
/// AccelStepper_PCF8574::HALF3WIRE (6) means a 3 wire half stepper, such as HDD spindle (3 pins required)
|
||||
/// AccelStepper_PCF8574::HALF4WIRE (8) means a 4 wire half stepper (4 pins required)
|
||||
/// Defaults to AccelStepper_PCF8574::FULL4WIRE (4) pins.
|
||||
/// \param[in] pin1 Arduino digital pin number for motor pin 1. Defaults
|
||||
/// to pin 2. For a AccelStepper_PCF8574::DRIVER (interface==1),
|
||||
/// this is the Step input to the driver. Low to high transition means to step)
|
||||
/// \param[in] pin2 Arduino digital pin number for motor pin 2. Defaults
|
||||
/// to pin 3. For a AccelStepper_PCF8574::DRIVER (interface==1),
|
||||
/// this is the Direction input the driver. High means forward.
|
||||
/// \param[in] pin3 Arduino digital pin number for motor pin 3. Defaults
|
||||
/// to pin 4.
|
||||
/// \param[in] pin4 Arduino digital pin number for motor pin 4. Defaults
|
||||
/// to pin 5.
|
||||
/// \param[in] enable If this is true (the default), enableOutputs() will be called to enable
|
||||
/// the output pins at construction time.
|
||||
AccelStepper_PCF8574(PCF8574 *device, uint8_t interface = AccelStepper_PCF8574::FULL4WIRE, uint8_t pin1 = 2, uint8_t pin2 = 3, uint8_t pin3 = 4, uint8_t pin4 = 5, bool enable = true);
|
||||
|
||||
/// Alternate Constructor which will call your own functions for forward and backward steps.
|
||||
/// You can have multiple simultaneous steppers, all moving
|
||||
/// at different speeds and accelerations, provided you call their run()
|
||||
/// functions at frequent enough intervals. Current Position is set to 0, target
|
||||
/// position is set to 0. MaxSpeed and Acceleration default to 1.0.
|
||||
/// Any motor initialization should happen before hand, no pins are used or initialized.
|
||||
/// \param[in] forward void-returning procedure that will make a forward step
|
||||
/// \param[in] backward void-returning procedure that will make a backward step
|
||||
|
||||
/// Set the target position. The run() function will try to move the motor (at most one step per call)
|
||||
/// from the current position to the target position set by the most
|
||||
/// recent call to this function. Caution: moveTo() also recalculates the speed for the next step.
|
||||
/// If you are trying to use constant speed movements, you should call setSpeed() after calling moveTo().
|
||||
/// \param[in] absolute The desired absolute position. Negative is
|
||||
/// anticlockwise from the 0 position.
|
||||
void moveTo(long absolute);
|
||||
|
||||
/// Set the target position relative to the current position
|
||||
/// \param[in] relative The desired position relative to the current position. Negative is
|
||||
/// anticlockwise from the current position.
|
||||
void move(long relative);
|
||||
|
||||
/// Poll the motor and step it if a step is due, implementing
|
||||
/// accelerations and decelerations to acheive the target position. You must call this as
|
||||
/// frequently as possible, but at least once per minimum step time interval,
|
||||
/// preferably in your main loop. Note that each call to run() will make at most one step, and then only when a step is due,
|
||||
/// based on the current speed and the time since the last step.
|
||||
/// \return true if the motor is still running to the target position.
|
||||
boolean run();
|
||||
|
||||
/// Poll the motor and step it if a step is due, implementing a constant
|
||||
/// speed as set by the most recent call to setSpeed(). You must call this as
|
||||
/// frequently as possible, but at least once per step interval,
|
||||
/// \return true if the motor was stepped.
|
||||
boolean runSpeed();
|
||||
|
||||
/// Sets the maximum permitted speed. The run() function will accelerate
|
||||
/// up to the speed set by this function.
|
||||
/// Caution: the maximum speed achievable depends on your processor and clock speed.
|
||||
/// The default maxSpeed is 1.0 steps per second.
|
||||
/// \param[in] speed The desired maximum speed in steps per second. Must
|
||||
/// be > 0. Caution: Speeds that exceed the maximum speed supported by the processor may
|
||||
/// Result in non-linear accelerations and decelerations.
|
||||
void setMaxSpeed(float speed);
|
||||
|
||||
/// returns the maximum speed configured for this stepper
|
||||
/// that was previously set by setMaxSpeed();
|
||||
/// \return The currently configured maximum speed
|
||||
float maxSpeed();
|
||||
|
||||
/// Sets the acceleration/deceleration rate.
|
||||
/// \param[in] acceleration The desired acceleration in steps per second
|
||||
/// per second. Must be > 0.0. This is an expensive call since it requires a square
|
||||
/// root to be calculated. Dont call more ofthen than needed
|
||||
void setAcceleration(float acceleration);
|
||||
|
||||
/// Sets the desired constant speed for use with runSpeed().
|
||||
/// \param[in] speed The desired constant speed in steps per
|
||||
/// second. Positive is clockwise. Speeds of more than 1000 steps per
|
||||
/// second are unreliable. Very slow speeds may be set (eg 0.00027777 for
|
||||
/// once per hour, approximately. Speed accuracy depends on the Arduino
|
||||
/// crystal. Jitter depends on how frequently you call the runSpeed() function.
|
||||
/// The speed will be limited by the current value of setMaxSpeed()
|
||||
void setSpeed(float speed);
|
||||
|
||||
/// The most recently set speed
|
||||
/// \return the most recent speed in steps per second
|
||||
float speed();
|
||||
|
||||
/// The distance from the current position to the target position.
|
||||
/// \return the distance from the current position to the target position
|
||||
/// in steps. Positive is clockwise from the current position.
|
||||
long distanceToGo();
|
||||
|
||||
/// The most recently set target position.
|
||||
/// \return the target position
|
||||
/// in steps. Positive is clockwise from the 0 position.
|
||||
long targetPosition();
|
||||
|
||||
/// The currently motor position.
|
||||
/// \return the current motor position
|
||||
/// in steps. Positive is clockwise from the 0 position.
|
||||
long currentPosition();
|
||||
|
||||
/// Resets the current position of the motor, so that wherever the motor
|
||||
/// happens to be right now is considered to be the new 0 position. Useful
|
||||
/// for setting a zero position on a stepper after an initial hardware
|
||||
/// positioning move.
|
||||
/// Has the side effect of setting the current motor speed to 0.
|
||||
/// \param[in] position The position in steps of wherever the motor
|
||||
/// happens to be right now.
|
||||
void setCurrentPosition(long position);
|
||||
|
||||
/// Moves the motor (with acceleration/deceleration)
|
||||
/// to the target position and blocks until it is at
|
||||
/// position. Dont use this in event loops, since it blocks.
|
||||
void runToPosition();
|
||||
|
||||
/// Runs at the currently selected speed until the target position is reached
|
||||
/// Does not implement accelerations.
|
||||
/// \return true if it stepped
|
||||
boolean runSpeedToPosition();
|
||||
|
||||
/// Moves the motor (with acceleration/deceleration)
|
||||
/// to the new target position and blocks until it is at
|
||||
/// position. Dont use this in event loops, since it blocks.
|
||||
/// \param[in] position The new target position.
|
||||
void runToNewPosition(long position);
|
||||
|
||||
/// Sets a new target position that causes the stepper
|
||||
/// to stop as quickly as possible, using the current speed and acceleration parameters.
|
||||
void stop();
|
||||
|
||||
/// Disable motor pin outputs by setting them all LOW
|
||||
/// Depending on the design of your electronics this may turn off
|
||||
/// the power to the motor coils, saving power.
|
||||
/// This is useful to support Arduino low power modes: disable the outputs
|
||||
/// during sleep and then reenable with enableOutputs() before stepping
|
||||
/// again.
|
||||
/// If the enable Pin is defined, sets it to OUTPUT mode and clears the pin to disabled.
|
||||
virtual void disableOutputs();
|
||||
|
||||
/// Enable motor pin outputs by setting the motor pins to OUTPUT
|
||||
/// mode. Called automatically by the constructor.
|
||||
/// If the enable Pin is defined, sets it to OUTPUT mode and sets the pin to enabled.
|
||||
virtual void enableOutputs();
|
||||
|
||||
/// Sets the minimum pulse width allowed by the stepper driver. The minimum practical pulse width is
|
||||
/// approximately 20 microseconds. Times less than 20 microseconds
|
||||
/// will usually result in 20 microseconds or so.
|
||||
/// \param[in] minWidth The minimum pulse width in microseconds.
|
||||
void setMinPulseWidth(unsigned int minWidth);
|
||||
|
||||
/// Sets the enable pin number for stepper drivers.
|
||||
/// 0xFF indicates unused (default).
|
||||
/// Otherwise, if a pin is set, the pin will be turned on when
|
||||
/// enableOutputs() is called and switched off when disableOutputs()
|
||||
/// is called.
|
||||
/// \param[in] enablePin Arduino digital pin number for motor enable
|
||||
/// \sa setPinsInverted
|
||||
void setEnablePin(uint8_t enablePin = 0xff);
|
||||
|
||||
/// Sets the inversion for stepper driver pins
|
||||
/// \param[in] directionInvert True for inverted direction pin, false for non-inverted
|
||||
/// \param[in] stepInvert True for inverted step pin, false for non-inverted
|
||||
/// \param[in] enableInvert True for inverted enable pin, false (default) for non-inverted
|
||||
void setPinsInverted(bool directionInvert = false, bool stepInvert = false, bool enableInvert = false);
|
||||
|
||||
/// Sets the inversion for 2, 3 and 4 wire stepper pins
|
||||
/// \param[in] pin1Invert True for inverted pin1, false for non-inverted
|
||||
/// \param[in] pin2Invert True for inverted pin2, false for non-inverted
|
||||
/// \param[in] pin3Invert True for inverted pin3, false for non-inverted
|
||||
/// \param[in] pin4Invert True for inverted pin4, false for non-inverted
|
||||
/// \param[in] enableInvert True for inverted enable pin, false (default) for non-inverted
|
||||
void setPinsInverted(bool pin1Invert, bool pin2Invert, bool pin3Invert, bool pin4Invert, bool enableInvert);
|
||||
|
||||
/// Checks to see if the motor is currently running to a target
|
||||
/// \return true if the speed is not zero or not at the target position
|
||||
bool isRunning();
|
||||
|
||||
protected:
|
||||
|
||||
/// \brief Direction indicator
|
||||
/// Symbolic names for the direction the motor is turning
|
||||
typedef enum
|
||||
{
|
||||
DIRECTION_CCW = 0, ///< Counter-Clockwise
|
||||
DIRECTION_CW = 1 ///< Clockwise
|
||||
} Direction;
|
||||
|
||||
/// Forces the library to compute a new instantaneous speed and set that as
|
||||
/// the current speed. It is called by
|
||||
/// the library:
|
||||
/// \li after each step
|
||||
/// \li after change to maxSpeed through setMaxSpeed()
|
||||
/// \li after change to acceleration through setAcceleration()
|
||||
/// \li after change to target position (relative or absolute) through
|
||||
/// move() or moveTo()
|
||||
void computeNewSpeed();
|
||||
|
||||
/// Low level function to set the motor output pins
|
||||
/// bit 0 of the mask corresponds to _pin[0]
|
||||
/// bit 1 of the mask corresponds to _pin[1]
|
||||
/// You can override this to impment, for example serial chip output insted of using the
|
||||
/// output pins directly
|
||||
virtual void setOutputPins(uint8_t mask);
|
||||
|
||||
/// Called to execute a step. Only called when a new step is
|
||||
/// required. Subclasses may override to implement new stepping
|
||||
/// interfaces. The default calls step1(), step2(), step4() or step8() depending on the
|
||||
/// number of pins defined for the stepper.
|
||||
/// \param[in] step The current step phase number (0 to 7)
|
||||
virtual void step(long step);
|
||||
|
||||
/// Called to execute a step using stepper functions (pins = 0) Only called when a new step is
|
||||
/// required. Calls _forward() or _backward() to perform the step
|
||||
/// \param[in] step The current step phase number (0 to 7)
|
||||
virtual void step0(long step);
|
||||
|
||||
/// Called to execute a step on a stepper driver (ie where pins == 1). Only called when a new step is
|
||||
/// required. Subclasses may override to implement new stepping
|
||||
/// interfaces. The default sets or clears the outputs of Step pin1 to step,
|
||||
/// and sets the output of _pin2 to the desired direction. The Step pin (_pin1) is pulsed for 1 microsecond
|
||||
/// which is the minimum STEP pulse width for the 3967 driver.
|
||||
/// \param[in] step The current step phase number (0 to 7)
|
||||
virtual void step1(long step);
|
||||
|
||||
/// Called to execute a step on a 2 pin motor. Only called when a new step is
|
||||
/// required. Subclasses may override to implement new stepping
|
||||
/// interfaces. The default sets or clears the outputs of pin1 and pin2
|
||||
/// \param[in] step The current step phase number (0 to 7)
|
||||
virtual void step2(long step);
|
||||
|
||||
/// Called to execute a step on a 3 pin motor, such as HDD spindle. Only called when a new step is
|
||||
/// required. Subclasses may override to implement new stepping
|
||||
/// interfaces. The default sets or clears the outputs of pin1, pin2,
|
||||
/// pin3
|
||||
/// \param[in] step The current step phase number (0 to 7)
|
||||
virtual void step3(long step);
|
||||
|
||||
/// Called to execute a step on a 4 pin motor. Only called when a new step is
|
||||
/// required. Subclasses may override to implement new stepping
|
||||
/// interfaces. The default sets or clears the outputs of pin1, pin2,
|
||||
/// pin3, pin4.
|
||||
/// \param[in] step The current step phase number (0 to 7)
|
||||
virtual void step4(long step);
|
||||
|
||||
/// Called to execute a step on a 3 pin motor, such as HDD spindle. Only called when a new step is
|
||||
/// required. Subclasses may override to implement new stepping
|
||||
/// interfaces. The default sets or clears the outputs of pin1, pin2,
|
||||
/// pin3
|
||||
/// \param[in] step The current step phase number (0 to 7)
|
||||
virtual void step6(long step);
|
||||
|
||||
/// Called to execute a step on a 4 pin half-steper motor. Only called when a new step is
|
||||
/// required. Subclasses may override to implement new stepping
|
||||
/// interfaces. The default sets or clears the outputs of pin1, pin2,
|
||||
/// pin3, pin4.
|
||||
/// \param[in] step The current step phase number (0 to 7)
|
||||
virtual void step8(long step);
|
||||
|
||||
/// Current direction motor is spinning in
|
||||
/// Protected because some peoples subclasses need it to be so
|
||||
boolean _direction; // 1 == CW
|
||||
|
||||
private:
|
||||
PCF8574 *_device;
|
||||
/// Number of pins on the stepper motor. Permits 2 or 4. 2 pins is a
|
||||
/// bipolar, and 4 pins is a unipolar.
|
||||
uint8_t _interface; // 0, 1, 2, 4, 8, See MotorInterfaceType
|
||||
|
||||
/// Arduino pin number assignments for the 2 or 4 pins required to interface to the
|
||||
/// stepper motor or driver
|
||||
uint8_t _pin[4];
|
||||
|
||||
/// Whether the _pins is inverted or not
|
||||
uint8_t _pinInverted[4];
|
||||
|
||||
/// The current absolution position in steps.
|
||||
long _currentPos; // Steps
|
||||
|
||||
/// The target position in steps. The AccelStepper_PCF8574 library will move the
|
||||
/// motor from the _currentPos to the _targetPos, taking into account the
|
||||
/// max speed, acceleration and deceleration
|
||||
long _targetPos; // Steps
|
||||
|
||||
/// The current motos speed in steps per second
|
||||
/// Positive is clockwise
|
||||
float _speed; // Steps per second
|
||||
|
||||
/// The maximum permitted speed in steps per second. Must be > 0.
|
||||
float _maxSpeed;
|
||||
|
||||
/// The acceleration to use to accelerate or decelerate the motor in steps
|
||||
/// per second per second. Must be > 0
|
||||
float _acceleration;
|
||||
float _sqrt_twoa; // Precomputed sqrt(2*_acceleration)
|
||||
|
||||
/// The current interval between steps in microseconds.
|
||||
/// 0 means the motor is currently stopped with _speed == 0
|
||||
unsigned long _stepInterval;
|
||||
|
||||
/// The last step time in microseconds
|
||||
unsigned long _lastStepTime;
|
||||
|
||||
/// The minimum allowed pulse width in microseconds
|
||||
unsigned int _minPulseWidth;
|
||||
|
||||
/// Is the direction pin inverted?
|
||||
///bool _dirInverted; /// Moved to _pinInverted[1]
|
||||
|
||||
/// Is the step pin inverted?
|
||||
///bool _stepInverted; /// Moved to _pinInverted[0]
|
||||
|
||||
/// Is the enable pin inverted?
|
||||
bool _enableInverted;
|
||||
|
||||
/// Enable pin for stepper driver, or 0xFF if unused.
|
||||
uint8_t _enablePin;
|
||||
|
||||
/// The pointer to a forward-step procedure
|
||||
void (*_forward)();
|
||||
|
||||
/// The pointer to a backward-step procedure
|
||||
void (*_backward)();
|
||||
|
||||
/// The step counter for speed calculations
|
||||
long _n;
|
||||
|
||||
/// Initial step size in microseconds
|
||||
float _c0;
|
||||
|
||||
/// Last step size in microseconds
|
||||
float _cn;
|
||||
|
||||
/// Min step size in microseconds based on maxSpeed
|
||||
float _cmin; // at max speed
|
||||
|
||||
};
|
||||
|
||||
/// @example Random.pde
|
||||
/// Make a single stepper perform random changes in speed, position and acceleration
|
||||
|
||||
/// @example Overshoot.pde
|
||||
/// Check overshoot handling
|
||||
/// which sets a new target position and then waits until the stepper has
|
||||
/// achieved it. This is used for testing the handling of overshoots
|
||||
|
||||
/// @example MultipleSteppers.pde
|
||||
/// Shows how to multiple simultaneous steppers
|
||||
/// Runs one stepper forwards and backwards, accelerating and decelerating
|
||||
/// at the limits. Runs other steppers at the same time
|
||||
|
||||
/// @example ConstantSpeed.pde
|
||||
/// Shows how to run AccelStepper_PCF8574 in the simplest,
|
||||
/// fixed speed mode with no accelerations
|
||||
|
||||
/// @example Blocking.pde
|
||||
/// Shows how to use the blocking call runToNewPosition
|
||||
/// Which sets a new target position and then waits until the stepper has
|
||||
/// achieved it.
|
||||
|
||||
/// @example AFMotor_MultiStepper.pde
|
||||
/// Control both Stepper motors at the same time with different speeds
|
||||
/// and accelerations.
|
||||
|
||||
/// @example AFMotor_ConstantSpeed.pde
|
||||
/// Shows how to run AccelStepper_PCF8574 in the simplest,
|
||||
/// fixed speed mode with no accelerations
|
||||
|
||||
/// @example ProportionalControl.pde
|
||||
/// Make a single stepper follow the analog value read from a pot or whatever
|
||||
/// The stepper will move at a constant speed to each newly set posiiton,
|
||||
/// depending on the value of the pot.
|
||||
|
||||
/// @example Bounce.pde
|
||||
/// Make a single stepper bounce from one limit to another, observing
|
||||
/// accelrations at each end of travel
|
||||
|
||||
/// @example Quickstop.pde
|
||||
/// Check stop handling.
|
||||
/// Calls stop() while the stepper is travelling at full speed, causing
|
||||
/// the stepper to stop as quickly as possible, within the constraints of the
|
||||
/// current acceleration.
|
||||
|
||||
/// @example MotorShield.pde
|
||||
/// Shows how to use AccelStepper_PCF8574 to control a 3-phase motor, such as a HDD spindle motor
|
||||
/// using the Adafruit Motor Shield http://www.ladyada.net/make/mshield/index.html.
|
||||
|
||||
/// @example DualMotorShield.pde
|
||||
/// Shows how to use AccelStepper_PCF8574 to control 2 x 2 phase steppers using the
|
||||
/// Itead Studio Arduino Dual Stepper Motor Driver Shield
|
||||
/// model IM120417015
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,73 @@
|
||||
// MultiStepper_PCF8574.cpp
|
||||
//
|
||||
// Copyright (C) 2015 Mike McCauley
|
||||
// $Id: MultiStepper_PCF8574.cpp,v 1.2 2015/10/04 05:16:38 mikem Exp $
|
||||
|
||||
#include "MultiStepper_PCF8574.h"
|
||||
#include "AccelStepper_PCF8574.h"
|
||||
|
||||
MultiStepper_PCF8574::MultiStepper_PCF8574()
|
||||
: _num_steppers(0)
|
||||
{
|
||||
}
|
||||
|
||||
boolean MultiStepper_PCF8574::addStepper(AccelStepper_PCF8574& stepper)
|
||||
{
|
||||
if (_num_steppers >= MULTISTEPPER_MAX_STEPPERS)
|
||||
return false; // No room for more
|
||||
_steppers[_num_steppers++] = &stepper;
|
||||
return true;
|
||||
}
|
||||
|
||||
void MultiStepper_PCF8574::moveTo(long absolute[])
|
||||
{
|
||||
// First find the stepper that will take the longest time to move
|
||||
float longestTime = 0.0;
|
||||
|
||||
uint8_t i;
|
||||
for (i = 0; i < _num_steppers; i++)
|
||||
{
|
||||
long thisDistance = absolute[i] - _steppers[i]->currentPosition();
|
||||
float thisTime = abs(thisDistance) / _steppers[i]->maxSpeed();
|
||||
|
||||
if (thisTime > longestTime)
|
||||
longestTime = thisTime;
|
||||
}
|
||||
|
||||
if (longestTime > 0.0)
|
||||
{
|
||||
// Now work out a new max speed for each stepper so they will all
|
||||
// arrived at the same time of longestTime
|
||||
for (i = 0; i < _num_steppers; i++)
|
||||
{
|
||||
long thisDistance = absolute[i] - _steppers[i]->currentPosition();
|
||||
float thisSpeed = thisDistance / longestTime;
|
||||
_steppers[i]->moveTo(absolute[i]); // New target position (resets speed)
|
||||
_steppers[i]->setSpeed(thisSpeed); // New speed
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Returns true if any motor is still running to the target position.
|
||||
boolean MultiStepper_PCF8574::run()
|
||||
{
|
||||
uint8_t i;
|
||||
boolean ret = false;
|
||||
for (i = 0; i < _num_steppers; i++)
|
||||
{
|
||||
if ( _steppers[i]->distanceToGo() != 0)
|
||||
{
|
||||
_steppers[i]->runSpeed();
|
||||
ret = true;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Blocks until all steppers reach their target position and are stopped
|
||||
void MultiStepper_PCF8574::runSpeedToPosition()
|
||||
{
|
||||
while (run())
|
||||
;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,78 @@
|
||||
// MultiStepper_PCF8574.h
|
||||
|
||||
#ifndef MultiStepper_PCF8574_h
|
||||
#define MultiStepper_PCF8574_h
|
||||
|
||||
#include <stdlib.h>
|
||||
#if ARDUINO >= 100
|
||||
#include <Arduino.h>
|
||||
#else
|
||||
#include <WProgram.h>
|
||||
#include <wiring.h>
|
||||
#endif
|
||||
|
||||
#define MULTISTEPPER_MAX_STEPPERS 10
|
||||
|
||||
class AccelStepper_PCF8574;
|
||||
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
/// \class MultiStepper_PCF8574 MultiStepper_PCF8574.h <MultiStepper_PCF8574.h>
|
||||
/// \brief Operate multiple AccelStepper_PCF8574s in a co-ordinated fashion
|
||||
///
|
||||
/// This class can manage multiple AccelStepper_PCF8574s (up to MULTISTEPPER_MAX_STEPPERS = 10),
|
||||
/// and cause them all to move
|
||||
/// to selected positions at such a (constant) speed that they all arrive at their
|
||||
/// target position at the same time. This can be used to support devices with multiple steppers
|
||||
/// on say multiple axes to cause linear diagonal motion. Suitable for use with X-Y plotters, flatbeds,
|
||||
/// 3D printers etc
|
||||
/// to get linear straight line movement between arbitrary 2d (or 3d or ...) positions.
|
||||
///
|
||||
/// Caution: only constant speed stepper motion is supported: acceleration and deceleration is not supported
|
||||
/// All the steppers managed by MultiStepper_PCF8574 will step at a constant speed to their
|
||||
/// target (albeit perhaps different speeds for each stepper).
|
||||
class MultiStepper_PCF8574
|
||||
{
|
||||
public:
|
||||
/// Constructor
|
||||
MultiStepper_PCF8574();
|
||||
|
||||
/// Add a stepper to the set of managed steppers
|
||||
/// There is an upper limit of MULTISTEPPER_MAX_STEPPERS = 10 to the number of steppers that can be managed
|
||||
/// \param[in] stepper Reference to a stepper to add to the managed list
|
||||
/// \return true if successful. false if the number of managed steppers would exceed MULTISTEPPER_MAX_STEPPERS
|
||||
boolean addStepper(AccelStepper_PCF8574& stepper);
|
||||
|
||||
/// Set the target positions of all managed steppers
|
||||
/// according to a coordinate array.
|
||||
/// New speeds will be computed for each stepper so they will all arrive at their
|
||||
/// respective targets at very close to the same time.
|
||||
/// \param[in] absolute An array of desired absolute stepper positions. absolute[0] will be used to set
|
||||
/// the absolute position of the first stepper added by addStepper() etc. The array must be at least as long as
|
||||
/// the number of steppers that have been added by addStepper, else results are undefined.
|
||||
void moveTo(long absolute[]);
|
||||
|
||||
/// Calls runSpeed() on all the managed steppers
|
||||
/// that have not acheived their target position.
|
||||
/// \return true if any stepper is still in the process of running to its target position.
|
||||
boolean run();
|
||||
|
||||
/// Runs all managed steppers until they acheived their target position.
|
||||
/// Blocks until all that position is acheived. If you dont
|
||||
/// want blocking consider using run() instead.
|
||||
void runSpeedToPosition();
|
||||
|
||||
private:
|
||||
/// Array of pointers to the steppers we are controlling.
|
||||
/// Fills from 0 onwards
|
||||
AccelStepper_PCF8574* _steppers[MULTISTEPPER_MAX_STEPPERS];
|
||||
|
||||
/// Number of steppers we are controlling and the number
|
||||
/// of steppers in _steppers[]
|
||||
uint8_t _num_steppers;
|
||||
};
|
||||
|
||||
/// @example MultiStepper_PCF8574.pde
|
||||
/// Use MultiStepper_PCF8574 class to manage multiple steppers and make them all move to
|
||||
/// the same position at the same time for linear 2d (or 3d) motion.
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,625 @@
|
||||
// AccelStepper_PCF8574_Soft.cpp
|
||||
//
|
||||
// Copyright (C) 2009-2013 Mike McCauley
|
||||
// $Id: AccelStepper_PCF8574_Soft.cpp,v 1.23 2016/08/09 00:39:10 mikem Exp $
|
||||
#include <SoftwareWire.h>
|
||||
#include "PCF8574_Soft.h"
|
||||
#include "AccelStepper_PCF8574_Soft.h"
|
||||
|
||||
#if 0
|
||||
// Some debugging assistance
|
||||
void dump(uint8_t* p, int l)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < l; i++)
|
||||
{
|
||||
Serial.print(p[i], HEX);
|
||||
Serial.print(" ");
|
||||
}
|
||||
Serial.println("");
|
||||
}
|
||||
#endif
|
||||
|
||||
void AccelStepper_PCF8574_Soft::moveTo(long absolute)
|
||||
{
|
||||
if (_targetPos != absolute)
|
||||
{
|
||||
_targetPos = absolute;
|
||||
computeNewSpeed();
|
||||
// compute new n?
|
||||
}
|
||||
}
|
||||
|
||||
void AccelStepper_PCF8574_Soft::move(long relative)
|
||||
{
|
||||
moveTo(_currentPos + relative);
|
||||
}
|
||||
|
||||
// Implements steps according to the current step interval
|
||||
// You must call this at least once per step
|
||||
// returns true if a step occurred
|
||||
boolean AccelStepper_PCF8574_Soft::runSpeed()
|
||||
{
|
||||
// Dont do anything unless we actually have a step interval
|
||||
if (!_stepInterval)
|
||||
return false;
|
||||
|
||||
unsigned long time = micros();
|
||||
if (time - _lastStepTime >= _stepInterval)
|
||||
{
|
||||
if (_direction == DIRECTION_CW)
|
||||
{
|
||||
// Clockwise
|
||||
_currentPos += 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Anticlockwise
|
||||
_currentPos -= 1;
|
||||
}
|
||||
step(_currentPos);
|
||||
|
||||
_lastStepTime = time; // Caution: does not account for costs in step()
|
||||
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
long AccelStepper_PCF8574_Soft::distanceToGo()
|
||||
{
|
||||
return _targetPos - _currentPos;
|
||||
}
|
||||
|
||||
long AccelStepper_PCF8574_Soft::targetPosition()
|
||||
{
|
||||
return _targetPos;
|
||||
}
|
||||
|
||||
long AccelStepper_PCF8574_Soft::currentPosition()
|
||||
{
|
||||
return _currentPos;
|
||||
}
|
||||
|
||||
// Useful during initialisations or after initial positioning
|
||||
// Sets speed to 0
|
||||
void AccelStepper_PCF8574_Soft::setCurrentPosition(long position)
|
||||
{
|
||||
_targetPos = _currentPos = position;
|
||||
_n = 0;
|
||||
_stepInterval = 0;
|
||||
_speed = 0.0;
|
||||
}
|
||||
|
||||
void AccelStepper_PCF8574_Soft::computeNewSpeed()
|
||||
{
|
||||
long distanceTo = distanceToGo(); // +ve is clockwise from curent location
|
||||
|
||||
long stepsToStop = (long)((_speed * _speed) / (2.0 * _acceleration)); // Equation 16
|
||||
|
||||
if (distanceTo == 0 && stepsToStop <= 1)
|
||||
{
|
||||
// We are at the target and its time to stop
|
||||
_stepInterval = 0;
|
||||
_speed = 0.0;
|
||||
_n = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
if (distanceTo > 0)
|
||||
{
|
||||
// We are anticlockwise from the target
|
||||
// Need to go clockwise from here, maybe decelerate now
|
||||
if (_n > 0)
|
||||
{
|
||||
// Currently accelerating, need to decel now? Or maybe going the wrong way?
|
||||
if ((stepsToStop >= distanceTo) || _direction == DIRECTION_CCW)
|
||||
_n = -stepsToStop; // Start deceleration
|
||||
}
|
||||
else if (_n < 0)
|
||||
{
|
||||
// Currently decelerating, need to accel again?
|
||||
if ((stepsToStop < distanceTo) && _direction == DIRECTION_CW)
|
||||
_n = -_n; // Start accceleration
|
||||
}
|
||||
}
|
||||
else if (distanceTo < 0)
|
||||
{
|
||||
// We are clockwise from the target
|
||||
// Need to go anticlockwise from here, maybe decelerate
|
||||
if (_n > 0)
|
||||
{
|
||||
// Currently accelerating, need to decel now? Or maybe going the wrong way?
|
||||
if ((stepsToStop >= -distanceTo) || _direction == DIRECTION_CW)
|
||||
_n = -stepsToStop; // Start deceleration
|
||||
}
|
||||
else if (_n < 0)
|
||||
{
|
||||
// Currently decelerating, need to accel again?
|
||||
if ((stepsToStop < -distanceTo) && _direction == DIRECTION_CCW)
|
||||
_n = -_n; // Start accceleration
|
||||
}
|
||||
}
|
||||
|
||||
// Need to accelerate or decelerate
|
||||
if (_n == 0)
|
||||
{
|
||||
// First step from stopped
|
||||
_cn = _c0;
|
||||
_direction = (distanceTo > 0) ? DIRECTION_CW : DIRECTION_CCW;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Subsequent step. Works for accel (n is +_ve) and decel (n is -ve).
|
||||
_cn = _cn - ((2.0 * _cn) / ((4.0 * _n) + 1)); // Equation 13
|
||||
_cn = max(_cn, _cmin);
|
||||
}
|
||||
_n++;
|
||||
_stepInterval = _cn;
|
||||
_speed = 1000000.0 / _cn;
|
||||
if (_direction == DIRECTION_CCW)
|
||||
_speed = -_speed;
|
||||
|
||||
#if 0
|
||||
Serial.println(_speed);
|
||||
Serial.println(_acceleration);
|
||||
Serial.println(_cn);
|
||||
Serial.println(_c0);
|
||||
Serial.println(_n);
|
||||
Serial.println(_stepInterval);
|
||||
Serial.println(distanceTo);
|
||||
Serial.println(stepsToStop);
|
||||
Serial.println("-----");
|
||||
#endif
|
||||
}
|
||||
|
||||
// Run the motor to implement speed and acceleration in order to proceed to the target position
|
||||
// You must call this at least once per step, preferably in your main loop
|
||||
// If the motor is in the desired position, the cost is very small
|
||||
// returns true if the motor is still running to the target position.
|
||||
boolean AccelStepper_PCF8574_Soft::run()
|
||||
{
|
||||
if (runSpeed())
|
||||
computeNewSpeed();
|
||||
return _speed != 0.0 || distanceToGo() != 0;
|
||||
}
|
||||
|
||||
AccelStepper_PCF8574_Soft::AccelStepper_PCF8574_Soft(PCF8574_Soft *device, uint8_t interface, uint8_t pin1, uint8_t pin2, uint8_t pin3, uint8_t pin4, bool enable)
|
||||
{
|
||||
_device = device;
|
||||
//_device->begin(0x20);
|
||||
//_device->pinMode(pin1, OUTPUT);
|
||||
//_device->pinMode(pin2, OUTPUT);
|
||||
//_device->pinMode(pin3, OUTPUT);
|
||||
//_device->pinMode(pin4, OUTPUT);
|
||||
_interface = interface;
|
||||
_currentPos = 0;
|
||||
_targetPos = 0;
|
||||
_speed = 0.0;
|
||||
_maxSpeed = 1.0;
|
||||
_acceleration = 0.0;
|
||||
_sqrt_twoa = 1.0;
|
||||
_stepInterval = 0;
|
||||
_minPulseWidth = 1;
|
||||
_enablePin = 0xff;
|
||||
_lastStepTime = 0;
|
||||
_pin[0] = pin1;
|
||||
_pin[1] = pin2;
|
||||
_pin[2] = pin3;
|
||||
_pin[3] = pin4;
|
||||
_enableInverted = false;
|
||||
|
||||
// NEW
|
||||
_n = 0;
|
||||
_c0 = 0.0;
|
||||
_cn = 0.0;
|
||||
_cmin = 1.0;
|
||||
_direction = DIRECTION_CCW;
|
||||
|
||||
int i;
|
||||
for (i = 0; i < 4; i++)
|
||||
_pinInverted[i] = 0;
|
||||
if (enable)
|
||||
enableOutputs();
|
||||
// Some reasonable default
|
||||
setAcceleration(1);
|
||||
}
|
||||
|
||||
void AccelStepper_PCF8574_Soft::setMaxSpeed(float speed)
|
||||
{
|
||||
if (speed < 0.0)
|
||||
speed = -speed;
|
||||
if (_maxSpeed != speed)
|
||||
{
|
||||
_maxSpeed = speed;
|
||||
_cmin = 1000000.0 / speed;
|
||||
// Recompute _n from current speed and adjust speed if accelerating or cruising
|
||||
if (_n > 0)
|
||||
{
|
||||
_n = (long)((_speed * _speed) / (2.0 * _acceleration)); // Equation 16
|
||||
computeNewSpeed();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
float AccelStepper_PCF8574_Soft::maxSpeed()
|
||||
{
|
||||
return _maxSpeed;
|
||||
}
|
||||
|
||||
void AccelStepper_PCF8574_Soft::setAcceleration(float acceleration)
|
||||
{
|
||||
if (acceleration == 0.0)
|
||||
return;
|
||||
if (acceleration < 0.0)
|
||||
acceleration = -acceleration;
|
||||
if (_acceleration != acceleration)
|
||||
{
|
||||
// Recompute _n per Equation 17
|
||||
_n = _n * (_acceleration / acceleration);
|
||||
// New c0 per Equation 7, with correction per Equation 15
|
||||
_c0 = 0.676 * sqrt(2.0 / acceleration) * 1000000.0; // Equation 15
|
||||
_acceleration = acceleration;
|
||||
computeNewSpeed();
|
||||
}
|
||||
}
|
||||
|
||||
void AccelStepper_PCF8574_Soft::setSpeed(float speed)
|
||||
{
|
||||
if (speed == _speed)
|
||||
return;
|
||||
speed = constrain(speed, -_maxSpeed, _maxSpeed);
|
||||
if (speed == 0.0)
|
||||
_stepInterval = 0;
|
||||
else
|
||||
{
|
||||
_stepInterval = fabs(1000000.0 / speed);
|
||||
_direction = (speed > 0.0) ? DIRECTION_CW : DIRECTION_CCW;
|
||||
}
|
||||
_speed = speed;
|
||||
}
|
||||
|
||||
float AccelStepper_PCF8574_Soft::speed()
|
||||
{
|
||||
return _speed;
|
||||
}
|
||||
|
||||
// Subclasses can override
|
||||
void AccelStepper_PCF8574_Soft::step(long step)
|
||||
{
|
||||
switch (_interface)
|
||||
{
|
||||
case FUNCTION:
|
||||
step0(step);
|
||||
break;
|
||||
|
||||
case DRIVER:
|
||||
step1(step);
|
||||
break;
|
||||
|
||||
case FULL2WIRE:
|
||||
step2(step);
|
||||
break;
|
||||
|
||||
case FULL3WIRE:
|
||||
step3(step);
|
||||
break;
|
||||
|
||||
case FULL4WIRE:
|
||||
step4(step);
|
||||
break;
|
||||
|
||||
case HALF3WIRE:
|
||||
step6(step);
|
||||
break;
|
||||
|
||||
case HALF4WIRE:
|
||||
step8(step);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// You might want to override this to implement eg serial output
|
||||
// bit 0 of the mask corresponds to _pin[0]
|
||||
// bit 1 of the mask corresponds to _pin[1]
|
||||
// ....
|
||||
void AccelStepper_PCF8574_Soft::setOutputPins(uint8_t mask)
|
||||
{
|
||||
uint8_t numpins = 2;
|
||||
if (_interface == FULL4WIRE || _interface == HALF4WIRE)
|
||||
numpins = 4;
|
||||
else if (_interface == FULL3WIRE || _interface == HALF3WIRE)
|
||||
numpins = 3;
|
||||
uint8_t i;
|
||||
for (i = 0; i < numpins; i++)
|
||||
_device->digitalWrite(_pin[i], (mask & (1 << i)) ? (HIGH ^ _pinInverted[i]) : (LOW ^ _pinInverted[i]));
|
||||
}
|
||||
|
||||
// 0 pin step function (ie for functional usage)
|
||||
void AccelStepper_PCF8574_Soft::step0(long step)
|
||||
{
|
||||
(void)(step); // Unused
|
||||
if (_speed > 0)
|
||||
_forward();
|
||||
else
|
||||
_backward();
|
||||
}
|
||||
|
||||
// 1 pin step function (ie for stepper drivers)
|
||||
// This is passed the current step number (0 to 7)
|
||||
// Subclasses can override
|
||||
void AccelStepper_PCF8574_Soft::step1(long step)
|
||||
{
|
||||
(void)(step); // Unused
|
||||
|
||||
// _pin[0] is step, _pin[1] is direction
|
||||
setOutputPins(_direction ? 0b10 : 0b00); // Set direction first else get rogue pulses
|
||||
setOutputPins(_direction ? 0b11 : 0b01); // step HIGH
|
||||
// Caution 200ns setup time
|
||||
// Delay the minimum allowed pulse width
|
||||
delayMicroseconds(_minPulseWidth);
|
||||
setOutputPins(_direction ? 0b10 : 0b00); // step LOW
|
||||
}
|
||||
|
||||
|
||||
// 2 pin step function
|
||||
// This is passed the current step number (0 to 7)
|
||||
// Subclasses can override
|
||||
void AccelStepper_PCF8574_Soft::step2(long step)
|
||||
{
|
||||
switch (step & 0x3)
|
||||
{
|
||||
case 0: /* 01 */
|
||||
setOutputPins(0b10);
|
||||
break;
|
||||
|
||||
case 1: /* 11 */
|
||||
setOutputPins(0b11);
|
||||
break;
|
||||
|
||||
case 2: /* 10 */
|
||||
setOutputPins(0b01);
|
||||
break;
|
||||
|
||||
case 3: /* 00 */
|
||||
setOutputPins(0b00);
|
||||
break;
|
||||
}
|
||||
}
|
||||
// 3 pin step function
|
||||
// This is passed the current step number (0 to 7)
|
||||
// Subclasses can override
|
||||
void AccelStepper_PCF8574_Soft::step3(long step)
|
||||
{
|
||||
switch (step % 3)
|
||||
{
|
||||
case 0: // 100
|
||||
setOutputPins(0b100);
|
||||
break;
|
||||
|
||||
case 1: // 001
|
||||
setOutputPins(0b001);
|
||||
break;
|
||||
|
||||
case 2: //010
|
||||
setOutputPins(0b010);
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// 4 pin step function for half stepper
|
||||
// This is passed the current step number (0 to 7)
|
||||
// Subclasses can override
|
||||
void AccelStepper_PCF8574_Soft::step4(long step)
|
||||
{
|
||||
switch (step & 0x3)
|
||||
{
|
||||
case 0: // 1010
|
||||
setOutputPins(0b0101);
|
||||
break;
|
||||
|
||||
case 1: // 0110
|
||||
setOutputPins(0b0110);
|
||||
break;
|
||||
|
||||
case 2: //0101
|
||||
setOutputPins(0b1010);
|
||||
break;
|
||||
|
||||
case 3: //1001
|
||||
setOutputPins(0b1001);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// 3 pin half step function
|
||||
// This is passed the current step number (0 to 7)
|
||||
// Subclasses can override
|
||||
void AccelStepper_PCF8574_Soft::step6(long step)
|
||||
{
|
||||
switch (step % 6)
|
||||
{
|
||||
case 0: // 100
|
||||
setOutputPins(0b100);
|
||||
break;
|
||||
|
||||
case 1: // 101
|
||||
setOutputPins(0b101);
|
||||
break;
|
||||
|
||||
case 2: // 001
|
||||
setOutputPins(0b001);
|
||||
break;
|
||||
|
||||
case 3: // 011
|
||||
setOutputPins(0b011);
|
||||
break;
|
||||
|
||||
case 4: // 010
|
||||
setOutputPins(0b010);
|
||||
break;
|
||||
|
||||
case 5: // 011
|
||||
setOutputPins(0b110);
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// 4 pin half step function
|
||||
// This is passed the current step number (0 to 7)
|
||||
// Subclasses can override
|
||||
void AccelStepper_PCF8574_Soft::step8(long step)
|
||||
{
|
||||
switch (step & 0x7)
|
||||
{
|
||||
case 0: // 1000
|
||||
setOutputPins(0b0001);
|
||||
break;
|
||||
|
||||
case 1: // 1010
|
||||
setOutputPins(0b0101);
|
||||
break;
|
||||
|
||||
case 2: // 0010
|
||||
setOutputPins(0b0100);
|
||||
break;
|
||||
|
||||
case 3: // 0110
|
||||
setOutputPins(0b0110);
|
||||
break;
|
||||
|
||||
case 4: // 0100
|
||||
setOutputPins(0b0010);
|
||||
break;
|
||||
|
||||
case 5: //0101
|
||||
setOutputPins(0b1010);
|
||||
break;
|
||||
|
||||
case 6: // 0001
|
||||
setOutputPins(0b1000);
|
||||
break;
|
||||
|
||||
case 7: //1001
|
||||
setOutputPins(0b1001);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Prevents power consumption on the outputs
|
||||
void AccelStepper_PCF8574_Soft::disableOutputs()
|
||||
{
|
||||
if (! _interface) return;
|
||||
|
||||
setOutputPins(0); // Handles inversion automatically
|
||||
if (_enablePin != 0xff)
|
||||
{
|
||||
//_device->pinMode(_enablePin, OUTPUT);
|
||||
_device->digitalWrite(_enablePin, LOW ^ _enableInverted);
|
||||
}
|
||||
}
|
||||
|
||||
void AccelStepper_PCF8574_Soft::enableOutputs()
|
||||
{
|
||||
if (! _interface)
|
||||
return;
|
||||
|
||||
//_device->pinMode(_pin[0], OUTPUT);
|
||||
//_device->pinMode(_pin[1], OUTPUT);
|
||||
//if (_interface == FULL4WIRE || _interface == HALF4WIRE)
|
||||
//{
|
||||
// _device->pinMode(_pin[2], OUTPUT);
|
||||
// _device->pinMode(_pin[3], OUTPUT);
|
||||
//}
|
||||
//else if (_interface == FULL3WIRE || _interface == HALF3WIRE)
|
||||
//{
|
||||
// _device->pinMode(_pin[2], OUTPUT);
|
||||
//}
|
||||
|
||||
if (_enablePin != 0xff)
|
||||
{
|
||||
//_device->pinMode(_enablePin, OUTPUT);
|
||||
_device->digitalWrite(_enablePin, HIGH ^ _enableInverted);
|
||||
}
|
||||
}
|
||||
|
||||
void AccelStepper_PCF8574_Soft::setMinPulseWidth(unsigned int minWidth)
|
||||
{
|
||||
_minPulseWidth = minWidth;
|
||||
}
|
||||
|
||||
void AccelStepper_PCF8574_Soft::setEnablePin(uint8_t enablePin)
|
||||
{
|
||||
_enablePin = enablePin;
|
||||
|
||||
// This happens after construction, so init pin now.
|
||||
if (_enablePin != 0xff)
|
||||
{
|
||||
//_device->pinMode(_enablePin, OUTPUT);
|
||||
_device->digitalWrite(_enablePin, HIGH ^ _enableInverted);
|
||||
}
|
||||
}
|
||||
|
||||
void AccelStepper_PCF8574_Soft::setPinsInverted(bool directionInvert, bool stepInvert, bool enableInvert)
|
||||
{
|
||||
_pinInverted[0] = stepInvert;
|
||||
_pinInverted[1] = directionInvert;
|
||||
_enableInverted = enableInvert;
|
||||
}
|
||||
|
||||
void AccelStepper_PCF8574_Soft::setPinsInverted(bool pin1Invert, bool pin2Invert, bool pin3Invert, bool pin4Invert, bool enableInvert)
|
||||
{
|
||||
_pinInverted[0] = pin1Invert;
|
||||
_pinInverted[1] = pin2Invert;
|
||||
_pinInverted[2] = pin3Invert;
|
||||
_pinInverted[3] = pin4Invert;
|
||||
_enableInverted = enableInvert;
|
||||
}
|
||||
|
||||
// Blocks until the target position is reached and stopped
|
||||
void AccelStepper_PCF8574_Soft::runToPosition()
|
||||
{
|
||||
while (run())
|
||||
;
|
||||
}
|
||||
|
||||
boolean AccelStepper_PCF8574_Soft::runSpeedToPosition()
|
||||
{
|
||||
if (_targetPos == _currentPos)
|
||||
return false;
|
||||
if (_targetPos >_currentPos)
|
||||
_direction = DIRECTION_CW;
|
||||
else
|
||||
_direction = DIRECTION_CCW;
|
||||
return runSpeed();
|
||||
}
|
||||
|
||||
// Blocks until the new target position is reached
|
||||
void AccelStepper_PCF8574_Soft::runToNewPosition(long position)
|
||||
{
|
||||
moveTo(position);
|
||||
runToPosition();
|
||||
}
|
||||
|
||||
void AccelStepper_PCF8574_Soft::stop()
|
||||
{
|
||||
if (_speed != 0.0)
|
||||
{
|
||||
long stepsToStop = (long)((_speed * _speed) / (2.0 * _acceleration)) + 1; // Equation 16 (+integer rounding)
|
||||
if (_speed > 0)
|
||||
move(stepsToStop);
|
||||
else
|
||||
move(-stepsToStop);
|
||||
}
|
||||
}
|
||||
|
||||
bool AccelStepper_PCF8574_Soft::isRunning()
|
||||
{
|
||||
return !(_speed == 0.0 && _targetPos == _currentPos);
|
||||
}
|
||||
@@ -0,0 +1,735 @@
|
||||
// AccelStepper_PCF8574_Soft.h
|
||||
//
|
||||
/// \mainpage AccelStepper_PCF8574_Soft library for Arduino
|
||||
///
|
||||
/// This is the Arduino AccelStepper_PCF8574_Soft library.
|
||||
/// It provides an object-oriented interface for 2, 3 or 4 pin stepper motors and motor drivers.
|
||||
///
|
||||
/// The standard Arduino IDE includes the Stepper library
|
||||
/// (http://arduino.cc/en/Reference/Stepper) for stepper motors. It is
|
||||
/// perfectly adequate for simple, single motor applications.
|
||||
///
|
||||
/// AccelStepper_PCF8574_Soft significantly improves on the standard Arduino Stepper library in several ways:
|
||||
/// \li Supports acceleration and deceleration
|
||||
/// \li Supports multiple simultaneous steppers, with independent concurrent stepping on each stepper
|
||||
/// \li API functions never delay() or block
|
||||
/// \li Supports 2, 3 and 4 wire steppers, plus 3 and 4 wire half steppers.
|
||||
/// \li Supports alternate stepping functions to enable support of AFMotor (https://github.com/adafruit/Adafruit-Motor-Shield-library)
|
||||
/// \li Supports stepper drivers such as the Sparkfun EasyDriver (based on 3967 driver chip)
|
||||
/// \li Very slow speeds are supported
|
||||
/// \li Extensive API
|
||||
/// \li Subclass support
|
||||
///
|
||||
/// The latest version of this documentation can be downloaded from
|
||||
/// http://www.airspayce.com/mikem/arduino/AccelStepper_PCF8574_Soft
|
||||
/// The version of the package that this documentation refers to can be downloaded
|
||||
/// from http://www.airspayce.com/mikem/arduino/AccelStepper_PCF8574_Soft/AccelStepper_PCF8574_Soft-1.59.zip
|
||||
///
|
||||
/// Example Arduino programs are included to show the main modes of use.
|
||||
///
|
||||
/// You can also find online help and discussion at http://groups.google.com/group/accelstepper
|
||||
/// Please use that group for all questions and discussions on this topic.
|
||||
/// Do not contact the author directly, unless it is to discuss commercial licensing.
|
||||
/// Before asking a question or reporting a bug, please read
|
||||
/// - http://en.wikipedia.org/wiki/Wikipedia:Reference_desk/How_to_ask_a_software_question
|
||||
/// - http://www.catb.org/esr/faqs/smart-questions.html
|
||||
/// - http://www.chiark.greenend.org.uk/~shgtatham/bugs.html
|
||||
///
|
||||
/// Tested on Arduino Diecimila and Mega with arduino-0018 & arduino-0021
|
||||
/// on OpenSuSE 11.1 and avr-libc-1.6.1-1.15,
|
||||
/// cross-avr-binutils-2.19-9.1, cross-avr-gcc-4.1.3_20080612-26.5.
|
||||
/// Tested on Teensy http://www.pjrc.com/teensy including Teensy 3.1 built using Arduino IDE 1.0.5 with
|
||||
/// teensyduino addon 1.18 and later.
|
||||
///
|
||||
/// \par Installation
|
||||
///
|
||||
/// Install in the usual way: unzip the distribution zip file to the libraries
|
||||
/// sub-folder of your sketchbook.
|
||||
///
|
||||
/// \par Theory
|
||||
///
|
||||
/// This code uses speed calculations as described in
|
||||
/// "Generate stepper-motor speed profiles in real time" by David Austin
|
||||
/// http://fab.cba.mit.edu/classes/MIT/961.09/projects/i0/Stepper_Motor_Speed_Profile.pdf or
|
||||
/// http://www.embedded.com/design/mcus-processors-and-socs/4006438/Generate-stepper-motor-speed-profiles-in-real-time or
|
||||
/// http://web.archive.org/web/20140705143928/http://fab.cba.mit.edu/classes/MIT/961.09/projects/i0/Stepper_Motor_Speed_Profile.pdf
|
||||
/// with the exception that AccelStepper_PCF8574_Soft uses steps per second rather than radians per second
|
||||
/// (because we dont know the step angle of the motor)
|
||||
/// An initial step interval is calculated for the first step, based on the desired acceleration
|
||||
/// On subsequent steps, shorter step intervals are calculated based
|
||||
/// on the previous step until max speed is achieved.
|
||||
///
|
||||
/// \par Adafruit Motor Shield V2
|
||||
///
|
||||
/// The included examples AFMotor_* are for Adafruit Motor Shield V1 and do not work with Adafruit Motor Shield V2.
|
||||
/// See https://github.com/adafruit/Adafruit_Motor_Shield_V2_Library for examples that work with Adafruit Motor Shield V2.
|
||||
///
|
||||
/// \par Donations
|
||||
///
|
||||
/// This library is offered under a free GPL license for those who want to use it that way.
|
||||
/// We try hard to keep it up to date, fix bugs
|
||||
/// and to provide free support. If this library has helped you save time or money, please consider donating at
|
||||
/// http://www.airspayce.com or here:
|
||||
///
|
||||
/// \htmlonly <form action="https://www.paypal.com/cgi-bin/webscr" method="post"><input type="hidden" name="cmd" value="_donations" /> <input type="hidden" name="business" value="mikem@airspayce.com" /> <input type="hidden" name="lc" value="AU" /> <input type="hidden" name="item_name" value="Airspayce" /> <input type="hidden" name="item_number" value="AccelStepper_PCF8574_Soft" /> <input type="hidden" name="currency_code" value="USD" /> <input type="hidden" name="bn" value="PP-DonationsBF:btn_donateCC_LG.gif:NonHosted" /> <input type="image" alt="PayPal — The safer, easier way to pay online." name="submit" src="https://www.paypalobjects.com/en_AU/i/btn/btn_donateCC_LG.gif" /> <img alt="" src="https://www.paypalobjects.com/en_AU/i/scr/pixel.gif" width="1" height="1" border="0" /></form> \endhtmlonly
|
||||
///
|
||||
/// \par Trademarks
|
||||
///
|
||||
/// AccelStepper_PCF8574_Soft is a trademark of AirSpayce Pty Ltd. The AccelStepper_PCF8574_Soft mark was first used on April 26 2010 for
|
||||
/// international trade, and is used only in relation to motor control hardware and software.
|
||||
/// It is not to be confused with any other similar marks covering other goods and services.
|
||||
///
|
||||
/// \par Copyright
|
||||
///
|
||||
/// This software is Copyright (C) 2010-2018 Mike McCauley. Use is subject to license
|
||||
/// conditions. The main licensing options available are GPL V2 or Commercial:
|
||||
///
|
||||
/// \par Open Source Licensing GPL V2
|
||||
/// This is the appropriate option if you want to share the source code of your
|
||||
/// application with everyone you distribute it to, and you also want to give them
|
||||
/// the right to share who uses it. If you wish to use this software under Open
|
||||
/// Source Licensing, you must contribute all your source code to the open source
|
||||
/// community in accordance with the GPL Version 2 when your application is
|
||||
/// distributed. See https://www.gnu.org/licenses/gpl-2.0.html
|
||||
///
|
||||
/// \par Commercial Licensing
|
||||
/// This is the appropriate option if you are creating proprietary applications
|
||||
/// and you are not prepared to distribute and share the source code of your
|
||||
/// application. To purchase a commercial license, contact info@airspayce.com
|
||||
///
|
||||
/// \par Revision History
|
||||
/// \version 1.0 Initial release
|
||||
///
|
||||
/// \version 1.1 Added speed() function to get the current speed.
|
||||
/// \version 1.2 Added runSpeedToPosition() submitted by Gunnar Arndt.
|
||||
/// \version 1.3 Added support for stepper drivers (ie with Step and Direction inputs) with _pins == 1
|
||||
/// \version 1.4 Added functional contructor to support AFMotor, contributed by Limor, with example sketches.
|
||||
/// \version 1.5 Improvements contributed by Peter Mousley: Use of microsecond steps and other speed improvements
|
||||
/// to increase max stepping speed to about 4kHz. New option for user to set the min allowed pulse width.
|
||||
/// Added checks for already running at max speed and skip further calcs if so.
|
||||
/// \version 1.6 Fixed a problem with wrapping of microsecond stepping that could cause stepping to hang.
|
||||
/// Reported by Sandy Noble.
|
||||
/// Removed redundant _lastRunTime member.
|
||||
/// \version 1.7 Fixed a bug where setCurrentPosition() did not always work as expected.
|
||||
/// Reported by Peter Linhart.
|
||||
/// \version 1.8 Added support for 4 pin half-steppers, requested by Harvey Moon
|
||||
/// \version 1.9 setCurrentPosition() now also sets motor speed to 0.
|
||||
/// \version 1.10 Builds on Arduino 1.0
|
||||
/// \version 1.11 Improvments from Michael Ellison:
|
||||
/// Added optional enable line support for stepper drivers
|
||||
/// Added inversion for step/direction/enable lines for stepper drivers
|
||||
/// \version 1.12 Announce Google Group
|
||||
/// \version 1.13 Improvements to speed calculation. Cost of calculation is now less in the worst case,
|
||||
/// and more or less constant in all cases. This should result in slightly beter high speed performance, and
|
||||
/// reduce anomalous speed glitches when other steppers are accelerating.
|
||||
/// However, its hard to see how to replace the sqrt() required at the very first step from 0 speed.
|
||||
/// \version 1.14 Fixed a problem with compiling under arduino 0021 reported by EmbeddedMan
|
||||
/// \version 1.15 Fixed a problem with runSpeedToPosition which did not correctly handle
|
||||
/// running backwards to a smaller target position. Added examples
|
||||
/// \version 1.16 Fixed some cases in the code where abs() was used instead of fabs().
|
||||
/// \version 1.17 Added example ProportionalControl
|
||||
/// \version 1.18 Fixed a problem: If one calls the funcion runSpeed() when Speed is zero, it makes steps
|
||||
/// without counting. reported by Friedrich, Klappenbach.
|
||||
/// \version 1.19 Added MotorInterfaceType and symbolic names for the number of pins to use
|
||||
/// for the motor interface. Updated examples to suit.
|
||||
/// Replaced individual pin assignment variables _pin1, _pin2 etc with array _pin[4].
|
||||
/// _pins member changed to _interface.
|
||||
/// Added _pinInverted array to simplify pin inversion operations.
|
||||
/// Added new function setOutputPins() which sets the motor output pins.
|
||||
/// It can be overridden in order to provide, say, serial output instead of parallel output
|
||||
/// Some refactoring and code size reduction.
|
||||
/// \version 1.20 Improved documentation and examples to show need for correctly
|
||||
/// specifying AccelStepper_PCF8574_Soft::FULL4WIRE and friends.
|
||||
/// \version 1.21 Fixed a problem where desiredSpeed could compute the wrong step acceleration
|
||||
/// when _speed was small but non-zero. Reported by Brian Schmalz.
|
||||
/// Precompute sqrt_twoa to improve performance and max possible stepping speed
|
||||
/// \version 1.22 Added Bounce.pde example
|
||||
/// Fixed a problem where calling moveTo(), setMaxSpeed(), setAcceleration() more
|
||||
/// frequently than the step time, even
|
||||
/// with the same values, would interfere with speed calcs. Now a new speed is computed
|
||||
/// only if there was a change in the set value. Reported by Brian Schmalz.
|
||||
/// \version 1.23 Rewrite of the speed algorithms in line with
|
||||
/// http://fab.cba.mit.edu/classes/MIT/961.09/projects/i0/Stepper_Motor_Speed_Profile.pdf
|
||||
/// Now expect smoother and more linear accelerations and decelerations. The desiredSpeed()
|
||||
/// function was removed.
|
||||
/// \version 1.24 Fixed a problem introduced in 1.23: with runToPosition, which did never returned
|
||||
/// \version 1.25 Now ignore attempts to set acceleration to 0.0
|
||||
/// \version 1.26 Fixed a problem where certina combinations of speed and accelration could cause
|
||||
/// oscillation about the target position.
|
||||
/// \version 1.27 Added stop() function to stop as fast as possible with current acceleration parameters.
|
||||
/// Also added new Quickstop example showing its use.
|
||||
/// \version 1.28 Fixed another problem where certain combinations of speed and acceleration could cause
|
||||
/// oscillation about the target position.
|
||||
/// Added support for 3 wire full and half steppers such as Hard Disk Drive spindle.
|
||||
/// Contributed by Yuri Ivatchkovitch.
|
||||
/// \version 1.29 Fixed a problem that could cause a DRIVER stepper to continually step
|
||||
/// with some sketches. Reported by Vadim.
|
||||
/// \version 1.30 Fixed a problem that could cause stepper to back up a few steps at the end of
|
||||
/// accelerated travel with certain speeds. Reported and patched by jolo.
|
||||
/// \version 1.31 Updated author and distribution location details to airspayce.com
|
||||
/// \version 1.32 Fixed a problem with enableOutputs() and setEnablePin on Arduino Due that
|
||||
/// prevented the enable pin changing stae correctly. Reported by Duane Bishop.
|
||||
/// \version 1.33 Fixed an error in example AFMotor_ConstantSpeed.pde did not setMaxSpeed();
|
||||
/// Fixed a problem that caused incorrect pin sequencing of FULL3WIRE and HALF3WIRE.
|
||||
/// Unfortunately this meant changing the signature for all step*() functions.
|
||||
/// Added example MotorShield, showing how to use AdaFruit Motor Shield to control
|
||||
/// a 3 phase motor such as a HDD spindle motor (and without using the AFMotor library.
|
||||
/// \version 1.34 Added setPinsInverted(bool pin1Invert, bool pin2Invert, bool pin3Invert, bool pin4Invert, bool enableInvert)
|
||||
/// to allow inversion of 2, 3 and 4 wire stepper pins. Requested by Oleg.
|
||||
/// \version 1.35 Removed default args from setPinsInverted(bool, bool, bool, bool, bool) to prevent ambiguity with
|
||||
/// setPinsInverted(bool, bool, bool). Reported by Mac Mac.
|
||||
/// \version 1.36 Changed enableOutputs() and disableOutputs() to be virtual so can be overridden.
|
||||
/// Added new optional argument 'enable' to constructor, which allows you toi disable the
|
||||
/// automatic enabling of outputs at construction time. Suggested by Guido.
|
||||
/// \version 1.37 Fixed a problem with step1 that could cause a rogue step in the
|
||||
/// wrong direction (or not,
|
||||
/// depending on the setup-time requirements of the connected hardware).
|
||||
/// Reported by Mark Tillotson.
|
||||
/// \version 1.38 run() function incorrectly always returned true. Updated function and doc so it returns true
|
||||
/// if the motor is still running to the target position.
|
||||
/// \version 1.39 Updated typos in keywords.txt, courtesey Jon Magill.
|
||||
/// \version 1.40 Updated documentation, including testing on Teensy 3.1
|
||||
/// \version 1.41 Fixed an error in the acceleration calculations, resulting in acceleration of haldf the intended value
|
||||
/// \version 1.42 Improved support for FULL3WIRE and HALF3WIRE output pins. These changes were in Yuri's original
|
||||
/// contribution but did not make it into production.<br>
|
||||
/// \version 1.43 Added DualMotorShield example. Shows how to use AccelStepper_PCF8574_Soft to control 2 x 2 phase steppers using the
|
||||
/// Itead Studio Arduino Dual Stepper Motor Driver Shield model IM120417015.<br>
|
||||
/// \version 1.44 examples/DualMotorShield/DualMotorShield.ino examples/DualMotorShield/DualMotorShield.pde
|
||||
/// was missing from the distribution.<br>
|
||||
/// \version 1.45 Fixed a problem where if setAcceleration was not called, there was no default
|
||||
/// acceleration. Reported by Michael Newman.<br>
|
||||
/// \version 1.45 Fixed inaccuracy in acceleration rate by using Equation 15, suggested by Sebastian Gracki.<br>
|
||||
/// Performance improvements in runSpeed suggested by Jaakko Fagerlund.<br>
|
||||
/// \version 1.46 Fixed error in documentation for runToPosition().
|
||||
/// Reinstated time calculations in runSpeed() since new version is reported
|
||||
/// not to work correctly under some circumstances. Reported by Oleg V Gavva.<br>
|
||||
/// \version 1.48 2015-08-25
|
||||
/// Added new class MultiStepper that can manage multiple AccelStepper_PCF8574_Softs,
|
||||
/// and cause them all to move
|
||||
/// to selected positions at such a (constant) speed that they all arrive at their
|
||||
/// target position at the same time. Suitable for X-Y flatbeds etc.<br>
|
||||
/// Added new method maxSpeed() to AccelStepper_PCF8574_Soft to return the currently configured maxSpeed.<br>
|
||||
/// \version 1.49 2016-01-02
|
||||
/// Testing with VID28 series instrument stepper motors and EasyDriver.
|
||||
/// OK, although with light pointers
|
||||
/// and slow speeds like 180 full steps per second the motor movement can be erratic,
|
||||
/// probably due to some mechanical resonance. Best to accelerate through this speed.<br>
|
||||
/// Added isRunning().<br>
|
||||
/// \version 1.50 2016-02-25
|
||||
/// AccelStepper_PCF8574_Soft::disableOutputs now sets the enable pion to OUTPUT mode if the enable pin is defined.
|
||||
/// Patch from Piet De Jong.<br>
|
||||
/// Added notes about the fact that AFMotor_* examples do not work with Adafruit Motor Shield V2.<br>
|
||||
/// \version 1.51 2016-03-24
|
||||
/// Fixed a problem reported by gregor: when resetting the stepper motor position using setCurrentPosition() the
|
||||
/// stepper speed is reset by setting _stepInterval to 0, but _speed is not
|
||||
/// reset. this results in the stepper motor not starting again when calling
|
||||
/// setSpeed() with the same speed the stepper was set to before.
|
||||
/// \version 1.52 2016-08-09
|
||||
/// Added MultiStepper to keywords.txt.
|
||||
/// Improvements to efficiency of AccelStepper_PCF8574_Soft::runSpeed() as suggested by David Grayson.
|
||||
/// Improvements to speed accuracy as suggested by David Grayson.
|
||||
/// \version 1.53 2016-08-14
|
||||
/// Backed out Improvements to speed accuracy from 1.52 as it did not work correctly.
|
||||
/// \version 1.54 2017-01-24
|
||||
/// Fixed some warnings about unused arguments.
|
||||
/// \version 1.55 2017-01-25
|
||||
/// Fixed another warning in MultiStepper.cpp
|
||||
/// \version 1.56 2017-02-03
|
||||
/// Fixed minor documentation error with DIRECTION_CCW and DIRECTION_CW. Reported by David Mutterer.
|
||||
/// Added link to Binpress commercial license purchasing.
|
||||
/// \version 1.57 2017-03-28
|
||||
/// _direction moved to protected at the request of Rudy Ercek.
|
||||
/// setMaxSpeed() and setAcceleration() now correct negative values to be positive.
|
||||
/// \version 1.58 2018-04-13
|
||||
/// Add initialisation for _enableInverted in constructor.
|
||||
/// \version 1.59 2018-08-28
|
||||
/// Update commercial licensing, remove binpress.
|
||||
///
|
||||
/// \author Mike McCauley (mikem@airspayce.com) DO NOT CONTACT THE AUTHOR DIRECTLY: USE THE LISTS
|
||||
// Copyright (C) 2009-2013 Mike McCauley
|
||||
// $Id: AccelStepper_PCF8574_Soft.h,v 1.27 2016/08/14 10:26:54 mikem Exp mikem $
|
||||
|
||||
#ifndef AccelStepper_PCF8574_Soft_h
|
||||
#define AccelStepper_PCF8574_Soft_h
|
||||
#include <SoftwareWire.h>
|
||||
#include "PCF8574_Soft.h"
|
||||
#include <stdlib.h>
|
||||
#if ARDUINO >= 100
|
||||
#include <Arduino.h>
|
||||
#else
|
||||
#include <WProgram.h>
|
||||
#include <wiring.h>
|
||||
#endif
|
||||
|
||||
// These defs cause trouble on some versions of Arduino
|
||||
#undef round
|
||||
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
/// \class AccelStepper_PCF8574_Soft AccelStepper_PCF8574_Soft.h <AccelStepper_PCF8574_Soft.h>
|
||||
/// \brief Support for stepper motors with acceleration etc.
|
||||
///
|
||||
/// This defines a single 2 or 4 pin stepper motor, or stepper moter with fdriver chip, with optional
|
||||
/// acceleration, deceleration, absolute positioning commands etc. Multiple
|
||||
/// simultaneous steppers are supported, all moving
|
||||
/// at different speeds and accelerations.
|
||||
///
|
||||
/// \par Operation
|
||||
/// This module operates by computing a step time in microseconds. The step
|
||||
/// time is recomputed after each step and after speed and acceleration
|
||||
/// parameters are changed by the caller. The time of each step is recorded in
|
||||
/// microseconds. The run() function steps the motor once if a new step is due.
|
||||
/// The run() function must be called frequently until the motor is in the
|
||||
/// desired position, after which time run() will do nothing.
|
||||
///
|
||||
/// \par Positioning
|
||||
/// Positions are specified by a signed long integer. At
|
||||
/// construction time, the current position of the motor is consider to be 0. Positive
|
||||
/// positions are clockwise from the initial position; negative positions are
|
||||
/// anticlockwise. The current position can be altered for instance after
|
||||
/// initialization positioning.
|
||||
///
|
||||
/// \par Caveats
|
||||
/// This is an open loop controller: If the motor stalls or is oversped,
|
||||
/// AccelStepper_PCF8574_Soft will not have a correct
|
||||
/// idea of where the motor really is (since there is no feedback of the motor's
|
||||
/// real position. We only know where we _think_ it is, relative to the
|
||||
/// initial starting point).
|
||||
///
|
||||
/// \par Performance
|
||||
/// The fastest motor speed that can be reliably supported is about 4000 steps per
|
||||
/// second at a clock frequency of 16 MHz on Arduino such as Uno etc.
|
||||
/// Faster processors can support faster stepping speeds.
|
||||
/// However, any speed less than that
|
||||
/// down to very slow speeds (much less than one per second) are also supported,
|
||||
/// provided the run() function is called frequently enough to step the motor
|
||||
/// whenever required for the speed set.
|
||||
/// Calling setAcceleration() is expensive,
|
||||
/// since it requires a square root to be calculated.
|
||||
///
|
||||
/// Gregor Christandl reports that with an Arduino Due and a simple test program,
|
||||
/// he measured 43163 steps per second using runSpeed(),
|
||||
/// and 16214 steps per second using run();
|
||||
class AccelStepper_PCF8574_Soft
|
||||
{
|
||||
public:
|
||||
/// \brief Symbolic names for number of pins.
|
||||
/// Use this in the pins argument the AccelStepper_PCF8574_Soft constructor to
|
||||
/// provide a symbolic name for the number of pins
|
||||
/// to use.
|
||||
typedef enum
|
||||
{
|
||||
FUNCTION = 0, ///< Use the functional interface, implementing your own driver functions (internal use only)
|
||||
DRIVER = 1, ///< Stepper Driver, 2 driver pins required
|
||||
FULL2WIRE = 2, ///< 2 wire stepper, 2 motor pins required
|
||||
FULL3WIRE = 3, ///< 3 wire stepper, such as HDD spindle, 3 motor pins required
|
||||
FULL4WIRE = 4, ///< 4 wire full stepper, 4 motor pins required
|
||||
HALF3WIRE = 6, ///< 3 wire half stepper, such as HDD spindle, 3 motor pins required
|
||||
HALF4WIRE = 8 ///< 4 wire half stepper, 4 motor pins required
|
||||
} MotorInterfaceType;
|
||||
|
||||
/// Constructor. You can have multiple simultaneous steppers, all moving
|
||||
/// at different speeds and accelerations, provided you call their run()
|
||||
/// functions at frequent enough intervals. Current Position is set to 0, target
|
||||
/// position is set to 0. MaxSpeed and Acceleration default to 1.0.
|
||||
/// The motor pins will be initialised to OUTPUT mode during the
|
||||
/// constructor by a call to enableOutputs().
|
||||
/// \param[in] interface Number of pins to interface to. Integer values are
|
||||
/// supported, but it is preferred to use the \ref MotorInterfaceType symbolic names.
|
||||
/// AccelStepper_PCF8574_Soft::DRIVER (1) means a stepper driver (with Step and Direction pins).
|
||||
/// If an enable line is also needed, call setEnablePin() after construction.
|
||||
/// You may also invert the pins using setPinsInverted().
|
||||
/// AccelStepper_PCF8574_Soft::FULL2WIRE (2) means a 2 wire stepper (2 pins required).
|
||||
/// AccelStepper_PCF8574_Soft::FULL3WIRE (3) means a 3 wire stepper, such as HDD spindle (3 pins required).
|
||||
/// AccelStepper_PCF8574_Soft::FULL4WIRE (4) means a 4 wire stepper (4 pins required).
|
||||
/// AccelStepper_PCF8574_Soft::HALF3WIRE (6) means a 3 wire half stepper, such as HDD spindle (3 pins required)
|
||||
/// AccelStepper_PCF8574_Soft::HALF4WIRE (8) means a 4 wire half stepper (4 pins required)
|
||||
/// Defaults to AccelStepper_PCF8574_Soft::FULL4WIRE (4) pins.
|
||||
/// \param[in] pin1 Arduino digital pin number for motor pin 1. Defaults
|
||||
/// to pin 2. For a AccelStepper_PCF8574_Soft::DRIVER (interface==1),
|
||||
/// this is the Step input to the driver. Low to high transition means to step)
|
||||
/// \param[in] pin2 Arduino digital pin number for motor pin 2. Defaults
|
||||
/// to pin 3. For a AccelStepper_PCF8574_Soft::DRIVER (interface==1),
|
||||
/// this is the Direction input the driver. High means forward.
|
||||
/// \param[in] pin3 Arduino digital pin number for motor pin 3. Defaults
|
||||
/// to pin 4.
|
||||
/// \param[in] pin4 Arduino digital pin number for motor pin 4. Defaults
|
||||
/// to pin 5.
|
||||
/// \param[in] enable If this is true (the default), enableOutputs() will be called to enable
|
||||
/// the output pins at construction time.
|
||||
AccelStepper_PCF8574_Soft(PCF8574_Soft *device, uint8_t interface = AccelStepper_PCF8574_Soft::FULL4WIRE, uint8_t pin1 = 2, uint8_t pin2 = 3, uint8_t pin3 = 4, uint8_t pin4 = 5, bool enable = true);
|
||||
|
||||
/// Alternate Constructor which will call your own functions for forward and backward steps.
|
||||
/// You can have multiple simultaneous steppers, all moving
|
||||
/// at different speeds and accelerations, provided you call their run()
|
||||
/// functions at frequent enough intervals. Current Position is set to 0, target
|
||||
/// position is set to 0. MaxSpeed and Acceleration default to 1.0.
|
||||
/// Any motor initialization should happen before hand, no pins are used or initialized.
|
||||
/// \param[in] forward void-returning procedure that will make a forward step
|
||||
/// \param[in] backward void-returning procedure that will make a backward step
|
||||
|
||||
/// Set the target position. The run() function will try to move the motor (at most one step per call)
|
||||
/// from the current position to the target position set by the most
|
||||
/// recent call to this function. Caution: moveTo() also recalculates the speed for the next step.
|
||||
/// If you are trying to use constant speed movements, you should call setSpeed() after calling moveTo().
|
||||
/// \param[in] absolute The desired absolute position. Negative is
|
||||
/// anticlockwise from the 0 position.
|
||||
void moveTo(long absolute);
|
||||
|
||||
/// Set the target position relative to the current position
|
||||
/// \param[in] relative The desired position relative to the current position. Negative is
|
||||
/// anticlockwise from the current position.
|
||||
void move(long relative);
|
||||
|
||||
/// Poll the motor and step it if a step is due, implementing
|
||||
/// accelerations and decelerations to acheive the target position. You must call this as
|
||||
/// frequently as possible, but at least once per minimum step time interval,
|
||||
/// preferably in your main loop. Note that each call to run() will make at most one step, and then only when a step is due,
|
||||
/// based on the current speed and the time since the last step.
|
||||
/// \return true if the motor is still running to the target position.
|
||||
boolean run();
|
||||
|
||||
/// Poll the motor and step it if a step is due, implementing a constant
|
||||
/// speed as set by the most recent call to setSpeed(). You must call this as
|
||||
/// frequently as possible, but at least once per step interval,
|
||||
/// \return true if the motor was stepped.
|
||||
boolean runSpeed();
|
||||
|
||||
/// Sets the maximum permitted speed. The run() function will accelerate
|
||||
/// up to the speed set by this function.
|
||||
/// Caution: the maximum speed achievable depends on your processor and clock speed.
|
||||
/// The default maxSpeed is 1.0 steps per second.
|
||||
/// \param[in] speed The desired maximum speed in steps per second. Must
|
||||
/// be > 0. Caution: Speeds that exceed the maximum speed supported by the processor may
|
||||
/// Result in non-linear accelerations and decelerations.
|
||||
void setMaxSpeed(float speed);
|
||||
|
||||
/// returns the maximum speed configured for this stepper
|
||||
/// that was previously set by setMaxSpeed();
|
||||
/// \return The currently configured maximum speed
|
||||
float maxSpeed();
|
||||
|
||||
/// Sets the acceleration/deceleration rate.
|
||||
/// \param[in] acceleration The desired acceleration in steps per second
|
||||
/// per second. Must be > 0.0. This is an expensive call since it requires a square
|
||||
/// root to be calculated. Dont call more ofthen than needed
|
||||
void setAcceleration(float acceleration);
|
||||
|
||||
/// Sets the desired constant speed for use with runSpeed().
|
||||
/// \param[in] speed The desired constant speed in steps per
|
||||
/// second. Positive is clockwise. Speeds of more than 1000 steps per
|
||||
/// second are unreliable. Very slow speeds may be set (eg 0.00027777 for
|
||||
/// once per hour, approximately. Speed accuracy depends on the Arduino
|
||||
/// crystal. Jitter depends on how frequently you call the runSpeed() function.
|
||||
/// The speed will be limited by the current value of setMaxSpeed()
|
||||
void setSpeed(float speed);
|
||||
|
||||
/// The most recently set speed
|
||||
/// \return the most recent speed in steps per second
|
||||
float speed();
|
||||
|
||||
/// The distance from the current position to the target position.
|
||||
/// \return the distance from the current position to the target position
|
||||
/// in steps. Positive is clockwise from the current position.
|
||||
long distanceToGo();
|
||||
|
||||
/// The most recently set target position.
|
||||
/// \return the target position
|
||||
/// in steps. Positive is clockwise from the 0 position.
|
||||
long targetPosition();
|
||||
|
||||
/// The currently motor position.
|
||||
/// \return the current motor position
|
||||
/// in steps. Positive is clockwise from the 0 position.
|
||||
long currentPosition();
|
||||
|
||||
/// Resets the current position of the motor, so that wherever the motor
|
||||
/// happens to be right now is considered to be the new 0 position. Useful
|
||||
/// for setting a zero position on a stepper after an initial hardware
|
||||
/// positioning move.
|
||||
/// Has the side effect of setting the current motor speed to 0.
|
||||
/// \param[in] position The position in steps of wherever the motor
|
||||
/// happens to be right now.
|
||||
void setCurrentPosition(long position);
|
||||
|
||||
/// Moves the motor (with acceleration/deceleration)
|
||||
/// to the target position and blocks until it is at
|
||||
/// position. Dont use this in event loops, since it blocks.
|
||||
void runToPosition();
|
||||
|
||||
/// Runs at the currently selected speed until the target position is reached
|
||||
/// Does not implement accelerations.
|
||||
/// \return true if it stepped
|
||||
boolean runSpeedToPosition();
|
||||
|
||||
/// Moves the motor (with acceleration/deceleration)
|
||||
/// to the new target position and blocks until it is at
|
||||
/// position. Dont use this in event loops, since it blocks.
|
||||
/// \param[in] position The new target position.
|
||||
void runToNewPosition(long position);
|
||||
|
||||
/// Sets a new target position that causes the stepper
|
||||
/// to stop as quickly as possible, using the current speed and acceleration parameters.
|
||||
void stop();
|
||||
|
||||
/// Disable motor pin outputs by setting them all LOW
|
||||
/// Depending on the design of your electronics this may turn off
|
||||
/// the power to the motor coils, saving power.
|
||||
/// This is useful to support Arduino low power modes: disable the outputs
|
||||
/// during sleep and then reenable with enableOutputs() before stepping
|
||||
/// again.
|
||||
/// If the enable Pin is defined, sets it to OUTPUT mode and clears the pin to disabled.
|
||||
virtual void disableOutputs();
|
||||
|
||||
/// Enable motor pin outputs by setting the motor pins to OUTPUT
|
||||
/// mode. Called automatically by the constructor.
|
||||
/// If the enable Pin is defined, sets it to OUTPUT mode and sets the pin to enabled.
|
||||
virtual void enableOutputs();
|
||||
|
||||
/// Sets the minimum pulse width allowed by the stepper driver. The minimum practical pulse width is
|
||||
/// approximately 20 microseconds. Times less than 20 microseconds
|
||||
/// will usually result in 20 microseconds or so.
|
||||
/// \param[in] minWidth The minimum pulse width in microseconds.
|
||||
void setMinPulseWidth(unsigned int minWidth);
|
||||
|
||||
/// Sets the enable pin number for stepper drivers.
|
||||
/// 0xFF indicates unused (default).
|
||||
/// Otherwise, if a pin is set, the pin will be turned on when
|
||||
/// enableOutputs() is called and switched off when disableOutputs()
|
||||
/// is called.
|
||||
/// \param[in] enablePin Arduino digital pin number for motor enable
|
||||
/// \sa setPinsInverted
|
||||
void setEnablePin(uint8_t enablePin = 0xff);
|
||||
|
||||
/// Sets the inversion for stepper driver pins
|
||||
/// \param[in] directionInvert True for inverted direction pin, false for non-inverted
|
||||
/// \param[in] stepInvert True for inverted step pin, false for non-inverted
|
||||
/// \param[in] enableInvert True for inverted enable pin, false (default) for non-inverted
|
||||
void setPinsInverted(bool directionInvert = false, bool stepInvert = false, bool enableInvert = false);
|
||||
|
||||
/// Sets the inversion for 2, 3 and 4 wire stepper pins
|
||||
/// \param[in] pin1Invert True for inverted pin1, false for non-inverted
|
||||
/// \param[in] pin2Invert True for inverted pin2, false for non-inverted
|
||||
/// \param[in] pin3Invert True for inverted pin3, false for non-inverted
|
||||
/// \param[in] pin4Invert True for inverted pin4, false for non-inverted
|
||||
/// \param[in] enableInvert True for inverted enable pin, false (default) for non-inverted
|
||||
void setPinsInverted(bool pin1Invert, bool pin2Invert, bool pin3Invert, bool pin4Invert, bool enableInvert);
|
||||
|
||||
/// Checks to see if the motor is currently running to a target
|
||||
/// \return true if the speed is not zero or not at the target position
|
||||
bool isRunning();
|
||||
|
||||
protected:
|
||||
|
||||
/// \brief Direction indicator
|
||||
/// Symbolic names for the direction the motor is turning
|
||||
typedef enum
|
||||
{
|
||||
DIRECTION_CCW = 0, ///< Counter-Clockwise
|
||||
DIRECTION_CW = 1 ///< Clockwise
|
||||
} Direction;
|
||||
|
||||
/// Forces the library to compute a new instantaneous speed and set that as
|
||||
/// the current speed. It is called by
|
||||
/// the library:
|
||||
/// \li after each step
|
||||
/// \li after change to maxSpeed through setMaxSpeed()
|
||||
/// \li after change to acceleration through setAcceleration()
|
||||
/// \li after change to target position (relative or absolute) through
|
||||
/// move() or moveTo()
|
||||
void computeNewSpeed();
|
||||
|
||||
/// Low level function to set the motor output pins
|
||||
/// bit 0 of the mask corresponds to _pin[0]
|
||||
/// bit 1 of the mask corresponds to _pin[1]
|
||||
/// You can override this to impment, for example serial chip output insted of using the
|
||||
/// output pins directly
|
||||
virtual void setOutputPins(uint8_t mask);
|
||||
|
||||
/// Called to execute a step. Only called when a new step is
|
||||
/// required. Subclasses may override to implement new stepping
|
||||
/// interfaces. The default calls step1(), step2(), step4() or step8() depending on the
|
||||
/// number of pins defined for the stepper.
|
||||
/// \param[in] step The current step phase number (0 to 7)
|
||||
virtual void step(long step);
|
||||
|
||||
/// Called to execute a step using stepper functions (pins = 0) Only called when a new step is
|
||||
/// required. Calls _forward() or _backward() to perform the step
|
||||
/// \param[in] step The current step phase number (0 to 7)
|
||||
virtual void step0(long step);
|
||||
|
||||
/// Called to execute a step on a stepper driver (ie where pins == 1). Only called when a new step is
|
||||
/// required. Subclasses may override to implement new stepping
|
||||
/// interfaces. The default sets or clears the outputs of Step pin1 to step,
|
||||
/// and sets the output of _pin2 to the desired direction. The Step pin (_pin1) is pulsed for 1 microsecond
|
||||
/// which is the minimum STEP pulse width for the 3967 driver.
|
||||
/// \param[in] step The current step phase number (0 to 7)
|
||||
virtual void step1(long step);
|
||||
|
||||
/// Called to execute a step on a 2 pin motor. Only called when a new step is
|
||||
/// required. Subclasses may override to implement new stepping
|
||||
/// interfaces. The default sets or clears the outputs of pin1 and pin2
|
||||
/// \param[in] step The current step phase number (0 to 7)
|
||||
virtual void step2(long step);
|
||||
|
||||
/// Called to execute a step on a 3 pin motor, such as HDD spindle. Only called when a new step is
|
||||
/// required. Subclasses may override to implement new stepping
|
||||
/// interfaces. The default sets or clears the outputs of pin1, pin2,
|
||||
/// pin3
|
||||
/// \param[in] step The current step phase number (0 to 7)
|
||||
virtual void step3(long step);
|
||||
|
||||
/// Called to execute a step on a 4 pin motor. Only called when a new step is
|
||||
/// required. Subclasses may override to implement new stepping
|
||||
/// interfaces. The default sets or clears the outputs of pin1, pin2,
|
||||
/// pin3, pin4.
|
||||
/// \param[in] step The current step phase number (0 to 7)
|
||||
virtual void step4(long step);
|
||||
|
||||
/// Called to execute a step on a 3 pin motor, such as HDD spindle. Only called when a new step is
|
||||
/// required. Subclasses may override to implement new stepping
|
||||
/// interfaces. The default sets or clears the outputs of pin1, pin2,
|
||||
/// pin3
|
||||
/// \param[in] step The current step phase number (0 to 7)
|
||||
virtual void step6(long step);
|
||||
|
||||
/// Called to execute a step on a 4 pin half-steper motor. Only called when a new step is
|
||||
/// required. Subclasses may override to implement new stepping
|
||||
/// interfaces. The default sets or clears the outputs of pin1, pin2,
|
||||
/// pin3, pin4.
|
||||
/// \param[in] step The current step phase number (0 to 7)
|
||||
virtual void step8(long step);
|
||||
|
||||
/// Current direction motor is spinning in
|
||||
/// Protected because some peoples subclasses need it to be so
|
||||
boolean _direction; // 1 == CW
|
||||
|
||||
private:
|
||||
PCF8574_Soft *_device;
|
||||
/// Number of pins on the stepper motor. Permits 2 or 4. 2 pins is a
|
||||
/// bipolar, and 4 pins is a unipolar.
|
||||
uint8_t _interface; // 0, 1, 2, 4, 8, See MotorInterfaceType
|
||||
|
||||
/// Arduino pin number assignments for the 2 or 4 pins required to interface to the
|
||||
/// stepper motor or driver
|
||||
uint8_t _pin[4];
|
||||
|
||||
/// Whether the _pins is inverted or not
|
||||
uint8_t _pinInverted[4];
|
||||
|
||||
/// The current absolution position in steps.
|
||||
long _currentPos; // Steps
|
||||
|
||||
/// The target position in steps. The AccelStepper_PCF8574_Soft library will move the
|
||||
/// motor from the _currentPos to the _targetPos, taking into account the
|
||||
/// max speed, acceleration and deceleration
|
||||
long _targetPos; // Steps
|
||||
|
||||
/// The current motos speed in steps per second
|
||||
/// Positive is clockwise
|
||||
float _speed; // Steps per second
|
||||
|
||||
/// The maximum permitted speed in steps per second. Must be > 0.
|
||||
float _maxSpeed;
|
||||
|
||||
/// The acceleration to use to accelerate or decelerate the motor in steps
|
||||
/// per second per second. Must be > 0
|
||||
float _acceleration;
|
||||
float _sqrt_twoa; // Precomputed sqrt(2*_acceleration)
|
||||
|
||||
/// The current interval between steps in microseconds.
|
||||
/// 0 means the motor is currently stopped with _speed == 0
|
||||
unsigned long _stepInterval;
|
||||
|
||||
/// The last step time in microseconds
|
||||
unsigned long _lastStepTime;
|
||||
|
||||
/// The minimum allowed pulse width in microseconds
|
||||
unsigned int _minPulseWidth;
|
||||
|
||||
/// Is the direction pin inverted?
|
||||
///bool _dirInverted; /// Moved to _pinInverted[1]
|
||||
|
||||
/// Is the step pin inverted?
|
||||
///bool _stepInverted; /// Moved to _pinInverted[0]
|
||||
|
||||
/// Is the enable pin inverted?
|
||||
bool _enableInverted;
|
||||
|
||||
/// Enable pin for stepper driver, or 0xFF if unused.
|
||||
uint8_t _enablePin;
|
||||
|
||||
/// The pointer to a forward-step procedure
|
||||
void (*_forward)();
|
||||
|
||||
/// The pointer to a backward-step procedure
|
||||
void (*_backward)();
|
||||
|
||||
/// The step counter for speed calculations
|
||||
long _n;
|
||||
|
||||
/// Initial step size in microseconds
|
||||
float _c0;
|
||||
|
||||
/// Last step size in microseconds
|
||||
float _cn;
|
||||
|
||||
/// Min step size in microseconds based on maxSpeed
|
||||
float _cmin; // at max speed
|
||||
|
||||
};
|
||||
|
||||
/// @example Random.pde
|
||||
/// Make a single stepper perform random changes in speed, position and acceleration
|
||||
|
||||
/// @example Overshoot.pde
|
||||
/// Check overshoot handling
|
||||
/// which sets a new target position and then waits until the stepper has
|
||||
/// achieved it. This is used for testing the handling of overshoots
|
||||
|
||||
/// @example MultipleSteppers.pde
|
||||
/// Shows how to multiple simultaneous steppers
|
||||
/// Runs one stepper forwards and backwards, accelerating and decelerating
|
||||
/// at the limits. Runs other steppers at the same time
|
||||
|
||||
/// @example ConstantSpeed.pde
|
||||
/// Shows how to run AccelStepper_PCF8574_Soft in the simplest,
|
||||
/// fixed speed mode with no accelerations
|
||||
|
||||
/// @example Blocking.pde
|
||||
/// Shows how to use the blocking call runToNewPosition
|
||||
/// Which sets a new target position and then waits until the stepper has
|
||||
/// achieved it.
|
||||
|
||||
/// @example AFMotor_MultiStepper.pde
|
||||
/// Control both Stepper motors at the same time with different speeds
|
||||
/// and accelerations.
|
||||
|
||||
/// @example AFMotor_ConstantSpeed.pde
|
||||
/// Shows how to run AccelStepper_PCF8574_Soft in the simplest,
|
||||
/// fixed speed mode with no accelerations
|
||||
|
||||
/// @example ProportionalControl.pde
|
||||
/// Make a single stepper follow the analog value read from a pot or whatever
|
||||
/// The stepper will move at a constant speed to each newly set posiiton,
|
||||
/// depending on the value of the pot.
|
||||
|
||||
/// @example Bounce.pde
|
||||
/// Make a single stepper bounce from one limit to another, observing
|
||||
/// accelrations at each end of travel
|
||||
|
||||
/// @example Quickstop.pde
|
||||
/// Check stop handling.
|
||||
/// Calls stop() while the stepper is travelling at full speed, causing
|
||||
/// the stepper to stop as quickly as possible, within the constraints of the
|
||||
/// current acceleration.
|
||||
|
||||
/// @example MotorShield.pde
|
||||
/// Shows how to use AccelStepper_PCF8574_Soft to control a 3-phase motor, such as a HDD spindle motor
|
||||
/// using the Adafruit Motor Shield http://www.ladyada.net/make/mshield/index.html.
|
||||
|
||||
/// @example DualMotorShield.pde
|
||||
/// Shows how to use AccelStepper_PCF8574_Soft to control 2 x 2 phase steppers using the
|
||||
/// Itead Studio Arduino Dual Stepper Motor Driver Shield
|
||||
/// model IM120417015
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,73 @@
|
||||
// MultiStepper_PCF8574_Soft.cpp
|
||||
//
|
||||
// Copyright (C) 2015 Mike McCauley
|
||||
// $Id: MultiStepper_PCF8574_Soft.cpp,v 1.2 2015/10/04 05:16:38 mikem Exp $
|
||||
|
||||
#include "MultiStepper_PCF8574_Soft.h"
|
||||
#include "AccelStepper_PCF8574_Soft.h"
|
||||
|
||||
MultiStepper_PCF8574_Soft::MultiStepper_PCF8574_Soft()
|
||||
: _num_steppers(0)
|
||||
{
|
||||
}
|
||||
|
||||
boolean MultiStepper_PCF8574_Soft::addStepper(AccelStepper_PCF8574_Soft& stepper)
|
||||
{
|
||||
if (_num_steppers >= MULTISTEPPER_MAX_STEPPERS)
|
||||
return false; // No room for more
|
||||
_steppers[_num_steppers++] = &stepper;
|
||||
return true;
|
||||
}
|
||||
|
||||
void MultiStepper_PCF8574_Soft::moveTo(long absolute[])
|
||||
{
|
||||
// First find the stepper that will take the longest time to move
|
||||
float longestTime = 0.0;
|
||||
|
||||
uint8_t i;
|
||||
for (i = 0; i < _num_steppers; i++)
|
||||
{
|
||||
long thisDistance = absolute[i] - _steppers[i]->currentPosition();
|
||||
float thisTime = abs(thisDistance) / _steppers[i]->maxSpeed();
|
||||
|
||||
if (thisTime > longestTime)
|
||||
longestTime = thisTime;
|
||||
}
|
||||
|
||||
if (longestTime > 0.0)
|
||||
{
|
||||
// Now work out a new max speed for each stepper so they will all
|
||||
// arrived at the same time of longestTime
|
||||
for (i = 0; i < _num_steppers; i++)
|
||||
{
|
||||
long thisDistance = absolute[i] - _steppers[i]->currentPosition();
|
||||
float thisSpeed = thisDistance / longestTime;
|
||||
_steppers[i]->moveTo(absolute[i]); // New target position (resets speed)
|
||||
_steppers[i]->setSpeed(thisSpeed); // New speed
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Returns true if any motor is still running to the target position.
|
||||
boolean MultiStepper_PCF8574_Soft::run()
|
||||
{
|
||||
uint8_t i;
|
||||
boolean ret = false;
|
||||
for (i = 0; i < _num_steppers; i++)
|
||||
{
|
||||
if ( _steppers[i]->distanceToGo() != 0)
|
||||
{
|
||||
_steppers[i]->runSpeed();
|
||||
ret = true;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Blocks until all steppers reach their target position and are stopped
|
||||
void MultiStepper_PCF8574_Soft::runSpeedToPosition()
|
||||
{
|
||||
while (run())
|
||||
;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,78 @@
|
||||
// MultiStepper_PCF8574_Soft.h
|
||||
|
||||
#ifndef MultiStepper_PCF8574_Soft_h
|
||||
#define MultiStepper_PCF8574_Soft_h
|
||||
|
||||
#include <stdlib.h>
|
||||
#if ARDUINO >= 100
|
||||
#include <Arduino.h>
|
||||
#else
|
||||
#include <WProgram.h>
|
||||
#include <wiring.h>
|
||||
#endif
|
||||
|
||||
#define MULTISTEPPER_MAX_STEPPERS 10
|
||||
|
||||
class AccelStepper_PCF8574_Soft;
|
||||
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
/// \class MultiStepper_PCF8574_Soft MultiStepper_PCF8574_Soft.h <MultiStepper_PCF8574_Soft.h>
|
||||
/// \brief Operate multiple AccelStepper_PCF8574_Softs in a co-ordinated fashion
|
||||
///
|
||||
/// This class can manage multiple AccelStepper_PCF8574_Softs (up to MULTISTEPPER_MAX_STEPPERS = 10),
|
||||
/// and cause them all to move
|
||||
/// to selected positions at such a (constant) speed that they all arrive at their
|
||||
/// target position at the same time. This can be used to support devices with multiple steppers
|
||||
/// on say multiple axes to cause linear diagonal motion. Suitable for use with X-Y plotters, flatbeds,
|
||||
/// 3D printers etc
|
||||
/// to get linear straight line movement between arbitrary 2d (or 3d or ...) positions.
|
||||
///
|
||||
/// Caution: only constant speed stepper motion is supported: acceleration and deceleration is not supported
|
||||
/// All the steppers managed by MultiStepper_PCF8574_Soft will step at a constant speed to their
|
||||
/// target (albeit perhaps different speeds for each stepper).
|
||||
class MultiStepper_PCF8574_Soft
|
||||
{
|
||||
public:
|
||||
/// Constructor
|
||||
MultiStepper_PCF8574_Soft();
|
||||
|
||||
/// Add a stepper to the set of managed steppers
|
||||
/// There is an upper limit of MULTISTEPPER_MAX_STEPPERS = 10 to the number of steppers that can be managed
|
||||
/// \param[in] stepper Reference to a stepper to add to the managed list
|
||||
/// \return true if successful. false if the number of managed steppers would exceed MULTISTEPPER_MAX_STEPPERS
|
||||
boolean addStepper(AccelStepper_PCF8574_Soft& stepper);
|
||||
|
||||
/// Set the target positions of all managed steppers
|
||||
/// according to a coordinate array.
|
||||
/// New speeds will be computed for each stepper so they will all arrive at their
|
||||
/// respective targets at very close to the same time.
|
||||
/// \param[in] absolute An array of desired absolute stepper positions. absolute[0] will be used to set
|
||||
/// the absolute position of the first stepper added by addStepper() etc. The array must be at least as long as
|
||||
/// the number of steppers that have been added by addStepper, else results are undefined.
|
||||
void moveTo(long absolute[]);
|
||||
|
||||
/// Calls runSpeed() on all the managed steppers
|
||||
/// that have not acheived their target position.
|
||||
/// \return true if any stepper is still in the process of running to its target position.
|
||||
boolean run();
|
||||
|
||||
/// Runs all managed steppers until they acheived their target position.
|
||||
/// Blocks until all that position is acheived. If you dont
|
||||
/// want blocking consider using run() instead.
|
||||
void runSpeedToPosition();
|
||||
|
||||
private:
|
||||
/// Array of pointers to the steppers we are controlling.
|
||||
/// Fills from 0 onwards
|
||||
AccelStepper_PCF8574_Soft* _steppers[MULTISTEPPER_MAX_STEPPERS];
|
||||
|
||||
/// Number of steppers we are controlling and the number
|
||||
/// of steppers in _steppers[]
|
||||
uint8_t _num_steppers;
|
||||
};
|
||||
|
||||
/// @example MultiStepper_PCF8574_Soft.pde
|
||||
/// Use MultiStepper_PCF8574_Soft class to manage multiple steppers and make them all move to
|
||||
/// the same position at the same time for linear 2d (or 3d) motion.
|
||||
|
||||
#endif
|
||||
667
arduino-cli/libraries/Adafruit-Motor-Shield-library/AFMotor.cpp
Normal file
667
arduino-cli/libraries/Adafruit-Motor-Shield-library/AFMotor.cpp
Normal file
@@ -0,0 +1,667 @@
|
||||
// Adafruit Motor shield library
|
||||
// copyright Adafruit Industries LLC, 2009
|
||||
// this code is public domain, enjoy!
|
||||
|
||||
|
||||
#if (ARDUINO >= 100)
|
||||
#include "Arduino.h"
|
||||
#else
|
||||
#if defined(__AVR__)
|
||||
#include <avr/io.h>
|
||||
#endif
|
||||
#include "WProgram.h"
|
||||
#endif
|
||||
|
||||
#include "AFMotor.h"
|
||||
|
||||
|
||||
|
||||
static uint8_t latch_state;
|
||||
|
||||
#if (MICROSTEPS == 8)
|
||||
uint8_t microstepcurve[] = {0, 50, 98, 142, 180, 212, 236, 250, 255};
|
||||
#elif (MICROSTEPS == 16)
|
||||
uint8_t microstepcurve[] = {0, 25, 50, 74, 98, 120, 141, 162, 180, 197, 212, 225, 236, 244, 250, 253, 255};
|
||||
#endif
|
||||
|
||||
AFMotorController::AFMotorController(void) {
|
||||
TimerInitalized = false;
|
||||
}
|
||||
|
||||
void AFMotorController::enable(void) {
|
||||
// setup the latch
|
||||
/*
|
||||
LATCH_DDR |= _BV(LATCH);
|
||||
ENABLE_DDR |= _BV(ENABLE);
|
||||
CLK_DDR |= _BV(CLK);
|
||||
SER_DDR |= _BV(SER);
|
||||
*/
|
||||
pinMode(MOTORLATCH, OUTPUT);
|
||||
pinMode(MOTORENABLE, OUTPUT);
|
||||
pinMode(MOTORDATA, OUTPUT);
|
||||
pinMode(MOTORCLK, OUTPUT);
|
||||
|
||||
latch_state = 0;
|
||||
|
||||
latch_tx(); // "reset"
|
||||
|
||||
//ENABLE_PORT &= ~_BV(ENABLE); // enable the chip outputs!
|
||||
digitalWrite(MOTORENABLE, LOW);
|
||||
}
|
||||
|
||||
|
||||
void AFMotorController::latch_tx(void) {
|
||||
uint8_t i;
|
||||
|
||||
//LATCH_PORT &= ~_BV(LATCH);
|
||||
digitalWrite(MOTORLATCH, LOW);
|
||||
|
||||
//SER_PORT &= ~_BV(SER);
|
||||
digitalWrite(MOTORDATA, LOW);
|
||||
|
||||
for (i=0; i<8; i++) {
|
||||
//CLK_PORT &= ~_BV(CLK);
|
||||
digitalWrite(MOTORCLK, LOW);
|
||||
|
||||
if (latch_state & _BV(7-i)) {
|
||||
//SER_PORT |= _BV(SER);
|
||||
digitalWrite(MOTORDATA, HIGH);
|
||||
} else {
|
||||
//SER_PORT &= ~_BV(SER);
|
||||
digitalWrite(MOTORDATA, LOW);
|
||||
}
|
||||
//CLK_PORT |= _BV(CLK);
|
||||
digitalWrite(MOTORCLK, HIGH);
|
||||
}
|
||||
//LATCH_PORT |= _BV(LATCH);
|
||||
digitalWrite(MOTORLATCH, HIGH);
|
||||
}
|
||||
|
||||
static AFMotorController MC;
|
||||
|
||||
/******************************************
|
||||
MOTORS
|
||||
******************************************/
|
||||
inline void initPWM1(uint8_t freq) {
|
||||
#if defined(__AVR_ATmega8__) || \
|
||||
defined(__AVR_ATmega48__) || \
|
||||
defined(__AVR_ATmega88__) || \
|
||||
defined(__AVR_ATmega168__) || \
|
||||
defined(__AVR_ATmega328P__)
|
||||
// use PWM from timer2A on PB3 (Arduino pin #11)
|
||||
TCCR2A |= _BV(COM2A1) | _BV(WGM20) | _BV(WGM21); // fast PWM, turn on oc2a
|
||||
TCCR2B = freq & 0x7;
|
||||
OCR2A = 0;
|
||||
#elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
|
||||
// on arduino mega, pin 11 is now PB5 (OC1A)
|
||||
TCCR1A |= _BV(COM1A1) | _BV(WGM10); // fast PWM, turn on oc1a
|
||||
TCCR1B = (freq & 0x7) | _BV(WGM12);
|
||||
OCR1A = 0;
|
||||
#elif defined(__PIC32MX__)
|
||||
#if defined(PIC32_USE_PIN9_FOR_M1_PWM)
|
||||
// Make sure that pin 11 is an input, since we have tied together 9 and 11
|
||||
pinMode(9, OUTPUT);
|
||||
pinMode(11, INPUT);
|
||||
if (!MC.TimerInitalized)
|
||||
{ // Set up Timer2 for 80MHz counting fro 0 to 256
|
||||
T2CON = 0x8000 | ((freq & 0x07) << 4); // ON=1, FRZ=0, SIDL=0, TGATE=0, TCKPS=<freq>, T32=0, TCS=0; // ON=1, FRZ=0, SIDL=0, TGATE=0, TCKPS=0, T32=0, TCS=0
|
||||
TMR2 = 0x0000;
|
||||
PR2 = 0x0100;
|
||||
MC.TimerInitalized = true;
|
||||
}
|
||||
// Setup OC4 (pin 9) in PWM mode, with Timer2 as timebase
|
||||
OC4CON = 0x8006; // OC32 = 0, OCTSEL=0, OCM=6
|
||||
OC4RS = 0x0000;
|
||||
OC4R = 0x0000;
|
||||
#elif defined(PIC32_USE_PIN10_FOR_M1_PWM)
|
||||
// Make sure that pin 11 is an input, since we have tied together 9 and 11
|
||||
pinMode(10, OUTPUT);
|
||||
pinMode(11, INPUT);
|
||||
if (!MC.TimerInitalized)
|
||||
{ // Set up Timer2 for 80MHz counting fro 0 to 256
|
||||
T2CON = 0x8000 | ((freq & 0x07) << 4); // ON=1, FRZ=0, SIDL=0, TGATE=0, TCKPS=<freq>, T32=0, TCS=0; // ON=1, FRZ=0, SIDL=0, TGATE=0, TCKPS=0, T32=0, TCS=0
|
||||
TMR2 = 0x0000;
|
||||
PR2 = 0x0100;
|
||||
MC.TimerInitalized = true;
|
||||
}
|
||||
// Setup OC5 (pin 10) in PWM mode, with Timer2 as timebase
|
||||
OC5CON = 0x8006; // OC32 = 0, OCTSEL=0, OCM=6
|
||||
OC5RS = 0x0000;
|
||||
OC5R = 0x0000;
|
||||
#else
|
||||
// If we are not using PWM for pin 11, then just do digital
|
||||
digitalWrite(11, LOW);
|
||||
#endif
|
||||
#else
|
||||
#error "This chip is not supported!"
|
||||
#endif
|
||||
#if !defined(PIC32_USE_PIN9_FOR_M1_PWM) && !defined(PIC32_USE_PIN10_FOR_M1_PWM)
|
||||
pinMode(11, OUTPUT);
|
||||
#endif
|
||||
}
|
||||
|
||||
inline void setPWM1(uint8_t s) {
|
||||
#if defined(__AVR_ATmega8__) || \
|
||||
defined(__AVR_ATmega48__) || \
|
||||
defined(__AVR_ATmega88__) || \
|
||||
defined(__AVR_ATmega168__) || \
|
||||
defined(__AVR_ATmega328P__)
|
||||
// use PWM from timer2A on PB3 (Arduino pin #11)
|
||||
OCR2A = s;
|
||||
#elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
|
||||
// on arduino mega, pin 11 is now PB5 (OC1A)
|
||||
OCR1A = s;
|
||||
#elif defined(__PIC32MX__)
|
||||
#if defined(PIC32_USE_PIN9_FOR_M1_PWM)
|
||||
// Set the OC4 (pin 9) PMW duty cycle from 0 to 255
|
||||
OC4RS = s;
|
||||
#elif defined(PIC32_USE_PIN10_FOR_M1_PWM)
|
||||
// Set the OC5 (pin 10) PMW duty cycle from 0 to 255
|
||||
OC5RS = s;
|
||||
#else
|
||||
// If we are not doing PWM output for M1, then just use on/off
|
||||
if (s > 127)
|
||||
{
|
||||
digitalWrite(11, HIGH);
|
||||
}
|
||||
else
|
||||
{
|
||||
digitalWrite(11, LOW);
|
||||
}
|
||||
#endif
|
||||
#else
|
||||
#error "This chip is not supported!"
|
||||
#endif
|
||||
}
|
||||
|
||||
inline void initPWM2(uint8_t freq) {
|
||||
#if defined(__AVR_ATmega8__) || \
|
||||
defined(__AVR_ATmega48__) || \
|
||||
defined(__AVR_ATmega88__) || \
|
||||
defined(__AVR_ATmega168__) || \
|
||||
defined(__AVR_ATmega328P__)
|
||||
// use PWM from timer2B (pin 3)
|
||||
TCCR2A |= _BV(COM2B1) | _BV(WGM20) | _BV(WGM21); // fast PWM, turn on oc2b
|
||||
TCCR2B = freq & 0x7;
|
||||
OCR2B = 0;
|
||||
#elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
|
||||
// on arduino mega, pin 3 is now PE5 (OC3C)
|
||||
TCCR3A |= _BV(COM1C1) | _BV(WGM10); // fast PWM, turn on oc3c
|
||||
TCCR3B = (freq & 0x7) | _BV(WGM12);
|
||||
OCR3C = 0;
|
||||
#elif defined(__PIC32MX__)
|
||||
if (!MC.TimerInitalized)
|
||||
{ // Set up Timer2 for 80MHz counting fro 0 to 256
|
||||
T2CON = 0x8000 | ((freq & 0x07) << 4); // ON=1, FRZ=0, SIDL=0, TGATE=0, TCKPS=<freq>, T32=0, TCS=0; // ON=1, FRZ=0, SIDL=0, TGATE=0, TCKPS=0, T32=0, TCS=0
|
||||
TMR2 = 0x0000;
|
||||
PR2 = 0x0100;
|
||||
MC.TimerInitalized = true;
|
||||
}
|
||||
// Setup OC1 (pin3) in PWM mode, with Timer2 as timebase
|
||||
OC1CON = 0x8006; // OC32 = 0, OCTSEL=0, OCM=6
|
||||
OC1RS = 0x0000;
|
||||
OC1R = 0x0000;
|
||||
#else
|
||||
#error "This chip is not supported!"
|
||||
#endif
|
||||
|
||||
pinMode(3, OUTPUT);
|
||||
}
|
||||
|
||||
inline void setPWM2(uint8_t s) {
|
||||
#if defined(__AVR_ATmega8__) || \
|
||||
defined(__AVR_ATmega48__) || \
|
||||
defined(__AVR_ATmega88__) || \
|
||||
defined(__AVR_ATmega168__) || \
|
||||
defined(__AVR_ATmega328P__)
|
||||
// use PWM from timer2A on PB3 (Arduino pin #11)
|
||||
OCR2B = s;
|
||||
#elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
|
||||
// on arduino mega, pin 11 is now PB5 (OC1A)
|
||||
OCR3C = s;
|
||||
#elif defined(__PIC32MX__)
|
||||
// Set the OC1 (pin3) PMW duty cycle from 0 to 255
|
||||
OC1RS = s;
|
||||
#else
|
||||
#error "This chip is not supported!"
|
||||
#endif
|
||||
}
|
||||
|
||||
inline void initPWM3(uint8_t freq) {
|
||||
#if defined(__AVR_ATmega8__) || \
|
||||
defined(__AVR_ATmega48__) || \
|
||||
defined(__AVR_ATmega88__) || \
|
||||
defined(__AVR_ATmega168__) || \
|
||||
defined(__AVR_ATmega328P__)
|
||||
// use PWM from timer0A / PD6 (pin 6)
|
||||
TCCR0A |= _BV(COM0A1) | _BV(WGM00) | _BV(WGM01); // fast PWM, turn on OC0A
|
||||
//TCCR0B = freq & 0x7;
|
||||
OCR0A = 0;
|
||||
#elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
|
||||
// on arduino mega, pin 6 is now PH3 (OC4A)
|
||||
TCCR4A |= _BV(COM1A1) | _BV(WGM10); // fast PWM, turn on oc4a
|
||||
TCCR4B = (freq & 0x7) | _BV(WGM12);
|
||||
//TCCR4B = 1 | _BV(WGM12);
|
||||
OCR4A = 0;
|
||||
#elif defined(__PIC32MX__)
|
||||
if (!MC.TimerInitalized)
|
||||
{ // Set up Timer2 for 80MHz counting fro 0 to 256
|
||||
T2CON = 0x8000 | ((freq & 0x07) << 4); // ON=1, FRZ=0, SIDL=0, TGATE=0, TCKPS=<freq>, T32=0, TCS=0; // ON=1, FRZ=0, SIDL=0, TGATE=0, TCKPS=0, T32=0, TCS=0
|
||||
TMR2 = 0x0000;
|
||||
PR2 = 0x0100;
|
||||
MC.TimerInitalized = true;
|
||||
}
|
||||
// Setup OC3 (pin 6) in PWM mode, with Timer2 as timebase
|
||||
OC3CON = 0x8006; // OC32 = 0, OCTSEL=0, OCM=6
|
||||
OC3RS = 0x0000;
|
||||
OC3R = 0x0000;
|
||||
#else
|
||||
#error "This chip is not supported!"
|
||||
#endif
|
||||
pinMode(6, OUTPUT);
|
||||
}
|
||||
|
||||
inline void setPWM3(uint8_t s) {
|
||||
#if defined(__AVR_ATmega8__) || \
|
||||
defined(__AVR_ATmega48__) || \
|
||||
defined(__AVR_ATmega88__) || \
|
||||
defined(__AVR_ATmega168__) || \
|
||||
defined(__AVR_ATmega328P__)
|
||||
// use PWM from timer0A on PB3 (Arduino pin #6)
|
||||
OCR0A = s;
|
||||
#elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
|
||||
// on arduino mega, pin 6 is now PH3 (OC4A)
|
||||
OCR4A = s;
|
||||
#elif defined(__PIC32MX__)
|
||||
// Set the OC3 (pin 6) PMW duty cycle from 0 to 255
|
||||
OC3RS = s;
|
||||
#else
|
||||
#error "This chip is not supported!"
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
inline void initPWM4(uint8_t freq) {
|
||||
#if defined(__AVR_ATmega8__) || \
|
||||
defined(__AVR_ATmega48__) || \
|
||||
defined(__AVR_ATmega88__) || \
|
||||
defined(__AVR_ATmega168__) || \
|
||||
defined(__AVR_ATmega328P__)
|
||||
// use PWM from timer0B / PD5 (pin 5)
|
||||
TCCR0A |= _BV(COM0B1) | _BV(WGM00) | _BV(WGM01); // fast PWM, turn on oc0a
|
||||
//TCCR0B = freq & 0x7;
|
||||
OCR0B = 0;
|
||||
#elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
|
||||
// on arduino mega, pin 5 is now PE3 (OC3A)
|
||||
TCCR3A |= _BV(COM1A1) | _BV(WGM10); // fast PWM, turn on oc3a
|
||||
TCCR3B = (freq & 0x7) | _BV(WGM12);
|
||||
//TCCR4B = 1 | _BV(WGM12);
|
||||
OCR3A = 0;
|
||||
#elif defined(__PIC32MX__)
|
||||
if (!MC.TimerInitalized)
|
||||
{ // Set up Timer2 for 80MHz counting fro 0 to 256
|
||||
T2CON = 0x8000 | ((freq & 0x07) << 4); // ON=1, FRZ=0, SIDL=0, TGATE=0, TCKPS=<freq>, T32=0, TCS=0; // ON=1, FRZ=0, SIDL=0, TGATE=0, TCKPS=0, T32=0, TCS=0
|
||||
TMR2 = 0x0000;
|
||||
PR2 = 0x0100;
|
||||
MC.TimerInitalized = true;
|
||||
}
|
||||
// Setup OC2 (pin 5) in PWM mode, with Timer2 as timebase
|
||||
OC2CON = 0x8006; // OC32 = 0, OCTSEL=0, OCM=6
|
||||
OC2RS = 0x0000;
|
||||
OC2R = 0x0000;
|
||||
#else
|
||||
#error "This chip is not supported!"
|
||||
#endif
|
||||
pinMode(5, OUTPUT);
|
||||
}
|
||||
|
||||
inline void setPWM4(uint8_t s) {
|
||||
#if defined(__AVR_ATmega8__) || \
|
||||
defined(__AVR_ATmega48__) || \
|
||||
defined(__AVR_ATmega88__) || \
|
||||
defined(__AVR_ATmega168__) || \
|
||||
defined(__AVR_ATmega328P__)
|
||||
// use PWM from timer0A on PB3 (Arduino pin #6)
|
||||
OCR0B = s;
|
||||
#elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
|
||||
// on arduino mega, pin 6 is now PH3 (OC4A)
|
||||
OCR3A = s;
|
||||
#elif defined(__PIC32MX__)
|
||||
// Set the OC2 (pin 5) PMW duty cycle from 0 to 255
|
||||
OC2RS = s;
|
||||
#else
|
||||
#error "This chip is not supported!"
|
||||
#endif
|
||||
}
|
||||
|
||||
AF_DCMotor::AF_DCMotor(uint8_t num, uint8_t freq) {
|
||||
motornum = num;
|
||||
pwmfreq = freq;
|
||||
|
||||
MC.enable();
|
||||
|
||||
switch (num) {
|
||||
case 1:
|
||||
latch_state &= ~_BV(MOTOR1_A) & ~_BV(MOTOR1_B); // set both motor pins to 0
|
||||
MC.latch_tx();
|
||||
initPWM1(freq);
|
||||
break;
|
||||
case 2:
|
||||
latch_state &= ~_BV(MOTOR2_A) & ~_BV(MOTOR2_B); // set both motor pins to 0
|
||||
MC.latch_tx();
|
||||
initPWM2(freq);
|
||||
break;
|
||||
case 3:
|
||||
latch_state &= ~_BV(MOTOR3_A) & ~_BV(MOTOR3_B); // set both motor pins to 0
|
||||
MC.latch_tx();
|
||||
initPWM3(freq);
|
||||
break;
|
||||
case 4:
|
||||
latch_state &= ~_BV(MOTOR4_A) & ~_BV(MOTOR4_B); // set both motor pins to 0
|
||||
MC.latch_tx();
|
||||
initPWM4(freq);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void AF_DCMotor::run(uint8_t cmd) {
|
||||
uint8_t a, b;
|
||||
switch (motornum) {
|
||||
case 1:
|
||||
a = MOTOR1_A; b = MOTOR1_B; break;
|
||||
case 2:
|
||||
a = MOTOR2_A; b = MOTOR2_B; break;
|
||||
case 3:
|
||||
a = MOTOR3_A; b = MOTOR3_B; break;
|
||||
case 4:
|
||||
a = MOTOR4_A; b = MOTOR4_B; break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
switch (cmd) {
|
||||
case FORWARD:
|
||||
latch_state |= _BV(a);
|
||||
latch_state &= ~_BV(b);
|
||||
MC.latch_tx();
|
||||
break;
|
||||
case BACKWARD:
|
||||
latch_state &= ~_BV(a);
|
||||
latch_state |= _BV(b);
|
||||
MC.latch_tx();
|
||||
break;
|
||||
case RELEASE:
|
||||
latch_state &= ~_BV(a); // A and B both low
|
||||
latch_state &= ~_BV(b);
|
||||
MC.latch_tx();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void AF_DCMotor::setSpeed(uint8_t speed) {
|
||||
switch (motornum) {
|
||||
case 1:
|
||||
setPWM1(speed); break;
|
||||
case 2:
|
||||
setPWM2(speed); break;
|
||||
case 3:
|
||||
setPWM3(speed); break;
|
||||
case 4:
|
||||
setPWM4(speed); break;
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************
|
||||
STEPPERS
|
||||
******************************************/
|
||||
|
||||
AF_Stepper::AF_Stepper(uint16_t steps, uint8_t num) {
|
||||
MC.enable();
|
||||
|
||||
revsteps = steps;
|
||||
steppernum = num;
|
||||
currentstep = 0;
|
||||
|
||||
if (steppernum == 1) {
|
||||
latch_state &= ~_BV(MOTOR1_A) & ~_BV(MOTOR1_B) &
|
||||
~_BV(MOTOR2_A) & ~_BV(MOTOR2_B); // all motor pins to 0
|
||||
MC.latch_tx();
|
||||
|
||||
// enable both H bridges
|
||||
pinMode(11, OUTPUT);
|
||||
pinMode(3, OUTPUT);
|
||||
digitalWrite(11, HIGH);
|
||||
digitalWrite(3, HIGH);
|
||||
|
||||
// use PWM for microstepping support
|
||||
initPWM1(STEPPER1_PWM_RATE);
|
||||
initPWM2(STEPPER1_PWM_RATE);
|
||||
setPWM1(255);
|
||||
setPWM2(255);
|
||||
|
||||
} else if (steppernum == 2) {
|
||||
latch_state &= ~_BV(MOTOR3_A) & ~_BV(MOTOR3_B) &
|
||||
~_BV(MOTOR4_A) & ~_BV(MOTOR4_B); // all motor pins to 0
|
||||
MC.latch_tx();
|
||||
|
||||
// enable both H bridges
|
||||
pinMode(5, OUTPUT);
|
||||
pinMode(6, OUTPUT);
|
||||
digitalWrite(5, HIGH);
|
||||
digitalWrite(6, HIGH);
|
||||
|
||||
// use PWM for microstepping support
|
||||
// use PWM for microstepping support
|
||||
initPWM3(STEPPER2_PWM_RATE);
|
||||
initPWM4(STEPPER2_PWM_RATE);
|
||||
setPWM3(255);
|
||||
setPWM4(255);
|
||||
}
|
||||
}
|
||||
|
||||
void AF_Stepper::setSpeed(uint16_t rpm) {
|
||||
usperstep = 60000000 / ((uint32_t)revsteps * (uint32_t)rpm);
|
||||
steppingcounter = 0;
|
||||
}
|
||||
|
||||
void AF_Stepper::release(void) {
|
||||
if (steppernum == 1) {
|
||||
latch_state &= ~_BV(MOTOR1_A) & ~_BV(MOTOR1_B) &
|
||||
~_BV(MOTOR2_A) & ~_BV(MOTOR2_B); // all motor pins to 0
|
||||
MC.latch_tx();
|
||||
} else if (steppernum == 2) {
|
||||
latch_state &= ~_BV(MOTOR3_A) & ~_BV(MOTOR3_B) &
|
||||
~_BV(MOTOR4_A) & ~_BV(MOTOR4_B); // all motor pins to 0
|
||||
MC.latch_tx();
|
||||
}
|
||||
}
|
||||
|
||||
void AF_Stepper::step(uint16_t steps, uint8_t dir, uint8_t style) {
|
||||
uint32_t uspers = usperstep;
|
||||
uint8_t ret = 0;
|
||||
|
||||
if (style == INTERLEAVE) {
|
||||
uspers /= 2;
|
||||
}
|
||||
else if (style == MICROSTEP) {
|
||||
uspers /= MICROSTEPS;
|
||||
steps *= MICROSTEPS;
|
||||
#ifdef MOTORDEBUG
|
||||
Serial.print("steps = "); Serial.println(steps, DEC);
|
||||
#endif
|
||||
}
|
||||
|
||||
while (steps--) {
|
||||
ret = onestep(dir, style);
|
||||
delay(uspers/1000); // in ms
|
||||
steppingcounter += (uspers % 1000);
|
||||
if (steppingcounter >= 1000) {
|
||||
delay(1);
|
||||
steppingcounter -= 1000;
|
||||
}
|
||||
}
|
||||
if (style == MICROSTEP) {
|
||||
while ((ret != 0) && (ret != MICROSTEPS)) {
|
||||
ret = onestep(dir, style);
|
||||
delay(uspers/1000); // in ms
|
||||
steppingcounter += (uspers % 1000);
|
||||
if (steppingcounter >= 1000) {
|
||||
delay(1);
|
||||
steppingcounter -= 1000;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t AF_Stepper::onestep(uint8_t dir, uint8_t style) {
|
||||
uint8_t a, b, c, d;
|
||||
uint8_t ocrb, ocra;
|
||||
|
||||
ocra = ocrb = 255;
|
||||
|
||||
if (steppernum == 1) {
|
||||
a = _BV(MOTOR1_A);
|
||||
b = _BV(MOTOR2_A);
|
||||
c = _BV(MOTOR1_B);
|
||||
d = _BV(MOTOR2_B);
|
||||
} else if (steppernum == 2) {
|
||||
a = _BV(MOTOR3_A);
|
||||
b = _BV(MOTOR4_A);
|
||||
c = _BV(MOTOR3_B);
|
||||
d = _BV(MOTOR4_B);
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// next determine what sort of stepping procedure we're up to
|
||||
if (style == SINGLE) {
|
||||
if ((currentstep/(MICROSTEPS/2)) % 2) { // we're at an odd step, weird
|
||||
if (dir == FORWARD) {
|
||||
currentstep += MICROSTEPS/2;
|
||||
}
|
||||
else {
|
||||
currentstep -= MICROSTEPS/2;
|
||||
}
|
||||
} else { // go to the next even step
|
||||
if (dir == FORWARD) {
|
||||
currentstep += MICROSTEPS;
|
||||
}
|
||||
else {
|
||||
currentstep -= MICROSTEPS;
|
||||
}
|
||||
}
|
||||
} else if (style == DOUBLE) {
|
||||
if (! (currentstep/(MICROSTEPS/2) % 2)) { // we're at an even step, weird
|
||||
if (dir == FORWARD) {
|
||||
currentstep += MICROSTEPS/2;
|
||||
} else {
|
||||
currentstep -= MICROSTEPS/2;
|
||||
}
|
||||
} else { // go to the next odd step
|
||||
if (dir == FORWARD) {
|
||||
currentstep += MICROSTEPS;
|
||||
} else {
|
||||
currentstep -= MICROSTEPS;
|
||||
}
|
||||
}
|
||||
} else if (style == INTERLEAVE) {
|
||||
if (dir == FORWARD) {
|
||||
currentstep += MICROSTEPS/2;
|
||||
} else {
|
||||
currentstep -= MICROSTEPS/2;
|
||||
}
|
||||
}
|
||||
|
||||
if (style == MICROSTEP) {
|
||||
if (dir == FORWARD) {
|
||||
currentstep++;
|
||||
} else {
|
||||
// BACKWARDS
|
||||
currentstep--;
|
||||
}
|
||||
|
||||
currentstep += MICROSTEPS*4;
|
||||
currentstep %= MICROSTEPS*4;
|
||||
|
||||
ocra = ocrb = 0;
|
||||
if ( (currentstep >= 0) && (currentstep < MICROSTEPS)) {
|
||||
ocra = microstepcurve[MICROSTEPS - currentstep];
|
||||
ocrb = microstepcurve[currentstep];
|
||||
} else if ( (currentstep >= MICROSTEPS) && (currentstep < MICROSTEPS*2)) {
|
||||
ocra = microstepcurve[currentstep - MICROSTEPS];
|
||||
ocrb = microstepcurve[MICROSTEPS*2 - currentstep];
|
||||
} else if ( (currentstep >= MICROSTEPS*2) && (currentstep < MICROSTEPS*3)) {
|
||||
ocra = microstepcurve[MICROSTEPS*3 - currentstep];
|
||||
ocrb = microstepcurve[currentstep - MICROSTEPS*2];
|
||||
} else if ( (currentstep >= MICROSTEPS*3) && (currentstep < MICROSTEPS*4)) {
|
||||
ocra = microstepcurve[currentstep - MICROSTEPS*3];
|
||||
ocrb = microstepcurve[MICROSTEPS*4 - currentstep];
|
||||
}
|
||||
}
|
||||
|
||||
currentstep += MICROSTEPS*4;
|
||||
currentstep %= MICROSTEPS*4;
|
||||
|
||||
#ifdef MOTORDEBUG
|
||||
Serial.print("current step: "); Serial.println(currentstep, DEC);
|
||||
Serial.print(" pwmA = "); Serial.print(ocra, DEC);
|
||||
Serial.print(" pwmB = "); Serial.println(ocrb, DEC);
|
||||
#endif
|
||||
|
||||
if (steppernum == 1) {
|
||||
setPWM1(ocra);
|
||||
setPWM2(ocrb);
|
||||
} else if (steppernum == 2) {
|
||||
setPWM3(ocra);
|
||||
setPWM4(ocrb);
|
||||
}
|
||||
|
||||
|
||||
// release all
|
||||
latch_state &= ~a & ~b & ~c & ~d; // all motor pins to 0
|
||||
|
||||
//Serial.println(step, DEC);
|
||||
if (style == MICROSTEP) {
|
||||
if ((currentstep >= 0) && (currentstep < MICROSTEPS))
|
||||
latch_state |= a | b;
|
||||
if ((currentstep >= MICROSTEPS) && (currentstep < MICROSTEPS*2))
|
||||
latch_state |= b | c;
|
||||
if ((currentstep >= MICROSTEPS*2) && (currentstep < MICROSTEPS*3))
|
||||
latch_state |= c | d;
|
||||
if ((currentstep >= MICROSTEPS*3) && (currentstep < MICROSTEPS*4))
|
||||
latch_state |= d | a;
|
||||
} else {
|
||||
switch (currentstep/(MICROSTEPS/2)) {
|
||||
case 0:
|
||||
latch_state |= a; // energize coil 1 only
|
||||
break;
|
||||
case 1:
|
||||
latch_state |= a | b; // energize coil 1+2
|
||||
break;
|
||||
case 2:
|
||||
latch_state |= b; // energize coil 2 only
|
||||
break;
|
||||
case 3:
|
||||
latch_state |= b | c; // energize coil 2+3
|
||||
break;
|
||||
case 4:
|
||||
latch_state |= c; // energize coil 3 only
|
||||
break;
|
||||
case 5:
|
||||
latch_state |= c | d; // energize coil 3+4
|
||||
break;
|
||||
case 6:
|
||||
latch_state |= d; // energize coil 4 only
|
||||
break;
|
||||
case 7:
|
||||
latch_state |= d | a; // energize coil 1+4
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
MC.latch_tx();
|
||||
return currentstep;
|
||||
}
|
||||
|
||||
181
arduino-cli/libraries/Adafruit-Motor-Shield-library/AFMotor.h
Normal file
181
arduino-cli/libraries/Adafruit-Motor-Shield-library/AFMotor.h
Normal file
@@ -0,0 +1,181 @@
|
||||
// Adafruit Motor shield library
|
||||
// copyright Adafruit Industries LLC, 2009
|
||||
// this code is public domain, enjoy!
|
||||
|
||||
/*
|
||||
* Usage Notes:
|
||||
* For PIC32, all features work properly with the following two exceptions:
|
||||
*
|
||||
* 1) Because the PIC32 only has 5 PWM outputs, and the AFMotor shield needs 6
|
||||
* to completely operate (four for motor outputs and two for RC servos), the
|
||||
* M1 motor output will not have PWM ability when used with a PIC32 board.
|
||||
* However, there is a very simple workaround. If you need to drive a stepper
|
||||
* or DC motor with PWM on motor output M1, you can use the PWM output on pin
|
||||
* 9 or pin 10 (normally use for RC servo outputs on Arduino, not needed for
|
||||
* RC servo outputs on PIC32) to drive the PWM input for M1 by simply putting
|
||||
* a jumber from pin 9 to pin 11 or pin 10 to pin 11. Then uncomment one of the
|
||||
* two #defines below to activate the PWM on either pin 9 or pin 10. You will
|
||||
* then have a fully functional microstepping for 2 stepper motors, or four
|
||||
* DC motor outputs with PWM.
|
||||
*
|
||||
* 2) There is a conflict between RC Servo outputs on pins 9 and pins 10 and
|
||||
* the operation of DC motors and stepper motors as of 9/2012. This issue
|
||||
* will get fixed in future MPIDE releases, but at the present time it means
|
||||
* that the Motor Party example will NOT work properly. Any time you attach
|
||||
* an RC servo to pins 9 or pins 10, ALL PWM outputs on the whole board will
|
||||
* stop working. Thus no steppers or DC motors.
|
||||
*
|
||||
*/
|
||||
// <BPS> 09/15/2012 Modified for use with chipKIT boards
|
||||
|
||||
|
||||
#ifndef _AFMotor_h_
|
||||
#define _AFMotor_h_
|
||||
|
||||
#include <inttypes.h>
|
||||
#if defined(__AVR__)
|
||||
#include <avr/io.h>
|
||||
|
||||
//#define MOTORDEBUG 1
|
||||
|
||||
#define MICROSTEPS 16 // 8 or 16
|
||||
|
||||
#define MOTOR12_64KHZ _BV(CS20) // no prescale
|
||||
#define MOTOR12_8KHZ _BV(CS21) // divide by 8
|
||||
#define MOTOR12_2KHZ _BV(CS21) | _BV(CS20) // divide by 32
|
||||
#define MOTOR12_1KHZ _BV(CS22) // divide by 64
|
||||
|
||||
#define MOTOR34_64KHZ _BV(CS00) // no prescale
|
||||
#define MOTOR34_8KHZ _BV(CS01) // divide by 8
|
||||
#define MOTOR34_1KHZ _BV(CS01) | _BV(CS00) // divide by 64
|
||||
|
||||
#define DC_MOTOR_PWM_RATE MOTOR34_8KHZ // PWM rate for DC motors
|
||||
#define STEPPER1_PWM_RATE MOTOR12_64KHZ // PWM rate for stepper 1
|
||||
#define STEPPER2_PWM_RATE MOTOR34_64KHZ // PWM rate for stepper 2
|
||||
|
||||
#elif defined(__PIC32MX__)
|
||||
//#define MOTORDEBUG 1
|
||||
|
||||
// Uncomment the one of following lines if you have put a jumper from
|
||||
// either pin 9 to pin 11 or pin 10 to pin 11 on your Motor Shield.
|
||||
// Either will enable PWM for M1
|
||||
//#define PIC32_USE_PIN9_FOR_M1_PWM
|
||||
//#define PIC32_USE_PIN10_FOR_M1_PWM
|
||||
|
||||
#define MICROSTEPS 16 // 8 or 16
|
||||
|
||||
// For PIC32 Timers, define prescale settings by PWM frequency
|
||||
#define MOTOR12_312KHZ 0 // 1:1, actual frequency 312KHz
|
||||
#define MOTOR12_156KHZ 1 // 1:2, actual frequency 156KHz
|
||||
#define MOTOR12_64KHZ 2 // 1:4, actual frequency 78KHz
|
||||
#define MOTOR12_39KHZ 3 // 1:8, acutal frequency 39KHz
|
||||
#define MOTOR12_19KHZ 4 // 1:16, actual frequency 19KHz
|
||||
#define MOTOR12_8KHZ 5 // 1:32, actual frequency 9.7KHz
|
||||
#define MOTOR12_4_8KHZ 6 // 1:64, actual frequency 4.8KHz
|
||||
#define MOTOR12_2KHZ 7 // 1:256, actual frequency 1.2KHz
|
||||
#define MOTOR12_1KHZ 7 // 1:256, actual frequency 1.2KHz
|
||||
|
||||
#define MOTOR34_312KHZ 0 // 1:1, actual frequency 312KHz
|
||||
#define MOTOR34_156KHZ 1 // 1:2, actual frequency 156KHz
|
||||
#define MOTOR34_64KHZ 2 // 1:4, actual frequency 78KHz
|
||||
#define MOTOR34_39KHZ 3 // 1:8, acutal frequency 39KHz
|
||||
#define MOTOR34_19KHZ 4 // 1:16, actual frequency 19KHz
|
||||
#define MOTOR34_8KHZ 5 // 1:32, actual frequency 9.7KHz
|
||||
#define MOTOR34_4_8KHZ 6 // 1:64, actual frequency 4.8KHz
|
||||
#define MOTOR34_2KHZ 7 // 1:256, actual frequency 1.2KHz
|
||||
#define MOTOR34_1KHZ 7 // 1:256, actual frequency 1.2KHz
|
||||
|
||||
// PWM rate for DC motors.
|
||||
#define DC_MOTOR_PWM_RATE MOTOR34_39KHZ
|
||||
// Note: for PIC32, both of these must be set to the same value
|
||||
// since there's only one timebase for all 4 PWM outputs
|
||||
#define STEPPER1_PWM_RATE MOTOR12_39KHZ
|
||||
#define STEPPER2_PWM_RATE MOTOR34_39KHZ
|
||||
|
||||
#endif
|
||||
|
||||
// Bit positions in the 74HCT595 shift register output
|
||||
#define MOTOR1_A 2
|
||||
#define MOTOR1_B 3
|
||||
#define MOTOR2_A 1
|
||||
#define MOTOR2_B 4
|
||||
#define MOTOR4_A 0
|
||||
#define MOTOR4_B 6
|
||||
#define MOTOR3_A 5
|
||||
#define MOTOR3_B 7
|
||||
|
||||
// Constants that the user passes in to the motor calls
|
||||
#define FORWARD 1
|
||||
#define BACKWARD 2
|
||||
#define BRAKE 3
|
||||
#define RELEASE 4
|
||||
|
||||
// Constants that the user passes in to the stepper calls
|
||||
#define SINGLE 1
|
||||
#define DOUBLE 2
|
||||
#define INTERLEAVE 3
|
||||
#define MICROSTEP 4
|
||||
|
||||
/*
|
||||
#define LATCH 4
|
||||
#define LATCH_DDR DDRB
|
||||
#define LATCH_PORT PORTB
|
||||
|
||||
#define CLK_PORT PORTD
|
||||
#define CLK_DDR DDRD
|
||||
#define CLK 4
|
||||
|
||||
#define ENABLE_PORT PORTD
|
||||
#define ENABLE_DDR DDRD
|
||||
#define ENABLE 7
|
||||
|
||||
#define SER 0
|
||||
#define SER_DDR DDRB
|
||||
#define SER_PORT PORTB
|
||||
*/
|
||||
|
||||
// Arduino pin names for interface to 74HCT595 latch
|
||||
#define MOTORLATCH 12
|
||||
#define MOTORCLK 4
|
||||
#define MOTORENABLE 7
|
||||
#define MOTORDATA 8
|
||||
|
||||
class AFMotorController
|
||||
{
|
||||
public:
|
||||
AFMotorController(void);
|
||||
void enable(void);
|
||||
friend class AF_DCMotor;
|
||||
void latch_tx(void);
|
||||
uint8_t TimerInitalized;
|
||||
};
|
||||
|
||||
class AF_DCMotor
|
||||
{
|
||||
public:
|
||||
AF_DCMotor(uint8_t motornum, uint8_t freq = DC_MOTOR_PWM_RATE);
|
||||
void run(uint8_t);
|
||||
void setSpeed(uint8_t);
|
||||
|
||||
private:
|
||||
uint8_t motornum, pwmfreq;
|
||||
};
|
||||
|
||||
class AF_Stepper {
|
||||
public:
|
||||
AF_Stepper(uint16_t, uint8_t);
|
||||
void step(uint16_t steps, uint8_t dir, uint8_t style = SINGLE);
|
||||
void setSpeed(uint16_t);
|
||||
uint8_t onestep(uint8_t dir, uint8_t style);
|
||||
void release(void);
|
||||
uint16_t revsteps; // # steps per revolution
|
||||
uint8_t steppernum;
|
||||
uint32_t usperstep, steppingcounter;
|
||||
private:
|
||||
uint8_t currentstep;
|
||||
|
||||
};
|
||||
|
||||
uint8_t getlatchstate(void);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
This library is old and deprecated - and the hardware disconinued years ago. V2 of the shield uses i2c only and works with anything that has I2C support (e.g. all arduinos) without endless incompatibilities and porting requirements! :)
|
||||
-> https://www.adafruit.com/products/1438
|
||||
|
||||
--------------
|
||||
|
||||
This is the August 12, 2009 Adafruit Motor shield firmware with basic Microstepping support. Works with all Arduinos and the Mega
|
||||
Updated in September 2012 for use on PIC32 architecture (chipKIT/MPIDE)
|
||||
|
||||
For more information on the shield, please visit https://learn.adafruit.com/adafruit-motor-shield
|
||||
|
||||
To install, click DOWNLOAD SOURCE in the top right corner, and see our tutorial at http://www.ladyada.net/library/arduino/libraries.html on Arduino Library installation
|
||||
@@ -0,0 +1,37 @@
|
||||
// ConstantSpeed.pde
|
||||
// -*- mode: C++ -*-
|
||||
//
|
||||
// Shows how to run AccelStepper in the simplest,
|
||||
// fixed speed mode with no accelerations
|
||||
// Requires the AFMotor library (https://github.com/adafruit/Adafruit-Motor-Shield-library)
|
||||
// And AccelStepper with AFMotor support (https://github.com/adafruit/AccelStepper)
|
||||
// Public domain!
|
||||
|
||||
#include <AccelStepper.h>
|
||||
#include <AFMotor.h>
|
||||
|
||||
AF_Stepper motor1(200, 1);
|
||||
|
||||
|
||||
// you can change these to DOUBLE or INTERLEAVE or MICROSTEP!
|
||||
void forwardstep() {
|
||||
motor1.onestep(FORWARD, SINGLE);
|
||||
}
|
||||
void backwardstep() {
|
||||
motor1.onestep(BACKWARD, SINGLE);
|
||||
}
|
||||
|
||||
AccelStepper stepper(forwardstep, backwardstep); // use functions to step
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(9600); // set up Serial library at 9600 bps
|
||||
Serial.println("Stepper test!");
|
||||
|
||||
stepper.setSpeed(50);
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
stepper.runSpeed();
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
// MultiStepper
|
||||
// -*- mode: C++ -*-
|
||||
//
|
||||
// Control both Stepper motors at the same time with different speeds
|
||||
// and accelerations.
|
||||
// Requires the AFMotor library (https://github.com/adafruit/Adafruit-Motor-Shield-library)
|
||||
// And AccelStepper with AFMotor support (https://github.com/adafruit/AccelStepper)
|
||||
// Public domain!
|
||||
|
||||
#include <AccelStepper.h>
|
||||
#include <AFMotor.h>
|
||||
|
||||
// two stepper motors one on each port
|
||||
AF_Stepper motor1(200, 1);
|
||||
AF_Stepper motor2(200, 2);
|
||||
|
||||
// you can change these to DOUBLE or INTERLEAVE or MICROSTEP!
|
||||
// wrappers for the first motor!
|
||||
void forwardstep1() {
|
||||
motor1.onestep(FORWARD, SINGLE);
|
||||
}
|
||||
void backwardstep1() {
|
||||
motor1.onestep(BACKWARD, SINGLE);
|
||||
}
|
||||
// wrappers for the second motor!
|
||||
void forwardstep2() {
|
||||
motor2.onestep(FORWARD, SINGLE);
|
||||
}
|
||||
void backwardstep2() {
|
||||
motor2.onestep(BACKWARD, SINGLE);
|
||||
}
|
||||
|
||||
// Motor shield has two motor ports, now we'll wrap them in an AccelStepper object
|
||||
AccelStepper stepper1(forwardstep1, backwardstep1);
|
||||
AccelStepper stepper2(forwardstep2, backwardstep2);
|
||||
|
||||
void setup()
|
||||
{
|
||||
stepper1.setMaxSpeed(200.0);
|
||||
stepper1.setAcceleration(100.0);
|
||||
stepper1.moveTo(24);
|
||||
|
||||
stepper2.setMaxSpeed(300.0);
|
||||
stepper2.setAcceleration(100.0);
|
||||
stepper2.moveTo(1000000);
|
||||
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
// Change direction at the limits
|
||||
if (stepper1.distanceToGo() == 0)
|
||||
stepper1.moveTo(-stepper1.currentPosition());
|
||||
stepper1.run();
|
||||
stepper2.run();
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
// Adafruit Motor shield library
|
||||
// copyright Adafruit Industries LLC, 2009
|
||||
// this code is public domain, enjoy!
|
||||
|
||||
#include <AFMotor.h>
|
||||
#include <Servo.h>
|
||||
|
||||
// DC motor on M2
|
||||
AF_DCMotor motor(2);
|
||||
// DC hobby servo
|
||||
Servo servo1;
|
||||
// Stepper motor on M3+M4 48 steps per revolution
|
||||
AF_Stepper stepper(48, 2);
|
||||
|
||||
void setup() {
|
||||
Serial.begin(9600); // set up Serial library at 9600 bps
|
||||
Serial.println("Motor party!");
|
||||
|
||||
// turn on servo
|
||||
servo1.attach(9);
|
||||
|
||||
// turn on motor #2
|
||||
motor.setSpeed(200);
|
||||
motor.run(RELEASE);
|
||||
}
|
||||
|
||||
int i;
|
||||
|
||||
// Test the DC motor, stepper and servo ALL AT ONCE!
|
||||
void loop() {
|
||||
motor.run(FORWARD);
|
||||
for (i=0; i<255; i++) {
|
||||
servo1.write(i);
|
||||
motor.setSpeed(i);
|
||||
stepper.step(1, FORWARD, INTERLEAVE);
|
||||
delay(3);
|
||||
}
|
||||
|
||||
for (i=255; i!=0; i--) {
|
||||
servo1.write(i-255);
|
||||
motor.setSpeed(i);
|
||||
stepper.step(1, BACKWARD, INTERLEAVE);
|
||||
delay(3);
|
||||
}
|
||||
|
||||
motor.run(BACKWARD);
|
||||
for (i=0; i<255; i++) {
|
||||
servo1.write(i);
|
||||
motor.setSpeed(i);
|
||||
delay(3);
|
||||
stepper.step(1, FORWARD, DOUBLE);
|
||||
}
|
||||
|
||||
for (i=255; i!=0; i--) {
|
||||
servo1.write(i-255);
|
||||
motor.setSpeed(i);
|
||||
stepper.step(1, BACKWARD, DOUBLE);
|
||||
delay(3);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
// Adafruit Motor shield library
|
||||
// copyright Adafruit Industries LLC, 2009
|
||||
// this code is public domain, enjoy!
|
||||
|
||||
#include <AFMotor.h>
|
||||
|
||||
AF_DCMotor motor(4);
|
||||
|
||||
void setup() {
|
||||
Serial.begin(9600); // set up Serial library at 9600 bps
|
||||
Serial.println("Motor test!");
|
||||
|
||||
// turn on motor
|
||||
motor.setSpeed(200);
|
||||
|
||||
motor.run(RELEASE);
|
||||
}
|
||||
|
||||
void loop() {
|
||||
uint8_t i;
|
||||
|
||||
Serial.print("tick");
|
||||
|
||||
motor.run(FORWARD);
|
||||
for (i=0; i<255; i++) {
|
||||
motor.setSpeed(i);
|
||||
delay(10);
|
||||
}
|
||||
|
||||
for (i=255; i!=0; i--) {
|
||||
motor.setSpeed(i);
|
||||
delay(10);
|
||||
}
|
||||
|
||||
Serial.print("tock");
|
||||
|
||||
motor.run(BACKWARD);
|
||||
for (i=0; i<255; i++) {
|
||||
motor.setSpeed(i);
|
||||
delay(10);
|
||||
}
|
||||
|
||||
for (i=255; i!=0; i--) {
|
||||
motor.setSpeed(i);
|
||||
delay(10);
|
||||
}
|
||||
|
||||
|
||||
Serial.print("tech");
|
||||
motor.run(RELEASE);
|
||||
delay(1000);
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
// Adafruit Motor shield library
|
||||
// copyright Adafruit Industries LLC, 2009
|
||||
// this code is public domain, enjoy!
|
||||
|
||||
#include <AFMotor.h>
|
||||
|
||||
// Connect a stepper motor with 48 steps per revolution (7.5 degree)
|
||||
// to motor port #2 (M3 and M4)
|
||||
AF_Stepper motor(48, 2);
|
||||
|
||||
void setup() {
|
||||
Serial.begin(9600); // set up Serial library at 9600 bps
|
||||
Serial.println("Stepper test!");
|
||||
|
||||
motor.setSpeed(10); // 10 rpm
|
||||
}
|
||||
|
||||
void loop() {
|
||||
Serial.println("Single coil steps");
|
||||
motor.step(100, FORWARD, SINGLE);
|
||||
motor.step(100, BACKWARD, SINGLE);
|
||||
|
||||
Serial.println("Double coil steps");
|
||||
motor.step(100, FORWARD, DOUBLE);
|
||||
motor.step(100, BACKWARD, DOUBLE);
|
||||
|
||||
Serial.println("Interleave coil steps");
|
||||
motor.step(100, FORWARD, INTERLEAVE);
|
||||
motor.step(100, BACKWARD, INTERLEAVE);
|
||||
|
||||
Serial.println("Micrsostep steps");
|
||||
motor.step(100, FORWARD, MICROSTEP);
|
||||
motor.step(100, BACKWARD, MICROSTEP);
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
#######################################
|
||||
# Syntax Coloring Map for AFMotor
|
||||
#######################################
|
||||
|
||||
#######################################
|
||||
# Datatypes (KEYWORD1)
|
||||
#######################################
|
||||
|
||||
AF_DCMotor KEYWORD1
|
||||
AF_Stepper KEYWORD1
|
||||
|
||||
#######################################
|
||||
# Methods and Functions (KEYWORD2)
|
||||
#######################################
|
||||
|
||||
enable KEYWORD2
|
||||
run KEYWORD2
|
||||
setSpeed KEYWORD2
|
||||
step KEYWORD2
|
||||
onestep KEYWORD2
|
||||
release KEYWORD2
|
||||
|
||||
#######################################
|
||||
# Constants (LITERAL1)
|
||||
#######################################
|
||||
|
||||
MICROSTEPPING LITERAL1
|
||||
FORWARD LITERAL1
|
||||
BACKWARD LITERAL1
|
||||
BRAKE LITERAL1
|
||||
RELEASE LITERAL1
|
||||
SINGLE LITERAL1
|
||||
DOUBLE LITERAL1
|
||||
INTERLEAVE LITERAL1
|
||||
MICROSTEP LITERAL1
|
||||
@@ -0,0 +1,9 @@
|
||||
name=Adafruit Motor Shield library
|
||||
version=1.0.1
|
||||
author=Adafruit
|
||||
maintainer=Adafruit <info@adafruit.com>
|
||||
sentence=Adafruit Motor shield V1 firmware with basic Microstepping support. Works with all Arduinos and the Mega
|
||||
paragraph=Adafruit Motor shield V1 firmware with basic Microstepping support. Works with all Arduinos and the Mega
|
||||
category=Device Control
|
||||
url=https://github.com/adafruit/Adafruit-Motor-Shield-library
|
||||
architectures=*
|
||||
46
arduino-cli/libraries/Adafruit-PWM-Servo-Driver/.github/ISSUE_TEMPLATE.md
vendored
Normal file
46
arduino-cli/libraries/Adafruit-PWM-Servo-Driver/.github/ISSUE_TEMPLATE.md
vendored
Normal file
@@ -0,0 +1,46 @@
|
||||
Thank you for opening an issue on an Adafruit Arduino library repository. To
|
||||
improve the speed of resolution please review the following guidelines and
|
||||
common troubleshooting steps below before creating the issue:
|
||||
|
||||
- **Do not use GitHub issues for troubleshooting projects and issues.** Instead use
|
||||
the forums at http://forums.adafruit.com to ask questions and troubleshoot why
|
||||
something isn't working as expected. In many cases the problem is a common issue
|
||||
that you will more quickly receive help from the forum community. GitHub issues
|
||||
are meant for known defects in the code. If you don't know if there is a defect
|
||||
in the code then start with troubleshooting on the forum first.
|
||||
|
||||
- **If following a tutorial or guide be sure you didn't miss a step.** Carefully
|
||||
check all of the steps and commands to run have been followed. Consult the
|
||||
forum if you're unsure or have questions about steps in a guide/tutorial.
|
||||
|
||||
- **For Arduino projects check these very common issues to ensure they don't apply**:
|
||||
|
||||
- For uploading sketches or communicating with the board make sure you're using
|
||||
a **USB data cable** and **not** a **USB charge-only cable**. It is sometimes
|
||||
very hard to tell the difference between a data and charge cable! Try using the
|
||||
cable with other devices or swapping to another cable to confirm it is not
|
||||
the problem.
|
||||
|
||||
- **Be sure you are supplying adequate power to the board.** Check the specs of
|
||||
your board and plug in an external power supply. In many cases just
|
||||
plugging a board into your computer is not enough to power it and other
|
||||
peripherals.
|
||||
|
||||
- **Double check all soldering joints and connections.** Flakey connections
|
||||
cause many mysterious problems. See the [guide to excellent soldering](https://learn.adafruit.com/adafruit-guide-excellent-soldering/tools) for examples of good solder joints.
|
||||
|
||||
- **Ensure you are using an official Arduino or Adafruit board.** We can't
|
||||
guarantee a clone board will have the same functionality and work as expected
|
||||
with this code and don't support them.
|
||||
|
||||
If you're sure this issue is a defect in the code and checked the steps above
|
||||
please fill in the following fields to provide enough troubleshooting information.
|
||||
You may delete the guideline and text above to just leave the following details:
|
||||
|
||||
- Arduino board: **INSERT ARDUINO BOARD NAME/TYPE HERE**
|
||||
|
||||
- Arduino IDE version (found in Arduino -> About Arduino menu): **INSERT ARDUINO
|
||||
VERSION HERE**
|
||||
|
||||
- List the steps to reproduce the problem below (if possible attach a sketch or
|
||||
copy the sketch code in too): **LIST REPRO STEPS BELOW**
|
||||
26
arduino-cli/libraries/Adafruit-PWM-Servo-Driver/.github/PULL_REQUEST_TEMPLATE.md
vendored
Normal file
26
arduino-cli/libraries/Adafruit-PWM-Servo-Driver/.github/PULL_REQUEST_TEMPLATE.md
vendored
Normal file
@@ -0,0 +1,26 @@
|
||||
Thank you for creating a pull request to contribute to Adafruit's GitHub code!
|
||||
Before you open the request please review the following guidelines and tips to
|
||||
help it be more easily integrated:
|
||||
|
||||
- **Describe the scope of your change--i.e. what the change does and what parts
|
||||
of the code were modified.** This will help us understand any risks of integrating
|
||||
the code.
|
||||
|
||||
- **Describe any known limitations with your change.** For example if the change
|
||||
doesn't apply to a supported platform of the library please mention it.
|
||||
|
||||
- **Please run any tests or examples that can exercise your modified code.** We
|
||||
strive to not break users of the code and running tests/examples helps with this
|
||||
process.
|
||||
|
||||
Thank you again for contributing! We will try to test and integrate the change
|
||||
as soon as we can, but be aware we have many GitHub repositories to manage and
|
||||
can't immediately respond to every request. There is no need to bump or check in
|
||||
on a pull request (it will clutter the discussion of the request).
|
||||
|
||||
Also don't be worried if the request is closed or not integrated--sometimes the
|
||||
priorities of Adafruit's GitHub code (education, ease of use) might not match the
|
||||
priorities of the pull request. Don't fret, the open source community thrives on
|
||||
forks and GitHub makes it easy to keep your changes in a forked repo.
|
||||
|
||||
After reviewing the guidelines above you can delete this text from the pull request.
|
||||
32
arduino-cli/libraries/Adafruit-PWM-Servo-Driver/.github/workflows/githubci.yml
vendored
Normal file
32
arduino-cli/libraries/Adafruit-PWM-Servo-Driver/.github/workflows/githubci.yml
vendored
Normal file
@@ -0,0 +1,32 @@
|
||||
name: Arduino Library CI
|
||||
|
||||
on: [pull_request, push, repository_dispatch]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/setup-python@v1
|
||||
with:
|
||||
python-version: '3.x'
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
repository: adafruit/ci-arduino
|
||||
path: ci
|
||||
|
||||
- name: pre-install
|
||||
run: bash ci/actions_install.sh
|
||||
|
||||
- name: test platforms
|
||||
run: python3 ci/build_platform.py main_platforms
|
||||
|
||||
- name: clang
|
||||
run: python3 ci/run-clang-format.py -e "ci/*" -e "bin/*" -r .
|
||||
|
||||
- name: doxygen
|
||||
env:
|
||||
GH_REPO_TOKEN: ${{ secrets.GH_REPO_TOKEN }}
|
||||
PRETTYNAME : "Adafruit PCA9685 PWM Library"
|
||||
run: bash ci/doxy_gen_and_deploy.sh
|
||||
8
arduino-cli/libraries/Adafruit-PWM-Servo-Driver/.gitignore
vendored
Normal file
8
arduino-cli/libraries/Adafruit-PWM-Servo-Driver/.gitignore
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
# osx
|
||||
.DS_Store
|
||||
|
||||
# doxygen
|
||||
Doxyfile*
|
||||
doxygen_sqlite3.db
|
||||
html
|
||||
*.tmp
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user