/**************************************************************************
**************************************************************************/
#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define LOAD_BUTTON true
#if LOAD_BUTTON==true
#include "OneButton.h"
#endif
///////////
//BUTTONS
const int TIME_PIN = 27;
//const int TIME_PIN = 13;
const int tonepin = 12;
OneButton time_button(TIME_PIN, true);
/////////
//Screen
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels
// Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)
#define OLED_RESET -1 // Reset pin # (or -1 if sharing Arduino reset pin)
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
////////////
//storage
#define STORAGE_SIZE 126 //126 // more than 60 causes issues with arduino UNO (120 OK for ESP) IDEAL WOULD BE 126 for tick every 0.5 seconds!
float storage[STORAGE_SIZE];
int ticks;
//////////////
//STopwatch
long startTime ; // start time for stop watch
long elapsedTime = 0; // elapsed time for stop watch
int seconds1 = elapsedTime / 1000L;;
int subseconds1 = (elapsedTime-(seconds1*1000))/100;
bool stopwatch = false;
////
//TODO: WAAGE!
long int iter;
void setup() {
Serial.begin(9600);
setup_display();
time_button.attachClick(singleclick);
time_button.attachLongPressStart(longclick);
}
void loop() {
time_button.tick();
iter ++;
display.clearDisplay();
display.setTextSize(2); // Draw 2X-scale text
display.setTextColor(WHITE);
draw_seperator_line();
////STOPWATCH-MODE////////////////////////////////////////////////
if (stopwatch == true) {
run_stopwatch();
//STORE DATA
if ((subseconds1+1) % 5 == 0){ticks++;} // in total: 126(+) ticks for whole duration!
storage[ticks] = random(1,100); //TODO: ADD CURRENT WEIGHT!
if (seconds1 > 30){
end_stopwatch();
}
} //END STOPWATCH-MODE
else {
////NOT-Stopwatch MODE
display_time();
}
display_weight(iter*1.1);
display.display(); //needs to happen at the end
}
///////////
///////////
//FUNCTIONS
////
//DISPLAY
void setup_display(){
// SSD1306_SWITCHCAPVCC = generate display voltage from 3.3V internally
if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // Address 0x3D for 128x64 /////beim ESP: 0x3C, bei Arduino UNO: 0x3D)) {
Serial.println(F("SSD1306 allocation failed"));
for(;;); // Don't proceed, loop forever
}
display.display();
}
void display_weight(float current_weight){
display.setCursor(60, 44);
display.println(current_weight,1);
}
void display_time(){
display.setCursor(10, 5); //zeile:1 (erste) spalte: 6
if (seconds1<10){display.print("0");} //print leading 0 for seconds
display.print(seconds1);
display.print(".");
display.print(subseconds1);
}
void draw_seperator_line(){
display.drawLine(0,63,126,0,WHITE); //128*64
display.drawLine(0,64,128,0,WHITE); //128*64
display.drawLine(0,65,130,0,WHITE); //128*64
}
///////
///BUTTONS
void singleclick() {
Serial.println("Single Cick");
if (stopwatch == false){ //to start stopwatch
prep_stopwatch(); //Start Stopwatch --> DONE via bool!
//TODO: TARE
} else { stopwatch = false;} //if already running: Stop the stoppwatch and leave time!
} // singleclick
void longclick() {
Serial.println("LONG Cick");
//plot data
plot_data();
delay(10000);
} //doubleclick
////////
//STOPWATCH
void prep_stopwatch() {
Serial.println("prep stopwatch");
//display.clearDisplay();
display.setCursor(10, 5);
for (int i = 0; i < 8; i++) {
uint16_t temp_x = SCREEN_WIDTH/8;
display.fillRect(i*temp_x, 0, temp_x, SCREEN_HEIGHT, WHITE);
delay(250);
display.display();
}
stopwatch = true; // set for stopwatch mode
// set parameters to ZERO
startTime = millis();
elapsedTime = 0;
seconds1=0;
subseconds1=0;
}
//run stopwatch routine
void run_stopwatch(){
//get elapsed time
elapsedTime = millis() - startTime;
seconds1 = elapsedTime / 1000L;
subseconds1 = (elapsedTime-(seconds1*1000))/100;
display_time();
//piepen
if (seconds1 == 25 and subseconds1 <2){ //beep
tone(tonepin, 147);
} else if (seconds1 == 28 and subseconds1 <4){ //double beep
tone(tonepin, 147,200);
delay(200);
tone(tonepin, 147,200);
} else if (seconds1 == 30 and subseconds1 <2){ //double beep
tone(tonepin, 90,200);
} else {
noTone(tonepin);
}
}
//end stopwatch-routine
void end_stopwatch() {
stopwatch = false;
display.clearDisplay();
}
///////////////////
//////FOR PLOTTING
int getIndexOfMaximumValue(float* array, int size){
int maxIndex = 0;
int max = array[maxIndex];
for (int i=1; i<size; i++){
if (max<array[i]){
max = array[i];
maxIndex = i;
}
}
return maxIndex;
}
int map_floattoint(float x, float in_min, float in_max, int out_min, int out_max)
{
return int((x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min);
}
void plot_data(){
display.clearDisplay();
//plots the storage-array based on storage-size (storage-size should not be longer then screen-width!)
for (int i = 0; i <= STORAGE_SIZE; i++){
//get maximum value of storage-array
float maxdata = storage[getIndexOfMaximumValue(storage, STORAGE_SIZE)];
int x = i;
//int y = SCREEN_HEIGHT-int(storage[i]); //without adjusting to maximal screen-scale
int y = map_floattoint(storage[i], 0.0, maxdata, SCREEN_HEIGHT, 0); //map so that it fits to screen
Serial.print(storage[i]);
Serial.print(" - ");
Serial.println(y);
display.drawPixel( x, y, WHITE);
}
display.display();
}