Go Down

Topic: Filtering External Noise (Read 999 times) previous topic - next topic

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

tjtj13

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

tjtj13

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".
Code: [Select]

/*
 * 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?

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.. :)
Everything runs on smoke, let the smoke out, it stops running....

Grumpy_Mike

Quote
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.

tjtj13

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


tjtj13

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.  

tjtj13

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?

Paul_KD7HB

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

Grumpy_Mike

Quote
, 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?

dlloyd

#25
Nov 19, 2020, 02:51 pm Last Edit: Nov 19, 2020, 02:55 pm by dlloyd
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.

kr3ator

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!

tjtj13

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?
So I was able to measure the voltage on the USB that I'm plugging into the Arduino, and I found that the output is a steady 5V. It seems there is no change even when the RPM is higher. I then tried powering the Arduino by plugging it into my laptop, and I output the same values. So the idea that there is external noise on the power wire is not correct :(
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!
I did some more research on what a PWM signal is, and found that many people use it to drive motors. This sounds similar to how the signal I am using would have been used to drive a small motor in the actual tachometer gauge, so now I'm thinking that I need to re-write my code. I have no experience with PWM at all; does anyone have any links that might help me? Everything I'm finding seems to talk about generating a PWM to drive a motor, but I need to do the opposite. Thanks so much for all your help!

Grumpy_Mike

#28
Nov 27, 2020, 11:02 pm Last Edit: Nov 27, 2020, 11:06 pm by Grumpy_Mike
Quote
So the idea that there is external noise on the power wire is not correct :(
Don't be silly, you will not see voltage spikes on a digital voltmeter, you need an oscilloscope. You can not make that conclusions from that information.

It was you who said that adding a filter improved things. Now you seem to have changed your mind on what the symptoms are. You told us that things changed with the revs, now you are saying it doesn't. We can only go off what you tell us, and if you don't tell us the truth then we can't give accurate advice.

Quote
Everything I'm finding seems to talk about generating a PWM to drive a motor, but I need to do the opposite.
So read this
http://www.thebox.myzen.co.uk/Tutorial/PWM.html
You will see that PWM can be turned into an analogue voltage by single resistor and capacitor.

Paul__B

Well, this is getting complex but I find it extremely implausible that interference on the (USB) power line is causing problems as such.

Using interrupts sounds like a generally bad idea for this application, and any interference is going to be coming in on the input signal, so that is where you need to be looking.

I see no reference to the ground connection which must be coming to the Arduino along with the input signal.  Clearly an optocoupler is simply essential in this application.

The diagrams repeatedly confuse the USB connector with the "Barrel jack".   :smiley-eek:

And as an incidental aside, disconnect the potentiometer from the 5 V line.  This is a persistent mistake that has infested projects virtually since the beginning!  Also, given that R8 on the LCD module is "101" or 100 Ohms, the 220 Ohm resistor is unnecessary unless you actually find the LCD too bright.  :smiley-lol:

Go Up