Closed Makuna closed 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.
@Makuna you are right I will soon add a doubleBlink example where two devices will both send and receive a packet.
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));
}
}
}
};
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)
Ciao @Makuna, I added the examples as you requested, see https://github.com/gioblu/PJON/commit/2a7a3571de0ac7009069ad258d14f9685ce3c2a7
I tried putting together a sketch that both transmits and receives; and it doesn't seem to work.
I confirmed the wiring works with your example, but I could not find an example that could be both a sender and receiver.