What does a higher clock signal frequency actually mean? - arduino

I've got an Arduino with an ATmega328 processor. It can be operated at 3.3V which nets a clock signal frequency of about 12 MHz respectively 16 Mhz at 5V.
I connected an IMU to the Arduino which runs an AHRS algorithm turning accelerometer, gyroscope and magnetometer data into orientation data.
What does the higher frequency of 16 MHz actually mean in this context?
Will the AHRS be calculated faster so I get a lower latency? Can I poll the sensors more often? I want a deeper understanding of what I'm doing here.

Higher frequency means more clock cycles per second which means more operations are done during the same duration of time. This means AHRS runs faster and you will achieve a lower latency and if you are repeatedly reading values from the IMU, you will be able to poll more often.

Related

How to send fully cycle pulse on lower volts with Arduino?

I am currently using analog pin 3 on my Arduino Uno to send out voltage from 0 to 5V.
I am using that voltage to control the motor and currently I am using the function:
analogWrite(pin, PWM_PULSE);
I am using 255 pwm for 5V and 127 for 2.5V.
The problem is that PWM is sending full cycle at 255pwm(5V), but on 127V the cycle is at 50% which causes my motor to twitch a little bit.
How can I solve this? I am searching for a way to send full PWM cycle even at lower volts. Is it possible?
First I believe you mean D3 not A3, since PWM does not exist on A3.
Assuming you are driving a DC motor, and not something like a servo or stepper
You have two problems.
1st. you may need a smoothing capacitor. Where your formula would be F=L*C Noting that analogWrite uses a F=490Hz. The concept is simple, in short the cap average out the high and lows of the PWM, based on the duty cycle. And the capacitance needed is based on the frequency and impedance. This will provide the analog voltage.
2nd. And bigger problem is the output of the Arduino can not supply sufficient current to drive the motor correctly. It will max out at about 20ma, and the motor likely needs more. So at low speeds the pulses which were week, stall out during their low periods.
You should have your PWM output drive a transistor, which in turn will ON-OFF the motor directly from the power supply. Now your motor may have enough inertia as not to need the cap.
see adafruit-arduino-lesson-13-dc-motors/breadboard-layout
and here for a discussion about the smoothing cap

Arduino adc wrong random values

i am using arduino uno , atmega328.
on analogRead on the analog pin A0 returns 0 when it is grounded, and with HIGH signal from another pin it returns some value around 1000. But when i connect it to a sensor which gives out around 26 mV it returns random values ...
YYY
My code is very basic, uses analogRead and display it in serial monitor.
A signal with fluctuations of 10mV is not random. The flucatuations are called noise. The standard approach is to add a low pass filter in hardware or software. Since you have a controller anyway I would go for software based low pass filtering. A simple and computational cheap but effective low pass filter is an exponential filter, also known as exponential moving average.

Interrupt works too fast on the Arduino

I know this sounds a bit funny :). But I am trying to eliminate possibilities:
On the Arduino Uno I have attached an interrupt triggered on HIGH to a routine which only increments a volatile defined long counter. This counter is displayed on an LCD screen.
If I connect a pulse generator with a frequency of 1 Hz at TTL levels, I would expect the counter to increase with about 1 per second. However this is not the case.
As the frequency is 1 Hz (duty cycle 50%) could it be possible that once the counter is incremented the IRS is exited (and clears the interrupt flag) BUT: the INT0 level is still HIGH so the ISR would be called again? At 1 Hz 50% duty, the HIGH would stay for 500 ms and at 16 mHz...
The processor at the heart of any Arduino has two different kinds of interrupts: “external”, and “pin change”. There are only two external interrupt pins on the ATmega168/328 (ie, in the Arduino Uno/Nano/Duemilanove), INT0 and INT1, and they are mapped to Arduino pins 2 and 3. These interrupts can be set to trigger on RISING or FALLING signal edges, or on low level. The triggers are interpreted by hardware, and the interrupt is very fast. The Arduino Mega has a few more external interrupt pins available.
So as commented: It triggers on an edge!
See more details on the Arduino Playground web page.
Two electrical reasons can explain why interrupt does not function as you need.
1- The pulse generator output and MCU input can have an impedance mismatch, which can cause ringing on the waveform edges. For example, if your function generator has a 50 ohm output capable of generating high frequencies you might see a problem driving a high impedance input like the Arduino at low frequency.
The name "pulse generator" makes me think this is a 50 ohm out device intended to make very short pulses with sharp edges. In such a case, you add a terminating resistor at the destination (load) to match the impedance of the source (pulse generator). For a 50 ohm output, 47 ohm would be close enough. If the output is 100 kohm, then place a matching resistor at the Arduino.
2- Just the opposite, the generator waveform edges may be so slow that the voltage passes through TTL 0 to 1 transition multiple times. If you have noise on your signal input, a slow edge could be causing multiple triggers. For example, if you are picking up some 60 Hz ripple from a power supply and grounding issues, your square wave edges won't be as square as you think.
In such cases hysteresis is a solution. There are many ways to de-glitch (debounce) in code. There is no answer that is right for all problems. A simple example would be that the ISR you require that the input reads high twice in a row for the edge to be accepted.

Multiple analogRead() calls at timed intervals

I'm looking to add the ability to capture wave forms to an ATmega 328 based product and I've been unable to find details on how responsive the ATmega 328 is when doing A/D conversions. The code is being prototyped on an Arduino, but will be migrated to custom board when done.
My plan is to have a total period (typically 16 to 20 milliseconds, based on local AC line frequency) and sample a single pin on the order of 50 to 100 times during that interval. Can the ATmega 328 reliably perform that many conversions successively? The minimum interval per conversion is 16ms / 100 = 160us.
I can add a code example if anyone has to see code, but right now I'm more concerned about the minimum period between multiple successive A/D conversions.
The easiest way would be to write a Arduino script and do some timing benchmarks for yourself.
The other way - doing this by spec - requires some more input for each involved level.
On the lowest level is the ATmega328 chip. The docs on the ADC part says:
By default, the successive approximation circuitry requires an input clock frequency between 50 kHz and 200 kHz to get maximum resolution. If a lower resolution than 10 bits is needed, the input clock frequency to the ADC can be higher than 200 kHz to get a higher sample rate.
Assuming a 16 MHz clock for the ATMega the only available prescaler value for the ADC clock is 128 which is 125kHz for 10 bit resolution. You could use the prescaler value 64 (250kHz) if you can get away with 8 bit resolution.
Next: The doc says:
A normal conversion takes 13 ADC clock cycles. The first conversion after the ADC is switched on (ADEN in ADCSRA is set) takes 25 ADC clock cycles in order to initialize the analog circuitry.
So taking the 125kHz ADC clock this would mean ~9600Hz sample rate in "single conversion" mode. This is 104µs per sample. These are the Arduino defaults.
Compared to your requirement of 160µs this seems good.
BUT: So far only the conversion alone have been considered. You have to transfer the data somewhere. ALSO the Arduino analogRead() function has some overhead as you can see in the file wiring_analog.c in the Arduino dist.
This overhead might be to much - you have to test it for yourself.
On the other hand: Nobody forces you to use the Arduino analogRead function. Some available choices:
you can ditch the overhead of analogRead and/or
you can reconfigure the ADC to your needs (8 bit only, higher ADC clock) and/or
you can use "advanced" modes like continuous sampling ("freerunning mode"9 of the ADC or
you can use even interrupts to trigger the conversions.
Of course all of these choices heavily depend on your knowledge and time budget. :-)

Arduino and External Peripherals

I am a CS guy getting started with Arduino. This is probably a very basic electronics question but from going over the arduino tutorials everything is connected to the arduino with a resistor.
Well since i am following the tutorials i know what type of resistor i should use but what i do not know is why i should use one? and What type of resistor to pick i am to do something which is not covered in a tutorial.
The resistor simply serves to limit the current into or out of a pin in case something goes awry. If your AVR decides to output high on a pin that something else wants low (or vice-versa), large, damaging currents can occur if not limited by some resistance. The current limit for AVRs is about 20 milliamps, and given that the voltages are usually 5V, something larger than 250 ohms "would work".
To give a margin of safety, 1-10k is a great choice; for digital signals it seldom matters unless you're into very high-speed applications (beyond the AVRs capability anyways). For analog inputs, a similar resistor would also be advisable, as the amount of current the ADC takes to sample is negligible when your resistor is in the few kilo-ohm range.
The underlying principle that you want to learn is Ohm's Law, which describes the relationship between voltage, resistance, and current in a circuit.
Resistors are used to
limit current,
devide voltage
protect against over voltage
pull-up, pull down
current to voltage conversion
etc ...
1) limit output current, the absolute max current per IO is 40mA, a typical LED works on ±2V 20mA.
the resistance value can by calculated by (5V - 2V)/(0.02A)=150Ω usually a 220Ω resistor is used, because: it consumes less power, there doesn't flow 20 milliamps, and there is no notable difference in emitted light.
2) if you have a analog voltage that variates between 0 and 10 Volts, you 'll need a voltage divider of 1/2. pick by example z2 10k and calculate z1 by 10k*(Vin,max/5V -1). take a value of resistance higher than the original calculated. and recalculate the new Vout.
3) place a resistor of 10k in series between the analog input of the arduino and the 'to measure voltage'
3) if you have to measure a analog current, you place a resistor to ground and the analog input, calculate the resistor by Z=5V/amps.
4) if you connect a button to the arduino, you 'll need to place a pull up or a pull down resistor. if you 're not using a resistor, the input is floating and can take any value (high or low). or you can enable the internal weak pull up. by pinMode(xx,INPUT); digitalWrite(xx,HIGH);. and disabeling by digitalWrite(xx,LOW); by default the pull-up is disabled.

Resources