gioblu / PJON

PJON (Padded Jittering Operative Network) is an experimental, arduino-compatible, multi-master, multi-media network protocol.
Other
2.73k stars 239 forks source link

Arduino Pro Mini interference #109

Open nomeme opened 7 years ago

nomeme commented 7 years ago

Hi, I am currently trying to get PJON (OverSampling) running on an Arduino Pro Mini 16Mhz and two of those cheap 433 Mhz rf receiver and transmitter pairs.

     Using Programmer              : arduino
     Overriding Baud Rate          : 57600
     AVR Part                      : ATmega328P
     Chip Erase delay              : 9000 us
     PAGEL                         : PD7
     BS2                           : PC2
     RESET disposition             : dedicated
     RETRY pulse                   : SCK
     serial program mode           : yes
     parallel program mode         : yes
     Timeout                       : 200
     StabDelay                     : 100
     CmdexeDelay                   : 25
     SyncLoops                     : 32
     ByteDelay                     : 0
     PollIndex                     : 3
     PollValue                     : 0x53

     Programmer Type : Arduino
     Description     : Arduino
     Hardware Version: 2
     Firmware Version: 1.16
     Vtarget         : 0.0 V
     Varef           : 0.0 V
     Oscillator      : Off
     SCK period      : 0.1 us

https://www.itead.cc/wiki/433Mhz_RF_Link_kit

The receiver is hooked up to pin 11 the transmitter to 12.

Packets are received mostly after one to three attempts, but the ACK gets always lost somewhere in-between.

In some rare cases it seems to work like a charm but in 95% of the cases I need to retransmit several times and the ACKs are lost anyways.

For me it seems like some kind of timing issue. I am using the default parameters but also tried to double the values defined in /OverSampling/Timimg.h with the result being the sent packets being half, no increase in accuracy.


Absolute com speed: 0.00B/s Practical bandwidth: 0.00B/s Packets sent: 0.00 Mistakes (error found with CRC) 0.00 Fail (no answer from receiver) 0 Busy (Channel is busy or affected by interference) 8 Accuracy: nan %


Don't know what i could do to improve here. Any suggestions?

I'm using the current master at:

commit 12a45bf5b3e9dfa2cfcf7ca4a336cc5a34aa36f5 Merge: 90b76a2 5d11cc6 Author: Giovanni Blu Mitolo gioscarab@gmail.com Date: Thu Jan 5 17:49:01 2017 +0100

Kind regards

gioblu commented 7 years ago

Ciao @nomeme thank you for the detailed report. Could you please assess nominal functionality in SIMPLEX mode (so only tx on one side, only rx on the other) running the OverSamplingSimplex example? https://github.com/gioblu/PJON/tree/master/examples/Local/OverSamplingSimplex

If you have a positive test result we can exclude a problem related to your particular hardware and assess that at least simplex communication works fine.

It's a while I am working on clearing out this issue: https://github.com/gioblu/PJON/issues/91 that could be related to what you report.

Extended tests in the last days with the oscilloscope have shown an unwanted bit, is transmitted after every packet. Maybe, this bit, can have a role disrupting the bidirectional exchange. I cannot see a way for PJON to produce it, it seems something related to this sort of hardware (also because, if testing OverSampling with a pair of wires I cannot replicate the same behaviour).

With STX882 and SRX882 I can obtain a similar behaviour:

(with LOS I mean line of sight)

Out of the described range:

It would be nice to solve this, and get 5km range in HALF-DUPPLEX with this sort of hardware.

gioblu commented 7 years ago

@nomeme reading better your report, are you using two Pro Mini or 1 Pro Mini and another supported device? If yes, which?

nomeme commented 7 years ago

Hi, Thanks for your quick reply. I am currently using two pro minis. I also tried with a pro mini and uno with similar results. I'll check the simplex test later today with both devices and will post my results here. Would it help you if Itry to find out at how many attempts the packet was received more or less reliably?

Kind Regards.

nomeme commented 7 years ago

Hi again, using the simplex i get following output using two pro mini


Starting 1 second communication speed test... Absolute com speed: 75.00B/s Practical bandwidth: 60.00B/s Packets sent: 3.00 Mistakes (error found with CRC) 3.00 Fail (no answer from receiver) 0 Busy (Channel is busy or affected by interference) 255 Accuracy: 0.00 %


Starting 1 second communication speed test... Absolute com speed: 125.00B/s Practical bandwidth: 100.00B/s Packets sent: 5.00 Mistakes (error found with CRC) 1.00 Fail (no answer from receiver) 0 Busy (Channel is busy or affected by interference) 197 Accuracy: 80.00 %


Starting 1 second communication speed test... Absolute com speed: 75.00B/s Practical bandwidth: 60.00B/s Packets sent: 3.00 Mistakes (error found with CRC) 1.00 Fail (no answer from receiver) 0 Busy (Channel is busy or affected by interference) 486 Accuracy: 66.67 %


Starting 1 second communication speed test... Absolute com speed: 150.00B/s Practical bandwidth: 120.00B/s Packets sent: 6.00 Mistakes (error found with CRC) 1.00 Fail (no answer from receiver) 0 Busy (Channel is busy or affected by interference) 113 Accuracy: 83.33 %


Starting 1 second communication speed test... Absolute com speed: 175.00B/s Practical bandwidth: 140.00B/s Packets sent: 7.00 Mistakes (error found with CRC) 0.00 Fail (no answer from receiver) 0 Busy (Channel is busy or affected by interference) 121 Accuracy: 100.00 %


Starting 1 second communication speed test... Absolute com speed: 125.00B/s Practical bandwidth: 100.00B/s Packets sent: 5.00 Mistakes (error found with CRC) 1.00 Fail (no answer from receiver) 0 Busy (Channel is busy or affected by interference) 290 Accuracy: 80.00 %


nomeme commented 7 years ago

Using the uno as receiver and pro mini as sender:


Starting 1 second communication speed test... Absolute com speed: 200.00B/s Practical bandwidth: 160.00B/s Packets sent: 8.00 Mistakes (error found with CRC) 0.00 Fail (no answer from receiver) 0 Busy (Channel is busy or affected by interference) 26 Accuracy: 100.00 %


Starting 1 second communication speed test... Absolute com speed: 200.00B/s Practical bandwidth: 160.00B/s Packets sent: 8.00 Mistakes (error found with CRC) 0.00 Fail (no answer from receiver) 0 Busy (Channel is busy or affected by interference) 26 Accuracy: 100.00 %


Starting 1 second communication speed test... Absolute com speed: 200.00B/s Practical bandwidth: 160.00B/s Packets sent: 8.00 Mistakes (error found with CRC) 0.00 Fail (no answer from receiver) 0 Busy (Channel is busy or affected by interference) 25 Accuracy: 100.00 %


Starting 1 second communication speed test... Absolute com speed: 200.00B/s Practical bandwidth: 160.00B/s Packets sent: 8.00 Mistakes (error found with CRC) 0.00 Fail (no answer from receiver) 0 Busy (Channel is busy or affected by interference) 26 Accuracy: 100.00 %


Starting 1 second communication speed test... Absolute com speed: 200.00B/s Practical bandwidth: 160.00B/s Packets sent: 8.00 Mistakes (error found with CRC) 0.00 Fail (no answer from receiver) 0 Busy (Channel is busy or affected by interference) 26 Accuracy: 100.00 %


nomeme commented 7 years ago

Using the uno as sender and the pro mini as receiver suddenly this happens: Tried with several pro minis and different circuits, always this result. Also retested with two pro minis and again mostly 100% accuracy.

This seems kind of strange


Starting 1 second communication speed test... Absolute com speed: 0.00B/s Practical bandwidth: 0.00B/s Packets sent: 0.00 Mistakes (error found with CRC) 1.00 Fail (no answer from receiver) 1 Busy (Channel is busy or affected by interference) 1199 Accuracy: inf %


Starting 1 second communication speed test... Absolute com speed: 0.00B/s Practical bandwidth: 0.00B/s Packets sent: 0.00 Mistakes (error found with CRC) 2.00 Fail (no answer from receiver) 0 Busy (Channel is busy or affected by interference) 1145 Accuracy: inf %


Starting 1 second communication speed test... Absolute com speed: 0.00B/s Practical bandwidth: 0.00B/s Packets sent: 0.00 Mistakes (error found with CRC) 2.00 Fail (no answer from receiver) 0 Busy (Channel is busy or affected by interference) 1008 Accuracy: inf %


Starting 1 second communication speed test... Absolute com speed: 0.00B/s Practical bandwidth: 0.00B/s Packets sent: 0.00 Mistakes (error found with CRC) 6.00 Fail (no answer from receiver) 0 Busy (Channel is busy or affected by interference) 985 Accuracy: inf %


Starting 1 second communication speed test... Absolute com speed: 0.00B/s Practical bandwidth: 0.00B/s Packets sent: 0.00 Mistakes (error found with CRC) 1.00 Fail (no answer from receiver) 0 Busy (Channel is busy or affected by interference) 3116 Accuracy: inf %


gioblu commented 7 years ago

Ciao @nomeme I have labeled this issue as an enhancement and not a bug, because Pro Mini is not a compatible device, and we are effectively now porting this device :). Other contributors and users asked a porting for ESP, that is actually work in progress.

I agree with you this is result of a timing issue as you correctly exposed. I do think that for both ESP and PRO mini a slight offset has to be added in the timing configuration (as happens in SoftwareBitBang) to have nominal transmission on different architectures. I was waiting for requests like yours to make this step.

Sadly I do not have in hands a PRO-mini to test by myself the timing offset, but I can prepare and push for you the necessary conditions (with default values) dedicated to pro mini, in the timing.h file where to try to get the correct value setup.

gioblu commented 7 years ago

@nomeme other thing, it could be necessary to add a READ_DELAY constant in OverSampling and so a sort of sync offset as synchronization_bit method does in SoftwareBitBang

nomeme commented 7 years ago

I'll gladly test it out. I was already tinkering with the Timing.h file, but without deeper knowledge of the functions calling it, I could not find out which values would be modified in which way to yield the expected result. @gioblu where would i need to set the READ_DELAY value?

nomeme commented 7 years ago

@gioblu I know this is kind of off-topic but could PJON also be used with the NRF24L01 and which strategy would i need to use for it. Would be nice if one could use those in combination for long and short distances and depending on the amount of interference in the respective band.

gioblu commented 7 years ago

Ciao @nomeme take a look to the other issue, it maybe could be interesting seeing the actual packet in the oscilloscope: https://github.com/gioblu/PJON/issues/91

It is for sure easy to create a strategy (or interface) for NRF library/codebase it is another thing many users asked, but sadly I do not have the physical time to dedicate a streak to that also if I agree is highly interesting.

Speaking about the READ_DELAY value, take a look to SoftwareBitBang: https://github.com/gioblu/PJON/blob/master/strategies/SoftwareBitBang/SoftwareBitBang.h#L260 This method is called here: https://github.com/gioblu/PJON/blob/master/strategies/SoftwareBitBang/SoftwareBitBang.h#L163 As you can see, one of the offsets is inserted in this method being architecture / mcu / clock specific.

On the other hand here in OverSampling: https://github.com/gioblu/PJON/blob/master/strategies/OverSampling/OverSampling.h#L160 there is no offset at all in the low padding bit. This is what I was meaning as maybe necessary.

Here wiki page related to timing: https://github.com/gioblu/PJON/wiki/Troubleshooting

I will tonight push for you the necessary changes to experiment with timing with the same "framework" proposed in SoftwareBitBang. Feel free to add me in gitter if you need direct communication for support / questions.

nomeme commented 7 years ago

Ok I'll have a look into it tomorrow thank you very much for your support. Would be really great if we can solve this issue for the pro mini. Maybe, with your assistance, I will be able to add the strategy for the NRF later on. thank you very much again.

gioblu commented 7 years ago

Ciao @nomeme I still didnt push because, it is not clear for me if exists a constant defined to identify the Pro Mini on the IDE level and use it for our need. It is for sure possible define a dedicated constant like ARDUINO_PRO_MINI to idefintify it, but I bet exists already, and I would not add duplication, obviously.

Cleared out this, I think Timing.h simply should be edited as following:

#if defined(__AVR_ATmega88__) || defined(__AVR_ATmega168__) || defined(__AVR_ATmega328__) || defined(__AVR_ATmega328P__)
  #if _OS_MODE == _STXRX882_STANDARD
    #if F_CPU == 16000000L
      #if ARDUINO_PRO_MINI (or similar)
        #define OS_BIT_WIDTH   512 (or other value)
        #define OS_BIT_SPACER  328 (or other value)
      #endif
      #ifndef OS_BIT_WIDTH
        #define OS_BIT_WIDTH   512
      #endif  
      #ifndef OS_BIT_WIDTH
        #define OS_BIT_SPACER  328
      #endif
    #endif
  #endif
#endif
gioblu commented 7 years ago

@nomeme speaking about the READ_DELAY, being the oversampling mechanism different, I would add it only if really necessary to get it working. So I would give a try slightly changing the bit and bit spacer duration, without considering the delay addon.

gioblu commented 7 years ago

@nomeme obviously a pull is suggested to get master. I pushed today the fix to the HALF_DUPLEX mode, that for sure was contributing to affect communication in your test.

See https://github.com/gioblu/PJON/issues/91

nomeme commented 7 years ago

@gioblu It is working without additional tinkering. I just pulled your commit and flashed the OverSamplingNetworkAnalysis to two pro minis and it seems to be working quite well:

PJON - Network analysis Starting a 5 second communication test..

Absolute com speed: 26.00B/s Practical bandwidth: 20.00B/s Packets sent: 5.00 Mistakes (error found with CRC) 0.00 Fail (no answer from receiver) 0 Busy (Channel is busy or affected by interference) 10 Accuracy: 100.00 %


Absolute com speed: 57.20B/s Practical bandwidth: 44.00B/s Packets sent: 11.00 Mistakes (error found with CRC) 0.00 Fail (no answer from receiver) 0 Busy (Channel is busy or affected by interference) 5 Accuracy: 100.00 %


Absolute com speed: 36.40B/s Practical bandwidth: 28.00B/s Packets sent: 7.00 Mistakes (error found with CRC) 0.00 Fail (no answer from receiver) 0 Busy (Channel is busy or affected by interference) 8 Accuracy: 100.00 %


Sometimes accuracy drops to 80% but i think that is due to interference on the channel. This really saved my project. Thank you very much for the quick fix it seems to be working really well now.

gioblu commented 7 years ago

@nomeme please soon pull new commits for a small fix and new examples showing how to use async ack with OverSampling.

nomeme commented 7 years ago

@gioblu I'll surely give it a try, thank you. I also discovered an additional issue when using PJON in a libraries .cpp file see #111

Don't know if this is easy to fix or even intended, but for me seems to look like a bug.

gioblu commented 7 years ago

@nomeme thank you again, it seems so, but I need a second to dig. This is the new example: https://github.com/gioblu/PJON/tree/master/examples/Network/OverSamplingHalfDuplex

In master you find the fixes I was speaking about

nomeme commented 7 years ago

So du you require a second test run with the new example code? Sorry unfortunately I was busy last weekend but I'm looking forward to be able to work on it coming weekend. Just a quick question regarding the example code.

Why are you initialising the transmitter with bus.set_asynchronous_acknowledge(true); bus.set_synchronous_acknowledge(false);

but the receiver only with

bus.set_synchronous_acknowledge(false);

I'll start a test run as soon as possible if you require one with the given settings.

Kind regards.

gioblu commented 7 years ago

Ciao @nomeme receiver will respond as requested by the packet configuration it receives. So if Transmitter sends a packet containing ACK_MODE_BIT up, this will trigger an asynchronous acknowledgment on the receiver side. This let many differently configured devices and group of devices to coexist on the same medium doing different things.

gioblu commented 7 years ago

@nomeme forgot to say that In the example I disable the synchronous acknowledgment on receiver side, to avoid requesting a synchronous acknowledgment for an asynchronous acknowledgment packet. That in some cases can be effective, and is called "Recursive acknowledgment pattern" but in this particular usecase is ineffective because of the long time needed for those modules to refresh their reception gain after a local transmission. Would obviously nice to have some testing. Thank you for your support to the project.

gioblu commented 7 years ago

Ciao @nomeme have you got the chance to try it? Can I consider this issue solved and OS stable on Pro Mini?

nomeme commented 7 years ago

Ok i was trying to run it with strange results, at some point it works quite well. Reliable blinking, sometimes there is not even any blinking. Unfortunately i mostly get error messages on the transmitter side. Recently i got like 4 consecutive transmits with ack, but then again not even blinking on receiver side. Sorry for not replying faster, but currently I got too much stuff to do and my free time suffers from that. Ok I'm beginning to see a pattern here. If the receiver is blinking I mostly get the ack, but somehow the packet to the receiver gets lost pretty often. NetworkAnalysis local gives 100% accuracy

gioblu commented 7 years ago

Ciao @nomeme watch out for bad connections and potential sources of interference! Other thing if you are not using STX882 / SRX882 modules but general "green ones" you may have to change OS_PREAMBLE_PULSE_WIDTH to a different duration.

in the course of the last week OverSampling on master was not stable and I tinkered quite a while, before and after your successful test. I have the feeling that simply tweaking OS_PREAMBLE_PULSE_WIDTH will get back working nominally, also because for now I still haven't developed a dedicated mode optimized for the green ones (and it could be a first step in that direction)

nomeme commented 7 years ago

Yes I'm using the "green ones"

I don't think that I can follow. The local/NetworkAnalysis is running with 100% success rate. Whereas the network/OversamplingHalfDuplex does seem to have a lot of loss transmitting. Is it using a different codebase or why would changing OS_PREAMBLE_PULSE_WIDTH have a positive effect on only the network/halfduplex.

Anyways will tinker around with it a bit and see what happens.

gioblu commented 7 years ago

CIao @nomeme, the tricky thing is to make 2 couples of tx/rx to transmit in half duplex. OverSampling simplex mode is tested and now finally quite accurate. I got it working nominally with default configuration on Uno, Nano, Duemilanove, Mega, Leonardo and Micro also in half-duplex ( network/OversamplingHalfDuplex) with 150/200 meters range in urban environment usign STX/SRX882.

OS_PREAMBLE_PULSE_WIDTH is the duration of the packet preamble necessary for the receiver module to have the time to tune back its sensitivity to the magnitude of the source. The gain sensitivity refresh issue appear only in half-duplex because of the transmitter's vicinity to the receiver (in half-duplex you have a pair on each device), so when a device locally transmits, it is also temporarily blinding its receiver and it will need some time to set its gain back to the magnitude of the more distant transmitter. The "green ones" could need a different preamble duration to let sensitivy to set back (it could also be shorter), for this reason I was suggesting tinkering with them. If we can find an optimal value for those modules, we could create another mode as _STXRX882_STANDARD maybe _ASK_FSK_GREEN_STANDARD.

nomeme commented 7 years ago

Yea but the Local/OverSamplingHalfDuplex runs fine, the issue is only with the Network/OverSamplingHalfDuplex And honestly i only receive the first packet for the Network example. The rest is simply lost. By now I don't think it is a transmission or channel issue but a problem with the Network code, because the hardware seems to work quite well with the Local example.

If I remove these lines at least it starts blinking:

  //bus.set_asynchronous_acknowledge(true);
  //bus.set_synchronous_acknowledge(false);

Still i get some error messages

in the default config only the first packet arrives -> blinking and then nothing more happens, not even error messages on transmitter side.

Ok I don't get it. There are no error messages in the default Network/OverSamplingHalfDuplex but for some reason the delay between the blinks is from 2s to 40s

Ok starting with 300000 for OS_PREAMBLE_PULSE_WIDTH I start receiving data on the receiver. The delay variance is therefore quite high ranging from 5 to 40 sec.

Sorry I did not quite get what you were trying to achieve here.

I was trying to find the sweet spot where delay variances are the lowest or nonexistent. i tried values from 50000 to 2000000 and there were still variances. The lowest being probably around 500000 to 700000.

Ok, no matter what i tried, i could not get the packets to be delivered always at first try. If the preamble was too short nothing was received on receiver side. I stared to receive packets at 200000. I tried increasing the values. Reception never was perfect. I guess the variance in reception times comes from retransmissions. It tends to get worse again starting at values higher than 1000000. Still, at It's very best being at around 500000 to 700000 the receiver sometimes did not get any packets for 10 to 20 sec, sometimes even 40 sec with fastest transmission times being around 3.2 sec.

I would like to provide further support here, but honestly I don't know the difference between the Network/OverSamplingHalfDuplex and the Local/OverSamplingHalfDuplex. Could you explain it quickly so I can maybe look a bit more into detail. Especially why they seem to perform so differently. I mean, both of them use packet acknowledgement, so there should be not that much difference. Am I right?

Regards.

gioblu commented 7 years ago

Ciao @nomeme, thank you for your precious support and testing. What is happening:

You exposed a known bug / strong limitation will be fixed in the next release, and soon pushed (still in testing). send_repeatedly method is not calling error in case of transmission failure and also doesn't try more than once every interval, if packet has been configured with async ack.

Considering that you are experiencing many times the packet to be retransmitted to be effectively delivered, it seems send_repeatedly issue in network may be, the, or a part of, the cause :) But it should not be repeated twice in the first place to be delivered!

It may be a good test to isolate the problem using the send method cyclically called instead and see what happens.

I forgot before to mention that it could be necessary to tune the time dedicated to reception passed as parameter to the receive(microseconds) method on both sides.

nomeme commented 7 years ago

Ok so what you suggest would be sending the packet every view seconds. See if the packet gets received on the other side by checking whether an ACK or sth. else gets sent back to the transmitter. In order for the packets to be received the receive function on receiver side needs to be called with a value > preamble. On transmitter side, we do the same by sending a packet of the same content back. Therefore we again have to call the receive with the same value as on receiver side. And then maybe add successful and unsuccessful to get some statistics.

Did I get that right? Regards

gioblu commented 7 years ago

Ciao, @nomeme sorry for the delay, yes, send a packet every second using send and a while micros - time try for example every 10 seconds (to avoid as described before the send repeatedly issue). I am not sure about the receive duration implications but I suspect it could be the case. try simply changing its value. I yesterday worked to provide the you and community with the send_repeatedly fix,, hope tonight to be able to push it after re-testing.

gioblu commented 7 years ago

Ciao @nomeme, the bug you reported has been fixed with the referenced commit above. Let me know your tests results if you can. Thank you again.

nomeme commented 7 years ago

Hi @gioblu, I' am using the latest version of PJON and the Network/OverSamplingHalfDuplexexample. No matter what i set for OS_PREAMBLE_PULSE_WIDTH. The first message is received on receiver side. The rest is lost. I set values from 100000 to 900000 with no apparent improvement.

The only thing improving it a little bit is setting the value of OS_PREAMBLE_PULSE_WIDTH to sth. like 400000 and increasing the value in bus.receive() on transmitter side to as much as 500000. This causes the messages to arrive on receiver side. But several times. Also the ACK's still seem to get lost. But i do not know if all of them get lost.

nomeme commented 7 years ago

Hi @gioblu, I then continued with our proposed test.

Transmitter

/* Include Async ACK code setting INCLUDE_ASYNC_ACK as true before including PJON.h */
#define INCLUDE_ASYNC_ACK true

#include <PJON.h>
uint16_t packet;
uint8_t bus_id[] = {0, 0, 0, 1};

// <Strategy name> bus(selected device id)
PJON<OverSampling> bus(bus_id, 45);

void setup() {
  Serial.begin(9600);
  pinMode(13, OUTPUT);
  digitalWrite(13, LOW); // Initialize LED 13 to be off

  bus.strategy.set_pins(11, 12);
  /* A packet containing the id of every packet received will be sent back
     by this device to the packet's sender to acknowledge packet reception.
     (With this setup you can avoid sending packet duplicates) */
  bus.set_asynchronous_acknowledge(true);
  bus.set_synchronous_acknowledge(false);
  bus.set_error(error_handler);
  bus.begin();

  //packet = bus.send_repeatedly(44, "B", 1, 2000000);
  /* Send B to device 44 every 2 seconds.
     Try to avoid to consinuosly jam the entire zone around you.
     Consider that many appliances and remotes around you are affected by
     PJON packet flooding occurring in this sketch, for this reason try to
     run your tests for short timeframes.
     DO NOT FORGET THIS SKETCH TRANSMITTING ALL DAY LONG :) */
}

void error_handler(uint8_t code, uint8_t data) {
  if(code == CONNECTION_LOST) {
    Serial.print("Connection with device ID ");
    Serial.print(data);
    Serial.print(" - ");
    Serial.print(micros());
    Serial.println(" is lost.");
  }
  if(code == PACKETS_BUFFER_FULL) {
    Serial.print("Packet buffer is full, has now a length of ");
    Serial.println(data, DEC);
    Serial.println("Possible wrong bus configuration!");
    Serial.println("higher MAX_PACKETS in PJON.h if necessary.");
  }
  if(code == CONTENT_TOO_LONG) {
    Serial.print("Content is too long, length: ");
    Serial.println(data);
  }
};

long timestamp = millis();
int counter = 0;
void loop() {
  bus.update();

  if ((long)(millis()-timestamp)>2000) {
    char content[] = {'B',counter>>8,counter&0xff};
    Serial.print("sending: ");
    Serial.println((int)counter);
    bus.send(44,content,3);
    timestamp = millis();
    counter++;
  }
  bus.receive(50000); // Receive for 50 milliseconds
};

Receiver:

/* Include Async ACK code setting INCLUDE_ASYNC_ACK as true before including PJON.h */
#define INCLUDE_ASYNC_ACK true

#include <PJON.h>

uint8_t bus_id[] = {0, 0, 0, 1};

// <Strategy name> bus(selected device id)
PJON<OverSampling> bus(bus_id, 44);

void setup() {
  pinMode(13, OUTPUT);
  digitalWrite(13, LOW); // Initialize LED 13 to be off

  Serial.begin(9600);
  bus.strategy.set_pins(11, 12);
  bus.begin();
  bus.set_receiver(receiver_function);
  bus.set_synchronous_acknowledge(false);
};

void receiver_function(uint8_t *payload, uint16_t length, const PJON_Packet_Info &packet_info) {
  if(payload[0] == 'B') {
      Serial.print("received ");
      Serial.println(payload[1] << 8 | payload[2] & 0xFF);
    digitalWrite(13, HIGH);
    delay(5);
    digitalWrite(13, LOW);
    delay(5);
  }
}

void loop() {
  bus.update();
  bus.receive(50000); // Receive for 50 milliseconds
};

This seems to work quite well with the default values. The packets are received on receiver side reliably until the packet buffer in the transmitter is full, because the ACK's are lost.

Setting the delay between packets from 2000 to 10000 I can remove the packet buffer overflow but even with OS_PREAMBLE_PULSE_WIDTH set to 1500000, no ACKs.

Increasing OS_PREAMBLE_PULSE_WIDTH to higher values increases packet loss in the receiver but does not improve the percentage of ACKs received, as there are none received ever, but the first. The first ACK is always received, from what I can tell. Decreasing OS_PREAMBLE_PULSE_WIDTH on the other hand improves reception of packets on receiver side.

So I would guess that the problem here is somewhere in the network stack and not in physical limitations of the channel.

gioblu commented 7 years ago

Ciao @nomeme I made a test probing with an oscilloscope and connecting Arduino Mega and Arduino Duemilanove through 2 simple wires, running the network/OverSamplingHalfDuplex to determine if there could be some issue in the stack, excluding the radio physical layer.

This is the visual result: img_0407

I get 100% accuracy with ACK always received. (if I disconnect the devices error is correctly thrown). I get the same result hooking up 2 couples of STX/SRX882. I would suggest you to give it a try in the same way, you may discover an issue in the physical layer used.

nomeme commented 7 years ago

Ok i can try that. Also what i just came up with would be turning the acknowledgement off and try sending my own packet as acknowledgement in order to find out if there could be an issue considering the timeout of the acknowledgement. I find this rather confusing, as the ack in the local example works quite well.

gioblu commented 7 years ago

Ciao @nomeme I agree, it seems strange if you get those results with the sync ACK. What happens running the async example through wires? Thank you for your support.

nomeme commented 7 years ago

Hi I finally got to digging deeper into this. Now i get some fairly reliable conditions using some really special configuration. I will update this with the parameters set to establish it. Firstly: I was wrong about the Local examples working. The ACK was not received.

Using #define OS_PREAMPLE_PULSE_WIDTH 500000 I got a fairly reliable result in the Local/OversamplingHalfDuplex.

Using this modified example code:

#define OS_MAX_ATTEMPTS 1

#include <PJON.h>
// <Strategy name> bus(selected device id)
PJON<OverSampling> bus(44);

int timeout = 500;
int count = 0;
signed long timestamp;

void setup() {
  pinMode(13, OUTPUT);
  digitalWrite(13, LOW); // Initialize LED 13 to be off

  bus.strategy.set_pins(11, 12);
  bus.set_receiver(receiver_function);
  bus.set_error(error_handler);

  bus.begin();
  timestamp = millis()+timeout;
  Serial.begin(9600);
};

void receiver_function(uint8_t *payload, uint16_t length, const PJON_Packet_Info &packet_info) {

}

void error_handler(uint8_t code, uint8_t data) {
  if(code == PJON_CONNECTION_LOST) {
    Serial.print("Connection with device ID ");
    Serial.print(bus.packets[data].content[0], DEC);
    Serial.println(" is lost.");
  }
  if(code == PJON_PACKETS_BUFFER_FULL) {
    Serial.print("Packet buffer is full, has now a length of ");
    Serial.println(data, DEC);
    Serial.println("Possible wrong bus configuration!");
    Serial.println("higher PJON_MAX_PACKETS if necessary.");
  }
  if(code == PJON_CONTENT_TOO_LONG) {
    Serial.print("Content is too long, length: ");
    Serial.println(data);
  }
};

int get_packet_count() {
  int result = 0;
  for(uint16_t i=0; i< PJON_MAX_PACKETS;i++){
    if(bus.packets[i].state != 0) {
      result++;
    }
  }
  return result;
}

void loop() {
  if(timestamp-(signed long)millis()<=0) {
    int pending = get_packet_count();
    Serial.print("Pending packages: ");
    Serial.println(pending);
    if(pending <=0) {
    Serial.println("Sending...");
    bus.send(45, "B", 1);}
    timestamp=millis()+timeout;
  }
  /*uint16_t result = bus.receive(5000000);
  if (result==PJON_ACK) {
    Serial.println("Got Ack!");
  }else if(result == PJON_FAIL){
  }else{
    Serial.println(result);
  }*/
  bus.update();
};
#include <PJON.h>

// <Strategy name> bus(selected device id)
PJON<OverSampling> bus(45);

void setup() {
  pinMode(13, OUTPUT);
  digitalWrite(13, LOW); // Initialize LED 13 to be off
  bus.set_error(error_handler);
  bus.strategy.set_pins(11, 12);
  bus.set_receiver(receiver_function);

  bus.begin();

  //bus.send(44, "B", 1);

  Serial.begin(9600);
};

void receiver_function(uint8_t *payload, uint16_t length, const PJON_Packet_Info &packet_info) {
  /* Make use of the payload before sending something, the buffer where payload points to is
     overwritten when a new message is dispatched */
  if((char)payload[0] == 'B') {
    //bus.reply("B", 1);
    digitalWrite(13, HIGH);
    delay(100);
    digitalWrite(13, LOW);
  }
}

void error_handler(uint8_t code, uint8_t data) {
  if(code == PJON_CONNECTION_LOST) {
    Serial.print("Connection with device ID ");
    Serial.print(bus.packets[data].content[0], DEC);
    Serial.println(" is lost.");
  }
  if(code == PJON_PACKETS_BUFFER_FULL) {
    Serial.print("Packet buffer is full, has now a length of ");
    Serial.println(data, DEC);
    Serial.println("Possible wrong bus configuration!");
    Serial.println("higher PJON_MAX_PACKETS if necessary.");
  }
  if(code == PJON_CONTENT_TOO_LONG) {
    Serial.print("Content is too long, length: ");
    Serial.println(data);
  }
};

void loop() {
  bus.receive(5000000);
  bus.update();
};
gioblu commented 7 years ago

ciao @nomeme, cool! Thank you for your feedback, curious to see what you ended up with.

nomeme commented 7 years ago

I added some debug output to the lib to detect whether the ACK was received or not. This made it far more easy to find out what was going wrong. I will start looking hat the network example in the next view days. Also ordered an additional set of pro minis to check for compatibility issues.

nomeme commented 7 years ago

Hi, I got to checking out the network example. Using the asynchronous ack mode, it seems that the sender actually receives a packet. But the packet is handled as broadcast packet. It actually enters this if branch after receiving the response:

strategy.send_string((uint8_t *)string, length);
        if(
          string[0] == PJON_BROADCAST ||
          !(config & PJON_ACK_REQ_BIT) ||
          _mode == PJON_SIMPLEX
        )

A bit more documentation in the code would make debugging much more easy. I don't really know what the difference is but it seems to be like this:

handle_asynchronous_acknowledgement seems to fail, therefore it enters the next if branch and calls dispatch() directly, which is then received on sender side and causes it to interpret this packet as broadcast packet.

Up to now I do not understand why this would make any difference, still digging. Ok I don't really get what is going on there. As far as I could understand the synchronous ACK seems to work quite well, whereas the async ack mode does work in approximately 5% of the send attempts.

Ok it seems like when modifying your example so receive for up to 1s the async ACK packets receive rate starts to increase to approximately 50%.

Ok I got it working quite reliably, there seems to be quite a noise on that channel around here, but i also got some quite stable connections. But there seems to be some delay() necessary between the bus.send() and bus.update() calls. Otherwise the packets would not arrive at receiver side. What's funny is that most ACK packets where received on sender side. So thats what got me thinking about excessive noise on the channel at some times, when otherwise everything was running quite smooth. Delays of 50ms were sufficient even to it down to 5ms running quite stable. Still confused at what might be causing this. Maybe you could give me some feedback at what could be going wrong.

In summary, all modes seem to run fast with OS_PREAMBLE_PULSE_WIDTHat 400000.

Regards.

gioblu commented 7 years ago

ciao @nomeme, please include me here the code headed you to successful results and which sort of hardware you use (I mean which modules) Im happy to hear that you got it working fine.

It could be nice to dedicate a mode to the cheap green modules, because for now you were using a mode originally dedicated to STX/RX882

gioblu commented 7 years ago

Hei @nomeme maybe I have found the cause of your last reported issue: https://github.com/gioblu/PJON/commit/0bfb8889e84aa8bb07a877aef73e382ce7a2d9fe

now with sync + asinc ack it should work fine :) If you can, give a try to master.

nomeme commented 7 years ago

ok so i got it running really stable with synchronous acknowledge and 400000 for OS_PREAMBLE_PULSE_WIDTH. Will give async ack a try asap.

Regards

nomeme commented 7 years ago

Hi,

I had some spare time on my hands the last days and did some testing with those cheap 433 MHZ. The problem seems to persist and the cause seems to be the hardware itself. The transmitters and receivers generate so much noise that on most attempts to send data the channel is being reported as busy. I tried adding a 10k resistor between and and data to pull the receiver down to ground if nothing is sent, no positive results. Also tried capacitors 200n to 1u between and and data line, still nothing.

Do you have any suggestion in how to improve the circuit to filter out the noise? Otherwise it seems that this kind of rf device is just not fit for half duplex transmissions as the noise is too big.

Kind regards

gioblu commented 7 years ago

ciao @nomeme the noise you get could come from third-party sources, and could be real RF noise. In our homes there are many systems that could produce noise on the 433/434 band, for example the power line transceivers.

Before trying to adopt changes to the circuit, try to determine if this sort of RF interference is present specially if this behavior is intermittent and not always present in your tests.

The suggested pull down resistor on the receiver pin is 1-5Mohm, capacitor on data line disrupts binary transitions and bit timing and should be avoided.

One way to try to filter incoming noise is to change antenna shape / length / position / orientation

It is important to feed receiver and transmitter with a stable and regulated power supply (for example the 5v out of the 7805)