// Stepper motor on Wokwi!
#include <Stepper.h>
#include <LiquidCrystal_I2C.h>
#include "math.h"
/*
#define ENCODER_CLK 2
#define ENCODER_DT 3
#define ENCODER_SW 4*/
#define BUTTON_PIN 5
LiquidCrystal_I2C lcd(0x27, 20, 4);
const int stepsPerRevolution = 200; // change this to fit the number of steps per revolution
// for your motor
// initialize the stepper library on pins 8 through 11:
Stepper myStepper(stepsPerRevolution, 8, 9, 10, 11);
// encoder init
int firstRun = true;
int lastClk = HIGH;
int counter = 0;
int steps = 0;
int throttlePin = 1; // analog pin used to connect the potentiometer
int throttleRangeMinPin = 2; // analog pin used to connect the potentiometer
int throttleRangeMaxPin = 3; // analog pin used to connect the potentiometer
int throttle; // variable to read the value from the analog pin
int throttleNew;
int throttleSlider;
int rpm;
int rpm2;
int rpmRandom;
int randomNumber;
int randomNumberEngine;
int randomNumberVolume;
//int throttleLast = map(analogRead(throttlePin), 0, 1023, 0, 50);
int throttleLast = 0;
double microphone;
double microphonePow;
double sound;
double soundDb;
double rpmPow;
//int rangeMin;
//int rangeMax;
int throttleRangeMin = analogRead(throttleRangeMinPin);
int throttleRangeMinSet= 900;
int throttleRangeMax = analogRead(throttleRangeMaxPin);
int throttleRangeMaxSet = 5600;
void engineSound () {
//microphone = analogRead(A0);
microphone = rpmRandom;
randomNumberEngine = random(-10, 10);
randomNumberVolume = random(-5, 5);
soundDb = 50 + randomNumberVolume + log10(pow(microphone / 10, 10)) * throttleLast / 15;
tone(7, (soundDb / 20) * (500 + randomNumberEngine), 5);
//Serial.println(soundDb, DEC);
delay(5);
digitalWrite(13, abs (microphone - 512) > 50);
}
void readRPM() {
throttle = analogRead(throttlePin);
randomNumber = random(0, 100);
rpm = map(throttle, 0, 1023, 900, 5600);
rpmRandom = rpm + randomNumber;
if ((rpm>throttleRangeMinSet)&&(rpm<throttleRangeMaxSet)) {
// throttleSlider = map(rpm, throttleRangeMinSet, throttleRangeMaxSet, 0, 1023);
// throttleSlider = map(throttle, 0, 1023, 0, (throttleRangeMaxSet-throttleRangeMinSet));
throttleSlider = map(rpm, 0, 1023, throttleRangeMinSet, throttleRangeMaxSet);
//throttleNew = map(throttleSlider, 0, (throttleRangeMaxSet-throttleRangeMinSet), 0, 50);
throttleNew = map(throttleSlider, 0,throttleRangeMaxSet, 0, 50);
//throttleNew = map(rpm, throttleRangeMinSet, throttleRangeMaxSet, 0, 50);
Serial.println(throttleSlider,DEC);
}
// rpm2 = map(throttle, 0, 1023, throttleRangeMinSet, throttleRangeMaxSet);
// rpmRandom = rpm + randomNumber;
// reads the value of the potentiometer (value between 0 and 1023)
//if (!(rpm>throttleRangeMinSet&&rpm<throttleRangeMaxSet)) {
//else {
//throttleNew = map(rpm, 900, 5600, 0, 50);}
// throttleNew = map(throttle, 0, 1023, 0, 50);
//rpm = map(throttleNew, 0, 50, throttleRangeMinSet, throttleRangeMaxSet) + randomNumber;
//}
}
void readRangeRPM () {
throttleRangeMin = analogRead(throttleRangeMinPin);
if (throttleRangeMinSet<throttleRangeMaxSet) throttleRangeMinSet= map(throttleRangeMin, 0, 1023, 900, 5600);
if (throttleRangeMinSet>=throttleRangeMaxSet) throttleRangeMinSet=throttleRangeMaxSet-1;
throttleRangeMax = analogRead(throttleRangeMaxPin);
if (throttleRangeMaxSet>throttleRangeMinSet) throttleRangeMaxSet = map(throttleRangeMax, 0, 1023, 900, 5600);
if (throttleRangeMaxSet<=throttleRangeMinSet) throttleRangeMaxSet=throttleRangeMinSet+1;
}
//Serial.println(throttleRangeMinNew,DEC);
/*
void readEncoder() {
int dtValue = digitalRead(ENCODER_DT);
if (dtValue == HIGH) {
counter++; // Clockwise
myStepper.step(1);
}
if (dtValue == LOW) {
counter--; // Counterclockwise
myStepper.step(-1);
}
}
void resetCounter() {
if (counter != 0)
myStepper.step(-counter);
noInterrupts();
counter = 0;
interrupts();
}
*/
void lcdUpdate(int steps, int counter, double sound, int rangeMin, int rangeMax) {
lcd.setCursor(0, 0);
lcd.print("Min:");
lcd.setCursor(5, 0);
lcd.println(rangeMin, DEC);
lcd.setCursor(10, 0);
lcd.print("Max:");
lcd.setCursor(15, 0);
lcd.println(rangeMax, DEC);
lcd.setCursor(0, 1);
lcd.print("RPM:");
lcd.setCursor(5, 1);
lcd.println(steps, DEC);
lcd.setCursor(10, 1);
lcd.print("Valve:");
lcd.setCursor(17, 1);
lcd.println(counter, DEC);
lcd.setCursor(0, 3);
lcd.print("Decibels:");
lcd.setCursor(10, 3);
lcd.print(sound);
}
void setup() {
// set the speed at 60 rpm:
myStepper.setSpeed(500);
// initialize the serial port:
Serial.begin(115200);
// Initialize LCD
lcd.init();
lcd.backlight();
/*
pinMode(ENCODER_CLK, INPUT);
pinMode(ENCODER_DT, INPUT);
pinMode(ENCODER_SW, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(ENCODER_CLK), readEncoder, FALLING);
*/
pinMode(13, OUTPUT); // sound led indicator
pinMode(7, OUTPUT); // buzzer
tone(7, (900 / 1000) * 500, 5);
pinMode(BUTTON_PIN, INPUT_PULLUP);
int value = LOW;
//int value = HIGH;
while (value == HIGH) {
myStepper.step(-1);
value = digitalRead((BUTTON_PIN));
}
//myStepper.step(0);
}
void loop() {
readRangeRPM();
readRPM();
engineSound();
if (throttleNew != throttleLast)
myStepper.step(throttleNew - throttleLast);
throttleLast = throttleNew;
//if (digitalRead(ENCODER_SW) == LOW)
// resetCounter();
lcdUpdate(rpm, throttleNew, soundDb, throttleRangeMinSet, throttleRangeMaxSet);
}