debounce with two button to turn on different leds with Arduino - c

I want to make debounce for two buttons. So turn on Red led or Green led knowing which button have pressed My program only works for 1 button.
I think that I need a array for two several buttons.
Could anyone help me to improve my code two buttons or more ?
int boton = 11;
int led = 13;
boolean estadoAnterior = LOW;
boolean estadoActual = LOW;
boolean ledOn = false;
int cont=0;
void setup()
{
pinMode(boton, INPUT);
pinMode(led, OUTPUT);
Serial.begin(9600);
}
boolean rebote(boolean eAnterior)
{
boolean eActual = digitalRead(boton);
if (eAnterior != eActual)
{
delay(5);
eActual = digitalRead(boton);
}
return eActual;
}
void loop()
{
estadoActual = rebote(estadoAnterior);
if (estadoAnterior == LOW && estadoActual == HIGH)
{
ledOn = !ledOn;
cont++;
Serial.println(cont);
}
estadoAnterior = estadoActual;
digitalWrite(led, ledOn);
}

Overall, using a busy-delay is a rather crude way to de-bounce buttons, but it will work for hobbyist purposes.
Change estadoAnterior into an array of expected button states.
Make an array of ints for the button pins boton. (In real MCU programming, this would be an array of ports + masks.)
In the debounce function, make an array of de-bounce bool values for buttons that need debouncing. Check which ones that need debouncing in a loop.
If any button needed debouncing, wait 5ms. Not per button, but once. (Btw 5ms may or may not be enough depending on button type)
Read that button again and use the result.
A more professional approach might be something along the lines of this.
Once done, rewrite all identifiers to English. We don't use our native language when programming, because that turns the source code into a mess. Your code is some mix of English and your native language, it is very hard to read.

Related

Sound Sensor RGB LED coding

So we connected a sound sensor to our board to light up our LED light when sound is heard, it kinda works but there some hiccups.
We tried messing with the code for a while but no matter what we do the senor will only react to loud even when we put in a threshold. If you see in the picture, it it only displaying "loud" noise to the display and cant seem be able to go to the other condition we set in our threshold. We configure the sensor with our screw driver but nothing seem to work. Our code is below & before we continue on, we wanted to know if there a problem with it that can fix out the issue,thanks you
ALSO the sound sensor is a "ko9A01"
PS: we use "energia" to code this.
#include <msp430.h>
#include <Wire.h>
int soundsensor = 2;
int led = 3;
void setup()
{
Serial.begin(9600);
Serial.println("Begin Test");
pinMode(soundsensor,OUTPUT);
pinMode(led,OUTPUT);
}
void loop()
{
int sensorValue = digitalRead(soundsensor);
Serial.println(sensorValue);
delay(250);
if (sensorValue == 1)
{
Serial.print("LOUD");
digitalWrite(led,HIGH);
}
else
{
Serial.print("QUIET");
digitalWrite(led,LOW);
}
}
EDIT: NOW With the help of Brydon we change the output to input and change it to this we change it to this and now we get this new error voi
void setup()
{
Serial.begin(9600);
Serial.println("Begin Testing");
pinMode(soundsensor,INPUT);
}
and it only show
"begin test":
0 and wont move from there
You have the sound sensor configured as an OUTPUT in the setup.
I assume you want it to be an input? That would be the case if you're reading values from it.
I can't tell what sensor you have - but with more information on the sensor, we can read the documentation and help you configure the inputs appropriately (ie a threshold)

Embedded C programming: Clearing LCD properly

I am trying to write the code for an embedded board (RX63N)in which I want to use the LCD along with the on board switches for the following functionality:
On pressing the switch the program should "pause" or "unpause" depending on the previous state and the LCD should display "paused" when it is paused. On unpausing, the LCD should display the custom graphics at the position defined by x and y. It is displayed using the function Set_LCD_Char(N) where N is defined as a custom graphic from a bitmap image. But I will need to clear the LCD before making any changes and that is where I am struggling. On using lcd_clear() function anywhere in the while keeps the LCD blank (or almost blank i.e. the text and graphics are so faint that they are as good as absent) Can someone please help me? heres the code:
while (1)
{
// lcd_clear();
if(g_sw3_press == true){ //detect switch press
pause_flag = !pause_flag;
g_sw3_press = false; //reset switch
}
if (pause_flag){
RESET_ALL_LEDS();
jet_x = 0;
jet_y = 0;
Set_Font_Bitmap(); //changes from text mode to bitmap
Set_LCD_Pos(jet_x,jet_y);
Set_LCD_Char(3);
}
else if(!(pause_flag)){
ALL_RED_LEDS_ON();
Set_Font_8_by_8();
lcd_display(LCD_LINE1, " PAUSED ");
}
}
Firstly, it's generally not a good idea to do a busy polling loop as you are doing. But I can't recommend any concrete alternatives as platform and OS (if any) have not been provided (perhaps your platform has no support for events).
Anyway, not sure if this is the answer you need. But since you ask for an example and I can't effectively put code into the comments, below is what I mean. The problem is that you are continuously writing and clearing the LCD. So in effect the two operations are competing with each other. So one way to solve this is to only update the LCD when the state changes.
while (1)
{
if(g_sw3_press == true){ //detect switch press
pause_flag = !pause_flag;
g_sw3_press = false; //reset switch
} else {
/* No state change - nothing to do. Poll again. */
continue;
}
lcd_clear();
if (pause_flag){
RESET_ALL_LEDS();
jet_x = 0;
jet_y = 0;
Set_Font_Bitmap(); //changes from text mode to bitmap
Set_LCD_Pos(jet_x,jet_y);
Set_LCD_Char(3);
} else {
ALL_RED_LEDS_ON();
Set_Font_8_by_8();
lcd_display(LCD_LINE1, " PAUSED ");
}
}

Problems with Arduino remotely controlling an outlet

This is a project that will be turned in, in 8 hours! We are stuck with this problem and thought of this place as a kind of last resort.
I'm trying to turn on/off a remotely controlled outlet with an Arduino.
We get inconsistencies when doing so. Sometimes when it goes into the if statement that ”should be ON” but instead turns the power off of the outlet and vice versa.
Code:
// on off remote control
int off = 12;
int on = 13;
void setup() {
pinMode(off, OUTPUT); // sets the digital pin as output
pinMode(on, OUTPUT);
}
void loop() {
// ..first we getting response from server if remote control should be on/off,
// working fine so not really relevant to problem.
// then we determine if outlet should be ON or OFF:
response.toCharArray(responseCharArray,100);
if(strstr( responseCharArray, "active") && strstr( responseCharArray, "1")) {
// This should turn ON the outlet.
digitalWrite(on, HIGH);
delay(250);
digitalWrite(on, LOW);
Serial.println("should be ON");
}
else if(strstr( responseCharArray, "active") && strstr( responseCharArray, "0")) {
// This should turn OFF the outlet.
digitalWrite(off, HIGH);
delay(250);
digitalWrite(off, LOW);
Serial.println("should be OFF");
}
}
Picture of the wiring:
Question:
What could be missing here? Since it randomly turns it on/off while entering same if statement.
There is too little information here.
Notice that your code will trigger (turn on) if responseCharArray contains something like e.g. "retroactively from 1941", or turn off for something like "active for 37 seconds".
In other words, that string-matching is not very precise, but it's hard to know what it should be since I don't know anything about the format of the response.
Perhaps it should at least be
if(strstr(responseCharArray, "active=1") != NULL)
or something, to at least lock the 1 to the active part.
In the logging that you do, print out the value of responseCharArray too. This will let you analyze whether or no the decision-making made sense.
Also, as always, triple-check your wiring and watch for e.g. back-feeding.

how to stop a loop arduino

I have this loop, how would I end the loop?
void loop() {
// read the pushbutton input pin:
a ++;
Serial.println(a);
analogWrite(speakerOut, NULL);
if(a > 50 && a < 300){
analogWrite(speakerOut, 200);
}
if(a <= 49){
analogWrite(speakerOut, NULL);
}
if(a >= 300 && a <= 2499){
analogWrite(speakerOut, NULL);
}
This isn't published on Arduino.cc but you can in fact exit from the loop routine with a simple exit(0);
This will compile on pretty much any board you have in your board list. I'm using IDE 1.0.6. I've tested it with Uno, Mega, Micro Pro and even the Adafruit Trinket
void loop() {
// All of your code here
/* Note you should clean up any of your I/O here as on exit,
all 'ON'outputs remain HIGH */
// Exit the loop
exit(0); //The 0 is required to prevent compile error.
}
I use this in projects where I wire in a button to the reset pin. Basically your loop runs until exit(0); and then just persists in the last state. I've made some robots for my kids, and each time the press a button (reset) the code starts from the start of the loop() function.
Arduino specifically provides absolutely no way to exit their loop function, as exhibited by the code that actually runs it:
setup();
for (;;) {
loop();
if (serialEventRun) serialEventRun();
}
Besides, on a microcontroller there isn't anything to exit to in the first place.
The closest you can do is to just halt the processor. That will stop processing until it's reset.
Matti Virkkunen said it right, there's no "decent" way of stopping the loop. Nonetheless, by looking at your code and making several assumptions, I imagine you're trying to output a signal with a given frequency, but you want to be able to stop it.
If that's the case, there are several solutions:
If you want to generate the signal with the input of a button you could do the following
int speakerOut = A0;
int buttonPin = 13;
void setup() {
pinMode(speakerOut, OUTPUT);
pinMode(buttonPin, INPUT_PULLUP);
}
int a = 0;
void loop() {
if(digitalRead(buttonPin) == LOW) {
a ++;
Serial.println(a);
analogWrite(speakerOut, NULL);
if(a > 50 && a < 300) {
analogWrite(speakerOut, 200);
}
if(a <= 49) {
analogWrite(speakerOut, NULL);
}
if(a >= 300 && a <= 2499) {
analogWrite(speakerOut, NULL);
}
}
}
In this case we're using a button pin as an INPUT_PULLUP. You can read the Arduino reference for more information about this topic, but in a nutshell this configuration sets an internal pullup resistor, this way you can just have your button connected to ground, with no need of external resistors.
Note: This will invert the levels of the button, LOW will be pressed and HIGH will be released.
The other option would be using one of the built-ins hardware timers to get a function called periodically with interruptions. I won't go in depth be here's a great description of what it is and how to use it.
The three options that come to mind:
1st) End void loop() with while(1)... or equally as good... while(true)
void loop(){
//the code you want to run once here,
//e.g., If (blah == blah)...etc.
while(1) //last line of main loop
}
This option runs your code once and then kicks the Ard into
an endless "invisible" loop. Perhaps not the nicest way to
go, but as far as outside appearances, it gets the job done.
The Ard will continue to draw current while it spins itself in
an endless circle... perhaps one could set up a sort of timer
function that puts the Ard to sleep after so many seconds,
minutes, etc., of looping... just a thought... there are certainly
various sleep libraries out there... see
e.g., Monk, Programming Arduino: Next Steps, pgs., 85-100
for further discussion of such.
2nd) Create a "stop main loop" function with a conditional control
structure that makes its initial test fail on a second pass.
This often requires declaring a global variable and having the
"stop main loop" function toggle the value of the variable
upon termination. E.g.,
boolean stop_it = false; //global variable
void setup(){
Serial.begin(9600);
//blah...
}
boolean stop_main_loop(){ //fancy stop main loop function
if(stop_it == false){ //which it will be the first time through
Serial.println("This should print once.");
//then do some more blah....you can locate all the
// code you want to run once here....eventually end by
//toggling the "stop_it" variable ...
}
stop_it = true; //...like this
return stop_it; //then send this newly updated "stop_it" value
// outside the function
}
void loop{
stop_it = stop_main_loop(); //and finally catch that updated
//value and store it in the global stop_it
//variable, effectively
//halting the loop ...
}
Granted, this might not be especially pretty, but it also works.
It kicks the Ard into another endless "invisible" loop, but this
time it's a case of repeatedly checking the if(stop_it == false) condition in stop_main_loop()
which of course fails to pass every time after the first time through.
3rd) One could once again use a global variable but use a simple if (test == blah){} structure instead of a fancy "stop main loop" function.
boolean start = true; //global variable
void setup(){
Serial.begin(9600);
}
void loop(){
if(start == true){ //which it will be the first time through
Serial.println("This should print once.");
//the code you want to run once here,
//e.g., more If (blah == blah)...etc.
}
start = false; //toggle value of global "start" variable
//Next time around, the if test is sure to fail.
}
There are certainly other ways to "stop" that pesky endless main loop
but these three as well as those already mentioned should get you started.
This will turn off interrupts and put the CPU into (permanent until reset/power toggled) sleep:
cli();
sleep_enable();
sleep_cpu();
See also http://arduino.land/FAQ/content/7/47/en/how-to-stop-an-arduino-sketch.html, for more details.
just use this line to exit function:
return;

How to set an int to 1 if dependent on a button and in a while loop?

I'm programming a robot, and unfortunately in its autonomous mode I'm having some issues.
I need to set an integer to 1 when a button is pressed, but in order for the program to recognize the button, it must be in a while loop. As you can imagine, the program ends up in an infinite loop and the integer values end up somewhere near 4,000.
task autonomous()
{
while(true)
{
if(SensorValue[positionSelectButton] == 1)
{
positionSelect = positionSelect + 1;
wait1Msec(0350);
}
}
}
I've managed to get the value by using a wait, but I do NOT want to do this. Is there any other way I can approach this?
assuming that the SensorValue comes from a physical component that is asynchronous to the while loop, and is a push button (i.e. not a toggle button)
task autonomous()
{
while(true)
{
// check whether
if(current_time >= next_detect_time && SensorValue[positionSelectButton] == 1)
{
positionSelect = positionSelect + 1;
// no waiting here
next_detect_time = current_time + 0350;
}
// carry on to other tasks
if(enemy_is_near)
{
fight();
}
// current_time
current_time = built_in_now()
}
}
Get the current time either by some built-in function or incrementing an integer and wrap around once reach max value.
Or if you are in another situation:
task autonomous()
{
while(true)
{
// check whether the flag allows incrementing
if(should_detect && SensorValue[positionSelectButton] == 1)
{
positionSelect = positionSelect + 1;
// no waiting here
should_detect = false;
}
// carry on to other tasks
if(enemy_is_near)
{
if(fight() == LOSING)
should_detect = true;
}
}
}
Try remembering the current position of the button, and only take action when its state changes from off to on.
Depending on the hardware, you might also get a signal as though it flipped back and forth several times in a millisecond. If that's an issue, you might want to also store the timestamp of the last time the button was activated, and then ignore repeat events during a short window after that.
You could connect the button to an interrupt and then make the necessary change in the interrupt handler.
This might not be the best approach, but it will be the simplest.
From The Vex Robotics catalogue :
(12) Fast digital I/O ports which can be used as interrupts
So, most probably which ever micro-controller of Vex you are using will support Interrupts.
Your question is a bit vague
I m not sure why u need this variable to increment and how things exactly work...but i ll make a try.Explain a bit more how things work for the robot to move...and we will be able to help more.
task autonomous()
{
int buttonPressed=0;
while(true)
{
if(SensorValue[positionSelectButton] == 1)
{
positionSelect = positionSelect +1;
buttonPressed=1;
}
else{
buttonPressed = 0;
}
//use your variables here
if( buttonPressed == 1){
//Move robot front a little
}
}
}
The general idea is :
First you detect all buttons pressed and then you do things according to them
All these go in your while loop...that will(and should) run forever(at least as long as your robot is alive :) )
Hope this helps!

Resources