1

I have an OBD-based Arduino project (OBD adapter link below) which uses two servos and a serial LCD from Sparkfun (link below). My problem: writing to the LCD seems to interfere with the servos. Details:

1) When all LCD-related code is excluded, the servos work smoothly. 2) When LCD-related code is included, but the servos are not hooked up, the LCD displays everything OK. 3) When the LCD-related code is included, even if the LCD itself is NOT hooked up, the problem occurs. There's a brief noise from the servos every time I write to the LCD (the servos don't move much, they just make a brief noise).

Any idea what's causing this? Below are the relevant parts of the code (OBD, servo, LCD):

#include <Arduino.h>
#include <Wire.h>
#include <OBD.h>
#include "MPU6050.h"
#include <SoftwareSerial.h>
#include <Servo.h>

int servoPin1=13;
int servoPin2=12;

Servo servo1;
Servo servo2;

COBDI2C obd;
SoftwareSerial lcd(2,3);

void clearDisplay() {
  lcd.write(0xFE);
  lcd.write(0x01);
}

void setLCDCursor(byte cursor_position) {
  lcd.write(0xFE);
  lcd.write(0x80);
  lcd.write(cursor_position);
}

void Show() {
  setLCDCursor(0);
  lcd.print("Test");
}

void setup() {
  lcd.begin(9600);
  clearDisplay();  
  setLCDCursor(0);
  lcd.print("OBD");

  pinMode(servoPin1,OUTPUT);
  pinMode(servoPin2,OUTPUT);
  servo1.attach(servoPin1);
  servo2.attach(servoPin2);
  servo1.write(0);
  delay(200); 
  servo2.write(100);
  delay(200);

  obd.begin();
  conn=obd.init(PROTO_AUTO);
  lcd.print("Connected");

  Wire.begin(); 
}

void loop() {
  conn=obd.readPID(PID_RPM,rpm);
  if (condition) {
     servo2.write(50);
    delay(500);
    servo1.write(100);
    delay(500); 
  }
  Show();
  delay(1000);
}

Schematic

OBD adapter Serial LCD

2

You are using SoftwareSerial which turns interrupts off when sending/receiving in order to precisely time gaps between bits. The Servo library may use hardware timers, but to work on pins 12 and 13 would require interrupts to "copy" the pulses to those pins. Thus the copies will be distorted when writing to, or reading from, SoftwareSerial.

I suggest using hardware serial (pins 0 and 1) for talking to the LCDs, which does not turn interrupts off. Alternatively, implement the servo positioning using the hardware timers yourself, which (once set up) won't change the pulse widths if interrupts are turned off.

  • Thanks. I tried connecting the LCD data wire (pink in the schematic above) to either Tx or Rx (0 or 1) on the UNO. I removed all refs to SoftwareSerial and replaced all calls to "lcd." with "Serial." in the above code, but I'm getting garbage on the LCD. I tried different baud rates 4800,9600,19200 = all garbage. Is this the proper way to use the hardware serial? – MrSparkly Jul 23 '18 at 5:23
  • To write to the LCD you need to use pin 1 on the board (Tx). Don't thrash around trying different baud rates, if 9600 worked with SoftwareSerial then it will work with Hardware Serial. You may need to unplug the LCD from pin 1 whilst uploading new sketches. – Nick Gammon Jul 23 '18 at 6:04
0

The servo control PWM signal is generated in HW. So should be stable if left alone with adequate power despite what the code is doing. Servos are analog devices. So any perturbation in the shape or length of the wave form may affect the servo.

Consider, once the servo has reached the desired position, turning off the PWM signal which, for most servos, simply leaves them motionless where they are.

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.