
xyiii
-
Content Count
15 -
Joined
-
Last visited
Reputation Activity
-
xyiii reacted to enl in ADC MSP430 delay(20)
First, theory: The wikipedia page on aliasing isn't bad. ANY sample rate that is not a sub-multiple of your sine wave frequency (without considering phase) will give you data that looks like a sine wave at some frequency or another. The RMS and offset will be the same as the wave you are sampling, but the frequency will not.
The original wave can be reconstructed from undersampled data in some cases IF there is other information available. This is how many oscilloscopes used to handle very high frequencies, and some still do, using low speed D/A converters. The TIMING of the samples on a 1ns scope is held to less than 1ns jitter, but the samples might be done very precisely at 500ns or more apart, timed at successively larger delays (1ns more per trigger) from the (repeating) trigger event. For a repetitive waveform, the waveform can be reproduced from samples spread over a large number of repetitions, as long as the max frequency is less than the 1ns (and a few other conditions are met.)
Essentially, this is what you are doing, but in a free running way. If you know it is a stable sine wave, then all you need is the upper and lower peak to get RMS and offset. It does not matter which cycle you measure the peaks on. If you are trying to do true-RMS calculation, then you need more data, but, again, if the signal is stable and repetitive, it doesn't matter if all samples come from the same cycle. In fact, for these tasks, clock jitter and frequency aren't critical either.
If you were trying to reproduce the waveform, not analyze the basic properties, these would matter.
-
xyiii reacted to enl in ADC MSP430 delay(20)
As @@bluehash said, to sample he input so as to get sufficient information to reproduce it, the sample rate needs to be greater than twice the maximum frequency in the signal.
First, I messed up units in my post above. I intermingles 50 microseconds and 50 milliseconds. The concept still applies and content is correct otherwise...
Second, we really need to know what you are trying to do for anyone to give a better response. Are you trying to synchronise to the input? Sample it like a digital oscillloscope? other? What development tools are you using (I presume from your post that the toolset you are using implements delay() as a millisecond delay, not microsecond)? What clock rate is your processor running at (if using Energia, this is probably 16MHz+/- a few percent. If CCS, unless you change it, it is the processor default of 1MHz uncalibrated.) What is YOUR background (so we can go to the appropriate level of explanation)
Short form: Nyquist demonstrated that to gain sufficient information about a sampled signal to reproduce it without aliasing (shifting frequency components to the wrong frequency), the sample rate must be GREATER than twice the maximum frequency present in the input. (It is often stated that it must be EQUAL OR GREATER, but equal fails, as the sampled data then becomes phase dependent for the highest frequencies). It is better to sample at a minimum of 4 to 10 times the max frequency, as this reduces the need to interpolate and filter to get information, such as peak, power, frequency spectrum, and phase, and reduces the time required to gather enough samples to get this information (as there will be much less modulation due to interference between the sample frequency and the signal than if the sample rate is barely greater than the max frequency in the signal)
The BEST way to do sampling is a stable clock (crystal controlled) and a sampling system with no jitter. This can be approximated on the MSP430 quite well by using interrupts and the hardware timers to control the process. In brief, you set a timer to interrupt at your sample rate, and the interrupt handler starts the next ADC cycle, giving a fairly well synchronized sample point. Having the ADC interrupt at the end of the conversion allows immediate handling of the result. This is not simple, but it isn't that complicated, either. To tell you more, we need to know more about what you are trying to do.
-
xyiii reacted to enl in ADC MSP430 delay(20)
In addition to undersampling the signal leading to loss of proper representation, the clock on the processor is NOT as accurate or as precise as a crystal oscillator. If the timing in your code was nominally perfect, it would still likely not match the real-world waveform timing, and not read at exactly the same point on the real world waveform each time, even if the real world wave had no error, which is unlikely. Undersampling IS used for a number of practical applications, but great care is needed to do it properly.
Another issue, that again would affect you even with perfect clock, is that the delay(20) puts a 20 microsecond delay BETWEEN the instructions before it and after it. The 20microsec does not account for a) the time required to do the function calls and ADC conversion, the time to save the value to the variable ADCvalue, c) the time to copy the value into the array element, d) the loop overhead. Depending on the processor clock speed, the overhead will be a couple microseconds at 16MHz to maybe 100 microsec or more at 1MHz.
-
xyiii reacted to roadrunner84 in Converting Float to String
You can split your displaying in two integers, in this example I assume current is an electrical current in mA (so displaying is in resolution up to uA, since you have three decimal places right of the dot)
Instead of calculating something to map to mA, map it to uA:
unsigned int rawADC = getADC(); // rawADC is retrieved from some ADC value float current = rawADC * 0.123 + 456.0; // this is some dummy scaling calculation unsigned int rawADC = getADC(); unsigned long current = rawADC * 123 + 456000; You see, the same information is contained, but without using float.
Now for converting it to a string, first using sprintf:
sprintf(final, "%u.%03u", current / 1000, current % 1000); You see, the same information is now contained in final, but without floating points.
A few optimisations can be placed in here; use itoa() instead of sprintf(), use div() instead of / and % :
ldiv_t fraction = ldiv(current, 1000); itoa(fraction.quot, final, 10); fraction.rem += 1000; itoa(fraction.rem, final + 3, 10); final[3] = '.'; final[7] = '\0'; Of course, this looks a bit messy and less comprehensible, so I understand you don't want to go there.
-
xyiii reacted to spirilis in Serial communication (UART) with other Wifi modules MSP430
Yes, because on the MSP430G2 launchpad, the "backchannel UART" that you see over the USB just happens to be the same as the UART on pins (3 & 4, technically).
So from here, you need to analyze what you intend to do with this - and whether that scenario is OK. I saw you post in another thread about connecting two launchpads with I2C or SPI or something. I recommend playing with that for now if you have another G2 launchpad. Getting experience with the "Wire" library (I2C) is good. Don't forget the pullup resistors you'll need on both those lines, and be sure to connect their GND's together. Otherwise I would recommend getting the F5529LP or FR5969LP for more I/O capability.
-
xyiii reacted to spirilis in Serial communication (UART) with other Wifi modules MSP430
I assume you have to have code to talk over a wifi module? And know the other node's IP address, TCP or UDP port it's listening on, etc?