{Solved} PPM signal incorrect timing with 9v battery source

Hi all,

first time poster here. I’ve searched high and low for someone who has had the same problem but perhaps I’m using the wrong queries…

Problem summary: PPM pulse position output from Servo library is correct when the Arduino is powered with 5v USB from PC, but incorrect when powered with any other source (inc. 9v battery, 5v USB battery bank, 5v wall chargers).

I am attempting to use an Arduino Uno to interface between an NRF24L01+PA+LNA with breakout adapter to stepdown to ~3.3v, and two VESC brushless motor controllers. There are two PWM outputs, Uno pins 3 and 5.

I have successfully executed my code for transmitting/receiving servo PWM with the Arduino and NRF24L01 circuits powered from my PC USB port. I have verified using the VESC tool that the pulse ranges from approximately 1.2ms to 2.2ms. This corresponds to the nominal 1000-2000 microsecond PPM min-max from servo.attach(pin#, min, max), as in:

Servo ESCl;
ESCl.attach(5,1000,2000);

However, when I power the Arduino through the Vin pin with 9v, the PPM from VESC_tool is 18-19ms.

I still have full authority of the PPM range when powered from a 9v battery. As in, when I have the transmitter throttle set to low: on USB 5v I have 1.2ms, and on 9v I have 19ms.

With throttle set to high: on USB 5v I have 2.2ms, and on 9v I have 18ms.

This suggests that the Arduino-radio interface is working correctly, however the Arduino PWM timing output is bogus when I am not using my PCs 5v USB to power the Arduino.

I get the same result (18-19ms ) when I power the Arduino using a 5v USB battery bank, or wall wart (phone charger). The only success I have is powering through the USB 5v from my PC.

I am not using the BEC from the VESC to power the Arduino at the moment because it seems that it cannot provide enough current to adequately power the radio module. Also, the brushless motors are powered by an independent 11.1v lipo battery (and not the 9v battery or 5v sources powering the Arduino and radio).

The transmitter code transmits a 2-tuple of integers from 0-180 corresponding to the left motor and right motor. The receiver code reads the 2-tuple and writes the servo PWM where 0 = min and 180 = max to the VESC motor controllers.

Can anyone suggest what might be the problem?

edit 1 - formatting
edit 2 - changed PWM to PPM since the servo library and ESCs use pulse position, not PWM.

#include <Servo.h>
#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
#define CE_PIN 9
#define CSN_PIN 10
const byte thisSlaveAddress[5] = {‘2’,‘f’,‘R’,‘O’,‘T’};
int dataReceived = {0, 0}; // this must match dataToSend in the TX
bool newData = false;
int losscount = 0;

Servo ESCl;
Servo ESCr;
RF24 radio(CE_PIN, CSN_PIN);

void setup() {
radio.begin();
radio.setAutoAck(false);
radio.setDataRate( RF24_250KBPS );
radio.setPALevel(RF24_PA_LOW);
radio.openReadingPipe(1, thisSlaveAddress);
radio.startListening();
ESCl.attach(5,1000,2000); // changed to pin 5 (was 3 on Uno)
ESCr.attach(6,1000,2000); // changed to pin 6 (was 5 on Uno)
// Serial.begin(9600);
}

void loop() {
getData();
showData();
}

void getData() {
if ( radio.available() ) {
radio.read( &dataReceived, sizeof(dataReceived) );
newData = true;
losscount = 0;
}
else {
losscount += 1;
if ( losscount > 10000){
dataReceived[0] *= 0.9;
dataReceived[1] *= 0.9;
ESCl.write(dataReceived[0]);
ESCr.write(dataReceived[1]);
// Serial.print(dataReceived[0]);
// Serial.print("\t");
// Serial.println(dataReceived[1]);
delay(50);
newData = false;
}

}

}

void showData() {
if (newData == true) {
// Serial.print(dataReceived[0]);
// Serial.print("\t");
// Serial.println(dataReceived[1]);

    ESCl.write(dataReceived[0]);
    ESCr.write(dataReceived[1]);
    newData = false;
}

}

I removed the else statement in getData() because I thought that constantly rewriting the servo PWM every iteration might be overwhelming the signal if it is kept at a constant pulsewidth.

However that made no difference.

I am currently powering the Arduino from a 5v 2A wall wart via USB, and getting the erroneous pulsewidth range of 18-19 milliseconds. The golden config is powering using my PC USB ports, which works every time but is unsuitable for the remote-controlled application.

Very confusing. What is “the VESC tool”? attach(pin,1000, 2000 corresponds to 1ms to 2ms. Where does the extra 0.2ms come from.

But first - when you are using the external power sources do you have all grounds connected, Arduino, ESCs, radio etc? What is the input to the “breakout connector”. A schematic (not a Fritzy) would probably be useful

Steve

Hi,
What sort of 9V battery, if a smokedetector battery, forget them, they cannot provide the current or the life that your project demands.

When you use the external 5V supplies, not the PC, where do you connect them?
Can you please post a link to specs/data of your hardware, including the servo?

Thanks… Tom… :grinning: :+1: :coffee: :australia:

VESC tool is an open source software for interacting with electronic speed controllers (Vedder ESC).
I have two VESC-based ESC’s (ESC’s), which each drive one brushless DC motor. The power to the VESC and motors is supplied from a 11.1v battery.

The VESC tool allows me to observe the pulsewidth of the VESC input signal, i.e. the output signal from the Arduino.

I am reasonably sure that all of the grounds are connected. If I unplug the USB from my PC and directly into a wall wart (without unplugging the cable from the Arduino), I get different signal behavior.

I don’t know where the extra 200 microseconds come from, could be latency in the VESC hardware or the Arduino not exactly creating a perfect square wave. Unfortunately I don’t have access to an oscilloscope to observe the actual Arduino signal output.

Here is the VESC tool showing 1.7ms timing (i.e. 50% throttle, halfway between 1.2 and 2.2ms) powered from my PC.

And the same exact configuration except plugged into a 5v 2.4A battery bank showing ~18.4 ms (same 50% throttle, halfway between max pulsewidth of 18.9ms and min of 17.9)

The breakout board has an AMS1117 to output 3.3 volts to the radio module. The inputs are 5-12v DC and ground, and SPI pins (which are passthrough to the radio module) CE, CSN, SCK, MISO, MOSI. My troubleshooting indicates that the radio module is still working, because I can control the signal between 17.9 and 18.9ms using the transmitter.

My apologies but I don’t know what a Fritzy is. Here is a rough sketch of the electronics. I should note that the transmitter which is very similar to the receiver, has had no issues being powered from 9v battery (like from a smoke detector) for long periods of time. Nevertheless the issue persists with any other power source other than my PC usb for the receiver.

When the Arduino is powered from USB the battery is omitted and the radio module takes its input from either Vin (Raw) or Vcc (5v). This schematic is drawn showing a Sparkfun Pro Micro, but I have two identical setups with genuine Arduino Unos and they exhibit exactly the same behavior.

Additional information:

There are numerous examples of people using Arduinos to control VESC for electronic skateboards, which is basically what I’m trying to do here. I would ultimately like to power the Arduino and radio using the Battery Elimination Circuit in the VESC which would allow the Arduino to run off of the 5V 1.5A output from the VESC.

here is one such tutorial: How to control FSESC(base on VESC) with Arduino ? | Flipsky.net – FLIPSKY

Note: initializing the servo in servo.attach(pin, min, max) appears to be equivalent to initializing without min/max arguments, and using servo.writeMicroseconds(min), for example. I still get 1.2ms pulsewidth in the VESC tool either way.

Here is an example of a breakout board for stepping down the voltage to power the radio module: nRF24L01 Breakout Adapter with Voltage Regulator - ProtoSupplies

Here is the radio module itself Addicore NRF24L01+PA+LNA with Antenna 2.4GHz Wireless Transceiver

1.5 amps and 5v should be sufficient to power the circuit. The max operating current for a Pro Micro and NRF24L01+PA+LNA is around 400mA. I expect that that is more current that the Arduino/radio experience when they’re powered from my PC usb since I’m not using the max radio amplification power.

The only theory that I have is that the quality of the 5v DC might be very high from my PC usb and noisy from the other 5v power sources? and similarly for the 9v battery it might not be providing adequate current according to TomGeorge. Others using the NRF24L01 often use capacitors to remove noise from the +3.3v to ground. I will purchase some capacitors of varying size and try that out.

edit: I will also try using one of the Arduino Uno’s as an oscilloscope to verify the signal output from the receiver Arduino.

edit2: I have removed the radio module and run a test code with just servo.writeMicroseconds(1000) and the same issue happens.

In the meantime, any other suggestions would be greatly appreciated!

Now it’s time for the “OP is an idiot.” lol! :crazy_face:

I added a ground wire between the VESC and the Arduino and am getting consistent behavior between the wall wart and PC USB. The reason it was working on my PC USB is that the VESC is grounded through the same USB bus as the Arduino since both are connected to my PC via USB.

Interestingly, the VESC tool is still reporting 1.2-2.2ms even though I’m expecting 1-2ms.

Thanks TomGeorge and slipstick for your replies

For future information the Servo library defaults are not 1000, 2000. Leaving max/min out of the attach() is equivalent to attach(pin, 544, 2400).

Steve

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