Analog Sensor Reading (SLOW)

Hi All,

I have attached a 24V Sensor to an Arduino Board that has been modified to have capability of 24V. The issue i’m having is I have it reading the sensor through an analog port therefore using the AnalogRead function. I am getting different readings for when the sensor sees something vs not however these readings have a bit of a delay to them. Am I over-looking something?

Thanks,

  • Matt

A4 is the pin of the sensor.

const int NextButton = 26;
const int SaveButton = 30;
const int UpButton = 32;
const int DownButton = 28;
const int ToggleButton = 40;
const int Led1 = 46;
const int Led2 = 44;
const int Led3 = 42;
const int Led4 = 8;
const int Led5 = 7;
const int ErrorLed = 38;
const int TestSwitch = A4;
const int ErrLight = 48;

/*
class TimeKeeper
{
  unsigned long previousTime;
  long TimeVar1;
  long TimeVar2;
  long TimeVar3;
  int a = 1;
  
  public:
  TimeKeeper(long TimeDelay1, long TimeDelay2, long TimeDelay3)
  {
    TimeVar1 = TimeDelay1;
    TimeVar2 = TimeDelay2;
    TimeVar3 = TimeDelay3;
    previousTime = 0;
    a = 1;
  }

  void Update()
  {
    unsigned long currentTime = millis();
    if ((a==1) && (currentTime - previousTime >= TimeVar1)){
      previousTime = currentTime;
      Serial.println("SEQ1.1 Activated");
      a = 2;
    }
    if ((a==2) && (currentTime - previousTime >= TimeVar2)){
      previousTime = currentTime;
      Serial.println("SEQ2.1 Activated");
      a = 3;
    }
    if ((a==3) && (currentTime - previousTime >= TimeVar3)){
      previousTime = currentTime;
      Serial.println("SEQ3.1 Activated");
      a = 1;
    }
  }
};
*/
int BNextLogic = 0;
int BUpLogic = 0;
int BDownLogic = 0;
int ToggleLogic = 0;
int SaveButtonTrigger = 0;
int x = 0;
int a = 1;

unsigned long previousTimer = 0;  //Previous Time for MAIN TIMER
unsigned int y[] = {100, 100, 100, 100, 100};  // Time ARRAY for MAIN TIMER

unsigned long buttonPreviousTime = 0;  //Previous Time for Button Timer
unsigned long previousTimer2 = 0;
int buttonWait = 20;  //Button wait Variable
int TestCheck = 0;


void setup() {
  pinMode(NextButton, INPUT);
  pinMode(SaveButton, INPUT);
  pinMode(UpButton, INPUT);
  pinMode(DownButton, INPUT);
  pinMode(ToggleLogic, INPUT);
  pinMode(Led1, OUTPUT);
  pinMode(Led2, OUTPUT);
  pinMode(Led3, OUTPUT);
  pinMode(Led4, OUTPUT);
  pinMode(Led5, OUTPUT);
  pinMode(ErrLight, OUTPUT);
  pinMode(ErrorLed, OUTPUT);
  pinMode(TestSwitch, INPUT);
  Serial.begin(9600);
  Serial.println("Starting...");
  digitalWrite(ErrLight, HIGH);
  delay(1000);
  digitalWrite(ErrLight, LOW);
  attachInterrupt(digitalPinToInterrupt(38), savetrigger, CHANGE);
}

void loop() {
//  ins.Update();
  TestCheck = analogRead(TestSwitch);
  unsigned long buttonCurrentTime = millis();
  if (TestCheck >= 246){
      //buttonPreviousTime = buttonCurrentTime;
      Serial.print(TestCheck);
      Serial.print(" | ");
      Serial.print(buttonCurrentTime);
      Serial.println(" | HIGH");
      digitalWrite(ErrLight, HIGH);
  }
  if (TestCheck <= 244){
      //buttonPreviousTime = buttonCurrentTime;
      Serial.print(TestCheck);
      Serial.print(" | ");
      Serial.print(buttonCurrentTime);
      Serial.println(" | LOW");
      digitalWrite(ErrLight, LOW);
  }
  BNextLogic = digitalRead(NextButton);
  if ((BNextLogic == HIGH) && (buttonCurrentTime - buttonPreviousTime >= buttonWait)){
    buttonPreviousTime = buttonCurrentTime;
    x++;
    if (x >= 5){
      x = 0;
      Serial.print("Time VAR: ");
      Serial.print(x+1);
      Serial.print(" selected. | ");
      Serial.println(y[x]);
    }
    else {
    Serial.print("Time VAR: ");
    Serial.print(x+1);
    Serial.print(" selected. | ");
    Serial.println(y[x]);
    }
  }
  BUpLogic = digitalRead(UpButton);
  if ((BUpLogic == HIGH) && (buttonCurrentTime - buttonPreviousTime >= buttonWait)){
    y[x] = y[x]+100;
    //buttonPreviousTime = buttonCurrentTime;
    Serial.print("TimeVar ");
    Serial.print(x+1);
    Serial.print(" is now: ");
    Serial.println(y[x]);
  }
  BDownLogic = digitalRead(DownButton);
  if ((BDownLogic == HIGH) && (buttonCurrentTime - buttonPreviousTime >= buttonWait)){
    y[x] = y[x]-100;
    buttonPreviousTime = buttonCurrentTime;
    Serial.print("TimeVar ");
    Serial.print(x+1);
    Serial.print(" is now: ");
    Serial.println(y[x]);
  }
  SaveButtonTrigger = digitalRead(SaveButton);
  if ((SaveButtonTrigger) && (buttonCurrentTime - buttonPreviousTime >= buttonWait)){
    buttonPreviousTime = buttonCurrentTime;
    Serial.print("TimeVar ");
    Serial.print(x+1);
    Serial.println(" saved.");
    savetrigger();
  }
  else {
    ToggleLogic = digitalRead(ToggleButton);
    if (ToggleLogic == HIGH){
      digitalWrite(ErrorLed, LOW);
      unsigned long Timer1 = millis();
      if (a == 1){
      if (Timer1 - previousTimer >= y[0]){
        previousTimer = Timer1;
        Serial.print("SEQ 1 | Running at: ");
        Serial.print(y[0]);
        Serial.print("  |  Time: ");
        Serial.println(Timer1);
        digitalWrite(Led1, HIGH);
        digitalWrite(Led2, LOW);
        digitalWrite(Led3, LOW);
        digitalWrite(Led4, LOW);
        digitalWrite(Led5, LOW);
        a = 2;
      }
      }
      if (a == 2){
      if (Timer1 - previousTimer >= y[1]){
        previousTimer = Timer1;
        Serial.print("SEQ 2 | Running at: ");
        Serial.print(y[1]);
        Serial.print("  |  Time: ");
        Serial.println(Timer1);
        digitalWrite(Led2, HIGH);
        digitalWrite(Led1, LOW);
        digitalWrite(Led3, LOW);
        digitalWrite(Led4, LOW);
        digitalWrite(Led5, LOW);
        a = 3;
      }
      }
      if (a == 3){
      if (Timer1 - previousTimer >= y[2]){
        previousTimer = Timer1;
        Serial.print("SEQ 3 | Running at: ");
        Serial.print(y[2]);
        Serial.print("  |  Time: ");
        Serial.println(Timer1);
        a = 4;
        digitalWrite(Led3, HIGH);
        digitalWrite(Led2, LOW);
        digitalWrite(Led1, LOW);
        digitalWrite(Led4, LOW);
        digitalWrite(Led5, LOW);
      }
      }
      if (a == 4){
      if (Timer1 - previousTimer >= y[3]){
        previousTimer = Timer1;
        Serial.print("SEQ 4 | Running at: ");
        Serial.print(y[3]);
        Serial.print("  |  Time: ");
        Serial.println(Timer1);
        a = 5;
        digitalWrite(Led4, HIGH);
        digitalWrite(Led2, LOW);
        digitalWrite(Led3, LOW);
        digitalWrite(Led1, LOW);
        digitalWrite(Led5, LOW);
      }
      }
      if (a == 5){
      if (Timer1 - previousTimer >= y[4]){
        previousTimer = Timer1;
        Serial.print("SEQ 5 | Running at: ");
        Serial.print(y[4]);
        Serial.print("  |  Time: ");
        Serial.println(Timer1);
        a = 1;
        digitalWrite(Led5, HIGH);
        digitalWrite(Led2, LOW);
        digitalWrite(Led3, LOW);
        digitalWrite(Led4, LOW);
        digitalWrite(Led1, LOW);
        }
        } 
      }
      else {
        digitalWrite(ErrorLed, HIGH);
        switch (x){
          case 0:
            digitalWrite(Led1, HIGH);
            digitalWrite(Led2, LOW);
            digitalWrite(Led3, LOW);
            digitalWrite(Led4, LOW);
            digitalWrite(Led5, LOW);
            break;
          case 1:
            digitalWrite(Led2, HIGH);
            digitalWrite(Led1, LOW);
            digitalWrite(Led3, LOW);
            digitalWrite(Led4, LOW);
            digitalWrite(Led5, LOW);
            break;
          case 2:
            digitalWrite(Led3, HIGH);
            digitalWrite(Led2, LOW);
            digitalWrite(Led1, LOW);
            digitalWrite(Led4, LOW);
            digitalWrite(Led5, LOW);
            break;
          case 3:
            digitalWrite(Led4, HIGH);
            digitalWrite(Led2, LOW);
            digitalWrite(Led3, LOW);
            digitalWrite(Led1, LOW);
            digitalWrite(Led5, LOW);
            break;
          case 4:
            digitalWrite(Led5, HIGH);
            digitalWrite(Led2, LOW);
            digitalWrite(Led3, LOW);
            digitalWrite(Led4, LOW);
            digitalWrite(Led1, LOW);
            break;
        }
      }
   }
}
void savetrigger(){
int state = digitalRead(ErrorLed);
    digitalWrite(ErrorLed, HIGH);
    delay(200);
    digitalWrite(ErrorLed, LOW);
    delay(200);
    digitalWrite(ErrorLed, HIGH);
    delay(200);
    digitalWrite(ErrorLed, LOW);
    delay(200);
    digitalWrite(ErrorLed, state);
}

You have an enormous amount of code there which seems unrelated to your question. One technique which works well is to try to trim the code down to the absolute minimum length which still exhibits the problem.

There's 3 outcomes from this:

  1. You find you trimmed away the problem so now you know which activity is interfering in a way you didn't expect.
  2. You now see the problem yourself.
  3. You get helped a lot faster here because the genius pool here can quickly find your error.

I apologize. I was in a rush so I didn't trim the code, the issue I'm having is in the beginning of the main loop so it's not hard to spot. I will post a trimmed version as soon as I have access to a computer again. (Currently replying using a smart phone).

I do have the sensor parsing through a timer check but it is not resetting the timer. I have it this way on purpose to check more frequently hoping to remove the delay of the sensor to arduino reaction.

MorganS:
You have an enormous amount of code there which seems unrelated to your question. One technique which works well is to try to trim the code down to the absolute minimum length which still exhibits the problem.

There’s 3 outcomes from this:

  1. You find you trimmed away the problem so now you know which activity is interfering in a way you didn’t expect.
  2. You now see the problem yourself.
  3. You get helped a lot faster here because the genius pool here can quickly find your error.
const int TestSwitch = A4;
const int ErrLight = 48;


unsigned long previousTimer = 0;  //Previous Time for MAIN TIMER
unsigned int y[] = {100, 100, 100, 100, 100};  // Time ARRAY for MAIN TIMER

unsigned long buttonPreviousTime = 0;  //Previous Time for Button Timer
unsigned long previousTimer2 = 0;
int buttonWait = 20;  //Button wait Variable
int TestCheck = 0;


void setup() {
  pinMode(TestSwitch, INPUT);
  Serial.begin(9600);
  Serial.println("Starting...");
}

void loop() {
//  ins.Update();
  TestCheck = analogRead(TestSwitch);
  unsigned long buttonCurrentTime = millis();
  if (TestCheck >= 246){
      //buttonPreviousTime = buttonCurrentTime;
      Serial.print(TestCheck);
      Serial.print(" | ");
      Serial.print(buttonCurrentTime);
      Serial.println(" | HIGH");
      digitalWrite(ErrLight, HIGH);
  }
  if (TestCheck <= 244){
      //buttonPreviousTime = buttonCurrentTime;
      Serial.print(TestCheck);
      Serial.print(" | ");
      Serial.print(buttonCurrentTime);
      Serial.println(" | LOW");
      digitalWrite(ErrLight, LOW);
  }
}

You are flooding Serial and this will slow you down.
You generate around 20 bytes per analogRead/loop.
Your Serial.begin(9600) only allows 1000 chars / second.
I would not expect more than one measurement per 20ms.

You could raise the baudrate and/or print only once/twice/.. each second.

Whandall:
You are flooding Serial and this will slow you down.
You generate around 20 bytes per analogRead/loop.
Your Serial.begin(9600) only allows 1000 chars / second.
I would not expect more than one measurement per 20ms.

You could raise the baudrate and/or print only once/twice/.. each second.

I actually thought this may have been the issue. I will try again after I return to work tomorrow but If I remember right I removed the Serial.print lines thinking that may have been the issue. Again, don't quote me on this and I'll try it again tomorrow and double check.

I did throw a millis delay on the function but it lowered the analog reading. Without the Millis delay it was reading 250 for a low and 260 for a HIGH, plus or minus a few of course. Dunno personally why a delay would play any role in the actual amount of the sensor reading.

I suspect that your connection to the sensor is wrong, may lack a ground line. Please show your circuit diagram.

DrDiettrich:
I suspect that your connection to the sensor is wrong, may lack a ground line. Please show your circuit diagram.

Its actually a very simple setup. Diagram will be posted below. I'm not the best at fritzing so i'm gonna explain it here also.

I have a transformer giving 24VAC power to the sensor, the power out (still 24VAC) going back to the circut and one wire going to my Arduino Mega pin A4. This version of the mega has been modified to receive up to 24V power without any issues. The ground from the sensor is not connected. The ground on the mega is not protected so any AC power going to it would probably fry it.

Circut Image:

EDIT:

Whandall:
You are flooding Serial and this will slow you down.
You generate around 20 bytes per analogRead/loop.
Your Serial.begin(9600) only allows 1000 chars / second.
I would not expect more than one measurement per 20ms.

You could raise the baudrate and/or print only once/twice/.. each second.

I have lowered the Serial.print to every 100ms and I have a reading. The sensor is triggering a little faster but the readings are dropping slowly. Is this regular behavior for analogRead?

Edit2:
I have tracked down the my test LED that is being lit when the sensor is activated is staying on the longer the sensor sees something. If it passes by quickly the test LED goes on and off quickly. If something is held for a period of time, the LED is lit for a period of time. How do I remove the delay even if the sensor is triggered for a period of time.

Blade2021:
I have a transformer giving 24VAC power to the sensor, the power out (still 24VAC) going back to the circut and one wire going to my Arduino Mega pin A4. This version of the mega has been modified to receive up to 24V power without any issues. The ground from the sensor is not connected. The ground on the mega is not protected so any AC power going to it would probably fry it.

This just doesn't make any sense.
Voltage is a potential difference. If you don't have two wires connected, you can't possibly measure a difference in potential. The ground connection acts as a reference, so the ADC converter of the Arduino measures the difference between A4 and ground.
Second, what do you mean by "This version of the mega has been modified to receive up to 24V power without any issues"? The voltage regulator on most Arduino's are rated 20V ABSOLUTE MAX. DC that is, 24VAC will damage the board if you don't rectify it. Keep in mind that 24VAC rectified > 24VDC, especially without a heavy load.
The next issue is measuring the 24VAC. The Arduino can measure voltages between 0 and 5V. 24VDC is way too high, so you'll need a voltage divider. You can't measure negative voltages, this will damage the chip, so you can't measure AC either, since it has a positive and a negative cycle. You have to rectify the input before the voltage divider. (Because of the forward voltage drop of diodes, this will change the voltage as well, so you'll have to make up for that in software.)
If you don't connect the ground to the voltage divider, it won't work, so the output will basically be 24V. If the ground of the 24V source is in any way connected to the Arduino, that is. If it's not connected at all, you'll get strange readings, because there is no voltage reference.

Do some research first, before trying to connect anything, or you'll fry the Arduino. Give us more information about this sensor first, and draw a complete schematic, including the power delivery to the Arduino itself.

Also please read the guide on how to post images/attachments.

Pieter

PieterP:
This just doesn't make any sense.
Voltage is a potential difference. If you don't have two wires connected, you can't possibly measure a difference in potential. The ground connection acts as a reference, so the ADC converter of the Arduino measures the difference between A4 and ground.
Second, what do you mean by "This version of the mega has been modified to receive up to 24V power without any issues"? The voltage regulator on most Arduino's are rated 20V ABSOLUTE MAX. DC that is, 24VAC will damage the board if you don't rectify it. Keep in mind that 24VAC rectified > 24VDC, especially without a heavy load.
The next issue is measuring the 24VAC. The Arduino can measure voltages between 0 and 5V. 24VDC is way too high, so you'll need a voltage divider. You can't measure negative voltages, this will damage the chip, so you can't measure AC either, since it has a positive and a negative cycle. You have to rectify the input before the voltage divider. (Because of the forward voltage drop of diodes, this will change the voltage as well, so you'll have to make up for that in software.)
If you don't connect the ground to the voltage divider, it won't work, so the output will basically be 24V. If the ground of the 24V source is in any way connected to the Arduino, that is. If it's not connected at all, you'll get strange readings, because there is no voltage reference.

Do some research first, before trying to connect anything, or you'll fry the Arduino. Give us more information about this sensor first, and draw a complete schematic, including the power delivery to the Arduino itself.

Also please read the guide on how to post images/attachments.

Pieter

I have been doing my research and that is why I specifically selected the board i'm using.
The Mega that i'm using is from Rugged Circuits. A link to it is here: MEGA Tech — Rugged CircuitsRugged Industrial Arduino Microcontrollers

I will look into using a rectifier but as of right now the sensor and board are working properly. I am not by any means an electrician but I will do my best try to understand this.

Ok, Bare with me but... Heres what i'm getting. (I think....)
If I were to do it the right way, I would send the 24V power through a rectifier to transform it to 24V BUT! it will have a slight voltage drop due to the rectifier. Not a problem cause I need to drop the voltage down anyway. So then I send it though a Voltage divider that has the in leg connected to the power from the rectifier and the ground connected to the negative of the rectifier? and the out leg connected to the arduino mega. Am I close? or not even?

While I was processing all of this I did find this rectifier that is both cost saving and fits the specs I would need. Panasonic - DB6J316K0R - DB6J316K0R,SMT Schottky Small Signal Diode,Iso,30V 300mA,0.8ns,6-Pin SMini6 F3 B - Allied Electronics & Automation

As far as the image goes, I do know how to post on forums, I have done it for many years but never had to hassle with dropbox so I will try a different method.

As far as specs go:
The circuit is 24V AC (Yeah I know.. the dreaded AC). All the sensors I have have a max rating of 300mA so should fall within that rectifier that I posted above if I am correct. The arduino I have is rated for 24V and I did contact them before to make sure it could accept AC before hooking it up, but I do want to do it with a lower voltage just to be safe.

Blade2021:
The arduino I have is rated for 24V and I did contact them before to make sure it could accept AC before hooking it up, but I do want to do it with a lower voltage just to be safe.

It is true that 24VAC won't damage the board, it's not ideal. The board has a diode in series with the DC jack, protecting it against AC and reverse voltages, however, this is only half-bridge rectification. Ideally, you'd use a full bridge rectifier, and maybe some power line capacitors to suppress noise and ripple.

24VDC is fine, since it's below the 30V that's specified on the rugged circuits page.

Blade2021:
Ok, Bare with me but... Heres what i'm getting. (I think....)
If I were to do it the right way, I would send the 24V power through a rectifier to transform it to 24V BUT! it will have a slight voltage drop due to the rectifier. Not a problem cause I need to drop the voltage down anyway. So then I send it though a Voltage divider that has the in leg connected to the power from the rectifier and the ground connected to the negative of the rectifier? and the out leg connected to the arduino mega. Am I close? or not even?

First you'll have to show us the sensor you're using. If it outputs voltages between 0 and 5 volts, you're fine, but if it outputs 0-24V, it won't work. It's true that the inputs of this rugged Mega are protected against voltages as high as 24V, but the Arduino still only reads voltages between 0 and 5 volts, anything higher than that will just read as 1023 (0b11 1111 1111, the maximum value). It just uses a TLS diode.
If this is the case, you'll need a voltage divider.
Whatever the output voltage is, as long as it's a low DC voltage, you have to connect the ground to the Arduino's ground, otherwise, you can't measure voltages.

Why are the sensors AC? Do they have a rectifier built-in? Please give us a part number or a link to the datasheet.

Pieter

PieterP:
It is true that 24VAC won't damage the board, it's not ideal. The board has a diode in series with the DC jack, protecting it against AC and reverse voltages, however, this is only half-bridge rectification. Ideally, you'd use a full bridge rectifier, and maybe some power line capacitors to suppress noise and ripple.

24VDC is fine, since it's below the 30V that's specified on the rugged circuits page.
First you'll have to show us the sensor you're using. If it outputs voltages between 0 and 5 volts, you're fine, but if it outputs 0-24V, it won't work. It's true that the inputs of this rugged Mega are protected against voltages as high as 24V, but the Arduino still only reads voltages between 0 and 5 volts, anything higher than that will just read as 1023 (0b11 1111 1111, the maximum value). It just uses a TLS diode.
If this is the case, you'll need a voltage divider.
Whatever the output voltage is, as long as it's a low DC voltage, you have to connect the ground to the Arduino's ground, otherwise, you can't measure voltages.

Why are the sensors AC? Do they have a rectifier built-in? Please give us a part number or a link to the datasheet.

Pieter

To my knowledge the sensor just acts as a switch and transfers the load. The datasheet can be found here http://info.bannerengineering.com/cs/groups/public/documents/literature/69942.pdf or the part number is SM2A312CV2

Technically speaking would a voltage divider lowering the voltage down to a maximum of 5 volts work since if its not reading it would give a reading of 0 and when the switch is activated it would give 5 volts.

We are using AC cause the machine their on has been AC for many many years, all of our solenoids, motors, transformers, everything is AC. We settled that problem quickly for most of it using Relays, the sensors (our inputs) are whats giving us the hassle as you see. We have dicsussed slowly switch all the sensors to DC but this is something that would have to take place over time, thus my lean more toward using rectifiers until the switch is made.

Could you show the complete wiring diagram? How are the sensors powered? The datasheet shows only 2 or 3 connections.

Pieter

PieterP:
Could you show the complete wiring diagram? How are the sensors powered? The datasheet shows only 2 or 3 connections.

Pieter

Thats all there is. Its a 3 connection sensor. AC IN, Ground, and AC OUT

Hope this helps.

EDIT: As far as being powered they are powered by a transformer. Transformer to Sensor transferring the power to the out line, then from there back to the neutral on the transformer. I can try to draw this up on fritzing if needed.

Blade2021:
Thats all there is. Its a 3 connection sensor. AC IN, Ground, and AC OUT

Hope this helps.

Your image isn't working :slight_smile:

PieterP:
Your image isn’t working :slight_smile:

Dropbox strikes again! I updated that post after you saw it with other information and here is the image.

sensorDiagram.jpg

But you still didn't show how it's connected to the Arduino, just draw it on a piece of paper, and take a picture of it if you don't have the right schematic software.

Pieter

PieterP:
But you still didn't show how it's connected to the Arduino, just draw it on a piece of paper, and take a picture of it if you don't have the right schematic software.

Pieter

Pardon my bad handwriting.

I just ran the #'s. Converting just one of our machines to completely DC sensors would be over $1000, verses possibly $50 - $100. Using a rectifier, capacitor, and voltage regulator on each sensor.

I know its logically backwards but a cost savings of $900 +-

You better hire some electronic professional for your project :-]