Filtering External Noise

Hello! I have a question concerning filtering noise produced by the system surrounding my Arduino and circuit. So for a project for my class, I've (sort of) designed a project that will be able to take the digital tachometer signal produced by my car, have the Arduino process it, and have it displayed on an LCD screen. I was actually able to install it, but I'm running into a few hiccups.

So far I've been able to run the signal through a voltage divider to a digital pin on the board. I wrote a shell of a code to display the values and I took it out to test it. The RPM displayed at idle is accurate, however when I rev the engine or drive it, the error in the displayed value gets worse as the RPM gets higher. I suspect that this is due to external noise because I had a few ferrite core clamps lying around and when I strapped them to the power wire, the error was smaller. So my question is this - does anyone know of any way I can use hardware to filter this external noise? To stay within the project guidelines, I need to use components like capacitors and transistors and such. I think the direction I need to head in is designing a high pass filter, but I'm not sure if that's right.

TL,DR: I have a project for class that's encountering external noise, and I need to figure out what hardware/circuitry to use to fix it. I think I need a high pass filter but I'm not sure.

Thanks so much in advance!!!

Show us a schematic of the existing wiring. Also images of the wiring if you can.

Can you supply a drawing of the

digital tachometer signal produced by my car

Are you working from the CAN-BUS or some other tachometer signal?
How does the signal change as the revs change?

aarg:
Show us a schematic of the existing wiring. Also images of the wiring if you can.

Here's a schematic of what I did. Sorry I don't have a proper schematic software, so credit to Arduino for the bulk of the picture! (sourced from https://www.arduino.cc/en/Tutorial/LibraryExamples/HelloWorld ) I don't have the car at the moment but I will soon, so if you need pictures of the actual wiring I can get them for you. Thanks for your help!

johnerrington:
Can you supply a drawing of the Are you working from the CAN-BUS or some other tachometer signal?
How does the signal change as the revs change?

I'm working with a signal straight from the Ignition Control Module attached to the engine. One of the wires in the wiring harness carries the signal for a tachometer. Normally, the signal would be used to drive a stepper motor to move the needle on the gauge in the dashboard cluster, but I don't have a tachometer gauge. The signal carries a higher voltage as the RPM increases to drive the needle further around the gauge. Thanks for your help!

Its unlikely that a signal from a digital device to another would use an analog voltage. From your description I'd guess its a frequency, or PWM.
How you process it would depend on the actual signal. However you could try this as an experiment

can you get an oscilloscope to look at the signal?

Ferrite clamps can just be considered as inductors because that is what they are. So if you want to replace them then you could use an inductor in seriese with your power cable. In addition you can use a capacitor to ground on the Arduino side of the inductor. Use a big capacitor like a 1000uF and in parallel with it put a 0.1uF ceramic capacitor. To increase the filtering repeat this circuit in series with the last.

I would even include those clamps and explain they are inductors and as such normal components. They are not exotic stuff like transorbs.

Ferrite sleeves at higher frequencies (VHF) are often fairly lossy inductors, which is even better
as interference is largely absorbed rather than reflected back at its source.

johnerrington:
Its unlikely that a signal from a digital device to another would use an analog voltage. From your description I'd guess its a frequency, or PWM.
How you process it would depend on the actual signal. However you could try this as an experiment

https://www.instructables.com/Analog-Output-Convert-PWM-to-Voltage/

can you get an oscilloscope to look at the signal?

I think you might actually be right, I think it is a PWM signal. In my code, I use the pinMode and INPUT_PULLUP functions, so it must be a digital signal. Unfortunately, I don't have access to an oscilloscope :frowning: but now knowing that it is indeed a digital signal, how does that change things? I assume I'll still be able to create some sort of filter to better isolate the desired signal, correct? Or would it be better to convert it to an analog signal using an RC circuit as shown in the link you provided, and then apply some filter?

Grumpy_Mike:
Ferrite clamps can just be considered as inductors because that is what they are. So if you want to replace them then you could use an inductor in seriese with your power cable. In addition you can use a capacitor to ground on the Arduino side of the inductor. Use a big capacitor like a 1000uF and in parallel with it put a 0.1uF ceramic capacitor. To increase the filtering repeat this circuit in series with the last.

I would even include those clamps and explain they are inductors and as such normal components. They are not exotic stuff like transorbs.

Very interesting, I didn't know that! To create the filter the filter you describe, I would run the power from the car, through the LC circuit, and then to the Arduino? If so, I'm using the USB port to power the board, so how difficult would it be to accomplish this?

MarkT:
Ferrite sleeves at higher frequencies (VHF) are often fairly lossy inductors, which is even better
as interference is largely absorbed rather than reflected back at its source.

Interesting, given this I think I'll probably keep them in even after I apply the filter. However, I think I might take them off and see what the difference is and add it to my analysis in my report. Thanks!

describe, I would run the power from the car, through the LC circuit, and then to the Arduino?

Yes.

If so, I'm using the USB port to power the board, so how difficult would it be to accomplish this?

What is regulating the USB power down to 5V? You would put the filtering before that regulator.

We are REALLY in the dark about this. Do you have a reference for the ignition control module - or even at worst just a make/model/age for the car - that might give us a guide as to the nature of the signal?

So far I've been able to run the signal through a voltage divider to a digital pin on the board. I wrote a shell of a code to display the values and I took it out to test it. The RPM displayed at idle is accurate, however when I rev the engine or drive it, the error in the displayed value gets worse as the RPM gets higher.

What are your voltage divider values?
Can you show your code?

The RPM displayed at idle is accurate

howw do you know? Did you calibrate it at idle - if so the value would naturally be "correct".

Also - youre powering your arduino from the cars "12V" supply which is VERY noisy, and also can go as high as 14 - 15V (still within spec) but it means you do have some headroom to add an RC filter. Say a 10 ohm resistor and 1000uF cap.

Simple experiment - if the ig uses a single crankshaft sensor you COULD have a signal of 600rpm = 10HZ at idle. So why not write (or crib) a sketch to time the interval between rising (or falling) edges?

Looking at your circuit from reply#3 you have wired up the voltage divider wrong.
The wire from signal goes to a resistor which is shorted out by the track of the bread board. The second resistor goes nowhere, so what you have is the signal being connected directly into pin 9 of your Arduino.

Hi,
Can I suggest you draw your circuit with pen(cil) and paper and post a picture of it?
You can then spread out and layout your components better.

You can also label your components, their value and any pin names.

Have you built your project on protoboard like in the Fritzy image?
Can you please post a picture of your project so we can see your component layout?

Thanks.. Tom... :slight_smile:

Hello,
The remark about no ground connection about the voltage divider is correct.
Just to check, I do see only 1 wire for power connection in the drawing, i assume there are 2 (12V and mass).
You could consider separation of car and Arduino world using optocoupler.
Also a Schmitt-trigger can be helpful in this case.
Is your Arduino program fast enough to keep up with the motor speed (interrupt handler for processing count or use internal hardware counters ?). 6000rpm = 100 rev/sec = 100 Hz
Best Regards,
Johi.

Grumpy_Mike:
Yes.
What is regulating the USB power down to 5V? You would put the filtering before that regulator.

At the moment, nothing is regulating the power for the board. I'm powering it straight from the vehicle's USB input from the cigarette lighter.

johnerrington:
We are REALLY in the dark about this. Do you have a reference for the ignition control module - or even at worst just a make/model/age for the car - that might give us a guide as to the nature of the signal?

What are your voltage divider values?

The car is a 2003 Chevy Impala with a 3.8L Supercharged engine (swapped it myself!)
My voltage divider values are 220 and 10.

johnerrington:
Can you show your code?
howw do you know? Did you calibrate it at idle - if so the value would naturally be "correct".

Also - youre powering your arduino from the cars "12V" supply which is VERY noisy, and also can go as high as 14 - 15V (still within spec) but it means you do have some headroom to add an RC filter. Say a 10 ohm resistor and 1000uF cap.

Simple experiment - if the ig uses a single crankshaft sensor you COULD have a signal of 600rpm = 10HZ at idle. So why not write (or crib) a sketch to time the interval between rising (or falling) edges?

Here's my code, I'm really sorry it's kind of a mess. But basically I run an introduction / welcome loop, then display the RPM value on the top row. I set ranges for the RPM values and have a little bar increase on the second row as the RPM increases. I did subtract 180 from the value in the "int averagedRpm" line to calibrate it at idle, so you're right that it's naturally "correct".

/*
 * SIMPLE ARDUINO CAR TACHOMETER
 */
#include <LiquidCrystal.h>
}*/

#define countof(array) ( sizeof(array) / sizeof(*(array)) )
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

 
const int DATA_PIN            = 9;

const int PINS_COUNT          = 4;

const int NUMBER_OF_CYLINDERS = 6;

const int LED_UPDATE_INTERVAL = 200;

/* Last led state update time in ms, used to calculate the time from last update */
unsigned long lastUpdateTime  = 0;

/* Amount of spark fires in a single interval */
volatile int sparkFireCount   = 0;

/* Rpm value from last update used to average the last 2 rpms for smoother output */
int lastRpmValue              = 0;
int lastlastRpmValue          = 0;

void incrementRpmCount () {
  sparkFireCount++;
}

/* Defines data pin function and opens serial for communication */
void setup() {

  pinMode(DATA_PIN, INPUT_PULLUP);
  attachInterrupt(1, incrementRpmCount, FALLING);
  Serial.begin(9600);

  lcd.createChar(0, box);

  // set up the LCD's number of columns and rows:
  lcd.begin(16, 2);
  // Print a message to the LCD.
  lcd.setCursor(1,0);
  lcd.print("*** WELCOME ***");
  lcd.setCursor(1,1);
  lcd.print("*** DRIVER ***");
  delay(2000);
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("2003 IMPALA 3.8L");
  lcd.setCursor(0,1);
  lcd.print("ALL SYSTEMS GO");
  delay(2000);
  lcd.clear();
  lcd.setCursor(2,0);
  lcd.print("PREPARE FOR");
  lcd.setCursor(4,1);
  lcd.print("LIFTOFF");
  delay(2000);
  lcd.clear();
}

// 4 stroke engine fires every spark in 2 revolutions
// so calculate at what degree interval sparks fires and divide 360 by it,
// to find the number of fires per rotation
const int FIRES_PER_REV = (360 / (720 / NUMBER_OF_CYLINDERS));

char rpm[16];

void loop() {
  if ((millis() - lastUpdateTime) > LED_UPDATE_INTERVAL) {

    // multiply the amount the spark fires in one interval by the number of intervals per
    // second, to find the amount in one second
    // then multiply the amount in one second by 60, to find the spark fires in one minute and
    // divide the result by the number of fires per revolution to find the rpm
    int currentRpm = (sparkFireCount * (1000 / LED_UPDATE_INTERVAL) * 60) / FIRES_PER_REV;

    // average the current and last 2 rpm for smoother results, subtract 180 to account for noise
    int averagedRpm = ((currentRpm + lastRpmValue + lastlastRpmValue) / 3)-180;

    Serial.println(averagedRpm);

    sprintf(rpm,"RPM: %d", averagedRpm);

    if(averagedRpm<1000){
    lcd.setCursor(3,0);
    lcd.print(rpm);
    lcd.setCursor(11,0);
    lcd.print("  ");
    }

    if(averagedRpm>1000){
    lcd.setCursor(3,0);
    lcd.print(rpm);
    }


    sparkFireCount = 0;
    lastUpdateTime = millis();
    lastlastRpmValue = lastRpmValue;
    lastRpmValue = currentRpm;
  }
}

I think the issue does lie in the power supply. The power from the vehicle would be noisy since at a higher RPM the alternator is suppling more voltage to charge the battery. That would explain why the ferrite clamps helped!
So, I think you're right in that I should run the power through an RC filter before I put it to the board. If I understand the concept correctly, the extra noise from the alternator will be regulated by the charging and discharging of the capacitor? Or should I use an LC circuit as Grumpy_Mike suggested?

Hi
Can you please answer/check about the gnd connections remarks previously with respect to the potential divider.

Do you have one end of the divider at gnd, the middle connection to the controller and the top connection to the ignition pulse?

Your fritzy picture shows you have no gnd connection and a resistor shorted out.

PLEASE post a picture of your project so we can see your component layout and also DRAW with pen(cil) and paper your schematic and post an image.

Thanks.. Tom.. :slight_smile:

At the moment, nothing is regulating the power for the board. I'm powering it straight from the vehicle's USB input from the cigarette lighter.

I am not sure I understand that.
Is is your have connected the USB socket directly to the cigarette lighter? Or is there something in between ?

When a car is running the voltage across the battery can be up to 14V with spikes on top of that. You need some spike filtering first like using zener diodes and resistors, or transorbs to absorb the spikes.