Complete code as it stands, and works at the moment...
#include "RTClib.h" //RTC DS1307 library
RTC_DS1307 rtc; //initialise specific RTC
#include <Adafruit_ADS1X15.h> //ADC library
Adafruit_ADS1115 ads; //initialise specific ADC
//-----------------------------Nextion
const int BUFFER_SIZE = 10; //buffer size for incoming serial from Nextion
char buf[BUFFER_SIZE]; //actual buffer of buffer_size
String celldisp = "4.00"; //initial cell area displayed
String armdisp = "12.00"; //initial arm length displayed
String gagdisp = "5000"; //initial full-scale gauge displayed
String pxdisp = "3000"; //initial pressure transducer value displayed
String st2next; //Strings for each command sent to Nextion
int cellpos = 0; //initial cell area switch-case setting
int armpos = 1; //initial arm length switch-case setting
int gagpos = 0; //initial full-scale gauge switch-case setting
int pxpos = 5; //initial pressure transducer switch-case setting
//-----------------------------SD card
#include <SD.h> //sd card library
Sd2Card card; //sd card comms and error handling
SdVolume volume; //sdcard filesystem (fat) handling
SdFile root; //sdcard file read & write handling
File dataFile; //define variable dataFile as the file
const int chipSelect = 5; //sc card chip select pin
String dataString; //set dataString variable as empty string
int sdflag = 0; //used to record if the logging button has been pressed, 1=yes
int sdflag2 = 0; //used to record if setup parameters have been written to sd card, 1=yes
//-----------------------------Torque variables
//float psi; //pounds-per-square-inch
float cellval = 4.00; //initial cell area
float armval = 12.00; //initial arm length
long gagval = 5000; //initial gauge full scale
int wave; //waveform variable
int16_t adc0; //16-bit integer assignment for adc0
//-----------------------------Calibration data
#include <EEPROM.h> //include the eeprom library
struct MyObject { //object to
float field1; //enable storage
byte field2; //of variables
char name[20]; //to eeprom
}; //
int pxval = 3000; //initial pressure transmitter full scale (used if eeprom is empty)
int pxzero; //calibration zero
int pxgain; //calibration gain
String pxserial; //pressure transmitter serial number
unsigned long caldatetime; //calibration date and time
int pxvaladd = 0; //pressure transmitter full scale
int pxzeroadd = 5; //calibration zero eeprom address
int pxgainadd = 10; //calibration gain eeprom address
int pxserialadd = 20; //px serial eeprom address
int caldateadd = 30; //px cal date eeprom address
int pxrange; //px adc0 range
float pxratio; //px adc to pxval ratio
//-----------------------------date & time
String datetime; //current date & time variable
void setup() {
Serial1.begin(115200); //Nextion default baud= 9600
EEPROM.get(pxvaladd, pxval); //read stored pressure transmitter full scale from eeprom
EEPROM.get(pxzeroadd, pxzero); //read stored pxzero setting from eeprom
EEPROM.get(pxgainadd, pxgain); //read stored pxzero setting from eeprom
pxrange = (pxgain - pxzero); //compute pxgain minus px zero to give span
pxratio = (pxrange / pxval);
DDRF |= (1 << PF0);
DDRD |= (1 << PD6);
if (!SD.begin(chipSelect)) { //check if the sd card is present and can be initialized
PORTD |= (1 << PD6); //turn on card present LED if no card
Serial1.print(F("vis b1,0")); //hide start logging button if no card present
three0xff(); //send three 0xff
}
ads.begin(0x48); //set ADS1115 I2C address and begin comms
//ads.setGain(GAIN_TWOTHIRDS); //2/3x gain +/- 6.144V 1 bit = 3mV
//ads.setGain(GAIN_ONE); //1x gain +/- 4.096V 1 bit = 0.125mV
ads.setGain(GAIN_TWO); //2x gain +/- 2.048V 1 bit = 0.0625mV
if (! rtc.begin()) { //check if the RTC is not available
PORTF |= (1 << PF0); //turn rtcled led on
}
if (!rtc.isrunning()) { //check if the RTC is not running
//Serial.println(F("RTC is NOT running, let's set the time!")); //print to serial port, replace with led flash
rtc.adjust(DateTime(F(__DATE__), F(__TIME__))); //write the compilation date & time to the RTC
}
//rtc.adjust(DateTime(F(__DATE__), F(__TIME__))); //write the compilation date & time to the RTC
//---------------------------------------------------------Initial comms with the Nextion
Serial1.print("t8.txt=\"" + String(celldisp) + "\""); //prints initial cell value to Nextion
three0xff(); //send three 0xff
Serial1.print("t10.txt=\"" + String(armdisp) + "\""); //prints initial armlength value to Nextion
three0xff(); //send three 0xff
Serial1.print("t12.txt=\"" + String(gagdisp) + "\""); //prints initial gauge full-scale value to Nextion
three0xff(); //send three 0xff
}
void loop() {
datestring();
HMI_read(); //read HMI
adc0 = ads.readADC_SingleEnded(0); //read the AD and store the value in var adc0
updatenextion();
//---------------------------------------------------------Check sdflags
if (sdflag == 1) { //if the start logging button has been pressed
st2next = ("vis b0,0"); //hide the settings button
stringtoNextion(); //send three 0xff
//-------------------------------------------------------Add file header information
File dataFile = SD.open("datalog", FILE_WRITE); //Create the dataFile
if (dataFile) { //Check if dataFile exists
if (sdflag2 == 1) { //Check if sdflag2 is set, skip writing header if = 1
dataFile.println(datetime); //Store date & time to sdcard
EEPROM.get(caldateadd, caldatetime); //Read stored calibration date from eeprom
dataFile.println(caldatetime); //Store calibration date to sdcard
dataFile.println((int)pxval, HEX); //Pressure transmitter full scale to sdcard
dataFile.println(pxzero, HEX); //Store pressure transmitter zero reading to sdcard
dataFile.println(pxgain, HEX); //Store pressure transmitter gain reading to sdcard
dataFile.println((int)(cellval * 100), HEX); //Store cell size to sdcard
dataFile.println((int)(armval * 100), HEX); //Store arm length to sdcard
dataFile.println(gagval / 2, HEX); //Store gauge full-scale divided by two as HEX
sdflag2 = 0; //Set sdflag2 to 0 to ensure next time around the loop these parameters are not stored
}
PORTD |= (1 << PD6); //Turn on logging LED
dataFile.println(adc0, HEX); //Store adc0 value to sd card
dataFile.close(); //Close the file on sd card
PORTD &= !(1 << PD6); //Turn off the logging LED
dataString = ""; //Empty the datastring
}
dataFile.close(); //Close the file on the sd card
}
else {
st2next = ("vis b0,1"); //Hide b1 if no card present
stringtoNextion(); //Send the string to Nextion
}
datetime = ""; //Reset datetime string to empty
}
//-----------------------------------------------------------HMI_read takes the data sent from the Nextion to the serial port
void HMI_read() { //There are 3 levels of nested switch statements corresponding to the page, object and index of the object.
static uint8_t HMI_read_data[10]; //Temporary buffer to hold the data from the display, space for 10 bytes
static uint8_t HMI_read_data_i; //Count of how many bytes have been received from the display.
static uint8_t a5count; //0xa5 repeated 3 times is used as a start indicator, this is a count of how many times it has been received.
uint8_t readtemp; //Hold the last received byte to ensure that it is only read from the receive buffer once.
while (Serial1.available() > 0) { //Read every byte in the receive buffer
readtemp = Serial1.read(); //Assign readtemp variable to incoming serial data
if (readtemp == 0xa5) { //Count the number of times 0xa5 has been received
++a5count; //Increment a5 counter
if (a5count > 2) { //If a5 count=3,
a5count = 0; //Set a5count variable to 0
HMI_read_data_i = 0; //Set HMI_read_data_i variable to 0
}
}
else {
a5count = 0; //if there is an a5 count followed by anything else, reset the a5count to 0
}
HMI_read_data[HMI_read_data_i] = readtemp;
if (HMI_read_data_i == 6) {
switch (HMI_read_data[1]) { //HMI_read_data[1] contains the page the data has come from
case 0://----------------------------------------------------page 0
switch (HMI_read_data[2]) { //HMI_read_data[2] contains the type of object on the page that the data has come from
case 0: //case 0 selects a page
break;
case 1:
switch (HMI_read_data[3]) { //HMI_read_data[3] is the index of the type of button, so 0 as there is 1 button to begin logging.
case 0: //this is where to begin logging then set a flag to 1 so that this same routine can stop logging
if (sdflag == 0) { //check if sdflag = 0
sdflag = 1; //set sdflag to 1
sdflag2 = 1; //set sdflag2 to 1
st2next = ("b1.txt=\"" + String{"Stop Log"} + "\""); //compile the stop log string
stringtoNextion(); //send the string to Nextion
}
else {
dataFile.close(); //close the satafile
sdflag = 0; //set sdflag to 0
st2next = ("b1.txt=\"" + String{"Start Log"} + "\""); //compile the start log string
stringtoNextion(); //send the string to Nextion
}
break;
}
break;
}
break;
case 1://----------------------------------page 1
switch (HMI_read_data[2]) { //HMI_read_data[2] is the index of the
case 1:
switch (HMI_read_data[3]) { //HMI_read_data[3] is the index of the type of button, 0 to 5 as there are 6 buttons for setup.
case 0://--------------------------cell down
cellpos--; //decrement cellpos variable
cellpos = constrain(cellpos, 0, 7); //keep cellpos variable between 0 to 10
change_cell(); //call change_cell routine
break;
case 1://--------------------------cell up
cellpos++; //increment cellpos variable
cellpos = constrain(cellpos, 0, 7); //keep cellpos variable between 0 to 10
change_cell(); //call change_cell routine
break;
case 2://--------------------------arm down
armpos--; //decrement armpos variable
armpos = constrain(armpos, 0, 12); //keep armpos variable between 0 to 10
armsel(); //call armsel routine
break;
case 3://--------------------------arm up
armpos++; //increment armpos variable
armpos = constrain(armpos, 0, 12); //keep armpos variable between 0 to 10
armsel(); //call armsel routine
break;
case 4://--------------------------gauge down
gagpos--; //decrement gagpos variable
gagpos = constrain(gagpos, 0, 15); //keep gagpos variable between 0 to 10
gaugesel(); //call gaugesel routine
break;
case 5://--------------------------gauge up
gagpos++; //increment gagpos variable
gagpos = constrain(gagpos, 0, 15); //keep gagpos variable between 0 to 10
gaugesel(); //call gaugesel routine
break;
case 6://--------------------------px serial number
//Serial.println("page1, case6");
break;
}
break;
}
break;
case 2://------------------------------------------------page 2
switch (HMI_read_data[2]) {
case 1:
switch (HMI_read_data[3]) { //HMI_read_data[3] is the index of the type of button, 0 to 5 as there are 6 buttons for setup.
case 0://----------------------------------------Transmitter down
pxpos--; //decrement pxpos variable
pxpos = constrain(pxpos, 0, 10); //keep pxpos variable between 0 to 10
pxsel(); //call pxsel routine
break;
case 1://----------------------------------------Transmitter up
pxpos++; //increment pxpos variable
pxpos = constrain(pxpos, 0, 10); //keep pxpos variable between 0 to 10
pxsel(); //call pxsel routine
break;
case 2://----------------------------------------Calibration set zero
pxzero = ads.readADC_SingleEnded(0); //read the adc
st2next = ("t16.txt=\"" + String(pxzero) + "\""); //set st2next equal to pxzero variable
stringtoNextion(); //send the string to Nextion
EEPROM.put(pxzeroadd, pxzero); //write zero reading to eeprom
break;
case 3://----------------------------------------Calibration set gain
pxgain = ads.readADC_SingleEnded(0); //read the adc
st2next = ("t18.txt=\"" + String(pxgain) + "\""); //set st2next equal to pxgain variable
stringtoNextion(); //send the string to Nextion
pxrange = (pxgain - pxzero); //compute pxgain minus px zero to give span
st2next = ("t19.txt=\"" + String(pxrange) + "\""); //set st2next equal to pxrange variable
stringtoNextion(); //send the string to Nextion
EEPROM.put(pxgainadd, pxgain); //write gain reading to eeprom
delay(100); //delay 100mS for EEprom write
EEPROM.put(pxvaladd, pxval); //write gain reading to eeprom
delay(100); //delay 100mS for EEprom write
caldatelong(); //Call caldatestring routine
delay(100); //delay 100mS for EEprom write
break;
}
break;
}
break;
}
}
++HMI_read_data_i;
if (HMI_read_data_i > 9) {
HMI_read_data_i = 9;
}
}
}
void change_cell() {//-------------------------------Selectable range of cell areas
switch (cellpos) {
case 0:
cellval = 4.00;
celldisp = ("4.00");
break;
case 1:
cellval = 4.08;
celldisp = ("4.08");
break;
case 2:
cellval = 6.44;
celldisp = ("6.44");
break;
case 3:
cellval = 6.53;
celldisp = ("6.53");
break;
case 4:
cellval = 8.00;
celldisp = ("8.00");
break;
case 5:
cellval = 10.80;
celldisp = ("10.80");
break;
case 6:
cellval = 12.00;
celldisp = ("12.00");
break;
case 7:
cellval = 16.00;
celldisp = ("16.00");
break;
}
st2next = ("t8.txt=\"" + String(celldisp) + "\""); //set st2next equal to celldisp variable
stringtoNextion(); //send the string to Nextion
}
void armsel() {//-------------------------------------Selectable range of arm lengths
switch (armpos) {
case 0:
armval = 1.0;
armdisp = ("0.00");
break;
case 1:
armval = 12.0;
armdisp = ("12.00");
break;
case 2:
armval = 18.0;
armdisp = ("18.00");
break;
case 3:
armval = 20.0;
armdisp = ("20.00");
break;
case 4:
armval = 22.0;
armdisp = ("22.00");
break;
case 5:
armval = 24.0;
armdisp = ("24.00");
break;
case 6:
armval = 26.0;
armdisp = ("26.00");
break;
case 7:
armval = 30.0;
armdisp = ("30.00");
break;
case 8:
armval = 32.0;
armdisp = ("32.00");
break;
case 9:
armval = 36.0;
armdisp = ("36.00");
break;
case 10:
armval = 42.0;
armdisp = ("42.00");
break;
case 11:
armval = 49.5;
armdisp = ("49.5");
break;
case 12:
armval = 52.0;
armdisp = ("52.00");
break;
}
st2next = ("t10.txt=\"" + String(armdisp) + "\""); //set st2next equal to armdisp variable
stringtoNextion(); //send the string to Nextion
}
void gaugesel() {//-------------------------Gauge selectable range of fsd torques
switch (gagpos) {
case 0:
gagval = 5000;
gagdisp = ("5000");
break;
case 1:
gagval = 6000;
gagdisp = ("6000");
break;
case 2:
gagval = 8000;
gagdisp = ("8000");
break;
case 3:
gagval = 10000;
gagdisp = ("10000");
break;
case 4:
gagval = 12000;
gagdisp = ("12000");
break;
case 5:
gagval = 15000;
gagdisp = ("15000");
break;
case 6:
gagval = 18000;
gagdisp = ("18000");
break;
case 7:
gagval = 20000;
gagdisp = ("20000");
break;
case 8:
gagval = 25000;
gagdisp = ("25000");
break;
case 9:
gagval = 30000;
gagdisp = ("30000");
break;
case 10:
gagval = 35000;
gagdisp = ("35000");
break;
case 11:
gagval = 40000;
gagdisp = ("40000");
break;
case 12:
gagval = 50000;
gagdisp = ("50000");
break;
case 13:
gagval = 75000;
gagdisp = ("75000");
break;
case 14:
gagval = 80000;
gagdisp = ("80000");
break;
case 15:
gagval = 120000;
gagdisp = ("120000");
break;
}
st2next = ("t12.txt=\"" + String(gagdisp) + "\""); //set st2next equal to gagdisp variable
stringtoNextion(); //send the string to Nextion
}
void pxsel() {//----------------------------Selectable range of full scale pressures
switch (pxpos) {
case 0:
pxval = 1000.0;
pxdisp = ("1000");
break;
case 1:
pxval = 1500.0;
pxdisp = ("1500");
break;
case 2:
pxval = 1800.0;
pxdisp = ("1800");
break;
case 3:
pxval = 2000.0;
pxdisp = ("2000");
break;
case 4:
pxval = 2600.0;
pxdisp = ("2600");
break;
case 5:
pxval = 3000.0;
pxdisp = ("3000");
break;
case 6:
pxval = 3500.0;
pxdisp = ("3500");
break;
case 7:
pxval = 4000.0;
pxdisp = ("4000");
break;
case 8:
pxval = 4500.0;
pxdisp = ("4500");
break;
case 9:
pxval = 5000.0;
pxdisp = ("5000");
break;
case 10:
pxval = 6000.0;
pxdisp = ("6000");
break;
}
st2next = ("t24.txt=\"" + String(pxdisp) + "\""); //set st2next equal to pxdisp variable
stringtoNextion(); //send the string to Nextion
}
void updatenextion() {//----------------------------------update the Nextion and do some crucial calcs
float psi = (adc0 / pxratio); //pounds-per-square-inch as a factor of adc0
float lbf = (psi * cellval); //cell pressure pounds-force
float armft = armval / 12; //convert arm inches to arm in feet for calcs only
float ftlbf = (lbf * armft); //foot-pounds torque
float lbffs = (gagval / armft); //line pull pounds-force full scale
float psifs = (lbffs / cellval); //pounds-per-square-inch full scale
float prpsi = (lbf / cellval); //linepull divided by cell area equals pounds-per-square-inch
wave = map(adc0, 0, 32752, 0, 255); //maps AD output for display on the grid only
//------------------------------------------------------strings to Nextion
st2next = ("t0.txt=\"" + String(ftlbf) + "\""); //compile the ftlbf string
stringtoNextion(); //send the string to Nextion
st2next = ("t2.txt=\"" + String(psi) + "\""); //compile the psi string
stringtoNextion(); //send the string to Nextion
st2next = ("t4.txt=\"" + String(lbf) + "\""); //compile the lbf string
stringtoNextion(); //send the string to Nextion
st2next = ("t16.txt=\"" + String(pxzero) + "\""); //compile the pxzero string
stringtoNextion(); //send the string to Nextion
st2next = ("t18.txt=\"" + String(pxgain) + "\""); //compile the pxgain string
stringtoNextion(); //send the string to Nextion
st2next = ("t21.txt=\"" + String(adc0) + "\""); //compile the adc0 string
stringtoNextion(); //send the string to Nextion
st2next = ("t23.txt=\"" + (datetime) + "\""); //compile the datetime string
stringtoNextion(); //send the string to Nextion
st2next = ("t30.txt=\"" + String(gagval * 0.25) + "\""); //compile the gagval/4 string
stringtoNextion(); //send the string to Nextion
st2next = ("t31.txt=\"" + String(psifs * 0.25) + "\""); //compile the psi full scale / 4 string
stringtoNextion(); //send the string to Nextion
st2next = ("t33.txt=\"" + String(gagval * 0.5) + "\""); //compile the gagval/2 string
stringtoNextion(); //send the string to Nextion
st2next = ("t34.txt=\"" + String(psifs * 0.5) + "\""); //compile the psi full scale / 4 string
stringtoNextion(); //send the string to Nextion
st2next = ("t36.txt=\"" + String(gagval * 0.75) + "\""); //compile the gagval*0.75 string
stringtoNextion(); //send the string to Nextion
st2next = ("t37.txt=\"" + String(psifs * 0.75) + "\""); //compile the psi full scale * 0.75 string
stringtoNextion(); //send the string to Nextion
st2next = ("t39.txt=\"" + String(gagval) + "\""); //compile the gagval string
stringtoNextion(); //send the string to Nextion
st2next = ("t40.txt=\"" + String(psifs) + "\""); //compile the psi full scale string
stringtoNextion(); //send the string to Nextion
st2next = ("t41.txt=\"" + String(psi) + "\""); //compile the psi string
stringtoNextion(); //send the string to Nextion
//---------------------------------------------------------Graph data
String Tosend = "add 6,0,"; //send the string "add id,channel,"
Tosend += wave; //Send the value and 3 full bytes
Serial1.print(Tosend); //send wave value to Nextion (string)
three0xff(); //send three 0xff
}
void stringtoNextion() {//------------------print nextion commands followed by three 0xff
Serial1.print(st2next); //print st2next string to serial1
three0xff(); //send three 0xff
st2next = ""; //reset string variable to empty
}
void three0xff() {//------------------------Three 0xff needed by Nextion following a command
Serial1.write(0xff); //print 0xff to serial1
Serial1.write(0xff); //print 0xff to serial1
Serial1.write(0xff); //print 0xff to serial1
}
void datestring() {//-----------------------Compile date and time "now" into a single string
DateTime now = rtc.now(); //grab date & time from the RTC
long datetime1 = (now.unixtime());
String datetimehex = String(datetime1);
datetime += (datetimehex);
}
void caldatelong() {//-----------------------Compile date and time "now" into a single string
DateTime now = rtc.now(); //grab date & time from the RTC
caldatetime = (now.unixtime()); //assign unixtime to caldatetime
EEPROM.put(caldateadd, caldatetime); //write calibration date to eeprom
}