// Stepper motor on Wokwi!
#include <Stepper.h>
#include <LiquidCrystal_I2C.h>
#include "math.h"
#include <Servo.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);
Servo myservo;
// encoder init
//int throttleChange = false;
int lastClk = HIGH;
int counter = 0;
int steps = 0;
int throttlePin = 0; // analog pin used to connect the potentiometer
int throttle; // variable to read the value from the analog pin
int throttleNew;
int servoPosition;
double rpm;
int randomNumber;
int randomNumberEngine;
int randomNumberVolume;
int throttleLast = analogRead(throttlePin);
double microphone;
double microphonePow;
double sound;
double soundDb;
double rpmPow;
void readRPM() {
throttle = analogRead(throttlePin); // reads the value of the potentiometer (value between 0 and 1023)
throttleNew = map(throttle, 0, 1023, 0, 50);
servoPosition = map(throttle, 0, 1023, 0, 90);
randomNumber = random(0, 100);
rpm = map(throttleNew, 0, 50, 900, 5500)+randomNumber;
myservo.attach(9);
}
void readEncoder() {
int dtValue = digitalRead(ENCODER_DT);
if (dtValue == HIGH) {
counter++; // Clockwise
myStepper.step(1);
}
if (dtValue == LOW) {
counter--; // Counterclockwise
myStepper.step(-1);
}
}
/*
// Get the counter value, disabling interrupts.
// This make sure readEncoder() doesn't change the value
// while we're reading it.
int getCounter() {
int result;
noInterrupts();
result = counter;
interrupts();
return result;
}
int getPosition() {
int result;
noInterrupts();
result = counter;
interrupts();
return result;
}
*/
void resetCounter() {
if (counter != 0)
myStepper.step(-counter);
noInterrupts();
counter = 0;
interrupts();
}
void lcdUpdate(int steps, int counter, double sound) {
lcd.setCursor(0, 0);
lcd.print("RPM:");
lcd.setCursor(10, 0);
lcd.println(steps,DEC);
lcd.setCursor(0, 1);
lcd.print("Position:");
lcd.setCursor(10, 1);
lcd.println(counter,DEC);
lcd.setCursor(0, 2);
lcd.print("Sound Db:");
lcd.setCursor(10, 2);
lcd.print(sound);
}
void setup() {
//readEncoder();
// 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
//readRPM();
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() {
readRPM();
//throttleNew = analogRead(throttlePin);
//throttleNew = map(throttleNew, 0, 1023, 0, 50);
//rpm = map(throttleNew, 0, 50, 0, 5600);
// sound measurmemt
//microphone = analogRead(A1);
microphone = rpm;
//soundDb = log10(microphone);
//soundDb = log10(pow(microphone,10));
//microphonePow = pow(microphone,10);
//soundDb = ((rpm/200)*log10(microphonePow))
//rpmPow = pow(rpm/100,10);
//soundDb = 50 + (log10(rpmPow)*(rpm/500));
randomNumberEngine = random(-10, 10);
randomNumberVolume = random(-5, 5);
soundDb = 50+randomNumberVolume+log10(pow(microphone/10,10))*throttleLast/15;
Serial.println(throttleNew,DEC);
delay(5);
digitalWrite(13, abs (microphone - 512) > 50);
tone(7,(soundDb/20)*(500+randomNumberEngine),5);
//lcdUpdate(rpm, throttleNew, soundDb);
if (throttleNew != throttleLast)
// There was a change on the CLK pin
//if (throttleNew > throttleLast) {
//throttleNew = map(val, 0, 1023, 0, 50);
//steps = throttleNew;
myStepper.step(throttleNew - throttleLast);
//}
// if (throttleNew < throttleLast) {
//throttleNew = map(val, 0, 1023, 0, 50);
//steps = throttleNew;
// myStepper.step(-(throttleLast - throttleNew));
// }
throttleLast = throttleNew;
//throttleChange = true;
//}
myservo.write(servoPosition);
delay(15);
//Serial.println(analogRead(throttlePin), DEC);
//Serial.println(throttleLast,DEC);
//Serial.println(rpm, DEC);
//delay(100);
if (digitalRead(ENCODER_SW) == LOW) {
resetCounter();
}
lcdUpdate(rpm, throttleNew, soundDb);
/*
val = analogRead(throttlePin); // reads the value of the potentiometer (value between 0 and 1023)
val = map(val, 0, 1023, 0, 50);
myStepper.step(val);
val = 0;
Serial.println(analogRead(throttlePin));
*/
// step one revolution in one direction:
//Serial.println("clockwise");
//myStepper.step(1);
//delay(500);
/*
// step one revolution in the other direction:
Serial.println("counterclockwise");
myStepper.step(-stepsPerRevolution);
delay(500);*/
/*
int dtValue = digitalRead(ENCODER_DT);
if (dtValue == HIGH) {
counter++; // Clockwise
myStepper.step(1);
}
if (dtValue == LOW) {
counter--; // Counterclockwise
myStepper.step(-1);
}*/
/*
// encoder part
int newClk = digitalRead(ENCODER_CLK);
if (newClk != lastClk) {
// There was a change on the CLK pin
lastClk = newClk;
int dtValue = digitalRead(ENCODER_DT);
if (newClk == LOW && dtValue == HIGH) {
myStepper.step(10);
//counter++; // Clockwise
Serial.println("Rotated clockwise ⏩");
}
if (newClk == LOW && dtValue == LOW) {
myStepper.step(20);
//counter--; // Clockwise
Serial.println("Rotated counterclockwise ⏪");
}
}*/
}