1/* 2 * Author: Jon Trulson <jtrulson@ics.com> 3 * Copyright (c) 2015 Intel Corporation. 4 * 5 * Permission is hereby granted, free of charge, to any person obtaining 6 * a copy of this software and associated documentation files (the 7 * "Software"), to deal in the Software without restriction, including 8 * without limitation the rights to use, copy, modify, merge, publish, 9 * distribute, sublicense, and/or sell copies of the Software, and to 10 * permit persons to whom the Software is furnished to do so, subject to 11 * the following conditions: 12 * 13 * The above copyright notice and this permission notice shall be 14 * included in all copies or substantial portions of the Software. 15 * 16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 20 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 21 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 22 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23 */ 24 25#include <iostream> 26#include <string> 27#include <stdexcept> 28 29#include "uln200xa.h" 30 31using namespace upm; 32using namespace std; 33 34ULN200XA::ULN200XA(int stepsPerRev, int i1, int i2, int i3, int i4) 35{ 36 m_stepsPerRev = stepsPerRev; 37 m_currentStep = 0; 38 m_stepDelay = 0; 39 m_stepDirection = 1; // default is forward 40 41 if ( !(m_stepI1 = mraa_gpio_init(i1)) ) 42 { 43 throw std::invalid_argument(std::string(__FUNCTION__) + 44 ": mraa_gpio_init(i1) failed, invalid pin?"); 45 return; 46 } 47 mraa_gpio_dir(m_stepI1, MRAA_GPIO_OUT); 48 49 if ( !(m_stepI2 = mraa_gpio_init(i2)) ) 50 { 51 throw std::invalid_argument(std::string(__FUNCTION__) + 52 ": mraa_gpio_init(i2) failed, invalid pin?"); 53 mraa_gpio_close(m_stepI1); 54 return; 55 } 56 mraa_gpio_dir(m_stepI2, MRAA_GPIO_OUT); 57 58 if ( !(m_stepI3 = mraa_gpio_init(i3)) ) 59 { 60 throw std::invalid_argument(std::string(__FUNCTION__) + 61 ": mraa_gpio_init(i3) failed, invalid pin?"); 62 mraa_gpio_close(m_stepI1); 63 mraa_gpio_close(m_stepI2); 64 return; 65 } 66 mraa_gpio_dir(m_stepI3, MRAA_GPIO_OUT); 67 68 if ( !(m_stepI4 = mraa_gpio_init(i4)) ) 69 { 70 throw std::invalid_argument(std::string(__FUNCTION__) + 71 ": mraa_gpio_init(i4) failed, invalid pin?"); 72 mraa_gpio_close(m_stepI1); 73 mraa_gpio_close(m_stepI2); 74 mraa_gpio_close(m_stepI3); 75 76 return; 77 } 78 mraa_gpio_dir(m_stepI4, MRAA_GPIO_OUT); 79 80 // set default speed to 1 81 setSpeed(1); 82} 83 84void ULN200XA::initClock() 85{ 86 gettimeofday(&m_startTime, NULL); 87} 88 89uint32_t ULN200XA::getMillis() 90{ 91 struct timeval elapsed, now; 92 uint32_t elapse; 93 94 // get current time 95 gettimeofday(&now, NULL); 96 97 // compute the delta since m_startTime 98 if( (elapsed.tv_usec = now.tv_usec - m_startTime.tv_usec) < 0 ) 99 { 100 elapsed.tv_usec += 1000000; 101 elapsed.tv_sec = now.tv_sec - m_startTime.tv_sec - 1; 102 } 103 else 104 { 105 elapsed.tv_sec = now.tv_sec - m_startTime.tv_sec; 106 } 107 108 elapse = (uint32_t)((elapsed.tv_sec * 1000) + (elapsed.tv_usec / 1000)); 109 110 // never return 0 111 if (elapse == 0) 112 elapse = 1; 113 114 return elapse; 115} 116 117 118ULN200XA::~ULN200XA() 119{ 120 mraa_gpio_close(m_stepI1); 121 mraa_gpio_close(m_stepI2); 122 mraa_gpio_close(m_stepI3); 123 mraa_gpio_close(m_stepI4); 124} 125 126void ULN200XA::setSpeed(int speed) 127{ 128 m_stepDelay = 60 * 1000 / m_stepsPerRev / speed; 129} 130 131void ULN200XA::setDirection(ULN200XA_DIRECTION_T dir) 132{ 133 switch (dir) 134 { 135 case DIR_CW: 136 m_stepDirection = 1; 137 break; 138 case DIR_CCW: 139 m_stepDirection = -1; 140 break; 141 } 142} 143 144void ULN200XA::stepperStep() 145{ 146 int step = m_currentStep % 8; 147 148 // This motor requires a different sequencing order in 8-steps than 149 // usual. 150 151 // Step I0 I1 I2 I3 152 // 1 0 0 0 1 153 // 2 0 0 1 1 154 // 3 0 0 1 0 155 // 4 0 1 1 0 156 // 5 0 1 0 0 157 // 6 1 1 0 0 158 // 7 1 0 0 0 159 // 8 1 0 0 1 160 161 switch (step) 162 { 163 case 0: // 0001 164 mraa_gpio_write(m_stepI1, 0); 165 mraa_gpio_write(m_stepI2, 0); 166 mraa_gpio_write(m_stepI3, 0); 167 mraa_gpio_write(m_stepI4, 1); 168 break; 169 case 1: // 0011 170 mraa_gpio_write(m_stepI1, 0); 171 mraa_gpio_write(m_stepI2, 0); 172 mraa_gpio_write(m_stepI3, 1); 173 mraa_gpio_write(m_stepI4, 1); 174 break; 175 case 2: // 0010 176 mraa_gpio_write(m_stepI1, 0); 177 mraa_gpio_write(m_stepI2, 0); 178 mraa_gpio_write(m_stepI3, 1); 179 mraa_gpio_write(m_stepI4, 0); 180 break; 181 case 3: // 0110 182 mraa_gpio_write(m_stepI1, 0); 183 mraa_gpio_write(m_stepI2, 1); 184 mraa_gpio_write(m_stepI3, 1); 185 mraa_gpio_write(m_stepI4, 0); 186 break; 187 case 4: // 0100 188 mraa_gpio_write(m_stepI1, 0); 189 mraa_gpio_write(m_stepI2, 1); 190 mraa_gpio_write(m_stepI3, 0); 191 mraa_gpio_write(m_stepI4, 0); 192 break; 193 case 5: // 1100 194 mraa_gpio_write(m_stepI1, 1); 195 mraa_gpio_write(m_stepI2, 1); 196 mraa_gpio_write(m_stepI3, 0); 197 mraa_gpio_write(m_stepI4, 0); 198 break; 199 case 6: // 1000 200 mraa_gpio_write(m_stepI1, 1); 201 mraa_gpio_write(m_stepI2, 0); 202 mraa_gpio_write(m_stepI3, 0); 203 mraa_gpio_write(m_stepI4, 0); 204 break; 205 case 7: // 1001 206 mraa_gpio_write(m_stepI1, 1); 207 mraa_gpio_write(m_stepI2, 0); 208 mraa_gpio_write(m_stepI3, 0); 209 mraa_gpio_write(m_stepI4, 1); 210 break; 211 } 212} 213 214void ULN200XA::stepperSteps(unsigned int steps) 215{ 216 while (steps > 0) 217 { 218 if (getMillis() >= m_stepDelay) 219 { 220 // reset the clock 221 initClock(); 222 223 m_currentStep += m_stepDirection; 224 225 if (m_stepDirection == 1) 226 { 227 if (m_currentStep >= m_stepsPerRev) 228 m_currentStep = 0; 229 } 230 else 231 { 232 if (m_currentStep <= 0) 233 m_currentStep = m_stepsPerRev; 234 } 235 236 steps--; 237 stepperStep(); 238 } 239 } 240} 241 242void ULN200XA::release() 243{ 244 mraa_gpio_write(m_stepI1, 0); 245 mraa_gpio_write(m_stepI2, 0); 246 mraa_gpio_write(m_stepI3, 0); 247 mraa_gpio_write(m_stepI4, 0); 248} 249