NeoPixel Arduino-Uno Programing

Good day all,

First off I am a beginner so apologies in advance if my questions are new-be ones. :slight_smile: However I love this stuff so teach me what I am doing wrong.

I have a very basic project I am trying to have my NEOPixels Light up the front of a road case, and a second NEOPixels strip that light up the back of the case. Two PIR ( Motion Sensors) one for the front and one for the back. each PIR would control the strip assigned to it ( FRONT) & (BACK).
If no motion is detected the led's are at 30% brightness, if motion is detected that section got to 100%.

Override Switch to bypass the PIR Sensors. LED's stay at current intensity.

Lastly Priority override for all if an E-Stop is pressed the All lights go red.

None of it is working when I add it all together, it work if I have one component. What am I missing?

Curent code:

#include <Adafruit_NeoPixel.h>
 
int NeoLEDFront = 2;    // the data pin for the NeoPixels Front
int NeoLEDRear = 5;    // the data pin for the NeoPixels  Rear
						//int numPixels = 40;     // How many NeoPixels we will be using
int FrontPixels = 20;   // How Many NeoPixels Front
int RearPixels = 20;   // How Many NeoPixels Rear
int ESTOP = 13;
int Override = 12;
int i = 0;

Adafruit_NeoPixel strip_Front = Adafruit_NeoPixel(FrontPixels, NeoLEDFront, NEO_GRB + NEO_KHZ800);  // Instatiate the NeoPixel from the Library
Adafruit_NeoPixel strip_Rear = Adafruit_NeoPixel(RearPixels, NeoLEDRear, NEO_GRB + NEO_KHZ800);  // Instatiate the NeoPixel from the Library

int r = 128;			// Global RGB values, change to suit your needs
int g = 128;
int b = 128;

int MotionFront = 3;     // Motion Sensor Input Side 1 Front
int MotionRear = 4;     // Motion Sensor Input Side 1 Rear

  
void setup() {
  pinMode(ESTOP, INPUT);         //Estop input
  pinMode(Override, INPUT);      // Override Switch
  pinMode(MotionFront, INPUT);   // PRI Sensor Input
  pinMode(MotionRear, INPUT);    // PRI Sensor Input
  pinMode(NeoLEDFront, OUTPUT);  // NeoPixel Signal Output
  pinMode(NeoLEDRear, OUTPUT);   // NeoPixel Signal Output
  strip_Front.begin();  // initialize the strip
  strip_Rear.begin();
  strip_Front.show();   // make sure it is visible
  strip_Rear.show();   
  strip_Front.clear();  // Initialize all pixels to 'off'
  strip_Rear.clear();
  Serial.begin(9600);
}

void loop() {
  if( digitalRead(ESTOP) == true ) {                       
 Serial.println("E-STOP");
    for( int i = 0; i < FrontPixels, RearPixels;  i++ )          // if value is 0,0,0, then the pixel will be "off"
       strip_Front.setPixelColor(i, 255, 0, 0 );
       strip_Rear.setPixelColor(i, 255, 0, 0 ); 
  }
    if( digitalRead(Override) == true ) {              // Check to see if the button is down
 Serial.println("Override");
    for( int i = 0; i < FrontPixels, RearPixels;  i++ )          // if value is 0,0,0, then the pixel will be "off"
       strip_Front.setPixelColor(i, 255, 255, 255 );
       strip_Rear.setPixelColor(i, 255, 255, 255 ); 
  }  
 if( digitalRead(MotionFront) == true ) {              // Check to see if the button is down
 Serial.println("Front Motion!");
 for( int i = 0; i < FrontPixels; i++ )                // if value is 0,0,0, then the pixel will be "off"
       strip_Front.setPixelColor(i, 255, 0, 0 );
 } 
if( digitalRead(MotionRear) == true ) {              // Check to see if the button is down
 Serial.println("Rear Motion!");
 for( int i = 0; i < RearPixels; i++ )                // if value is 0,0,0, then the pixel will be "off"
       strip_Rear.setPixelColor(i, 255, 255, 255 );
}
  else {
  Serial.println("Normal Operation");
     
     for( int i = 0; i < FrontPixels, RearPixels;  i++ )
      strip_Front.setPixelColor(i, r, g, b);
      strip_Rear.setPixelColor(i, r, g, b);
       
  } 
strip_Front.show();
strip_Rear.show();
  
  // delay for the purposes of debouncing the switch
  delay(10);
}

Do you mean that you have previous sketches that can do one thing each like testing one of the things that go into your bigger project?

Have you just made one regular LED show your PIR working?

Have you gotten one attached neopixel strip to do something, just and only?

And what does "it work[s as] if I have one component"? Not sure what you are seeing.

Do your print statements shed any light on how the program is flowing? You could add more to get a finer picture.

a7

     
     for( int i = 0; i < FrontPixels, RearPixels;  i++ )
      strip_Front.setPixelColor(i, r, g, b);
      strip_Rear.setPixelColor(i, r, g, b);
       

Looks like you mean to control two statements judging by your indentation.

C/C++ won't take that hint. Perhaps you mean

     
     for( int i = 0; i < FrontPixels, RearPixels;  i++ ) {
       strip_Front.setPixelColor(i, r, g, b);
       strip_Rear.setPixelColor(i, r, g, b);
     }   

The braces make the one statement the for loop controls, a statement that is two statments.

If you've made similar syntactic errors, that could explain some things. Check that.

a7

     for( int i = 0; i < FrontPixels, RearPixels;  i++ )

Someone can take the time to explain why this for loop causes your code to malfunction.

It is valid syntax but isn't doing what you think... you can't improvise!

Since FrontPixels and RearPixels are idenitcal, for now use

     for( int i = 0; i < RearPixels;  i++ )

When they aren't, you'll need to use two loops or some logic. Until then...

HTH

a7

Change all the instructions to turn on the leds of the type:

strip_Front.setPixelColor(i, r, g, b);

Do it like the "Adafruit_NeoPixel.h" library does in its examples:

 strip_Front.setPixelColor(i, pixels.Color(r, g, b));

Wow

Thank you all for your prompt reply's

I have addressed all of the comments and tried all and variations, with no success.

Here are to screen grabs of the hardware.


(upload://vwmtP0c3B2mkNsqP4X5diMVZDvu.png)

Here is the second photo.

It has to be coding,

Think the issue has to do with the IF, ELSE terminology

Your switches are not wired right. The switch inputs are floating when the switches are open. Put a pulldown resistor from each switch input pin to ground. 10K is a good value. Or better yet, wire the common to ground instead of Vcc and enable the internal pullup on each switch input with pinMode(pin, INPUT_PULLUP); The switches will read HIGH when open and LOW when closed so you will need to adjust your logic in the code.

If you want to continue with our help, please post your latest code in a new response on this thread.

The complete code that compiles, runs and doesn't do what you want.

A good idea of what you see it doing that it shouldn't, or not doing that it should.

Why? What do you think this helps? Have you tested and found the OP's version to not work, while yours fixes something that made it not work?

a7

I don't know from which library he got the original instruction he publishes. But in the library "Adafruit_NeoPixel.h" is as I said before, just open any example of those that brings to see it.

And as for the wiring diagram, I totally agree with @groundFungus.
@rigger1, you must change the connection of the buttons and at the same time add a resistance of between 300 - 450 ohms between the arduino pins and the "IN" of the strips to protect the first diode of the strip.
It is also highly advisable to install a 1000 Uf electrolytic capacitor at the power led strip and as close as possible to it (preferably on it).

1 Like

Thanks all for the help. Again apologies for the new-be mistakes.

Here is my current code, on the advise of @groundFungus., & gonpezzi. I have revised the drawing.

CODE:

#include <Adafruit_NeoPixel.h>
#ifdef __AVR__
#include <avr/power.h> // Required for 16 MHz Adafruit Trinket
#endif
 
int NeoLEDFront = 2;    // the data pin for the NeoPixels Front
int NeoLEDRear = 5;    // the data pin for the NeoPixels  Rear
						//int numPixels = 40;     // How many NeoPixels we will be using
int FrontPixels = 20;   // How Many NeoPixels Front
int RearPixels = 20;   // How Many NeoPixels Rear
int ESTOP = 13;
int Override = 12;
int r = 8;			// Global RGB values, change to suit your needs
int g = 0;
int b = 255;
int MotionFront = 3;     // Motion Sensor Input Side 1 Front
int MotionRear = 4;      // Motion Sensor Input Side 1 Rear
int delayval = 100;

Adafruit_NeoPixel strip_Front = Adafruit_NeoPixel(FrontPixels, NeoLEDFront, NEO_GRB + NEO_KHZ800);  // Instatiate the NeoPixel from the Library
Adafruit_NeoPixel strip_Rear = Adafruit_NeoPixel(RearPixels, NeoLEDRear, NEO_GRB + NEO_KHZ800);  // Instatiate the NeoPixel from the Library

  
void setup() {
 pinMode(ESTOP, INPUT);         //Estop input
 pinMode(Override, INPUT);      // Override Switch
 pinMode(MotionFront, INPUT);   // PRI Sensor Input
 pinMode(MotionRear, INPUT);    // PRI Sensor Input
 pinMode(NeoLEDFront, OUTPUT);  // NeoPixel Signal Output
 pinMode(NeoLEDRear, OUTPUT);   // NeoPixel Signal Output
 pinMode(ESTOP, INPUT_PULLUP);
  strip_Front.begin();  // initialize the strip
  strip_Rear.begin();
  strip_Front.show();  
  strip_Rear.show();   // Initialize all pixels to 'off'
  Serial.begin(9600);
}

void loop() {
  if(digitalRead(ESTOP)== HIGH)
    for(int i=0;i<FrontPixels;i++){
    strip_Front.setPixelColor(i, strip_Front.Color(255,0,0)); {  // Moderately bright green color.
  }
 }
    for(int i=0;i<RearPixels;i++){
   strip_Rear.setPixelColor(i, strip_Rear.Color(255,0,0));{
   strip_Front.show();
   strip_Rear.show();
  }
    }
  if(digitalRead(MotionFront)== HIGH)
    for(int i=0;i<FrontPixels;i++){
   strip_Front.setPixelColor(i, strip_Front.Color(0,150,0));  // Moderately bright green color.
   strip_Front.show();
  }
  if(digitalRead(MotionFront)== LOW)
    for(int i=0;i<FrontPixels;i++){
   strip_Front.setPixelColor(i, strip_Front.Color(125,125,125));  // Moderately bright Red color.
   strip_Front.show();
  }
   if(digitalRead(MotionRear)== HIGH)
    for(int i=0;i<RearPixels;i++){
   strip_Rear.setPixelColor(i, strip_Rear.Color(200,255,200));  
   strip_Rear.show();
  }
   if(digitalRead(MotionRear)== LOW)
    for(int i=0;i<RearPixels;i++){
   strip_Rear.setPixelColor(i, strip_Rear.Color(125,125,125));  
   strip_Rear.show(); 
    
  delay(delayval); // Delay for a period of time (in milliseconds.    
  }
}

Goal:

To have two independent led strips that rest at 50% intensity, white color ( 128,128,128)
when motion is detected the leds go to 100% intensity. IF E-STOP is pressed the lights go to Red ( 255,0,0) Lastly if a switch is pressed the lights bypass the motion sensors and go to 100% intensity.

FYI: I know my colors are off on the code, Hard to see white on virtual screen so it is modified to see it work.

I will send schematic view shortly.

Thanks again for all the help !!!

I hacked your old version.

I've only glanced at your newer code - it will most likely have the same problems that exist in my current version, and maybe new problems.

I tried to fix it without changing the intent or structure of your original - for example, the strip show() remain called once per loop - unless you are looking for animated effects, you should not call show() in the for loops that set pixel colors.

The main thing "wrong" as I see it is that once a stimulus is removed, the LEDs immediately revert to "normal", which would mean if you lift your finger off the override button or estop.

Are those switches or pushbuttons? Would it be nice(r) to have any motion trigger the change in the LEDs and make that last long enough to be seen by humans?

What about priority? Should front work even if front and back detect motion? You don't have any logic (or color, haha) for "front AND back" motion.

Which rules: stop or override? Any questions like that you don't explicitly ask and answer with code will result in some behaviour, maybe what you want, maybe not...

And so forth. See it here, play with it.

a7

I know the syntax you promote. But I use the method you seem to think would be a problem.

The OP's calls were fine. As they were. Total distraction.

If that code compiles, it is obvsly getting one of the several variants of setPixelColor().

From the Adafruit_NeoPixel.h file:

  void setPixelColor(uint16_t n, uint8_t r, uint8_t g, uint8_t b);
  void setPixelColor(uint16_t n, uint8_t r, uint8_t g, uint8_t b, uint8_t w);
  void setPixelColor(uint16_t n, uint32_t c);

And if your cleverness extends to noticing and then worrying about passing 16 bit integers to a function expecting unsigned chars, don't:

If char is unsigned, the original int value is reduced to the unsigned char range modulo UCHAR_MAX+1 .

a7

Not quite right. The 330Ω resistors go between the Din of each strip and that strips output pin (D2 & D5).

The SESTOP switch input is still floating when the switch is open.

The 1000uF cap should be as close to the LED strip power input as possible.

Alto 777

Thank you so much!

For your main concern, the override is a latched switch it should override the motion sensors and got to 100 % intensity when switched back to normal it should be instant.

As for the E-Stop it is a connector sensing from the automation system it will receive 5V DC for trip and nothing to revert back.

I like your emulator and It all seems to work better on yours. Not sure if it is a TinkerCAD emulation issue. Still nothing on one of the motion sensors everything else is working on yours.

What about priority? Should front work even if front and back detect motion? You don't have any logic (or color, haha) for "front AND back" motion.

Priority is: ESTOP, Override switch, Motion Sensing. Copy on answer with code, thanks.

I will have a play, thanks !!

Cheers,

I'm sure I don't know what you mean. If you mean my simulation doesn't work, which motion sensor (button) fails? Both work for me.

If on the other hand you mean the code as I left it doesn't function fully in you tinkercod, please be sure to look closely at the polarity of the button digital reads… I use LOW (pressed) to mean activity (motion) while HIGH means lack thereof. LOW means estop when that button is pressed, LOW means override when that button is pressed.

And my last and only guess rather than waiting for you to say more… is that you could mean the code from my sim, which I still call yours, does not function well on real hardware… come to think of it, I don't recall seeing that you have actually run anything IRL, but if you have, and have had insufficient joy doing, it may point to a wiring or other issue.

If you are using real parts, I hope you have little sketches that can be run to ferret out any issues by simply exercising one component, or component type, at a time… does a neopixel demo work, work on both strips? Can the buttons be read and their state simply reporting on the serial monitor and so forth.

Even a program as small as yours can behave in baffling ways, like how your code went off the rails and the loop just stopped looping until I never did wait for 655360 milliseconds for some of your previously near-infinite for loops to finich. :expressionless:

wokwi dot com is currently the best simulator, at least for how I use it. It has flaws but they tend to get fixed and so far have involved some of the more esoteric microprocessor features that most ppl don't avail themselves of or even, TBH, know or need to know about.

I have not found the wokwi to be different from real life unless I was in one of those dark corners. For straight up stuff like this, it is very faithful, making it a terrific valuable tool, so much easier than the upload/test/edit cycle.

a7

Let it be, it seems to be a war between simulators.

Well, I don't see in the simulation that the Arduino burns or smokes.
Be careful with the circuits that we simulate because the reality can be very different. Simulators presume too many things that can lead to catastrophes in reality.
As for the code used, just say that: Unbeatable.
Greetings to all.