#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <OneButton.h>
/*
+++++++++++++++++++++++++++++++++++++++
Display (OLED 128x64)
fontsize 6x8 (default)
+++++++++++++++++++++++++++++++++++++++
*/
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels
// declare an SSD1306 display object connected to I2C
Adafruit_SSD1306 oled(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);
/*
+++++++++++++++++++++++++++++++++++++++
Encoder
+++++++++++++++++++++++++++++++++++++++
*/
#define inputCLKEncoder 19
#define inputDTEncoder 18
#define inputSWEncoder 17
float rotatedCounterE = 0.4; // at beginning, between 0.4 and 1.4
uint16_t rotatedCountert = 0; // at beginning, between 0 and 999
uint8_t rotatedCounters = 3; // between 1 and 4
uint8_t currentStateCLK;
uint8_t previousStateCLK;
String encdir = ""; //löschbar
uint8_t pressedCounter[] = {9,25,54,115}; //y-Coordinate to write in
uint8_t i = 0; //counter to go through pressedCounter[]
float distance;
float dose;
OneButton button(inputSWEncoder,true);
/*
+++++++++++++++++++++++++++++++++++++++
Setup
+++++++++++++++++++++++++++++++++++++++
*/
void setup() {
pinMode (inputCLKEncoder,INPUT);
pinMode (inputDTEncoder,INPUT);
button.attachClick(validateValue);
button.attachDoubleClick(goBackValue);
button.setDebounceMs(20);
Serial.begin(9600); // Serial display //löschbar
// initialize OLED display with address 0x3C for 128x64
if (!oled.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
Serial.println(F("SSD1306 allocation failed")); //löschbar
while (true);
}
delay(2000); // wait for initializing
previousStateCLK = digitalRead(inputCLKEncoder);
startDisplay();
}
/*
+++++++++++++++++++++++++++++++++++++++
Loop
+++++++++++++++++++++++++++++++++++++++
*/
void loop() {
unsigned long now=millis();
button.tick();
setValue();
}
/*
+++++++++++++++++++++++++++++++++++++++
Functions
+++++++++++++++++++++++++++++++++++++++
*/
//Function starts the display and shows the topics
void startDisplay(){
oled.clearDisplay(); // clear display
oled.setTextSize(1); // text size, minimum 1
oled.setTextColor(WHITE); // text color
oled.setRotation(3); // rotate text (270°)
oled.setCursor(0, 0); // position to display
oled.print("E ="); // text to display, line 1
oled.setCursor(27,9); // set the cursor to next position to be written in
oled.println("mW/cm2"); // line 2
oled.println("t ="); // line 3
oled.print(rotatedCountert);
oled.setCursor(27,25);
oled.println("s"); // line 4
oled.println("Shutter- position:"); // line 5 + 6
oled.println("l[ ], r[ ]"); // line 7
oled.println("m[X], n[ ]"); // line 8
oled.drawLine(0,70,64,70,WHITE); // line to seperate input and output values
oled.setCursor(0,73);
oled.println("Distance ="); // line 9
getDistance(rotatedCounterE);
oled.setCursor(27,82);
oled.println("cm"); // line 10
oled.println("Dose ="); // line 11
getDose(rotatedCounterE,rotatedCountert);
oled.setCursor(27,100);
oled.print("mJ/cm2"); // line 12
oled.setCursor(11,115);
oled.print("[START]"); //line 13
oled.setCursor(0,9);
oled.writeFillRect(0,9,25,7,WHITE);
oled.setTextColor(BLACK);
oled.print(rotatedCounterE,1);
oled.display(); // show on OLED
}
// Function to change the value in the marked line.
void setValue(){
currentStateCLK = digitalRead(inputCLKEncoder);
switch (pressedCounter[i]){
case 9:
if (currentStateCLK != previousStateCLK){
if (digitalRead(inputDTEncoder)!=currentStateCLK && rotatedCounterE < 1.4){
rotatedCounterE = rotatedCounterE+0.1;
encdir = "CW"; // Encoder rotated counterclockwise //löschbar
} else if (rotatedCounterE > 0.4 && rotatedCounterE != 1.4){
rotatedCounterE = rotatedCounterE-0.1; //
encdir = "CCW"; // Encoder rotated counterclockwise //löschbar
}
getDistance(rotatedCounterE);
displayValue(i);
oled.print(rotatedCounterE,1);
oled.display();
Serial.println(encdir); //löschbar
}
break;
case 25:
if (currentStateCLK != previousStateCLK){
if (digitalRead(inputDTEncoder)!=currentStateCLK && rotatedCountert < 999){
rotatedCountert = rotatedCountert+1;
encdir = "CW"; // Encoder rotated counterclockwise //löschbar
} else if (rotatedCountert > 1){
rotatedCountert = rotatedCountert-1; //
encdir = "CCW"; // Encoder rotated counterclockwise //löschbar
}
getDose(rotatedCounterE,rotatedCountert);
displayValue(i);
oled.print(rotatedCountert);
oled.display();
Serial.println(encdir); //löschbar
}
break;
case 54:
if (currentStateCLK != previousStateCLK){
if (digitalRead(inputDTEncoder)!=currentStateCLK && rotatedCounters < 4){ //Wert sprint von 4 auf 3?
rotatedCounters = rotatedCounters+1;
encdir = "CW"; // Encoder rotated counterclockwise //löschbar
} else if (rotatedCounters > 1){
rotatedCounters = rotatedCounters-1; //
encdir = "CCW"; // Encoder rotated counterclockwise //löschbar
}
setShutterpos(rotatedCounters);
oled.display();
Serial.println(rotatedCounters);
Serial.println(encdir); //löschbar
}
break;
//case 115:
//oled.writeFillRect(11,115,42,7,WHITE);
//oled.setTextColor(BLACK);
//oled.setCursor(11,115);
//oled.println("[Start]"); //line 14
//oled.display();
//break;
}
}
void displayValue(uint8_t i){
oled.setCursor(0,pressedCounter[i]);
oled.writeFillRect(0,pressedCounter[i],25,7,WHITE); // overwrite previous value
oled.setTextColor(BLACK);
}
void deleteValue(uint8_t i){
oled.setCursor(0,pressedCounter[i]);
oled.writeFillRect(0,pressedCounter[i],25,7,BLACK); // overwrite previous value
oled.setTextColor(WHITE);
}
// Function if the encoder gets clicked. Choosen value is logged in and you can change the value below.
void validateValue(){
if (pressedCounter[i] == 9 || pressedCounter[i] == 25){
deleteValue(i);
switch (pressedCounter[i]){
case 9:
oled.println(rotatedCounterE,1);
displayValue(i+1);
oled.println(rotatedCountert);
break;
case 25:
oled.println(rotatedCountert);
setShutterpos(rotatedCounters);
break;
}
}
if (pressedCounter[i] == 54){
validateShutterpos(rotatedCounters);
oled.writeFillRect(11,115,42,7,WHITE);
oled.setTextColor(BLACK);
oled.setCursor(11,115);
oled.println("[START]"); //line 14
}
if (pressedCounter[i] == 115){
oled.setCursor(0,pressedCounter[i]);
oled.writeFillRect(0,pressedCounter[i],64,7,BLACK);
oled.setTextColor(WHITE);
oled.print("RUNNING..."); //irridiation is running
oled.display();
delay(rotatedCountert*1000); //you have to wait until the irridiation is over
oled.writeFillRect(0,pressedCounter[i],64,7,BLACK);
oled.setCursor(17,pressedCounter[i]);
oled.writeFillRect(11,115,42,7,WHITE);
oled.setTextColor(BLACK);
oled.setCursor(11,115);
oled.print("[AGAIN]"); //you can start again or change values
}
oled.display();
if (i<3){
i++;
}
Serial.println(i);
Serial.println("forward");
}
// Function if the encoder gets double clicked. Choosen value is logged in and you can change the value above.
void goBackValue(){
switch (pressedCounter[i]){
case 25:
deleteValue(i);
oled.println(rotatedCountert);
displayValue(i-1);
oled.print(rotatedCounterE,1);
break;
case 54:
validateShutterpos(rotatedCounters);
displayValue(i-1);
oled.print(rotatedCountert);
break;
case 115:
oled.writeFillRect(0,pressedCounter[i],64,7,BLACK);
oled.setTextColor(WHITE);
oled.setCursor(11,115);
oled.println("[START]");
setShutterpos(rotatedCounters);
break;
}
oled.display();
if (i>0){
i--;
}
Serial.println(i);
Serial.println("backward");
}
// Function sets the old Shutterposition to the new Shutterposition
void setShutterpos(uint8_t rotatedCounters){
switch (rotatedCounters){
case 1:
oled.writeFillRect(11,49,8,7,WHITE);
oled.writeFillRect(47,49,8,7,BLACK);
oled.setCursor(12,49);
break;
case 2:
oled.writeFillRect(47,49,8,7,WHITE);
oled.writeFillRect(11,49,8,7,BLACK);
oled.writeFillRect(11,57,8,7,BLACK);
oled.setCursor(48,49);
break;
case 3:
oled.writeFillRect(11,57,8,7,WHITE);
oled.writeFillRect(47,49,8,7,BLACK);
oled.writeFillRect(47,57,8,7,BLACK);
oled.setCursor(12,57);
break;
case 4:
oled.writeFillRect(47,57,8,7,WHITE);
oled.writeFillRect(11,57,8,7,BLACK);
oled.setCursor(48,57);
break;
}
oled.setTextColor(BLACK);
oled.print("X");
}
// Function validates the choosen Shutterposition before the next value can be changed
void validateShutterpos(uint8_t rotatedCounters){
switch (rotatedCounters){
case 1:
oled.writeFillRect(11,49,8,7,BLACK);
oled.setCursor(12,49);
break;
case 2:
oled.writeFillRect(47,49,8,7,BLACK);
oled.setCursor(48,49);
break;
case 3:
oled.writeFillRect(11,57,8,7,BLACK);
oled.setCursor(12,57);
break;
case 4:
oled.writeFillRect(47,57,8,7,BLACK);
oled.setCursor(48,57);
break;
}
oled.setTextColor(WHITE);
oled.print("X");
}
// Function calculates the distance based on E and prints the new value
void getDistance(float rotatedCounterE){ // highest possible E = 1.4 mW/cm2, distance 0.16 cm
distance = (169.01-sqrt(pow(169.01,2)-4*5.5552*(1426.7-rotatedCounterE*1000)))/(2*5.552);
oled.writeFillRect(0,82,25,8,BLACK); // overwrite previous value on display
oled.setCursor(0,82);
oled.setTextColor(WHITE);
oled.print(distance);
}
// Function calculates the distance based on E and t and prints the new value
void getDose(float rotatedCounterE, uint16_t rotatedCountert){
dose = rotatedCounterE*rotatedCountert;
oled.writeFillRect(0,100,25,8,BLACK); // overwrite previous value on display
oled.setCursor(0,100);
oled.setTextColor(WHITE);
oled.print(dose);
}