使用 H-Bridge 和 neopixel 以及 Arduino UNO 控制直流电机

Posted

技术标签:

【中文标题】使用 H-Bridge 和 neopixel 以及 Arduino UNO 控制直流电机【英文标题】:Control dc-motor using H-Bridge and neopixel together with Arduino UNO 【发布时间】:2018-06-19 11:35:16 【问题描述】:

我正在做一个项目,用 H 桥控制直流电机的前后旋转。并在电路开启的同时点亮一个adafruit neopixel。

我让这两件事分开工作。现在我合并了代码,但它不能正常工作。它的工作原理就像直流电机执行一个正向和反向循环并停止。然后新像素环亮起。在新像素代码完成一段时间后,直流电机执行相同的一个循环并继续此循环。

我需要帮助以使此代码同时启动直流电机工作和新像素照明。

代码如下:

#include <Adafruit_NeoPixel.h>

#ifdef __AVR__
  #include <avr/power.h>
#endif

#define PIN 6
Adafruit_NeoPixel strip = Adafruit_NeoPixel(60, PIN, NEO_GRB + NEO_KHZ800);


//DC motor
const int pwm = 3;  //initializing pin 2 as pwm
const int in_1 = 8 ;
const int in_2 = 7 ;

//For providing logic to L298 IC to choose the direction of the DC motor

void setup()

pinMode(pwm,OUTPUT) ;   //we have to set PWM pin as output
pinMode(in_1,OUTPUT) ;  //Logic pins are also set as output
pinMode(in_2,OUTPUT) ;

//Neopixel Ring
// This is for Trinket 5V 16MHz, you can remove these three lines if you are not using a Trinket
#if defined (__AVR_ATtiny85__)
  if (F_CPU == 16000000) clock_prescale_set(clock_div_1);
#endif
  // End of trinket special code

strip.begin();
strip.show(); // Initialize all pixels to 'off'




void loop()

//For Clock wise motion , in_1 = High , in_2 = Low

digitalWrite(in_1,HIGH) ;
digitalWrite(in_2,LOW) ;
analogWrite(pwm,255) ;

/*setting pwm of the motor to 255
we can change the speed of rotaion
by chaning pwm input but we are only
using arduino so we are using higest
value to driver the motor  */

//Clockwise for 3 secs
delay(1000) ;    

//For brake
digitalWrite(in_1,HIGH) ;
digitalWrite(in_2,HIGH) ;
delay(50) ;

//For Anti Clock-wise motion - IN_1 = LOW , IN_2 = HIGH
digitalWrite(in_1,LOW) ;
digitalWrite(in_2,HIGH) ;
delay(1000) ;

//For brake
digitalWrite(in_1,HIGH) ;
digitalWrite(in_2,HIGH) ;
delay(50) ;

//Neopixel Ring

// Some example procedures showing how to display to the pixels:
  colorWipe(strip.Color(255, 0, 0), 50); // Red
  colorWipe(strip.Color(0, 255, 0), 50); // Green
  colorWipe(strip.Color(0, 0, 255), 50); // Blue
//colorWipe(strip.Color(0, 0, 0, 255), 50); // White RGBW
  // Send a theater pixel chase in...
  theaterChase(strip.Color(127, 127, 127), 50); // White
  theaterChase(strip.Color(127, 0, 0), 50); // Red
  theaterChase(strip.Color(0, 0, 127), 50); // Blue

  rainbow(20);
  rainbowCycle(20);
  theaterChaseRainbow(50);


// Fill the dots one after the other with a color
void colorWipe(uint32_t c, uint8_t wait) 
  for(uint16_t i=0; i<strip.numPixels(); i++) 
    strip.setPixelColor(i, c);
    strip.show();
    delay(wait);
  


void rainbow(uint8_t wait) 
  uint16_t i, j;

  for(j=0; j<256; j++) 
    for(i=0; i<strip.numPixels(); i++) 
      strip.setPixelColor(i, Wheel((i+j) & 255));
    
    strip.show();
    delay(wait);
  


// Slightly different, this makes the rainbow equally distributed throughout
void rainbowCycle(uint8_t wait) 
  uint16_t i, j;

  for(j=0; j<256*5; j++)  // 5 cycles of all colors on wheel
    for(i=0; i< strip.numPixels(); i++) 
      strip.setPixelColor(i, Wheel(((i * 256 / strip.numPixels()) + j) & 255));
    
    strip.show();
    delay(wait);
  


//Theatre-style crawling lights.
void theaterChase(uint32_t c, uint8_t wait) 
  for (int j=0; j<10; j++)   //do 10 cycles of chasing
    for (int q=0; q < 3; q++) 
      for (uint16_t i=0; i < strip.numPixels(); i=i+3) 
        strip.setPixelColor(i+q, c);    //turn every third pixel on
      
      strip.show();

      delay(wait);

      for (uint16_t i=0; i < strip.numPixels(); i=i+3) 
        strip.setPixelColor(i+q, 0);        //turn every third pixel off
      
    
  


//Theatre-style crawling lights with rainbow effect
void theaterChaseRainbow(uint8_t wait) 
  for (int j=0; j < 256; j++)      // cycle all 256 colors in the wheel
    for (int q=0; q < 3; q++) 
      for (uint16_t i=0; i < strip.numPixels(); i=i+3) 
        strip.setPixelColor(i+q, Wheel( (i+j) % 255));    //turn every third pixel on
      
      strip.show();

      delay(wait);

      for (uint16_t i=0; i < strip.numPixels(); i=i+3) 
        strip.setPixelColor(i+q, 0);        //turn every third pixel off
      
    
  


// Input a value 0 to 255 to get a color value.
// The colours are a transition r - g - b - back to r.
uint32_t Wheel(byte WheelPos) 
  WheelPos = 255 - WheelPos;
  if(WheelPos < 85) 
    return strip.Color(255 - WheelPos * 3, 0, WheelPos * 3);
  
  if(WheelPos < 170) 
    WheelPos -= 85;
    return strip.Color(0, WheelPos * 3, 255 - WheelPos * 3);
  
  WheelPos -= 170;
  return strip.Color(WheelPos * 3, 255 - WheelPos * 3, 0);



【问题讨论】:

【参考方案1】:

基本上每次您调用延迟时,arduino 都无法执行任何其他操作。因此,您需要将控制权切换到您想做的任何其他事情上。

有几种方法:

计时器 - 使用计时器来更新您的两个任务之一的状态。这样做的好处是你的任务不依赖另一个任务来产生,但不会超过几个任务。

软件状态机 - 为每个任务创建一个状态机,并在循环中依次递增每个状态机。您需要创建一个结构来跟踪任务的状态,每次调用延迟时,您都会更新结构并返回。通常你会为每个任务创建一个类,就像在this Adafruit tutorial 中所做的那样。这可能需要大量工作,因此有一些库可以为您完成。

协程 - 这些使用库来为您构建状态机。例如http://forum.arduino.cc/index.php?topic=256256.0

【讨论】:

非常感谢您的回答。我基本上正在阅读您放置的adafruit链接,仍然可以理解。由于我的代码中有两个并行任务,请您编辑我的代码,以便直流电机和新像素同时工作。它将帮助我更多地了解它在未来的工作中是如何工作的。

以上是关于使用 H-Bridge 和 neopixel 以及 Arduino UNO 控制直流电机的主要内容,如果未能解决你的问题,请参考以下文章

Neopixel 示例代码在使用更多像素时崩溃

PyMonzo 库和使用 Raspberry Pi 3 的 Adafruit_Neopixel 库之间的冲突

使用用户输入中断while循环(通过arduino和python 2.7控制neopixels)

Neopixel / WS2811 通过本地 HTML 控制

带孔的 Neopixel 矩阵

具有多个 NeoPixels 的 Arduino Sketch(采用不同 NeoPixels 的功能)