Go Down

Topic: PJON library - A new tool to create arduino boards networks (Read 1 time) previous topic - next topic

gbm

Hi there, I started 3 years ago working on a communication protocol that could be suitable to my projects and to keep simple communication between different arduinos. This is a really early version of the protocol I am presenting now: https://www.youtube.com/watch?v=-Ul2j6ixbmE
Here you can see two arduinos connected two 2 leds. The two boards can establish a bidirectional communication and send digital data in form of light flashes. LEDs are also photodiodes so reading analog output of them hit by light you can determine if the other LED is flashing or not and use the same LED to flash back.


Now I am working on a really big home automation project for my home (like 10 arduinos all around and outside the house) connected to a master. I needed a protocol that could be fast to implement with a fast programming time for each board and simple hardware wiring.

I decided to wrote mine, the name is PJON. Is not stricly an acronym but a nerd name to describe it. As pigeons is not stricly fast :P it has a practical bandwidth of almost 4kB/s and a baudrate of maximum 39600 baud with a bit duration of 18 microseconds, but contains all someone can need to build a intercommunication between up to 255 arduinos on the same wire.

The protocol includes:

Single pin communication (you only need one wire on wich up to 255 arduino boards can transmit)
Packet receive acknowledge (sender will know if the receiver received)
CRC (receiver can calculate if the packet is correctly received and in case ask to repeat to the sender)
Collision avoidance (Every node connected check if the channel is busy before transmitting)
Encryption (optional, with optional initialization vector)
Packets scheduler (manages packets sending automatically)
Reaction scheduler (for example if you receive command '@' call a certain function)

I've finished not so much time ago the code and I am testing it.

This should be considered an alpha version!!
https://github.com/gioblu/PJON/blob/master/PJON.cpp

Please if you can or need try it and let me know if you find bugs
Community robotica / programmazione Arduino
www.gioblu.com
PJON multimaster communications bus system for Arduino and IOT https://github.com/gioblu/PJON

robtillaart

Looks like a very decent alpha!

Have you ever investigated the original Appletalk protocol?
this looks a bit like it.

some remarks
---
please use UPPERCASE defines
Code: [Select]

#define max_reactions 20
#define max_packets 20

#define MAX_REACTIONS  20
#define MAX_PACKETS   20


---
for loops can have an uint8_t i  in the constructor
Code: [Select]
  for(uint8_t i = 0; i < MAX_REACTIONS  ; i++)
    reactions[i].empty = true;


---
defining small functions in the PJON.h file gives the compiler an extra optimization option (IIRC)
Code: [Select]

void PJON::set_collision_avoidance(boolean state) {
  _collision_avoidance = state;
}


---
the do while are not needed here,
Code: [Select]
#define swap(a,b) do { int t = _s_box[a]; _s_box[a] = _s_box[b]; _s_box[b] = t; } while(0)


You should give a link to the digitalWriteFast library used, (or add it to the archive?)

---
This loop does not allow for any latency in the response, a small value could improve the reliability as it gives the receiver time to respond.
Code: [Select]


  while(response == FAIL && micros() - time <= bit_spacer + bit_width)
    response = this->receive_byte();

==>
Code: [Select]

  while (response == FAIL && micros() - time <= bit_spacer + bit_width + 4)
    response = this->receive_byte();


---
in receive_byte a small issue?
  if(time >= acceptance && !this->syncronization_bit())  <<<<<<<<<<<<<     >=  iso > 

---
receive()

    for(unsigned long i = 0; i < 3706; i++) {

i can be an int
+ magic number detected, should be a #define MAGIC 3706

---
void PJON::activate_reaction(uint8_t id) {
  reactions[id].active = true;
}

should test that  id < max_reactions  and that reactions[id] not is empty.


---
Code: [Select]
void PJON::process_reaction() {
  for(uint8_t i = 0; i < max_reactions; i++)
    if(this->compare_reaction(reactions[i].command_type))
      reactions[i].execution();
}


should test for empty??
Code: [Select]
void PJON::process_reaction() {
  for(uint8_t i = 0; i < max_reactions; i++)
    if (! reactions[i].empty)
        if(this->compare_reaction(reactions[i].command_type))
          reactions[i].execution();
}


(time is up)
Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

gbm

Ciao! Thank you very much for the analysis you did and for the correct advices for best practices and standard approach. What do you think about PJON?? Is there something you would add or change, or, there is something you don't like?
Community robotica / programmazione Arduino
www.gioblu.com
PJON multimaster communications bus system for Arduino and IOT https://github.com/gioblu/PJON

robtillaart

I think it is an interesting library, useful to say the least

what would be interesting if you could connect the two Arduino's by fibreglass,
then you would circumvent the line of sight..
Or experiment with mirrors,

Or pass through liquids /water, I can imagine a submarine communicating by pjon, if you get that working !

Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

cr0sh

This seems kinda like a low-cost, low-parts "Ronja" system - albeit slower:

http://ronja.twibright.com/

I could see this system being expanded to allow input on one pin and output on the other, then hook up high-brightness IR LEDs on the output, and a phototransistor + lens on the input - and gain long-distance link-ups.

This is really neat as-is, though - lots of potential with it!
I will not respond to Arduino help PM's from random forum users; if you have such a question, start a new topic thread.

rasumo

I've tested PJON out and it's works extremely well. The only thing I haven't been able to figure out is how to send messages using an interrupt based setup. I'm working on a low-power solution so I use LowPower.powerDown and interrupts. Is there any way to send data in the interrupt function since network.update is not called in every cycle as the README specifies?

Go Up
 


Please enter a valid email to subscribe

Confirm your email address

We need to confirm your email address.
To complete the subscription, please click the link in the email we just sent you.

Thank you for subscribing!

Arduino
via Egeo 16
Torino, 10131
Italy