Wall avoiding ATtiny2313 Robot motor stopping randomly (Solved)

Using an ultrasonic sensor and 2 motors and an ATtiny2313 and a few other small components I made a small wall avoiding robot which turns away from walls, what its supposed to do is as the detected range gets lower than a certain value, (here its 10), then one motor stops which would let the robot turn away from the wall.

But for some reason, the motor which is supposed to stop only when it detects a wall is stopping randomly every few seconds even when there is no wall.
So its basically stopping when there is nothing in front of it making the robot turn, but when it does detect a wall it surely stops, so I want to make it stop stopping randomly which makes the robot almost go in circles at times.

The hardware is I have connected the 2 motors to a 9V battery with 2 transistors(NPN) which connect to 2 resistors(1K) which connects to pins on the ATtiny2313.
The ATtiny2313 however is powered off another 9V battery which is regulated by a voltage regulator to 5V and the ultrasonic sensor is powered off the ATtiny2313 itself (Connected parallely to ATtiny2313 5V supply line and the voltage regulated 5V supply line)

I am not sure if there is a problem with the code or with the hardware, I replaced the transistors and the motors with new ones but the same results :frowning:
So I am guessing that there is a problem with the code and its not working perfectly

Can anyone have a look at it and tell me whats wrong with it

Thanks

This is the code I am using:

#include <Ultrasonic.h>

int RELAY = 9;  // RELAY Pin. 
int RELAY2 = 7;
int TRIG = 11; // Trigger Pin
int ECHO = 10; // Echo Pin
int Range; // The range of the object from Ping Sensor
int Dist; // The Distance value

Ultrasonic ultrasonic(TRIG,ECHO); // Create and initialize the Ultrasonic object.

void setup() {
  pinMode(RELAY, OUTPUT); //To the relay via the transistor
  pinMode(RELAY2, OUTPUT);
  Dist = 10; //The distance in inches. Change this for increasted or dicreasted range.
}

void loop() {
  //Range = ultrasonic.Ranging(CM); // Range is calculated in Centimeters.
  Range = ultrasonic.Ranging(INC); // Range is calculated in Inches.
  
  if (Range > Dist) {
    digitalWrite(RELAY, HIGH);
    digitalWrite(RELAY2, HIGH);  
  } else if (Range < Dist) {
    digitalWrite(RELAY, LOW);
    digitalWrite(RELAY2, HIGH);
     delay(500);
  }

}

Since the code is for ATtiny2313, its limited.

Hi,

  1. What transistors are you using, and are they driving the motors directly, or via relays as suggested by the code?

  2. Did you connect flyback diodes across the motors/relays?

  3. What is the purpose of RELAY2? You only ever write HIGH to it.

  4. Where did you download the Ultrasonic library from?

The code looks OK to me, so I suspect the ultrasonic sensor/library may be reporting spurious reflections, either from the floor or due to noise pickup from the motors, or possibly a bug in the library. Some suggestions:

  • Try angling the ultrasonic sensors up a little so they don’t see the floor.

  • Keep the motor wiring away from the ultrasonic sensor wiring. In particular, use separate ground wires from the Arduino to the sensor, and from the Arduino the its battery and the motor or relay system.

  • Try changing the code so that you need to read range < dist a few times (with a delay of a few ms between calls) before you decide there is a wall and stop the motor.

I am not using any relays and I I did connect flyback diodes and the reason I have relay 2 is if I connect it directly to the battery its spins faster than relay1

I downloaded the ultrasonic library from I dont really rememebr where

When I take the ultrasonic sensor in front of an AC, then the force or air seems to distort the motors a little.

So I am guessing its the ultrasonic sensor

Can you tell me how to change the code so that it checks a few times before deciding if there is a wall to stop it as this thing will probably make it work perfectly!

void loop() {
  static int sensorCount = 0;

  Range = ultrasonic.Ranging(INC); // Range is calculated in Inches.
  
  if (Range > Dist) {
    digitalWrite(RELAY, HIGH);
    digitalWrite(RELAY2, HIGH);
    sensorCount = 0;  
  } else {
    ++sensorCount;
    if (sensorCount = 5)      // turn if we sense a wall 5 times in a row
    {
      digitalWrite(RELAY, LOW);
      digitalWrite(RELAY2, HIGH);
      delay(500);
      sensorCount = 0;
    }
    else
    {
       delay(20);   // wait 20ms before testing the range again
    }
  }
}

The values of 5 for the maximum count and 20ms for the delay between ranging are just guesses.

That helped a little bit as the amount of times it stops in a certain time interval has dropped but it still happens occationally

dc42:

    if (sensorCount = 5)      // turn if we sense a wall 5 times in a row

You'll want "==" rather than "=" here.

kelvin31415:

dc42:

    if (sensorCount = 5)      // turn if we sense a wall 5 times in a row

You'll want "==" rather than "=" here.

Good catch! I mostly program in a language in which "=" really does mean equality, and when I do use C/C++, I always use compilers with sensible warning settings that complain about such constructs. Unfortunately, the Arduino IDE suppresses all compiler warnings by default (a reckless thing to do IMO).

Oh! Ok back to uploading the code again, hopefully it will work this time :slight_smile:

I just have another small question, now both motors work as they should and all but 1 motor is just a little bit faster than the 2nd one so it kind of tends to curve instead of going in a straight line, is there anything I can do to reduce the speed of the motor a little? like maybe add a resistor in series with it or something? Im not exactly sure...
Thanks!

Adding a resistor in series with the faster motor will reduce its speed, but will also reduce its starting torque, so it will make the motor slower to start up that the other one. If the faster motor is driven from a PWM pin, then a better solution may be to use PWM to slow the faster motor down a little. Just do analogWrite(pin, 250) instead of digitalWrite(pin, HIGH) to it.

It might not be the motors that are different, it might be the transistors driving them. What transistors are you using, and what value base resistors are you using with them? Do you know the stall current of the motors, or their DC resistance?

The motor which needs to be slowed down is connected to pin 9 of the ATtiny2313 so I dont think that pin can be used for analogue commands, changing the pin is a problem as i have glued the whole thing onto a support and its really hard to get it out :frowning:

So if that pin supports PWM then its fine.

I am using the same transistors for both of them with a 1k ohm resistor on the base for both of them. I dont know the stall current sorry nor the DC resistance :frowning:

And by the way the motor stopping problem has been cleared completely! It does not do it anymore as soon as I changed the = to == as you said :smiley: Thanks!

vishalapr:
I am using the same transistors for both of them with a 1k ohm resistor on the base for both of them. I dont know the stall current sorry nor the DC resistance :frowning:

Yes, but WHAT transistors? 1K may be too low a value ensure that they are turned on fully.

They are these NPN transistors:
2N3904 NPN Transistors, http://www.ebay.com/itm/2N3904-NPN-2N3906-PNP-General-Purpose-Transistor-x-50-/400268734918?pt=LH_DefaultDomain_0&hash=item5d31e031c6

Which pins on the ATtiny2313 have PWM capability?
Thanks

OK, those transistors are not very suitable for driving motors because they are intended for lower currents. You would be better to use something like BC337 that is designed for more current. But in either case, 1K is too high a value for the base resistors. Try reducing them to about 220 ohms, but don't go below 100 ohms. You may find that with the lower value, the motors run faster and more evenly. Also the transistors may run cooler.

The pins that support PWM on the attiny2313 are physical pins 14, 15 and 16 on the chip. How these map to Arduino pin numbers depends on the core you are using.

My Motor is connected to pin 9 and I used the analogue Write command on it and it seemed to work :smiley:
Now everything is working and it runs smoothly!

(I also changed the resistor to 270 Ohms)

Thanks for all the help

From next time I will be using BC337 transistors for other motor projects, and I think that those 3 pins support like PWM input whereas output is supported by most of the pins, Thanks for all the help!

btw BC337 is only suitable for driving small motors (up to ~500mA) - which yours must be, otherwise your 2N3904s would not have survived. For up to ~1A you can use ZTX851. For higher still, you need a mosfet (for an SMD design, mosfets are good for lower currents too).