0

So I have a program that works great on the Mega, it uses serial 3 to read and streams out to the USB (I posted a previous question which someone answered) I tried to use Serial (D0) to read and then write to serial, which did not work. So now I am looking in to Software Serials

Is there a difference between a real serial and software serial as it does not seem to be working, It all runs a bit slower

#include <SoftwareSerial.h>
const int DesiredRPM=300; // Setting Desired RPM Here.
const int MotorPWMPin=4;
int inByte = 0; // incoming serial byte
unsigned char Data_status=0;
unsigned char Data_4deg_index=0;
unsigned char Data_loop_index=0;
unsigned char SpeedRPHhighbyte=0; // 
unsigned char SpeedRPHLowbyte=0;
int SpeedRPH=0;
const unsigned char PWM4dutyMax=255;
const unsigned char PWM4dutyMin=100;
unsigned char PWM4duty=PWM4dutyMin; // have to set a default value make motor start spining
SoftwareSerial mySerial(10, 11); // RX, TX
void setup() {
 pinMode(MotorPWMPin, OUTPUT); 
 Serial.begin(115200); // USB serial
 Serial3.begin(115200); // XV-11 LDS data 
 // prints title with ending line break 
 Serial.println("Arduino Neato XV-11 Motor control board v0.1 by Cheng-Lung Lee"); 
 // Pick your magic number and drive your motor , 178 is 178/255*5V=3.49V
 analogWrite(MotorPWMPin, PWM4duty ); 
 mySerial.begin(115200);
}
void loop() {
 // if we get a valid byte from LDS, read it and send it to USB-serial
 if (Serial3.available() > 0) {
 // get incoming byte:
 inByte = Serial3.read();
 //Serial.print(inByte, BYTE);
 //Serial.write(inByte);
 Serial.print((char)inByte);
 decodeData(inByte);
 }
 if (mySerial.available() > 0) {
 // get incoming byte:
 inByte = mySerial.read();
 //Serial.print(inByte, BYTE);
 //Serial.write(inByte);
 Serial.print((char)inByte);
 decodeData(inByte);
 }
}
void decodeData(unsigned char inByte){
 switch (Data_status){
 case 0: // no header
 if (inByte==0xFA)
 {
 Data_status=1;
 Data_loop_index=1;
 }
 break;
 case 1: // Find 2nd FA
 if (Data_loop_index==22){
 if (inByte==0xFA)
 {
 Data_status=2;
 Data_loop_index=1;
 } 
 else // if not FA search again
 Data_status=0;
 }
 else{
 Data_loop_index++;
 }
 break;
 case 2: // Read data out
 if (Data_loop_index==22){
 if (inByte==0xFA)
 {
 Data_loop_index=1;
 } 
 else // if not FA search again
 Data_status=0;
 }
 else{
 readData(inByte);
 Data_loop_index++;
 }
 break;
 }
}
void readData(unsigned char inByte){
 switch (Data_loop_index){
 case 1: // 4 degree index
 Data_4deg_index=inByte-0xA0;
// Serial.print(Data_4deg_index, HEX); 
// Serial.print(": "); 
 break;
 case 2: // Speed in RPH low byte
 SpeedRPHLowbyte=inByte;
 break;
 case 3: // Speed in RPH high byte
 SpeedRPHhighbyte=inByte;
 SpeedRPH=(SpeedRPHhighbyte<<8)|SpeedRPHLowbyte;
 SpeedControl ( DesiredRPM ) ; // 
// Serial.print(SpeedRPHhighbyte, HEX); 
// Serial.println(SpeedRPHLowbyte, HEX); 
 break;
 default: // others do checksum
 break;
 } 
}
// Very simple speed control
void SpeedControl ( int RPMinput)
{
 if (Data_4deg_index%30==0) { // I only do 3 updat I feel it is good enough for now
 if (SpeedRPH<RPMinput*60)
 if (PWM4duty<PWM4dutyMax) PWM4duty++; // limit the max PWM make sure it don't overflow and make LDS stop working
 if (SpeedRPH>RPMinput*60)
 if(PWM4duty>PWM4dutyMin) PWM4duty--; //Have to limit the lowest pwm keep motor running
 } 
 analogWrite(MotorPWMPin, PWM4duty ); // update value
}
asked Nov 28, 2016 at 22:49

1 Answer 1

2

There are huge differences. The most important ones are:

  • SoftwareSerial is half duplex (it can send or it can receive, it cannot do both at once)
  • SoftwareSerial is blocking - while it is sending or receiving nothing else can happen

SoftwareSerial is very much a poor-man's serial port. It should only really be used for very low volume data (things like NEMA messages once a second or so) and only if you have absolutely no choice (and, let's face it, you always have a choice).

answered Nov 28, 2016 at 23:05
9
  • Ok thank you, damn I need 2 serial ports then. I read on the serial and send on to USB. Commented Nov 28, 2016 at 23:07
  • That is often the case. That is why Atmel came up with the "upgrade" of the ATMega328PB which has a second UART. Another good choice is the ATMega32U4 (as used on the Leonardo) which separates the USB from the UART so you can use both separately. Commented Nov 28, 2016 at 23:08
  • Oh brilliant, I only need it for this project, so I should get a Leonardo, hopefully it's smaller than the mega Commented Nov 28, 2016 at 23:10
  • It's the same footprint as the Uno. Commented Nov 28, 2016 at 23:10
  • Thanks you :) out of scope I know but any down point? Like not compatible with shield etc. Assuming the Leonardo uses serial1 Commented Nov 28, 2016 at 23:11

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.