Filtering External Noise

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.

TomGeorge:
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:

Here are my hand drawn schematics. The first is what I'm working with right now, and the second is what I think I need to do. Namely, I need to connect that second resistor to ground and add a filter to the power supply line.

The project is already in the car so I can't get any pictures that would be clear enough to really show anything.

JOHI:
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.
www.SylvesterSolutions.com

I have read about optocouplers and although they sound like they might be the best option, I was looking more for a solution using inductors, capacitors, diodes and transistors.
I'm pretty sure the program is fast enough to keep up. It's not as fast as a direct gauge, but I haven't had an issue with the delay between accelerating and a change in the value on the screen.

Grumpy_Mike:
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.

Exactly! I have a USB socket in the cigarette lighter socket, and a USB wire from there to the board. I think that's exactly the source of the issue. It think it explains why the error increases as the RPM increases - when the engine is spinning faster, the alternator is spinning faster and supplying more voltage to charge the battery like the 14V you suggested.
I will look into spike filtering now! Do you have any suggestions as to what I should specifically look for? And would I run the power through the spike filter, and then through another RC or LC filter and then to the board?

I know I am late to the game, but have you absolutely confirmed the interference is being conducted to your project by the power wiring? Did you power the project from local batteries and the interference goes away?

Paul

, I need to connect that second resistor to ground and add a filter to the power supply line.

Yes you do. Are you sure that a 10R resistor is the right value, it looks a bit low to me.

So if it is a USB socket in the car it is likely to be at a nominal 5V. Have you measured this with a meter?

If there's room, it would be ideal to wrap multiple turns through the ferrite clamp. Try for up to 5 turns.

.

Note: Number of turns is passes through the hole, not outside. Therefore left image is 3 turns, right image is 5 turns.

I would not immediately blame this on interference. As someone mentioned in an earlier post, it is critical to understand what type of tacho signal you are getting in: is it a square wave with a frequency equal to the ignition frequency, or a PWM signal, or... and at what voltage?

Your current code already makes an assumption about this, as it is counting pulses over time. However, you mention you expect the tacho signal to be PWM, in which case your code would not produce the correct rpm, no matter how many ferrite clamps you attach.

The fact that you have to calibrate to get a correct rpm reading at idle already suggests something is off, as with your current pulse counting code you should not have to calibrate at all.

Hope this helps!