Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

OverSampling - HALF_DUPLEX mode with reduced range #91

Closed
gioblu opened this issue Sep 10, 2016 · 2 comments
Closed

OverSampling - HALF_DUPLEX mode with reduced range #91

gioblu opened this issue Sep 10, 2016 · 2 comments

Comments

@gioblu
Copy link
Owner

gioblu commented Sep 10, 2016

Ciao! It's a while I am trying to fix this issue locally, but seems this is harder than expected. I am trying to enable HALF_DUPLEX mode with a couple of cheap ASK/FSK 315/433 modules. After various tests seems the receiver is saturated by the transmitter, so its sensitivity is lowered, and the sync ACK can not be received correctly at far distances, SRX885 in particular has a CS pin that should be set HIGH to receive data and LOW to set the module in sleep mode. I considered possible to solve the issue making the receiver sleep while transmitting and making it awake to get the acknowledge after transmission. I tried to extend the OverSampling strategy with a setter: set_cs_pin to pass the pin, and modified the codebase to set its state where necessary:

    /* Send a string: */

    void send_string(uint8_t *string, uint8_t length) {
      if(_cs_pin != NOT_ASSIGNED)
        pullDownFast(_cs_pin);
     // If CS pin is set make receiver sleep
      for(uint8_t b = 0; b < length; b++)
        send_byte(string[b]);
    };

  uint16_t receive_byte() {
      pullDownFast(_input_pin);

      if(_output_pin != NOT_ASSIGNED && _output_pin != _input_pin)
        pullDownFast(_output_pin);
      // If CS pin is defined set it HIGH wake up the receiver
      if(_cs_pin != NOT_ASSIGNED) {
        pinModeFast(_cs_pin, OUTPUT);
        digitalWriteFast(_cs_pin, HIGH);
      }

      float value = 0.5;
      unsigned long time = micros();
      /* Update pin value until the pin stops to be HIGH or passed more time than
         BIT_SPACER duration */
      while(((uint32_t)(micros() - time) < _OS_BIT_SPACER) && digitalReadFast(_input_pin))
        value = (value * 0.999)  + (digitalReadFast(_input_pin) * 0.001);
      /* Save how much time passed */
      time = micros();
      /* If pin value is in average more than 0.5, is a 1, and if is more than
         ACCEPTANCE (a minimum HIGH duration) and what is coming after is a LOW bit
         probably a byte is coming so try to receive it. */
      if(value > 0.5) {
        value = 0.5;
        while((uint32_t)(micros() - time) < _OS_BIT_WIDTH)
          value = (value * 0.999)  + (digitalReadFast(_input_pin) * 0.001);
        if(value < 0.5) return read_byte();
      }
      return FAIL;
    };

But I have the same negative results also sending more than one ACK.
Is there someone with some experience with those modules or with a good SDR ready to help :) ?

@gioblu
Copy link
Owner Author

gioblu commented Jan 7, 2017

Here some pictures from oscilloscope:

15943306_1290935024301482_246932764_o

The signal shown is the device 1 rx pin reading
You can see on left the packet transmitted by device 2 correctly received. Immediately after the packet it is seen the synchronous acknowledge transmitted by device 1, that is heard back by its own receiver.

What is seems happening is that the transmitter of device 1 is saturating or blinding its receiver sensitivity because of its antenna vicinity. After this it occurs always 80 milliseconds of total silence and no background noise and an unwanted high bit followed by noise and channel back to stable state.

It seems that an ack or a packet it is much more difficult to be received if arrives in the 80 milliseconds timeframe following a transmission of the local device transmitter (blinding its own receiver).

What it seems occurring, is that the receiver's chip is highering the gain, getting only 0s, until passing the background noise threshold (the unwanted bit). After this process reception can occur properly.

15934225_1290935104301474_1608384750_o

So I am working adding the necessary delay to avoid the repection loss in this timeframe.
The picture below shows a packet transmitted by device 2, that transitioning to ackwnoledge reception, waits for 100 milliseconds, and then tries to receive it (so enough after the unwanted bit interference) and on the other side, device 1 delays for 100 milliseconds before transmitting ack to let device 2 to reach back a proper gain.

15943420_1291003980961253_1927666620_o

Initial tests implementing this mechanism seems to prove the hypotesis exposed above:

  • Hugely extended range
  • Few duplicated transmissions

@gioblu
Copy link
Owner Author

gioblu commented Jan 8, 2017

Issue finally fixed:

This is a picture of an HALF_DUPLEX packet exchange, with the use of the asynchronous acknowledgment.

15942588_1291186830942968_395778678_o

There is a reduction in bandwidth because SRX882 needs around 100 milliseconds to set back its gain after transmission if used in HALF_DUPLEX mode, but maximum range seems with initial tests the same obtained in SIMPLEX so 250 meters in urban environment with no line of sight or around 5 kilometers in line of sight.

@gioblu gioblu closed this as completed Jan 8, 2017
@gioblu gioblu removed the help wanted label Jan 8, 2017
@gioblu gioblu removed the bug label Dec 31, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant