I made a keyboard emulator with my Arduino and hooked it up to some switches, thought I'd test them out in OSU. Osu, while it can be played with one key is best with two so naturally, I tried to add another switch/key to my emulator. This broke my emulator completely and caused it to start spitting out characters without any input. I've rewritten this script twice so forgive me if it's kind of frantic but can anyone tell me what's causing this?
Code:
#include <Keyboard.h>
void setup() {
// put your setup code here, to run once:
pinMode (2, INPUT_PULLUP);
pinMode (5, INPUT_PULLUP);
Serial.begin(9600);
}
void loop() {
// put your main code here, to run repeatedly:
bool keyL = false;
bool keyR = false;
Keyboard.begin();
if (digitalRead (2) == 0){ //if switch 2 is activated
keyL = true;
}
else{
}//do nothing
if (digitalRead (5) == 0){
keyR = true;
}
else{
}//do nothing
if (keyR = true){
Keyboard.press ('c');
delay (50);
if (digitalRead (5) == 1){
keyR = false;
Keyboard.releaseAll();
}
}
if (keyL = true){
Keyboard.press ('z');
delay (50);
if (digitalRead (2) == 0){
keyL = false;
Keyboard.releaseAll();
}
}
}
It happens because the = operator is used for assignment only, and it returns the value of the assignment. so the expressions (keyR = true) inside if (keyR = true){ and (keyL = true) inside if(keyL = true){ always return true.
To compare the value of 2 variables you have to use the == operator:
#include <Keyboard.h>
void setup() {
// put your setup code here, to run once:
pinMode (2, INPUT_PULLUP);
pinMode (5, INPUT_PULLUP);
Serial.begin(9600);
}
void loop() {
// put your main code here, to run repeatedly:
bool keyL = false;
bool keyR = false;
Keyboard.begin();
if (digitalRead (2) == 0){ //if switch 2 is activated
keyL = true;
}
else{
}//do nothing
if (digitalRead (5) == 0){
keyR = true;
}
else{
}//do nothing
if (keyR == true){
Keyboard.press ('c');
delay (50);
if (digitalRead (5) == 1){
keyR = false;
Keyboard.releaseAll();
}
}
if (keyL == true){
Keyboard.press ('z');
delay (50);
if (digitalRead (2) == 0){
keyL = false;
Keyboard.releaseAll();
}
}
}
Related
I just started getting into Arduino and I put together a very simple led control with one button to change the on and off state. When I push the button the light will come on, but it will only stay on about 50% of the time (so I have to push it multiple times until it actually stays on), and The same thing happens when I try to turn it off.
Is there some problem with my code? Or is it likely to be a wiring issue?
//define variables
int ledPin = 5;
int btnOnPin = 9;
bool isItOn = false;
void setup() {
pinMode(ledPin, OUTPUT);
pinMode(btnOnPin, INPUT_PULLUP);
}
void loop() {
if(digitalRead(btnOnPin) == LOW)
{
if(isItOn == false)
{
digitalWrite(ledPin, HIGH);
isItOn = true;
}
else if (isItOn == true)
{
digitalWrite(ledPin, LOW);
isItOn = false;
}
}
}
The button is connected to ground and pin9, the led is connected to ground, and pin5 through a 220ohm resistor.
This should be super simple, but for some reason I can't get it to work properly.
Thanks for any help
try putting the arduiton to sleep for a few milli seconds after changing its val
void loop() {
if(digitalRead(btnOnPin) == LOW)
{
if(isItOn == false)
{
digitalWrite(ledPin, HIGH);
isItOn = true;
}
else if (isItOn == true)
{
digitalWrite(ledPin, LOW);
isItOn = false;
}
sleep(K);
}
a few days ago I started working with the Arduino. I've set up a small project with a DHT22 to read the temperature and humidity and write it to an LCD. That works without a problem. Now I want to only turn on the backlight of the LCD when I press a button. That mostly works too:
void loop() {
buttonState = digitalRead(BUTTONPIN);
currentMillisScreen = millis();
if (buttonState == HIGH) {
screenOn = true;
lcd.backlight();
}
// DHT22 related code in here
if (currentMillisScreen - previousMillisScreen >= SCREEN_ON_TIME) {
previousMillisScreen = currentMillisScreen;
screenOn = false;
lcd.noBacklight();
}
}
The problem is that with this code is that the Backlight won't always stay on for exactly 5 seconds. I thought putting the currentMillisScreen = millis() in the following if-Statement would fix it:
if (buttonState == HIGH) {
currentMillisScreen = millis();
screenOn = true;
lcd.backlight();
}
But if I do that, the Backlight won't turn off again and I don't understand why.
You are not updating currentMillisScreen in the loop and that is your problem. You just need to find different between currentTime (equal to millis()) and previous time that light turned on and if it reaches above the threshold then turn it off. Something like this:
#define SCREEN_ON_TIME 5000
bool screenOn = false;
void setup()
{
//setup
}
void loop()
{
buttonState = digitalRead(BUTTONPIN);
if (buttonState == HIGH)
{
previousMillisScreen = millis();
lcd.backlight();
screenOn = true;
}
// DHT22 related code in here
// if time passed above SCREEN_ON_TIME after we turned on light
if ((screenOn) && (millis() - previousMillisScreen >= SCREEN_ON_TIME))
{
lcd.noBacklight();
screenOn = false;
}
}
I'm trying to build a system using Arduino Uno, 8x8 LED matrix and 3 push buttons. The goal of the system is to display 3 different characters upon pushing the 3 buttons correspondingly. For instance, I've chosen the letters A,B,C. When the button corresponding to A is pressed, the letter A must be displayed and similar for B and C too. I'm kinda stuck in this code, where it seems logically correct for me but I have no idea why it isn't working. Thanks in advance.
#include "LedControlMS.h"
#define NBR_MTX 1
LedControl lc=LedControl(4,3,2, NBR_MTX);//
const int buttonPinA = 8;
const int buttonPinB = 9;
const int buttonPinC = 10;
char ip2;
void setup()
{
Serial.begin(9600);
for (int i=0; i< NBR_MTX; i++)
{
lc.shutdown(i,false);
lc.setIntensity(i,8);
lc.clearDisplay(i);
delay(100);
}
}
void Fun1()
{
lc.writeString(0,"A");
delay(500);
lc.clearAll();
}
void Fun2{
lc.writeString(0,"B");
delay(500);
lc.clearAll();
}
void Fun3()
{
lc.writeString(0,"C");
delay(500);
lc.clearAll();
}
void loop(){
if( digitalRead(buttonPinA) == HIGH){
ip2 = 1;}
else if(digitalRead(buttonPinB) == HIGH){
ip2 = 2;}
else if(digitalRead(buttonPinC) == HIGH){
ip2 = 3;
}
if(ip2 == '1'){
for(int i=1;i<=6;i++){
Fun1();
}
}
else if(ip2 == '2')
{
for(int i=1;i<=6;i++){
Fun2();}
}
else if(ip2 == '3'){
for(int i=1;i<=6;i++){
Fun3();}
}}
You're setting your char ip2 variable as an integer and then checking it as a character. You will see in this ASCII Table that '1' is equal to 31 as in integer, '2' is equal to 32 and so on.
Replacing the first few lines of you main loop with the code below should fix your problem. If not, I would check the documentation of the led library you're using and make sure you're implementing it correctly.
if( digitalRead(buttonPinA) == HIGH)
{
ip2 = '1';
}
else if(digitalRead(buttonPinB) == HIGH)
{
ip2 = '2';
}
else if(digitalRead(buttonPinC) == HIGH)
{
ip2 = '3';
}
Simply, I want to make a counter to execute a subroutine if digital read gets a toggle value just thefirst time. But the result shows that the "aFunction" executes more than once (repeatedly).
Code:
int lastState = 1;
void setup() {
Serial.begin(115200);
}
void loop() {
int currentState = digitalRead(D5);
if (currentState == 1) {
if (currentState = !lastState) {
aFunction();
}
lastState = !lastState;
}
Serial.println("Still running loop");
delay(2000);
}
void aFunction() {
Serial.println("in a function");
}
This is the final result:
bool executed = false;
void setup()
{
Serial.begin(115200);
}
void loop()
{
int currentState = digitalRead(D5);
if (currentState == 1 && executed == false)
{
aFunction();
executed = true;
}
if (currentState == 0 && executed == true)
{
aFunction();
executed = false;
}
Serial.println("Still running loop");
delay(2000);
}
void aFunction()
{
Serial.println("in a function");
}
By keeping track of execution of function and checking it along with currentState variable will help you in achieving your goal.
Your code with this change will look like:
bool executed = false;
void setup() {
Serial.begin(115200);
}
void loop() {
int currentState = digitalRead(D5);
if (currentState == 1 && executed == false) {
executed = true;
aFunction();
}
Serial.println("Still running loop");
delay(2000);
}
void aFunction() {
Serial.println("in a function");
}
You need a variable to signal it's been run once:
int lastState = 1;
int runOnce = 0;
void setup() {
Serial.begin(115200);
}
void loop() {
int currentState = digitalRead(D5);
if (currentState == 1) {
if (currentState = !lastState) {
if (runOnce == 0)
aFunction();
}
lastState = !lastState;
}
Serial.println("Still running loop");
delay(2000);
}
void aFunction() {
Serial.println("in a function");
runOnce = 1;
}
So now your aFunction() sets the runOnce flag to 1 and it won't ever run again until the device is reset due to the if statement inside loop().
Your problem lies right here:
if (currentState == 1) {
if (currentState = !lastState) {
aFunction();
}
lastState = !lastState;
}
This will run indefinitely until currentState /= 1. You are having problems because you're not exactly understanding how the code runs in runtime. The computer is reading this repeatedly, and its reading if currentState==1 to execute the bracket.
The next issue is your nested if statement, it's not using a comparison operator. You have an = sign, but you should have an == operator to compare currentstate to laststate.
Essentially, if you want it to run once, you need to make sure the function changes the variable currentState to something other than 1, then if you want this function to execute again at some other point during runtime, change currentState back 1 for this function to run again, where again it'll change currentState to something other than 1.
I suggest instead of using an integer for currentState to use a boolean true or false. If true, execute, change to false at the end - since its changed to false it wont run again until its true again.
Here's my code for starting a Stepper motor and trying to stop the motor:
#include <BasicStepperDriver.h>
#define DIR 34
#define STEP 36
#define ENBL 30
BasicStepperDriver stepper1(10000, DIR, STEP, ENBL);
BasicStepperDriver stepper2(10000, DIR, STEP, ENBL);
bool enableMotor1 = false;
bool enableMotor2 = false;
void rotate1() {
Serial.println("Rotate start 1");
stepper1.rotate(360);
Serial.println("Rotate end 1");
}
void rotate2() {
Serial.println("Rotate start 2");
stepper2.rotate(360);
Serial.println("Rotate end 2");
}
void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
stepper1.enable();
stepper1.setMicrostep(1);
stepper1.setRPM(50);
stepper2.enable();
stepper2.setMicrostep(1);
stepper2.setRPM(50);
}
void loop() {
if(enableMotor1 == true) {
rotate1();
} else if(enableMotor2 == true) {
rotate2();
}
if (Serial.available ()) {
String first = Serial.readStringUntil(',');
Serial.read();
String second = Serial.readStringUntil(',');
if(first == "start"){
if(second == "1") {
Serial.println("Starting motor 1");
enableMotor1 = true;
}
if(second == "2") {
Serial.println("Starting motor 2");
enableMotor2 = true;
}
} else if(first == "stop") {
if(second == "1") {
Serial.println("Stopping motor 1");
enableMotor1 = false;
stepper1.disable();
}
if(second == "2") {
enableMotor2 = false;
Serial.println("Stopping motor 1");
stepper2.disable();
}
}
}
}
The problem with this code is that it is not possible to stop the motor through Serial interface. The goal is to have the Stepper motor running until the stop command is entered in the serial monitor. What could be wrong in my code?
This image shows that we can start the motor but can't be stopped: