#include <SoftwareSerial.h>
#include <PJONThroughSerial.h>
#include <U8g2lib.h>



/* Set synchronous response timeout to 100 milliseconds.
   If operating at less than 9600Bd TS_RESPONSE_TIME_OUT should be longer */
#define TS_RESPONSE_TIME_OUT 100000

// pin 10 drives the buzzer
#define buzzer  10

#define OK_PIN  A0 //
#define ERROR_PIN  A1  //


// Bus id definition
uint8_t bus_id[] = {0, 146, 2, 92};


SoftwareSerial Serial2(2,3); // RX, TX
PJONThroughSerial bus(bus_id,45);
U8X8_SSD1306_128X64_NONAME_HW_I2C display(U8X8_PIN_NONE);



uint16_t  count_error = 0;
uint16_t  count_send = 0;


void error_handler(uint8_t code, uint16_t data, void *custom_pointer) {
  if(code == PJON_CONNECTION_LOST) {
    Serial.print("Connection with device ID ");
    Serial.print(bus.packets[data].content[0], DEC);
    Serial.println(" is lost.");
  }
  if(code == PJON_PACKETS_BUFFER_FULL) {
    Serial.print("Packet buffer is full, has now a length of ");
    Serial.println(data, DEC);
    Serial.println("Possible wrong bus configuration!");
    Serial.println("higher PJON_MAX_PACKETS if necessary.");
  }
  if(code == PJON_CONTENT_TOO_LONG) {
    Serial.print("Content is too long, length: ");
    Serial.println(data);
  }
};

void receiver_function(uint8_t *payload, uint16_t length, const PJON_Packet_Info &packet_info) {
  /* Make use of the payload before sending something, the buffer where payload points to is
     overwritten when a new message is dispatched */
  if((char)payload[0] == 'B') {
    if(!bus.update()) // If all packets are delivered, send another
      bus.reply("B", 1);
    digitalWrite(LED_BUILTIN, HIGH);
    delay(5);
    digitalWrite(LED_BUILTIN, LOW);
    delay(5);
  }
};





void setup() {
// Initialize LED 13 to be off
pinMode(LED_BUILTIN, OUTPUT);
digitalWrite(LED_BUILTIN, LOW);

// buzzer setup
pinMode(buzzer, OUTPUT);

// INPUT PIN  setup
pinMode(ERROR_PIN, INPUT_PULLUP);
pinMode(OK_PIN, INPUT_PULLUP);

// UART setup
Serial.begin(115200);
Serial2.begin(38400); 


// bus strategy setup
bus.strategy.set_serial(&Serial2);
// Avoid acknowledgement
bus.set_acknowledge(true); //false  true
// not sender's information
bus.include_sender_info(false);

// error function
bus.set_error(error_handler);
// receiver function
bus.set_receiver(receiver_function);

bus.begin();
// Send B to device 45 every second
//bus.send_repeatedly(45, "B", 1, 1000000);

//display
display.begin();
display.setPowerSave(0);
display.setFont(u8x8_font_7x14B_1x2_r); //u8x8_font_7x14B_1x2_r

//print display
display.clearDisplay();
display.setCursor(0, 0);
display.print("Send-"+ String(count_send, DEC));
display.setCursor(0, 2);
display.print(" Err-"+ String(count_error, DEC));//"ERR-"

}


void loop() {

  if (digitalRead(OK_PIN) == LOW) {  
    tone (buzzer, 125, 100);
    delay(150);
    tone (buzzer, 125, 100);

     delay(500);
  }

  if (digitalRead(ERROR_PIN) == LOW) {
    tone (buzzer, 1800, 15);
    delay (150);
    tone (buzzer, 1800, 15);
    Serial.println("ERROR");
    bus.send(44, "B", 1);

    delay(500);
  }

bus.receive(50000); 
bus.update();

}