Non working pulseIn() on A0 and 3.3V

Hi.

I have a RF433 (XD-RF-5V) sensor connected to 5V, GND and A0. The receiver receives signal from a wireless thermometer, which sends a signal every 43seconds. I am trying to measure the width of the received signal using the pulseIn() method. If the receiver is connected to 5V I get a lot of interference and the pulseIn method returns a lot of values.

Sample:

 dur = 58usec
 dur = 79usec
 dur = 59usec
 dur = 40usec
 dur = 93usec
 dur = 301usec
 dur = 55usec
 dur = 847usec
 dur = 79usec
 dur = 58usec
 dur = 402usec
 dur = 3979usec
 dur = 471usec
 dur = 1810usec
 dur = 215usec
 dur = 29usec
 dur = 304usec
 dur = 1904usec
 dur = 171usec
 dur = 280usec
 dur = 86usec
 dur = 14usec
 dur = 231usec
 dur = 335usec
 dur = 89usec
 dur = 60usec
 dur = 60usec
 dur = 695usec
 dur = 135usec
 dur = 41usec
 dur = 451usec
 dur = 423usec
 dur = 340usec
 dur = 20usec
 dur = 35usec
 dur = 55usec
 dur = 64usec
 dur = 92usec
 dur = 1268usec

Because I don't want to read interference data I connected the receiver to 3.3V, which eliminated them, but after running the following sketch I don't get any values whatsoever.

unsigned long dur;

void setup()
{
  Serial.begin (9600);
  pinMode(A0, INPUT);
}

void loop()
{

  dur = pulseIn( A0, HIGH);
  Serial.print(" dur = ");
  Serial.print(dur);
  Serial.println("usec");
}

Does anyone know, why the pulseIn() isn't giving me any values on the 3.3V?

Thanks in advance!

I have a RF433 (XD-RF-5V) sensor

Post a link. RF is typically serial in and out, not measuring some pulse widths.

Some info about the receiver.

Another thread, where someone A0 as an imput pin.

Some info about the receiver.

You would use VirtualWire or RadioHead libraries to write to/read from them.

Why are you trying to use pulseIn()?

Why are you doing that on an analog pin?

I want to decode the signal to binary. I saw one solution in this thread, where someone measured the duration of 1's and 0's so he could determine which pulse was a 1 and which one was a 0. After that, he could find the signal preabmle. I already know the protocol format, so if someone knows an easier way to solve this, please, do share.

The temperature sensor uses a non-standard protocol, so I think the VirtualWire library wouldn't be able to decode it. I also tried the RCSwitch library which doesn't return anything.

Can't I do it on an analog pin?

pulseIn() has a default 1-second timeout. I'm surprised you don't get a zero result 42 out of 43 times. When you say "doesn't return anything" do you mean "only displays 0" or do you mean "never displays any output"?

johnwasser:
When you say "doesn't return anything" do you mean "only displays 0" or do you mean "never displays any output"?

It only displays 0 (i tried setting the timeout parameter to 30s and 1min).

Can't I do it on an analog pin?

Why not try it on a digital pin, and answer your own question. If you get non-zero values, then the answer is no. If you only get 0s on a digital pin, then the problem is elsewhere.

Tried measuring it on the digital pin 7. Still, I only get zeroes, so this probably won't be the way to go.
Could it be possible that the pulse never goes HIGH (doesn't reach the right voltage to be detected as high, which is above 2V at Vcc=3.3V, as stated here? A colleague measured the output voltage with a multimeter and the readings showed approximately 2V).

What about the 5V interference? Is there a way to reduce it?

I tried using analogRead() (and converted the received data to voltage) in the loop and this is a sample output (sampled in idle state - when it's not receiving a signal from the thermometer).

3.70
0.00
3.70
0.00
3.70
0.00
3.70
0.00
3.71
0.00
3.70
0.00
3.70
0.00
3.70
0.00
3.70
0.00
3.71
0.00
3.70
0.00

The same measurement for 3.3V:

00
0.00
0.00
0.00
0.00
0.00
0.00
0.00
0.00
0.00
0.00
0.00
0.00
0.00
0.00
0.00
0.00
0.00
0.00
0.00
0.00
0.00
0.00
0.00
0.00
0.00
0.00
0.00
0.00
0.00
1.28
0.00
0.00
1.28
0.00
1.28
1.29
0.00
0.00
0.00
0.00
1.30
0.00
0.00
0.00
0.00
0.00
0.00
0.00
0.00
0.00
0.00
0.00
0.00
0.00
0.00
0.00
0.00
0.00
0.00
0.00
0.00
0.00
0.00
0.00
0.00
0.00
0.00
0.00
0.00
0.00
0.00
0.00
0.00
0.00
0.00
0.00
0.00
0.00
0.00
0.00
0.00
0.00
0.00
0.00
0.00
0.00
0.00
0.00
0.00
0.00
0.00
0.00
0.00
0.00
0.00
0.00
0.00
0.00
0.00
0.00
0.00
0.00
0.00
0.00
0.00
0.00
0.00
0.00
0.00
0.04
0.00
0.00
0.00
0.00
1.28
0.00
0.00
0.00
0.00
0.00
0.00
0.00
0.00
0.00
0.00
0.00
0.00
0.00
0.00
0.00
0.00
0.00
0.00
0.00
0.00
0.00
0.00
0.00
0.00
0.00
0.00
0.00
0.00
0.00
0.00

I get no such interference at 3.3V, as seen above.

It sounds like your receiver is not working at 3.3V so you will have to find a way to filter out the spurious signals you are receiving at 5V. Have you tried sampling the signal a specific times to see if it matches the protocol? Have you searched the Internet to see if anyone else has already solved this problem?

I haven't found a single thread about this problem.

The main problem is still decoding the signal into bits. I've found two ways about doing that:

1.) By using a ring buffer (which is above my knowledge level)
2.) Using the pulseIn() method (which I obviously can't use now)

The main

johnwasser:
Have you tried sampling the signal a specific times to see if it matches the protocol?

Could you, please, explain how I could do this?

You might try connecting the device to an external interrupt pin, to see if it triggers an interrupt.

PaulS:
You might try connecting the device to an external interrupt pin, to see if it triggers an interrupt.

I ran the following two sketches.

At 3.3V: The first sketch reads the digital state of the pin, which is connected to the RF receiver's data pin. It never reaches the HIGH state (even when the signal is transmitted from the transmitter). The second sketch is a simple pin state changed interrupt and is never run.

At 5V: We quickly reach the while loop at the bottom and the led turns on (due to interference). The second sketch - the interrupts are called (again, due to interference), because I can see the led flicker.

/*
 * Tried reading the binary state of the digital pin 7, which receives the RF signal
 * 
 * At 3.3V the pin state never, even when the RF transmitter transmits  
 * a signal, jumps to HIGH (Output example: 0000000000000)
 * 
 * At 5V we have a lot of interference, so we quickly reach the while loop, due to
 * interference. (Output example: 001010010011010010)                            
 */

int val;
int pin = 7;
void setup() {
  pinMode(13,OUTPUT);
  digitalWrite(13,LOW);
  
  pinMode(pin,INPUT);
  Serial.begin(9600);
}

void loop() {
   val = digitalRead(pin);
   Serial.println(val);
  
   if(val == HIGH){
    while(1){
       digitalWrite(13, HIGH);
       Serial.println("Reached HIGH state.");
    }
   }
}
#include <PinChangeInt.h>

/*
 * Specific Pin interrupt example
 * 
 * 
 * At 3.3V the pin state interrupt is never called (even when the RF transmitter transmits  
 * a signal).
 * 
 * At 5V we have a lot of interference, so the interrupt is quickly called.
 */
 
#define MY_PIN 7 // the pin which receives the RF433 signal
 
volatile int pwm_value = 0;
volatile int prev_time = 0;
uint8_t latest_interrupted_pin;
 
void rising()
{
  latest_interrupted_pin=PCintPort::arduinoPin;
  PCintPort::attachInterrupt(latest_interrupted_pin, &falling, FALLING);
  prev_time = micros();

  // Turn the led ON
  digitalWrite(13, HIGH);
  delay(2000);
}
 
void falling() {
  latest_interrupted_pin=PCintPort::arduinoPin;
  PCintPort::attachInterrupt(latest_interrupted_pin, &rising, RISING);
  pwm_value = micros()-prev_time;
  
  // Turn the led OFF
  digitalWrite(13, LOW);
  delay(2000);
}

void setup() {
  // LED setup
  pinMode(13, OUTPUT); 
  digitalWrite(13,LOW); 

  // Receiving pin setup
  pinMode(MY_PIN, INPUT); 
  //digitalWrite(MY_PIN, HIGH);
  
  //Serial.begin(9600);
  PCintPort::attachInterrupt(MY_PIN, &rising, RISING);
}
 
void loop() { }

Can anybody suggest another solution (besides buying a different receiver)? Is there a way to reduce the interference at 5V (also mentioned here)? Could I redefine the digitalWrite() or pulseIn() method so they check for a different, lower, voltage value?

Thank you for your help.

You should NOT put a two second delay in an ISR.

No, you can't 'redefine' the logic levels of digitalRead() or pulseIn(). You can run the Arduino on 3.8V which would make the threshold lower. This might allow you to receive input from the 3.3V radio but I expect it will receive the same interference as you saw at 5V.

johnwasser:
You should NOT put a two second delay in an ISR.

I only put them in for diagnostic purposes (to create a delay and I could see the flicker).

Could anyone recommend any other receiver module, where I wouldn't have problems with interference at 5V?

Thank you for your help!