diff --git a/lcd.h b/lcd.h new file mode 100644 index 0000000..07dd6b1 --- /dev/null +++ b/lcd.h @@ -0,0 +1,72 @@ +#ifndef _LCD_H_ + #define _LCD_H_ + + #include + + 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 \ No newline at end of file diff --git a/node/main/lcd.h b/node/main/lcd.h new file mode 120000 index 0000000..cb6a257 --- /dev/null +++ b/node/main/lcd.h @@ -0,0 +1 @@ +../../lcd.h \ No newline at end of file diff --git a/node/main/main.ino b/node/main/main.ino index c202ec1..a371ae2 100644 --- a/node/main/main.ino +++ b/node/main/main.ino @@ -1,27 +1,23 @@ #include -#include +#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); } \ No newline at end of file diff --git a/packet.cpp b/packet.cpp index efe0abb..f81f0cf 100644 --- a/packet.cpp +++ b/packet.cpp @@ -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; diff --git a/packet.h b/packet.h index 8a5ec60..4da5014 100644 --- a/packet.h +++ b/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[]); diff --git a/well/main/lcd.h b/well/main/lcd.h new file mode 120000 index 0000000..cb6a257 --- /dev/null +++ b/well/main/lcd.h @@ -0,0 +1 @@ +../../lcd.h \ No newline at end of file diff --git a/well/main/main.ino b/well/main/main.ino index 486a9fc..d318e75 100644 --- a/well/main/main.ino +++ b/well/main/main.ino @@ -1,48 +1,63 @@ #include -#include +#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()); } diff --git a/xbee_wrapper.cpp b/xbee_wrapper.cpp index 4b341de..9a764c7 100644 --- a/xbee_wrapper.cpp +++ b/xbee_wrapper.cpp @@ -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); }; diff --git a/xbee_wrapper.h b/xbee_wrapper.h index 861fea9..0bd18f1 100644 --- a/xbee_wrapper.h +++ b/xbee_wrapper.h @@ -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);