PWM signal generation based on Mic input - c

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.

Related

dependancy between 3 variables in real time embedded c code

hello everyone i performed rgb to grayscale image transformation with fixed point arithmetic on zynq7000 microcontroller and the opperations was faster,now i want to have a threshold of time and perform fixed point arithmetic(reduced precision) or floating point arithmetic(high precision) based on time that i have left.
for example:
if i perform rgb to grayscale with high precision it takes for the cpu 10 seconds.
if i perform rgb to grayscale with low precision it takes for the cpu 5 seconds.
but if the time that i can spend on the task is 7.5 seconds how i will say that i want half of the image to be performed with high precision and the other half with low precition?
i am seeking for a formula that will see my time threshold and will calculate how many values of the image i need to transform to grayscale with high precisionand how many values of the image with low precsion based on that threshold of time!thnx
The formula follows from the equation
h 10 + (1 - h) 5 = 7.5
where h is the fraction at high speed (here 50%).
Being
nH -> number of high precision images
nL -> number of low precision images
uH -> time to process a high precision image
uL -> time to process a low precision image
T -> available time
N -> images to process
To process all the images in less than T:
nH * uH + nL * uL < T
Where high precision plus low precision is equal to all the images to process:
nH + nL = N
Substituting:
nH < (T- (uL * N))/(uH - uL);
nL = N - nH;

How can we convert a Signal-to-noise in decible?

suppose ,
we get a value of Signal-to-noise(SNR) is 255.
what is value of SNR in dB ?
Note:
we know,
if a value is given 30 dB.
the SNR value will be = 10^3 = 1000
SNR Calculation – Simple
If your signal and noise measurements are already in dB form, simply subtract the noise figure from the main signal: S - N. Because when you subtract logarithms, it is the same as dividing normal numbers. The difference of the numbers is the SNR. For example: you measure a radio signal with a strength of -5 dB and a noise signal of -40 dB. -5 - (-40) = 35 dB.
SNR Calculation – Complicated
To calculate SNR, divide the value of the main signal by the value of the noise, and then take the common logarithm of the result: log(S ÷ N). There’s one more step: If your signal strength figures are units of power (watts), multiply by 20; if they are units of voltage, multiply by 10. For power, SNR = 20 log(S ÷ N); for voltage, SNR = 10 log(S ÷ N). The result of this calculation is the SNR in decibels. For example, your measured noise value (N) is 1 microvolt, and your signal (S) is 200 millivolts. The SNR is 10 log(.2 ÷ .000001) or 53 dB.
info from https://sciencing.com/how-to-calculate-signal-to-noise-ratio-13710251.html
This question might be best on https://physics.stackexchange.com/ though

How do I count on picaxe?

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.

Microchip PIC period register PR2

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.

inverse a number

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

Resources