Go Down

Topic: PIR not working properly anymore after timed function executes (Read 180 times) previous topic - next topic

stadtpflaenzchen

Jun 15, 2019, 05:32 pm Last Edit: Jun 15, 2019, 06:24 pm by stadtpflaenzchen Reason: Update
Hello,

I want to use an PIR (cheap china PIR) to detect motion and light some LEDs. I am using an Arduino Uno (cheap china as well. We need a lot of them for a festival).
The motion detection itself works fine. When a motion gets detected it changes color (currentDefaultMotionColor), and when there is no motion anymore, it changes back to the color before (currentDefaultColor).
BUT now I want to change the used default colors after a certain period of time to make it more interesting - so I added code for that. And there the problem starts :D
The motion sensor works fine until the program first executes the function changeDefaultColors. After that the motion sensor goes on and off without any reason.
I got noooo clue where the problem is :( maybe someone can help...

Code: [Select]
#include <Adafruit_NeoPixel.h>

#define MATRIX_PIN 7 // Matrix
#define PIR_PIN 6 // Bewegungsmelder
#define NUMPIXELS 64
#define COLOR_CHANGE_FREQUENCE 300 // Sekunden
#define COLOR_QUANTITY 6

Adafruit_NeoPixel pixels(NUMPIXELS, MATRIX_PIN, NEO_GRB + NEO_KHZ800);

const uint32_t RED = pixels.Color(255, 0, 0);
const uint32_t GREEN = pixels.Color(0, 255, 0);
const uint32_t MAGENTA = pixels.Color(255, 0, 255);
const uint32_t YELLOW = pixels.Color(255, 255, 0);
const uint32_t WHITE = pixels.Color(255, 255, 255);
const uint32_t BABYBLUE = pixels.Color(0, 255, 255);

const uint32_t COLORS [COLOR_QUANTITY]  = {RED, GREEN, MAGENTA, YELLOW, WHITE, BABYBLUE};

volatile uint32_t currentDefaultColor = RED;
volatile uint32_t currentDefaultMotionColor = GREEN;


int pirState = LOW;                 // we start, assuming no motion detected
int val = 0;                        // variable for reading the pin status

unsigned long previousMillis = 0;   // last time update
unsigned long currentMillis = 0;
long interval = 30000;               // interval at which to do something (milliseconds)

/*
  SETUP
*/
void setup() {
  randomSeed(analogRead(3));         //use random analog pin noise as seed for random generator

  pixels.begin();                   // INITIALIZE NeoPixel strip object (REQUIRED)
  pinMode(PIR_PIN, INPUT);          // declare sensor as input
  Serial.begin(9600);
}

long getRandomNumber() {
  long randNumber = random(COLOR_QUANTITY);            // 9 is the size of COLORS
  Serial.println(randNumber);
  return randNumber;
}

uint32_t chooseRandomCurrentlyUnusedColor() {
  Serial.println("chooseRandomCurrentlyUnusedColor");
  uint32_t newColor = COLORS[getRandomNumber()];

  while (newColor == currentDefaultColor || newColor == currentDefaultMotionColor) {
    newColor = COLORS[getRandomNumber()];
  }

  return newColor;
}

void udpateColor(uint32_t color) {
  for (int i = 0; i < NUMPIXELS; i++) { // For each pixel...
    pixels.setPixelColor(i, color);
    pixels.show();                  // Send the updated pixel colors to the hardware.
  }
}

void changeDefaultColors() {
  Serial.println("changeDefaultColors");
  uint32_t newCurrentDefaultColor = chooseRandomCurrentlyUnusedColor();
  currentDefaultColor = newCurrentDefaultColor;

  uint32_t newCurrentDefaultMotionColor = chooseRandomCurrentlyUnusedColor();
  currentDefaultMotionColor = newCurrentDefaultMotionColor;
}

/*
  LOOP
*/
void loop() {
currentMillis = millis();
  if (currentMillis - previousMillis > interval) {
    Serial.println("interval is over");
    previousMillis = currentMillis;
    changeDefaultColors();
    delay(50);
  }
  
  val = digitalRead(PIR_PIN);         // read input value
  if (val == HIGH) {                 // check if the PIR input is HIGH
    udpateColor(currentDefaultColor);
    if (pirState == LOW) {            // we have just turned ON
      Serial.println("Motion detected");
      pirState = HIGH;              // We only want to print on the output change, not state
    }
  } else {
    udpateColor(currentDefaultMotionColor);
    if (pirState == HIGH) {          // we have just turned OFF
      Serial.println("Motion ended");
      pirState = LOW;               // We only want to print on the output change, not state
    }
  }
  
}


Code: [Select]
Motion detected
Motion ended
Motion detected
Motion ended
interval is over
changeDefaultColors
chooseRandomCurrentlyUnusedColor
3
chooseRandomCurrentlyUnusedColor
2
Motion detected
Motion ended
Motion detected
Motion ended
Motion detected
Motion ended
Motion detected
Motion ended
Motion detected
Motion ended


UPDATE:
I tried to change the colors pretty lame using a switch statement - and that seems to work. So I guess there is some mistake in my "random color change alrorithms".

larryd

Show us a good schematic of your circuit.
Show us a good image of your wiring. 
Give links to components.
Posting images: 
https://forum.arduino.cc/index.php?topic=519037.0


No technical PMs.
The last thing you did is where you should start looking.

wvmarle

I tried to change the colors pretty lame using a switch statement - and that seems to work. So I guess there is some mistake in my "random color change alrorithms".
Nothing obviously wrong.

It may help to strip down your sketch to just the colour selection part. Have it choose a new set of colours every second or so, and just print the new selection on the Serial monitor. Add some print statements to the while loop, as that's a candidate to get stuck into.
Quality of answers is related to the quality of questions. Good questions will get good answers. Useless answers are a sign of a poor question.

Go Up