Good afternoon! I create a human movement alarm. I am signaling atmega328. I receive a signal from the sensor and if there is a signal, then using the "tone" I generate a sound. enter image description here I am using a motion sensor. I want that if one movement was noticed for a short time, then turn on a short melody, and if the movement continues longer than a certain time, then play a long melody.

I wrote the code to play a short melody. How can you track that the input from the sensor is at a high logical level for a long time and play a long melody in this case?

unsigned long timing; // Variable to store the starting point
int T = 15; // Signal playback time!
int S0 = PIND0; // With Doppler Probe

int S1 = PIND1; // Food
int S2 = PIND2; // Audio

void setup ()

  // Port control via registers:
  DDRD = B00000110; // Set the output pin (the first and second pins of register D as output pins, the rest (0.3-7) are set as input pins)
  // 76543210
  pinMode (PIND0, INPUT);
  pinMode (PIND1, OUTPUT); // Power for the audio amplifier
  pinMode (PIND2, OUTPUT); // Audio
void loop ()
  if (digitalRead (PIND0))
    sendSignal ();

  if (digitalRead (PIND0) == 0)
    digitalWrite (PIND1, LOW); // Food
    digitalWrite (PIND2, LOW); // Sound

void sendSignal ()
  digitalWrite (PIND1, HIGH); // Food
  for (int n = 0; n <4; n ++)
    for (int i = 4800; i <5800; i ++)
      tone (PIND2, i, 10); // tone (port, frequency in Hz, duration in ms) 600 - 6 sec.

And yes, if my code can be optimized, tell me how!

  • What is the threshold duration between a “short” and a “long” signal? How long are the short and the long melodies? Is the short melody a prefix of the long one? What should the program do if it reads a long signal while playing the short melody? Nov 27, 2020 at 14:18

1 Answer 1


I don't see where you are even attempting to detect the long condition in your code.

First of all you need determine what constitutes a long vs. a short detection. My recommendation is to write your code to do the following:

  1. Initial detection.
  2. Wait for your "short" interval. If the detection is gone, then you know it was a "short" one and you can play your short music.
  3. If the detection is still there, wait for the remainder of the time for your "long" detection.
  4. If the detection is gone you know it was a "short" one since it didn't make it to the "long" state. So play your "short" song.
  5. Play your "long" music since the detection lasted for the duration of the long interval.

I'll leave the actual coding of that to you. I'll also add that doing it this way, that is using the built-in delay() function is probably not the best approach overall. The issue is that delay() blocks your loop() function and prevents you from doing anything else while it's delaying.

A better approach is to implement this as a state-machine coupled with an timer-driven interrupt. That will give you much better control over your detections and also allow you do handle other inputs or set other outputs while you are waiting for detections to occur.

There are many resources online that discuss how to configure and handle AVR timers and their interrupts and there are also many resources discussing state machines and programming them in C.

  • 1. You don't need both a “short” and a “long” interval: only a single “threshold” duration to tell them apart. If the signal stops before the threshold duration, short melody, otherwise long melody. 2. Nothing here is time-critical to the point where you would need a timer-driven interrupt. Timing with millis() is easier and perfectly appropriate in this case. Nov 27, 2020 at 13:39
  • all the same, I do not understand, if the melody is playing and there are delays, then the microcontroller at this time does not look at what comes from the sensor. In fact, after being triggered, the sensor still remains in a high state for another 2 seconds, so I count 2 responses (4 seconds) - to play a short melody. more than two - long. How to implement it? study interrupts? Two functions of short and long melody to write?
    – Антон
    Nov 27, 2020 at 14:29
  • I am trying to make interrupts, but I cannot set pin PD0(PCINT16) for interrupt
    – Антон
    Nov 27, 2020 at 15:51
  • @Антон It doesn't really help to say "I cannot set pin...". It's also not directly related to this question. Please ask another question, post your code, show how you are connecting the pin. Then someone can help you.
    – jwh20
    Nov 27, 2020 at 16:16

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.