Okay so first thing is first… I just turned it on and it’s sometimes working fine now. Like, a few times it worked fine and now it’s back to not working again… without even changing the code. I have no fucking clue why though. I didn’t change the code since yesterday when it was broken.
Here is the code for the receiving Arduino, the one giving me the problem.
#include <VirtualWire.h>
#include <Adafruit_NeoPixel.h>
#ifdef __AVR__
#include <avr/power.h>
#endif
#define VW_DATA_RX_PIN 2 // Digital Pin 12 for receiving data
#define DISPLAY_PIN 13 // Digital Pin 13 to represent power save mode (until implemented)
#define NEOPIXEL_PIN 12 // Digital Pin 4 for feeding data to the neopixel string
// Parameter 1 = number of pixels in strip
// Parameter 2 = Arduino pin number (most are valid)
// Parameter 3 = pixel type flags, add together as needed:
// NEO_KHZ800 800 KHz bitstream (most NeoPixel products w/WS2812 LEDs)
// NEO_KHZ400 400 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 strip = Adafruit_NeoPixel(60, NEOPIXEL_PIN, NEO_GRB + NEO_KHZ800);
enum MessageID
{
MI_COLOR_RED = 0,
MI_COLOR_GREEN = 1,
MI_COLOR_BLUE = 2
};
uint8_t LastMessage = MI_COLOR_RED;
enum ColorNames
{
RED = 0,
GREEN = 1,
BLUE = 2,
COLOR_COUNT
};
const int Colors[COLOR_COUNT][3] =
{
{ 255, 0, 0 }, // RED
{ 0, 255, 0 }, // GREEN
{ 0, 0, 255 }, // BLUE
};
uint8_t MessageBuffer[VW_MAX_MESSAGE_LEN];
uint8_t MessageBufferLength = VW_MAX_MESSAGE_LEN;
// Fill the dots one after the other with a color
void colorWipe(uint32_t c, uint8_t wait) {
Serial.print(strip.numPixels());
Serial.print(" - ");
Serial.print(wait);
Serial.print("\n");
for (int i = 0; i < 10; ++i) strip.setPixelColor(i, c);
delay(50);
}
void CheckForMessages()
{
if (vw_get_message(MessageBuffer, &MessageBufferLength)) // Non-blocking
{
//if (MessageBufferLength != 1) Serial.print(MessageBufferLength);
if (LastMessage == MessageBuffer[0]) return;
LastMessage = MessageBuffer[0];
Serial.print(MessageBuffer[0]);
Serial.write("\n");
switch (MessageBuffer[0])
{
case MI_COLOR_RED: colorWipe(strip.Color(255, 0, 0), 1); break;
//case MI_COLOR_GREEN: /*DO NOTHING*/ break;
case MI_COLOR_BLUE: colorWipe(strip.Color(0, 0, 255), 1); break;
}
strip.show();
}
//else Serial.print(".\n");
//ContinuePattern();
}
void setupReceiver()
{
// Set up the VirtualWire system
vw_set_rx_pin(VW_DATA_RX_PIN);
vw_set_ptt_inverted(true); // Required for DR3100
vw_setup(400); // Bits per sec
vw_rx_start(); // Start the receiver PLL running
}
void setup()
{
pinMode(DISPLAY_PIN, OUTPUT);
// 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();
colorWipe(strip.Color(0, 0, 0), 0);
strip.show(); // Initialize all pixels to 'off'
Serial.begin(9600);
randomSeed(analogRead(0));
setupReceiver();
Serial.write("Program started\n");
}
void loop()
{
CheckForMessages();
}
As you can see, the signal recieved for green (message ID 1) does nothing, except that it shows in the serial output that a message is received. This is how I first discovered that the freezing (of sorts) occurs when I change the color.
If I remove the line “strip.show();” the program works, and I can tell from the Serial output that all messages are being received. Having that line in there breaks the message system completely, though… and obviously I need it to have the LED strip actually light up.
Some notes:
- I tried putting in “interrupts();” right after strip.show() just in case interrupts were still disabled by NeoPixel, but that did nothing.
- I tried re-initializing the radio receiver after strip.show() just in case the interrupts being off temporarily caused a problem, but that did nothing.
- I tried using FastLED as well, but it had the same problem