add 'lcd' library (LCDWrapper) that implements formatting + autoscroll | use rich formatting in entrypoints (.ino) | make well routine#0 to be non-blocking before each WAVE_TIMEOUT | add well routine#1 to receive and print messages
This commit is contained in:
parent
373ecc6b32
commit
cbe48ceebc
|
@ -0,0 +1,72 @@
|
|||
#ifndef _LCD_H_
|
||||
#define _LCD_H_
|
||||
|
||||
#include <LiquidCrystal_I2C.h>
|
||||
|
||||
class LCDWrapper {
|
||||
private:
|
||||
LiquidCrystal_I2C *display;
|
||||
size_t cursor;
|
||||
uint8_t cols;
|
||||
uint8_t rows;
|
||||
|
||||
public:
|
||||
LCDWrapper(uint8_t addr, uint8_t cols, uint8_t rows){
|
||||
rows = rows;
|
||||
cols = cols;
|
||||
*display = LiquidCrystal_I2C(addr, cols, rows, LCD_5x8DOTS);
|
||||
cursor = 0;
|
||||
}
|
||||
~LCDWrapper(){ display = NULL; }
|
||||
|
||||
void begin(){
|
||||
display->begin();
|
||||
display->backlight();
|
||||
display->home();
|
||||
clear();
|
||||
}
|
||||
|
||||
void move(const uint8_t line, const uint8_t c){ display->setCursor(line, c); }
|
||||
|
||||
void clear(){ cursor = 0; display->clear(); }
|
||||
|
||||
void printf(const char *fmt, ...){
|
||||
va_list va;
|
||||
va_start(va, fmt);
|
||||
char buffer[34] = {0};
|
||||
int size = sprintf(buffer, fmt, va);
|
||||
va_end(va);
|
||||
|
||||
display->print(buffer);
|
||||
}
|
||||
|
||||
void printfn(const uint8_t line, const char *fmt, ...){
|
||||
va_list va;
|
||||
va_start(va, fmt);
|
||||
char buffer[34] = {0};
|
||||
int size = sprintf(buffer, fmt, va);
|
||||
va_end(va);
|
||||
|
||||
display->setCursor(0,line);
|
||||
display->print(buffer);
|
||||
}
|
||||
|
||||
void printfn_overflow(const uint8_t line, const char *fmt, ...){
|
||||
va_list va;
|
||||
va_start(va, fmt);
|
||||
char buffer[34] = {0};
|
||||
int size = sprintf(buffer, fmt, va);
|
||||
va_end(va);
|
||||
|
||||
display->setCursor(0,line);
|
||||
display->print(buffer);
|
||||
|
||||
for( uint8_t offset = 0 ; size-offset > cols ; offset++ ){
|
||||
delay(50);
|
||||
display->setCursor(0,line);
|
||||
display->print(buffer+offset);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
|
@ -0,0 +1 @@
|
|||
../../lcd.h
|
|
@ -1,27 +1,23 @@
|
|||
#include <Wire.h>
|
||||
#include <LiquidCrystal_I2C.h>
|
||||
#include "lcd.h"
|
||||
#include "packet.h" // Packet
|
||||
#include "xbee_wrapper.h" // WBeeWrapper
|
||||
|
||||
// Peripherals
|
||||
LiquidCrystal_I2C screen(0x20, 16, 2);
|
||||
LCDWrapper screen = LCDWrapper(0x20, 16, 2);
|
||||
XBeeWrapper xbee = XBeeWrapper();
|
||||
|
||||
// ACTUAL DATA
|
||||
uint8_t wave_id = 255; // last wave
|
||||
uint8_t dist = 255; // actual distance
|
||||
Packet recv;
|
||||
Packet send;
|
||||
Packet recv, send;
|
||||
|
||||
void setup() {
|
||||
Serial.begin(38400);
|
||||
Serial.println("+ ready");
|
||||
|
||||
screen.begin();
|
||||
screen.backlight();
|
||||
screen.home();
|
||||
screen.setCursor(0, 0);
|
||||
screen.print("ready");
|
||||
screen.printf("[ node ready ]");
|
||||
|
||||
xbee.begin(38400);
|
||||
|
||||
|
@ -43,82 +39,50 @@ void loop() {
|
|||
if( recv.getDist() == 0 && recv.getSender() != 255 )
|
||||
return;
|
||||
|
||||
screen.printfn(0, "dsc[%3d] %3d / %3d", recv.getSender(), recv.getDist(), recv.getWave());
|
||||
|
||||
status(wave_id, dist);
|
||||
screen.print("dsc");
|
||||
screen.print("[");
|
||||
screen.print(recv.getSender());
|
||||
screen.print("] -> ");
|
||||
screen.print(recv.getDist());
|
||||
screen.print("/");
|
||||
screen.print(recv.getWave());
|
||||
|
||||
if( recv.getWave() != wave_id ){
|
||||
wave_id = recv.getWave();
|
||||
dist = recv.getDist()+1;
|
||||
|
||||
status(wave_id, dist);
|
||||
screen.print("propagated");
|
||||
delay(100);
|
||||
|
||||
send.setOpcode(0);
|
||||
send.setWave(wave_id);
|
||||
send.setDist(dist);
|
||||
send.setSender(42);
|
||||
xbee.broadcast(send);
|
||||
Serial.print(" + send discover[");
|
||||
Serial.print(send.getSender());
|
||||
Serial.print("] -> ");
|
||||
Serial.print(send.getDist());
|
||||
Serial.print(" / ");
|
||||
Serial.println(send.getWave());
|
||||
|
||||
// ignore if same wave
|
||||
if( recv.getWave() == wave_id ){
|
||||
screen.printfn(1, "x");
|
||||
return;
|
||||
}
|
||||
|
||||
// update features
|
||||
wave_id = recv.getWave();
|
||||
dist = recv.getDist()+1;
|
||||
|
||||
// propagate wave
|
||||
send.setOpcode(0);
|
||||
send.setWave(wave_id);
|
||||
send.setDist(dist);
|
||||
send.setSender(42);
|
||||
|
||||
screen.printfn(1, "dsc[%3d] %3d / %3d", send.getSender(), send.getDist(), send.getWave());
|
||||
xbee.broadcast(send);
|
||||
|
||||
// MESSAGE DATA
|
||||
} else {
|
||||
|
||||
screen.clear();
|
||||
screen.setCursor(0,0);
|
||||
screen.print("message(");
|
||||
screen.print(recv.getDist());
|
||||
screen.print(",");
|
||||
screen.print(recv.getTTL());
|
||||
screen.print(",");
|
||||
screen.print(recv.getSize());
|
||||
screen.print(")");
|
||||
screen.setCursor(0,1);
|
||||
screen.print( (char*)recv.getData());
|
||||
delay(600);
|
||||
screen.printfn(0, "msg[%3d/%3d] %3d", recv.getDist(), recv.getTTL(), recv.getSize());
|
||||
delay(500);
|
||||
screen.printfn_overflow(0, "%s", recv.getData());
|
||||
|
||||
// ignore
|
||||
if( recv.getTTL() <= 0 || recv.getDist() > dist ){
|
||||
screen.printfn(1, "x");
|
||||
return;
|
||||
}
|
||||
|
||||
// propagation
|
||||
if( recv.getTTL() > 0 && recv.getDist() <= dist ){
|
||||
send.setOpcode(1);
|
||||
send.setTTL(recv.getTTL()-1);
|
||||
send.setDist(dist);
|
||||
send.setData(recv.getData(), recv.getSize());
|
||||
xbee.broadcast(send);
|
||||
Serial.print(" + send message(");
|
||||
Serial.print(recv.getDist());
|
||||
Serial.print(", ");
|
||||
Serial.print(recv.getTTL());
|
||||
Serial.print(", ");
|
||||
Serial.print(recv.getSize());
|
||||
Serial.println(")");
|
||||
}
|
||||
send.setOpcode(1);
|
||||
send.setTTL(recv.getTTL()-1);
|
||||
send.setDist(dist);
|
||||
send.setData(recv.getData(), recv.getSize());
|
||||
|
||||
screen.printfn(1, "msg[%3d/%3d] %3d", send.getDist(), send.getTTL(), send.getSize());
|
||||
xbee.broadcast(send);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
void status(uint8_t wave, uint8_t dist){
|
||||
screen.clear();
|
||||
screen.setCursor(0,0);
|
||||
screen.print(dist);
|
||||
screen.print(" / ");
|
||||
screen.print(wave);
|
||||
screen.setCursor(0,1);
|
||||
}
|
|
@ -4,7 +4,7 @@
|
|||
/* PUBLIC
|
||||
----------------------------------------*/
|
||||
// builds a packet from raw data and returns the error code
|
||||
uint8_t Packet::read(uint8_t buf[], 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;
|
||||
|
@ -51,7 +51,7 @@ void Packet::setData(uint8_t *buffer, uint8_t size) { memcpy(msg.data, buffer, s
|
|||
|
||||
/* PRIVATE
|
||||
----------------------------------------*/
|
||||
uint8_t Packet::read_discover(uint8_t buf[], 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;
|
||||
|
@ -64,7 +64,7 @@ uint8_t Packet::read_discover(uint8_t buf[], size_t size){
|
|||
return PKTREAD_OK;
|
||||
};
|
||||
|
||||
uint8_t Packet::read_message(uint8_t buf[], size_t size){
|
||||
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;
|
||||
|
|
6
packet.h
6
packet.h
|
@ -20,14 +20,14 @@
|
|||
struct message msg;
|
||||
|
||||
// 3. helpers
|
||||
uint8_t read_discover(uint8_t buf[], size_t size);
|
||||
uint8_t read_message(uint8_t buf[], size_t size);
|
||||
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:
|
||||
// builds a packet from raw data and returns the status code
|
||||
uint8_t read(uint8_t buf[], 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[]);
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
../../lcd.h
|
|
@ -1,48 +1,63 @@
|
|||
#include <Wire.h>
|
||||
#include <LiquidCrystal_I2C.h>
|
||||
#include "lcd.h"
|
||||
#include "xbee_wrapper.h"
|
||||
#include "packet.h"
|
||||
|
||||
#define WAVE_TIMEOUT 5000
|
||||
|
||||
// Peripherals
|
||||
LiquidCrystal_I2C screen(0x20, 16, 2);
|
||||
LCDWrapper screen(0x20, 16, 2);
|
||||
XBeeWrapper xbee = XBeeWrapper();
|
||||
|
||||
// ACTUAL DATA
|
||||
uint8_t wave_id = 250;
|
||||
Packet send;
|
||||
Packet recv, send;
|
||||
unsigned long time;
|
||||
|
||||
void setup() {
|
||||
Serial.begin(38400);
|
||||
Serial.println("+ ready");
|
||||
|
||||
screen.begin();
|
||||
screen.backlight();
|
||||
screen.home();
|
||||
screen.setCursor(0,0);
|
||||
screen.print("ready");
|
||||
screen.printf("[ well ready ]");
|
||||
|
||||
xbee.begin(38400);
|
||||
|
||||
time = millis();
|
||||
}
|
||||
|
||||
void loop() {
|
||||
|
||||
delay(WAVE_TIMEOUT);
|
||||
/* [1] if WAVE_TIMEOUT reached */
|
||||
if( millis() - time >= WAVE_TIMEOUT ){
|
||||
time = millis();
|
||||
|
||||
// increment wave id (will overflow from 255 to 0)
|
||||
send.setOpcode(0);
|
||||
send.setWave(++wave_id);
|
||||
send.setDist(0);
|
||||
send.setSender(42);
|
||||
|
||||
screen.clear();
|
||||
screen.printfn(1, "dsc[%3d] %3d / %3d", send.getSender(), send.getDist(), send.getWave());
|
||||
|
||||
if( xbee.broadcast(send) == XBWSEND_OK ) screen.printfn(1, "sent");
|
||||
else screen.printfn(1, "failed");
|
||||
}
|
||||
|
||||
/* [2] Listen for incoming data */
|
||||
if( xbee.receive(recv) != XBWRECV_OK )
|
||||
return;
|
||||
|
||||
uint8_t opcode = recv.getOpcode();
|
||||
|
||||
// ignore DISCOVER requests
|
||||
if( opcode == 0 )
|
||||
return;
|
||||
|
||||
// log message
|
||||
screen.clear();
|
||||
screen.print("+ wave");
|
||||
screen.print(wave_id+1);
|
||||
|
||||
// increment wave id (will overflow from 255 to 0)
|
||||
send.setOpcode(0);
|
||||
send.setWave(++wave_id);
|
||||
send.setDist(0);
|
||||
send.setSender(42);
|
||||
|
||||
if( xbee.broadcast(send) == XBWSEND_OK )
|
||||
Serial.println("sent");
|
||||
else
|
||||
Serial.println("failed");
|
||||
screen.printfn(0, "msg[%3d/%3d] %3d", recv.getDist(), recv.getTTL(), recv.getSize());
|
||||
screen.printfn_overflow(1, "%s", recv.getData());
|
||||
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
XBeeWrapper::XBeeWrapper(){ xbee = XBee(); };
|
||||
|
||||
|
||||
void XBeeWrapper::begin(unsigned long baud){
|
||||
void XBeeWrapper::begin(const unsigned long baud){
|
||||
xbee.setSerial(Serial1);
|
||||
Serial1.begin(baud);
|
||||
};
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
XBeeWrapper();
|
||||
|
||||
// initialises the XBee interface
|
||||
void begin(unsigned long baud);
|
||||
void begin(const unsigned long baud);
|
||||
|
||||
// tries to extract a received packet
|
||||
uint8_t receive(Packet& pkt);
|
||||
|
|
Loading…
Reference in New Issue