fix lcd | change to simplest protocol | fix packet

This commit is contained in:
Adrien Marquès 2018-12-11 12:42:34 +01:00
parent 90529c814f
commit fb33a450e0
7 changed files with 131 additions and 137 deletions

41
lcd.h
View File

@ -11,6 +11,7 @@
uint8_t rows, cols;
char* buffer = NULL;
public:
LCDWrapper(uint8_t addr, uint8_t cols, uint8_t rows, uint8_t charsize=LCD_5x8DOTS) : LiquidCrystal_I2C(addr,cols,rows,charsize) {
this->cols = cols;
@ -22,20 +23,6 @@
LiquidCrystal_I2C::backlight();
}
void printf(const char *fmt, ...){
buffer = (char*) malloc( BUFSIZE * sizeof(char*));
buffer[0] = 0;
va_list ap;
va_start(ap, fmt);
int size = vsnprintf(buffer, BUFSIZE, fmt, ap);
va_end(ap);
if( size < 0 || size > BUFSIZE ){ free(buffer); return; }
LiquidCrystal_I2C::print(buffer);
free(buffer);
}
void printfn(const uint8_t line, const char *fmt, ...){
buffer = (char*) malloc( BUFSIZE * sizeof(char*));
buffer[0] = 0;
@ -44,7 +31,7 @@
va_start(ap, fmt);
int size = vsnprintf(buffer, BUFSIZE, fmt, ap);
va_end(ap);
if( size < 0 || size > BUFSIZE ){ free(buffer); return; }
if( size < 0 || size >= BUFSIZE ){ free(buffer); return; }
LiquidCrystal_I2C::setCursor(0, line);
LiquidCrystal_I2C::print(buffer);
@ -59,20 +46,36 @@
va_start(ap, fmt);
int size = vsnprintf(buffer, BUFSIZE, fmt, ap);
va_end(ap);
if( size < 0 || size > BUFSIZE ){ free(buffer); return; }
buffer[BUFSIZE-1] = 0;
if( size < 0 || size >= BUFSIZE ){ free(buffer); return; }
LiquidCrystal_I2C::setCursor(0, line);
LiquidCrystal_I2C::setCursor(0,line);
LiquidCrystal_I2C::print(buffer);
if( size <= cols ){ free(buffer); return; }
for( uint8_t offset = 1 ; offset <= size-cols ; offset++ ){
delay(200);
LiquidCrystal_I2C::setCursor(0, line);
LiquidCrystal_I2C::setCursor(0,line);
LiquidCrystal_I2C::print(buffer+offset);
}
free(buffer);
}
protected:
void printf(const char *fmt, ...) {
buffer = (char*) malloc( BUFSIZE * sizeof(char*));
buffer[0] = 0;
va_list ap;
va_start(ap, fmt);
int size = vsnprintf(buffer, BUFSIZE, fmt, ap);
va_end(ap);
if( size < 0 || size >= BUFSIZE ){ free(buffer); return; }
LiquidCrystal_I2C::print(buffer);
free(buffer);
}
};
#endif

View File

@ -20,10 +20,9 @@ void setup() {
Serial.println("+ ready");
screen.begin();
screen.printf("[ node ready ]");
screen.printfn(0, "[ node ready ]");
xbee.begin(38400);
time = millis();
}
@ -35,7 +34,6 @@ void loop() {
send_data();
}
/* [2] Listen for incoming data */
if( xbee.receive(recv) != XBWRECV_OK )
return;
@ -43,11 +41,11 @@ void loop() {
uint8_t opcode = recv.getOpcode();
// 1. manage discover request
if( opcode == 0 )
if( opcode == OPCODE_DISCOVER )
return manage_discover();
// 2. manage message data
else if( opcode == 1 )
else if( opcode == OPCODE_MESSAGE )
return manage_message();
@ -56,21 +54,19 @@ void loop() {
void send_data(){
Serial.println(" -> message");
// 1. prepare message
send.setOpcode(1);
send.setOpcode(OPCODE_MESSAGE);
send.setSender(SENDERID);
send.setDist(dist);
send.setTTL(MESSAGE_TTL);
uint8_t data[32] = {0};
char data[64] = {0};
strcpy(data, "https://git.xdrm.io");
Serial.print("'");
Serial.print( (char*) data);
Serial.println("'");
send.setData(data, strlen(data));
send.setSender(SENDERID);
send.setData(data);
// 2. debug
screen.clear();
screen.printfn(0, "msg[%3d/%3d] %3d", send.getDist(), send.getTTL(), send.getSize());
screen.printfn_overflow(1, "%s", send.getData());
screen.printfn_overflow(1, "%s", (char*) send.getData());
delay(1000);
// 3. send
xbee.broadcast(send);
@ -79,17 +75,18 @@ void send_data(){
void manage_discover(){
Serial.println(" <- discover");
// security
if( recv.getDist() == 0 && recv.getSender() != SENDERID )
return;
Serial.print(" <- discover[ ");
Serial.print(recv.getDist());
Serial.print(" / ");
Serial.print(recv.getWave());
Serial.println(" ]");
screen.clear();
screen.printfn(0, "dsc[%3d] %3d/%3d", recv.getSender(), recv.getDist(), recv.getWave());
screen.printfn(0, "dsc[ %3d / %3d ]", recv.getDist(), recv.getWave());
// ignore if same wave
if( recv.getWave() == wave_id ){
screen.printfn(1, "x");
screen.printfn(1, "x ");
return;
}
@ -98,33 +95,44 @@ void manage_discover(){
dist = recv.getDist()+1;
// propagate wave
send.setOpcode(0);
send.setOpcode(OPCODE_DISCOVER);
send.setWave(wave_id);
send.setDist(dist);
send.setSender(SENDERID);
screen.printfn(1, "dsc[%3d] %3d/%3d", send.getSender(), send.getDist(), send.getWave());
screen.printfn(1, "dsc[ %3d / %3d ]", send.getDist(), send.getWave());
xbee.broadcast(send);
}
void manage_message(){
Serial.println(" <- message");
if( recv.getTTL() <= 0 )
return;
Serial.print(" <- message[");
Serial.print(recv.getDist());
Serial.print("/");
Serial.print(recv.getTTL());
Serial.print("] ");
Serial.print(recv.getSize());
Serial.print(" '");
Serial.print((char*) recv.getData());
Serial.println("'");
screen.clear();
screen.printfn(0, "msg[%3d/%3d] %3d", recv.getDist(), recv.getTTL(), recv.getSize());
delay(500);
screen.printfn_overflow(0, "%s", recv.getData());
screen.printfn_overflow(1, "%s", (char*) recv.getData());
delay(1000);
// ignore
if( recv.getTTL() <= 0 || recv.getDist() > dist ){
screen.printfn(1, "x");
if( recv.getDist() > dist ){
screen.printfn(1, "x ");
return;
}
// propagation
send.setOpcode(1);
send.setOpcode(OPCODE_MESSAGE);
send.setTTL(recv.getTTL()-1);
send.setDist(dist);
send.setData(recv.getData(), recv.getSize());
send.setData(recv.getData());
screen.printfn(1, "msg[%3d/%3d] %3d", send.getDist(), send.getTTL(), send.getSize());
xbee.broadcast(send);

View File

@ -1,10 +1,12 @@
#include "packet.h"
Packet::Packet(){
msg.data = malloc(1 * sizeof(char));
}
/* PUBLIC
----------------------------------------*/
// builds a packet from raw data and returns the error code
uint8_t Packet::read(uint8_t buf[], const size_t size){
uint8_t Packet::read(uint8_t* buf, const size_t size){
// 1. fail on invalid size
if( size < 1 ) return PKTREAD_EMPTY;
if( size > PROTO_SIZE ) return PKTREAD_OVERFLOW;
@ -18,7 +20,7 @@ uint8_t Packet::read(uint8_t buf[], const size_t size){
};
// writes the binary representation of the packet
size_t Packet::write(uint8_t buf[]){
size_t Packet::write(uint8_t* buf){
if( opcode == 0 )
return write_discover(buf);
@ -33,8 +35,8 @@ void Packet::setOpcode(uint8_t value) { opcode = value; dsc.opcode = value; msg.
uint8_t Packet::getWave() { return dsc.wave; }
void Packet::setWave(uint8_t value) { dsc.wave = value; }
uint8_t Packet::getSender() { return (opcode == 0) ? dsc.sender : msg.sender; }
void Packet::setSender(uint8_t value) { if(opcode == 0) dsc.sender = value; else msg.sender = value; }
uint8_t Packet::getSender() { return msg.sender; }
void Packet::setSender(uint8_t value) { msg.sender = value; }
uint8_t Packet::getDist() { return (opcode == 0) ? dsc.dist : msg.dist; }
void Packet::setDist(uint8_t value) { if(opcode == 0) dsc.dist = value; else msg.dist = value; }
@ -44,14 +46,22 @@ void Packet::setTTL(uint8_t value) { msg.ttl = value; }
uint8_t Packet::getSize() { return msg.size; }
uint8_t* Packet::getData() { return msg.data; }
void Packet::setData(uint8_t *buffer, uint8_t size) { memcpy(msg.data, buffer, size); msg.size = size; }
uint8_t* Packet::getData(){ return msg.data; }
void Packet::setData(uint8_t *buffer) {
if( strlen(buffer) >= 255 )
return;
msg.size = strlen(buffer);
resizeMessage();
strcpy(msg.data, buffer);
}
/* PRIVATE
----------------------------------------*/
uint8_t Packet::read_discover(uint8_t buf[], const size_t size){
uint8_t Packet::read_discover(uint8_t *buf, const size_t size){
// 1. fail on invalid size
if( size != DISCOVER_SIZE )
return PKTREAD_INVALID_DISCOVER_FORMAT;
@ -59,52 +69,52 @@ uint8_t Packet::read_discover(uint8_t buf[], const size_t size){
dsc.opcode = buf[0];
dsc.wave = buf[1];
dsc.dist = buf[2];
dsc.sender = buf[3];
return PKTREAD_OK;
};
uint8_t Packet::read_message(uint8_t buf[], const size_t size){
size_t Packet::write_discover(uint8_t *buf){
buf[0] = dsc.opcode;
buf[1] = dsc.wave;
buf[2] = dsc.dist;
return 3;
};
uint8_t Packet::read_message(uint8_t *buf, const size_t size){
// 1. fail on invalid size
if( size < MESSAGE_MIN_SIZE || size > MESSAGE_MAX_SIZE )
return PKTREAD_INVALID_MESSAGE_FORMAT;
// 2. fill values
msg.opcode = buf[0];
msg.dist = buf[1];
msg.ttl = buf[2];
msg.size = buf[3];
msg.sender = buf[1];
msg.dist = buf[2];
msg.ttl = buf[3];
msg.size = buf[4];
// 3. check message size
if( size - 5 - 1 != msg.size )
if( size - 5 != msg.size )
return PKTREAD_INVALID_MESSAGE_FORMAT;
// 4. extract message
memcpy(msg.data, buf+4, msg.size);
// 5. add sender id
msg.sender = buf[msg.size+4+1];
resizeMessage();
strncpy(msg.data, buf+5, msg.size);
return PKTREAD_OK;
};
size_t Packet::write_discover(uint8_t buf[]){
buf[0] = dsc.opcode;
buf[1] = dsc.wave;
buf[2] = dsc.dist;
buf[3] = dsc.sender;
return 4;
};
size_t Packet::write_message(uint8_t buf[]){
size_t Packet::write_message(uint8_t *buf){
buf[0] = msg.opcode;
buf[1] = msg.dist;
buf[2] = msg.ttl;
buf[3] = msg.size;
buf[1] = msg.sender;
buf[2] = msg.dist;
buf[3] = msg.ttl;
buf[4] = msg.size;
memcpy( buf+4, msg.data, msg.size );
buf = realloc(buf, (5+msg.size+1)* sizeof(uint8_t));
strncpy(buf+5, msg.data, msg.size);
buf[msg.size+5] = msg.sender;
return 4 + msg.size;
return 5 + msg.size;
};

View File

@ -20,17 +20,19 @@
struct message msg;
// 3. helpers
uint8_t read_discover(uint8_t buf[], const size_t size);
uint8_t read_message(uint8_t buf[], const size_t size);
size_t write_discover(uint8_t buf[]);
size_t write_message(uint8_t buf[]);
uint8_t read_discover(uint8_t* buf, const size_t size);
uint8_t read_message(uint8_t* buf, const size_t size);
size_t write_discover(uint8_t* buf);
size_t write_message(uint8_t* buf);
public:
Packet();
// builds a packet from raw data and returns the status code
uint8_t read(uint8_t buf[], const size_t size);
uint8_t read(uint8_t* buf, const size_t size);
// writes the binary representation of the packet returns the size
size_t write(uint8_t buf[]);
size_t write(uint8_t* buf);
// GETTERS / SETTERS
uint8_t getOpcode();
@ -51,7 +53,13 @@
uint8_t getSize();
uint8_t* getData();
void setData(uint8_t *buffer, uint8_t size);
void setData(uint8_t *buffer);
protected:
resizeMessage(){
msg.data = realloc(msg.data, (msg.size+1) * sizeof(uint8_t));
// memset(msg.data, 0, msg.size+1);
}
};

View File

@ -7,56 +7,29 @@
#define SENDERID 42
#define MESSAGE_TTL 10
#define OPCODE_DISCOVER 0
#define OPCODE_MESSAGE 1
// discover request (c.f. class node)
#define DISCOVER_SIZE sizeof(uint8_t)*4
#define DISCOVER_SIZE sizeof(uint8_t)*3
struct discover {
uint8_t opcode; // opcode = 0
uint8_t wave; // id de la wave
uint8_t dist; // current node's distance
uint8_t sender; // sender id
};
#define MESSAGE_MIN_SIZE sizeof(uint8_t)*5
#define MESSAGE_MAX_SIZE sizeof(uint8_t)*5+sizeof(uint8_t)*255
#define MESSAGE_MAX_SIZE (5 + 255) * sizeof(uint8_t)
struct message {
uint8_t opcode; // opcode = 1
uint8_t sender; // sender id
uint8_t dist; // distance of the last sender
uint8_t ttl; // time to live default = 10
uint8_t size; // size of message in bytes
uint8_t *data; // actual message
uint8_t sender; // sender id
};
#define PROTO_SIZE MESSAGE_MAX_SIZE
// A <node> object is held by each node which values are determined thanks
// to the DISCOVER requests it receives; each node broadcasts a DISCOVER
// request every DISCOVER_TTL milliseconds
// class node{
// private:
// // unique id of the node : MAC ADDR
// int id;
// // last received wave id
// uint8_t last_wave;
// // relative node-distance to the well
// // WELL : dist = 0
// // NODE1 can reach WELL : dist = 1
// // NODE2 can reach NODE1 : dist = 2
// // and so on...
// uint8_t dist;
// public:
// // send a discover request
// bool discover();
// // update the current node according to a (received)
// // discover request
// bool update(struct discover dsc);
// };
#endif

View File

@ -17,7 +17,7 @@ void setup() {
Serial.println("+ ready");
screen.begin();
screen.printf("[ well ready ]");
screen.printfn(0, "[ well ready ]");
xbee.begin(38400);
@ -31,13 +31,12 @@ void loop() {
time = millis();
// increment wave id (will overflow from 255 to 0)
send.setOpcode(0);
send.setOpcode(OPCODE_DISCOVER);
send.setWave(++wave_id);
send.setDist(0);
send.setSender(SENDERID);
screen.clear();
screen.printfn(0, "dsc[%3d] %3d/%3d", send.getSender(), send.getDist(), send.getWave());
screen.printfn(0, "dsc[ %3d / %3d ]", send.getDist(), send.getWave());
if( xbee.broadcast(send) == XBWSEND_OK ) screen.printfn(1, "sent");
else screen.printfn(1, "failed");

View File

@ -49,21 +49,14 @@ uint8_t XBeeWrapper::broadcast(Packet& pkt){
XBeeAddress64 bcast = XBeeAddress64(0x00000000, 0x0000FFFF);
// build payload from packet
uint8_t payload[PROTO_SIZE];
uint8_t* payload = malloc(6 * sizeof(uint8_t));
size_t payload_size = pkt.write(payload);
// send
Tx64Request tx = Tx64Request(bcast, payload, payload_size);
xbee.send(tx);
// // check status
// TxStatusResponse txStatus = TxStatusResponse();
// xbee.readPacket();
// if( xbee.getResponse().isAvailable() ){
// if( xbee.getResponse().getApiId() == TX_STATUS_RESPONSE ){
// xbee.getResponse().getTxStatusResponse(txStatus);
// return txStatus.isSuccess() ? XBWSEND_OK : XBWSEND_ERROR;
// }
// }
free(payload);
return XBWSEND_OK;
};