Best approach to mitigate possible EM interference corrupting LCD?

Seeing some garbage characters printed on an LCD at seemingly random times - although it does seem as if the garbage only appears after my sketch/circuit has been running for a while. I'm not sure if it's a memory leak in my code, or whether it's EM interference from e.g. AC lighting switches etc. in the vicinity.

I'd like some advice about the best electronic modifications that could be made to my circuit to mitigate against EM interference corrupting my LCD. I've read a range of similar forum posts where various capacitor values (100uF? 47uF?) have been quoted as worth putting across Vss and Vdd at the LCD, to smooth any supply noise.

If anyone has any ideas I would be very keen to hear them.

I appreciate that since I've currently got all this lashed together on breadboards, I might be seeing more EM interference than would otherwise be the case if I had everything soldered down to veroboard etc. (due to jumper wires acting as inductors?).
If you think that's my main problem then by all means say so :slight_smile:

Here are the details of my set-up:

I'm using an Arduino Nano v3.0, driving an HD44780 LCD display using a 74HD595 shift register, as per this link:

I drew out a schematic in Fritzing for this (see attached). Note that I've chosen to use Arduino pins 5, 6 & 7 to as the datapin, latchpin and clockpin instead of 7, 8 & 9.

I've also added a simple LDR-based voltage divider consisting of a 60K resistor and a 5516 LDR as follows:

5V ]-----[[60K]]-----|-----((5516 LDR))----[GND
|
|---->to Arduino pin 2 (interrupt 0)

...the idea being that any voltage drop across the 5516 LDR (it's 'looking' straight at a blinking LED in darkness) will fire an ISR declared in my sketch.

The LDR voltage divider is connected across the same 5V & GND as the LCD/shift register circuit.

The 5V & GND are taken from the corresponding Arduino 5v / GND pins.

#include <LiquidCrystal595.h>    // include the library
 
const float METER_BLINKS_PER_KWH = 800.0;
const float MILLIS_PER_HOUR = 3600000.0;
float bill_units_per_hour = 0;
 
LiquidCrystal595 lcd(5,6,7);     // datapin, latchpin, clockpin
int backlightPin = 4;
 
const long BOUNCE_WINDOW_MS=450;
unsigned long prev_interrupt_ms = 0;
unsigned long interrupt_ms = 0;
unsigned long millis_since_last_blink = 0;
volatile unsigned long last_blink_ms = 0;
volatile int blinks = 0;
int interruptPin = 2;
 
unsigned long curr_millis = 0;
unsigned long prev_millis = 0;
 
void onBlink()
{
  interrupt_ms = millis();
  millis_since_last_blink = (unsigned long)(interrupt_ms - prev_interrupt_ms);
  if(millis_since_last_blink >= BOUNCE_WINDOW_MS)
  {
    last_blink_ms = millis_since_last_blink;
    blinks++;
    prev_interrupt_ms = interrupt_ms;
  }
}
 
void setup() {
 
  pinMode(interruptPin,INPUT);
  attachInterrupt(0, onBlink, FALLING);
 
  pinMode(backlightPin,OUTPUT);
  lcd.begin(16,2);             // 16 characters, 2 rows
  lcd.clear();
  
  digitalWrite(backlightPin, HIGH); //turn on backlight
 
  lcd.setCursor(0,0);
  lcd.print("Blink Monitor");
  lcd.setCursor(0,1);
  lcd.print("Initializing...");
  delay(5000);
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("ms     kW");
}
 
void loop() {
 
  curr_millis = millis();
 
  if((unsigned long)curr_millis - prev_millis > 1000)
  {
    calculateKWH();
    prev_millis = curr_millis;
  }
}
 
void calculateKWH()
{
  if(blinks > 0)
  {
    bill_units_per_hour = MILLIS_PER_HOUR / ((float)last_blink_ms * METER_BLINKS_PER_KWH); // 3600000 / [X * 800]
    lcd.setCursor(0,1);
    lcd.print(last_blink_ms);  lcd.print("   ");//add whitespace over any previous long timing
    lcd.setCursor(8,1);
    lcd.print(bill_units_per_hour,2); // 2 decimal places
  }
}

Thanks in advance for any help.
Happy to supply any further info you may need.

20140303_095159.jpg

Sorry, for some reason the schematic didn't attach in the first post.
See attached below.

Hi, don't be to worried, with protoboard you can and quite often do end up with a ratsnest wires, with digital signals passing through them you can induce phantom spikes into other wires.
So try changing the physical layout.
Also put some 0.1uF capacitors from the supply wires to gnd, do this as close as possible to the supply pins of the LCD display. This will bypass any noise in the supply wires.

Tom.... :slight_smile:

Thanks for the reassurance!

I'm on the point of moving the shift register stuff off the breadboard and onto some veroboard and soldering things into place, so I guess the layout will change fairly radically anyway at that point. But I'm keen to add what I can to the electronics before I do that by way of belt and braces as it'd be very tedious if I ended up with the same problems after doing all the soldering!

Just to clarify what you've suggested about the 0.1uF caps..... do you effectively mean one capacitor between LCD 'Vss' and GND and also another one between LCD 'Vdd' and GND?

Should I consider something similar with the backlight supply too? i.e. the 'A' and 'K' pins on the LCD.***[see below]

I'm sure I can look up the info on what this type of capacitor placement actually does, but if you feel like giving me a quick sentence on it here that would be really handy :slight_smile:

And of course any other pre-soldering-stage belt & braces additions you or anyone else cares to add, I'd be very grateful.
(e.g. I'm quite curious about the benefit of adding a 47uF [or more suitable value] smoothing capacitor across the supply to the LCD - would I be wasting my time bothering?)

***Apologies - need to point out (visible in code but not schematic) that I rigged the breadboard to use Arduino pin 4 as direct power to LCD pin 'A' (backlight +ve). Did this originally as the instructables link didn't mention the library method to call to achieve the same thing via the NPN BC547. I've since found the method to call, so will re-wire and cross fingers it 'does what it says on the tin'. Not sure if this will make any difference to the LCD garbage - I'm hazarding a guess it won't.

Hi, fine on moving things, the shift register as well could do with 47uF and 0.1uF caps across the the supply pins, as close to the pins on the IC as possible. 47uF cap is to help filter power supply , 0.1uF is to filter switching noise from digital circuitry.
Vss is already gnd, so between Vdd and Vss at the LCD.

Tom..... :slight_smile:

Thanks again Tom
I've just read a fair bit of interesting stuff about decoupling capacitors etc.
It's all making a lot more sense now.
Big thing learned today is that it's pretty standard to apply 0.1uF across every IC supply as close as poss to the IC, just as you recommend.
I appreciate what you said about Vss being already GND... just wasn't sure what you meant at first :~
Thanks for the tips and for pointing me in the right direction + the confirmation on 47uF usage - I've learned some really useful stuff today!