From 5bb6d90735a1007c3a8a5b531745d3b671804b7c Mon Sep 17 00:00:00 2001 From: Utsav Kataria Date: Thu, 28 Mar 2024 06:23:57 +0000 Subject: [PATCH] Upload New File --- TruehemeV0.1.3.ino | 764 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 764 insertions(+) create mode 100644 TruehemeV0.1.3.ino diff --git a/TruehemeV0.1.3.ino b/TruehemeV0.1.3.ino new file mode 100644 index 0000000..f2821a3 --- /dev/null +++ b/TruehemeV0.1.3.ino @@ -0,0 +1,764 @@ +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////TRUEHEME CODE V0.1.3 - BETA Version (Tested)///////////////////////////////////////////////////////////////////// +//////////NEW Changes: All LED warmup function Added; Limit Switch added;EEPROM storage of DAC values; Stray light sensing; Turing on any one LED/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +#include "ADS1X15.h" +#include +#include +#include +/////////////////////////////////////////////////////////////////////PLEASE UPDATE DEVICE ID BEFORE UPLOADING TO ANY DEVICE///////////////////////////////////////////////////////////////// +String Device_ID = "SNS HCV-001-0012 SNE"; // Device ID +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +const int LED_available[] = {1,2,3,4}; // List of LEDs available. All Variables with 4 columns (other than ones controlling the LED turning ON sequence) must be filled in this order +int LED_sequence[] = {1,2,3,4}; // LED turning ON sequence +int Detector_sequence[] = {1,1,1,1}; // Detector sequence (if hardware supports dual pathlength) +int LED_dac[] = {1792,2304,2040,1920}; // Preset DAC values for the device +int LED_sample_size[] = {50,50,50,50}; // No. of ADC readings to use for Average ADC calculation +int LED_DS_threshold[] = {22000,18000,18000,22000}; // DAC sweep upperlimit for each LED +int LED_settling_time[] = {20000,20000,20000,20000}; // Settling time given to each LED +int ADC_reading_delay[] = {0,0,0,0}; // Delay for each ADC reading while averaging +int led_warmup_DAC[] = {3000,3000,3000,3000}; // DAC value at which all the LEDs will be powered during LED warmup +int DAC_Sweep_start_limit[] = {1000,1000,1000,1000}; // Lower limit for DAC sweep +int DAC_Sweep_end_limit[] = {4000,4000,4000,4000}; // Upper limit for DAC sweep +int DacSweep_gain_combinations[] = {0,0,0,0}; // Gain to be used for DAC sweep + +int incr=8; // DAC sweep increment +int del=1000; // Delay between each interval of the DAC sweep +int appmode=1; // if =1, it removes most of the unwanted serial prints +int raw_ADC_print=0; // if =1, it will serialprint raw ADC values (even during LED warmup and settling) +int timestamp_printer=0; // if =1, will print timestamp at regular intervals +int limit_switch_active=0; // If there is a limit switch in the device, make it 1 + +int Blank_gain_combinations[] = {0,0,0,0}; // Programmable gain to be used while blanking +int Sample_gain_combinations[5][4] = {{0,0,0,0},{1,1,1,1},{2,2,2,2},{4,4,4,4},{8,8,8,8}}; // Programmable gain to be used while taking sample readings + +///////////////////////////////////////////DO NOT CHANGE ANY VALUES BELOW ////////////////////////////////////////////////////////////////////////////////////////////// +const int PIN_CS_DAC1 = 10; // Chip select pin for DAC 1 +const int PIN_CS_DAC2 = 9; // Chip select pin for DAC 2 +const int GAIN_1 = 0x1; // DAC 1X gain (output between 0 - 2.048 Volts) +const int GAIN_2 = 0x0; // DAC 2X gain (output between 0 - 4.096 Volts) + +const int PD1G1 = 6; // Programmable gain resistor _______ohm +const int PD1G2 = 8; // Programmable gain resistor _______ohm +const int PD2G1 = 5; // Programmable gain resistor _______ohm +const int PD2G2 = 7; // Programmable gain resistor _______ohm + +const int LEDR = A2; // Red indicator LED +const int LEDB = A0; // Blue indicator LED +const int LEDG = A1; // Green indicator LED + +const int Limit_Switch = 2; // Limit switch for cuvette sensing +const int Buzzer_pin = 3; // Buzzer connection for alert + +ADS1115 ADS(0x48); +///////////////////////////////////////////DO NOT CHANGE ANY VALUES ABOVE ////////////////////////////////////////////////////////////////////////////////////////////// +const char compile_date[] = __DATE__ " " __TIME__; //Stores date and time when the firmware was uploaded on the arduino +String Firmware_location_Auto=__FILE__; //Stores location of the firmware on the computer used for uploading +String Firmware_version_Auto=__FILE__; //Stores the firmware version uploaded +int DAC_lower_limit[]= {0,0,0,0}; +int DAC_upper_limit[]= {4096,4096,4096,4096}; +unsigned long long intensity_storage = 0; +int temp_counter = 0; +const int detector_settling_time=2000; +const int detector_settling_time_DACsweep=1000; + +float avg_storage = 0; +float avg_green = 0; +float avg_blue = 0; +float old_green = 0; +float old_blue = 0; +int initialRGBstate=0; + +int split_counter = 0; +int intensity_display = 1; +int plotter = 0; + +int j = 0; + +float average_readings = 0; +float avg_blank[]={0,0,0,0}; +float avg_air_blank[]={0,0,0,0}; +float avg_sample[]={0,0,0,0}; +int LED_on_status[]={0,0,0,0}; +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void setup() +{ + Serial.begin(9600); + pinMode(PIN_CS_DAC1, OUTPUT); + pinMode(PIN_CS_DAC2, OUTPUT); + pinMode(PD1G1, OUTPUT); + pinMode(PD1G2, OUTPUT); + pinMode(PD2G1, OUTPUT); + pinMode(PD2G2, OUTPUT); + pinMode(LEDR, OUTPUT); + pinMode(LEDG, OUTPUT); + pinMode(LEDB, OUTPUT); + pinMode(Limit_Switch, INPUT); + pinMode(Buzzer_pin, OUTPUT); + digitalWrite(LEDR, LOW); + digitalWrite(LEDG, HIGH); + digitalWrite(LEDB, HIGH); + SPI.begin(); + SPI.setClockDivider(SPI_CLOCK_DIV2); + ADS.begin(); + if(appmode==0) + { + Serial.print("Initial DAC Settings: "); + for (int i =0; i<4;i++) + { + Serial.print("\t");Serial.print(LED_dac[i]); + } + Serial.println(); + } + if(appmode==0) + { + Serial.print("Process: Setup End; Timestamp: ");Serial.println(millis()); + } +} +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void buzzer(int mode) +{ + if(mode==1) + { + tone(Buzzer_pin, 2730, 1000); + } + else if (mode==2) + { + tone(Buzzer_pin, 2730, 5000); + } +} +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void all_LEDs_turnoff() +{ + setOutput(GAIN_1, 0, 1); //LED 1 + setOutput(GAIN_1, 0, 2); //LED 2 + setOutput(GAIN_1, 0, 3); //LED 3 + setOutput(GAIN_1, 0, 4); //LED 4 +} +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void secondary_gain_select(int gain_combo) +{ + bool gain_choice1=bitRead(gain_combo, 0); + bool gain_choice2=bitRead(gain_combo, 1); + bool gain_choice3=bitRead(gain_combo, 2); + bool gain_choice4=bitRead(gain_combo, 3); + digitalWrite(PD1G1, gain_choice1); + digitalWrite(PD1G2, gain_choice2); + digitalWrite(PD2G1, gain_choice3); + digitalWrite(PD2G2, gain_choice4); + if(appmode==0) + { + Serial.print("Gains Used\t G1:");Serial.print(gain_choice1);Serial.print("\t G2:");Serial.print(gain_choice2);Serial.print("\t G3:");Serial.print(gain_choice3);Serial.print("\t G4:");Serial.println(gain_choice4); + } +} +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void setOutput(byte gain, unsigned int val, int LEDselect) +{ + byte channel=0; + byte shutdown=1; + if(LEDselect%2==0) + { + channel=1; + } + else + { + channel=0; + } + byte lowByte = val & 0xff; + byte highByte = ((val >> 8) & 0xff) | channel << 7 | gain << 5 | shutdown << 4; + if (LEDselect <= 2) + { + PORTB &= 0xfb; + SPI.transfer(highByte); + SPI.transfer(lowByte); + PORTB |= 0x4; + } + else + { + PORTB &= 0xfd; + SPI.transfer(highByte); + SPI.transfer(lowByte); + PORTB |= 0x2; + } +} +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void indicator_LED(char statusLED) +{ + digitalWrite(LEDR,LOW); + digitalWrite(LEDG,LOW); + digitalWrite(LEDB,LOW); + digitalWrite(LEDR,(statusLED=='R')); + digitalWrite(LEDG,(statusLED=='G')); + digitalWrite(LEDB,(statusLED=='B')); + /* + if(statusLED=='R') + { + digitalWrite(LEDR,HIGH); + digitalWrite(LEDG,LOW); + digitalWrite(LEDB,LOW); + //Serial.println("RED"); + } + else if(statusLED=='G') + { + digitalWrite(LEDR,LOW); + digitalWrite(LEDG,HIGH); + digitalWrite(LEDB,LOW); + //Serial.println("G"); + } + else if(statusLED=='B') + { + digitalWrite(LEDR,LOW); + digitalWrite(LEDG,LOW); + digitalWrite(LEDB,HIGH); + //Serial.println("B"); + } + else + { + digitalWrite(LEDR,LOW); + digitalWrite(LEDG,LOW); + digitalWrite(LEDB,LOW); + } + */ +} +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +int setDAC_LED() +{ + int LED_flags[]={0,0,0,0}; + int flags_combined=0; + if(appmode==0) + { + Serial.println("#DAC Sweep Start"); + } + all_LEDs_turnoff(); + delay(1000); + ////////////////////////////////////////FIRST FORLOOP TO DISCARD STARTS///////////////////////////////////////////////// + for (int i=3000;i<4096;i+=incr) + { + setOutput(GAIN_1, i, 1); + delay(del); + int16_t val_0 = ADS.readADC(0); + if((val_0>24000)) + { + break; + } + } + all_LEDs_turnoff(); + delay(1000); + ////////////////////////////////////////FIRST FORLOOP TO DISCARD ENDS///////////////////////////////////////////////// + for (int j=0;j<4;j++) + { + all_LEDs_turnoff(); + secondary_gain_select(DacSweep_gain_combinations[j]); + for (int i=DAC_Sweep_start_limit[j];iLED_DS_threshold[j])&&(LED_flags[j]==0)) + { + LED_dac[j]=i; + LED_flags[j]=1; + break; + } + } + all_LEDs_turnoff(); + if (appmode==0) + { + Serial.print("LED ");Serial.print(j+1);Serial.print(" DACsweep Completed");Serial.print("\t");Serial.print("NEW DAC VALUE : ");Serial.println(LED_dac[j]); + } + delay(1000); + } + all_LEDs_turnoff(); + flags_combined=(LED_flags[3]*1)+(LED_flags[2]*10)+(LED_flags[1]*100)+(LED_flags[0]*1000); + if(appmode==0) + { + Serial.println("#DAC Sweep End"); + } + return flags_combined; +} +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void eeprom_DAC_write() +{ + int led_dac_split[]= {0,0,0,0,0,0,0,0}; + Serial.println("#WS"); + led_dac_split[0] = LED_dac[0]/100; + led_dac_split[1] = LED_dac[0]-(led_dac_split[0]*100); + led_dac_split[2] = LED_dac[1]/100; + led_dac_split[3] = LED_dac[1]-(led_dac_split[2]*100); + led_dac_split[4] = LED_dac[2]/100; + led_dac_split[5] = LED_dac[2]-(led_dac_split[4]*100); + led_dac_split[6] = LED_dac[3]/100; + led_dac_split[7] = LED_dac[3]-(led_dac_split[6]*100); + if(appmode==0) + { + Serial.print(led_dac_split[0]);Serial.print("\t");Serial.println(led_dac_split[1]); + Serial.print(led_dac_split[2]);Serial.print("\t");Serial.println(led_dac_split[3]); + Serial.print(led_dac_split[4]);Serial.print("\t");Serial.println(led_dac_split[5]); + Serial.print(led_dac_split[6]);Serial.print("\t");Serial.println(led_dac_split[7]); + } + for (int i=0;i<8; i++) + { + EEPROM.write(i, led_dac_split[i]); + } + Serial.println("#WC"); +} +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void eeprom_DAC_read() +{ + int led_dac_split[]= {0,0,0,0,0,0,0,0}; + Serial.println("#RS"); + for(int i=0;i<8;i++) + { + led_dac_split[i] = EEPROM.read(i); + } + for(int i=0;i<4;i++) + { + LED_dac[i] = (led_dac_split[i*2]*100)+led_dac_split[(i*2)+1]; + } + if(appmode==0) + { + Serial.print(led_dac_split[0]);Serial.print("\t");Serial.println(led_dac_split[1]); + Serial.print(led_dac_split[2]);Serial.print("\t");Serial.println(led_dac_split[3]); + Serial.print(led_dac_split[4]);Serial.print("\t");Serial.println(led_dac_split[5]); + Serial.print(led_dac_split[6]);Serial.print("\t");Serial.println(led_dac_split[7]); + Serial.print(LED_dac[0]);Serial.print("\t");Serial.print(LED_dac[1]);Serial.print("\t");Serial.print(LED_dac[2]);Serial.print("\t");Serial.println(LED_dac[3]); + } + Serial.println("#RC"); +} +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void LED_warmup(int warmup_time) +{ + int warmup_start=millis(); + int current_time=millis(); + while((current_time-warmup_start) 10)&&(appmode==0)) + { + Serial.println("Error: stray light interference or LED partly ON "); + } + int flag=0; + secondary_gain_select(DacSweep_gain_combinations[j]); + for (int i = 0; i <=4096; i+= reading_increment) + { + setOutput(GAIN_1, i, j+1); + int start_time=millis(); + int current_time=millis(); + while ((current_time-start_time)LED_DS_threshold[LED_sequence[j]-1])&&(flag==0)) + { + lowerlimit_dac= i-(reading_increment*2); + upperlimit_dac= i+(reading_increment*2); + if (lowerlimit_dac<0) + { + lowerlimit_dac=0; + } + if(upperlimit_dac>4095) + { + upperlimit_dac=4095; + } + DAC_lower_limit[j]=lowerlimit_dac; + DAC_upper_limit[j]=upperlimit_dac; + flag=1; + } + Serial.print("LED:");Serial.print(j+1);Serial.print("__DAC:");Serial.print(i);Serial.print("__ADC:");Serial.println(val_0); + } + if (appmode==0) + { + Serial.print("LED:");Serial.print(j+1);Serial.print("__DAC LOWER LIMIT:");Serial.println(DAC_lower_limit[j]); + Serial.print("LED:");Serial.print(j+1);Serial.print("__DAC UPPER LIMIT:");Serial.println(DAC_upper_limit[j]); + } + secondary_gain_select(0); + all_LEDs_turnoff(); + } + Serial.println("#DC"); + all_LEDs_turnoff(); + delay(1000); + if((appmode==0)&&(timestamp_printer==1)) + { + Serial.print("Process: Diagnostics end; Timestamp: ");Serial.println(millis()); + } +} +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void startTask4() +{ + if((appmode==0)&&(timestamp_printer==1)) + { + Serial.print("Process: Buffer start; Timestamp: ");Serial.println(millis()); + } + all_LEDs_turnoff(); + delay(100); + all_LEDs_turnoff(); + Serial.println("#BS"); + for (int i=0;i<4;i++) + { + setOutput(GAIN_1, 0, LED_sequence[i]); + delay(100); + avg_blank[i] = detector(LED_sample_size[LED_sequence[i]-1], Detector_sequence[LED_sequence[i]-1], Blank_gain_combinations[LED_sequence[i]-1], 2000, ADC_reading_delay[LED_sequence[i]-1]); + all_LEDs_turnoff(); + delay(1000); + } + if (appmode==0) + { + Serial.print(millis());Serial.print("\t");Serial.print("LED1B : "); Serial.print(avg_blank[0]); Serial.print("\t"); Serial.print("LED2B : "); Serial.print(avg_blank[1]); Serial.print("\t"); Serial.print("LED3B : "); Serial.print(avg_blank[2]); Serial.print("\t"); Serial.print("LED4B : "); Serial.println(avg_blank[3]); + } + Serial.println("#BC"); + if((appmode==0)&&(timestamp_printer==1)) + { + Serial.print("Process: Buffer end; Timestamp: ");Serial.println(millis()); + } +} +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////