Hello AAC forum,
Working on using PIR & switch to operate
an Adafruit Neopixel Ring 24.
To get started it was decided to keep things simple.
- If the switch is closed the Neopixel is solid green.
- If the switch is open the Neopixel is off, unless the
PIR is triggered. If the switch is open
and the PIR is triggered the Neopixel is solid blue
for an interval of time.
A sketch was written and loaded onto the
Arduino Uno and the system works well as designed.
Eos_Neopixel_2_color_240425_KB.ino, attached.
Unable to attach sketch so sketch copied herewith at end of post,
The Arduino setup is shown at
Arduino_setup_240426.jpg, attached
allenpitts.com/PM/Eos_Arduino_setup_240426.jpg
To make the system smaller an ATtiny85 was
substituted for the Uno using the breadboard
as shown in the attached line drawing
EOS__LED3_PIR_SW_NeoPix_240423_Brdbrd.jpg.
allenpitts.com/PM/EOS__LED3_PIR_SW_NeoPix_240423_Brdbrd.jpg
But as shown in Test 240426.1 and
Test 240426.2, copied herewith below,
the sketch works perfectly on the Uno
but does not work on the breadboard.
So either the assumption that a sketch
that works on an Arduino Uno
will also work on an ATtiny is false
or
there is a defect in the breadboard
setup.
or
both.
Please accept a request to review
and help me figure how to get
the sketch that works on the
Arduino Uno rev3 work on the ATTiny85.
Thanks
Allen Pitts
***** Test Results *****
Test 240426.1 ATtiny85, PIR & switch
Preconditions
- Set up EOS__LED3_PIR_SW_NeoPix_240423_Brdbrd.jpg.
- Load Eos_Neopixel_2_color_240425_KB.ino with Internal Clock to 8MHZ
- SW1 closed.
Action 1: +5v Power to board
Expected Result:
- All Neopixel lights green constantly.
- LED3 oscillates at 500 ms intervals.
Actual Result:
- Neopixel does not light
- LED3 lights constantly
Note: With the conjecture that the PIR is failing, a measurement
was done at PIR out/pin 7.
Result: 3.2 volts for eight seconds when PIR triggered.
Then 1.5 volts until PIR retriggered. Retrigger: 3.2 volts for eight seconds.
This is as expected.
Action 2: Move SW1 from closed to open
Result: 2.1. Neopixel, no change
2.2 LED3 off
Action 3: Move SW1 from open to closed
Result: 3.1. Neopixel, no change
2.2 LED3 oscillates at .5 seconds
Action 4: Move SW1 from closed to open
Result: 4.1. Neopixel, no change
4.2 LED3 off
Test 240426.2 Arduino Uno, PIR & switch
Preconditions
- Set up EOS_Arduino_Setup_240426.jpg.
- Load Eos_Neopixel_2_color_240425_KB.ino with Internal Clock to 8MHZ
- SW1 open.
- PIR isolated.
Action 1: +5v Power to board
Expected Result:
- All Neopixel lights blue
- LED3 oscillates at 500 ms intervals.
Actual Result:
- All Neopixel lights blue
- LED3 oscillates at 500 ms intervals.
Action 2: Wait 30 seconds for PIR LOW
Expected Result:
- All Neopixel off
- LED3 oscillates at 500 ms intervals.
Actual Result:
- All Neopixel off
- LED3 oscillates at 500 ms intervals.
Action 3: Retrigger PIR
Expected Result:
- All Neopixel lights blue
- LED3 oscillates at 500 ms intervals.
Actual Result:
- All Neopixel lights blue
- LED3 oscillates at 500 ms intervals.
/* Eos_Neopixel_2_color_240425_KB.ino
This sketch uses two functions, runLED3 and runNeoPixel to operate one LED w runNeoPixel using the PIR and Switch closure as a trigger.
*/
//Library to run the Neopixel
#include <Adafruit_NeoPixel.h>
// Which pin on the Arduino is connected to the NeoPixels?
const int neoPixelPin = 4;
// Number of Neopixel LEDs in the Ring
#define LED_COUNT 24
// Declare our NeoPixel strip object:
Adafruit_NeoPixel strip(LED_COUNT, neoPixelPin, NEO_GRB + NEO_KHZ800);
// see strandTest_240124_colorWipe.ino for argument definitions
// constants won't change. Used here to set a pin number :
const int ledPin3 = 3; // the number of the LED pin
const int PIN_PIR_SENSOR_INPUT = 2; //the number of the PIR PIN **********************
const int switchPin = 0;
// Variables will change :
int ledState3 = LOW;
int neoPixelState = LOW; // A variable to track whether the Neopixel is currently showing color (ON) or not showing color (OFF)
int pirState = LOW; //State of the PIR input to the Attiny
bool pirWasTriggered = false; // A bool variable (True/False) to track whether the PIR went HIGH and the Attiny registered that the PIR went HIGH
bool switchIsClosed = false;
unsigned long previousMillis3 = 0; // will store last time LED was updated
unsigned long previousMillis4 = 0;
const long interval3 = 500;
const long interval4 = 10000; // interval LED4 stays on after a trigger from PIR
void setup() {
// These lines are specifically to support the Adafruit Trinket 5V 16 MHz.
// Any other board, you can remove this part (but no harm leaving it):
//#if defined(__AVR_ATtiny85__) && (F_CPU == 16000000)
// clock_prescale_set(clock_div_1);
//#endif
// END of Trinket-specific code.
// set the digital pin as output:
pinMode(ledPin3, OUTPUT);
pinMode(PIN_PIR_SENSOR_INPUT, INPUT); //Define the pin input from the PIR sensor to the Attiny and INPUT *********************
pinMode(switchPin, INPUT); //240430 pinMode(switchPin, INPUT_PULLUP);
//Neopixel setup commands
strip.begin(); // INITIALIZE NeoPixel strip object (REQUIRED)
strip.show(); // Turn OFF all pixels ASAP
strip.setBrightness(50); // Set BRIGHTNESS to about 1/5 (max = 255)
}
void loop() {
//Every loop this logic will be evaluated
//If the PIR wasn't triggered recently (A HIGH hasn't been read), then check the PIR for HIGH/LOW
if(pirWasTriggered == false){
pirState = digitalRead(PIN_PIR_SENSOR_INPUT); //Read whether the input from the PIR sensor is LOW or HIGH and set that value to pirState ****************
if(pirState == HIGH){ //If the input is HIGH, record that it was triggered
pirWasTriggered = true;
}
}
//runLED3 will perform the toggling ON/OFF of LED3 and the timing
runLED3();
//runNeoPixel will perform the toggling ON/OFF of NEOPIXEL and the timing
runNeoPixel();
}
void runLED3() {
unsigned long currentMillis3 = millis();
if (currentMillis3 - previousMillis3 >= interval3) {
// save the last time you blinked the LED
previousMillis3 = currentMillis3;
// if the LED is off turn it on and vice-versa:
if (ledState3 == LOW) {
ledState3 = HIGH;
} else {
ledState3 = LOW;
}
// set the LED with the ledState of the variable:
digitalWrite(ledPin3, ledState3);
}
}
void runNeoPixel(){
//Read the logic level of the Switch (HIGH/LOW), The Switch will read HIGH when OPEN and LOW when closed
/*
There are 4 Combinations and their meanings:
1.) currentSwitchValue == LOW and switchIsClosed == false -> Switch is now CLOSED after having been OPEN
2.) currentSwitchValue == LOW and switchIsClosed == true -> Switch is still CLOSED after having already been CLOSED
3.) currentSwitchValue == HIGH and switchIsClosed == true -> Switch is now OPEN after having been CLOSED
4.) currentSwitchValue == HIGH and switchIsClosed == false -> Switch is still OPEN after having already been OPEN
*/
bool currentSwitchValue = digitalRead(switchPin); //Read the current value of the Switch Pin (HIGH/LOW)
//This is combination 1 from the above list
if( currentSwitchValue == LOW && switchIsClosed == false){ //If the Switch is CLOSED (LOW) and the switchIsClosed variable was set to False before, set switchIsClosed to True and turn ON LED4
switchIsClosed = true;
colorWipe(strip.Color(0,255,0)); // Set the neopixel to Green
pirWasTriggered = false; //Set this false in case the PIR was triggered and then the Switch is CLOSED. Setting pirWasTriggered to false prevents the light turning back on from the interval4 timer after the Siwtch is OPEN again
return; //exit the runLED4 function for this round of the loop
}
//This is combination 3 from the above list
if( currentSwitchValue == HIGH && switchIsClosed == true){ //If the Switch is now OPEN (HIGH) and the switchIsClosed variable was set to True before, set switchIsClosed to False and turn OFF the neopixel ring
switchIsClosed = false;
//neopixel_off(); //Turn off the neopixel display by showing Black
colorWipe(strip.Color(0,0,0)); // Set the neopixel to Black/Off
pirWasTriggered = false; //Set this false in case the PIR was triggered and then the Switch is CLOSED. Setting pirWasTriggered to false prevents the light turning back on from the interval4 timer after the Siwtch is OPEN again
return; //exit the runLED4 function for this round of the loop
}
//This is combination 2 from the above list
if(switchIsClosed == true){
return; //exit the function because LED4 is already ON and the PIR signal does not need to be read because LED4 is on because the Switch is CLOSED
}
//Combination 4 is the default state of the Switch being OPEN and we will proceed to the PIR logic below for this condition
//If PIR wasn't triggered (didn't go HIGH), exit out of this function altogether with the 'return' command since nothing else needs to be done on LED4
if(pirWasTriggered == false){
return;
}
//If it's here that means PIR was triggered, and we can turn on the LED
if(neoPixelState == LOW){ //Check if the neopixel state is currently LOW, set it HIGH and turn on the LED.
//This prevents taking time and resources to digitalWrite ledPin4 HIGH every loop when it is already HIGh
previousMillis4 = millis(); //set the time of previousMillis4
neoPixelState = HIGH;
colorWipe(strip.Color(0,0,255)); // Set the neopixel to Blue
}
//This timer is now tracking how long until LED4 is turned OFF
unsigned long currentMillis4 = millis();
if (currentMillis4 - previousMillis4 >= interval4) { //Once interval4 amount of time has passed since the LED4 was turned ON, it will enter this IF statement
//set the LED to OFF
neoPixelState = LOW;
//neopixel_off(); //Turn off the neopixel display by showing Black
colorWipe(strip.Color(0,0,0)); // Set the neopixel to Black/Off
pirWasTriggered = false;
}
}
// 1. Fill Strip Pixels One After Another with a Color
//Fill strip pixels one after another with a color. Strip is NOT cleared
// first; anything there will be covered pixel by pixel. Pass in color
// (as a single 'packed' 32-bit value, which you can get by calling
// strip.Color(red, green, blue) as shown in the loop() function above),
// and a delay time (in milliseconds) between pixels.
void colorWipe(uint32_t color) {
for(int i=0; i<strip.numPixels(); i++) { // For each pixel in strip...
strip.setPixelColor(i, color); // Set pixel's color (in RAM)
strip.show(); // Update strip to match
}
}
void neopixel_off(){
strip.clear(); //Set all color values of the Neopixels to Black
strip.show(); //Update and display the Black color (effectively this means the LEDs are OFF)
}