Pages: [1]   Go Down
Author Topic: Serial write to an LCD causes motors on PWM to twitch.  (Read 1146 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 0
Posts: 12
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi everyone,

So I have a basic robot, uses the bottom half of a wheelchair, an arduino mega to send servo PWM signals to a Sabertooth 2x25amp motor driver. I recently added a Parallax 2x16 LCD display that uses a serial port. I found an example program for the LCD, tested it on mine, and everything worked fine. I merged the LCD test program into my main program, and now every time the arduino writes or prints to the LCD, the motors do a hard twitch. So I went back to the example code, and brought over some code from the main program relating to the motors to try to duplicate the problem in the example code, and sure enough, they twitch still. Even when I comment out all the 'wheelL.write(wheelLpwmset);', so there's no writing to the motors, they still twitch. Is this because the arduino is crossing Tx wires somewhere? Right now the Sabertooth is in servo mode, and connected to the PWM pins 2 and 3, while the LCD Rx is on Tx pin 16. My guess is when the arduino needs to write serial, it has a hiccup of some sort on the PWM pins. Even when the LCD is disconnected and wires removed, still twitches. I've tried many modifications to my code but the only thing that seemed to make it stop was to comment out any 'mySerialLCD.write(' and 'mySerialLCD.print(' lines. Any insight to this would be really great!

My potential alternative might have to be to switch my Sabertooth to serial port mode also, but I'm trying to avoid this as it will take several hours of testing and re-configuring!

I have also tried digging around the Arduino site to learn what more I can about serial and servos but haven't found anything about serial causing interference with PWM.

 - Trevor

Code:
const int TxPinLCD = 16;

int timer;
#include <Servo.h>
#include <SoftwareSerial.h>
SoftwareSerial mySerialLCD = SoftwareSerial(255, TxPinLCD);
Servo wheelL;
Servo wheelR;
float wheelLpwm, wheelRpwm, wheelLpwmset, wheelRpwmset, wheelLmax, wheelRmax, wheeltemp;

void setup() {
  wheelL.attach(2, 600, 2400);
  wheelR.attach(3, 600, 2400);
  wheelLpwmset = 90.0; wheelRpwmset = 90.0; wheelLmax = 1.0; wheelRmax = 1.0;
 
  timer = 0;
 
  pinMode(TxPinLCD, OUTPUT);
  //digitalWrite(TxPinLCD, HIGH);
 
  mySerialLCD.begin(9600);
  delay(100);
  mySerialLCD.write(12);                 // Clear             
  mySerialLCD.write(17);                 // Turn backlight on
  delay(5);                           // Required delay
  mySerialLCD.print("Hello, world...");  // First line
  mySerialLCD.write(13);                 // Form feed
  mySerialLCD.print("from Parallax!");   // Second line
  mySerialLCD.write(212);                // Quarter note
  mySerialLCD.write(220);                // A tone
  delay(3000);                        // Wait 3 seconds
  //mySerialLCD.write(18);                 // Turn backlight off

}

void loop() {
  wheelL.write(wheelLpwmset);
  wheelR.write(wheelRpwmset);
  timer = int(millis() / 1000);
  mySerialLCD.write(12);//clear screen
  mySerialLCD.print("Hello, world...");
  mySerialLCD.write(13);
  mySerialLCD.print(timer);
  wheelL.write(wheelLpwmset);
  wheelR.write(wheelRpwmset);
 
  delay(1000);
 
}
Logged

Massachusetts, USA
Offline Offline
Tesla Member
***
Karma: 208
Posts: 8821
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

My guess is that SoftwareSerial is disabling interrupts when it sends characters.  If the Servo library uses interrupts for timing this can cause significant errors in the pulses coming from the Servo library.  If you have an oscilloscope handy you can watch the serial line and servo pulses to see if they are interacting.

A fix might be to switch to an Arduino Mega or Leonardo and use hardware serial to talk to the LCD.
Logged

Send Bitcoin tips to: 1L3CTDoTgrXNA5WyF77uWqt4gUdye9mezN
Send Litecoin tips to : LVtpaq6JgJAZwvnVq3ftVeHafWkcpmuR1e

Central MN, USA
Offline Offline
Tesla Member
***
Karma: 73
Posts: 7189
Phi_prompt, phi_interfaces, phi-2 shields, phi-panels
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Can you use the hardware serial? You only need to disconnect lcd from it when you upload code but other times you are free to use the hardware serial for your serial lcd. Besides, with software serial, can you use higher baud rate on the parallax lcd? Higher baud rate makes data pass to the lcd controller faster and blocks the PWM generation less.
Logged


0
Offline Offline
Shannon Member
****
Karma: 206
Posts: 12092
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

My guess is that SoftwareSerial is disabling interrupts when it sends characters.  If the Servo library uses interrupts for timing this can cause significant errors in the pulses coming from the Servo library.  If you have an oscilloscope handy you can watch the serial line and servo pulses to see if they are interacting.

A fix might be to switch to an Arduino Mega or Leonardo and use hardware serial to talk to the LCD.

Its probably not explicitly disabling interrupts, just handling higher-priority interrupts which delay the handling of the Servo library interrupts...  You'd need to check the various interrupts priorities to see if that's true though.
Logged

[ I won't respond to messages, use the forum please ]

Offline Offline
Newbie
*
Karma: 0
Posts: 12
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I thought it might be something of this nature. I wish I had an oscilloscope, maybe for Christmas heh. The Arduino is constantly sending data to the computer on the robot through the USB, which I believe is also Tx0 and Rx0, are those the only hardware serials? Right now the baud is set to 9600, the LCD can go as high as 19200, I will give that a shot and see if it reduces or eliminates the twitches. But yes it makes perfect sense now, it must be interrupting the PWM causing pulses to be cut short and then the Sabertooth is responding to that. It looks like I might have to switch the Sabertooth to serial after all, uhg. Thank you guys so much for your input, I'll get back to this after my tests.
Logged

Central MN, USA
Offline Offline
Tesla Member
***
Karma: 73
Posts: 7189
Phi_prompt, phi_interfaces, phi-2 shields, phi-panels
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Try this:

Disconnect the serial LCD, but still run the program, at high software serial baud rate. This makes arduino output to software serial fast but you're not messing up your display. If at say 38400 or 57600 you stop seeing twitching then you need a serial LCD that can work that fast. Parallax lcd is not so fast.
Logged


0
Offline Offline
Shannon Member
****
Karma: 206
Posts: 12092
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

A somewhat devious suggestion:  clone a copy of SoftwareSerial, call it mySoftwareSerial or similar, and remove all the interrupt
disabling code from it.  It would only work reliably at lower baud rates, but wouldn't then interfere with the Servo library....

The code disabling/reenabling interrupts looks like this:
Code:
    uint8_t oldSREG = SREG;
    cli();
    ...
    SREG = oldSREG;

all you really need to do is comment-out the "cli();" lines...
Logged

[ I won't respond to messages, use the forum please ]

Pages: [1]   Go Up
Jump to: