Feed on
Posts
Comments

A downside of the AT Mini Matrix Ctrl is that if you have your animation only playing a few times an hour that you are very likely to miss it. You could have it running every minute for a specific time but it’s not that great if no one is there to see it.

IMG_2975

The solution to this is to use a PIR module (H8157 on Ebay) to detect if someone is around. The problem is that the PIR module is quite large compared to the led matrix so it would look out of place.

I started looking at IR transmitters/receivers and using them to reflect off a surface which would detect if someone was there however to have decent accuracy you really needed to use quite a bit of current which isn’t what I wanted. So back to square one, what can we do with the PIR module?

atmmc5-3

After researching the PIR sensors themselves, some datasheets (above is a random datasheet I found) said that they already had some noise reduction and some had application examples. The PIR sensors themselves can cost $2 or more even on Ebay which was odd as the PIR module was about $2 itself.

atmmc5-1

Here’s how the PIR sensor looks side, it contains a FET which you feed in 3 to 12 volts and you monitor the source voltage, seems simple enough.

atmmc5-2

I wired it up and initially I was getting about 1 volt and the reading was fluctuating a bit too much. I added in a 100K resistor between the source and ground like the schematic had and found that the voltage hovered around 0.7v – 1v depending upon where I positioned it and it takes a few seconds to stabilise.

When I moved my hand near the front of it, I noticed some voltage fluctuation by about 10mV. I measured the current consumption and it was 7uA. This means that potentially we could use the MCU’s ADC at 1.1V reference to read for the 10mV fluctuation.

IMG_2980

void setup() {
  Serial.begin(9600);
  analogReference(INTERNAL); // 1.1V reference
  pinMode(13, OUTPUT);
}

void loop() {
  int average = 0;
  for (int x = 0; x < 20; x++) {
    average += analogRead(A0);
    delay(5);
  }
  Serial.println(average, DEC);
  delay(100);

  int average1 = 0;
  for (int x = 0; x < 20; x++) {
    average1 += analogRead(A0);
    delay(5);
  }
  Serial.println(average1, DEC);

  int change = average - average1;
  if (change < 0) {
    change = change - (change * 2);
  }
  Serial.print("-------");
  Serial.println(change, DEC);

  if (change > 15) {
    digitalWrite(13, HIGH);
    delay(500);
    digitalWrite(13, LOW);
  }
  delay(50);
}

At first on the Arduino I was reading each ADC value and comparing it to the last value but that gave incorrect results, so I added some averaging. Averaging of 20 or more with a pause in-between each ADC reading and the two averages seemed to give the best results. Download PIR_Sensor_Detect

// Check we have reached the start time
if (unix_timestamp >= triggers[trigger_location][start_time]) {
  ...

  // Turn on mosfet to power up PIR sensor
  PORTB |= (1<<mosfetPin);

  // When delay time is over, check the PIR if it detects someone and if so light up the LEDs
  if (trigger_delay >= triggers[trigger_location][delay_time]) {

    // Read the PIR sensor
    sbi(ADCSRA, ADEN); // Enable ADC conversions
    int average = 0;
    for (int x = 0; x < 20; x++) {
      average += adcRead(pirADC);
      watchdogSleep(T16MS);
    }
    cbi(ADCSRA, ADEN); // Disable ADC conversions
    watchdogSleep(T128MS); // Wait a little while

    sbi(ADCSRA, ADEN); // Enable ADC conversions
    int average1 = 0;
    for (int x = 0; x < 20; x++) {
      average1 += adcRead(pirADC);
      watchdogSleep(T16MS);
    }
    cbi(ADCSRA, ADEN); // Disable ADC conversions

    // Check if there was much change
    int change = average - average1;
    if (change < 0) { // Convert change to positive if it's negative
      change = change - (change * 2);
    }

    // If there was a lot of change, display the animation or text
    // If you find the PIR is going off by itself or not going off at all, try changing this
    if (change > 15) {

    // Check if we play an animation or text
    ...

For the AT Mini Matrix Ctrl what we  do is when we are in the wake up period of displaying text, instead of displaying the text a few times every hour, we activate the PIR sensor with a mosfet. When we are woken by the timer, we read the PIR voltage, sleep a few milliseconds with the watchdog timer, re-read the PIR voltage and then act based on that. Download AT_Mini_Matrix_Ctrl_v0.5

atmmc5-4

IMG_2983

I was able to stick the PIR on the LED matrix, solder the 100K resistor and capacitor on the PIR and glue down a mosfet with 100K resistor on it too. When it’s powered and the PIR is on it takes up 38uA, I should reduce the 100K resistor to 1M.

https://www.youtube.com/watch?v=12wAKVbTH6w

Working good, it does look a little strange but better than the whole PIR module! The range did go down to about 1 metre and is subject to the power supply you are using, if it’s a coin cell then it’s a bit noisy sometimes so you have to bump up the “change > 15” number.

Part 1
Part 2
Part 3
Part 4
Part 5: Modifying a PIR module

Leave a Reply