I2C LCD screen issues.

I am troubleshooting an issue with a project I am working on. This is the first time I have used the I2C LCD screen backpack from Adafruit and I’m finding I have issues that I do not understand. I’ll give a quick summary of the project, share the code, then explain what is going on.

Project summary
This project is wired to a Mega2560 R3. In a nutshell, I have 5 pots being used to vary PWM output to control the speeds of 5 different motors through N-Channel Mosfets. Two of those motors have backshaft encoders. I am using the TimerOne library and ISR’s on Pins 2 and 18. The Pots, backshaft encoders, and screen are being powered by the 5V output from the mega. The Mega is powered by 12V from the input jack, and the motors are powered externally by 24V.

What is going on:
With everything plugged in:
-on power up the screen display characters are jumbled. If I hit reset enough times it eventually displays the right thing.
-Whatever the pot value is on start up is stuck. turning them does nothing. Resetting at a different setpoint does change the value.

Unplugging Screen Power:
Same as above

Unplugging Pins 20/21 (SDA/SCL)
Upon reset fixes all issues; except of course no screen

Does anyone have an idea of what is going on here, or how I can fix it? it seems like somethign directly tied to the presence of the screen SDA/SCL connection.

Code:

#include <TimerOne.h>
#include <Adafruit_LiquidCrystal.h>
#include <Wire.h>
Adafruit_LiquidCrystal lcd(0);  //PIN 20 = dat pIN 21 = clk) 

float counter1 = 0;       //Variables use to store # of hall effect pulses from pumps
float counter2 = 0;
float Pump1Flow = 0;
float Pump2Flow = 0;

int Stir1RPM = 0;
int Stir2RPM = 0;

int Pump1Pot = A0;
int Pump2Pot = A1;
int Stir1Pot = A2;
int Stir2Pot = A3;
int AugerPot = A4;
int Pump1Pin = 4;
int Pump2Pin = 5;
int Stir1Pin = 6;
int Stir2Pin = 7;
int AugerPin = 3;
int Pump1PotValue = 0; //Initial value reading of pot
int Pump2PotValue = 0;
int Stir1PotValue = 0;
int Stir2PotValue = 0;
int AugerPotValue = 0;

int Pump1OutputPWM = 0;   //Initial output value for motor
int Pump2OutputPWM = 0;
int Stir1OutputPWM = 0;
int Stir2OutputPWM = 0;
float AugerOutputPWM = 0;
float AugerFlow = 0;
float AugerFlowScaled;


void docount1()
{
  counter1++;   //increase +1 counter value
}

void docount2()
{
  counter2++;   //increase +1 counter value
}

void timerIsr1()
{
  Timer1.detachInterrupt(); //stop the timer
  Pump1Flow = (counter1*0.008888889*.902248);    //see Phase2 design notebook for derivation of scaling values; last value is scalar based on test performance
  Pump2Flow = (counter2*0.001866667*.9188);
  counter1=0; //reset the counters
  counter2=0; //reset the counters
  Timer1.attachInterrupt( timerIsr1); // enable the timer
}





void setup() {
  lcd.begin(20, 4);
  pinMode(Pump1Pin, OUTPUT);
  pinMode(Pump2Pin, OUTPUT);
  pinMode(Stir1Pin, OUTPUT);
  pinMode(Stir2Pin, OUTPUT);
  pinMode(AugerPin, OUTPUT);

  Timer1.initialize(500000); //sets timer for .5sec
  attachInterrupt(digitalPinToInterrupt(2), docount1, RISING); //increase counter when speed sensor pin goes High WAS 0=2, 1=3
  attachInterrupt(digitalPinToInterrupt(18), docount2, RISING);
  Timer1.attachInterrupt( timerIsr1); //enable timer
}

void loop() {
  //Check All Pot values, convert to PWM values, and store 
  Pump1OutputPWM = analogRead(Pump1Pot)/4;
  Pump2OutputPWM = analogRead(Pump2Pot)/4;
  Stir1OutputPWM = analogRead(Stir1Pot)/4;
  Stir2OutputPWM = analogRead(Stir2Pot)/4;
  AugerOutputPWM = analogRead(AugerPot)/5.14;

  Stir1RPM = map(Stir1OutputPWM, 0,255,0,100);
  Stir2RPM = map(Stir2OutputPWM, 0,255,0,100);
  
if(AugerOutputPWM <25 ){
  AugerFlow = 0;
}
else{
  AugerFlow = .06712*AugerOutputPWM-1.61176;
}
  AugerFlowScaled = AugerFlow/100;

  analogWrite(Pump1Pin, Pump1OutputPWM);
  analogWrite(Pump2Pin, Pump2OutputPWM);
  analogWrite(Stir1Pin, Stir1OutputPWM);  
  analogWrite(Stir2Pin, Stir2OutputPWM);
  analogWrite(AugerPin, AugerOutputPWM);

  
  lcd.setCursor (0,1);
  lcd.print("STR1%:");
  lcd.print(Stir1RPM);
  lcd.setCursor (10,1);
  lcd.print("STR2%:");
  lcd.print(Stir2RPM);
  lcd.setCursor(0,0);
  lcd.print("P1:");
  lcd.print(Pump1Flow,2);
  lcd.setCursor(8,0);
  lcd.print("P2:");
  lcd.print(Pump2Flow,2);
  lcd.setCursor(16,0);
  lcd.print("mL/m");
  lcd.setCursor(0,2);
  lcd.print("AUGER:");
  lcd.print(AugerFlow,2);
  lcd.setCursor(10,2);
  lcd.print("g/m");
  lcd.setCursor(6,1);
  lcd.print("   ");
  lcd.setCursor(16,1);
  lcd.print("   ");
}
Adafruit_LiquidCrystal lcd(0);  //PIN 20 = dat pIN 21 = clk)

I doubt that you have a liquid crystal I2C interface with address 0 so why do you define it that way?

0 Is the default specified by the Adafruit lcd backpack interface:

I don’t have great understanding beyond that of the address.

I should add that the screen does work normally, and shows character changes corresponding to variable change from the pots when powered by USB. Of course the motors aren't functional without the 24V supply on. When I Plug in the 24V to power the motors, the screen quits working again.

0 Is the default specified by the Adafruit lcd backpack interface:

Quite stupid, Adafruit should know it better. Addresses 0-7 are reserved and must not be used. Address 0 is a general call, comparable to a network broadcast, any device connected should react to it.

Please post a wiring diagram of your setup. I guess there isn't enough isolation from the motors. As the motors are inductors you have to take care of the fly back current.

Pylon - I think you are right. I isolated the wiring to the screen and all problems were immediately resolved. I had all my wiring in a braided bundle. By routing screen wires separate my issues seem to be gone.

I do have a diodes in place to deal with flyback.