#include<Wire.h>voidsetup(){Wire.begin();Serial.begin(115200);Serial.println("\nI2C Scanner");}voidloop(){byteerror,address;intnDevices;Serial.println("Scanning...");nDevices=0;for(address=1;address<127;address++){Wire.beginTransmission(address);error=Wire.endTransmission();if(error==0){Serial.print("I2C device found at address 0x");if(address<16){Serial.print("0");}Serial.println(address,HEX);nDevices++;}elseif(error==4){Serial.print("Unknow error at address 0x");if(address<16){Serial.print("0");}Serial.println(address,HEX);}}if(nDevices==0){Serial.println("No I2C devices found\n");}else{Serial.println("done\n");}delay(5000);}
If the IR sensor detects nothing, reset IR_status, and shows the score and status of the sensor in the LCD.
If the IR sensor detects anything, the score increase by 1, and shows the score and status of the sensor in the LCD.
If the IR sensor keeps detecting nothing, shows the score and status of the sensor on the LCD.
Note: IR_status is a value used to prevent the score keep increasing in a detection.
#include<LiquidCrystal_I2C.h>#define IRSensor (14)LiquidCrystal_I2Clcd(0x26,16,2);// set the LCD address to 0x27 for a 16 chars and 2 line displayintScore=0;intIR_staus=0;voidsetup(){Serial.begin(115200);pinMode(IRSensor,INPUT);// sensor pin INPUTlcd.init();// initialize the lcdlcd.backlight();lcd.print("> -------- <");lcd.setCursor(0,1);lcd.print("Hello, world!");lcd.setCursor(0,1);lcd.print("IR: ");lcd.setCursor(6,1);lcd.print("Count: ");}voidloop(){intstatusSensor=digitalRead(IRSensor);if(statusSensor==1&&IR_staus==1){IR_staus=0;lcd.setCursor(4,1);lcd.print(statusSensor);lcd.setCursor(13,1);lcd.print(Score);}elseif(statusSensor==0&&IR_staus==0){Score=Score+1;IR_staus=1;lcd.setCursor(4,1);lcd.print(statusSensor);lcd.setCursor(13,1);lcd.print(Score);}else{lcd.setCursor(4,1);lcd.print(statusSensor);lcd.setCursor(13,1);lcd.print(Score);}}
The difficulties can be changed by the white button.
Start the game by pushing the black button.
After 3 sec countdown, the ESP32 will count the number of things that pass through the IR sensor.
The score and time willing showing on the I2C LCD.
At the same time the brushless DC motor will make the balls fly.
The frequency of changing speed were depends on the difficulties selected by the player.
#include<pitches.h>#include<Tone32.h>#include<ESP32Servo.h> // ESP32Servo library installed by Library Manager#include"ESC.h" // RC_ESP library installed by Library Manager#include<analogWrite.h>#include<ESP32Tone.h>#include<ESP32PWM.h>#include<LiquidCrystal_I2C.h>//#include <digitalWriteFast.h>#define RotateServo (25)#define IRSensor (14)#define ESC_PIN (13) // connected to ESC control wire#define Button_1 (27)#define Button_2 (32)#define Button_3 (26)#define MIN_SPEED 1244 // speed just slow enough to turn motor off#define MAX_SPEED 1900 // speed where my motor drew 3.6 amps at 12v.LiquidCrystal_I2Clcd(0x26,16,2);// set the LCD address to 0x27 for a 16 chars and 2 line displayServoRotate;// create servo object to control the ESCintangle=0;intangleMin=30;intangleMax=150;ESCMotorESC(ESC_PIN,1000,2000,500);// ESC_Name (PIN, Minimum Value, Maximum Value, Arm Value)intSpeed=0;intPlayTime=31;intcountDownSec=PlayTime;intScore=0;intIR_staus=0;intBT_staus=0;intwaiting_staus=0;introtate_staus=0;intmotor_staus=0;intstarted=0;floatwaiting=0;intdifficulty=0;intcounter1=0;intcounter2=0;unsignedlongpreviousMillis=0;constlonginterval=1000;voidsetup(){Serial.begin(115200);delay(1000);pinMode(ESC_PIN,OUTPUT);MotorESC.arm();// Send the Arm command to ESCdelay(5000);// Wait a whileRotate.attach(RotateServo);Rotate.write((angleMax+angleMin)/2);randomSeed(analogRead(0));pinMode(IRSensor,INPUT);// sensor pin INPUTpinMode(Button_1,INPUT_PULLUP);pinMode(Button_2,INPUT_PULLUP);pinMode(Button_3,INPUT_PULLUP);lcd.init();// initialize the lcdlcd.backlight();lcd.print("> -------- <");lcd.setCursor(0,1);lcd.print(">START EASY<");// the following loop turns on the motor slowly, so get readyfor(inti=0;i<350;i++){// run speed from 840 to 1190MotorESC.speed(MIN_SPEED-200+i);// motor starts up about half way through loopdelay(10);}MotorESC.speed(0);}voidwaitforuser(){if(waiting<=1){lcd.setCursor(0,0);lcd.print(">BALL-IN <");}elseif(waiting<=2){lcd.setCursor(0,0);lcd.print("> BALL-IN <");}elseif(waiting<=3){lcd.setCursor(0,0);lcd.print("> BALL-IN <");}elseif(waiting<=4){lcd.setCursor(0,0);lcd.print("> BALL-IN <");}elseif(waiting<=5){lcd.setCursor(0,0);lcd.print("> BALL-IN <");}elseif(waiting<=6){lcd.setCursor(0,0);lcd.print("> BALL-IN <");}elseif(waiting<=7){lcd.setCursor(0,0);lcd.print("> BALL-IN <");}elseif(waiting<=8){lcd.setCursor(0,0);lcd.print("> BALL-IN<");}else{lcd.setCursor(0,0);lcd.print("> ERROR ERROR <");}}voidshowScore(){lcd.setCursor(7,0);lcd.print(Score);}voidshowTime(){lcd.setCursor(6,1);lcd.print(countDownSec);lcd.print(" ");Serial.println((String)"Sec: "+countDownSec);}voidreset(){difficulty=0;countDownSec=PlayTime;Score=0;counter1=0;counter2=0;Speed=0;MotorESC.speed(Speed);lcd.setCursor(0,1);lcd.print(">START EASY<");started=0;}voideasy_mode(){if(counter1==80){if(angle>=angleMax&&rotate_staus!=1){rotate_staus=1;}elseif(angle<=angleMin&&rotate_staus!=0){rotate_staus=0;}elseif(rotate_staus==0){angle=angle+random(2,4);}elseif(rotate_staus==1){angle=angle-random(2,4);}if(angle>angleMax){angle=angleMax;}if(angle<angleMin){angle=angleMin;}Serial.println((String)"Angle: "+angle);Rotate.write(angle);counter1=0;}else{counter1++;}if(counter2==100){if(Speed>=MAX_SPEED&&motor_staus!=1){motor_staus=1;}elseif(Speed<=MIN_SPEED&&motor_staus!=0){motor_staus=0;}elseif(motor_staus==0){Speed=Speed+75;}elseif(motor_staus==1){Speed=Speed-75;}if(Speed>MAX_SPEED){Speed=MAX_SPEED;}if(Speed<MIN_SPEED){Speed=MIN_SPEED;}Serial.println((String)"Speed: "+Speed);MotorESC.speed(Speed);counter2=0;}else{counter2++;}}voidnormal_mode(){if(counter1==80){if(angle>=angleMax&&rotate_staus!=1){rotate_staus=1;}elseif(angle<=angleMin&&rotate_staus!=0){rotate_staus=0;}elseif(rotate_staus==0){angle=angle+random(1,8);}elseif(rotate_staus==1){angle=angle-random(1,8);}if(angle>angleMax){angle=angleMax;}if(angle<angleMin){angle=angleMin;}Serial.println((String)"Angle: "+angle);Rotate.write(angle);counter1=0;}else{counter1++;}if(counter2==100){if(Speed>=MAX_SPEED&&motor_staus!=1){motor_staus=1;}elseif(Speed<=MIN_SPEED&&motor_staus!=0){motor_staus=0;}elseif(motor_staus==0){Speed=Speed+random(25,100);}elseif(motor_staus==1){Speed=Speed-random(25,200);}if(Speed>MAX_SPEED){Speed=MAX_SPEED;}if(Speed<MIN_SPEED){Speed=MIN_SPEED;}Serial.println((String)"Speed: "+Speed);MotorESC.speed(Speed);counter2=0;}else{counter2++;}}voidhard_mode(){if(counter1==80){if(angle>=angleMax&&rotate_staus!=1){rotate_staus=1;}elseif(angle<=angleMin&&rotate_staus!=0){rotate_staus=0;}elseif(rotate_staus==0){angle=angle+random(1,16);}elseif(rotate_staus==1){angle=angle-random(1,16);}if(angle>angleMax){angle=angleMax;}if(angle<angleMin){angle=angleMin;}Serial.println((String)"Angle: "+angle);Rotate.write(angle);counter1=0;}else{counter1++;}if(counter2==100){if(Speed>=MAX_SPEED&&motor_staus!=1){motor_staus=1;}elseif(Speed<=MIN_SPEED&&motor_staus!=0){motor_staus=0;}elseif(motor_staus==0){Speed=Speed+random(50,200);}elseif(motor_staus==1){Speed=Speed-random(50,200);}if(Speed>MAX_SPEED){Speed=MAX_SPEED;}if(Speed<MIN_SPEED){Speed=MIN_SPEED;}Serial.println((String)"Speed: "+Speed);MotorESC.speed(Speed);counter2=0;}else{counter2++;}}voidloop(){unsignedlongcurrentMillis=millis();intstatusSensor=digitalRead(IRSensor);intPushed_1=digitalRead(Button_1);intPushed_2=digitalRead(Button_2);intPushed_3=digitalRead(Button_3);Serial.println(Pushed_1);Serial.println(Pushed_2);Serial.println(Pushed_3);if(started==1){if(currentMillis-previousMillis>=interval){previousMillis=currentMillis;countDownSec--;if(countDownSec<0){countDownSec=0;}showTime();}if(countDownSec>0&&Pushed_1!=LOW&&Pushed_3==LOW){if(difficulty==0){// easy modeeasy_mode();}elseif(difficulty==1){// normal modenormal_mode();}elseif(difficulty==2){// hard modehard_mode();}Serial.println((String)"IR: "+statusSensor);if(statusSensor==1&&IR_staus==1){IR_staus=0;showScore();}elseif(statusSensor==0&&IR_staus==0){Score++;IR_staus=1;showScore();}else{showScore();}}else{Speed=0;MotorESC.speed(Speed);lcd.clear();lcd.setCursor(0,1);lcd.print("Gameover!");lcd.setCursor(0,0);lcd.print("Score: ");lcd.print(Score);lcd.setCursor(15,1);lcd.print("3");delay(1000);lcd.setCursor(15,1);lcd.print("2");delay(1000);lcd.setCursor(15,1);lcd.print("1");delay(1000);reset();}}else{if(Pushed_1==LOW){started=1;lcd.clear();lcd.setCursor(0,0);lcd.print("Start In...");lcd.setCursor(0,1);lcd.print("3");delay(1000);lcd.setCursor(0,1);lcd.print("2");delay(1000);lcd.setCursor(0,1);lcd.print("1");delay(1000);lcd.clear();lcd.setCursor(0,1);lcd.print("Time:");lcd.setCursor(0,0);lcd.print("Score:");}elseif(Pushed_2==LOW){if(difficulty==0&&BT_staus==0){BT_staus=1;difficulty=1;// easy > normallcd.setCursor(9,1);lcd.print("NORMAL");}elseif(difficulty==1&&BT_staus==0){BT_staus=1;difficulty=2;// normal > hardlcd.setCursor(9,1);lcd.print(" HARD");}elseif(difficulty==2&&BT_staus==0){BT_staus=1;difficulty=0;// hard > easylcd.setCursor(9,1);lcd.print(" EASY");}}else{BT_staus=0;if(waiting==8&&waiting_staus!=1){waiting_staus=1;}elseif(waiting==0&&waiting_staus!=0){waiting_staus=0;}elseif(waiting_staus==0){waiting=waiting+0.25;waitforuser();}elseif(waiting_staus==1)waiting=waiting-0.25;waitforuser();}}}
/* Blink without Delay Turns on and off a light emitting diode (LED) connected to a digital pin, without using the delay() function. This means that other code can run at the same time without being interrupted by the LED code. The circuit: - Use the onboard LED. - Note: Most Arduinos have an on-board LED you can control. On the UNO, MEGA and ZERO it is attached to digital pin 13, on MKR1000 on pin 6. LED_BUILTIN is set to the correct LED pin independent of which board is used. If you want to know what pin the on-board LED is connected to on your Arduino model, check the Technical Specs of your board at: https://www.arduino.cc/en/Main/Products created 2005 by David A. Mellis modified 8 Feb 2010 by Paul Stoffregen modified 11 Nov 2013 by Scott Fitzgerald modified 9 Jan 2017 by Arturo Guadalupi This example code is in the public domain. https://www.arduino.cc/en/Tutorial/BuiltInExamples/BlinkWithoutDelay*/// constants won't change. Used here to set a pin number:constintledPin=LED_BUILTIN;// the number of the LED pin// Variables will change:intledState=LOW;// ledState used to set the LED// Generally, you should use "unsigned long" for variables that hold time// The value will quickly become too large for an int to storeunsignedlongpreviousMillis=0;// will store last time LED was updated// constants won't change:constlonginterval=1000;// interval at which to blink (milliseconds)voidsetup(){// set the digital pin as output:pinMode(ledPin,OUTPUT);}voidloop(){// here is where you'd put code that needs to be running all the time.// check to see if it's time to blink the LED; that is, if the difference// between the current time and last time you blinked the LED is bigger than// the interval at which you want to blink the LED.unsignedlongcurrentMillis=millis();if(currentMillis-previousMillis>=interval){// save the last time you blinked the LEDpreviousMillis=currentMillis;// if the LED is off turn it on and vice-versa:if(ledState==LOW){ledState=HIGH;}else{ledState=LOW;}// set the LED with the ledState of the variable:digitalWrite(ledPin,ledState);}}
For driving a brushless motor with an ESC from a ESP32, I referenced to this:
https://esp32.com/viewtopic.php?t=20450#p74915