My target is to code a GUI in Java where with which the user can output a PWM signal over one of the Hardware-PWM Pins of the Raspberry 3. Doing so, the user should be able to select the length of a whole pulse (in ms), the length of the duty cycle (in ms) and how often the pulse is repeated.
To code this, I used the Pi4J library (http://pi4j.com) which is based on WiringPi. When trying to actually create a PWM signal, I noticed that there are three main functions:
pwmSetRange(int x)
pwmSetClock(int x)
Setpwm(int x)
As far as I understood these functions correctly, setRange basically sets the possible single steps for the duty cycle while setclock sets the divisor for the frequency and setpwm sets the duty cycle.
But how can I configure these methods correctly depending on the user input?
And also what I noticed: Referencing to an article I read, the PWM frequency gets calculated using following formula: frequency = 19.2e6 Hz / pwmClock / pwmRange while for clock values up to 4095 and for range up to 4096 are accepted.
Did I understand it correctly that with the Pi's hardware PWM only frequencies from around 1.2Hz up to 1920Hz are possible?
Related
I am writing code for a robotic slide lift. I can accurately get the position of of the lift but I would like to be able to keep the position of lift with little to no oscillation (small high frequency oscillations should be fine). I am using a PID control loop and I have spent a lot of time trying to tune it. However, since gravity is helping the thing down but slowing it when its trying to go up, it is impossible to tune the PIDs very well. Right now when it is trying to hold its position it slowly goes up to the target position then once it reaches it and just barely overshoots the next update it falls back down then repeats the process again.
I was thinking of getting the raw power value that the PID calculates and simply add some constant to it to compensate for gravity but I don't have access to the PID calculations so I would have to write the PID code myself.
Would this modified PID loop work or is there another control loop that will help to compensate for this asymmetric situation?
For reference, I control the lift using a joystick. I apply to move the lift up then whenever I stop giving power (the joystick is at the 0 position), the PID kicks in to try to keep the position at that time.
This is a classic example of where you may want to use a feed-forward term in your control loop.
In the model above, the Feedback compensator is your PID loop, which converts your error signal into an actuator command. The Feedforward compensator is a calculation that converts your desired angle, r in this example, to an actuator command.
Because you know the force of gravity acting on your system, you can estimate the amount of torque needed from your actuator to cancel this force. This is called gravity compensation.
The gravity compensating torque needed from your actuator will be
Torque = Force * Distance. (Make sure your units are correct for this calculation!).
Force is the weight of your element, or mass*gravity.
Be careful with your distance calculation though! Because the force is a vector pointing in the direction of gravity, the distance needed is only the horizontal distance from your actuator center. This distance will be dependent on the current angle of your slide. This calculation will be something like Distance = cos(theta) * x.
Assuming that the output to your actuator is in terms of torque (or possibly current), this calculation will now be Output = Perror + I(integrated error) + D*(velocity error) + Feed-Forward.
You want your PID feedback to merely cancel out the errors. This way when your slide is at the set position, the feed-forward term will hold it in place and the PID loop will correct any errors. If your feed-forward model is exactly correct, your PID gains could all be set to zero and it would work (but the model won't be correct, and that's why feedback is necessary).
By the way, this question is better suited for the robotics stack exchange. You may find more answers to your question over there.
If you set a too high Integrative term, you will get more overshoot... To dampen the oscillations you should carefully set the Derivative term without putting too much of it. (Daunting, isn't it?)
Try starting from P = 0, I = 0, D = 0. Raise P until you have your system oscillating. Then put some D term to dampen those oscillations. Then put some I term to get a 0 steady state error.
To get the best out of tuning with your gravity issue, I would suggest using a Gain Scheduling approach, thus tuning and using one PID just to go up, and another PID just to go down.
If not satisfied, you could try with some adaptive control technique such as Model-Reference Adaptive Control.
I have problem with determinate when new stroke is done at Sport Academic Rowing.
I need simple algorithm which to detect moment, which characteristic are one global valley, then big rising which end with peak( look at picture 1 - catch phase, immediately after vertical dotted line
The algorithm needs to be “adaptive”, because when you are rowing hard, the highest point is much higher than when you are paddling and reverse.
Input: float acceleration
Data is from accelerometer, so because of that data come continuously.
I can find timestamp too.
Target: That is cyclic graph, so i want to find how much cycles(strokes) are made per minute, for that i need to detect each one. (period between each two vertical dotted lines - - -)
Rowing boat acceleration vs time graph:
Thank you
Looking at the data, a simple algorithm could be to divide acceleration into three distinct regions:
less than -9 m/s^2
between -9 m/s^2 and 0 m/s^2
greater than 0 m/s^2
Then you construct a state machine with two states to detect each stroke. The first state is triggered when the acceleration is less than -9 m/s^2, and the second state is triggered when the acceleration is greater than 0 m/s^2. When the acceleration is in between, it doesn't change the state.
With your data, at 89.5s, it enters state 1, then enters state 2 at 89.8s, then state 1 again at 91.1s, etc.
you need to use real time,
you can use realTime Databse from frirebase API
Am a Flink beginner.
Tutorials whatever I see focus on very simple logic with on the fly data. Like when temperature is > 100 within x seconds, etc.
How do I bring in a a logic like this
1. When the temperature is 90 deg for 10 consecutive records
2. When the temperature for the last 10 minutes is < 90
A stypid question , Does apache flink support this kind of pattern
I could see within x seconds but there is nothing like for x minutes / for x records
You can certainly address such use cases with Flink.
I'll sketch some solutions using Flink's window operators below. Note that there are also other ways to do this using custom functions / operators which can provide lower latency and less state to handle but which require more user-defined code.
When the temperature is 90 deg for 10 consecutive records:
This can be done using a sliding window that collects ten records and slides by one record. You should implement the window function as a ReduceFunction which immediately combines the records of the window into a boolean value that encodes whether all temperatures are > 90 degs or if one is not. This will reduce the space requirements to one record per window, i.e., 10 records at a time (because 10 windows are simultaneously computed). Note that count windows can be problematic because ordering is somewhat hard to reason about in a distributed stream processor.
When the temperature is more than 90 degs for the last 10 minutes:
This can be done using a sliding time window, e.g., a window over 10 minutes which slides by one minute. This will give you a 1 minute resolution, i.e., it will check every minute for the temperature of the last 10 minutes. Again, you'll have one record for each window (10 at a time for a 10min/1min window, 20 at a time for a 10min/30sec window, ...). The other logic is the same as with the count approach above. If you use event-time logic, you can control records with out-of-order timestamps.
Depending on you use case the window approach might be sufficient. If you need better latency or have you can implement your use case also in a stateful FlatMapFunction (last 10 records) or stateful ProcessFunction which gives you access to timestamps and watermarks for better time control.
More complex patterns can be detected by Flink's CEP library.
If you were to write a program that takes microphone input, reverses it (sets it out of phase by making 1's 0's and 0's 1's), and plays it back out of the speakers, could that cancel out sound? Wave physics says if crests align with troughs, destructive interference occurs, so can that be utilized here to achieve a lessened noise if not canceled out "completely." I can imagine that this wouldn't work due to either complication in reversing the audio, or even because it takes too long to reverse and play back, so that the sound wave has passed. If i had to associate a language to do this in it would have to be either c++ or java (I'm at least competent in both).
Yes it will cancel out sound. That's more or less how Surround Sound works: by subtracting the left/right channels, playing that in the 3rd speaker, and inverting the samples, playing those out of the 4th you get interesting spatial effects.
Also you wouldn't simply want to toggle all bits, you'd get noise; instead you want to negate.
With a small sample buffer you'd be fast enough to cancel out waves of certain frequencies. When these attack and decay, you'll be lagging, but as long as the wave sustains you can effectively cancel it out.
With bigger sample buffers, obviously the delay increases, since it takes longer to fill the buffer with samples. The size of the buffer determines how often a device interrupt occurs where the program would copy the input samples to an output buffer while applying an operation to them.
Typically recordings are made at 44.1kHz, meaning that many samples per second. If you set the buffer to say 256 samples, you would get notified 44100/256 times a second that there are 256 samples to be processed.
At 256 samples you'd lag behind 256/44100 = 0.0058 seconds or 5.8 milliseconds. Sound travels at around 340 m/s, so the sound wave would have moved 1.97 meters (340 * 5.8ms). This wavelength corresponds with the frequency 172 Hz (44100/256). That means that you can only effectively cancel out frequencies that have a lower frequency than that, because those of a higher frequency 'move' more than once during 5.8ms and are thus above the maximum 'sample rate', if you will.
For 64 samples, the frequency would be 44100/64 = 689 Hz. And, this is the maximum frequency! That means you could cancel out bass and the base frequency of the human voice, but not the harmonics.
A typical OS has it's clock frequency set to either 500, 1000, or 2000 Hz, meaning at best you could use a sample buffer of around two to three samples, giving you a maximum frequency of 500, 1000, or 2000 Hz. Telephones usually have a maximum frequency of about 3500 Hz.
You could get the system clock up to around 32kHz, and poll an ADC directly to reach such frequencies. However, you'd probably need to solder one to your LPT and run a custom OS, which means Java is out of the question, or use a pre-fab real-time embedded system that runs Java (see the comment by #zapl for links).
One thing I forgot to mention, is that you will need to take into account the position of the sound source, the microphone, and the speaker. Ideally all 3 are in the same place, so there is no delay. But this is almost never the case, which means you'd get an interference pattern: there will be spots in the room where the sound is cancelled, inbetween spots where it is not.
You cannot do this in software, with c++, or even assembly - the latency of just mirroring the the output on the speakers would be more than 6 ms on most computers. Even if you had a latency of only 0.1 ms, the resulting sound (assuming it is perfectly mixed) would at best sound like it was sampled at 10kHz (not very good).
I need some help confirming some basic DSP steps. I'm in the process of implementing some smartphone accelerometer sensor signal processing software, but I've not worked in DSP before.
My program collects accelerometer data in real time at 32 Hz. The output should be the principal frequencies of the signal.
My specific questions are:
From the real-time stream, I am collecting a 256-sample window with 50% overlap, as I've read in the literature. That is, I add in 128 samples at a time to fill up a 256-sample window. Is this a correct approach?
The first figure below shows one such 256-sample window. The second figure shows the sample window after I applied a Hann/Hamming window function. I've read that applying a window function is a typical approach, so I went ahead and did it. Should I be doing so?
The third window shows the power spectrum (?) from the output of an FFT library. I am really cobbling together bits and pieces I've read. Am I correct in understanding that the spectrum goes up to 1/2 the sampling rate (in this case 16 Hz, since my sampling rate is 32 Hz), and the value of each spectrum point is spectrum[i] = sqrt(real[i]^2 + imaginary[i]^2)? Is this right?
Assuming what I did in question 3 is correct, is my understanding right that the third figure shows principal frequencies of about 3.25 Hz and 8.25 Hz? I know from collecting the data that I was running at about 3 Hz, so the spike at 3.25 Hz seems right. So there must be some noise other other factors causing the (erroneous) spike at 8.25 Hz. Are there any filters or other methods I can use to smooth away this and other spikes? If not, is there a way to determine "real" spikes from erroneous spikes?
Making a decision on sample size and overlap is always a compromise between frequency accuracy and timeliness: the bigger the sample, the more FFT bins and hence absolute accuracy, but it takes longer. I'm guessing you want regular updates on the frequency you're detecting, and absolute accuracy is not too important: so a 256 sample FFT seems a pretty good choice. Having an overlap will give a higher resolution on the same data, but at the expense of processing: again, 50% seems fine.
Applying a window will stop frequency artifacts appearing due to the abrupt start and finish of the sample (you are effectively applying a square window if you do nothing). A Hamming window is fairly standard as it gives a good compromise between having sharp signals and low side-lobes: some windows will reject the side-lobes better (multiples of the detected frequency) but the detected signal will be spread over more bins, and others the opposite. On a small sample size with the amount of noise you have on your signal, I don't think it really matters much: you might as well stick with a Hamming window.
Exactly right: the power spectrum is the square-root of the sum of the squares of the complex values. Your assumption about the Nyquist frequency is true: your scale will go up to 16Hz. I assume you are using a real FFT algorithm, which is returning 128 complex values (an FFT will give 256 values back, but because you are giving it a real signal, half will be an exact mirror image of the other), so each bin is 16/128 Hz wide. It is also common to show the power spectrum on a log scale, but that's irrelevant if you're just peak detecting.
The 8Hz spike really is there: my guess is that a phone in a pocket of a moving person is more than a 1st order system, so you are going to have other frequency components, but should be able to detect the primary. You could filter it out, but that's pointless if you are taking an FFT: just ignore those bins if you are sure they are erroneous.
You seem to be getting on fine. The only suggestion I would make is to develop some longer time heuristics on the results: look at successive outputs and reject short-term detected signals. Look for a principal component and see if you can track it as it moves around.
To answer a few of your questions:
Yes, you should be applying a window function. The idea here is that when you start and stop sampling a real-world signal, what you're doing anyway is applying a sharp rectangular window. Hann and Hamming windows are much better at reducing frequencies you don't want, so this is a good approach.
Yes, the strongest frequencies are around 3 and 8 Hz. I don't think the 8 Hz spike is erroneous. With such a short data set you almost certainly can't control the exact frequencies your signal will have.
Some insight on question 4 (from staring at accelerometer signals of people running for months of my life):
Are you running this analysis on a single accelerometer axis channel or are you combining them to create the magnitude of acceleration? If you are interested in the overall magnitude of acceleration of signal, then you should combine x y z such as mag_acc = sqrt((x - 0g_offset)^2 + (y - 0g_offset)^2 + (z - 0g_offset)^2). This signal should be at 1g when the device is still. If you are only looking at a single axis, then you will get components from the dominant running motion and also from the orientation of the phone changing contributing to your signal (because the contribution from gravity will be transitioning around). So if the phone orientation is moving around while you are running from how you are holding it, it can contribute a significant amount to the signal, but the magnitude will not show the orientation changes as much. A person running should have a really clean dominant frequency at the persons step rate.