Electric Skateboard

Six months is the time it took me to finish up this skateboard. This must be the most complex project I built so far as I was exposed to mechanics, electricity, programming, CNC manufactures, protocols I never studied before (NMEA) and even engraving.
It all started since I needed some mobility that is small enough and light enough to carry with me when I go to work.
Since everyone already the traditional electric scooter or bicycle I wanted to build something more extreme, Skateboard was it.
I decided that if I'm going to do this project it is going to be the most Hi-tech electric skateboard there is and to include any sensor that might be useful.

As a platform, I use surprisingly, an old malfunctioned electric skateboard, obviously I wouldn't use any of the pre-exist electronics so the first step I took was to tear the skateboard apart and start to renew the whole thing.

The Skateboard just before I tear it apart.
The original batteries I no longer needed.
The battery tray.
The back of the skateboard before disassembling it.
The original motor is no longer needed.
The origial ESC.
The board needed to be renewed.
The original ESC was digged out.
I did try to sell this motor, no luck.
Renewing the board.
Taking off the original grip.
Scratching that paint.
Upper side ready to stark work on.
Bottom side need some paint
After paint.
Painting in red the ESC box.

One of the biggest challenge was to design and manufacture the motor mount.
I knew I need to take a few steps back and re-think about the design so I started to design each part in Solidworks only to make sure this motor mount will fit neatly.

Motor mount.
Wheel base with the motor mount.
Full Solidworks assembly.

I was really worried about the motor mount since I wanted it to be from aluminium and I needed it to be precise since I only had one strap to connect the motor to the wheel it needed to be exactly at the right distance.
I designed the motor mount using Solid Works and send it to manufacturer to laser cut it in 4mm aluminium, I took two pieces of these.

Motor - 270KV 3000 Watt.
From CAD software to real product.

At this point it finally started to take shape because at this point I starter to think of the right way to organize all the components at the bottom in a way everything will be hidden and protected behind the bottom cover.
I wanted that all wiring will be hidden so cut a black sheet of foam which only a the few cables that were exposed will go under that foam.
After deciding were each component will be I started to drill holes for all the screws. I needed a place for the ESC, screws to hold the batteries, hole for the pressure sensor wires and even engrave a special lace to hold the GPS.
The two pieces of the motor mount were attached with one bolt between them to strengthen the mount and make it less flexible. To place the pulley of the motor right infront of the wheel pulley, I placed it on four spacers.

First plan to organize everything.
From CAD software to real product.

Since this is not a regular electric skateboard, the electricity design needed extra careful.
In what was the ESC box I planned to put all the electronics, that is a very small area!!
There are two main PCB inside, one is for the micro controller and the other is a distribution board to keep everything orginized.
In addition to these two boards in this box there is also the RC receiver and a Relay switch.
To make myself visible at night, there is a red break light and white bright LED at the front.

It tool more than one try to solder the proper board.
From CAD software to real product.

To make it real Hi-tech, I use almost any sensor I could think of. the sensors I used are:
  • Current and Voltage sensor
  • RGB LED indicator that I use to alert low battery or any other use
  • OLED Display to see all data like speed, cruse, limit, lights and more
  • GPS to determine speed, direction and display clock
  • Pressure sensor to sense if I am still on the skateboard and other aplications
  • Buzzer to buzz on low voltage
  • Relay switch to control lights
  • RC Receiver to control throttle with the remote
  • Teensy 3.1 as a micro controller, this was the only one strong enough to hold all the sensors

  • Wireing schema for all the sensors.
    Testing the GPS.
    The current and voltage sensor.
    OLED display.
    Pressure sensor.
    The GPS, LED and OLED display.
    Everything connected.

    The real fun was the program, having all these sensors allow me to do almost any thing with it!
    I program a menu that I can navigate using the wheel and button that on the remote control.
    Each menu item is displayed on the OLED screen.
    These are the menu items:
  • BUZZER - empty screen
  • Lights ON/OFF
  • BATTERY - Voltage
  • CURRENT - Amp
  • POWER - Watt
  • MAXIMUMS - Max Amp, Watt and Speed
  • GPS - Speed ,direction and satellite in view
  • Time and Date
  • Cruz control
  • Force sensor ON/OFF - use for safety - it will stop the skateboard when I am not on it
  • Speed limit ON/OFF
  • Change the curve value
  • Add/Remove Debugging screen
  • Debugging Screen


  • I have used a several libraries in the software:
  • Servo.h
  • TinyGPS++.h
  • SPI.h
  • Wire.h
  • Adafruit_GFX.h
  • Adafruit_SSD1306.h

  • I tried to keep the code readable as possible with lots and lots of comments:
    				#include 
    				#include 
    				#include 
    				#include 
    				#include 
    				#include 
    				//*********************************RC Variables Setup***************************************
    				Servo ThrottleServo;
    
    				int ThrottleOutPin = 5; //Goes to ESC
    				int ThrottleInPin = 7; // connect RC receiver here CH2 - throttle.
    				int ThrottleValue;     // The value goes pulseIn and then mapped to set the servo PWM
    				int smoothedThrottleValue = 0;    // smoothed result of the Throttle - This is what the servo will get
    				int samples = 4;    // amount of samples for smoothing
    
    				int WheelInPin = 8; // connect RC receiver here CH1 - throttle.
    				int WheelValue;
    
    				int ButtonInPin = 6; // connect RC receiver here CH3 - throttle.
    				int ButtonValue;
    				//******************************************************************************************
    
    				//************************************Menu Variables****************************************
    				int ScreenNumber = 0; //the position of the LCD (switch case menu)
    				int AmountOfScreens = 10; //how many screens there will be
    				//******************************************************************************************
    
    				//***************************************LED Variables**************************************    
    				int redp = 23;
    				int greenp = 22;
    				int bluep = 21;
    				//******************************************************************************************
    
    				//***************************************Buzzer PIN*****************************************
    				int buzzer = 4;
    				//******************************************************************************************
    
    				//***************************************Lights PINS to the Relay***************************
    				int breakLightPin = 12; //Break lights pin
    				int frontLightPin = 11; //Front lights pin
    				boolean lightsOn = false; //to check the light state
    				//******************************************************************************************
    
    				//***************************************Current & Voltage Sensor***************************
    				int voltPin = A0;
    				int ampPin = A1;
    				float Volt; //Analog 0 - Volt before conversion - Volt = Volt/12.99; //180 Amp board calculation
    				float Amp; //Analog 1 - Amp before conversion - Amp = Amp/3.7; //180 Amp board calculation
    				float maxAmp = 0; //Save the maximum Ampere 
    				float Watt; //Calculation of Volt*Amp
    				float maxWatt; //Save the maximum Watt 
    				float minVolt = 3.4*8; //27.2 volts - calculation of 3.4 for cell
    
    				//These vars will be stored as strings and hold the Volt and Amp data to display them in the OLED
    				char VoltChar[5];
    				char AmpChar[5];
    				char maxAmpChar[5];
    				//********************************************************************************************
    
    				//***************************************Force Sensor*****************************************
    				int forcePin = A2;
    				int forceValue;  //Call to - forceValue = analogRead(forcePin);
    				boolean forceOn = false;
    				//*********************************************************************************************
    
    				//***************************************GPS Variables*****************************************
    				TinyGPSPlus gps; // The TinyGPS++ object
    				int maxSpeed = 0; //Store the maximum GPS speed
    				static const uint32_t GPSBaud = 9600; //Baud rate
    				//*********************************************************************************************
    
    				//***************************************OLED Variables****************************************
    				Adafruit_SSD1306 display(4); //attach the OLED
    				boolean printed = false; //Print only once when on the menu
    				//*********************************************************************************************
    
    				//***************************************Speed limit Variables*********************************
    				int speedLimit = 1700;  //Speed limit is limitation to the smoothedThrottleValue in microseconds
    				boolean speedLimitOn = false; //ON/OFF the speed limit
    				//*********************************************************************************************
    
    				//***************************************Force Control Variables*********************************
    				const int buttonPin = 2;     // the number of the pushbutton pin
    				const int ledPin =  20;  // red LED on the panel
    				boolean forceControl = false; //ON/OFF the force control
    				int button_delay = 0; //Long press short press detection
    				//*********************************************************************************************
    
    				//***************************************Cruz Control Variables*********************************
    				boolean cruzOn = false; //ON/OFF the Cruz control
    				int cruzValue; //to overwrite throttle value 
    				//*********************************************************************************************
    
    				//***************************************Curve*************************************************
    				float curve = 0;
    				//*********************************************************************************************
    
    
    				//boolean remoteOff = true; // Optional - require to press ch3 to start the program
    
    				void setup(){
    				  /*while(remoteOff){ // Optional - require to press ch3 to start the program
    					if (pulseIn(ButtonInPin, HIGH, 20000) > 1800){
    						remoteOff = false;
    					}
    					Serial.println("Your remote is OFF");
    				  }*/
    
    				  Serial.begin(9600); //For Debugging and/or GPS
    				  ThrottleServo.attach(ThrottleOutPin);  // attaches the servo on pin ThrottleOutPin to the servo object
    				  
    				  pinMode(redp, OUTPUT);   //RGB LED setup
    				  pinMode(greenp, OUTPUT);
    				  pinMode(bluep, OUTPUT);
    				  
    				  pinMode(ThrottleInPin, INPUT);  //RC Receiver inputs 
    				  pinMode(WheelInPin, INPUT);
    				  pinMode(ButtonInPin, INPUT);
    				  
    				  pinMode(buzzer, OUTPUT); // set a pin for buzzer output
    				  
    				  pinMode(breakLightPin, OUTPUT); // set the relay lights pins
    				  pinMode(frontLightPin, OUTPUT);
    				  
    				  pinMode(ledPin, OUTPUT);      //Force Control initialize - Panel
    				  pinMode(buttonPin, INPUT);  
    				  
    				  Serial1.begin(GPSBaud);//Start the Serial with the GPS Baud
    				  /*//Initial the GPS in case it's battery is dead
    				  Serial.write("$PMTK220,300*2D\r\n");//updates every 300 milliseconds
    				  Serial.write("$PMTK314,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0*28\r\n");//Send the GGA and RMC sentences
    				  Serial.write("$PMTK251,9600*17\r\n");//Set lower baud rate
    				  Serial.begin(9600);//Begin new baud rate*/
    				  
    				  setColor(0,0,255);//Just blink the Green LED for two seconds
    				  
    				  display.begin(SSD1306_SWITCHCAPVCC, 0x3C);  // initialize with the I2C addr 0x3D (for the 128x64)
    				  display.setTextColor(WHITE);//Set the color to white 
    				  //Say Hi to myself :)
    				  display.clearDisplay(); 
    				  display.setTextSize(2);
    				  display.setCursor(0,0);
    				  display.println("Hello");
    				  display.setTextSize(5);
    				  display.println("Roy");
    				  display.display(); 
    				  delay(3000);
    				  
    				  setColor(0,0,0); //turn the LED off
    				}
    
    				void loop(){
    
    				  if(!forceControl){// use the remote if force control is off
    					ThrottleValue = pulseIn(ThrottleInPin, HIGH, 20000); //read throttle value	
    				  }else{ //use the force sensor if force control is off
    					while(analogRead(forcePin)>850){
    						if(ThrottleValue>speedLimit)
    							ThrottleValue = speedLimit;
    						ThrottleServo.writeMicroseconds(ThrottleValue);
    						ThrottleValue++;
    						delay(60);
    					}
    					ThrottleValue=1530 ;
    				 }
    				 smoothedThrottleValue = smoothedThrottleValue + ((ThrottleValue - smoothedThrottleValue)/samples); //Smooth calculation of the value
    				 
    				 if (smoothedThrottleValue >= 1500 && curve != 0){//Curve the throttle value
    					smoothedThrottleValue = fscale( 1500, 2000, 1500, 2000, smoothedThrottleValue, curve);
    				 }
    				 
    				  if (cruzOn){//set to throttle the Cruz value if Cruz Control is on
    					if (smoothedThrottleValue<=cruzValue){smoothedThrottleValue=cruzValue;}//change smoothedThrottleValue to the Cruz value
    					else{cruzOn = false; printed = false; cruzValue = 0;}//turn OFF the cruz vontrol if throttle exceed the cruz value
    				  }
    				  
    				  if(speedLimitOn){  //Check if Speed limit is on and change smoothedThrottleValue accordingly
    					if(smoothedThrottleValue>=speedLimit){smoothedThrottleValue = speedLimit;}//check if throttle exceed the limit value
    				  }
    				   
    				  if(forceOn){ //Check if force is activated and write to throttle
    					forceValue = analogRead(forcePin);// Read the force sensor
    					if(forceValue>100){ //Check for force
    						ThrottleServo.writeMicroseconds(smoothedThrottleValue); // Write to Throttle if there is force
    					}else{ThrottleServo.writeMicroseconds(1000);}  //In case there is no force, stop the skateboard
    				  }
    				  else{ThrottleServo.writeMicroseconds(smoothedThrottleValue);} //Write to Throttle if force is OFF
    				  
    				  if(lightsOn && smoothedThrottleValue < 1400){digitalWrite(breakLightPin, HIGH);}//Turn ON the Break Lights
    				  else if(lightsOn){digitalWrite(breakLightPin, LOW);} //Turn OFF the Break Lights
    				  
    				  if (digitalRead(buttonPin) == HIGH) { //toggle the forceControl option or change screens through button
    					button_delay = 0; // Reset the 'timer' to detect long or short press
    					while(digitalRead(buttonPin) == HIGH){//start counting the time
    						button_delay++;
    						delay(1);
    					}
    					if(button_delay <= 500){ //on short press increase the screen #
    						ScreenNumber++;
    						ScreenNumber=((ScreenNumber % AmountOfScreens) + AmountOfScreens) % AmountOfScreens;  //Always positive Modulo
    						printed = false;//Print to the OLED on screen change
    					}else{ //On long press toggle the forceControl option
    						if(forceControl==false){//turn ON the forceControl
    							forceControl = true;
    							digitalWrite(ledPin, HIGH);
    							forceOn = false;
    						}
    						else{ //turn OFF the forceControl
    							forceControl = false;
    							digitalWrite(ledPin, LOW);
    							forceOn = true; //Turn off the force on limitation
    						}
    					}
    				  }
    				  
    				  //Measure the current and voltage
    				  Volt = analogRead(voltPin);
    				  Amp = analogRead(ampPin);
    				  //Convert the voltage and the amp
    				  Volt = Volt/19.3;//12.99 for 5V; //180 Amp board 
    				  Amp = Amp/5.7;//3.7 for 5V; //180 Amp board
    				  if(Volt<=minVolt){setColor(255,0,0);buzz(buzzer, 2500 , 50);ScreenNumber = 2;printed = false;}//Low voltage warning with RED LED, BUZZ and set to display voltage
    				  else{setColor(0,255,0);}//Green LED if BATT is OK
    				  if(Amp>maxAmp){maxAmp = Amp; maxWatt = Volt*maxAmp;} //Save the Maximum Ampere and Watt
    				  
    				  //Read from GPS
    				  while (Serial1.available() > 0)
    					gps.encode(Serial1.read());
    				  if(gps.speed.kmph()>maxSpeed){maxSpeed = gps.speed.kmph();} //Save the Maximum Speed
    
    				  ButtonValue = pulseIn(ButtonInPin, HIGH, 20000); //Listen to the Button value
    				  WheelValue = pulseIn(WheelInPin, HIGH, 20000); // Listening to the Wheel value and setting what need to be displayed
    				  
    				  if (WheelValue > 1800){  //increase the ScreenNumber Value for the menu
    					ScreenNumber++;
    					ScreenNumber=((ScreenNumber % AmountOfScreens) + AmountOfScreens) % AmountOfScreens;  //Always positive Modulo
    					printed = false;//Print to the OLED on screen change
    					delay(300);
    				  }else if(WheelValue <1200){  //decrease the ScreenNumber Value
    					ScreenNumber--;
    					ScreenNumber=((ScreenNumber % AmountOfScreens) + AmountOfScreens) % AmountOfScreens; //Always positive Modulo
    					printed = false;//Print to the OLED on screen change
    					delay(300); 
    				  }
    				  
    				  //Print the screen # for debugging 
    				  Serial.print("screen # :");
    				  Serial.println(ScreenNumber);
    				  
    				  /*Menu items:
    					0 - BUZZER   - empty screen
    					1 - ON/OFF   - Lights
    					2 - BATTERY  - Voltage
    					3 - CURRENT  - Amp
    					4 - POWER    - Watt
    					5 - MAXIMUMS - Max Amp, Watt and Speed
    					6 - GPS      - Speed , direction and satellite in view - Alway update screen 
    					7 - Time and Date - Alway update screen
    					8- Cruz control
    					9- settings
    						0 - ON/OFF   - Force sensor
    						1 - ON/OFF   - Speed limit
    						2 - Change the curve value
    						3 - Add / remove Debugging screen (10)
    						4 - Exit
    					10- Debugging Screen
    				  */
    				  
    				  switch (ScreenNumber) { //Select the screen to display
    					case 0: //BUZZER - empty screen
    						//Print to the OLED blank screen
    						if(!printed){//Print only once if status wasn't changed
    							display.clearDisplay(); // Clear the buffer.
    							display.display();  //Display whatever in the buffer
    							printed = true;
    						}
    						if (ButtonValue > 1800){  //Buzz when pressed 
    							buzz(buzzer, 2500 , 100); // buzz the buzzer on pin 'buzzer' at 500Hz for 150 milliseconds
    						}
    					  break;
    					case 1:  // ON/OFF the lights
    						if(!printed){  //Print only once if status wasn't changed
    							display.clearDisplay(); 
    							display.setTextSize(2);
    							display.setCursor(0,0);
    							display.println("LIGHTS:");
    							display.setTextSize(4);
    							if(lightsOn){display.println("ON");}
    							else{display.println("OFF");}
    							display.display();  
    							printed = true;
    						}
    						if (ButtonValue > 1800){  //Change the 'lightsOn' variable alternately
    							if(lightsOn){
    								lightsOn = false;
    								digitalWrite(frontLightPin, LOW); //Turn the Front lights OFF
    								digitalWrite(breakLightPin, LOW); //Turn the Break lights OFF
    							}else{
    								lightsOn = true;
    								digitalWrite(frontLightPin, HIGH);  //Turn the Front lights ON
    							}
    							printed = false; //It will print to the changes to the display in the next round
    							delay(300);
    						}
    						break;
    					case 2:  // BATTERY - Voltage
    						if(!printed){//Print only once if status wasn't changed
    							display.clearDisplay();
    							display.setTextSize(2);
    							display.setCursor(0,0);
    							display.println("BATTERY:");
    							display.setTextSize(3);
    							display.println(dtostrf(Volt,5, 2, VoltChar));
    							display.setTextSize(2);
    							display.println("Volts");
    							display.display();
    							printed = true;
    						}
    						if (ButtonValue > 1800){  //Click the button to refresh the screen
    							printed = false; //It will print to the changes to the display in the next round
    						}
    						break;
    					case 3:  // CURRENT - Amp
    						if(!printed){//Print only once if status wasn't changed
    							display.clearDisplay();
    							display.setTextSize(2);
    							display.setCursor(0,0);
    							display.println("CURRENT:");
    							display.setTextSize(3);
    							display.println(dtostrf(Amp,5, 2, AmpChar));
    							display.setTextSize(2);
    							display.println("Amp");
    							display.display();
    							printed = true;
    						}
    						if (ButtonValue > 1800){  //Click the button to refresh the screen
    							printed = false; //It will print to the changes to the display in the next round
    						}
    						break;
    					case 4:  // POWER - WATT
    						if(!printed){//Print only once if status wasn't changed
    							display.clearDisplay();
    							display.setTextSize(2);
    							display.setCursor(0,0);
    							display.println("POWER:");
    							display.setTextSize(3);
    							display.println((int)(Volt*Amp));
    							display.setTextSize(2);
    							display.println("WATT");
    							display.display();
    							printed = true;
    						}
    						if (ButtonValue > 1800){  //Click the button to refresh the screen
    							printed = false; //It will print to the changes to the display in the next round
    						}
    						break;
    					case 5:  // Max Amp and Watt
    						if(!printed){//Print only once if 'printed' status wasn't changed
    							display.clearDisplay();
    							display.setTextSize(2);
    							display.setCursor(0,0);
    							display.println("Maximums:");
    							display.print(dtostrf(maxAmp,5, 2, maxAmpChar));
    							display.println(" A");
    							display.print((int)maxWatt);//it crash the program
    							display.println(" W");
    							display.print(maxSpeed);//it crash the program
    							display.println(" km/h");
    							display.display();
    							printed = true;
    						}
    						if (ButtonValue > 1800){  //Click the button to refresh the screen
    							printed = false; //It will print to the changes to the display in the next round
    						}
    						break;
    					case 6: // GPS Speed information
    						if(!printed){//Print only once if status wasn't changed
    							display.clearDisplay();
    							display.setTextSize(2);
    							display.setCursor(0,0);
    							display.print("GPS: ");
    							display.setTextSize(1);
    							display.print("in view:");
    							display.println(gps.satellites.value());
    							display.setCursor(0,20);
    							display.setTextSize(4);
    							display.print((int)gps.speed.kmph()); //Speed in KMH
    							display.setTextSize(1);
    							display.println("KM/H");
    							display.setCursor(85,43);
    							display.setTextSize(2);
    							display.println(TinyGPSPlus::cardinal(gps.course.value())); 
    							display.display();
    							//printed = true;
    						}
    						if (ButtonValue > 1800){  //Click the button to refresh the screen
    							printed = false; //It will print to the changes to the display in the next round
    						}
    						break;
    					case 7: // Show Time and Date
    						if(!printed){//Print only once if status wasn't changed
    							display.clearDisplay();
    							display.setTextSize(2);
    							display.setCursor(0,0);
    							display.println("CLOCK:");
    								display.print(gps.date.day());
    								display.print(F("/"));
    								display.print(gps.date.month());
    								display.print(F("/"));
    								display.print(gps.date.year());
    								display.println();
    								 
    								if (gps.time.hour() < 10) display.print(F("0"));
    								display.print(gps.time.hour()+2);//IL time
    								display.print(F(":"));
    								if (gps.time.minute() < 10) display.print(F("0"));
    								display.print(gps.time.minute());
    								display.print(F(":"));
    								if (gps.time.second() < 10) display.print(F("0"));
    								display.print(gps.time.second());
    								display.println();
    								
    							display.display();
    							//printed = true;
    						}	
    						if (ButtonValue > 1800){  //Click the button to refresh the screen
    							printed = false; //It will print to the changes to the display in the next round
    						}
    						break;
    					case 8: // Cruz control
    						if(!printed){//Print only once if status wasn't changed
    							display.clearDisplay();
    							display.setTextSize(2);
    							display.setCursor(0,0);
    							display.println("CRUZ:");
    							display.setTextSize(4);				
    							if(cruzOn){
    								display.print(map(cruzValue, 1500, 2000, 0, 100)); // mapping the speedlimit to percent
    								display.println("%"); 
    							}
    							else{display.println("OFF");}
    							display.display();
    							printed = true;
    						}	
    						if (ButtonValue > 1800){  //Click the button to refresh the screen
    							cruzOn = true;
    							cruzValue = smoothedThrottleValue; //save the throttle value as the cruz value
    							printed = false; //It will print to the changes to the display in the next round
    							delay(500);
    						}
    						break;
    					case 9: // Settings
    						if(!printed){//Print only once if status wasn't changed
    							display.clearDisplay();
    							display.setTextSize(2);
    							display.setCursor(0,0);
    							display.println("Settings:");
    							display.setTextSize(1);
    							display.println("ON/OFF Force sensor");
    							display.println("ON/OFF Speed limit");
    							display.println("Curve Value");
    							display.println("Debug Mode");	
    							display.display();
    							printed = false;
    						}
    						if (ButtonValue > 1800){  //get inside the menu
    								delay(300); //to give some time until I'll stop press the button
    								int settingsMenu = 0;
    								int AmountOfSettings = 5;
    								boolean exit = false;
    								while(!exit){  
    									  ButtonValue = pulseIn(ButtonInPin, HIGH, 20000); //Listen to the Button value
    									  WheelValue = pulseIn(WheelInPin, HIGH, 20000); // Listening to the Wheel value and setting what need to be displayed
    				 
    									  if (WheelValue > 1800){  //increase the ScreenNumber Value for the menu
    										settingsMenu++;
    										settingsMenu=((settingsMenu % AmountOfSettings) + AmountOfSettings) % AmountOfSettings;  //Always positive Modulo
    										printed = false;//Print to the OLED on screen change
    										delay(300);
    									  }else if(WheelValue <1200){  //decrease the settingsMenu Value
    										settingsMenu--;
    										settingsMenu=((settingsMenu % AmountOfSettings) + AmountOfSettings) % AmountOfSettings; //Always positive Modulo
    										printed = false;//Print to the OLED on screen change
    										delay(300); 
    									  }
    									  
    									  switch (settingsMenu) { //Select the screen to display
    										case 0: //ON/OFF Force sensor
    											if(!printed){//Print only once if status wasn't changed
    												display.clearDisplay();
    												display.setTextSize(2);
    												display.setCursor(0,0);
    												display.println("FORCE:");
    												display.setTextSize(4);
    												if(forceOn){display.println("ON");}
    												else{display.println("OFF");}
    												display.display();
    												printed = true;
    											}
    											if (ButtonValue > 1800){  //Change the 'forceOn' variable alternately
    												if(forceOn){
    													forceOn = false;
    												}else{
    													forceOn = true;
    												}
    												printed = false; //It will print to the changes to the display in the next round
    												delay(300);
    											}
    										  break;
    										case 1: // ON/OFF the Speed Limit
    											if(!printed){//Print only once if status wasn't changed
    												display.clearDisplay();
    												display.setTextSize(2);
    												display.setCursor(0,0);
    												display.println("LIMIT:");
    												display.setTextSize(4);
    												if(speedLimitOn){
    													display.println("ON");
    													display.setTextSize(1);
    													display.print(map(speedLimit, 1500, 2000, 0, 100)); // mapping the speedlimit to percent
    													display.println("%");
    													}
    												else{display.println("OFF");}
    												display.display();
    												printed = true;
    											}
    											if (ButtonValue > 1800){  //Change the 'speedLimitOn' variable alternately
    												if(speedLimitOn){ //Turn OFF the speed limit
    													speedLimitOn = false;
    												}else{ //If it's OFF then Set the speed limit value first and then turn it ON
    													delay(300); //to give some time until I'll stop press the button
    													//setting the speed limit value
    													while(pulseIn(ButtonInPin, HIGH, 20000) < 1800){  //Need to press CH3 to set the value and exit this loop
    														WheelValue = pulseIn(WheelInPin, HIGH, 20000);//Read the Wheel to increase or decrease the Speedlimit value
    														  if (WheelValue > 1800){  //increase the speedLimit Value
    															speedLimit-=5;
    															if(speedLimit<1500){speedLimit=2000;} //limit the lower boundary to 1500
    														  }else if(WheelValue <1200){  //decrease the speedLimit Value
    															speedLimit+=5;
    															if(speedLimit>2000){speedLimit=1500;}
    														  }
    														//Display the changes to the speedLimit value
    														display.clearDisplay();
    														display.setTextSize(2);
    														display.setCursor(0,0);
    														display.println("LIMIT:");
    														display.setTextSize(1);
    														display.println("Use the wheel");
    														display.setTextSize(4);
    														display.print(map(speedLimit, 1500, 2000, 0, 100)); // mapping the speedlimit to percent
    														display.println("%"); 
    														display.setTextSize(1);
    														display.println("Press CH3 to set");
    														display.display();				
    													}
    													speedLimitOn = true; //Turn the speed limit on after setting the value
    												}
    												printed = false; //It will print to the changes to the display in the next round
    												delay(300);
    											}
    											break;
    										case 2: // change the curve
    											if(!printed){//Print only once if status wasn't changed
    												display.clearDisplay();
    												display.setTextSize(2);
    												display.setCursor(0,0);
    												display.println("CURVE:");
    												display.setTextSize(3);
    												display.println(abs(curve));
    												display.display();
    												printed = true;
    											}
    											if (ButtonValue > 1800){  //Change the Curve value
    													delay(300); //to give some time until I'll stop press the button
    													//setting the speed limit value
    													while(pulseIn(ButtonInPin, HIGH, 20000) < 1800){  //Need to press CH3 to set the value and exit this loop
    														WheelValue = pulseIn(WheelInPin, HIGH, 20000);//Read the Wheel to increase or decrease the Speedlimit value
    														  if (WheelValue > 1800){  //increase the speedLimit Value
    															curve-=0.1;
    															if(curve<-1.5){curve=0;} //limit the lower boundary to 1500
    														  }else if(WheelValue <1200){  //decrease the speedLimit Value
    															curve+=0.1;
    															if(curve>0){curve=-1.5;}
    														  }
    														//Display the changes to the speedLimit value
    														display.clearDisplay();
    														display.setTextSize(2);
    														display.setCursor(0,0);
    														display.println("CURVE:");
    														display.setTextSize(1);
    														display.println("Use the wheel");
    														display.setTextSize(3);
    														display.println(abs(curve)); // mapping the speedlimit to percent 
    														display.setTextSize(1);
    														display.println("Press CH3 to set");
    														display.display();				
    													}
    
    												printed = false; //It will print to the changes to the display in the next round
    												delay(300);
    											}
    											break;
    										case 3: // Add / remove Debugging screen
    											if(!printed){//Print only once if status wasn't changed
    												display.clearDisplay();
    												display.setTextSize(2);
    												display.setCursor(0,0);
    												display.println("Debug:");
    												display.setTextSize(4);
    												if(AmountOfScreens == 11){display.println("ON");}
    												else{display.println("OFF");}
    												display.display();
    												printed = true;
    											}
    											if (ButtonValue > 1800){  //Change the 'forceOn' variable alternately
    												if(AmountOfScreens == 11){
    													AmountOfScreens = 10;
    												}else{
    													AmountOfScreens = 11;
    												}
    												printed = false; //It will print to the changes to the display in the next round
    												delay(300);
    											}
    											break;
    										case 4: //Exit
    											if(!printed){//Print only once if status wasn't changed
    												display.clearDisplay();
    												display.setTextSize(3);
    												display.setCursor(10,20);
    												display.println("Exit");
    												display.display();
    												printed = true;
    											}
    											if (ButtonValue > 1800){  //Change the 'forceOn' variable alternately
    												exit = true;
    												printed = false; //It will print to the changes to the display in the next round
    												delay(300);
    											}
    										  break;
    									}
    								}
    
    							printed = false; //It will print to the changes to the display in the next round
    							delay(300);
    						}
    						break;
    					case 10: // Debugging Screen
    						if(!printed){//Print only once if status wasn't changed
    							display.clearDisplay();
    							display.setTextSize(2);
    							display.setCursor(0,0);
    							display.println("Debuging:");
    							display.setTextSize(1);
    							display.print("Smoothed T Val:");
    							display.println(smoothedThrottleValue);
    							display.print("CH2 Val: ");
    							display.println(pulseIn(ThrottleInPin, HIGH, 20000));
    							display.print("Force Val: ");
    							display.println(analogRead(forcePin));
    							display.print("Volt Pin: ");
    							display.println(analogRead(voltPin));
    							display.print("Amp Pin: ");
    							display.println(analogRead(ampPin));			
    							display.display();
    							printed = false;
    						}
    						if (ButtonValue > 1800){  //refresh the screen
    							printed = false; //It will print to the changes to the display in the next round
    						}
    						break;
    					default: 
    						Serial.println("Fail");
    						Serial.println(ScreenNumber);
    						// if nothing else matches, do the default
    						// default is optional
    				  }
    				}
    
    				void setColor(int R, int G, int B){ // RGB LEG with analogWrite (This is not available when servo attached, this is just preparation for new board)
    					R=255-R;
    					G=255-G;
    					B=255-B;
    					
    					analogWrite(redp, R); 
    					analogWrite(greenp, G); 
    					analogWrite(bluep, B);
    				}
    				void buzz(int targetPin, long frequency, long length) {  //BUZZ function
    				  long delayValue = 1000000/frequency/2; // calculate the delay value between transitions
    				  //// 1 second's worth of microseconds, divided by the frequency, then split in half since
    				  //// there are two phases to each cycle
    				  long numCycles = frequency * length/ 1000; // calculate the number of cycles for proper timing
    				  //// multiply frequency, which is really cycles per second, by the number of seconds to 
    				  //// get the total number of cycles to produce
    				 for (long i=0; i < numCycles; i++){ // for the calculated length of time...
    					digitalWrite(targetPin,HIGH); // write the buzzer pin high to push out the diaphram
    					delayMicroseconds(delayValue); // wait for the calculated delay value
    					digitalWrite(targetPin,LOW); // write the buzzer pin low to pull back the diaphram
    					delayMicroseconds(delayValue); // wait againf or the calculated delay value
    				  }
    				}
    				float fscale( float originalMin, float originalMax, float newBegin, float newEnd, float inputValue, float curve){
    
    				  float OriginalRange = 0;
    				  float NewRange = 0;
    				  float zeroRefCurVal = 0;
    				  float normalizedCurVal = 0;
    				  float rangedValue = 0;
    				  boolean invFlag = 0;
    
    
    				  // condition curve parameter
    				  // limit range
    
    				  if (curve > 10) curve = 10;
    				  if (curve < -10) curve = -10;
    
    				  curve = (curve * -.1) ; // - invert and scale - this seems more intuitive - postive numbers give more weight to high end on output 
    				  curve = pow(10, curve); // convert linear scale into lograthimic exponent for other pow function
    
    				  // Check for out of range inputValues
    				  if (inputValue < originalMin) {
    					inputValue = originalMin;
    				  }
    				  if (inputValue > originalMax) {
    					inputValue = originalMax;
    				  }
    
    				  // Zero Refference the values
    				  OriginalRange = originalMax - originalMin;
    
    				  if (newEnd > newBegin){ 
    					NewRange = newEnd - newBegin;
    				  }
    				  else
    				  {
    					NewRange = newBegin - newEnd; 
    					invFlag = 1;
    				  }
    
    				  zeroRefCurVal = inputValue - originalMin;
    				  normalizedCurVal  =  zeroRefCurVal / OriginalRange;   // normalize to 0 - 1 float
    
    				  // Check for originalMin > originalMax  - the math for all other cases i.e. negative numbers seems to work out fine 
    				  if (originalMin > originalMax ) {
    					return 0;
    				  }
    
    				  if (invFlag == 0){
    					rangedValue =  (pow(normalizedCurVal, curve) * NewRange) + newBegin;
    
    				  }
    				  else     // invert the ranges
    				  {   
    					rangedValue =  newBegin - (pow(normalizedCurVal, curve) * NewRange); 
    				  }
    
    				  return rangedValue;
    				}
    				
    Last but not least, I have paste the new black grip after everything was in place to give it the final touch.
    I am very proud of the final result: