# Switch on the piezo emitter for a short time

I need a short beep for every minute of change. I wrote a separate function. The signal duration should be 50 ms, the rest of the time the emitter connected to the A1 contact should be silent.

A really working sketch is shown below:

``````uint32_t mysound; // Variable for storing time (duration of the sound signal)
uint32_t myTimer1;
uint32_t t; //Time that always increases
byte seconds; // Seconds
byte minutes; // Minutes
int k = 1;
void setup()
{
DDRC = B00000010; // Set pin A1 as output
//      76543210
Serial.begin(9600);
myTimer1 = millis();
}

void loop()
{
t = (millis() - myTimer1) / 1000; // Time in seconds
seconds = t % 60; // when 60 seconds are reached, it is reset to zero
minutes = t / 60 % 60; // Counts the minutes and drops to zero when 60 minutes are reached
Serial.println(seconds);
if (seconds == 0 && k)
{
sound();
}
if (seconds > 0) k = 1;
}

void sound()
{
mysound = millis();
while (millis() - mysound < 50)
{
PORTC = B00000010; // We set high voltage on pin A1 for a time of 50 ms
}
k = 0;
PORTC = B00000000;
}
``````
• `doesn't work` is a meaningless description of what you observed ... please describe what happens ... also, describe what tests you performed to make sure that the piezo emitter works Feb 5, 2021 at 4:35
• does the piezo make sound with pin HIGH?
– Juraj
Feb 5, 2021 at 5:55
• Yes, if you just raise the pin to a high level, then the piezo emitter beeps Feb 5, 2021 at 7:02
• All my attempts end with him either constantly beeping or constantly silent. I was unable to achieve a short-term peak Feb 5, 2021 at 7:03
• I assume, you are using atmega328 or atmega2560 when using register PORTC instead of digitalWrite() for generic arduino board. Are you trying to avoid using TIM1 or TIM2? And so maybe there is a reason to avoid using delay() as well. So try this one single line code >>>> if ((millis() % 60000) < 50) PORTC |= 0x02; else PORTC &= ~0x02; Feb 5, 2021 at 13:09

Your `myTimer1` in `t = (millis() - myTimer1) / 1000;` is not set

In addition to Qareke's answer, you also have a problem with the `mysound` variable. You only set this timestamp to `millis()` inside your `millis()` if statement. `mysound` is global and thus will be implicitly initialized with zero. So, by the time, that the code reaches the if statement, the difference between `millis()` and `mysound` is most likely already too big, thus the timestamp gets never set.

Solution: You need to move 2 lines around in your code:

• Move the `mysound = millis();` statement up into the `if (seconds == 0)` statement.
• Move the `sound();` statement outside of the if statement directly into the `void loop()` function (for example directly after the `if (seconds == 0)` statement).

Now the `sound()` function will always be executed, but it will only do a sound, if the timestamp was set to `millis()` previously, and then only for 50ms. Now we only need to make sure, that the timestamp variable `mysound` will only be set once, when the seconds get zero. You could either introduce a new flag variable for that, or you could just use the timestamp itself and check, if more than 1s passed since the last time the timestamp was set. So you need to change

``````if (seconds == 0)
``````

to

``````if (seconds == 0 && millis() - mysound > 1100)
``````

I used `1100` (1.1s) here, to make sure, that there is no bad edge case happening. Since `seconds` will only get zero every minute, that shouldn't be a problem.

• Sorry, but I did not understand how you can move a function call out of a condition. Then what remains within the condition? I fixed the program from above, in this form the squeak starts but never stops Feb 5, 2021 at 9:26
• If you read my answer closely, you see, that I instructed you to move the `mysound = millis();` statement inside that if statement. But you have put still inside the `sound()` function. Also you have chosen to use a flag variable (instead of the proposed `millis()` solution). So you haven't used my solution to the problem. Nonetheless, your current code works perfectly for me. I don't have a piezo at hand, but my logic analyser shows a 50ms long positive pulse every minute. If that doesn't work for you, probably there is something wrong with your wiring Feb 5, 2021 at 10:40