3

I have a code sample that uses serial3 (RX3 on a Mega) which I want to try and get working on a Uno. It reads on RX3 and streams to USB. What I had read, you use Serial for RX0, however Serial seems to be used for USB

 /*
Arduino Neato XV-11 Laser Distance Scanner 
Motor control board v0.2 by Cheng-Lung Lee

XV-11 LDS adapter reads LDS data from RX3 then relay to TX. Also extract the speed 
data from the data stream to do speed control on LDS motor. Everythin can power 
from USB no extra power required.

Change log:
V0.2 Add simple speed control code update PWM 3 times per rev.
V0.1 Opend loop control version.

This code is tested on Arduino Mega 1280
I/O:
Motor drive by low side driver IPS041L connect to PWM Pin4, Motor power from 5V
Neato XV-11 LDS Vcc(red) : 5V
Neato XV-11 LDS TX(Orange) : RX3

 */


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

 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 );  
}

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);
  }

}

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
}
  • 1
    UNO only has one hardware UART, hence only one Serial, which is linked to USB, but you could still use it for something else by connecting to directly to D0 & D1. However, if you need 2 UART then go for SoftwareSerial. – jfpoilpret Nov 27 '16 at 21:21
  • Thank you, so I need to read on 1 serial (lidar) and stream to the USB? – Burf2000 Nov 27 '16 at 21:21
  • If you need only RX on one side (lidar) and only TX on the other side (USB), then that should work, provided both links work at same speed and settings (parity...) Also you must ensure that USB won't receive anything otherwise you would get it and confuse it with lidar input. – jfpoilpret Nov 27 '16 at 21:24
  • Oh great thats awesome, maybe post that as the answer. So I am fine to read from RX0 and write to Serial (USB) – Burf2000 Nov 27 '16 at 21:26
3

Arduino UNO only has one hardware UART, hence only one Serial available, which is linked to USB, but you could still use it for something else by connecting directly to D0 & D1.

However, if you need 2 separate, independent, UART then go for SoftwareSerial for the second one.

Now, if you need to connect 2 devices, one to exclusively get data from, the other exclusively to send data to, then you can use just one UART, i.e. Serial for both devices, as long as both links work at the same speed and settings (parity...)

Also you must ensure that USB won't receive anything otherwise you would get it and confuse it with input from the first device.

The non USB device providing input to the Uno should be connected to D0 (RX).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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