Measure RPM using LM2917N and ESP32 - arduino

I want to measure RPM of a metal wheel using an inductive proximity sensor (npn) and a LM2917N which is supose to convert frequency into voltage which I intend to read using an ESP32 since has 12bits ADC.
The wheel has 2 holes which will be "see" by the sensor and a diameter of 50mm. Basically for a complete RPM sensor needs to "see" 2 wholes. Considering the max speed of the wheel which I intend to measure is 5 km/h I made following calculations:
Max rpm of the wheel will be around 530 rpm.
For that rpm sensor will get max 1060 pulses per minute which means about 17.67 Hz
Min rpm which I would like to measure is 100 rpm which means about 3.2 Hz.
Now the concerns:
I see in LM2917N datasheet that the input voltage can be 0 and 28 V, in my setup will be powered at 12V and supply voltage I assume will be same 12V since proximity sensor is powered also on same power supply as LM2917N.
I am not able to do calculations of the C1, C2 and R1 based on my setup and also have to find a way to put the output voltage in range of 0-3.3V (esp32 limits)
Second help is needed to understand how to match the read voltage to frequency (eg - 1V means 10Hz or rpm...)
Any help will be highly appreciated
Thanks in advance!

after reading datasheet : formula is Vo = R1 × C1 × VCC × f
with Vcc=12V, C1=0.1 mF and R1=100K >> V0=0.12V/Hz
for 18Hz, output will be 2.16V
so you can connect directly output to analog input and convert value as
int getRPM() {
float V0 = 3.3 * analogRead(A0)/1024;
float F = V0 / 0.12;
int rpm = F * 60;
return(rpm);
}

Related

Energy Calculation using Arduino

How I can calculate accurate energy if I have Power, Current , Voltage values
This is the code of energy calculation, the result's it's wrong so how I can fix that
I want to measure apparent energy, I don't have a problem in V , I, P values
if(millis() >= energyLastSample + 1)
{
energySampleCount = energySampleCount + 1;
energyLastSample = millis();
}
if(energySampleCount >= 1000)
{
apparent_energy_l1 = apparent_power_l1/3600.0;
finalEnergyValue_l1 = finalEnergyValue_l1 + apparent_energy_l1;
apparent_energy_l2 = apparent_power_l2/3600.0;
finalEnergyValue_l2 = finalEnergyValue_l2 + apparent_energy_l2;
apparent_energy_l3 = apparent_power_l3/3600.0;
finalEnergyValue_l3 = finalEnergyValue_l3 + apparent_energy_l3;
// Serial.print(finalEnergyValue,2);
// Serial.println("test");
energySampleCount = 0 ;
}
energy_total= finalEnergyValue_l1+finalEnergyValue_l2+finalEnergyValue_l3;
}
Some tips about power calculation using Arduino or any microcontroller,
open-source code or project,
guidelines to solve my problem
Note that energy (W x t) is a measurement of power over time, while power is a measurement of work, meaning that you cannot simply divide power by 3600 (which would be the factor to convert from seconds to hours) to get an energy value. Power (W) is a measurement of how much work for example a device is currently doing. If you want to calculate the Energy consumed by a device, you will have to continuously measure the Power, for example in 1s intervals, and add it to a counter. Then you have a value which represents Ws - Watt seconds. You can then calculate the Wh consumed from that value.
Example:
You have a device which consumes 300W of power. You keep that device running for exactly 3 hours. If you measure the power consumption every second as described, you will have measured 3240000 Ws. 3240000 Ws / 3600 = 900Wh / 1000 = 0,9 kWh. You can of course change your measurement interval to fit your needs in regard to accuracy.
Pseudocode:
if ( millis() >= lastmillis + 1000 )
{
lastmillis = millis();
wattseconds = wattseconds + power; #increment energy counter by current power
kilowatthours = wattseconds / 3600000;
print(kilowatthours)
}
You could of course use a one second interrupt with an external RTC to get a more accurate timing.

Question about delayed sampled sinusoid math expression

I have been studying the digital audio processing by using the book <Designing Audio Effect Plugins in C++>.
For analog Sinusoid:
Complex Sinusoid = e^(jωt)
Delayed Sinusoid = e^(jω(t−n)) = e^(jwt) * e^(-jwn), a delay of n seconds
For digital sampled version:
sampled complex sinusoid = e^(jωnT), T is interval for each sample, n is the index of sample
I understand all above, but I got confused about the delayed sampled sinusoid which described as: e^(jω ( nT −M )), M = samples of delay
But I think it should be described as e^(jωT( n − M )), since the T is a constant for a fixed sample rate, n and M has the same unit.
Anyone can explain it for me?
You are right about e^(jωT( n − M )), when M represents delay as sample count
Formula e^(jω ( nT −M )) is valid for M as time

Wave prediction after a FFT with a certain phase and frequency

I am using a sliding window to extract information from my EEG data with a FFT. Now I want to predict the signal from my window into the next one. So I extract the phase from a 0.25 second time window to predict for the next 0.25 second long window.
I am new to signal-processing/prediction, so my knowledge here is a little rusty.
I am not able to generate a sine wave with my extracted phase and frequency. I am just not finding a solution. I might just need a push into the right direction, who knows.
Is there a function in R to help me generate a suitable sine wave?
So I have my maximum Frequency with the phase extracted and need to generate a wave with this information.
here is pseudo-code to synthesize a sin curve of chosen frequency ... currently it assumes an initial seed phase shift of zero so just alter the theta value if you need a different initial phase shift
func pop_audio_buffer(number_of_samples float64, given_freq float64,
samples_per_second float64) ([]float64, error) {
// output sinusoidal curve is assured to both start and stop at the zero cross over threshold,
// independent of supplied input parms which control samples per cycle and buffer size.
// This avoids that "pop" which otherwise happens when rendering audio curves
// which begins at say 0.5 of a possible range -1 to 0 to +1
int_number_of_samples := int(number_of_samples)
if int_number_of_samples == 0 {
panic("ERROR - seeing 0 number_of_samples in pop_audio_buffer ... float number_of_samples " +
FloatToString(number_of_samples) + " is your desired_num_seconds too small ? " +
" or maybe too low value of sample rate")
}
source_buffer := make([]float64, int_number_of_samples)
incr_theta := (2.0 * math.Pi * given_freq) / samples_per_second
theta := 0.0
for curr_sample := 0; curr_sample < int_number_of_samples; curr_sample++ {
source_buffer[curr_sample] = math.Sin(theta)
theta += incr_theta
}
return source_buffer, nil
} // pop_audio_buffer

How should i calculate that in Arduino

If the voltage across a 16 mF capacitor is 7 volts at t=0, find the voltage across the capacitor after 0.2 seconds of discharging through a 120 Ω resistor.
Substitute your values into the capacitor discharge equation:
Vc = Vi * exp(-t/RC)
Vc = voltage across the capacitor at time 't'
Vi = Voltage across capacitor at t = 0

Slightly-off temperatures coming cut of Arduino

I am using an Arduino Due with a TMP36 (for reading temperature). Here is my formula that converts the readings to °F:
tempReading = analogRead(tempPin);
voltage = tempReading * 5.0; // Saves the voltage
voltage /= 1024.0;
tempC = (voltage - 0.5) * 100 ; //Converts to Celsius
tempF = (tempC * 9.0 / 5.0) + 32; //Converts to Fahrenheit
In the serial, my Arduino is printing out temperatures from 90-100 °F, and my house is set to about 70 °F. What the problem here be?
From http://arduino.cc/en/Main/ArduinoBoardDue:
"Unlike other Arduino boards, the Arduino Due board runs at 3.3V. The maximum voltage that the I/O pins can tolerate is 3.3V. Providing higher voltages, like 5V to an I/O pin could damage the board."
So likely you should multiply tempreading not by 5, but by 3.3.

Resources