Arduino Model Limitations

Evening all

I’m building an autonomous rover and am wondering about the limitations of each model of Arduino and when to split tasks.

Right now I am working with both a Uno and Mega 2650 and need to run:

  1. GPS
  2. Magnetometer
  3. Motor controllers (two motors)

I have both the magnetometer and a motor working together off a single board (either uno or mega), the serial monitor shows correct GPS values and the motor does as instructed.

Things get confusing when I try to add the GPS to the same board as both GPS and magnetometer are using Port 4, 9,600 board rate, and I either get perfect compass reading but no GPS or mashed up GPS.

I can (and probably will) just use a USB GPS device, but this has left me wondering if such a task is better split over two boards, or whether it would be best on one? Is this just a problem of timings?

The Mega has 3 extra hardware serial ports (besides the USB connected port). Can't the GPS use one of those?

What is “Port 4”?

sterretje:
What is "Port 4"?

in very basic, crude terms. a port is typically a group of 8 I/O pins that are common to a byte in the chip. think physical pins, but also sorta-kinda like a shift register. ( exactly like a shift register ? )

[snip]

edit : port manipulation

@dave-in-nj

The ports that you describe don't have baudrates :wink: OP's port 4 has so I have no idea what he/she is talking about and hence the question.

sterretje:
@dave-in-nj

The ports that you describe don't have baudrates :wink: OP's port 4 has so I have no idea what he/she is talking about and hence the question.

ah... portA, portB.... where does port 4 come in ?
is he doing weather ? boating.... sometimes one is just looking for any port in a storm....

Maybe he is using the 4th set of serial pins and calling that port 4 ?

Yeah, actually that was a bit of a poor description, soz...

“What is port 4?”

Fair question. Though please bear in mind that I’m a relative newbie. Having been doing this first project for a couple of months now, I am quite happy with how far I have come with it so far. Try not to be too crushing :wink:

What I meant was that the board is connected to COM4. As far as I understand the GPS and compass, their results can be streamed to the serial monitor for real time viewing. So when I fire up the serial monitor for either GPS or compass individually, I get valid results. When I combine the two working sketches into a single sketch and fire up the monitor to check results, they are mashed up. Typically I am getting reliable compass values, but gibberish (or no results) from the GPS.

This is why I was asking about splitting the load; would it be better to have the GPS and compass on different boards? I don’t actually think so as I have seen designs for many automated rovers and they all seem to work off a single Uno.

Is this making any sense yet?

Would this make more sense with code?

Please tell us exactly what GPS and compass modules that you have. Tell us how they are wired to the Arduino. Which Arduino?
Like I said the Mega has more serial ports. A schematic and photos will help us to know your project.

Post the code that you have that does not work.

We cannot help with what we cannot see.

Yep, apologies again. I was on my mobile phone and the laptop strapped to the Arduino is away in the conservatory (due to my not getting a GPS signal in the house).

I’ll bring in the laptop shortly and post some clearer information. Thanks for your patience.

Hardware:

Arduino Mega 2560
GPS: U-Blox Neo-6M
Compass: GY-271
Motor Controller: Cytron MD10C
Motor:12VDC

The Cytron is strapped directly to a 12VDC motorcycle battery, Arduino is pulling power from laptop USB, rough schematic attached.

The following code runs the compass fine, valid output in Serial Monitor. It also runs a couple of basic commands on the motor:

#include "CytronMotorDriver.h"

#include <Wire.h> //I2C Arduino Library

#define addr 0x0D //I2C Address for The HMC5883



// Configure the motor driver.
CytronMD motor(PWM_DIR, 3, 4);  // PWM = Pin 3, DIR = Pin 4.


// The setup routine runs once when you press reset.
void setup() {

Serial.begin(9600);
  Wire.begin();


  Wire.beginTransmission(addr); //start talking
  Wire.write(0x0B); // Tell the HMC5883 to Continuously Measure
  Wire.write(0x01); // Set the Register
  Wire.endTransmission();
  Wire.beginTransmission(addr); //start talking
  Wire.write(0x09); // Tell the HMC5883 to Continuously Measure
  Wire.write(0x1D); // Set the Register
  Wire.endTransmission();
}


// The loop routine runs over and over again forever.
void loop() {
  motor.setSpeed(64);  // Run forward at 25% speed.
  delay(50);
  
  motor.setSpeed(128);  // Run forward at 1/8 speed.
  delay(50);

  motor.setSpeed(0);    // Stop.
  delay(3000);

  motor.setSpeed(-64);  // Run backward at 1.5% speed.
  delay(50);
  
  motor.setSpeed(-128);  // Run backward at full speed.
  delay(200);

  motor.setSpeed(0);    // Stop.
  delay(1000);

//Compass


  int x, y, z; //triple axis data

  //Tell the HMC what regist to begin writing data into


  Wire.beginTransmission(addr);
  Wire.write(0x00); //start with register 3.
  Wire.endTransmission();

  //Read the data.. 2 bytes for each axis.. 6 total bytes
  Wire.requestFrom(addr, 6);
  if (6 <= Wire.available()) {
    x = Wire.read(); //MSB  x
    x |= Wire.read() << 8; //LSB  x
    z = Wire.read(); //MSB  z
    z |= Wire.read() << 8; //LSB z
    y = Wire.read(); //MSB y
    y |= Wire.read() << 8; //LSB y
  }

  // Show Values
  Serial.print("X Value: ");
  Serial.println(x);
  Serial.print("Y Value: ");
  Serial.println(y);
  Serial.print("Z Value: ");
  Serial.println(z);
  Serial.println();

  delay(500);


  
}

So this is a basic PoC, the bot can steer according to very basic instructions and knows which way it’s heading.

What I wanted to add next is the GPS so that it knows where it is. This very simple sketch works on its own, but when I add it into the main sketch and run the Serial Monitor, I get a lot of nonsense.

void setup()
{
  Serial.begin(9600);
  Serial.println("uBlox Neo 6M Test");
  Serial1.begin(9600);
}

void loop() // run over and over
{
  if (Serial1.available())
     Serial.write(Serial1.read());
}

Can anyone see why?

** Full disclosure**

What I am trying to create is a basic chassis for an automated rover that will run up and down fields. This can be put to a variety of tasks such as lawn mowing, seed sewing, ploughing, ground scanning, measuring, etc, etc depending on what is strapped onto it.

Phase 1 is just to get the electronics sorted out.

There is a lot to learn here and to a beginner such as myself, there is some complicated stuff to bend my head around. Ideally, I would like to be able to import boundaries from Google Earth so that it knows where it is, turn it on and let it go to work. I do understand the (in)accuracy of GPS (I’m a mountaineer in my spare time and use GPS a lot) and will invest in a more accurate (RTK) solution to this if it proves successful, but that is a lot further up the road. Calculating a path, following it, performing a U-turn and following a parallel path back whilst trying to achieve a high degree of accurate saturation is daunting, but I am taking this in bite sized chunks.

I wouldn't rely on Google Earth for that, they're easily several meters off if not worse, and you're suddenly moving your neighbour's prized orchids instead of your own grass.

Getting a rover move in a more or less straight line is quite doable on smooth ground using encoders in the wheels with a compass as backup reference. On rough ground the encoders become quite useless, and you will have to rely on the compass while constantly adjusting the wheel speed to keep the thing going straight. I'd suggest you to get that part working first. Gonna be a serious challenge.

Next you can think about having the thing make a u-turn, in a way that it ends up in a parallel path, slightly overlapping to not leave lines of grass standing. That's going to be another serious challenge.

Another concern, as you're talking about ploughing, you must be thinking of a pretty big and powerful rover. Those things are inherently dangerous, if they can plough a field they will have no problem ploughing a person or an animal. The other applications can be done with much smaller, less dangerous contraptions. Remember, it's not a question of whether they will run out of control, but when they will run out of control, and that's not just while testing.

Please show your sketch where you integrate the GPS in the main sketch.

OP's schematic

Why are you feeding the Neo-6M from the Vin?

Hi,
Is there a reason you are not using a hmc5883 arduino library?

google

hmc5883 arduino library

Tom... :slight_smile:

wvmarle: I’m really not that troubled by any of the points you raise, they can be overcome to a workable extent.

  1. I’m not relying on google earth (though I will ask if you can suggest a better alternative?), I’ll employ failsafes.

Let’s say I want to cover a 100m x 100m field and there is a ditch enclosing it. Obviously I don’t want my bot to end up in this ditch and there’s a + / - 5m GPS accuracy, so I would plot the boundary as 90m x 90m (or even 10x10, then do it in pieces).

  1. Please bear in mind that this is a primitive prototype, for rough ground I would scale up and probably employ a quad bike or even a Land Rover and utilise an RTK system coupled with wheel angle sensors and an inclinometer. It’s never going to be perfect, but (with repeated passes) good enough.

I do agree that it’s going to be a challenge, but not insurmountable.

  1. U-turning. Yes, another challenge, already acknowledged.

  2. Danger of it running out of control. That’s a very fair point and perhaps the most significant. Above all, I don’t want to see anything get hurt. However, have a look at agopengps, these guys are running fleets of fully stacked tractors using a basic Arduino circuit and obtaining incredibly accurate results.

I really wanted to leverage agopengps against my own project and have talked with the developers, but it’s not suited to my current requirements as it’s designed to work with very large vehicles. I just couldn’t get it working properly so thought it better to work from the bottom up.

For my purposes, right now it doesn’t have to be anything close to perfect, things can be refined once I have a better understanding of things. As I say, one step at a time.

sterretje: I’ll post the sketch shortly, am not in front of laptop right now.

Good spot on the Vin, mistake on my part. For some reason I thought this was a second 3.3v supply, but I’ve just read up and see how wrong I am. I’ll change to 5v (though oddly it does work fine off the VIN).

Tom: that sounds like a very loaded question!! I will indeed google this later this evening and no doubt realise my folly.

Thanks all :slight_smile:

Hi

bluerabbot:
these guys are running fleets of fully stacked tractors using a basic Arduino circuit and obtaining incredibly accurate results

don’t they have some kind sensor at each end of each ‘run’ for the tractors to travel between between the two points?

Peter

Nope, a variety of solutions are employed, but not that. RTK stations are common, one mounted at a fixed position and one mounted on the tractor. They are getting CM accuracy.

sterretje:
Please show your sketch where you integrate the GPS in the main sketch.

This is the sketch with the GPS code:

 #include "CytronMotorDriver.h"

#include <Wire.h> //I2C Arduino Library

#define addr 0x0D //I2C Address for The HMC5883



// Configure the motor driver.
CytronMD motor(PWM_DIR, 3, 4);  // PWM = Pin 3, DIR = Pin 4.


// The setup routine runs once when you press reset.
void setup() {

Serial.begin(9600);
  Wire.begin();


  Wire.beginTransmission(addr); //start talking
  Wire.write(0x0B); // Tell the HMC5883 to Continuously Measure
  Wire.write(0x01); // Set the Register
  Wire.endTransmission();
  Wire.beginTransmission(addr); //start talking
  Wire.write(0x09); // Tell the HMC5883 to Continuously Measure
  Wire.write(0x1D); // Set the Register
  Wire.endTransmission();


//GPS


  Serial.begin(9600);
  Serial.println("uBlox Neo 6M Test");
  Serial1.begin(9600);
}


  



// The loop routine runs over and over again forever. Turn Left
void loop() {
  motor.setSpeed(-128);  // Run forward at 25% speed.
  delay(1300);
  
 // motor.setSpeed(128);  // Run forward at 1/8 speed.
 // delay(00);

  motor.setSpeed(0);    // Stop.
  delay(3000);

  motor.setSpeed(128);  // Run backward at 1.5% speed.
  delay(1300);
  
 // motor.setSpeed(-128);  // Run backward at full speed.
 // delay(200);

  motor.setSpeed(0);    // Stop.
  delay(1000);

//Compass


  int x, y, z; //triple axis data

  //Tell the HMC what regist to begin writing data into


  Wire.beginTransmission(addr);
  Wire.write(0x00); //start with register 3.
  Wire.endTransmission();

  //Read the data.. 2 bytes for each axis.. 6 total bytes
  Wire.requestFrom(addr, 6);
  if (6 <= Wire.available()) {
    x = Wire.read(); //MSB  x
    x |= Wire.read() << 8; //LSB  x
    z = Wire.read(); //MSB  z
    z |= Wire.read() << 8; //LSB z
    y = Wire.read(); //MSB y
    y |= Wire.read() << 8; //LSB y
  }

  // Show Values
  Serial.print("X Value: ");
  Serial.println(x);
  Serial.print("Y Value: ");
  Serial.println(y);
  Serial.print("Z Value: ");
  Serial.println(z);
  Serial.println();

  delay(500);


// GPS

  if (Serial1.available())
     Serial.write(Serial1.read());

}

This is a very basic GPS sketch and I realise that I will have to format the output at some stage, but when I run a SM on the connected COM port, the compass results and GPS output are mashed up as per below.

uBlox Neo 6M Test
21:27:17.664 -> X Value: -1076
21:27:17.699 -> Y Value: 1422
21:27:17.699 -> Z Value: -335
21:27:17.699 -> 
21:27:18.176 -> )X Value: -1078
21:27:24.845 -> Y Value: 1437
21:27:24.845 -> Z Value: -347
21:27:24.878 -> 
21:27:25.326 -> ⸮X Value: -1073
21:27:31.995 -> Y Value: 1427
21:27:32.041 -> Z Value: -342
21:27:32.041 -> 
21:27:53.959 -> bX Value: -1066
21:28:00.675 -> Y Value: 1440
21:28:00.675 -> Z Value: -342
21:28:00.675 -> 
21:28:01.153 -> ⸮X Value: -1076
21:28:07.819 -> Y Value: 1447
21:28:07.819 -> Z Value: -340
21:28:07.819 ->

Is there some other output for the GPS stream, some way to separate it from the compass?

what are you trying to read from the GPS? it looks like you just take what you get. I see no effort to parse the data

have you tried using the TinyGPSPlus library, and getting just the longitude and latitude?

Correct, that's exactly what I am doing at this stage; taking what I get.

As stated exhaustively, this is a proof of concept built by someone with about 2 months of Arduino exposure. I had tried to adapt someone else's code, but I couldn't get it working. Naively, I had hoped that Arduino was simply a case of buy the right hardware, plug in the right wires, modify a bit of code and the job's a carrot, but this is not the case, so I am learning from the bottom up.

In this case, I am taking everything in simple steps: first confirm that the hardware works, then start adding bits.

Yes, I did try TinyGPS and it parsed the data much better: I saw valid compass results separated from GPS fields, but absolutely no data populated in those fields. The GPS was left running overnight and saw no satellites (testing with u-centre). I put in the simple, raw, unparsed GPS sketch and immediately got a fix, so I thought I would try to use this working sketch for now in my overall sketch just to see if it worked.

It doesn't.

I am trying to understand why.

Sounds like you're suggesting I re-try TinyGPS; I'll give it a shot and get back with results.

And there it is again.

Tried using TinyGPS and I get really nice formatting with no data. Try that simple sketch and immediately get a GPS fix.

I’m thinking I’ll bypass this problem for now as I’m just getting bogged down in details and making no progress. USB will do the job.