Help troubleshoot 433 RF receiver

I'm trying to read my rf receiver using a software/soundcard oscilloscope. I first attached the oscilloscope directly to digital pulses from my arduino and the oscilloscope seemed to work ok.
Here is the sketch I used for the pulses:

 #define rfTransmitPin 10  //RF Transmitter pin = digital pin 4
 #define ledPin 13        //Onboard LED = digital pin 13

 void setup(){ 
   pinMode(ledPin, OUTPUT);
   pinMode(rfTransmitPin, OUTPUT);   
 }

 void loop(){
   digitalWrite(rfTransmitPin, HIGH);     //Transmit a signal 
   digitalWrite(ledPin, HIGH);            //Blink LED for 0.2 s
   delay(200);    
   digitalWrite(rfTransmitPin, LOW);                     
   digitalWrite(ledPin, LOW);
   delay(1000);  

   digitalWrite(rfTransmitPin, HIGH);      //Transmit a lower signal
   digitalWrite(ledPin, HIGH);            //Blink LED for 0.2 s
   delay(200);                         
   digitalWrite(rfTransmitPin, LOW);
   digitalWrite(ledPin, LOW);
   delay(500);
   
   digitalWrite(rfTransmitPin, HIGH);       //Transmit a lower signal
   digitalWrite(ledPin, HIGH);            //Blink LED for 0.2 s
   delay(200);                         
   digitalWrite(rfTransmitPin, LOW);
   digitalWrite(ledPin, LOW);
   delay(100);
 }

And I've attached the corresponding "digitalPulseTest.png" to show the waveform.

Now I have an arduino transmitting a signal according to this sketch:

/* 
  RF Blink - Transmit sketch 
     Written by ScottC 17 Jun 2014
     Arduino IDE version 1.0.5
     Website: http://arduinobasics.blogspot.com
     Transmitter: FS1000A/XY-FST
     Description: A simple sketch used to test RF transmission.          
 ------------------------------------------------------------- */

 #define rfTransmitPin 4  //RF Transmitter pin = digital pin 4
 #define ledPin 13        //Onboard LED = digital pin 13

 void setup(){
   pinMode(rfTransmitPin, OUTPUT);     
   pinMode(ledPin, OUTPUT);    
 }

 void loop(){
   for(int i=4000; i>5; i=i-(i/3)){
     digitalWrite(rfTransmitPin, HIGH);     //Transmit a HIGH signal
     digitalWrite(ledPin, HIGH);            //Turn the LED on
     delay(2000);                           //Wait for 1 second
     
     digitalWrite(rfTransmitPin,LOW);      //Transmit a LOW signal
     digitalWrite(ledPin, LOW);            //Turn the LED off
     delay(i);                            //Variable delay
   }
 }

What I'm getting on my rf receiver is shown in the attached "testSend.png". It's definitely not what I had expected to see.
Can anyone shed light on what might be happening here?

thanks

digitalPulseTest.PNG

What you are seeing is correct.
Those OOK radio receivers require constant hi rate transitions in the data being sent to work properly.
Simply turning on and off a 433 Mhz carrier slowly wont yield any useful output.
To succsessfully send data with them you need to precondition the data with something like Virtualwire
or Radiohead, both of which generate the constant transitions needed for the receivers to work properly.

Try sending a 500 Hz signal, as follows, and you should see something more reasonable on the receiver output.

void loop() {
   digitalWrite(rfTransmitPin, HIGH);          
   delay(1);                        
   digitalWrite(rfTransmitPin, LOW);
   delay(1);
}

Thanks.
I have both of your suggestions implemented.

My receiver is constantly receiving the attached signal, eventhough I don't have anything transmitting at the moment. This can't be right, can it?

I will bet that it is not constantly receiving the pictured signal, but something similar would be normal background noise and is expected. That is why you need VirtualWire or RadioHead -- to send an easily recognizable signal.

Thanks so much. Attached is screen grab from Audacity, showing some received packets from a Lacrosse weather sensor. The Radiohead was a big help.

I now have to consider how to incorporate the rh_ask library (which I'm not familiar with, so far I'm just copying code) with other lacrosse sketches I've found and played with which use interrupts - another tricky aspect for me. That's for another thread though!

What exactly are you trying to do?
Virtualwire or RH is only needed if you are sending data from one Arduino to another.
Trying to decode a weather station is a differant problem and requires some knowledge of
the protocol that the weather station uses.

mauried:
What exactly are you trying to do?
Virtualwire or RH is only needed if you are sending data from one Arduino to another.
Trying to decode a weather station is a different problem and requires some knowledge of
the protocol that the weather station uses.

I was using my software oscilloscope to decode the protocol of the weather station. I had the oscilloscope connected to my receiver and the last screenshot was from the weather station sensor.

I was using the transmitter to troubleshoot my oscilloscope and receiver.

I now know the sensor protocol and will try to get it to work with the sketch from here: GitHub - kjordahl/Arduino-Weather-Station: RF receiver for LaCrosse weather station, with pressure and indoor temperature. I tried using this sketch before without success, but I hope to troubleshoot my problems with the new info I've learned here.

What specific model of LaCrosse weather transmitter do you want to decode?
The signal protocol is often different from one model to the next.

The best way to decode Weather Station data formats is to connect your oscilloscope directly to one of the
weather stations sensors, (tx data pin) and capture the data transmission.
That way , you avoid all the random noise that you get from the 433 receiver, and it makes the task of figuring out the data format much easier.

I have the TX7UN.
I checked my scope waveform and confirmed that my timings and start packet are the same as those found in the lacrosse.pde above. I measured the timing of the 0 and 1 pulses, along with the starting packet (0x0a) and the timing between pulses.

All I'm getting in my serial monitor is "missed one" and "missed zero".
To be honest, I'm not sure how the interrupt timer ICR1 corresponds to the time. ie I don't know why MIN_ONE and MAX_ONE corrspond to 0.5 ms. I'm just assuming that the code's comments are accurate (I know that my timings correspond to 0.5ms, 1.3 ms and 1. ms).

You may need to invert the signal for the code to work.

I'm just assuming that the code's comments are accurate

Generally speaking, this is not a wise assumption.

The Arduino clock speed is 16MHz, the prescaler is 1024 and OCR2A = 255. This gives an interrupt frequency of 100 Hz.0

For a "1", according to my oscilloscope reading the pulse time was 44 samples at 44100Hz, which is 1. ms.

So I should be looking a 1.0 ms signal arriving on the interrupt that is 100 Hz. The code I'm using has:

// 1 ms between bits
#define MIN_WAIT 225		// minimum interval since end of last bit
#define MAX_WAIT 275		// maximum interval since end of last bit

and

CapturedTime = ICR1;
CapturedPeriod = (CapturedTime - PreviousCapturedTime);

Where the MIN_WAIT and MAX_WAIT are compared to CapturedPeriod. So I don't get how the 225/275 relates to 1 ms.

the prescaler is 1024 and OCR2A = 255

The above is for Timer2.

CapturedTime = ICR1;

The above depends on the Timer1 prescaler.

Ah, that makes sense. Timer1 has CS10 and CS11 set to 1, which is a prescale of 64. So for example, MAX_WAIT = 275/(16MHz/64) = 1.1 ms. So that part of the setup seems OK.

For inverting the signal, are you talking about doing something with hardware such that the signal going to pin 8 is inverted?

I do know that right now the script is failing on line 212:
if (SinceLastBit > MAX_WAIT) { // too long since last bit read

I'm printing the SinceLastBit to the serial monitor and it is reading around 800 to 900.

The library you are using is intended for a TX4 Sensor.
Is that what you are using?

No, I have a TX7. I found that my sensor was sending out the same pattern as this: Lacrosse TX3-TH thermo/hygro sensor

I thought that maybe this was all that was needed: I know that the message is the same format (for parsing) and length, and that the pulse timing and starting packet are the same.

For inverting the signal, are you talking about doing something with hardware such that the signal going to pin 8 is inverted?

Yes, you could use a transistor. Or invert the bits in software as they are received.

I do know that right now the script is failing on line 212:
if (SinceLastBit > MAX_WAIT) { // too long since last bit read

suggests something else is wrong, i.e. the message is shorter than expected. The only way to know for sure is to look at the messages (e.g. with Audacity), count all the bits and compare with what the program expects.

If you dont get anywhere, have a look at the sketch to see if its looking for a TX4.
Most weather stations have a sensor identifier in the sensors transmission to tell the receiving console
what type of sensor it is, and if the particular sensor type code isnt there the data just gets ignored even if
all the timing and the data fields are correct.

The attached graphic is a typical packet sent by the TX7, and it's also the first packet sent by the TX7 when it is powered on. It corresponds to a "0" of 1.3 ms, a "1" of 0.5 ms and 1 ms in between pulses. I don't see any code that looks for any kind of handshake or identifier from the sensor.

I think the most relevant code is as follows:

#define INPUT_CAPTURE_IS_RISING_EDGE()    ((TCCR1B & _BV(ICES1)) != 0)
#define INPUT_CAPTURE_IS_FALLING_EDGE()   ((TCCR1B & _BV(ICES1)) == 0)
#define SET_INPUT_CAPTURE_RISING_EDGE()   (TCCR1B |=  _BV(ICES1))
#define SET_INPUT_CAPTURE_FALLING_EDGE()  (TCCR1B &= ~_BV(ICES1))

I'm a bit unsure of what the above is, but I think is define the setting and clearing of bits on timer 1 as pulses are received. I'm not sure what ICES1 is, but I found that these are bit operators.

// 0.5 ms high is a one
#define MIN_ONE 135		// minimum length of '1'
#define MAX_ONE 155		// maximum length of '1'
// 1.3 ms high is a zero
#define MIN_ZERO 335		// minimum length of '0'
#define MAX_ZERO 370		// maximum length of '0'
// 1 ms between bits
#define MIN_WAIT 225		// minimum interval since end of last bit
#define MAX_WAIT 275		// maximum interval since end of last bit

The above corresponds to the timing of the TX7

ISR( TIMER1_CAPT_vect )
{
  // Immediately grab the current capture time in case it triggers again and
  // overwrites ICR1 with an unexpected new value
  CapturedTime = ICR1;

  // GREEN test led on (flicker for debug)
  GREEN_TESTLED_ON();
  if( INPUT_CAPTURE_IS_RISING_EDGE() )
  {
    SET_INPUT_CAPTURE_FALLING_EDGE();      //previous period was low and just transitioned high
    CapturedPeriodWasHigh = false;    //uiICP_CapturedPeriod about to be stored will be a low period
  } else {
    SET_INPUT_CAPTURE_RISING_EDGE();       //previous period was high and transitioned low
    CapturedPeriodWasHigh = true;     //uiICP_CapturedPeriod about to be stored will be a high period
  }

  CapturedPeriod = (CapturedTime - PreviousCapturedTime);

Setting and clearing bits on timer 1, this part is also a bit confusing for me. CapturedPeriod is the length of the pulse. Looking at the serial monitor I seem to be picking up pulses of the correct length.

  if ((CapturedPeriod > MIN_ONE) && (CapturedPeriodWasHigh == true)) { // possible bit
    /* time from end of last bit to beginning of this one */
    SinceLastBit = (PreviousCapturedTime - LastBitTime);
    
    if ((CapturedPeriod < MAX_ONE) && (SinceLastBit > MIN_WAIT)) {
          
      if (SinceLastBit > MAX_WAIT) { // too long since last bit read
      	if ((SinceLastBit > (2*MIN_WAIT+MIN_ONE)) && (SinceLastBit < (2*MAX_WAIT+MAX_ONE))) { /* missed a one */
          #ifdef DEBUG
      	    Serial.print("missed one ");
            Serial.println(SinceLastBit);
      	  #endif
      	} else {
      	  if ((SinceLastBit > (2*MIN_WAIT+MIN_ZERO)) && (SinceLastBit < (2*MAX_WAIT+MAX_ZERO))) { /* missed a zero */
            #ifdef DEBUG
        	    Serial.print("missed zero ");
                    Serial.println(SinceLastBit);
      	    #endif
      	  }
      	}

This is where things break. After I receive a pulse of 1.3 ms or 0.5 ms, the SinceLastBit is never 1 ms. It typically is about > 3 ms. On the serial monitor I just get a stream of "missed one" and "missed zero."

Later in the sketch the program looks at the first 4 pulses to see that it is 0000. This is how it identifies a packet. But I never get that far. SinceLastBit is always > MAX_WAIT.

I may have to start with another person's code and see how that goes. There's not a lot more I can do with this, and I don't understand all the bit and timers well enough to start from scratch.

Cheers