Arduino HC-SR04 water experiment - arduino

I am working on an experiment with the HC-SR04 sound sensor, and i am using it to record the speed of sound. I successfully measured the speed of sound in air, but when measuring it in water, I encountered a small problem. The sound waves emitted by the sensor are both absorbed and reflected off the water. Obviously, the reflected sound waves are the first ones to reach the sensor, and therefore are the ones used for calculating the speed of sound. Is there a way to code the Arduino program in order to ignore the first set of waves and only record the set of waves that were absorbed by the water? I was thinking of increasing the delay time for the pulse, but I'm not sure that would work.

This answer is theorical only. No test has been done yet.
By adding a small delay, such as 1 - 2 milliseconds could work.
You could calculate the distances twice and get the result from the seconds calculations only.
For you info, here is the speed of sound in water : 1,484 m/s.

Related

how to use esp32 ulp interrupt pulse counter and periodic wake up deepsleep mode

I am trying to measure power usage using dds353 kWh meter. This meter has a pulse output. I am interested in using the esp32 since I can periodically send the data over the internet to nodered dashboard.I am also very interested in using the esp32 in low power mode and periodically wake up to send data over mqtt. I have tried out examples from github using espressif idf but I would not mind an arduino equivalent. I would like to do hardware interrupt which when one of the rtc gpio pin goes high a counter is incremented while a seperate timer interrupt run and occasionally wakes up the main xtensia cores which fetches data from the rtc and sends it over. I have looked at the pulse counter examples and with my limited knowledge can not tell if the interrupts are triggered when the ulp is in sleep mode or only when it is on. I would really be glad if someone would show me how to basically use the ulp for counting pulses even when it is sleep mode and periodically wake up the main cores. I am ok with IDF or arduino examples
If you want to count pulses while in deep sleep youuse the ULP. Code on the ULP continues to execute when the board wakes up and goes to normal power mode. So when it is awake, it will still run the counter on the ULP processor unless you stop the ULP periodic wake up timer, ULP will keep waking up and running while the main CPU is active.
As you gave already checked with this example , it should be pretty close to what you need. The only difference seems to be that the example is set to wake up after a given number of pulses, rather than a fixed amount of time. However it should be easy to change that, by enabling deep sleep wake up from timer.For the Arduino you could check Some additional info:
ULP doesn't have GPIO interrupts. So you use deep sleep wake stub (small piece of code which runs immediately after deep sleep, prior to loading application from flash into RAM) you can increment the pulse counter variable, and go to sleep again. This way you can get low power consumption (~5uA) between pulses and moderate power consumption while running the wake stub (around 13mA), for a very short time.
So its up to you to experiment with your specific scenario.
You can use Pulse Counter(PCNT) feature in ESP32 to count the number of pulse in background, Understanding by using same you can able to do some periodic wake-up and read the count.. Its also possible to configure event when number of counts reached certain threshold and had lot of options,
For get information and available Interfaces and API's for Pulse Counter(PCNT) please follow below link, https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/peripherals/pcnt.html
Initially I faced lot of issue to make Pulse Counter(PCNT) work in Adrino IDE for ESP-32, After multiple attempt I make it working, And same sample code is uploaded in GitHub for reference. I have not use all the API's in the official documentation but but used few of them and are working..
I have created sample program for a water flow meter, there also we use to get pulse which needs to count to measure the water flow rate, understanding simile to kWh meter.
GitHub Sample code Path:- https://github.com/Embedded-Linux-Developement/Arduino_Sample_Programs/tree/main/ESP_32/Water_Flow_Pulse_counter_WithOut_Interrupt_Using_PCNT
I have not placing the code here, because its there in GitHub and not directly for the asked question, but simile one and can use it. Its a working code I tested in HW.
Hopes Its helpful,
Regards, Jerry James

ATmega128 microprocessor, issue regarding error when measuring distance in timer ticks?

Ok, so a laser on earth hits a mirror on the moon and bounces back. On the ATmega128 microprocessor, we use TIMER1 to capture the clock ticks when the laser shot out and the clock ticks when it returned, subtract and get a "distance" in clock ticks. (16MHz clock on ATmega128).
So we are supposed to determine how different can this measured distance be from the actual distance and what can cause it. As well as compute max error in each legal prescaler of TIMER1.
Looking at TIMER1's registers and input capture information in the ATmega128 datasheet I cannot find any kind of percentage error with the input capture. Like, this seems like a conceptual question, yet we are supposed to pull values out of the air and calculate something?
My question is if anyone knows anything of ATmega128, what values are being referred to in determining error from reading distance with timer ticks? My only guess is the error occurs when you use higher and higher prescalers because you lose preciseness when prescalers get larger. But again this is a conceptual answer and don't understand how I would calculate anything.
The counters/prescalars can be assumed to be perfect and will not cause any loss of resolution.
Your original clock source will be a predominant source of errors. If you are using an external clock with a crystal, these are usually good to 50 ppm (part per million) or better. If you are using an internal clock, the error is much higher (1% is not unreasonable for some microcontrollers).
The whole thing gets tricky if you remember your general relativity (you do have a PhD in Physics right?). The earth's rotation and gravity come into play wrt the speed of light and distance...

Arduino + multiple ultrasonic sensors + interference

I have two buggies moving around a track, both of which use ultrasonic measurement modules to detect obstacles in their paths and are controlled by Arduino microcontrollers. The two ultrasonic sensors operate at the same frequency and this frequency cannot be changed. The two ultrasonic sensors are interfering with each other. How can I reduce this interference, or prevent it, by adding something to the Arduino code. The hardware cannot be changed. Thanks for your help
There are in general six ways to reduce interference between two channels (see for example http://en.wikipedia.org/wiki/Multiplexing) - two of which don't apply to sound. That leaves you with four:
space - don't operate in the same space (e.g. cell towers): not applicable for you
frequency - (e.g. channels) you said you can't change that
time - don't operate at the same time
code - send out different amplitude patterns
In a sense, "code" is a bit like "time", but more complicated. With "time", you try to time it so the two transducers don't transmit at the same time. With "code", they send complex pulse sequences and use these to eliminate the interference.
I think your best bet (simple, but effective) is "time". This is going to depend a little bit on the frequency of update that you need, but you could make one buggy the "master", sending a short chirp every 100 ms (say); then have the second buggy wait until it hears the master chirp, and send its own pulse 50 ms later (when it knows the other buggy will be quiet). In this way each will have 10 updates per second, but they will not interfere.
To be more robust, the "slave" buggy could decide (after not hearing a pulse from the "master") to send its own pulse after 100 ms - this way it can operate when there is only one buggy present. And they could in fact each use this algorithm - then there is no "master" and "slave" and they have the same code (usually a good idea). As a final tweak, if you make this "wait for n ms" interval random, you will have implemented a version of "carrier sense multiple access with collision detection" - see http://en.wikipedia.org/wiki/Carrier_sense_multiple_access_with_collision_detection
Good luck.

What is the theory behind active noise cancellation?

In a previous question, I had asked Why can't I simply negate the source time domain amplitude values to produce a destructive noise signal?
One of the posters said that while simply producing a inverses polarity (negated) signal will work in theory, in practice it is not possible
So I am asking, what is the fundamental approach (in a sort of semi technical way) to active noise cancellation?
Secondly, why are most literature on this topic in frequency domain?
It's rather simple.
By the time you send your inverted signal, the noise has already been heard.
You need to look at what frequencies are being generated, and then produce the appropriate inverted signals of those to cancel them out.
Noise cancellation is prediction. Your algorithm has to predict what the sound of the noise will be at some time in the future (that time given by the system and audio time latencies), and then predict what signal will produce the opposite sound at that same point in the future (which your system will distort and delay, so you have to figure in the opposite distortion and delay).
You might be able to use several successive FFTs to determine which frequencies in the noise are not changing, and assume or calculate some probability that they will continue for a short time into the future.
If you know the frequency response curve of the speaker, you might be able to figure out the frequency amplitudes of a signal needed to match some predicted noise spectrum. The phase angle of a sinusoid will change with time. If you know the time delay of your output signal, you might be able to calculate the phase of a sinusoid at some point in the future. If you have a predicted phase of a particular frequency of noise at some time and location, you can add π to that phase angle to estimate the noice-cancelling signal.
If you don't know the frequency response and delay of your system, then you won't know what frequencies, amplitudes or phases of signal to create for cancellation. You might well end up amplifying the noise instead of cancelling it.
It seems that what’s missing is the propagation delay required to intercept and negate a signal. The KISS rule will eventually prove this true. The FFT is a complex calculation and each N iteration will introduce resulting error due to the time required to process the signal. To cancel a sound wave it will need to be intercepted in advance, processed and inverted. Then the time constant of the transducer must. E considered. My experience is that a microphone near the source of “noise” connected by wire and amplification device and transducer near the location where It is to be cancelled.
edit: typo
The basic idea of ANC is to find repetitive sound and play the opposite of it. If the repetitive sound continue to play we'll be able to cancel it. That goes in direct contradiction to to the other answers, but I'll clarify.
Playing the opposite sound means playing it again with a precise power and delay, possibly inverting the waveform. The delay itself varies for each frequency. For example, for a 20Hz sound we have to replay the inverted sound on a precise multiple of 1/20 = 0.05s. For 23Hz, for example, the delay has to be a multiple of 1/23 ~= 0.04347s.
Since any waveform can be produced by sum of sinusoidal, one way of doing it would be to only worry about the N biggest sinusoids, measured in power (square of the amplitudes). For finding the sinusoidal's frequencies and power we use the Fourier Transform, typically with the FFT algorithm.
If we take, for example N=8, it means we are trying to eliminate the 8 most powerfull wave components. For each of them we store:
wave's amplitude
wave's offset, taking the computer's clock as a base.
than we constantly play 8 sinusoids, each on the correct power and with the correct delay. The hard part is what happens next. We need to keep listening to adapt, but now we are listening to the environment sound + our own sound. This algorithm is harder to implement, but conceptually is easier, and one could easily figure out how to do it by himself.
So, contrary to what the other answers say, managing the time delay is critical. Is not possible to create an ANC system without doing it. If you only care about the frequency domain, the only thing you could possibly do is filter those frequencies. On an ANC system this makes not sense.

Arduino encoder interrupts corrupting serial data

I have an Arduino Mega connected to a 6 axis robotic arm. All 6 interrupts are attached to encoders (one encoder pin on an interrupt, the other on a vanilla digital input). The interrupts are handled with this code:
void readEncoder1(){
//encoders is a 2d array, where the first d is the axis, and the two pin numbers
//first pin is on an interrupt (CHANGE), and second is a standard digital in
if (digitalRead(encoders[0][0]) == digitalRead(encoders[0][1])) {
positions[0]++;
} else {
positions[0]--;
}
if(servoEnable){
updatePositions(); //// compares positions[] to targets[] and adjusts motor speed accordingly
}
}
This is designed to keep the arm locked at a certain position- if the arduino detects that the position of the motor is off by a certain threshold, it updates the power going to the motor to keep the arm in position.
The problem is this, then -- if two or three (or more) axis are under load (requiring constant updating to stay in position) or they are moving, the Arduino will stop receiving intact commands on Serial input, several characters will be dropped. The interrupts are obviously running quite quickly, and for some reason this is causing commands to become corrupted. Is there any way around this? Architecturally, am I doing this right? My main instinct is to call updatePositions() in the main run loop at, say, 100 ms intervals, will this significantly reduce interrupt overhead? I guess what my question boils down to is how do I get reliable serial commands into the Arduino even if all 6 encoders are pulsing away?
Quadrature encoders were designed to be read by hardware counters. Pulse rates are generally high with the motor running at full speed. One megahertz is not unusual. The higher the number of pulses, the better the servo loop works and the more accurate you can position the motor.
Doing this is in software with a low-power cpu is, well, challenging. It will fall apart when the ISR takes longer than the interval between pulses. You'll lose pulses and thus position. Especially bad because there is no way you can detect this error condition. And that this loss happens when the robot is moving fast, the worst case condition to lose control.
You absolutely cannot afford to update the servo loop in the interrupt handler so get rid of that first. Keep the ISR to the bare minimum, only count the position and nothing else. The servo loop should be separate, driven by a timer interrupt or tick. You cannot properly control a robot with a 100 msec servo update unless it is big an sluggish, this needs to be a handful of milliseconds at most to get smooth acceleration and stable feedback.
There's a limited amount of wisdom in spending forty bucks to control thousands of dollars worth of robot hardware. Not being able to keep up in the servo loop is something you can detect, shut it down when the position error builds up too much. There's nothing you can do about losing pulses, that's a wreck. Get the hardware counters.
First rule of embedded systems:
Do as little as possible in interrupts.
In your case, just update the positions in the interrupt and run your position/speed control loop in the background or at a lower priority.
Aside: I assume you are aware that you are "losing" encoder pulses as you don't have an interrupt on one of the channels?
Also, interrupt-driven encoder-analysis is very noise-prone. If you get a noise pulse, you'll likely only see an interrupt for one of the edges as they'll be too close together to process both.
A more robust way is to use a state machine which watches all 4 transitions, but that requires either interrupts on both edges of both channels, or polling fast enough to not miss anything up the to rate you are expecting to see.

Resources