//SCPI RTC
//commands:
//SYST:TIME:SEC
//SYST:TIME:MIN
//SYST:TIME:HOUR
//SYST:TIME?
//SYST:DATE:DAY
//SYST:DATE:MON
//SYST:DATE:YEAR
//SYST:DATE?
//*RST
//*IDN?
#include <Wire.h> //include the wire library for i2c communication
#include "Arduino.h"
#include "Vrekrer_scpi_parser.h" //include the SCPI library
SCPI_Parser RTC_DS1307; //Start new Instrument
#define idn_string "Arduino controlled SCPI RST,DS1307,v1.0" //define an IDN
void setup() {
Wire.begin(); //start wire communication
Serial.begin(9600); // start the serial monitor
RTC_DS1307.RegisterCommand(F("*IDN?"), &Identify); //define command to get the IDN
RTC_DS1307.RegisterCommand(F("*RST"), &SoftReset); //define command to reset the RTC
RTC_DS1307.SetCommandTreeBase(F("SYSTem")); //define root
RTC_DS1307.RegisterCommand(F(":TIME:SEConds"), &SetSec); //define command to set seconds
RTC_DS1307.RegisterCommand(F(":TIME:MINutes"), &SetMin); //define command to set minutes
RTC_DS1307.RegisterCommand(F(":TIME:HOUR"), &SetHour); //define command to set hours
RTC_DS1307.RegisterCommand(F(":TIME?"), &GetTime); //define command to read time and print to monitor
RTC_DS1307.RegisterCommand(F(":DATE:DAY"), &SetDay); //define command to set day
RTC_DS1307.RegisterCommand(F(":DATE:MONth"), &SetMonth); //define command to set month
RTC_DS1307.RegisterCommand(F(":DATE:YEAR"), &SetYear); //define command to set year
RTC_DS1307.RegisterCommand(F(":DATE?"), &GetDate); //define command to get the date
delay(1000);
Serial.println("Ready");
}
void loop() {
RTC_DS1307.ProcessInput(Serial, "\n");
}
uint8_t DS1307_Read(uint8_t addr){ // function to read the registers
uint8_t data = 0; // define a unsigned char in which the time is stored
Wire.beginTransmission(0x68); //start the communication with the slave address
Wire.write(addr); //set the register to read from
Wire.endTransmission(); //end transmission
delay(5);
Wire.requestFrom(0x68,1); //start reading from slave address by requesting 1 byte
if(Wire.available()){ // if there is any data
data = Wire.read(); // raed and save data
data = ((data>>4)*10)+(data&0x0F); //convert data to decimal
}
return data; // return the data
}
char decimal_to_bcd(unsigned char value){ // function to convert decimal into bcd values
unsigned char msb,lsb,hex;
msb=value/10;
lsb=value%10;
hex = ((msb<<4)+lsb);
return hex;
}
void Identify(SCPI_C commands, SCPI_P parameters, Stream& interface) { //function to print the IDN
interface.println(F(idn_string));
}
void SoftReset(SCPI_C commands, SCPI_P parameters, Stream& interface) { //function to reset all registers
Wire.beginTransmission(0x68); //start communication to the slave address
Wire.write(0x00); //set the first register to write to
Wire.write(0);
Wire.write(0);
Wire.write(0);
Wire.write(0);
Wire.write(0);
Wire.write(0);
Wire.write(0);
Wire.endTransmission(); // end the data transmission
interface.println(F("RESET OK")); //print note to monitor
}
void SetSec(SCPI_C commands, SCPI_P parameters, Stream& interface) {//function to set the seconds
if (parameters.Size() > 0) { //if there is any value transmitted
int seconds = constrain(String(parameters[0]).toInt(), 0, 59); //extract the value
Wire.beginTransmission(0x68); //start the communication with the slave address
Wire.write(0x00); // set starting register to write data to
Wire.write(decimal_to_bcd(seconds)); // convert into bcd and write value in register
Wire.endTransmission(); // end the communication
interface.print(F("SECONDS SET OK: ")); //print feedback to monitor
interface.println(DS1307_Read(0x00));
}
else{
interface.println(F("ERROR")); // if now value was given, print error message
}
}
void SetMin(SCPI_C commands, SCPI_P parameters, Stream& interface) {//function to set the minutes
if (parameters.Size() > 0) { //if there was any value transmitted
int minutes = constrain(String(parameters[0]).toInt(), 0, 59); //extract the value form string and convert to int
Wire.beginTransmission(0x68); //start the communication with the slave address
Wire.write(0x01); // set starting register to write data to
Wire.write(decimal_to_bcd(minutes)); // convert into bcd and write value in register
Wire.endTransmission(); // end the communication
interface.print(F("Minutes SET OK: "));//print feedback to monitor
interface.println(DS1307_Read(0x01));
}
else{
interface.println(F("ERROR")); // if now value was given, print error message
}
}
void SetHour(SCPI_C commands, SCPI_P parameters, Stream& interface) {//function to set the hour
if (parameters.Size() > 0) { //if there was any value transmitted
int hour = constrain(String(parameters[0]).toInt(), 0, 59); //extract the value from string and convert to int
Wire.beginTransmission(0x68); //start the communication with the slave address
Wire.write(0x02); // set starting register to write data to
Wire.write(decimal_to_bcd(hour)); // convert into bcd and write value in register
Wire.endTransmission(); // end the communication
interface.print(F("Hours SET OK: "));//print feedback to monitor
interface.println(DS1307_Read(0x02));
}
else{
interface.println(F("ERROR")); // if now value was given, print error message
}
}
void GetTime(SCPI_C commands, SCPI_P parameters, Stream& interface) { //function to read to time and print to the monitor
interface.print("Time-");
interface.print(DS1307_Read(0x02)); //calling the read-functions and print the value to the monitor by going to the corresponding registers
interface.print(":");
interface.print(DS1307_Read(0x01)); //0x00->sec
interface.print(":"); //0x01->min
interface.println(DS1307_Read(0x00)); //0x02->h
}
void SetDay(SCPI_C commands, SCPI_P parameters, Stream& interface) {//function to set the day
if (parameters.Size() > 0) { //if there was any value transmitted
int day = constrain(String(parameters[0]).toInt(), 0, 59); //extract the value from string and convert to int
Wire.beginTransmission(0x68); //start the communication with the slave address
Wire.write(0x04); // set starting register to write data to
Wire.write(decimal_to_bcd(day)); // convert into bcd and write value in register
Wire.endTransmission(); // end the communication
interface.print(F("DAY SET OK: "));//print feedback to monitor
interface.println(DS1307_Read(0x04));
}
else{
interface.println(F("ERROR")); // if no value was given, print error message
}
}
void SetMonth(SCPI_C commands, SCPI_P parameters, Stream& interface) {//function to set the month
if (parameters.Size() > 0) { //if there was any value transmitted
int month = constrain(String(parameters[0]).toInt(), 0, 59); //extract the value and convert to int
Wire.beginTransmission(0x68); //start the communication with the slave address
Wire.write(0x05); // set starting register to write data to
Wire.write(decimal_to_bcd(month)); // convert into bcd and write value in register
Wire.endTransmission(); // end the communication
interface.print(F("MONTH SET OK: ")); //print feedback to monitor
interface.println(DS1307_Read(0x05));
}
else{
interface.println(F("ERROR")); // if no value was given, print error message
}
}
void SetYear(SCPI_C commands, SCPI_P parameters, Stream& interface) {//function to set the year
if (parameters.Size() > 0) { //if there was any value tarnsmitted
int year = constrain(String(parameters[0]).toInt(), 0, 59); //extract value andconvert to int
Wire.beginTransmission(0x68); //start the communication with the slave address
Wire.write(0x06); // set starting register to write data to
Wire.write(decimal_to_bcd(year)); // convert into bcd and write value in register
Wire.endTransmission(); // end the communication
interface.print(F("YEAR SET OK: ")); // print feedback to monitor
interface.println(DS1307_Read(0x06));
}
else{
interface.println(F("ERROR")); // if no value was given, print error message
}
}
void GetDate(SCPI_C commands, SCPI_P parameters, Stream& interface) { //function to read the date and print to monitor
interface.print("Date-"); //0x03->weekday
interface.print(DS1307_Read(0x04)); //0x04->day
interface.print("/"); //0x05->month
interface.print(DS1307_Read(0x05)); //0x06->year
interface.print("/");
interface.println(DS1307_Read(0x06));
}