2

I connected a wave generator to the analog pins to read the frequencies of the waves generated. I used different frequencies of sine waves with a minimum of 0V and maximum of 5V.

Whenever the voltage is greater than 2.5V, I made one of the digital pins HIGH, and LOW when less than 2.5V. Now by measuring the square wave from the digital pin, it always has the same frequency as the sine waves until 500Hz.

After 500Hz, the square wave's frequency doesn't agree with the sine wave, which made me think that the problem is in the analogRead(). Is there a way to have higher frequency?

Code:

const int sensorPin1 = A0;
const int sensorPin2 = A1;
const float maximumPower = 2.5;
int calibration = 1;

void setup() {
  Serial.begin(57600);
  pinMode(6, OUTPUT);
  digitalWrite(6, LOW);
}

void loop() {
  int voltage2 = 3;
  int voltage1 = 3;
  int sensorVal = abs(analogRead(sensorPin1) - analogRead(sensorPin2));
  float ratio = abs(analogRead(sensorPin2) / analogRead(sensorPin1));
  float voltageDifference = (sensorVal / 1024.0) * 5.0;
  float power = calibration * voltageDifference;
  if (power >= maximumPower || voltage1 <= 1 || voltage2 <= 1) {
    digitalWrite(6, LOW);
  }
  else {
    digitalWrite(6, HIGH);
  }
}
7
  • Have you googled for this? When using terms like "analogread higher sample frequency" or similar, you can find solutions for this (basically just changing the prescaler of the ADCs clock). Have you read some of these results? – chrisl Feb 6 at 9:52
  • 2
    500 Hz seems a bit low. I would have expected something like 4 kHz. Do you realize that you need at least two samples per cycle? What Arduino are you using? Can you show us your code? Why are you using analogRead() instead of digitalRead()? What sampling rate would you need for your application? What analog resolution? What are you trying to achieve? – Edgar Bonet Feb 6 at 10:26
  • 3
    analogRead() is slow. digitalWrite() is slow. Combine the two together and it's slowly slow. Throw floating point maths into the mix (you mention 2.5V not 512) and it crawls to a snail's pace. Why are you using an Arduino at all for this? The same can be done with a simple comparator (op-amp). – Majenko Feb 6 at 12:18
  • @Majenko: Even using floats and digitalWrite(), I still get more than 7200 iterations per second on an Uno. – Edgar Bonet Feb 6 at 14:24
  • @EdgarBonet Halve that for nyquist-shannon, so 3600. No mention of what he's running on - it could be a breadboard Arduino off the 1MHz internal (div-8) clock. So divide that by 16, and you're down to a mere 225Hz... – Majenko Feb 6 at 14:44
3

You have 4 calls to analogRead() in your loop. At about 112 µs per call, that's already taking 448 µs. Add to that the time taken by the floating point calculations, and you are likely to end up with something in the order of 500 µs per loop iteration. This should give you a sampling rate close to 2 kHz, which should allow you to detect the highs and lows of an input signal up to 1 kHz, provided the duty cycle is close to 50%.

There are a couple of easy optimizations that could be done here. Two of the calls to analogRead() serve no purpose, as the results are never used. And the floating point calculations are also pointless. The whole loop can be simplified to this:

void loop() {
    if (abs(analogRead(A0) - analogRead(A1)) >= 512) {
        digitalWrite(6, LOW);
    } else {
        digitalWrite(6, HIGH);
    }
}

This should take about 224 µs per iteration. If you need to go faster, you will have to increase the working frequency of the ADC. This can cost some accuracy, but if accuracy is not critical to your application, it can be a good trade-off. See Nick Gammon's page on the Arduino ADC for details. If that's not enough, you will have to use external components, e.g. an analog subtractor made from an op-amp, and a couple of comparators.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.