// Created by prof. Egidijus Kazanavicus Kaunas university of technology

#include "SerialCommand.h"
#include "DHT.h"

#define DHTPIN 18     // what pin we're connected to

// Uncomment whatever type you're using!
//#define DHTTYPE DHT11   // DHT 11 
#define DHTTYPE DHT22     // DHT 22  (AM2302)
//#define DHTTYPE DHT21   // DHT 21 (AM2301)

void digital_read_command();
void digital_write_command();
void analog_read_command();
void analog_write_command();
void dht_command();
void reset_command();
void pin_mode_command();
void ping_command();
void unrecognized(const char *command);


SerialCommand sCmd;

#define KEYPAD_ENABLED

#ifdef KEYPAD_ENABLED
#include "keypad_command.h"
#endif

#define LED_BUILTIN 13
#define REALAY 12

DHT dht(DHTPIN, DHTTYPE, 6);

// the setup function runs once when you press reset or power the board

void setup() {
  // initialize digital pin LED_BUILTIN as an output.
  pinMode(LED_BUILTIN, OUTPUT);
  pinMode(REALAY, OUTPUT);

  Serial.begin(115200); 

  sCmd.addCommand("DR", digital_read_command); 
  sCmd.addCommand("DW", digital_write_command);
  sCmd.addCommand("AR", analog_read_command);
  sCmd.addCommand("PM", pin_mode_command);  
	sCmd.addCommand("PING", ping_command);
	sCmd.addCommand("DHT", dht_command);
  sCmd.addCommand("RESET", reset_command);
#ifdef KEYPAD_ENABLED
  sCmd.addCommand("K", keypad_command);
#endif
  sCmd.setDefaultHandler(unrecognized);
	Serial.print("ready\r\n");

  dht.begin();

  int mode = INPUT_PULLUP;


}

// the loop function runs over and over again forever
void loop() {

// handle serial command
	sCmd.readSerial();
#ifdef KEYPAD_ENABLED
	// handle keypad keypress
	keypad_loop();
#endif
}

void digital_read_command() {
	char* arg = sCmd.next();
  	if(arg == NULL) {
  		argument_error();
    	return;
  	}
  	int pin = atoi(arg);
  
    //---------------------
    int val;
    if(pin > 19)
    {
      val = analogRead(pin) > 100 ? 1 : 0;
    }
    else
    {
    //--------------------- 
  	 val = digitalRead(pin);
    }
  	Serial.print("ACK ");
  	Serial.write('0' + val);
  	Serial.print("\r\n");
}


void digital_write_command() {
	char* arg = sCmd.next();
  	if(arg == NULL) {
  		argument_error();
    	return;
  	}
  	int pin = atoi(arg);
  	arg = sCmd.next();
  	if(arg == NULL) {
  		argument_error();
    	return;
  	}
  	int val = atoi(arg);
  	digitalWrite(pin, val);
  	Serial.print("ACK\r\n");
}

void argument_error() {
	Serial.print("ERR argument_error\r\n");
}
// This gets set as the default handler, and gets called when no other command matches.
void unrecognized(const char *command) {
	Serial.print("ERR unknown_command\r\n");
}

void ping_command() {
  char *arg;
  Serial.print("PING");
  arg = sCmd.next();
  if (arg != NULL) {
    Serial.write(' ');
    Serial.print(arg);
  }
  Serial.print("\r\n");
}

void reset_command() {
  Serial.print("ready\r\n");
}

void dht_command() {
    char* arg = sCmd.next();
    if(arg == NULL) {
        argument_error();
        return;
    }
    int dht_type = atoi(arg);
    arg = sCmd.next();
    if(arg == NULL) {
        argument_error();
        return;
    }
    int dht_pin = atoi(arg);

    int chk;
    
    float h = dht.readHumidity();
    // Read temperature as Celsius
    float t = dht.readTemperature();

    // Check if any reads failed and exit early (to try again).
    if (isnan(h) || isnan(t)) {
    Serial.println("Failed to read from DHT sensor!");
    //return;
    }
    else {

            Serial.print("ACK ");
            Serial.print(dht.readTemperature());
            Serial.write(' ');
            Serial.print(dht.readHumidity());
            Serial.print("\r\n");
    }  
}

void pin_mode_command() {
	char* arg = sCmd.next();
  	if(arg == NULL) {
  		argument_error();
    	return;
  	}
  	int pin = atoi(arg);
  	arg = sCmd.next();
  	if(arg == NULL) {
  		argument_error();
    	return;
  	}
  	// INPUT 0x0
	  // OUTPUT 0x1
  	int mode = atoi(arg);
    //-----------------------
    if (mode == INPUT)
    {
      mode = INPUT_PULLUP;
    }
    
    //-----------------------
  	pinMode(pin, mode);
    Serial.print("ACK\r\n");	
}

void analog_read_command() {
	char* arg = sCmd.next();
  	if(arg == NULL) {
  		argument_error();
    	return;
  	}
  	int pin = atoi(arg);
  	int val = analogRead(pin);
  	Serial.print("ACK ");
  	Serial.print(val);
  	Serial.print("\r\n");
}
NOCOMNCVCCGNDINLED1PWRRelay Module
NOCOMNCVCCGNDINLED1PWRRelay Module
NOCOMNCVCCGNDINLED1PWRRelay Module
NOCOMNCVCCGNDINLED1PWRRelay Module