Will do!
Will probably look at that, @paulpaulson ‘s code and tone()’s code.
Nice…..
Interesting way..
Will do!
Will probably look at that, @paulpaulson ‘s code and tone()’s code.
Nice…..
Interesting way..
If I used Direct Port Manipulation it would run faster, correct?
Using DPM you can change up to 8 pins at a time depending on having a port with 8 unused pins. To change two pins you would write one byte with 2 set bits to the PINx register.
That means using your board's Pin Map to know which port both pins are on and which bits to set in that byte. Then a 1 cycle write toggles those pins only. It'd be about 10x faster than doing two Arduino-safetied digitalWrite()'s.
It is an AVR trick but might have been copied. Nick Gammon uses it in his Mono-VGA Uno code to handle video timing.
Makes sense…..
Where can I get tone()’s code?
Know also that there are errors in BWD that won't show for almost 25 days.
Specifically, all time variables need to be unsigned integers and not critical but a good idea is to make them all the same size...
unsigned long (32 bit, what millis() and micros() return.
good for 49.71-some DAY intervals. Millis precision is +/- 1 ms.
or
unsigned int (16 bit)
good for 65.534 second interval with millis() and 65.534 ms with micros(). Micros() precision is to 4 us (microseconds).
or
Arduino byte (unsigned 8 bit) good for 254 ticks of either clock.
unsigned int A = millis(); // gets the low 16 bits only
byte B = millis(); // gets the low 8 bits only
See what blinking ON/OFF at twice the desired frequency does?
Middle C frequency is 256 Hz (cycles/second) so
1000000 / 512 = 1953.125 microseconds... not going to exact on AVR!
Try blinking the piezo/speaker at 1952 micros, the closest 4 to 1953.
Will do!
Will need to figure it out later………
Thanks!
Hi @v205,
I found an old thread here in the forum:
and made a demo work on Wokwi:
https://wokwi.com/projects/382583782521458689
It seems to significantly influence millis(), so it's not really useful for applications other than simple sound generation ... ![]()
Done!
Will probably add the math that you did earlier.....
Now to add other features.
Thanks!
Oh, Thanks!
Seems interesting....
Is it possible to fix that millis thing?
Will my program also affect micros/millis?
I just learned about DPM and it is surprisingly simply......
Use micros, 1000 of those in 1 milli.
Did that....
I think.
So It won't cause the same problem.....
Thank you!
That's why I divided 1 second by twice the frequency (Googled it) for ON-OFF-ON so from each ON to the next is the frequency.
I think an uneven blink with less ON than OFF should be quieter.
Someone else here (xfpd) can likely fill in much more detail.
That would be interesting!
Probably....
So a Frequency pulse and then a pause......
How can I write code for analyzing a variable and rounding it to the nearest 4(Or other, depending on board, /I guess)?
Thank you.
How can I use DPM without overriding other pin's states?
For example,
I used a calculator and showed my work for middle C note.
If you don't care about getting notes and your variable is desired frequency then to get micros, divide 1 million (micros in 1 second) by twice the frequency then divide by 4 (losing any remainder) and multiply that by 4 to get a multiple of 4 since micros() ticks are 4 microseconds long.
Negative numbers?? How do negative frequencies work seems like nonsense to me so maybe the variable value must be turned into a frequency, which it is not. By the way, what is in the variable?
The library mentioned in the linked earlier thread is available now on github:
https://github.com/bhagman/Tone
For two tones on an UNO it should use Timer 2 and 1, not Timer 0 (which is used for micros() and millis() function). From theory it should not influence as long as the interrupts do not stress the controller. I have not checked the sketch in a real environment, only on Wokwi where it seems to slow down the millis() function.
It had to be verified with real hardware ...
If it still shows that behavior I would assume that the ISR of the library keep the controller too busy ...
Just a guess.
ec2021
Which variable?
/*
Two Tone V2 WIP
Turns on and off a light emitting diode (LED) connected to a digital pin,
without using the delay() function. This means that other code can run at the
same time without being interrupted by the LED code.
The circuit:
- Use the onboard LED.
- Note: Most Arduinos have an on-board LED you can control. On the UNO, MEGA
and ZERO it is attached to digital pin 13, on MKR1000 on pin 6. LED_BUILTIN
is set to the correct LED pin independent of which board is used.
If you want to know what pin the on-board LED is connected to on your
Arduino model, check the Technical Specs of your board at:
https://www.arduino.cc/en/Main/Products
created 2005
by David A. Mellis
modified 8 Feb 2010
by Paul Stoffregen
modified 11 Nov 2013
by Scott Fitzgerald
modified 9 Jan 2017
by Arturo Guadalupi
This example code is in the public domain.
https://www.arduino.cc/en/Tutorial/BuiltInExamples/BlinkWithoutDelay
*/
// constants won't change. Used here to set a pin number:
const int ledPin = LED_BUILTIN; // the number of the LED pin
// Variables will change:
int ledState = LOW; // ledState used to set the LED
// Generally, you should use "unsigned long" for variables that hold time
// The value will quickly become too large for an int to store
unsigned long previousMicros = 0; // will store last time LED was updated
// constants won't change:
const long interval = 1952; // interval at which to blink (microseconds)
void setup() {
// set the digital pin as output:
//pinMode(ledPin, OUTPUT);
DDRD = DDRD | B11111100; // this is safer as it sets pins 2 to 7 as outputs
// without changing the value of pins 0 & 1, which are RX & TX
}
void loop() {
// here is where you'd put code that needs to be running all the time.
// check to see if it's time to blink the LED; that is, if the difference
// between the current time and last time you blinked the LED is bigger than
// the interval at which you want to blink the LED.
/*
unsigned long currentMicros = micros();
if (currentMicros- previousMicros >= interval) {
// save the last time you blinked the LED
previousMicros = currentMicros;
// if the LED is off turn it on and vice-versa:
if (ledState == LOW) {
ledState = HIGH;
PORTD = B10101000; // sets digital pins 7,5,3 HIGH
} else {
ledState = LOW;
} PORTD = B00000000; // sets digital pins 7,5,3 LOW
// set the LED with the ledState of the variable:
//digitalWrite(ledPin, ledState);
}
*/
newTone(0, 100);
}
void newTone(int pin, int frequncy){
const int intervalMicros = ((1000000 / (frequncy*2))/4)*4;
unsigned long currentMicros = micros();
if (currentMicros- previousMicros >= intervalMicros) {
// save the last time you blinked the LED
previousMicros = currentMicros;
// if the LED is off turn it on and vice-versa:
if (ledState == LOW) {
ledState = HIGH;
PORTD = B10101000; // sets digital pins 7,5,3 HIGH
} else {
ledState = LOW;
} PORTD = B00000000; // sets digital pins 7,5,3 LOW
// set the LED with the ledState of the variable:
//digitalWrite(ledPin, ledState);
}
}
Pin is not used yet..
The possibly negative value variable that sets the tone of course!
With binary, clear bits 0 and 1 and every value left is a multiple of 4.
Ok.
Currently the code for that is:
const int intervalMicros = ((1000000 / (frequncy*2))/4)*4;
Could probably make find a absolute value to make it always positive.....
Possibly fixed now.
Need to test on real hardware.
const int intervalMicros = abs(((1000000 / (frequncy*2))/4)*4);