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

extend range with rs485? #61

Closed domonetic closed 8 years ago

domonetic commented 8 years ago

my installation it is very extensive. I'm about to try using PJON as protocol, but using rs485 like interface. Analyzing the code I see very optimal to send commands as I need. I'm trying to control remotely access a door, which sent a command it must receive a state when someone accesses through a RDIF tag.

I have some questions:

The master (data collector) should send commands long variables. Example: open, 1 character Add a tag, 10 characters

  1. Can handle variable data, or should I define a maximum?
  2. In the begin () function use analogRead can cause problems if this pin is used as part of the program to another function as a digital pin.
  3. What happens if I try to access beyond the long, assuming that the data entered and which I hope is not?
gioblu commented 8 years ago

This is really interesting. Please explain me more in particular which risks you see using analogRead on pin 0. Do not use NULL terminator strategy to determine data length. Is not safe, if a 0 is transmitted in your datastream can be detected as the end of the string. Use always the length of your data to determine its end. Maximum determination can be a solution,

domonetic commented 8 years ago

When using analogRead after setup the pin is configured as analog, and if i use this pin as digital can fail. I do not understand the rest. In theory if the package is right one, I can know the length of the data received? If send 5 byte and access to position payload [6] what happens?

gioblu commented 8 years ago

Yes you can. If you read out of the variable, if I am not mistaken, you will read the rest of the memory.

domonetic commented 8 years ago

rest of the memory between MAX_LEGHT_PACKET. out of this vector cause error or freezzing

gioblu commented 8 years ago

Ciao @domonetic how its going?

domonetic commented 8 years ago

This weekend I try . I've had a tough week

-----Mensaje original----- De: "Giovanni Blu Mitolo" notifications@github.com Enviado el: ‎30/‎04/‎2016 07:47 Para: "gioblu/PJON" PJON@noreply.github.com CC: "Maximiliano Duarte" maximiliano.duarte@gmail.com; "Mention" mention@noreply.github.com Asunto: Re: [gioblu/PJON] extend range with rs485? (#61)

Ciao @domonetic how its going? — You are receiving this because you were mentioned. Reply to this email directly or view it on GitHub

gioblu commented 8 years ago

Ciao @domonetic, now PJON supports 2 pins, I think can be useful for this experiment :+1: Take a look to the 3.0 beta now released.

domonetic commented 8 years ago

I see it and test.

-----Mensaje original----- De: "Giovanni Blu Mitolo" notifications@github.com Enviado el: ‎06/‎05/‎2016 00:24 Para: "gioblu/PJON" PJON@noreply.github.com CC: "Maximiliano Duarte" maximiliano.duarte@gmail.com; "Mention" mention@noreply.github.com Asunto: Re: [gioblu/PJON] extend range with rs485? (#61)

Ciao @domonetic, now PJON supports 2 pins, I think can be useful for this experiment
Take a look to the 3.0 beta now released. — You are receiving this because you were mentioned. Reply to this email directly or view it on GitHub

domonetic commented 8 years ago

Wow!! is incredible change. I've only seen the code and it really is very neat and advanced programming. My congratulations. Right now, I go along with the RS485 interface to put into practice.

domonetic commented 8 years ago

I think it would take in version 2 pin an output toggle to switch RX / TX. If the pin is assigned to transmit put the output high

gioblu commented 8 years ago

Thank you :+1: "Right now, I go along with the RS485 interface to put into practice." What you mean?

"I think it would take in version 2 pin an output toggle to switch RX / TX. If the pin is assigned to transmit put the output high" I can't understand what you mean

domonetic commented 8 years ago

in rs485(max485 or 75175) chip to Transmit in simplex you need put pin 2&3 to high. And receive data put 2&3 to low. Because otherwise, sending you get an echo

gioblu commented 8 years ago

So if I am not mistaken you are reporting the necessity of passing both pins to the strategy functions to have the chance to correctly implement RS485?

domonetic commented 8 years ago

Yes

-----Mensaje original----- De: "Giovanni Blu Mitolo" notifications@github.com Enviado el: ‎06/‎05/‎2016 18:52 Para: "gioblu/PJON" PJON@noreply.github.com CC: "Maximiliano Duarte" maximiliano.duarte@gmail.com; "Mention" mention@noreply.github.com Asunto: Re: [gioblu/PJON] extend range with rs485? (#61)

So if I am not mistaken you are reporting the necessity of passing both pins to the strategy functions to have the chance to correctly implement RS485? — You are receiving this because you were mentioned. Reply to this email directly or view it on GitHub

gioblu commented 8 years ago

You are right, thank you for the report. I will now test the effect of this modifications and push it. Question, you would implement this by yourself or you would use another library inside your strategy? You want to use interrupts?

domonetic commented 8 years ago

Interruptions no. you can use a strategywith toggle pin. Is more clear. It is simpler. Send or Send_byte the function must switch to Tx while a data is sentand back immediately to RX. Why do I do outside? Because if I have packets periodicals as send(44, c, 1, 1000); I can not have control of the TX / RX line. It is also important that the library has control over delays to rehear correctly.

Excuse my English

gioblu commented 8 years ago

So if I understood correctly you would use a software emulated bit bang strategy to emulate rs485 through a PJON strategy you want to wright by yourself?

If you are implementing your strategy and you need to read the pin, inside the send_byte function, you can. WIth the modification you proposed, both pins will be passed to the strategy and so you will be able to define your dedicated function inside the strategy where to do what you need with the input pin, while transmitting.

What you mean to "do it outside"? What you mean with "control over delays"?

gioblu commented 8 years ago

https://github.com/gioblu/PJON/commit/2c6fe7f0caf01459c3083f68378f02ffc6cadd65

domonetic commented 8 years ago

My apologies for the delay. It is simpler but my C ++ is very bad and not doing must inherit from SoftwareBitBang and override the send_byte function to enable transmission (DTR), but the methods must be defined as virtual in a base class and inherit these in each strategy, so inheriting code is saved only as needed

_Mis disculpas por la demora. Es mas simple pero mi C++ es muy malo y no se hacerlo Debe heredarse de SoftwareBitBang, y sobreescribir la funcion sendbyte para que habilite la transmisión (DTR), pero los metodos deben estar definidos como virtuales en un clase base y de estos heredar en cada estrategia, asi se ahorra codigo heredando solo lo necesario

Pseudo example:

#include ".Timing.h"

class rs485(SoftwareBitBang or class base) {
  public:
    //override method
    void send_byte(uint8_t b, uint8_t input_pin,uint8_t output_pin, uint8_t dtr_pin) 

//implementation
void rs485::send_byte(uint8_t b, uint8_t input_pin,uint8_t output_pin, uint8_t dtr_pin) 
{
      digitalWriteFast(dtr_pin, HIGH);
      self::send_byte(b,input_pin,output_pin); //CALL METHOD BASE
      digitalWriteFast(dtr_pin, LOW);
}
domonetic commented 8 years ago

shieldrs485

gioblu commented 8 years ago

Ciao @domonetic! Happy to see you going forward with this. If I got correctly what you mean, you want to extend SoftwareBitBang class with your new rs485, you need to redefine send_byte, but at the same time you need the old version : ), right?

domonetic commented 8 years ago

Yes. Only need add set to high pin dtr, send byte and set to low the pin dtr. If you see is simple to implement. But why implement all methods?. If inherited only send_byte can call the ascent.

Do you understand?

-----Mensaje original----- De: "Giovanni Blu Mitolo" notifications@github.com Enviado el: ‎16/‎05/‎2016 19:01 Para: "gioblu/PJON" PJON@noreply.github.com CC: "Maximiliano Duarte" maximiliano.duarte@gmail.com; "Mention" mention@noreply.github.com Asunto: Re: [gioblu/PJON] extend range with rs485? (#61)

Ciao @domonetic! Happy to see you going forward with this. If I got correctly what you mean, you want to extend SoftwareBitBang class with your new rs485, you need to redefine send_byte, but at the same time you need the old version : ), right? — You are receiving this because you were mentioned. Reply to this email directly or view it on GitHub

gioblu commented 8 years ago

Clear, you are right virtual in SoftwareBitBang is necessary.

to access to the base class method see: http://stackoverflow.com/questions/10177809/c-extend-inherited-functions I am not sure self:: is right, but more probably SoftwareBitBang??

I will have to run the tests for all the architectures to be sure not to brake nothing, that now become quite long so, I will make this modification in the next release if this doesn't affect a potential pull request for this from you.

Can you please go further in development editing by yourself this in your file for now? Or you are suggesting to me to make this addon by myself? Because for now I could not be able to practically test it, not having a working setup of this sort, but I can help you if necessary to have it working :+1:

domonetic commented 8 years ago

As I said, my c ++ is bad, I am programmer Object-Pascal and I did not find how. now I got it. In delphi there is a class inheritance, which new items are released. To json should be so. virtualizing base class methods that will possibly be overwritten for other platforms, using a single timing.h. This mode reduces significantly and more extensible code. Besides the communication process will be always assured. Sorry to interfere in their thinking.

Como le dije, mi c++ es malo, soy programador de Object-Pascal y no encontre como hacerlo. ahora lo tengo. En delphi existe una herencia de la cual se desprenden nuevos objetos. Para json deberia ser asi. Clase base virtualizando los metodos que van a ser posiblemente sobreescritos para otras plataformas, usar un timing.h. De este modo se reduce el codigo notablemente y mas extensible. Ademas de que el proceso de comunicacion va a estar siempre asegurado. Perdon por interferir en su pensamiento.

class BasePJON { protected: virtual void send_byte(uint8_t b, uint8_t input_pin,uint8_t output_pin); virtual uint8_t read_byte(); virtual uint16_t get_response();

uint8_t read_byte(uint8_t pin);
uint16_t receive_byte(uint8_t pin);
uint16_t get_response(uint8_t pin);

public: uint8_t syncronization_bit(uint8_t pin) {

};

void BasePJON::send_byte(uint8_t b, uint8_t input_pin,uint8_t output_pin);


Strategy SotwareBigBang

class SotwareBigBang: public BasePJON { Public: //make public a protected method BasePJON::send_byte(uint8_t b, uint8_t input_pin,uint8_t output_pin); }

SotwareBigBang::send_byte(uint8_t b, uint8_t input_pin,uint8_t output_pin); { //add extra control if need //call inherited basePJON::send_byte(b,input_pin,output_pin); //or can create different procces to send byte

}

2016-05-16 23:51 GMT-03:00 Giovanni Blu Mitolo notifications@github.com:

Clear, you are right virtual in SoftwareBitBang is necessary.

to access to the base class method see: http://stackoverflow.com/questions/10177809/c-extend-inherited-functions I am not sure self:: is right, but more probably SoftwareBitBang??

I will have to run the tests for all the architectures to be sure not to brake nothing, that now become quite long so, I will make this modification in the next release if this doesn't affect a potential pull request for this from you.

Can you please go further in development editing by yourself this in your file for now? Or you are suggesting to me to make this addon by myself? Because for now I could not be able to practically test it, not having a working setup of this sort, but I can help you if necessary to have it working [image: :+1:]

— You are receiving this because you were mentioned. Reply to this email directly or view it on GitHub https://github.com/gioblu/PJON/issues/61#issuecomment-219606436

El que pregunta aprende, y el que contesta aprende a responder.

No a la obsolecencia programada: http://www.rtve.es/noticias/20110104/productos-consumo-duran-cada-vez-menos/392498.shtml

Linux User #495070 http://domonetic.com/blog

gioblu commented 8 years ago

It's not interfering but supporting with passion. Thank you for your suggestion. Let me experiment a little with your codebase.

gioblu commented 8 years ago

CIao @domonetic, thank you for your precious suggestions. I worked yesterday to completely abstract the physical layer out of PJON.h (pinModeFast, digitalWritFast) and also to create the necessary strategy's methods. I think there is still the lack of a init_transmission() to set the pinMode. After this little addon, having a complete setup, I will start experimenting with the approach you proposed. I hope will be able to have something working and tested before the weekend.

domonetic commented 8 years ago

Wow, You are very fast. Please let me help you test

2016-05-18 13:01 GMT-03:00 Giovanni Blu Mitolo notifications@github.com:

CIao @domonetic https://github.com/domonetic, thank you for your precious suggestions. I worked yesterday to completely abstract the physical layer of out PJON.h (pinModeFast, digitalWritFast) and also to create the necessary strategy's methods. I think there is still the lack of a init_transmission() to set the pinMode. After this little addon, having a complete setup, I will start experimenting with the approach you proposed. I hope will be able to have something working and tested before the weekend.

— You are receiving this because you were mentioned. Reply to this email directly or view it on GitHub https://github.com/gioblu/PJON/issues/61#issuecomment-220074342

El que pregunta aprende, y el que contesta aprende a responder.

No a la obsolecencia programada: http://www.rtve.es/noticias/20110104/productos-consumo-duran-cada-vez-menos/392498.shtml

Linux User #495070 http://domonetic.com/blog

gioblu commented 8 years ago

Now Would be amazing to test the actual nominal functionality of:

I would have a good tests resolution to be sure :)

After a double check I will also do in tonight and tomorrow, I would finally dedicate some time to this issue you proposed and to understand how organize all with this new structure.

gioblu commented 8 years ago

Ciao @domonetic, I am finally back. I have released the 3.0 stable version with a quite extensive update. Take a look, I would be happy to know what you think about it. Now I think I have some time to try to help you / implement for you this strategy. Happy tinkering :+1:

Girgitt commented 8 years ago

Hi, Thank you @gioblu for your great work. I'm running my home automation system on a RS485 bus and considering switching from poling-based field protocol (based on ModbusRTU@153600bps) to multi-master PJON implementation and would like to suggest simplified approach of using RS485 as a physical layer.

@domonetic - did you try so called "auto-tx" RS485 setup? You don't need the third DTR pin if you extend the transceiver with a single transistor switching the driver to sending mode when TX is high; example: image

"Auto-tx" setup introduces dominant state of the bus (bus it kept at 0 until any node transmits 1). It works fine for me 24/7 for last 2+ years with 20-70 polls/sec.

"Auto-tx" RS485 should be transparent to SoftwareBitbang strategy configured for 2 pins however I have not tested it yet (still trying to get ACKs working in OverSampling strategy v4.1 with FS1000A modules)

gioblu commented 8 years ago

Ciao @Girgitt , I see this as a quite elegant solution! I was considering to develop an rs485 dedicated strategy on my return from vacation but your proposal seems another way to get away with it! Seeing so good results of SoftwareBitBang in terms of range and connected devices number, I was also considering to develop a SoftwareBitBang inverted twisted pair strategy, to emulate via software the RS485 procedure in auto-tx as you proposed to domonetic (working only with 5v 3v3 pin output) without any hardware addition. Which problems you are encountering with ACK and OverSampling?

domonetic commented 8 years ago

@Girgitt very good proposal , I will try how it works . thanks

Girgitt commented 8 years ago

Hi @gioblu, what a surprisingly fast response :) The problem I have may require separate thread but in few words: ACKs do not seem to come back to the transmitting node; maybe 1 out of 50 gets through but this number may be misleading as the default MAX_ATTEMPTS 125 may be clogging up the tx once message's delivery was not confirmed interrupting next transmission attempts.

Here is the test code I used based on the examples delivered with the library: TX, RX

Communication works both ways just fine when acknowledgement is turned off (RF link is fine bi-directionally - tested by switching the role of each node; I've added pull-down resistors to rx lines, caps to vcc, tested on 5, 9 and 12V VCC for TX module) but with ACK enabled TX repeats packets all the time. I made initial attempts to increase time window for response in strategies/OverSampling.h:receive_response, repeating sending ACKs, increasing bit/spacer length but nothing helps. After each modification operation was confirmed with point-point wired connection. RF connection tested each time at 20cm, 0,5m and 5m distance. Tested with bus.receive(1000); and bus.receive(); but this should not influence ACK anyway as it's synchronous.

gioblu commented 8 years ago

Ciao @Girgitt this is a known issue! And should obviously exposed in the issues! My miss. After a lot of testing I concluded that the problem is in the transmitter's receiver! After transmission the sensitivity is low because of the strong radiation of the transmitter near to the receiver, that will need to hear some far packets to regulate back its sensitivity to the necessary value to receive from higher distance! In srx886 the cs pin is present and sets the rx in sleep! At my return I will attempt to fix this problem modifying OverSampling to set the receiver in idle while transmitting! This should fix the problem!

Girgitt commented 8 years ago

Thank you @gioblu for valuable hints. Receiver's (XY-MK-5V) Vcc current is within ATMEGA328P's pin's max rating; let's test that.. what may go wrong? ;) Anyway loosing third pin just to control receiver's mode may be not worth the hassle and maybe RXB8 receiver will work better without additional modifications (I will give it a try if I find it). The turn on time is probably about ~10ms and other thing that comes to mind is delay before sending and receiving ACK - I'll try that as well.

gioblu commented 8 years ago

If you want to give it a try I would be inspired by the set serial implementation in ThroughHardwareSerial. So not changing the PJON code base but adding a function to the Strategy and handle it there

Girgitt commented 8 years ago

I tested using "auto-tx" RS485 PHY with two pins configuration of the SoftwareBitBang strategy. No go. I didn't use a logic analyzer but the auto-tx setup used the rx line picks up tx data which causes interference (^RE pin to gnd). This problem may be eliminated by connecting RS485 driver's pins ^RE to TE but I've already made driver boards and want to actually explore this "self-reading" feature to detect collisions at byte-level.

However I created a sketch of a strategy with collision avoidance to enable multi-master communication through the hardware serial port over auto-tx RS485 bus.

The initial draft handles 50 10-byte data packets per second just fine; tested with 3 nodes @153600 baud. looks promising - for my case it is a drop-in replacement (at the firmware-level) of the currently used field protocol.

When I'm done with testing I'll make a pull request. Draft version of the ThroughHardwareSerialRs485AutoTx stragegy is here: GIST

The multi-master setup also works with SoftwareSerial (making uploading easier as auto-tx interferes with arduino upload process) but code must be changed (control with #ifdef would be nice..) and baud should be lowered to e.g. 76800).

gioblu commented 8 years ago

Ciao @Girgitt this is really cool! Could ThroughHardwareSerial be modified to include your modifications instead of having two really similar strategies?? I agree with you that could really be nice to bring compatible also SoftwareSerial as you proposed!! Happy to hear satisfactory results from your side! I will be in a couple of days be back working and will be able to support you directly if necessary

Girgitt commented 8 years ago

Hi @gioblu, You're right the ThroughHardwareSerial can be easily extended instead of making a new strategy. Collision avoidance can be activated with e.g. set_collision_avoidance(bool) setter as in other strategies. As for SoftwareSerial support - my experience with Cpp classes may be too limited to provide proper/clean way of overriding the public serial pointer which should either be HardwareSerial or SoftwareSerial type - this is where your help would be appreciated. I'll check if serial will work when declared as Stream (not sure if polymorphism will do the trick but why not?).

The only reason behind the idea of creating a new strategy was possibility of handling byte-level collisions by reading back what was just sent - supporting such mechanism requires deeper changes as PJON.h:send_string in the current form does not assume strategy.send_byte returns anything but collision detected while sending byte should return FAIL immediately. Anyway such byte-level collision detection may be unnecessary (due to overhead) as ACK at packet-level exists anyway.

If byte-level collision detection would not be added then extending the existing ThroughHardwareSerial strategy seems the best/reasonable way to go.

gioblu commented 8 years ago

Ciao @Girgitt I agree with you. I would for now extend ThroughHardwareSerial and consider collision avoidance as a possible new feature after testing.

gioblu commented 8 years ago

@Girgitt feel free to pull request your changes or ask for support if necessary

Girgitt commented 8 years ago

Hi @gioblu, I started coding a python client for PJON protocol (PJON-python) and when I'm done with it - including unit and functional tests with hardware - I'll issue a pull request with modified serial strategy.

gioblu commented 8 years ago

Ciao! Its is sad to close this issue, because one of the most interesting. Is the use of ThroughHardwareSerial + rs485 modules solving this issue?