diff --git a/Software_development/Code.ino b/Software_development/Code.ino new file mode 100644 index 0000000..9ac7ca8 --- /dev/null +++ b/Software_development/Code.ino @@ -0,0 +1,383 @@ +#include + +// LCD +#define rs 2 +#define en 3 +#define d4 4 +#define d5 5 +#define d6 6 +#define d7 7 +LiquidCrystal lcd(rs, en, d4, d5, d6, d7); + +// Encoder inicialization +#define CLK 10 +#define DT 9 +#define SW 8 + +// Borders for buttons +#define UP_const 100 +#define DOWN_const_high 600 +#define DOWN_const_low 400 + +// Discharge button +#define DISCH_PIN 11 + + +// Output pin +#define OUT_PIN_1 12 +#define OUT_PIN_2 21 +#define OUT_PIN_3 20 + +// Variables +int counter_case_1 = 0; +int currentStateCLK; +int lastStateCLK; +String currentDir =""; +unsigned long lastButtonPress = 0; +unsigned long DICHARGElastButtonPress = 0; + +bool button_UP_pressed=false; +bool button_DOWN_pressed=false; +bool button_UP_status=false; +bool button_DOWN_status=false; +bool Case_0_status=false; +bool Case_1_status=false; +bool Case_2_status=false; + +int menu_status=0; +bool menu_status_CHANGE=false; + +float voltage_level=0; +float voltage_step=1; + +int x, x_check; + +int battery_status=-1, battery_status_update=-1, battery_level=0; + +int puls_freq=11; //puls frequency in kHz + +void setup() { + +// LCD initialization +lcd.begin(20, 4); + +lcd.clear(); +lcd.setCursor(7, 1); +lcd.print("O-ESD"); +lcd.setCursor(6, 2); +lcd.print("WELCOME"); +delay(3000); +lcd.clear(); +lcd.setCursor(1, 0); +lcd.print("Battery: "); +lcd.setCursor(0, 1); +lcd.print(">Discharge: Contact"); +lcd.setCursor(1, 2); +lcd.print("Frequency: 11 kHz"); +lcd.setCursor(1, 3); +lcd.print("Mode: Single"); + + +// Encoder initialization +pinMode(CLK,INPUT); +pinMode(DT,INPUT); +pinMode(SW, INPUT_PULLUP); +lastStateCLK = digitalRead(CLK); + +// Output pin +digitalWrite(OUT_PIN_1, LOW); +pinMode(OUT_PIN_1, OUTPUT); +digitalWrite(OUT_PIN_2, HIGH); +pinMode(OUT_PIN_2, OUTPUT); +digitalWrite(OUT_PIN_3, LOW); +pinMode(OUT_PIN_3, OUTPUT); +} + +void loop() { + + battery_level=analogRead(1); + //lcd.setCursor(0, 0); + //lcd.print("Battery: "); + + if (battery_level < 650) {battery_status_update=0;} //under 3.7 V + else {if (650 < battery_level && battery_level < 675) battery_status_update=1; + else {if (675 < battery_level && battery_level < 700) battery_status_update=2; + else {if (700 < battery_level && battery_level < 725) battery_status_update=3; + else {if (725 < battery_level && battery_level < 750) battery_status_update=4; + else {if (750 < battery_level && battery_level < 775) battery_status_update=5; + else {if (775 < battery_level && battery_level < 800) battery_status_update=6; + else {if (800 < battery_level && battery_level < 825) battery_status_update=7; + else {if (825 < battery_level && battery_level < 850) battery_status_update=8; + else {if (850 < battery_level && battery_level < 860) battery_status_update=9; + else {battery_status_update=10;} + } } } } } } } } } + + if (battery_status!=battery_status_update) { + switch (battery_status_update){ + case 0: lcd.setCursor(9, 0); lcd.print(" "); lcd.setCursor(12, 0);lcd.print("Low"); break; //under 3.7 V + case 1: lcd.setCursor(9, 0); lcd.print(" "); lcd.setCursor(19, 0); lcd.print(char(255)); break; + case 2: lcd.setCursor(9, 0); lcd.print(" "); lcd.setCursor(18, 0); lcd.print(char(255));lcd.print(char(255)); break; + case 3: lcd.setCursor(9, 0); lcd.print(" "); lcd.setCursor(17, 0); lcd.print(char(255));lcd.print(char(255));lcd.print(char(255)); break; + case 4: lcd.setCursor(9, 0); lcd.print(" "); lcd.setCursor(16, 0); lcd.print(char(255));lcd.print(char(255));lcd.print(char(255));lcd.print(char(255)); break; + case 5: lcd.setCursor(9, 0); lcd.print(" "); lcd.setCursor(15, 0); lcd.print(char(255));lcd.print(char(255));lcd.print(char(255));lcd.print(char(255));lcd.print(char(255)); break; + case 6: lcd.setCursor(9, 0); lcd.print(" "); lcd.setCursor(14, 0); lcd.print(char(255));lcd.print(char(255));lcd.print(char(255));lcd.print(char(255));lcd.print(char(255));lcd.print(char(255)); break; + case 7: lcd.setCursor(9, 0); lcd.print(" "); lcd.setCursor(13, 0); lcd.print(char(255));lcd.print(char(255));lcd.print(char(255));lcd.print(char(255));lcd.print(char(255));lcd.print(char(255));lcd.print(char(255)); break; + case 8: lcd.setCursor(9, 0); lcd.print(" "); lcd.setCursor(12, 0); lcd.print(char(255));lcd.print(char(255));lcd.print(char(255));lcd.print(char(255));lcd.print(char(255));lcd.print(char(255));lcd.print(char(255));lcd.print(char(255)); break; + case 9: lcd.setCursor(9, 0); lcd.print(" "); lcd.setCursor(11, 0); lcd.print(char(255));lcd.print(char(255));lcd.print(char(255));lcd.print(char(255));lcd.print(char(255));lcd.print(char(255));lcd.print(char(255));lcd.print(char(255));lcd.print(char(255)); break; + case 10: lcd.setCursor(9, 0); lcd.print(" "); lcd.setCursor(12, 0);lcd.print("Problem"); break; + } + battery_status=battery_status_update; + } + + +if (menu_status_CHANGE) { + switch (menu_status) { + case 0: + lcd.setCursor(0, 2); + lcd.print(" "); + lcd.setCursor(0, 3); + lcd.print(" "); + lcd.setCursor(0, 1); + lcd.print(">"); + break; + case 1: + lcd.setCursor(0, 1); + lcd.print(" "); + lcd.setCursor(0, 3); + lcd.print(" "); + lcd.setCursor(0, 2); + lcd.print(">"); + break; + case 2: + lcd.setCursor(0, 1); + lcd.print(" "); + lcd.setCursor(0, 2); + lcd.print(" "); + lcd.setCursor(0, 3); + lcd.print(">"); + break; + } + menu_status_CHANGE=false; +} + + + + // Handle buttons + x = analogRead (0); + delay(1); + + if (x < UP_const && !button_UP_pressed) { + delay(5); + x_check=analogRead(0); + if(x_check < UP_const) { + button_UP_pressed=true; + } + + if(button_UP_pressed){ + if (menu_status>0){ + menu_status=menu_status-1; + menu_status_CHANGE=true; + } + + } + + + while(button_UP_pressed) + { + delay(10); + x_check=analogRead(0); + if(x_check DOWN_const_low && !button_DOWN_pressed) { + delay(5); + x_check=analogRead(0); + if(x_check< DOWN_const_high && x_check>DOWN_const_low){ + button_DOWN_pressed=true; + } + if(button_DOWN_pressed){ + if (menu_status<2){ + menu_status=menu_status+1; + menu_status_CHANGE=true; + + } + + while(button_DOWN_pressed) + { + delay(10); + x_check=analogRead(0); + if(x_checkDOWN_const_low){ + button_DOWN_pressed=true; + } + else {button_DOWN_pressed=false;} + } + } + } + delay(1); + + + +// Encoder check + +if (menu_status==1){ + currentStateCLK = digitalRead(CLK); + if (currentStateCLK != lastStateCLK && currentStateCLK == 1){ + + if (digitalRead(DT) != currentStateCLK) { + if (Case_1_status) { + puls_freq=puls_freq-1; + } + else { + puls_freq=puls_freq-1; + } + currentDir ="CCW"; + } + else { + if (Case_1_status) { + puls_freq=puls_freq+1; + } + else { + puls_freq=puls_freq+1; + } + currentDir ="CW"; + } + + lcd.setCursor(12, 2); + lcd.print(" "); + lcd.setCursor(12, 2); + lcd.print(puls_freq,1); + lcd.print(" kHz"); + } + + + lastStateCLK = currentStateCLK; +} + +int btnState = digitalRead(SW); + +if (btnState == LOW) { + if (millis() - lastButtonPress > 50) { + switch (menu_status){ + case 0: + if (Case_0_status) { + lcd.setCursor(12, 1); + lcd.print(" "); + lcd.setCursor(12, 1); + lcd.print("Contact"); + Case_0_status=false; + } + else { + lcd.setCursor(12, 1); + lcd.print(" "); + lcd.setCursor(12, 1); + lcd.print("Air"); + Case_0_status=true; + } + break; + case 1: + if (Case_1_status){ + Case_1_status=false; + } + else{ + Case_1_status=true; + } + break; + case 2: + if (Case_2_status) { + lcd.setCursor(12, 3); + lcd.print(" "); + lcd.setCursor(12, 3); + lcd.print("Single"); + Case_2_status=false; + } + else { + lcd.setCursor(12, 3); + lcd.print(" "); + lcd.setCursor(12, 3); + lcd.print("Pulse"); + Case_2_status=true; + } + break; + } + } + lastButtonPress = millis(); +} + +//Button for disharge start + +int Mode=5; + +if (!Case_0_status && !Case_2_status) Mode=1; // Contact discharge, Single +if (!Case_0_status && Case_2_status) Mode=2; // Contact discharge, Repetition +if (Case_0_status && !Case_2_status) Mode=3; // Air discharge, Single +if (Case_0_status && Case_2_status) Mode=4; // Air discharge, Repetition + +int DICHARGEbtnState = digitalRead(DISCH_PIN); + +if (DICHARGEbtnState == HIGH) { + if (millis() - DICHARGElastButtonPress > 50) { + + lcd.clear(); + lcd.setCursor(6,1); + lcd.print("TESTING"); + lcd.setCursor(5,2); + lcd.print("DISCHARGE"); + int us_delay=1000/(2*puls_freq); + + + for (int counter=0; counter<20000; counter++) + { + digitalWrite(OUT_PIN_1, HIGH); + digitalWrite(OUT_PIN_2, LOW); + delayMicroseconds(us_delay); + digitalWrite(OUT_PIN_1, LOW); + digitalWrite(OUT_PIN_2, HIGH); + delayMicroseconds(us_delay); + } + + digitalWrite(OUT_PIN_3, HIGH); + delay(100); + digitalWrite(OUT_PIN_3, LOW); + + lcd.clear(); + lcd.setCursor(1, 0); + lcd.print("Battery: "); + lcd.setCursor(1, 1); + lcd.print("Discharge: Contact"); + lcd.setCursor(0, 2); + lcd.print(">Frequency: "); + lcd.setCursor(12, 2); + lcd.print(puls_freq,1); + lcd.print(" kHz"); + lcd.setCursor(1, 3); + lcd.print("Mode: Single"); + + + } + DICHARGElastButtonPress = millis(); + + lcd.setCursor(1, 0); + lcd.print("Battery: "); + + switch (battery_status){ + case 0: lcd.setCursor(9, 0); lcd.print(" "); lcd.setCursor(12, 0);lcd.print("Low"); break; //under 3.7 V + case 1: lcd.setCursor(9, 0); lcd.print(" "); lcd.setCursor(19, 0); lcd.print(char(255)); break; + case 2: lcd.setCursor(9, 0); lcd.print(" "); lcd.setCursor(18, 0); lcd.print(char(255));lcd.print(char(255)); break; + case 3: lcd.setCursor(9, 0); lcd.print(" "); lcd.setCursor(17, 0); lcd.print(char(255));lcd.print(char(255));lcd.print(char(255)); break; + case 4: lcd.setCursor(9, 0); lcd.print(" "); lcd.setCursor(16, 0); lcd.print(char(255));lcd.print(char(255));lcd.print(char(255));lcd.print(char(255)); break; + case 5: lcd.setCursor(9, 0); lcd.print(" "); lcd.setCursor(15, 0); lcd.print(char(255));lcd.print(char(255));lcd.print(char(255));lcd.print(char(255));lcd.print(char(255)); break; + case 6: lcd.setCursor(9, 0); lcd.print(" "); lcd.setCursor(14, 0); lcd.print(char(255));lcd.print(char(255));lcd.print(char(255));lcd.print(char(255));lcd.print(char(255));lcd.print(char(255)); break; + case 7: lcd.setCursor(9, 0); lcd.print(" "); lcd.setCursor(13, 0); lcd.print(char(255));lcd.print(char(255));lcd.print(char(255));lcd.print(char(255));lcd.print(char(255));lcd.print(char(255));lcd.print(char(255)); break; + case 8: lcd.setCursor(9, 0); lcd.print(" "); lcd.setCursor(12, 0); lcd.print(char(255));lcd.print(char(255));lcd.print(char(255));lcd.print(char(255));lcd.print(char(255));lcd.print(char(255));lcd.print(char(255));lcd.print(char(255)); break; + case 9: lcd.setCursor(9, 0); lcd.print(" "); lcd.setCursor(11, 0); lcd.print(char(255));lcd.print(char(255));lcd.print(char(255));lcd.print(char(255));lcd.print(char(255));lcd.print(char(255));lcd.print(char(255));lcd.print(char(255));lcd.print(char(255)); break; + case 10: lcd.setCursor(9, 0); lcd.print(" "); lcd.setCursor(12, 0);lcd.print("Problem"); break; + } +} + +} \ No newline at end of file diff --git a/Software_development/Readme.txt b/Software_development/Readme.txt new file mode 100644 index 0000000..6f38cca --- /dev/null +++ b/Software_development/Readme.txt @@ -0,0 +1,10 @@ +This folder contains codes for O-ESD microcontroller(s) that orchestrate all functionalities. + +Due to the ESD tests, the Arduino Nano & Arduino Nano Every are selected as microcontrollers. Hence, the code is for Arduino Nano family of microcontrollers. + +The currently used code in O-ESD prototypes can be found in Code.ino. Note that only functionalities used up to this moment are coded, while the place-holders are put for additional functionalities that are planed. This code is under development and will change. + +Additionally, the code for synthesis of pulse trains of precise frequency can be found in Registers.ino. It is primarily used to test prototypes. + + + diff --git a/Software_development/Registers.ino b/Software_development/Registers.ino new file mode 100644 index 0000000..0125964 --- /dev/null +++ b/Software_development/Registers.ino @@ -0,0 +1,53 @@ +void setup () +{ + //--- These lines set-up output at pins #9 and #10 for push-pull and are implemented in hardware ---// + digitalWrite( 9, HIGH); // set pin #9 to HIGH + pinMode ( 9, OUTPUT); // pin #9 in output mode + digitalWrite(10, LOW ); // set pin #10 to LOW + pinMode (10, OUTPUT); // pin #10 in output mode + + TCCR1A = 0; // Timer/Counter Control Register 1A set to 0 + TCCR1B = 0; // Timer/Counter Control Register 1B set to 0 + TCNT1 = 0; // Set counter for timer #1 to 0 + + uint16_t freq = 9000; + uint16_t tc = 8000000/freq; + // 2 -> 4000 kHz + // 20 -> 400 kHz + // 200 -> 40 kHz + // 800 -> 10 kHz + // 1600 -> 5 kHz + // 2000 -> 4 kHz + + ICR1 = tc; + OCR1A = tc/2; // number of ticks for counter 1A - Output Compare Register for A + OCR1B = tc/2; // set number of ticks for counter 1B to the same value as for 1A - Output Compare Register for B + + TCCR1A |= (0 << COM1A0); // enable toggling output A - Compare Match Output A Mode bit set to 1/* + TCCR1A |= (1 << COM1A1); + TCCR1A |= (1 << COM1B0); // enable toggling output B - Compare Match Output B Mode bit set to 1 + TCCR1A |= (1 << COM1B1); + + // Phase and Frequency correct PWM with TOP set by ICR1 + TCCR1B |= (1 << WGM13); // WGM=8 + + TCCR1B &= ~((1 << CS12) | (1 << CS11) | (1 << CS10)); // Clear the three clock select bits + TCCR1B |= (1 << CS10); + + // see https://ww1.microchip.com/downloads/aemDocuments/documents/MCU08/ProductDocuments/DataSheets/ATmega48A-PA-88A-PA-168A-PA-328-P-DS-DS40002061B.pdf + // sections 16, 17, 18 for details + + // f = fclk/(2*N*(1+OCR1A)) + // N variable represents the prescale factor (1, 8, 32, 64, 128, 256, or 1024), set CS10/CS11/CS12 appropriately + + // find values of OCR1A for frequencies of interest + // consider using timer #2! + +} + +void loop() { + // put your main code here, to run repeatedly: + +} + +