hejie13250 发表于 2016-7-29 16:43:11

红外遥控支持库与“多线程”支持库冲突导致接收红外乱变

本帖最后由 hejie13250 于 2016-7-29 17:32 编辑

在淘宝上买了一个RGB灯环,每个灯(12个)都带有微型控制器,只用一个IO就可以搞定。
想通过一个4*4的矩阵键盘控制灯环的变色样式,其中按键“D”为关闭所有灯。
现在增加红外遥控来控制,和4*4的矩阵键盘一样。



此时问题来了,不加“多线程”库,读取的红外信号是正常的,加上后读取的信号值就会乱变,下图为多次按下遥控上的“9”后接收到的信号



经排除确认是红外遥控支持库与“多线程”支持库冲突导致,还望大神支招!!!


代码如下:
主体
#include <SCoop.h>

char style = 'd';//灯环样式 style 默认为关闭状,按 d 键或 遥控 EQ关闭

//初始化功能
void setup() {
Serial.begin(9600);
mySCoop.start();//启用“多线程”
}
void loop()
{
yield();
}
遥控接收
#include <IRremote.h>

int RECV_PIN = A0;
IRrecv irrecv(RECV_PIN);
decode_results results;

defineTask(IRremote);
void IRremote::setup()
{
irrecv.enableIRIn(); // 开始接收信号
}

void IRremote::loop()
{
if (irrecv.decode(&results))
{
    switch (results.value)
    {
      //灯环样式 style 默认为关闭状态,按 d 键或 遥控 EQ关闭
      case 16761405:      style = 'd'; break;      // PLAY
      case 16769055:      style = 'c'; break;      // VOL-
      case 16754775:      style = 'b'; break;      // VLO+
      case 16748655:      style = 'a'; break;      // EQ
      case 16738455:      style = '0'; break;      // 0
      case 16750695:      style = '*'; break;      // 100+
      case 16756815:      style = '#'; break;      // 200+
      case 16724175:      style = '1'; break;      // 1
      case 16718055:      style = '2'; break;      // 2
      case 16743045:      style = '3'; break;      // 3
      case 16716015:      style = '4'; break;      // 4
      case 16726215:      style = '5'; break;      // 5
      case 16734885:      style = '6'; break;      // 6
      case 16728765:      style = '7'; break;      // 7
      case 16730805:      style = '8'; break;      // 8
      case 16732845:      style = '9'; break;      // 9
      default : break;
    }
    //Serial.println(style + "" + results.value);
    Serial.print(style);
    Serial.print("");
    Serial.println(results.value);
    irrecv.resume(); //接收下一个信号
}
}

按键部分
//按键4*4定义
const int numRows = 4;//定义4行
const int numCols = 4;//定义4列
const int rowPins = {4, 5, 6, 7}; //设置4*4按键对应的引脚
const int colPins = {8, 9, 10, 11};
const int debounceTime = 20;//去抖动时间长度 20ms
const char keymap = { //键值,可以按需要更改
                                        { '1', '2', '3', 'a' },
                                        { '4', '5', '6', 'b' },
                                        { '7', '8', '9', 'c' },
                                        { '*', '0', '#', 'd' }
                                    };

defineTask(Key);
void Key::setup()
{
for (int row = 0; row < numRows; row++)
{
    pinMode(rowPins, INPUT);
    digitalWrite(rowPins, HIGH);
}
for (int column = 0; column < numCols; column++)
{
    pinMode(colPins, OUTPUT);
    digitalWrite(colPins, HIGH);
}
}
void Key::loop()
{
char key = getkey();
if (key != 0)
{
    Serial.print("Got key ");//串口打印键值
    Serial.println(key);
    style = key;
}
}

//读取键值程序
char getkey()
{
char key = 0;
for (int column = 0; column < numCols; column++) {
    digitalWrite(colPins, LOW);
    for (int row = 0 ; row < numRows; row++) {
      if (digitalRead(rowPins) == LOW) { //是否有按键按下
      sleep(debounceTime);
      while (digitalRead(rowPins) == LOW) //等待按键释放
          ;
      key = keymap;
      }
    }
    digitalWrite(colPins, HIGH); //De-active the current column
}
return key;
}
灯环样式部分
#include <Adafruit_NeoPixel.h>//灯环支持库
#include <stdlib.h>
#define PIN A1 //灯环使用了Arduino的12号端口

// 参数 1 = 条带中的像素数
// 参数 2 = Arduino 的引脚号 (most are valid)
// 参数 3 = 像素类型的标志,根据需要添加在一起:
//   NEO_KHZ800800 KHz 位流 (most NeoPixel products w/WS2812 ColorLEDs)
//   NEO_KHZ400400 KHz (classic 'v1' (not v2) FLORA pixels, WS2811 drivers)
//   NEO_GRB   Pixels are wired for GRB bitstream (most NeoPixel products)
//   NEO_RGB   Pixels are wired for RGB bitstream (v1 FLORA pixels, not v2)
//Adafruit_NeoPixel ColorLED = Adafruit_NeoPixel(60, PIN, NEO_GRB + NEO_KHZ800);

Adafruit_NeoPixel ColorLED = Adafruit_NeoPixel(64, PIN, NEO_GRB + NEO_KHZ800); // 定义灯环为 ColorLED


defineTask(Style);
void Style::setup()
{
//灯初始化
ColorLED.begin();
ColorLED.show(); // 初始化所有像素'关闭'
}
void Style::loop()
{
//这是是loop的内容
switch (style)
{
    case '1': sj(62);      break;
    case '2': colorWipe(ColorLED.Color(255, 0, 0), 62); // 红
      break;
    case '3': colorWipe(ColorLED.Color(0, 255, 0), 62); // 绿
      break;
    case '4': colorWipe(ColorLED.Color(0, 0, 255), 62); // 蓝
      break;
    case '5': theaterChase(ColorLED.Color(127, 127, 127), 100); // 白
      break;
    case '6': theaterChase(ColorLED.Color(127, 0, 0), 100); // 红
      break;
    case '7': theaterChase(ColorLED.Color(0, 127, 0), 100); // 绿
      break;
    case '8': theaterChase(ColorLED.Color(0, 0, 127), 100); // 蓝
      break;
    case '9': theaterChase(ColorLED.Color(255, 64, 127), 100);
      break;
    case '0': theaterChase(ColorLED.Color(0, 255, 127), 100);
      break;
    case '*': rainbow(20);
      break;
    case '#': rainbowCycle(20);
      break;
    case 'a': theaterChaseRainbow(50);
      break;
    case 'b': ab(100);
      break;
    case 'c': sj(200);
      break;
    case 'd': off();
      break;
}
}

////////////灯光模式

//随机模式
void sj(uint8_t wait)
{
for ( int l = 0; l < 12; l++)
{
    ColorLED.setPixelColor(l, ColorLED.Color(random(0, 255), random(0, 255), random(0, 255)));
    ColorLED.show();
    sleep(wait);
}
}

void ab(uint8_t wait)
{
ColorLED.setPixelColor(0, ColorLED.Color(255, 0, 0));
ColorLED.setPixelColor(1, ColorLED.Color(0, 255, 0));
ColorLED.setPixelColor(2, ColorLED.Color(0, 0, 255));
ColorLED.setPixelColor(3, ColorLED.Color(255, 255, 0));
ColorLED.setPixelColor(4, ColorLED.Color(255, 0, 255));
ColorLED.setPixelColor(5, ColorLED.Color(0, 255, 255));
ColorLED.setPixelColor(6, ColorLED.Color(128, 0, 0));
ColorLED.setPixelColor(7, ColorLED.Color(0, 128, 0));
ColorLED.setPixelColor(8, ColorLED.Color(0, 0, 128));
ColorLED.setPixelColor(9, ColorLED.Color(128, 128, 0));
ColorLED.setPixelColor(10, ColorLED.Color(128, 0, 128));
ColorLED.setPixelColor(11, ColorLED.Color(0, 128, 128));
ColorLED.show();
sleep(wait);
}

void off()
{
for ( int l = 0; l < 12; l++)
{
    ColorLED.setPixelColor(l, ColorLED.Color(0, 0, 0));
    ColorLED.show();
}
}

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

void rainbow(uint8_t wait)
{
uint16_t i, j;

for (j = 0; j < 256; j++)
{
    for (i = 0; i < ColorLED.numPixels(); i++)
      ColorLED.setPixelColor(i, Wheel((i + j) & 255));
    ColorLED.show();
    sleep(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 < ColorLED.numPixels(); i++)
      ColorLED.setPixelColor(i, Wheel(((i * 256 / ColorLED.numPixels()) + j) & 255));
    ColorLED.show();
    sleep(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 (int i = 0; i < ColorLED.numPixels(); i = i + 3)
      ColorLED.setPixelColor(i + q, c);//turn every third pixel on
      ColorLED.show();
      sleep(wait);
      for (int i = 0; i < ColorLED.numPixels(); i = i + 3)
      ColorLED.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 (int i = 0; i < ColorLED.numPixels(); i = i + 3)
      ColorLED.setPixelColor(i + q, Wheel((i + j) % 255)); //turn every third pixel on
      ColorLED.show();
      sleep(wait);

      for (int i = 0; i < ColorLED.numPixels(); i = i + 3)
      ColorLED.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)
{
if (WheelPos < 85)
    return ColorLED.Color(WheelPos * 3, 255 - WheelPos * 3, 0);
else if (WheelPos < 170)
{
    WheelPos -= 85;
    return ColorLED.Color(255 - WheelPos * 3, 0, WheelPos * 3);
}
else
{
    WheelPos -= 170;
    return ColorLED.Color(0, WheelPos * 3, 255 - WheelPos * 3);
}
}
代码和要用的库

hejie13250 发表于 2016-7-30 07:50:49

自己顶!!!!!!

谭峰 发表于 2016-11-12 09:30:56

我才刚刚接触Arduino,还暂时不能回答您的这个问题。

不过,我正在到处找多线程库SCoop.h,想开发一个小程序。

您能不能把这个SCoop.h库发给我一份?非常感谢!

我的邮箱是:deak1970@163.com

20060606 发表于 2020-8-15 07:53:39

谭峰 发表于 2016-11-12 09:30
我才刚刚接触Arduino,还暂时不能回答您的这个问题。

不过,我正在到处找多线程库SCoop.h,想开发一个小程 ...

希望在df上挂个链接
页: [1]
查看完整版本: 红外遥控支持库与“多线程”支持库冲突导致接收红外乱变