Real ADC value BLE113 - bluetooth-lowenergy

I would like to ask you for advice regarding the real value calculation from the ADC. I use call hardware_adc_read(6,1,2) set up. The BLE113 is supplied by 3V.
Voltage = ADC value * 3V / 2048 is close to the real value. However, 2048 number does not make sense for me. I thought, there should be 512/4096 because of the setup of hardware_adc_read(6,1,2) where 1 should be 2^9 = 512 or because of the ADC resolution which should be 2^12 = 4096.
I am a little bit confused. If you can help me with this computation, I would be grateful.
Thank you,
Daniel

Related

Arduino accelerometer MPU-6050

This might sound like a very silly question, so I apologize if this is something very simple but I just cannot get my head around it. I am trying to understand what the data provides in terms of real time information, for example, the MPU-6050:
Gyroscope - is a 16 bit data register with a range from (0 <-> 65535)
There is a selection of ranges (±250, ±500, ±1000, and ±2000°/sec)
If the range is set to ±250°/sec, is the reading 360/65535 = 0.0054 resolution?
What does °/sec mean, if the sensor does not move and reads zero and then turned quickly does it mean it will be reading the angle at the set range? For example, if the range was set to ±2000°/sec and it was moved 200° would the read move from 0 to (2/65535 *200) and keep sending this value once the sensor stopped moving?
Accelerometer - is a 16 bit data register with a range from (0 <-> 65535)
There is a selection of ranges (±2g, ±4g, ±8g and ±16g)
If the sensor is not moving, completely flat the reading will be 0?
If the sensor is shocked at 2g will the max reading be 65535 (if set of 2g, with a resolution of 2/65535)
If the sensor is shocked at 16g will the max reading be 65535 (if set of 16g, with a resolution of 16/65535))
There are two main documents regarding the MPU6050, and those are the datasheet and the register map.
The gyro measurements are stored in the GYRO_XOUT, GYRO_YOUT, GYRO_ZOUT parameters, as you can see in the register map document, page 31. Each parameter is stored as a 2-complement signed 16 bit value split into two 8-bit registers: the GYRO_xOUT_L and _H.
In the same page, you can see the sensitivity for each full-scale range. For example, if your FSR is +/- 250º/sec, and you want to measure 1º/sec, the GYRO_xOUT parameter should read 131 counts.
The accelerometer-related registers can be seen in the same document, page 29. The idea is the same, two 8-bit registers to form a 2-complement signed 16-bit value, and the sensitivity values for each FSR.
Regarding your question in comments, if you rotate the device 125º in a second, at constant rotation speed, you should read 16375 in the rotation registers during the movement. This value comes from 131 counts/(º/sec) * 125º/sec = 16375 counts.

Generate signals with 0.1Hz resolutions using AD9833 via Arduino Uno

I would like to generate a frequency with the resolution of 0.1Hz from the range of 0.0 up til 1000.0 Hz ( Example such as 23.1 Hz, 100.5 Hz and 999.7 Hz) I have found that using AD9833 we can generate the signal as what I was required, but the notes are a bit confusing to me.
The specification can be obtained HERE .
Need your kind assist to if we can make the Arduino code.. lets say, to generate a signal of 123.4 Hz via Serial monitor from Arduino and it displayed as it is in the oscilloscope?
Thank you.
Looking at the notes, it appears that programming this chip will be non-trivial. If you don't require frequencies all the way down to 0 Hz, this job can be done much more easily with a standard Windows sound card. (Sound cards are AC-coupled, so won't go below a few Hz.) For one example, my Daqarta software can generate frequencies (with any waveform you want) at a resolution better than 0.001 Hz. The maximum frequency will be a bit less than half the sound card's sample rate... typically 20 kHz at the default 48000 Hz sample rate.
You don't have to buy Daqarta to get this capability; the Generator function will continue to work after the trial period... free, forever.
UPDATE: You don't mention what sort of waveforms you need, but note that if you can use square waves you may be able to do the whole job with the Arduino alone. The idea is to set up a timer to produce interrupts at some desired sample rate. On each interrupt you add a step value to an accumulator, and send the MSB of the accumulator to an output pin. You control the output frequency by changing the step value. This is essentially a 1-bit version of the phase accumulator approach used by the AD9833 (and by the Daqarta Generator). The frequency resolution is controlled by the sample rate and the size of the accumulator. You can easily get much better than 0.1 Hz resolution.
Best regards,

Modifying hex codes to produce a larger output

I was working on this project : http://elm-chan.org/works/sd8p/report.html
and I failed in every possible way from the start. Now that the .Hex files have been uploaded, and the fuses written, when I plugged the SD card in, nothing happened. Nothing at all. Directly asking for a solution might be impossible here as I have no idea what went wrong. So instead I tested the speaker's positive connection with the arduino serial plotter, and I found some interesting results. The output gave some cool irregular pattern of waves,similar to what I would expect from a sound output. But there was no sound, and I suspect that it was because of the output size being too small.(60/1023 is around 0.06 volts, 200/1023 is around 0.2 volts and the bigger output at 500++ levels out, so it shouldn't produce a sound.)
So now I would like to ask whether I can change the fuses of the .hex file(or the hex file itself, but its big.) to produce a larger output. I have not much understanding in hex files or even AVR devices, so any hep at all would be useful.
Thanks in advance.
the graphs
Please let me know if any other information is needed.
Your voltage output on a GPIO pin is limited to your supply voltage, so no you probably can't fix your problem by changing the software or the fuse bits. Depending on your current supply voltage, you might be able to crank that higher, which would increase your voltage output of the PWM, but the supply voltage can only go so high without damaging the chip.
That being said, you need to disconnect the amp and speaker from the AVR and probe the output pin of the PWM and make sure that it is actually producing a signal on that pin. The plots that you posted with that amplitude look like they are nothing but random electrical noise to me.

Maximum size of 2D array on Arduino Uno

I tried making an array double data[640][14], but the compiler says that the array size is too big. Can anyone tell me what is the maximum size I can use, and how can I work around this problem?
An Arduino Uno has an Atmel 328p MCU. It only has 2048 Bytes of memory. Considering a double takes 8 bytes (64bits) on its own. 640 * 14 * 8 = 71680 bytes.
Does the data you are storing need to be doubles? If you are working with doubles, Arduino is probably very underpowered for what you are trying to do. What is the use case of this array? Even as the smallest data type, it would still be 8960 bytes. If you are storing all Boolean values (1 or 0), then you could store them as individual bits and only take up 1120 bytes.
A little data on what you are trying to do can get you a better answer.

Can an Arduino sample audio in microseconds for 1-4 kHz?

I've just hooked up a electret microphone to an Arduino, and I'd like to sample between the ranges of 1 kHz and 4 kHz.
I understand this is limited to the machine code and the ADC, so I'm trying to keep the sketch simple.
Is it possible to sample between these frequencies with the sketch below?
const int analogPin = 0;
int ledPin = 13;
void setup() {
pinMode(ledPin, OUTPUT);
}
void loop() {
int mn = 1024;
int mx = 0;
for (int i = 0; i < 5; ++i) {
int val = analogRead(analogPin);
mn = min(mn, val);
mx = max(mx, val);
}
if (mx-mn >= 50) {
digitalWrite(ledPin, HIGH);
}
else {
digitalWrite(ledPin, LOW);
}
}
Arduino is a prototyping platform consisting of a number of hardware boards plus a software abstraction layer. For a question like this, it is useful to consider the capabilities of the underlying hardware, as these provide the ultimate limits. I'll assume you are using Arduino Uno/Nano, the story is different for Due.
According to the datasheet, each ADC reading (beyond the first one) takes 13 ADC clock cycles. ADC clock (different from the MCU) clock is derived by dividing the system clock by some factor, at least 2. So at 16Mhz board this amounts to 0.6 million samples per second. So far so good. However, that's not the end of the story, you still need to read the data. If you use interrupts, even if you do something very simple, experience suggests that you will lose about 100 clock to interrupt processing. Now you are down to 126K samples/second. But this is a theoretical maximum.
The datasheet states that for maximum accuracy for the ADC requires 50kHz - 200kHz ADC clock. In the Arduino code (in wiring.c), a division factor of 128 is chosen:
sbi(ADCSRA, ADPS2);
sbi(ADCSRA, ADPS1);
sbi(ADCSRA, ADPS0);
This means that each conversion takes 128*13 = 1764 clocks, which yields a theoretical maximum of 10K samples per second. It is a little bit worse than that given that the readAnalog() function does something beyond just starting the ADC conversion and waiting for it to finish, but it shouldn't be too much worse. This doesn't involve your code of course: any processing you do on the results of readAnalog() will make it more difficult to capture more samples. But yes, to capture at 4Khz you will need to make sure that you code spends less than 1.5k clock cycles/sample, which should be doable. Note that if you are doing five readings like you are doing in the code you posted, the maximum capture rate will be 2kHz if your code does very little.
As far as how to capture the data, you need to make deal with the fact that microphones without amplification will not give you 0-5V readings that you might expect if you are using analogRead(). In fact, microphone output voltages swing from positive to negative, however, the negative voltages will not be picked up by the ADC, and show up as just zeros, unless you give your microphone a voltage offset.
I am not exactly sure what your code that compares minimum amplitude to maximum amplitude is supposed to be doing. Are you wanting to digitize the audio? In this case you need to save all the amplitude readings collected from analogRead(), and then you can run FFTs on them on another computer: Arduino is most likely not going to be fast enough to do frequency analysis on the data.
I have heard, or rather remember reading, that the ADC could handle up to 10k-samples per second, so it should be OK up to 5 kHz. However, I have not tried this nor do I have a link to back it up at the moment.
Just try and see.
Now I know some of the Arduino library functions are slow, notably the DigitalRead/Write that has overhead of hundreds of cycles. Most of this is the sanity checking that allows people to just perform DigitalRead/Write without thinking much about setting everything up.
However, to squeeze out the maximum performance you could look into writing your own AnalogRead that is optimized for your use case.
At least some links on the subject:
Pin I/O performance (JeeLabs)
C++ Template method for faster access (JeeLabs)
I happen to have just tried this using an Arduino Uno and similar code to yours and I've been able to sample an average of 8000 times a second. That is the Nyquist frequency for 4 kHz so you're good but not much margin for error.

Resources