#include <LiquidCrystal.h>
#include <SoftwareSerial.h>
#include <stdio.h>

//MR1132 DEMO

#define PIN_RX      19    // RX PIN (connect to TX on noolite controller)
#define PIN_TX      18    // TX PIN (connect to RX on noolite controller)
#define PIN_LVL     52
#define PIN_CONTROL 48
#define ASCII_ETX   0x03

#define RS_PIN  37
#define E_PIN   35
#define D4_PIN  33
#define D5_PIN  32
#define D6_PIN  31
#define D7_PIN  30

char commandLine[20];
char ParsedData[16];
char DataFromModule[16];
char FlagBind = 0;
char StateMsgCount = '0';
unsigned char TOGLCommand = 0;

unsigned long previousMillis = 0; 

const long interval = 5000;

LiquidCrystal lcd(RS_PIN, E_PIN, D4_PIN, D5_PIN, D6_PIN, D7_PIN);


/****Send command to MR1132****/
void sendCommand()
{
  if(!FlagBind)
    sprintf(commandLine,"bind_mode_cell_00");
  else
    sprintf(commandLine,"bind_mode_off");
  Serial1.write(&commandLine[0]);
  Serial1.write((byte)ASCII_ETX);
  FlagBind = ~FlagBind;
}

/****Check messages from MR1132****/
int checkMessage()
{
    for(int j = 0; j <sizeof(DataFromModule);j++)
      DataFromModule[j] = 0;
    int i = 0;
    while(Serial1.available()>0)
    {
      delay(2);
      DataFromModule[i++] = Serial1.read();
    }
    if(i)
    {
      Serial.write(DataFromModule,12);
      return 1;
    }
    return 0;
}

/****Some parsed data output to LCD****/
void DataToLcd(char* BufData)
{
  sprintf(ParsedData,"Ch-%d/Com-%d ",BufData[2],BufData[3]);
  lcd.setCursor(0,0);
  lcd.print(ParsedData);
}

/****State parsing data output to LCD****/
void StateToLcd(char* state, char *counter)
{
    if(counter[0] > '9')
      counter[0] = '0';
    lcd.setCursor(6,1);
    lcd.print(counter[0]++);
    lcd.print(state);
}

/****Parsing data from MR1132****/
void parsingData()
{
  if(!strncmp(DataFromModule,"OK",2))
    StateToLcd((char*)":OK      ", &StateMsgCount);
  else if(((unsigned char)DataFromModule[0] == 0x55) && ((unsigned char)DataFromModule[10] == 0xAA))
  {
    char CheckSum = 0;
    for(int i = 0; i < 9; i++)
      CheckSum += DataFromModule[i];
      
    if(!(CheckSum == (DataFromModule[9] - 1)))
      StateToLcd((char*)":ERR-1   ", &StateMsgCount);
    else if(DataFromModule[1] != TOGLCommand)
    {
      StateToLcd((char*)":OK      ", &StateMsgCount);
      DataToLcd(DataFromModule);
      TOGLCommand = DataFromModule[1];
    }
  }
  else
    StateToLcd((char*)":ERR-2   ", &StateMsgCount);
}

/****Check answer from MR1132****/
void CheckAnswer()
{
  previousMillis = millis();
  while(1)
  {
    if(checkMessage())
    {
      parsingData();
      return;
    }
    if (millis() - previousMillis >= interval) 
    {
      StateToLcd((char*)":ERR-3   ", &StateMsgCount);
      return;
    }
  }
}

void setup() 
{          
  pinMode(PIN_RX, INPUT);
  pinMode(PIN_TX, OUTPUT);
  
  Serial1.begin(9600); 
  Serial.begin(9600);
  
  lcd.begin(16,2);
  lcd.setCursor(0,1);
  lcd.print("State");
    
  pinMode(PIN_LVL,OUTPUT);
  pinMode(PIN_CONTROL,INPUT_PULLUP);
  Serial1.write((byte)ASCII_ETX);
}

void loop()
{   
    while(digitalRead(PIN_CONTROL) == HIGH)
    {
      delay(10);
      if(checkMessage())
        parsingData();
    }
    
    sendCommand();
    CheckAnswer();
        
    delay(500);
    while(digitalRead(PIN_CONTROL) == LOW)
    {
      delay(10);
    }
}