i'm having some issues whit a little program in arduino with a button; i have a code that i make a little modified from the examples of the arduino's page.
the code is
const int buttonPin = 7; // the number of the pushbutton pin
int buttonState = 0;
void setup() {
pinMode(buttonPin, INPUT);
Serial.begin(9600);
}
void loop() {
buttonState = digitalRead(buttonPin);
Serial.println(buttonState);
}
Probably you will follow the simple idea, the program read the state of the button and send to the serial the value of the state.
The idea is, it will send something like
0
0
0
0
0
0
when the button is not pressed
and
1
1
1
1
1
1
when it is.
but i recieve something like this when it's not pressed
0
0
1
0
1
1
0
0
0
1
... i had this problems with other type of inputs but i just want tu figured it out this issue.
From what you explain, you connected the button to 5V. Then, when you press the button you are connecting the input to logical level 1. But when you release the button, Arduin's input is connected to nowhere. Which isn't 1 nor 0 logic level. That's why you get an ambiguous reading.
You have to put a pull-down resistor. That is a resistor between the input and GND. Usually 4k7 resistor is ok for that. Then when the button is released the input will sense a logic 0. This works the other way around too. You can place the button to connect to GND when pressed, and the 4k7 pull-up resistor to logic 1 (5 volt).
Furthermore, Arduino has bult-in pull up resistors for its digital input pins. Once you setup an input, you can turn the pull-up resistor with:
pinMode(pin, INPUT);
digitalWrite(pin, HIGH);
And then you don't need to use an actual resistor. That input will always read 1 unless you actually connect it to GND.
Related
I would like your help to solve the following problem.
I'm using an ESP32 Dev Kit V1 connected as follows:
Pin 4 (input) is connected to a 20kHz and 3.3V signal and to channel 1 of the oscilloscope; and
Pin 2 (output) is connected to channel 2 of the oscilloscope.
My goal is to use interrupts and generate a signal on pin 2 (output) that follows the variations of the signal on pin 4 (input).
The image below illustrates two behaviors. The most frequent and the other one that happens occasionally.
In the first behavior, the latency is around 3 us, but sometimes there is a variation (jitter) and the rise of the output signal takes 15 us or even more to keep up with the input.
I would like to know how to remove this occasional behavior and keep the system stable.
The code that I'm using is below. To compile and upload I am using the latest Arduino IDE version 1.8.13.
I'm using GPIO.out_w1ts and GPIO.out_w1tc because I believe it will be faster than using digitalWrite(pin, state).
Also notice that I'm not reading the state of pin 4 (input) to be faster, because of this, sometimes the output signal gets inverted, but that's not a problem at this point.
#define OUTPUT_PIN 2
#define INPUT_PIN 4
volatile bool state = false;
void IRAM_ATTR interruptFunction() {
if (state)
GPIO.out_w1ts = 0b100;
else
GPIO.out_w1tc = 0b100;
state = !state;
}
void setup() {
pinMode(INPUT_PIN, INPUT);
attachInterrupt(digitalPinToInterrupt(INPUT_PIN), interruptFunction, CHANGE);
gpio_config_t io_conf;
io_conf.mode = GPIO_MODE_OUTPUT;
io_conf.pin_bit_mask = 0b100;
gpio_config(&io_conf);
}
void loop() {
}
The settings used in the Arduino IDE are illustrated in the next image.
Thanks in advance for all the help!
I am trying to wire up a simple switch to an Arduino, as per the code below, for use in a model trainset.
When the buttonState is high, Serial.print(buttonState) shows 111111111, however, the problem I have is when buttonState should be low: Serial.print(buttonState) "flickers" between 0 and 1 like so: 000111100000101000111001.
Why is it doing this and how do I stop it? I assumed it was connections but when I simply use a wire between the 2 ports, plugging it in for on and unplugging for off I still get this issue.
int RED=6;
int YELLOW=5;
int GREEN=3;
int relaytrig = 10; // trigger on pin 10
int powertoswitch = 9; // powertoswitch
int buttonPin = 12; // switch the button comms with
int buttonState = 0;
void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
// inputs
// switch input
pinMode(buttonPin,INPUT);
// outputs
// powerforswitch
pinMode(powertoswitch,OUTPUT);
// track power
pinMode(relaytrig, OUTPUT);
//signal outputs
pinMode(RED,OUTPUT);
pinMode(YELLOW,OUTPUT);
pinMode(GREEN,OUTPUT);
}
void loop() {
// put your main code here, to run repeatedly:
digitalWrite(powertoswitch,HIGH);
buttonState = digitalRead(buttonPin);
if (buttonState == HIGH) {
digitalWrite(relaytrig,LOW);
digitalWrite(GREEN,LOW);
digitalWrite(RED,HIGH);
digitalWrite(YELLOW,LOW);
Serial.print(buttonState);
} else if (buttonState == LOW) {
digitalWrite(relaytrig,HIGH);
digitalWrite(GREEN,HIGH);
digitalWrite(RED,LOW);
digitalWrite(YELLOW,LOW);
Serial.print(buttonState);
}
}
Unplugging it leaves the input pin floating, and noise etc. can make a floating input pin take any value.
Depending on your connection, you need a pull-down or a pull-up resistor on the pin to make it a 1 or a 0 when nothing is connected to it.
From the code, I assume the switching wire is between 5 V (or 3.3 V for some Arduinos) and an input pin. If I'm right, you need to put a, say, 10 kΩ resistor from that input pin to ground. This will keep it 0 when there is no wire connected.
BTW you are using an IO pin (9 aka powertoswitch) to provide the plus for the switch; there's no need and you shouldn't.
Connect one end of the switch to 5 V (or 3.3 V for some Arduinos), and the other end to the input pin. Connect the input pin with the resistor to ground (GND).
There's a picture here, but they use pin 2 as the input pin, and you use pin 12.
Also, your button or wire may need debouncing, but that is another matter.
I want to make a device like Knocki(https://knocki.com), which essentially is a relay control using a vibration sensor. i can detect vibrations rn but the problem is, once i knock the relay blinks on and then turns off. i understand this is a lack of programming that is causing this. could someone help me write code which makes it so that when i knock the relay is turned on indefinitely; until I knock again to turn relay off.
And yes u can probably tell that this code is copied from somewhere(https://wiki.keyestudio.com/Ks0068_keyestudio_37_in_1_Sensor_Kit_for_Arduino_Starters#Project_21:_Vibration_Sensor).I took it from the home page of the vibration sensor. the code was initially so that every time i knocked, the onboard Arduino led lit up. Also, right now the relay is blinking faintly every time i knock(Although correctly,in sync with my knocks)
#define SensorLED 13
#define SensorINPUT 3 //Connect the sensor to digital Pin 3 which is Interrupts 1.
unsigned char state = 0;
int Relay = 5;
void setup()
{
pinMode(SensorLED, OUTPUT);
pinMode(SensorINPUT, INPUT);
attachInterrupt(1, blink, FALLING);// Trigger the blink function when the falling edge is detected
}
void loop()
{ if(state!=0)
{
state = 0;
digitalWrite(SensorLED,HIGH);
delay(500);
digitalWrite(Relay,HIGH);
}
else
digitalWrite(SensorLED,LOW);
digitalWrite(Relay,lOW);
}
void blink()//Interrupts function
{ state++;
Yes its in your code: The (bad) example works only because there is a
digitalWrite(SensorLED,HIGH);
->>> delay(500);
a delay for 1/2 sec to keep the led on.So as a check put an other delay after the relay line and it should go on for 1/2 sec too (so the led is lit 1 sec in total)
digitalWrite(SensorLED,HIGH);
delay(500);
digitalWrite(Relay,HIGH);
delay(500);
Thats just for checking -> NEXT STEP:
Get rid of the delays (see blinkwithoutdelay example in
Arduino->File->Examples->2.Digital -> blinkwithoutdelay
and introduce a second state variable e.g.
bool relayStateOn = false;
to get an independent on/off of the relay and the led.(If thats - what I understand -what you want to do)
If you feed your relay from the board, that is not the problem. Please, check the voltage in your relay when you try to set it on, if your voltage falls down, it means that this output to your relay does not supply the necessary current.
Currently, my code below turns on the motor, delays for a bit then starts again. This is all being done in the clockwise direction, however how can I write my code so it can turn counter-clockwise?
int motorPin = 3;
void setup()
{
pinMode(motorPin, OUTPUT);
}
void loop()
{
startStopMotor(135);
delay(1000);
startStopMotor(0);
delay(1000);
}
void startStopMotor(int speed){
analogWrite(motorPin, speed);
}
By the code you share i'am guessing you are running a low power 5v dc motor... but you should edit your answer to give us what type of hardware you are using. This is not an answer but an idea of what you should be looking for... Basically on the motor i suppose you have, you have pin 1 and pin 2. Pin 1 is connected to a PWM signal and pin 2 is connected to ground. This configuration allows you to run your motor clock'wise. To run your motor counter clock'wise you need to invert the direction of the current basically have pin 1 connected to ground and pin 2 connected to a PWM signal.
Now there are multiple ways of doing this, i am unsure of the exact code to do this on an arduino but your pin 1 and 2 will be connected each to a PWM pin. In the code you will need to tell the arduino to put Pin 1 or 2 as a pullDown pin which basically mimics a ground thus telling the direction the other pin will output a PWM
this is not example code but it will give you an idea of what it should look like
void loop(){
//move clock'wise
pin1.pullup();
pin2.pulldown();
analogWrite(pin1, 180);
//move counterclock'wise
pin2.pullup();
pin1.pulldown();
analogWrite(pin2, 180);
}
I'm having a bit of trouble with my Arduino when I try and use long wires to a switch.
If I use a shorter wire I have no problems, but as soon as they are extended, things start playing up.
What I'm trying to do is, when I press a button I would like it to output to a pin, stay on for 2 seconds, then turn off regardless whether the button is still pressed or not.
The code I use at the moment that does work with short wires is:
// constants won't change. They're used here
// to set pin numbers:
const int buttonPin = 2; // the number of the pushbutton pin
const int ledPin = 10; // the number of the LED pin
// variables will change:
int buttonState = 0; // variable for reading the pushbutton status
void setup() {
// initialize the LED pin as an output:
pinMode(ledPin, OUTPUT);
// initialize the pushbutton pin as an input:
pinMode(buttonPin, INPUT);
}
void loop() {
// read the state of the pushbutton value:
buttonState = digitalRead(buttonPin);
// check if the pushbutton is pressed.
// if it is, the buttonState is HIGH:
if (buttonState == HIGH) {
// turn LED on:
digitalWrite(ledPin, HIGH);
delay(2000); // wait for a second
digitalWrite(ledPin, LOW);
}
}
I've been reading on forums that using debounce may solve this problem. However I'm new to Arduino and not sure how to implement this.
I used the Arduino button tutorial and used a 10k pull down resistor as stated. Is there any way I can allow, either with code or with a resistor / cap, to trigger via a switch that has a wire length of <2m?
Any help appreciated.
Wire length is not going to be an issue here. You either have a wiring fault or your code doesn't match your expected behaviour. (You didn't mention what the actual behaviour is right now.)
Additional debouncing of the switch won't be necessary since after you detect a button press, you are ignoring its state for some time. That is what software debouncing typically is.
stay on for 2 seconds, then turn off regardless whether the button is still pressed or not.
Right now the output will not turn off until you release the button. The reason for this is that after you write it low, you immediately check the button again and write the output high if it's still pressed. You either need to put a delay below
digitalWrite(ledPin, LOW);
or be a little fancier and make sure the button is released before you allow another press.