In modern timekeeping, there is a 10 MHz reference frequency (or any power of 10). The digital clock takes 32768 Hz frequency only (or some other power of 2 possible).
The problem is how to convert power of 10 to power of 2 nicely. It is done by a series of 1.25 (every 5 inputs output 4) and 2.5 dividers (every 5 inputs output 2).
I am interested in how this can be done by Arduino. I have a high input frequency, say 1 MHz, therefore i have to use registers directly. Then I have output frequency 1/2 (counter of 2) of the input and 1/4 of the input frequency and I would like to have output 4/5 of the input (divide by 1.25 counter). So, do I need 3 output pins, 1 for counting twos, one for fours, and one for fives? Or can this be done somehow just by 1 input pin and 1 output pin with 4/5 input frequency?
I tried to modify the code but I can not tell how to skip every 5th cycle. Let's say in the chaining of these counters I can get from 1 000 000 Hz frequency: 1000000 Hz - 800000 Hz - 640000 Hz - 512000 Hz - 409600 Hz - 327680 Hz - 2262144 Hz so input = power of ten, then output = power of two My question is how high could be the maximal input frequency to this code? and can you please help me to modify that code?
/*
* From one square wave generate 3 waves 1/2, 1/4 and 4/5 of the original frequency.
*
* Original sketch tried to be modified from here:
*
* https://arduino.stackexchange.com/questions/63202
* _ _ _ _ _ _ _ _ _ _
* input: digital 13 = PB7 / \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ 1 000 000 Hz
* R1F0R1F0R1F0R1F0R1F0R1F0R1F0R1F0R1F0R1F0R
* ___ ___ ___ ___ ___
* output: digital 10 = PB4 / \___/ \___/ \___/ \___/ \___/ 500 000 Hz
* R 1 F 0 R 1 F 0 R 1 F 0 R 1 F 0 R 1 F 0 R
* _______ _______ _______
* output: digital 11 = PB5 / \_______/ \_______/ \ 250 000 Hz
* R 1 F 0 R 1 F 0 R 1 F
* _ _ _ _ _ _ _ _
* output: digital 12 = PB6 / \_/ \_/ \_/ \_____/ \_/ \_/ \_/ \_____/ 800 000 Hz
* R1F0R1F0R1F0R1F00000R1F0R1F0R1F0R1F00000R
*/
int main(void)
{
DDRB = _BV(PB4) | _BV(PB5) | _BV(PB6) | ~_BV(PB7); // PB4 PB5 PB6 as outputs and PB7 as input
for (;;) {
loop_until_bit_is_clear(PINB, PB7); // wait for rising input
loop_until_bit_is_set(PINB, PB7);
PORTB |= _BV(PB4); // rise PB4
loop_until_bit_is_clear(PINB, PB4); // wait for rising input
loop_until_bit_is_set(PINB, PB4);
PORTB |= _BV(PB5); // rise PB5
loop_until_bit_is_clear(PINB, PB5); // wait for rising input
loop_until_bit_is_set(PINB, PB5);
PORTB |= _BV(PB6); // rise PB6
loop_until_bit_is_clear(PINB, PB7); // wait for rising input
loop_until_bit_is_set(PINB, PB7);
PORTB &= ~_BV(PB4); // fall PB4
loop_until_bit_is_clear(PINB, PB7); // wait for rising input
loop_until_bit_is_set(PINB, PB7);
PORTB |= _BV(PB4); // rise PB4
loop_until_bit_is_clear(PINB, PB4); // wait for rising input
loop_until_bit_is_set(PINB, PB4);
PORTB |= ~_BV(PB5); // fall PB5
loop_until_bit_is_clear(PINB, PB7); // wait for rising input
loop_until_bit_is_set(PINB, PB7);
PORTB &= ~_BV(PB4); // fall PB4
loop_until_bit_is_clear(PINB, PB7); // wait for rising input
loop_until_bit_is_set(PINB, PB7);
PORTB |= _BV(PB4); // rise PB4
loop_until_bit_is_clear(PINB, PB4); // wait for rising input
loop_until_bit_is_set(PINB, PB4);
PORTB |= _BV(PB5); // rise PB5
loop_until_bit_is_clear(PINB, PB5); // wait for rising input
loop_until_bit_is_set(PINB, PB5);
PORTB |= ~_BV(PB6); // fall PB6
loop_until_bit_is_clear(PINB, PB7); // wait for rising input
loop_until_bit_is_set(PINB, PB7);
PORTB &= ~_BV(PB4); // fall PB4
loop_until_bit_is_clear(PINB, PB7); // wait for rising input
loop_until_bit_is_set(PINB, PB7);
PORTB |= _BV(PB4); // rise PB4
loop_until_bit_is_clear(PINB, PB4); // wait for rising input
loop_until_bit_is_set(PINB, PB4);
PORTB |= ~_BV(PB5); // fall PB5
loop_until_bit_is_clear(PINB, PB7); // wait for rising input
loop_until_bit_is_set(PINB, PB7);
PORTB &= ~_BV(PB4); // fall PB4
}
}
Nick Gamon personally :D I saw you so many times here. what an honour. I do need a source clock for multiplanetary clock, without fractions. The least common multiple for periods of second for: Earth, Mars, Titan.
If I will keep the ratio between planets exactly, then even if the Earth clock using Arduino resonator will drift by a few tens of seconds per day, Mars clock and Titan clock will drift the same amount of time.
This does not matter to me because if I stop the clock and wait then All 3 planets will be aligned again. But if I would not keep the ratio between planets exactly, for Example Earth would drift 30 seconds per day, Mars would drift 31 seconds per day, and Titan would drift 29 seconds per day- it depends on how close approximation I will take. So, by stopping the clock for 30 seconds to set it correctly, Earth would go back to 0 seconds, but Titan would be 1 second behind and Mars would be 1 second before. I would not correct all 3 just by stopping the clock. I would have to stop the clocks 3 times individually (once for each planet, if not, the error for the 2 remaining planets would accumulate over time, even if correcting Earth) And trust me, it's not easy to calculate Mars time (ok it is because NASA application already exists) but Titan Time I have only in my Excel, and that one I have to recalculate when setting the clock.
Periods for Earth: 1 s, Mars 1.027 491 251 7 s, Titan 0.998 068 437 5 s,
Obviously, Arduino math is not exact to the 10 decimal places, maximally 32 bytes which is 0.000 000 000 2 and something ... that is 2 to -32nd power.
The options for least common multiple:
Earth:Mars = 291/299, Earth:Titan = 3624/3617
Earth:Mars:Titan = integer:integer:1 054 584 (that is 291 x 3624)
so 1st option, is to generate 1 054 584 Hz (I call it golden Megahertz) which is slightly more than 15 Arduino clock cycles = to be exact 15 and 16 cycles would have to alternate with some leap cycle rule (analogous to our leap year rule) to get this frequency.
Find another, decimal frequency slightly off.
Option 1:
Earth:Mars = 812993/800000 and Titan could be 1/4 cycle off, so 800 kHz
Option 2:
Earth:Mars:Titan = integer:integer:3200000 so 3.2 MHz (5 clock cycles) and Mars, Titan, Earth are better aligned,
Option 3: 9600000 Hz frequency (5 clock cycles on 48 MHz Arduino Zero exactly, or 10 cycles on overclocked 96 MHz Arduino Due), and perfect planet alignment.
These options need to have 24 bit counter, up to 16777216 not just 16 bytes. If I don't keep the ratio exactly, the clock would drift at different speeds and to correct the clock to stop all 3 clocks at once would not be enough.
Each one would have to be corrected individually (even though Earth would have the biggest error from Arduino resonator, some residual errors from not exact ratios will accumulate over time, and once in a while, additional 2 clocks would have to be stopped and set individually)
Also, i would like to have something like calendar for each planet, what would the fastest and shortest way to configure it? Earth: 365.2425 days, Mars 668.592 days and Titan 673.54388 days. For Earth we have 365 plus every 4th leap but every 100th not leap but every 400th leap. Days in month are 31,28/29,31,30,31,30,31,31,30,31,30,31. For Mars we would have: 56,56,55,56,56,55,56,56,55,56,56,55/56, and every odd and every 10th leap (thats .6) but not every 100 (thats .59 )but every 500 leap (thats .592). Leap month would be 12-th month. For Titan we would have 56,56,56,56,56,57,56,56,56,56,56,56/57, and every odd and every 20th leap (thats .55) but not every 160 th leap (thats .54388). Also, that lenghth mentioned is not 1 Titan day, but 1/16th Titan day, yes Titan day is almost 16 days long. So, i would like to have something like "days in a day" = 8 days week of 24 hours of 60 minutes of 60 seconds of 0.98 above mentioned earth seconds, and AM and PM week. The 8th day would be called "Earthday and would be between Sunday and Monday". For Mars we would have 7 day weeks as on Earth, and in a similar way, Monday 1st, Tuesday 2nd, .... But for Titan we would have 16 times 1st: AM Monday 1st, AM Tuesday 1st, ... AM Sunday 1st, AM Earthday 1st, PM Monday 1st, PM Tuesday 1st, ... PM Sunday 1st, PM Earthday 1st, and then 16 times 2nd, ... again from AM Monday till PM Earthday. So we can divide terribly long 16 day day into weeks and days. do we have some reasonable function like RTC where i in/out put (year, month, day, week, weekday, hour, minute, second) when i in/out put "unix time" for Earth, Mars and Titan based on different length of seconds? We would have Unix Earth, Unix Mars and unix Titan. Obviously for Earth and Mars, the weekday and date would advance simultaneously and we dont need "week" for Earth and Mars (that would be dislabled) and for Titan there are 8 weekdays and then 2 weeks and then 1 titan day (2 weeks long) so yes 16 days day and 673.54 of them thats almost 30 years long year. the formulas among Earth Mars and Titan Unix time have to be ready yet, but how to break that unsigned long unix time for each planet into the components, and one more (week) component for Titan, an titan day is awfully long, do weekday (and week) here is time, not day, but day within a day, and week within a day.
Nick Gamon, i dont want to be disrespectful, this is my very first question after several years of reading these forums.
There is indeed a capability of Arduino Uno r4 generating 1/256 sec interrupt directly, as there is dedicated library for that, using its bult in RTC clock, which are already part of that Arduino.
Unfortunately, the nice round multiple for Earth, Mars, Titan would be 3.2 million Hz. As Arduino 4 is 32 bit processor 48 MHz, it does math up to 32 bits within one or two clock cycles. and 3.2 million Hz would be exactly 15 clock cycles, however that not much cycles for interrupt. But 256 Hz is plenty of time for 48 MHz 32 bit processor right? im not sure how exact are that RTC clock, need to find out as soon as ill get it. That Arduino uno R4 appeared just few days ago in the shop and its totally new and different. (32 bit, 48 MHz)
1/256 th of second is 12500 / 3200000 second. so Thank god 3.2 million is divisible by 256 without any fraction.
I am enclosing the example for Arduino r4 documentation:
https://docs.arduino.cc/tutorials/uno-r4-wifi/rtc#unix
#include "RTC.h"
const int LED_ON_INTERRUPT = 22;
void setup(){
RTC.begin();
if (!RTC.setPeriodicCallback(periodic_cbk, Period::ONCE_EVERY_2_SEC)) {
Serial.println("ERROR: periodic callback not set");
}
}
void loop() {
}
void periodic_cbk() {
static bool clb_st = false;
if(clb_st) {
digitalWrite(LED_ON_INTERRUPT,HIGH);
}
else {
digitalWrite(LED_ON_INTERRUPT,LOW);
}
clb_st = !clb_st;
Serial.println("PERIODIC INTERRUPT");
}
The period can be specified using the following enumerations:
ONCE_EVERY_2_SEC
ONCE_EVERY_1_SEC
N2_TIMES_EVERY_SEC
N4_TIMES_EVERY_SEC
N8_TIMES_EVERY_SEC
N16_TIMES_EVERY_SEC
N32_TIMES_EVERY_SEC
N64_TIMES_EVERY_SEC
N128_TIMES_EVERY_SEC
N256_TIMES_EVERY_SEC
Now, I am also strugglling with how to incorporate that calendar from Unix time, to break it into individual components for Earth, Mars and Titan. Unix time began on 01/01/1970 00:00:00, unix Mars would began on 01/01/192 00:00:00 and Titan Unix would began on 01/01/13 AM Monday 00:00:00, but i would like to have the initial years adjustable because. It will eventually run out of range after 136 earth years, 72 Mars years and some 4.6 Titan years so we could re-use it by shifting initial year, and also, i would like to have it valid at least till 2323, so, only with resolution 4 second, because 300 years has less than 2 to the 32th 4-second intervals. But that calendar is giving me a headache. I saw RTC library but i cant just change numbers to get Mars, and Titan calendar.
The reason i would like to have it, is because in some point in the future, the human colonisation of Mars will begin, and in more distant future, the human colonisation of Titan (Saturns moon) will begin (there is already a nuclear powered helicopter which will operate in Titan high density atmosphere and low gravity and very cold environment, in 2034 (the date is already approved by NASA, it will lift off in 2027, but as u can suppose the flight takes 7 years to cover one billion miles, or 1.6 billion kilometers to Saturn), and plan for nuclear powered submarine which will swim in its liquid methane seas, not sure when, but the concept already exists, its close to liquid nitrogen temperature, liquid methane has temperature of minus 180 degrees Celsius or like minus 300 degrees of Farenheit, so heating by and insulation have to be perfect) and for enery planet we do need different calendar
If i would have to be capable to construct PLL (phase-locked-loop) then i would have to be able to go from 32768 Hz exactly to 3.2 MHz (as exactly as the 32768 Hz crystal is exact), by 5 times multiplying it by 2.5 that is (multiply by 5 and divide by 2). Lol I could not do 5 times multiply by five because i would get 102.4 MHz (and then divide it 5 times by 2) and not even Arduino due is that fast enough to catch that interrupt. But pure TTL logic is capable to to do it (assuming it can multiply by fractions, that is 2.5 to the 5th power)
Hi guys, the lcd keypad shield 1602 A is compatible with which library and which arduino? how the pins have to be set? I just cant make it working