Can't get expected readings using PulseIn command

Hello, I want to use an Uno in an RC galley to control the oars. Idea is that the Uno receives two servo PWM streams from the RC Rcvr (call them "throttle" and "rudder") then generates four PWM streams to control four servos which drive the oars; one on each side to drive the sweeping back and forth, and another one on each side to raise/lower the oars.

I put together a little shield to interface all this for a prototype. It has 3-pin connectors for the four servos, and for connections from the RC Rcvr. I'm using servo extension cords to connect the Rcvr to the Arduino's shield's connectors. It is these cords which pass +5V from the arduino to the Rcvr via their red wire (currently the Arduino gets its +5V from the laptop USB cable).

I have selected PortB2:0 as inputs from the Rcvr (I added a third connector for future use). These are pins 16, 15, 14 on the 328. I copied the little example routine to read a PWM input pulse width and print the result on the monitor. All I ever get is zero, once a second, indicating it is timing out waiting to see a pulse.

I'm a little handicapped because I don't have access to an oscilloscope, but my multimeter reads the DC level on the input as 0.27V and 0.46V with the RX transmitter stick at its two end points. This is consistent with 1msec and 2msec pulses of amplitude between 4V and 5V, which should be large enough for the Uno to see. All three ports behave the same. I'm sure it's something silly; is there something else I have to declare in order to use PulseIn? Do I have to "enable" Port B somehow? Or have I picked pins unsuitable for this function?

It would be lovely to have a scope even for half an hour! I should mention that I verified continuity from the three 3-pin connectors to the board SIP connector; and also from the Atmega pins to its SIP connector; but I haven't actually measured it all the way through because with the shield plugged into the Arduino I can't probe the Atmega pins.

Any suggestions would be gratefully received.

Read How to get the best out of this forum then follow the advice it contains on posting code

I second the wish to see your code.
Use the IDE autoformat tool (ctrl-t or Tools, Auto format) before posting code in code tags.

How are the servos powered?

OK, maybe I'm even more lost than I thought. I don't see any toolbar from which to do a format before posting; I'm in the web Editor and I don't see any way of going "up" to the higher-level IDE? I think I am misunderstanding this whole software thing. I thought I had installed the web-based Create but where I am editing code is Arduino Cloud. I had downloaded and run the ArduinoCreateAgent installer. How do I get to the IDE screen? Sorry for being so appallingly dense.....

Just post your code. Copy and paste the code into a post. Highlight it then click the </> in the toolbar above. Once that you have posted the code we can copy it to our IDE and format it if necessary.

OK, I gave up on the web Editor and downloaded the IDE to run offline. Now I see the toolbar etc. But I get the same result: monitor returns zero after each timeout. I still see the DC level of the PWM vary as I move the RC transmitter's stick. God I wish I had a scope....

Since I am a newbie I am breaking this project into small pieces to gain experience. Step 1 is to try out the PulseIn. My current setup is a single 3-wire servo extension cable from anRC Rcvr channel to a 3-pin connector on my proto shield which connects to pin 15 on the Atmega (DIGITAL 9 connector pin). The Uno passes +5V to the Rcvr via this cable.

To answer your earlier question, the four servos are/will be powered from a separate supply which right now is a 6V lantern battery but if I do build a model ship will be NiMH or whatever. Thus the pins on the connectors intended for the servos are GND, +6V, Signal. The pins on the connectors intended for the RC Rcvr are GND, +5V, Signal. GND is common - Arduino, Rcvr, Servos. Right now there are no servos plugged in and no +6V; testing this will be the next stage when reading the Rcvr's PWM with PulseIn works.

By the way, I already like the offline IDE better than the web version.

So here is the code - right out of the Reference examples.

int pin = 15;

void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
pinMode(pin, INPUT);
}

void loop() {
// put your main code here, to run repeatedly:
int duration = pulseIn(pin, HIGH);
Serial.println(duration);

What do you mean by this? A photo of your wiring might help.

Pin 15 on an Uno is the same as analog input A1. Is that where the RC receiver is connected?

The posted code is incomplete. Please post the whole code. Read the forum guidelines to see how to properly post code.
Use the IDE autoformat tool (ctrl-t or Tools, Auto format) before posting code in code tags.
You can edit your post to put the format the code and put it in code tags.

Please follow the advice given in the link below when posting code. Use code tags (the </> icon above the compose window) to make it easier to read and copy for examination

There are a lot of pages on the net about reading the PPM signals from an RC receiver with an Arduino. For instance this Sparkfun page. Note the use of the timeout parameter in the pulseIn function and the delay to slow down the loop(). I would not use delay, but a millis() blink without delay timer.

Lots more with a Google search for "reading rc receiver with uno".

example using a millis() timer:

const byte rcvPin = 15; // same as A1

void setup()
{
   Serial.begin(115200);
   pinMode(rcvPin, INPUT);   
}

void loop()
{
   static unsigned long timer = 0;
   unsigned long interval = 100;
   if (millis() - timer >= interval)
   {
      timer = millis();
      if (digitalRead(rcvPin) == LOW)
      {
         unsigned long val = pulseIn(rcvPin, HIGH, 25000);
         Serial.println(val);         
      }
   }
}

millis() (Non-blocking) timing tutorials:
Several things at a time.
Beginner's guide to millis().
Blink without delay().

I've stripped this down to basics hardware-wise. My proto shield is out of the picture in order to eliminate it as any possible cause. I simply have three connections from my RC receiver to the Uno: +5V, GND, and a CH1 signal from the Rcvr. My receiver has no power indicator so I plugged a servo into CH2 and verified that it is controlled by the RC transmitter. So everything looks right power-wise and the receiver is functioning. Beforehand I verified that I could control a servo from CH1 so I know that output works.

I tried connecting the signal lead to various atmega pins via the Uno connectors, obviously recompiling each time. All I ever get from the monitor is zeroes. Happily with my shield dismounted I can now probe atmega pins direct and I see the DC level at the selected input pin varying as I move the RC transmitter's stick. There definitely seems to be a PWM signal.

My damn camera battery just died so I cannot upload pictures of my three wires connecting to the Uno. I will upload later (do I simply paste the jpeg images into here?). I will add some of my shield for any interest.

I don't understand why you remark that my code is incomplete. Here is another try at placing it here; I clicked on "select all" in the editor window then "copy". Hopefully I used the code tags properly this time. Is there something fundamental the code is missing? I'm literally copying examples from the reference but perhaps they assume one already has a functional code framework for the sketch.


int duration;

void setup() {
  // put your setup code here, to run once:
  pinMode(6, INPUT);
  Serial.begin(9600);

}

void loop() {
  // put your main code here, to run repeatedly:
  duration = pulseIn(6, HIGH, 25000);
  Serial.println(duration);

  delay(100);
}

Did you try the code that I posted in reply #10?

I tried out the code with my receiver signal connected to A1 of the connector labelled "Analog In".

Two things now:

First, after downloading that code I get a single number on the serial monitor, followed by a stream of backwards question marks. The interesting thing is that I held the RC transmitter stick at each end, and in the middle, in turn, and after clicking download I got a number each time that is very close to what one would expect: ~1000, ~1500, ~2000.

But here is where my head explodes, and I guess this is the crux of my issue: On my Uno Rev3 schematic, the atmega pin 15 connects to the Digital/PWM connector pin labelled "9~" (verified on my ohmmeter); whereas the connector pin labelled "A1" connects to pin 24 on the atmega (again, verified on my ohmmeter).

How in Lucifer's name does this code seem to see a signal on pin15 which I thought was over on pin24?

My schematic is UNO-TH_Rev3e dated 06/03/19 12:33

Is there another UNO board which uses a QFP package? Is that what I have accidentally printed?

I ran the original simple code specifying pin 15 and with the Rcvr connected to "A1". The serial monitor displays 68 zeroes, a valid value, 68 zeroes, a valid value, etc etc.

The Arduino Uno SMD uses the same microcontroller but in a QFP package. In both cases pin 24 on the microcontroller connects to A1 (which is also D15 or simply pin 15). Note that as long as you are just using the provided Arduino library functions and declarations you never need to know what the package pin or the GPIO port of the microcontroller is being referenced. So just forget "24". :grinning:

On your folllowup post where you say 68 zeroes then a valid value, which repeats, is there one second between each zero value? The pulseIn function with only two arguments will timeout and return a zero after one second without seeing input. If it is returning a zero faster I would guess it is seen very short pulses that it cannot measure. And in that case you really need an oscilloscope to see what is going on. You would be having some signal integrity issue from the receiver.

Dear almytom,

Thank you very much for your post! So if I understand you correctly, all the library functions refer to pin numbers of the Arduino board itself, not of the Atmega?:thinking: No wonder I was screwed up!!!

But I still don't quite understand how pin A1 is actually D15 or plain 15. My schematic doesn't show these; atmega pin 24 is signal AD1 which connects to pin 2 of the "IOH" 6-pin connector. There are no silkscreen markings showing these pin numbers at the connectors. If I treat the Uno board as a giant IC I'd expect pin A1 to be pin #10 (or #28 if you spin the Uno board around). Please explain further- I feel we are very close to making me understand, finally.

As for the many zeroes with intermittent "real" values, I will figure it out once I am sure of the correct pin numbers to use. In real life there is a servo pulse every 20 msec; thanks to ground_fungus and his references to the millis() command I can get the elapsed time displayed on the monitor by adding this command in my code at salient points which should help me decipher the issue. Maybe I have some sort of aliasing issue.

I'm asking around among my friends for who might have a scope they could lend me. No luck yet. They're kind of pricey to buy, for a project which I may decide not to implement ie. the operating model ship.

Thanks again,
Ian

Pin numbers of the terminal blocks are not the same as the Arduino pin numbers! The pinout diagram at https://content.arduino.cc/assets/Pinout-UNOrev3_latest.pdf shows:
https___content_arduino_cc_assets_Pinout-UNOrev3_latest_pdf
And you can see that the pin marked as A1 is also D15, but the silkscreen on the board only shows it as A1. In the IDE A1 is defined to be 15, so it doesn't matter which you use
Arduino_Uno_Rev3_—_Arduino_Online_Shop
Now if you look at the schematic:
UNO-TH_Rev3e_sch_pdf-2

You see that net AD1 connects to ADC1, which is Port C bit 1 in the ATmega328P microcontroller and connects to pin 2 of the terminal block AD. Sadly, we can't tell the pin ordering of the terminal block AD or even where AD is from any of the above screen snaps! We just have to rely on the schematic matching the board, which is fairly safe bet on such an old product with lots of sales.

Tom, thanks for this! Now I understand. I thought since I'm programming the atmega then pin numbers would be its pins. How in the world would a newbie manage to find, or even know to look for, that document? I'm an old guy and not very good at finding stuff online as opposed to having a printed manual to read through.

I will annotate my schematic as such. They could perhaps have silkscreened these pin numbers on one side of the "AD" connector body and left A0...A5 on the other side; might have helped. As for the schematic, these numbers should be added to the right of the AD connector, as they are for the other two connectors. Suggestion to Arduino.

Again, thank you very much!

Now I can start to debug actual code!

Why in the World would they need to ?

Just use the pin designations silkscreened on the board.

Want to use the pin marked A3 as an input ?

pinMode(A3, INPUT_PULLUP);

Want to iterate through the pins marked A0 to A5 ?

for (int p = A0; p <= A5; p++)
{
  digitalWrite(p, HIGH);
  delay(1000);
  digitalWrite(p, LOW);
}

and so on

Arduino's (the company) goal is to make microcontrollers accessible to everyone, not just engineers! So if you just use their IDE and software library you don't need to be concerned about anything within the board, just the terminal blocks at the periphery. Being an Electrical Engineer, and having spent decades teaching (part time) electrical engineering students, I ended up writing a series of books that delve into the workings of the microcontrollers in Arduino boards and how the Arduino software library presents or hides the features. The titles all have "Far Inside The Arduino" as part of their titles and can be found on Amazon. If you ever want to get into this deeply, look them up!