#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define OLED_RESET -1
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
int button = 8;
int button2 = 7;
int button3 = 4;
int wheel = A0;
int scroll = A1;
int func = 0;
int counteraxes1 = 0;
int counteraxes2 = 0;
int counterarea = 0;
int counterfunc = 1;
int temppointvalue=0;
void setup() {
Serial.begin(9600);
if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
Serial.println(F("SSD1306 allocation failed"));
for(;;);
}
// for (int i : pins) {
// pinMode(i,INPUT);
// }
display.clearDisplay();
display.display();
pinMode(button,INPUT);
pinMode(button2,INPUT);
pinMode(wheel,INPUT);
pinMode(scroll,INPUT);
pinMode(button3,INPUT);
}
void axes(){
for (int i=0; i<64;i++){
int j = map(i,0,63,0,127);
display.drawPixel(63,i,SSD1306_WHITE);
display.drawPixel(j,32,SSD1306_WHITE);
}
display.display();
}
void area(int x , float m){
float a = 0;
if (x>0){
for (int i=0; i<x+1 ; i++){
if (func==1){
float y2 = m*(i+1);
//Serial.println(y2);
float y1 = m*(i);
//Serial.println(y1);
a = (y1+y2)/2+a;
}
else if (func==2){
int y2=m*pow(i+1,2);
int y1=m*pow(i,2);
a = (y1+y2)/2+a;
}
else if (func==3){
float y2 = sin(i+1);
float y1 = sin(i);
a = (y1+y2)/2+a;
}
else if (func==4){
int y2 = pow(m,i+1);
int y1 = pow(m,i);
a = (y1+y2)/2+a;
}
}
Serial.print("The area under the curve from x = 0 to x = ");
Serial.print(x);
Serial.print(" is ");
Serial.println(a);
}
else {
for (int i=x; i<0 ; i++){
if (func==1){
float y2 = m*(i-1);
//Serial.println(y2);
float y1 = m*(i);
//Serial.println(y1);
a = (y1+y2)/2+a;
}
else if (func==2){
int y2=m*pow(i-1,2);
int y1=m*pow(i,2);
a = (y1+y2)/2+a;
}
else if (func==3){
float y2 = sin(i-1);
float y1 = sin(i);
a = (y1+y2)/2+a;
}
else if (func==4){
int y2 = pow(m,i-1);
int y1 = pow(m,i);
a = (y1+y2)/2+a;
}
}
Serial.print("The area under the curve from x = ");
Serial.print(x);
Serial.print(" to x = 0 is ");
Serial.println(a);
}
}
void derivative(int x ,float m){
if (func==1){
float y2 = m*(x+1-64)+64;
//Serial.println(y2);
float y1 = m*(x-64)+64;
//Serial.println(y1);
float d = (y2-y1);
Serial.print("The derivative at x = ");
Serial.print(x);
Serial.print(" is ");
Serial.println(d);
}
else if (func==2){
int y2=m*pow(x+1,2);
int y1=m*pow(x,2);
float d = (y2-y1);
Serial.print("The derivative at x = ");
Serial.print(x);
Serial.print(" is ");
Serial.println(d);
}
else if (func==3){
float rawx2 = (x+1)/20.0;
float y2 = 32-sin(rawx2)*31;
float rawx1 = (x)/20.0;
float y1 = 32-sin(rawx1)*31;
float d = -(y2-y1)*20.0/31.0;
Serial.print("The derivative at x = ");
Serial.print(x);
Serial.print(" is ");
Serial.println(d);
}
else if (func==4){
float max_rawy = pow(m, 127.0 / 32.0);
float denominator = max_rawy - 1.0;
if (abs(denominator) < 0.0001) {
return 0.0;
}
float exponent1 = (float)(-x + 1.0) / 32.0;
float rawy1 = pow(m, exponent1);
float y1 = 63.0 - ((rawy1 - 1.0) * 63.0 / (max_rawy - 1.0));
float exponent2 = (float)(-x) / 32.0;
float rawy2 = pow(m, exponent2);
float y2 = 63.0 - ((rawy2 - 1.0) * 63.0 / (max_rawy - 1.0));
float d = y2-y1;
Serial.print("The derivative at x = ");
Serial.print(x);
Serial.print(" is ");
Serial.println(d, 4);
}
}
void linear(float m){
display.clearDisplay();
for (int x=0; x<128; x++){
int rawy = m*(x-64)+64;
int y = map(rawy,0,127,63,0);
display.drawPixel(x,y,SSD1306_WHITE);
}
func = 1;
display.display();
}
void quadratic(float m){
display.clearDisplay();
for (int x=-64;x<65;x++){
int rawy=m*pow(x,2);
int y = map(rawy,0,4096,32,0);
display.drawPixel(x+64,y,SSD1306_WHITE);
}
func=2;
display.display();
}
void sine(float m) {
display.clearDisplay();
for (int x=-128;x<65;x++){
float rawx = x/20.0;
float rawy=sin(rawx);
int y = 32-rawy*31;
display.drawPixel(x+64+m,y,SSD1306_WHITE);
}
func=3;
display.display();
}
void exponential(float m) {
display.clearDisplay();
for (int x = 0; x < 128; x++) {
float exponent = (float)x / 32.0;
float rawy = pow(m, exponent);
float max_rawy = pow(m, 127.0 / 32.0);
int y = 63 - (int)((rawy - 1.0) * 63.0 / (max_rawy - 1.0));
if (y >= 0 && y < 64) {
display.drawPixel(x, y-32, SSD1306_WHITE);
}
}
func = 4;
display.display();
}
void loop() {
int funcchange = digitalRead(button);
int axestoggle = digitalRead(button2);
int wheelvalue = analogRead(wheel);
int pointvalue = analogRead(scroll);
int areavalue = digitalRead(button3);
//Serial.println(wheelvalue/1023.0);
//Serial.println(wheelvalue);
//Serial.println(wheelvalue/102);
if (funcchange==HIGH){
if (counterfunc==1){
Serial.println("drawing linear graph");
linear(wheelvalue/1023.0);
counterfunc++;
}
else if (counterfunc==2){
Serial.println("drawing quadratic graph");
quadratic(wheelvalue/1023.0*4.0);
counterfunc++;
}
else if (counterfunc==3){
Serial.println("drawing sine graph");
sine(wheelvalue/1023.0*63);
counterfunc++;
}
else if (counterfunc==4){
Serial.println("drawing exponential graph");
exponential(wheelvalue/51+1);
counterfunc=1;
}
}
// if (pointvalue!=temppointvalue){
// derivative(pointvalue/1023.0*128 - 64.0 ,wheelvalue/1023.0);
// }
if (func==1){
linear(wheelvalue/1023.0);
if (counteraxes1==1){
axes();
}
}
else if (func==2){
quadratic(wheelvalue/1023.0*4.0);
if (counteraxes1==1){
axes();
}
}
else if (func==3){
sine(wheelvalue/1023.0*63);
if (counteraxes1==1){
axes();
}
}
else if (func==4){
exponential(wheelvalue/51+1);
if (counteraxes1==1){
axes();
}
}
//Area & Derivative
if (areavalue==HIGH){
//Serial.println("Working");
if (counterarea == 0){
area(pointvalue/1023.0*128 - 64.0 ,wheelvalue/1023.0);
derivative(pointvalue/1023.0*128 - 64.0 ,wheelvalue/1023.0);
counterarea=1;
}
}
else{
counterarea=0;
}
//Axis toggling
if (axestoggle==HIGH){
if (counteraxes1==0 && counteraxes2==0){
counteraxes2=1;
counteraxes1=1;
Serial.println("drawing axes");
// Serial.print(counteraxes1);
// Serial.println(counteraxes2);
}
else if (counteraxes1==1 && counteraxes2==0){
Serial.println("removing axes");
counteraxes1=0;
counteraxes2=1;
display.clearDisplay();
// Serial.print(counteraxes1);
// Serial.println(counteraxes2);
}
}
else{
counteraxes2=0;
if (counteraxes1==1){
axes();
}
}
delay(10);
temppointvalue = pointvalue;
}