gioblu / PJON

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

A single Sketch being a Transmitter and Reciever.... #63

Closed Makuna closed 8 years ago

Makuna commented 8 years ago

I tried putting together a sketch that both transmits and receives; and it doesn't seem to work.

PJON pjonNet(PjonPin, PjonUnitId); 

void OnReceive(uint8_t size, uint8_t* payload)  {
// left out code as all it did was echo it to serial
}
void setup() {
pjonNet.set_receiver(OnReceive);
}

void loop() {
pjonNet.update();
pjonNet.receive();
// left out code that all it did was buffer serial input if there was any call pjonNet.send_string() when last char was a '\r'
}

I confirmed the wiring works with your example, but I could not find an example that could be both a sender and receiver.

gioblu commented 8 years ago

Ciao @Makuna, if you can please post the entire sketch you tested.

I think that maybe the issue comes out because of the Serial library (hardware) using interrupts, Serial.read() mode could affect PJON timing and my suggestion is to try to use SoftwareSerial.

In 2.1 interrupts will be probably paused using noInterrupts() in the transmitting and receiving functions not to affect bit timing, and reading time.

gioblu commented 8 years ago

@Makuna you are right I will soon add a doubleBlink example where two devices will both send and receive a packet.

gioblu commented 8 years ago

see https://github.com/gioblu/PJON/issues/58

Makuna commented 8 years ago

Below you will find the complete sketch. It uses my task library (GitHub/Makuna/Task) which does not use interrupts.
I am only reading one char at a time and only if its present in the buffer. You might be right about interrupts; which in the long term will be problematic on Esp8266 as the core WiFi does not like having the interrupts disabled for longer than a few micro seconds. And as another conversation, you may need to mark some routines as RAM CACHE on esp8266.

sketch.ino

#include <Task.h>
#include <PJON.h>

//#define ECHO_SLACE

#ifdef ECHO_SLACE
const uint8_t PjonUnitId = 13;
const uint8_t PjonUnitIdOther = 24;
#else
const uint8_t PjonUnitId = 24;
const uint8_t PjonUnitIdOther = 13;
#endif

const uint8_t PjonPin = D1;

PJON pjonNet(PjonPin, PjonUnitId); 

#include "PjonReceiver.h"
#include "PjonTransmitter.h"

TaskManager taskManager;

TaskPjonReceiver pjonReceiver;
TaskPjonTransmitter pjonTransmitter;

void setup() {
  Serial.begin(115200);
  while (!Serial); // wait for serial attach
  Serial.println("initializing...");

  taskManager.StartTask(&pjonReceiver);
  taskManager.StartTask(&pjonTransmitter);
}

void loop() {
  taskManager.Loop();
}

"PjonReceiver.h"


class TaskPjonReceiver : public Task
{
public:
  TaskPjonReceiver() :
      Task(30)  {
  };

private:
  virtual bool OnStart()  {
    pjonNet.set_error(OnError);
    pjonNet.set_receiver(OnReceive);
    return true;
  }

  virtual void OnStop()  {
  }

  virtual void OnUpdate(uint32_t deltaTime)  {
    pjonNet.receive();
  }

  static void OnReceive(uint8_t size, uint8_t* payload)  {
    while (size)
    {
      Serial.print("<");
      while (size--)
      {
        Serial.print((char)*payload++);
      }
      Serial.println();
    }
  }

  static void OnError(uint8_t code, uint8_t data)  {
    Serial.print("(ERROR) ");
    switch (code)   {
      case CONNECTION_LOST:
        Serial.print("Connection Lost with ");
        Serial.print(data);
        break;
      case PACKETS_BUFFER_FULL:
        Serial.print("packet buffer full");
        break;
      case MEMORY_FULL:
        Serial.print("Memory full");
        break;
      case CONTENT_TOO_LONG:
        Serial.print("Content too long at");
        Serial.print(data);
        break;
      default:
        Serial.print("unknown ");
        Serial.print(code);
        break;
    }
    Serial.println();
  }
};

"PjonTransmitter.h"


const uint8_t c_maxCommandLength = 63;

class TaskPjonTransmitter : public Task {
public:
  TaskPjonTransmitter() :
      Task(30),
      _lengthCommand(0),
      _lastTarget(255)  {
  };

private:
  char _command[c_maxCommandLength + 1];
  uint8_t _lengthCommand;
  uint8_t _lastTarget;

  virtual bool OnStart()  {
    return true;
  }

  virtual void OnStop()  {
  }

  virtual void OnUpdate(uint32_t deltaTime)  {
    pjonNet.update();
    if (Serial)   {
      while (Serial.available())  {
        char ch = Serial.read();
        if (ch == '\r')  {
          _command[_lengthCommand] = '\0';
          SendCommand();
          _lengthCommand = 0;
        }
        else if (_lengthCommand < c_maxCommandLength)   {
          _command[_lengthCommand++] = ch; 
        }
      }
    }
  }

  void SendCommand()  {
    // parse command, expect #: 
    char* token;
    token = strtok(_command, ":");
    if (token != NULL)   {
      uint8_t newTarget = (uint8_t)strtoul(token, NULL, 0);
      token = strtok(NULL, ":");
      if (token != NULL)  {
        // target supplied, use it
        _lastTarget = newTarget;
        Serial.print(_lastTarget);
        Serial.print(": ");
        Serial.print(token);
        Serial.println();

        pjonNet.send_string(_lastTarget, token, strlen(token));
      }
      else  {
        // no target supplied, use the last
        Serial.print(_lastTarget);
        Serial.print(": ");
        Serial.print(_command);
        Serial.println();

        pjonNet.send_string(_lastTarget, _command, strlen(_command));
      }
    }

  }
};
gioblu commented 8 years ago

Ciao @Makuna. I don't think it is necessary the usage of a task manager for this example, you could simply call instance.send(10, "B", 1, 1000000); // Send "B" every second once (for example in setup see blink example), and instance.update(); and instance.receive(); in the loop but if you need one, I would suggest you to use Agenda: https://github.com/gioblu/Agenda I developed for High Altitude Balloon flight computer and for my PJON home automation project.

I will soon update the master version with the example you requested (I am now not at home)

gioblu commented 8 years ago

Ciao @Makuna, I added the examples as you requested, see https://github.com/gioblu/PJON/commit/2a7a3571de0ac7009069ad258d14f9685ce3c2a7