Sonar modules are notorious for pulling so much instantaneous power during their brief pulses that they often reset the processor, causing the Arduino to start all over from the beginning.
Do you have any way of knowing whether your program is executing more-or-less normally, or if your program in the Arduino is getting reset?
If not, you need better debugging tools.
(tangential rant about debugging tools)
Many people debug by sprinkling their code with print(F()) statements that get sent to a LCD screen or a serial port.
Other people debug by sprinking their code with statements that turn on and off a series of LEDs of various colors, or at least a single LED with a (hopefully easy-to-decode) blink code.
Some kinds of problems are much easier to track down with an oscilloscope.
dealing with high-current pulses
My best guess is that the sonar is pulling very brief high-current pulses from the battery, which causes the battery voltage to droop low enough to reset the Arduino.
When the USB cable is plugged in, (I'm guessing that) the additional power supplied by the USB cable somehow keeps the Arduino from resetting.
Many sonar modules (very briefly) pull 1 A or 2 A, far more than a USB cable or a handful of AA batteries can supply.
There are many ways to solve that problem, but if I were you I would first see if that is really the problem in this case.
Possibly the quickest way to tell is:
- Use at least 2 separate battery packs.
- Hook all the grounds of all the battery packs and all the devices together.
- hook the positive power of one battery pack to the Arduino and nothing else.
- Hook the power lead of all the other devices to some other battery pack (ideally a different battery pack for each device).
Then run the test again.
This should give you a clue as to whether the problem is the Arduino seeing power-supply droop (which separate battery packs should "fix"), or something else.
If the problem really is power supply droop, there are a variety of ways to fix it:
- (a) Many people recommend: use a large 1000 uF capacitor directly across the power pins of the sonar, and a 10 Ohm or 100 Ohm resistor between the battery positive and that capacitor. (a) (b) (c) (d) (e) (f)
- (b) Use a large capacitor directly across the power pins of the Arduino, and a diode from the battery to that capacitor so that normally the diode allows the battery to charge the capacitor, but when the sonar or whatever briefly drags the battery voltage to a low level, the diode blocks the sonar from pulling energy "backwards" out of that capacitor, and the capacitor is large enough to run the Arduino during the sonar pulse.
- (c) Get a dedicated "logic" battery array to power the Arduino and a few LEDs, etc., and a separate (often much larger) "dirty power" battery array to power the sonar, motors, etc.