本帖最后由 jinglixixi 于 2021-9-13 17:14 编辑
#申请原创#
Firebeetle开发板是一款体型小巧、功能丰富的开发板,并可以Arduino IDE来开发,从而有效地化解编程的复杂性。 1.硬件构成: 以Firebeetle开发板为核心,在红外接收模块和W2812彩色灯带的配合下即可完成一个遥控型彩色灯带显示装置。由于W2812彩色灯带是一种单总线型的器件,因此可以级联起来使用,以形成一条长度可以进行延伸的彩色灯带。 至于红外接收模块的模块的使用,则是为了便于进行非接触性的操控。红外接收模块的引脚也非常简单,除了信号输出引脚外,就只是2个电源引脚了。 所用的遥控器则是一款为太阳能充电灯所配置的遥控器,按键不是很多,其主要作用就是对于电源开关及工作模式的切换。 硬件的整体构成如图1所示,其结构框图则如图2所示。 图1 整体构成
图2结构框图
根据 NEC 协议的标准,每一帧数据的周期为 110 ms,且逻辑 0 和 逻辑 1的波形如图3所示。其中逻辑 1 对应的两个高电平的时间间隔为 2.25ms,同样地逻辑 0 对应的两个高电平的时间间隔为 1.12ms。 图3 NEC 协议波形
2.程序设计 在引脚的连接方面,其对应关系如下: 红外接收模块的OUT---开发板的SCL W2812彩色灯带的DI---开发板的A4
因此对相关的引脚对应如下: int IR_RECEIVE_PIN = 15; #define DATA_PIN SCL int LED_PIN= D9; int KEY_PIN = D4; 所实现的功能为: 1)使用开发板上的按键可切换LED灯的亮灭; 2)使用遥控器的电源开关键可控制LED灯的亮灭; 3)使用遥控器的模式键可进行彩色灯带的色彩变换及演示效果的切换。 为了便于后续的程序设计,先进行了遥控器的键值检测,经检测该遥控器的相应键值为: ON键---0xFFA25D OFF键---0xFFE21D MODE1---0xFFE01F MODE2---0xFFA857 MODE3---0xFF906F
故该遥控器的键值识别处理程序如下: - if(codeValue==0xFFA25D)
- {
- Serial.println("ON");
- F=1;
- }
- if(codeValue==0xFFE21D)
- {
- Serial.println("OFF");
- F=0;
- }
- if(codeValue==0xFFE01F)
- {
- Serial.println("R");
- F=2;
- }
- if(codeValue==0xFFA857)
- {
- Serial.println("G");
- F=3;
- }
- if(codeValue==0xFF906F)
- {
- Serial.println("B");
- F=4;
- }
- }
- }
其中变量F的作用是标识所要执行的处理功能,所输出的提示信息则是为了便于进行验证,其验证结果如图4所示,说明识别有效。 图4 测试结果
为此,所设计的各模式切换处理程序如下: - if(F==2)
- {
- for(i=0;i<NUM_LEDS;i++)
- {
- //灯珠显示红色依次点亮
- leds[i] = CRGB::Red;
- FastLED.show();
- delay(500);
- }
- }
- if(F==3)
- {
- for(i=0;i<NUM_LEDS;i++)
- {
- //灯珠显示绿色依次点亮
- leds[i] = CRGB::Green;
- FastLED.show();
- delay(500);
- }
- }
- if(F==4)
- {
- for(i=0;i<NUM_LEDS;i++)
- {
- //灯珠显示蓝色依次点亮
- leds[i] = CRGB::Blue;
- FastLED.show();
- delay(500);
- }
其测试效果如图5至图8所示,其演示效果为按指定的色彩从前至后依次递进点亮。当然我们也可以按自己意愿来设计所需的效果。 图5 模式1的效果 图6模式2的效果 图7 模式3的效果
除了前面介绍的遥控方式外,它还支持按键的操控方式,实现两种操控方式的兼容,其执行效果如图8所示。
图8 电源键效果
这种与遥控方式兼容的处理程序为: if(digitalRead(KEY_PIN)==LOW) F=(F+1)%2; if(F==1) digitalWrite(LED_PIN,HIGH); else digitalWrite(LED_PIN,LOW);
这里由于是按照变量F的值进行判别处理,故达到了2种控制方式的并行不背。 若将上面的条件语句改为:if(digitalRead(KEY_PIN)==LOW) F=(F+1)%5; 则按键与遥控器的作用是等价的,否则只是在控制LED灯时作用相同。
有了前面的这些介绍,再了解下面的完整程序就不困难了。此外,在此框架的基础上若再添加或修改程序,则可适应自己的功能需求,例如以遥控器控制一个MP3语音播放器等。
3.程序内容 该设计的完整程序如下: - #include <FastLED.h>
- #define NUM_LEDS 7
- #define DATA_PIN SCL
- CRGB leds[NUM_LEDS];
- #include <IRremote.h>
- #if defined(ESP32)
- int IR_RECEIVE_PIN = 15;
- int SEND_BUTTON_PIN = 16;
- #endif
- int STATUS_PIN = LED_BUILTIN;
- IRrecv irrecv(IR_RECEIVE_PIN);
- IRsend irsend;
- decode_results results;
- int LED_PIN = D9;
- int KEY_PIN = D4;
- int F=0;
- #if defined(ARDUINO_ARCH_SAMD)
- #define Serial SerialUSB
- #endif
- void setup() {
- pinMode(LED_PIN, OUTPUT);
- pinMode(KEY_PIN, INPUT_PULLUP);
- digitalWrite(LED_PIN, HIGH);
- FastLED.addLeds<NEOPIXEL, DATA_PIN>(leds, NUM_LEDS);
- Serial.begin(115200);
- irrecv.enableIRIn(); // Start the receiver
- pinMode(SEND_BUTTON_PIN, INPUT_PULLUP);
- pinMode(STATUS_PIN, OUTPUT);
- Serial.print(F("Ready to receive IR signals at pin "));
- Serial.println(IR_RECEIVE_PIN);
- Serial.print(F("Ready to send IR signals at pin "));
- Serial.println(IR_SEND_PIN);
- }
- int codeType = -1;
- unsigned long codeValue;
- unsigned int rawCodes[RAW_BUFFER_LENGTH];
- int codeLen;
- int toggle = 0;
- void storeCode(decode_results *results) {
- codeType = results->decode_type;
- if (codeType == UNKNOWN) {
- Serial.println("");
- } else {
- if (codeType == NEC) {
- Serial.print("Received NEC: ");
- if (results->value == REPEAT) {
- // Don't record a NEC repeat value as that's useless.
- //Serial.println("repeat; ignoring.");
- Serial.println("");
- return;
- }
- }
- Serial.println(results->value, HEX);
- codeValue = results->value;
- codeLen = results->bits;
- if(codeValue==0xFFA25D)
- {
- Serial.println("ON");
- F=1;
- }
- if(codeValue==0xFFE21D)
- {
- Serial.println("OFF");
- F=0;
- }
- if(codeValue==0xFFE01F)
- {
- Serial.println("R");
- F=2;
- }
- if(codeValue==0xFFA857)
- {
- Serial.println("G");
- F=3;
- }
- if(codeValue==0xFF906F)
- {
- Serial.println("B");
- F=4;
- }
- }
- }
- void sendCode(int repeat) {
- }
- int lastButtonState;
- void loop() {
- int i;
- // If button pressed, send the code.
- int buttonState = digitalRead(SEND_BUTTON_PIN);
- if (lastButtonState == LOW && buttonState == HIGH) {
- Serial.println("Released");
- irrecv.enableIRIn(); // Re-enable receiver
- }
- if (buttonState == LOW) {
- Serial.println("Pressed, sending");
- digitalWrite(STATUS_PIN, HIGH);
- sendCode(lastButtonState == buttonState);
- digitalWrite(STATUS_PIN, LOW);
- delay(50);
- } else if (irrecv.decode(&results)) {
- digitalWrite(STATUS_PIN, HIGH);
- storeCode(&results);
- irrecv.resume(); // resume receiver
- digitalWrite(STATUS_PIN, LOW);
- }
- lastButtonState = buttonState;
- if(digitalRead(KEY_PIN)==LOW) F=(F+1)%2;
- if(F==1) digitalWrite(LED_PIN, HIGH);
- else digitalWrite(LED_PIN, LOW);
- if(F==2)
- {
- for(i=0;i<NUM_LEDS;i++)
- {
- //灯珠显示红色
- leds[i] = CRGB::Red;
- FastLED.show();
- delay(500);
- }
- }
- if(F==3)
- {
- for(i=0;i<NUM_LEDS;i++)
- {
- //灯珠显示绿色
- leds[i] = CRGB::Green;
- FastLED.show();
- delay(500);
- }
- }
- if(F==4)
- {
- for(i=0;i<NUM_LEDS;i++)
- {
- //灯珠显示蓝色
- leds[i] = CRGB::Blue;
- FastLED.show();
- delay(500);
- }
- }
- }
动画效果:
|