Strategy help for robotics project

Hey guys, it's been a while since I was last here. My previous project got shelved after I struggled to find a solution to a problem but I am trying again to figure out what the best way forward would be now as I have recently designed and printed a body for the robot.

Concept:

I have built a tracked robot using the hardware listed below. It can drive around, look for obstacles, move it's head around, blink LEDs and make noises. It is currently being controlled through a Bluetooth module using an app on my phone. I haven't got all the code working at the same time in the same sketch yet but have tested all the ideas in separate sketches as a proof of concept and am satisfied that everything can work in harmony.. almost.

The idea is that when the robot is placed in a certain mode using the controller, the head will be fixed in orientation independent of the tracks moving around - kind of like a chicken. I will move two servos to pick a point with the controller (looking at something), then the HC-SR04 will determine the distance and will use the YAW data along with servo positions and distance to keep the head pointing at the object for as long as possible. Most of this is basic maths and is easy enough but my issue is taking data from the IMU accurately without limiting the duration of the loop.

Issues:

As you can imagine this brings up a few problems. If I want to go to another function in the loop that has a delay in it, that obviously messes with the data from the MPU6050. I have a number of sounds I am using through the piezo speaker which rely on delays and even telling the servo to move to a certain position seems to require a delay so we can wait for it to get there. Getting data from the HC-SR04 will further add to the complication as this will require yet another function with delays. So despite my best efforts (albeit with limited knowledge as a relative beginner) I cannot find a good way to use a single arduino for this project.

Possible Solution:

I have been looking into the possibility of using a second arduino (Nano) in order to read data from the IMU and have read a little about the I2C bus which seems like it's not a good option either as I would need 2 master devices. The only other thing I can think of is using SPI to communicate between the two Arduinos and I was wondering if this is possible?

I would need the Arduino Uno to be able to run all of the function as normal and when it needs information, it can request the YAW data from the second Arduino Nano which will simply give the Uno an angle. This might be needed maybe 10 times a second in one function in particular but would not be used at all in some of the other functions.

Am I completely barking up the wrong tree here? Any suggestions or examples on how this has been achieved would be awesome. I'm not looking for coding specifics here really, just possibilities to explore.

Hardware:

Arduino Uno R3
(Arduino Nano available but not currently being used)
Piezo Speaker
HC-SR04 Ultrasonic Sensor
2 x MG90S Servos
L298N Motor Controller
2 x 12v DC Motors
MPU6050 IMU
HC-06 Bluetooth Module

It sounds like you're going to have to lose the delays and use millis instead.

Check Robin2's sticky thread at the top of the page for details.

Thank you I will give that a read over. If it’s possible without a second Arduino that would be pretty awesome!

Ok so it seems this is a classic case of knowing what the right question to ask is. I had never even considered using code this way but after reading a number of posts and watching countless YouTube videos on the subject - I can see this will open up a whole world of programming options so thank you for pointing me to that wildbill!

I have started with what I think is the most important element to get right and that is the IMU data and will gradually add functions around that so I can keep an eye on it’s accuracy as I go. I managed to get a light blinking in sequence (something I previously thought impossible!) which is not a lot to some people but a whole leap for me.

I thought I would take it a step further and see if I could also get a ping distance function to work with the HC-SR04 and it does kind of work but it seems to be timing out at around 30cm (rated for up to 400cm I believe) and when that happens it is slowing the code down - seems to be causing stuttering in the rest of the code? It’s a work in progress but this is what I have so far for my distance measurement:

float elapsedTime, currentTime, previousTime, currentMicros;
unsigned long HSPreviousTime;
unsigned long HSTrigInt = 2;
byte HSStart = 1;
byte HSLoopCount = 0;
float duration, distance;
const byte Trig = A4;

void getDistance() {

  //start the process of getting the ping
  if (HSStart == 1)
  {
    digitalWrite(Trig, LOW);  // Added this line
    HSStart = 0;
  }
  //wait 2 micros the first time then 10 micros  the second time
  if (HSLoopCount <= 2)
  {
    if (currentMicros - HSPreviousTime >= HSTrigInt)
    {
      //now set the trig pin opposite
      digitalWrite(Trig, !digitalRead(Trig));
      HSPreviousTime += HSTrigInt;
      //once high, it needs to start that way for 10ms
      HSLoopCount++;
      HSTrigInt = 10;
    }
  }
  else
  {
    //the previous loop has ran twice and this is the third time round
    //reset the counter and find the distance from the ping
    duration = pulseIn(Echo, HIGH);
    distance = duration / 58;
    Serial.print(", ");
    Serial.println(distance);
    HSLoopCount = 0;
    HSTrigInt = 2;
  }
}

I’ve cut the fat out to get the the meat of what I am taking about but obviously have setup pin modes etc for each of the pins involved. Just wanted to post the bit that is causing problems and see if anyone has any thoughts?

Thanks again for taking the time to read and as always any help, critique or guidance is most appreciated.

Pulsein has a timeout, so it's going to block, which likely swamps your use of micros to speed things up on the occasions it can't see anything.

Strangely enough I found some code online that is trying to achieve the same thing but is using a slightly different technique and this seems to be working somewhat… not sure why. If you know of any other ways it can be done I would appreciate a pointer in the right direction. Will keep tinkering and reading what I can :slight_smile:

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.