From Microchip sample code
PR2 = 2083u; /* Timer2 Period, 19.2 kHz */
How does 2083u correspond to 19.2 kHz, which is
1 / 19.2E03 = 52.083u
They don't correspond at all. Mistake by Microchip?
PR2 = 2083U
makes TIMER2 trigger every 2083 CPU cycles. Calculating
52.083 us / 2083 = 25 ns
1 / 25 ns = 40 MHz
we can conclude that the processor is probably running at FCY = 40 MHz in the example.
The letter u in PR2 = 2038u; does not mean microseconds; it is a C language syntax that makes the integer literal unsigned. See Signedness (Wikipedia).
Setting PR2 to 2083 means that the timer triggers every 2084 (not 2083) clock cycles. When you calculate a timer period, you always have to subtract 1 because the timer value is zero-based.
Related
An online delay loop generator gives me this delay loop of runtime of 0.5s for a chip running at 16MHz.
The questions on my mind are:
Do the branches keep branching if the register becomes negative?
How exactly does one calculate the values that are loaded in the beginning?
ldi r18, 41
ldi r19, 150
ldi r20, 128
L1: dec r20
brne L1
dec r19
brne L1
dec r18
brne L1
To answer your questions exactly:
1: The DEC instruction doesn't know about 'signed' numbers, it just decrements an 8-bit register. The miracle of twos complement arithmetic makes this work at the wraparound (0x00 -> 0xFF, is the same bit pattern as 0 -> -1). The DEC instruction also sets the Z flag in the status register, which BRNE uses to determine if branching should happen.
2: You can see from the AVR manual that DEC is a single cycle instruction. BRNE is also a single cycle when not branching, and 2 cycles when branching. therefore to compute the time of your loop, you need to count the number of times each path will be taken.
Consider a single DEC/BRNE loop:
ldi r8 0
L1: dec r8
brne L1
This loop will execute exactly 256 times, which is 256 cycles of DEC, and 512 cycles of BRNE, for a total of 768 cycles. At 16MHz, that's 48us.
Wrapping that in an outer delay loop:
ldi r7 10
ldi r8 0
L1: dec r8
brne L1
dec r7
brne L1
You can see that the outer loop counter will decrement every time the inner loop counter hits 0. Thus in our example the outer loop DEC/BRNE will happen 10 times(for 768 cycles), and the inner loop will happen 10 x 256 times so the total time for this loop is 10 x 48us + 48us for 528us. Similarly for 3 nested loops.
From here, it's trivial to figure out how many times each loop should execute to achieve the desired delay. It's the largest number of iterations the outer loop can do less than the desired time, then taking that time out, do the same for the next nested loop, and so on until the inner most loop fills up the tiny amount left.
How exactly does one calculate the values that are loaded in the beginning?
Calculate total amount of cycles => 0.5s * 16000000 = 8000000
Know the total cycles of r20 and r19 loops (from zero to zero), AVR registers are 8 bit, so a full loop is 256 times (dec 0 = 255). dec is 1 cycle. brne is 2 cycles when condition (branch) happens, 1 cycle when not.
So the most inner loop:
L1: dec r20
brne L1
Is from zero to zero (r20=0): 255 * (1+2) + 1 * (1+1) = 767 cycles (255 times the branch is taken, 1 time it goes through).
The second wrapping loop working with r19 is then: 255 * (767+1+2) + 1 * (767+1+1) = 197119 cycles
The single r18 loop when branch is taken is then 197119+1+2 = 197122 cycles. (197121 when branch is not taken = final exit of delay loop, I will avoid this -1 by a trick in next step).
Now this is almost enough to calculate initial r18, let's adjust the total cycles first by the O(1) code, that's three times ldi instruction, which takes 1 cycle: total2 = 8000000 - (1+1+1) + 1 = 7999998 ... wait, what is the last +1 there? That's fake additional cycle to delay, to make the final r18 loop pretend it costs same as non-final, i.e. 197122 cycles.
And that's it, the initial r18 must be enough to wait at least 7999998 cycles: r18 = (7999998 + 197122 - 1) div 197122 = 41. The " + 197122 - 1" part will make sure the abundant cycles fits constraint: 0 <= abundant_cycles < 197122 (remainder by 197122 division).
41 * 197122 = 8082002 ... this is too much, but now we can shave the extra cycles down by setting up also r19 and r20 to particular values, to fine-tuned the delay. So how much is to be shaved off? 8082002 - 7999998 = 82004 cycles.
The single r19 loop takes 770 cycles when branching and 769 when exiting, so again let's avoid the 769 by adjusting 82004 to only 82003 to be shaved off. 82003 div 770 = 106: 106 r19 loops can be skipped, r19 = 256 - 106 = 150. Now this will shave 81620 cycles, so 82003 - 81620 = 383 cycles more to be shaved off.
The single r20 loop takes 3 cycles when branching and 2 when exiting. Again I will take into account the exiting loop being only 2 cycles -> 383 => 382 to shave off. And 382 div 3 = 127, remainder 1. r20 = 256 - 127 = 129 and do one less to shave additional 3 cycles (to cover that remainder) = 128. Then 2 cycles (3-1) wait is missing to make it a full 8mil.
So:
ldi r18, 41
ldi r19, 150
ldi r20, 128
L1: dec r20
brne L1
dec r19
brne L1
dec r18
brne L1
According to my calculations should wait exactly 8000000-2 cycles (if not interrupted by something else).
Let's try to verify:
Initial r20: 1273 + 12 = 383 cycles
Initial r19: 1*(383+1+2) + 148*(767+1+2) + 1*(767+1+1) = 115115 cycles
(that's initial r20 incomplete cycle one time, then 149 times full time r20 cycle with the final one being -1 due to exiting brne)
The r18 total: 1*(115115+1+2) + 39*(197119+1+2) + 1*(197119+1+1) = 7999997 cycles.
And the three ldi are +3 cycles = 7999997+3 = 8000000.
And the missing 2 cycles are nowhere to be seen, so I made somewhere a mistake.
As you can see, the math behind is reasonably simple, but very mundane to do by hand, and prone to mistakes...
Ah, I think I know where I did the mistake. When I'm shaving off the abundant cycles, the termination loop is not involved (that's part of the actual delay process), so I shouldn't have adjusted the to_shave_off cycles by -1. Then After r19 = 106 I would have still to shave off 384 cycles, and that's exactly 384/3 = 128 loops to shave off from r20 = 256-128 = 128. No remainder, no missing cycle, perfect 8mil.
If you have trouble to follow this reverse calculation, try it other way, imagine 2 bit registers (0..3 values only), and do on paper similar loop with r18=r19=r20=2, and count the cycles manually to see how it is evolving. .. i.e. 3x ldi = +3, dec r20,brne,dec r20,brne(skip) = +5 cycles, dec r19, brne = +3, ... etc.
Edit: and this was explained before by Jester in his links. And I'm too lazy to clean this up down to some simple formula to create your own online calculator.
I am using MPC 7555 controller. It has a 16 bit sigma delta ADC.
A signal called mic input is fed to this ADC pin. based upon the voltage , a PWM signal of same frequency of ADC signal sampling should be generated.
For e.g.
0.1 V = 2 percent
0.2 V = 4 percent
0.3 V = 6 percent....and so on
So, i thought the following logic -
5V - 0xFFFF in digital
0.1V - 1310
0.2V - 2620 and so on
So, dividing the digital value by 655 will give exact duty cycle value
1310/655 = 2
2620/655 = 4........
But digital pin could also show value of 1309 for 0.1 V which when divided by 655 would yield 1 and not 2.
Anyway i can avoid this or does any have a better solution, please share.
The task is to output PWM at the same rate as the ADC conversion rate.
Suppose the ADC conversion time is T (you can establish this by reading a free-run timer counter). And suppose the ADC conversion value is V. Then the PWM output time H spent "high" must be
H = T * V / 0xFFFF
Every time an ADC conversion is available, you (cancel any pending one-shot timer interrupt and) set the PWM output to 1 and trigger a one-shot timer at time H. When it interrupts, you set the PWM output to 0 (or the other way round if you have inverse logic).
If the input is 0x0000 or 0xFFFF you can employ an alternative strategy - set the output to 0 or 1, but don't deploy the one-shot timer.
To get the best fidelity in teh PWM signal, you would do better to work directly at the resolution of the PWM rather then calculate a percentage only to then convert that to a PWM count. Using integer percentage, you are effectively limiting your resolution to 6.64 bits per sample (i.e. log10(100)/log10(2)).
So let's say your PWM count per cycle is PWM_MAX, and your ADC maximum ADC_MAX, then the PWM high period would be:
pwm_high = adc_val * PWM_MAX / ADC_MAX ;
It is important to perform the multiplication first to avoid loss of information. If PWM_MAX is suficiently high, there is probably no need to worry about integer division rounding toward zero rather then to teh nearest integer, but if that is a concern (for low PWM_MAX ) then:
pwm_high = ((adc_val * PWM_MAX) + (ADC_MAX / 2)) / ADC_MAX ;
For example, soy your PWM_MAX is only 100 (i.e. the resolution truely is in integer percent), then in the first case:
pwm_high = 1310 * 100 / 0xFFFF = 1
and in the second:
pwm_high = ((1310 * 100) + 0x7FFF) / 0xFFFF = 2
However if PWM_MAX is a more suitable 4096 perhaps, then:
pwm_high = 1310 * 4096 / 0xFFFF = 81
or
pwm_high = ((1310 * 4096) + 0x7fff) / 0xFFFF = 82
With PWM_MAX at 4096 you have effectively 12 bits of resolution and will maintain much higher fidelity as well as directly calculating the correct PWM value.
I am trying to count the number of times a button is pressed at input pin C.4 on a picaxe 14M2. I would then like to have a 'mode' that sets b.4 high for 5 seconds then low. This 'mode' needs to repeat the number of times you press the button before hand.
If this makes any sense, how would I do this?
Here is what I have so far...
init:
let b0 = 0
main:
low B.1
low B.2
low B.3
low B.4
low B.5
if pinC.4 = 1
let b0 = b0 +1
goto mode
Endif
goto main
mode:
high B.4
wait 5
low B.4
goto main
If I understand your question you want to first count a number of button presses, then output that number of 5 second pulses. But how will your program decide that you've finished your series of button presses, and want it to carry on and generate the sequence of pulses?
Here's a possible solution, but you'll have to decide if it's suitable and adapt it if not:
b0 = 0 ' initialise counting variable
w1 = 0 ' initialise timing variable (a 2-byte word)
countpresses:
pause 10 ' wait for 10 ms
w1 = w1 + 1 ' increment the timing variable
if pinC.4 = 0 then countpresses ' loop until button pressed
wait_release:
pause 10
w1 = w1 + 1 ' increment the timing variable
if pinC.4 = 1 then wait_release ' loop until button released
b0 = b0 + 1 ' increment the counter
if w1 < 200 then countpresses ' keep counting until 4 seconds have elapsed
if b0 > 0 then
for b1 = 1 to b0
high B.4
pause 5000 ' take B.4 high for 5 seconds
low B.4
pause 1000 ' and low for 1 second between pulses
next b1
endif
This will count how many times you press the button in a 4 second period (200 x 20 ms), then output that number of pulses. The pause statements make sure that you don't count 'bounces' of the switch contacts that might occur in the few milliseconds after the button is pressed or released, and the second loop makes sure that you only count once for each press rather than incrementing as fast as the PICAXE can go for as long as you hold the button down! You didn't say how long B.4 should go low for in between the 5 second high pulses - in the code above I've made that 1 second.
If that's not exactly what you want then it shouldn't be hard to figure out how to modify it, for example to wait for a number of seconds after the last time you release the button.
I've used a word variable for the timing counter so that the maximum time to wait isn't limited to 255 counts - you could change the 200 in the code to any value up to 65535 if you wanted (but you should have a think about what might happen if it got near that value). If you're a PICAXE beginner then do read the section of the manual about how byte and word variables relate to each other, which might not be obvious.
We are getting very poor quality of voice during testing of a new
filtering application of us.
The application receives packets from kernel using netfilter_queue
library. Then insert the packets into a new user managed queue and
does some transformations on it, like concatenation of udp payload.
The network is healthy. Its inside our lab. And it does not drop
packets or anything .
In our app we do not forward packet immediately. After enough packet
received to increase rtp packetization time (ptime) the we forward the
message over raw socket and set dscp to be 10 so that this time
packets can escape iptable rules.
From client side the RTP stream analysis shows nearly every stream as
problematic. summery for some streams are given below :
Stream 1:
Max delta = 1758.72 ms at packet no. 40506
Max jitter = 231.07 ms. Mean jitter = 9.27 ms.
Max skew = -2066.18 ms.
Total RTP packets = 468 (expected 468) Lost RTP packets = 0
(0.00%) Sequence errors = 0
Duration 23.45 s (-22628 ms clock drift, corresponding to 281 Hz (-96.49%)
Stream 2:
Max delta = 1750.96 ms at packet no. 45453
Max jitter = 230.90 ms. Mean jitter = 7.50 ms.
Max skew = -2076.96 ms.
Total RTP packets = 468 (expected 468) Lost RTP packets = 0
(0.00%) Sequence errors = 0
Duration 23.46 s (-22715 ms clock drift, corresponding to 253 Hz (-96.84%)
Stream 3:
Max delta = 71.47 ms at packet no. 25009
Max jitter = 6.05 ms. Mean jitter = 2.33 ms.
Max skew = -29.09 ms.
Total RTP packets = 258 (expected 258) Lost RTP packets = 0
(0.00%) Sequence errors = 0
Duration 10.28 s (-10181 ms clock drift, corresponding to 76 Hz (-99.05%)
Any idea where should we look for the problem?
As we go up the musical scale the note frequency increases;
#define A4 440 // These are the frequencies of the notes in herts
#define AS4 466
#define B4 494
#define C5 523
#define CS5 554
#define D5 587
I am generating the tones mechanically, I tell a step motor to step, delay, step, delay etc etc very quickly.
The longer the delay between steps, the lower the note. Is there some smart maths I could use to inverse the frequencies so as I climb up the scale the numbers come out lower and lower?
This way I could use the frequencies to help calculate the correct delay to generate a note.
So what you're saying is you want the numbers to represent the time between steps rather than a frequency?
440 Hz means 440 cycles/second. What you want is the number of seconds/cycle (i.e. time between steps). That's just 1 / <frequency>. That means all you have to do is define your values as 1/440, 1/466, etc. (or, if you want the values to be milliseconds, 1000/440, 1000/466 etc.)
If that is too fast (or doesn't match the actual notes), you can multiply each value by a scale factor and the relationships between the audible tones should remain the same.
For example, lets say that you empirically discover that for your machine to make an "A4" tone, the delay between steps is 10 milliseconds. To figure out the scale factor, solve for x:
x / 440 = 10
x = 4400
So define scale = 4400, and define each of your notes as scale / 440, scale / 466 etc.
Yes, that sounds possible! Let's have a look... (some of this you will know but I'll post it anyway)
In what's called an equal tempered scale, you can calculate Hertz values by multiplying by the twelfth root of two for every semitone you go up. There are 12 semitones in a whole octave, and multiplying by this value twelve times doubles the frequency, which raises the tone by an octave.
So, if you wanted to calculate descending semitone frequencies from e.g. A 440, you can calculate double x = pow(2.0, 1.0/12.0) (assuming C), and then repeatedly divide by that value (remember to do the divisions as doubles not ints :) ) and then you'll get your descending scale.
Aside: If you want to do a major scale rather than a chromatic (semitone) scale, this is the pattern of tones and semitones to use: (e.g. in C Major - using T for Tone, S for semitone)
C [T] D [T] E [S] F [T] G [T] A [T] B [S] C