I got a short time ago an Arduino Kit, and i am trying a little project. Using a Sound sensor i want to sequentially turn on 3 leds. Meaning one clap turns LED1, then a second one the second one and so on. Problem is that this happens only for LED 1 and LED2, and without waiting for the third clap the third LED turns on and without a 4th clap the lights go off, even though i am counting them and resetting the value from the sensor.
I cannot understand why this code works for the first and second Leds but the 3rd and 4th stages are going automatically .
Thanks!
I tried the following code, but it works only for the first and second LED, when the counter is 0 and 1, when it reaches 2, or 3 it activates even though i am not activating the sensor.
int soundSensor=2;
int LED1=4;
int LED2=5;
int LED3=6;
int counter =0;
int SensorData=0;
void setup() {
Serial.begin(9600);
pinMode(soundSensor,INPUT);
pinMode(LED1,OUTPUT);
pinMode(LED2,OUTPUT);
pinMode(LED3,OUTPUT);
counter = 0;
}
void loop() {
SensorData=digitalRead(soundSensor);
if(SensorData==1 && counter == 0){
digitalWrite(LED1,HIGH);
counter++;
SensorData=2;
delay(1000);
}
if(SensorData==1 && counter == 1){
digitalWrite(LED2,HIGH);
counter++;
SensorData=2;
delay(1000);
}
if(SensorData==1 && counter == 2){
digitalWrite(LED3,HIGH);
counter++;
SensorData=2;
delay(1000);
}
if(SensorData==1 && counter == 3){
digitalWrite(LED1,LOW);
digitalWrite(LED2,LOW);
digitalWrite(LED3,LOW);
counter++;
SensorData=2;
delay(1000);
counter =0;
}
}
Related
I need a motor to cycle forward, then backward when the user pushes a once. the problem is, the arduino will run in loops after it is presses and wont stop.
How can i make it only cycle through once each time the button is pushed?
Ive tried exit(0), stop_it, etc, but those just exit the loop instead of starting back up when the button is pressed another time.
const int pwm_pin = 9;
const int dir_1a_pin = 8;
const int dir_2a_pin = 7;
int buttonPin = 2;
boolean on=false;
int buttonState = 0;
void setup() {
pinMode(buttonPin, INPUT);
pinMode(pwm_pin, OUTPUT);
pinMode(dir_1a_pin, OUTPUT);
pinMode(dir_2a_pin, OUTPUT);
}
void loop() {
buttonState = digitalRead(buttonPin);
if (buttonState == HIGH){
if (on==true){
on=false;
} else{
on=true;
}
}
if(on == true){
digitalWrite(dir_1a_pin, HIGH);
digitalWrite(dir_2a_pin, LOW);
analogWrite(pwm_pin, 255);
delay (8000);
digitalWrite(dir_1a_pin, LOW);
digitalWrite(dir_2a_pin, HIGH);
analogWrite(pwm_pin, 255);
delay (12000);
}
}
You are making the logic too much complicated. Just read the button state in your loop and if it was HIGH do your motorcycle job. The next time loop runs as you haven't pressed the button it would become LOW and won't go into if statement.
const int pwm_pin = 9;
const int dir_1a_pin = 8;
const int dir_2a_pin = 7;
int buttonPin = 2;
void MotorCycle()
{
digitalWrite(dir_1a_pin, HIGH);
digitalWrite(dir_2a_pin, LOW);
analogWrite(pwm_pin, 255);
delay(8000);
digitalWrite(dir_1a_pin, LOW);
digitalWrite(dir_2a_pin, HIGH);
analogWrite(pwm_pin, 255);
delay(12000);
}
void setup()
{
pinMode(buttonPin, INPUT);
pinMode(pwm_pin, OUTPUT);
pinMode(dir_1a_pin, OUTPUT);
pinMode(dir_2a_pin, OUTPUT);
}
void loop()
{
// if button pressed
if (digitalRead(buttonPin) == HIGH)
{
MotorCycle();
}
}
I assume that the part you want to run once is in the section at the end in the if(on == true) section. If you don't want that to repeat, then how about setting on to false in that section. Then next time loop repeats it won't go into that section.
I'm having some trouble with my arduino code and I need help making it work, it is going to be used to control some LED lights. Brighten, darken, blink, and make them run.
I have added comments all over the script so you can read the problems and so on.
/*This script is supposed to make a arduino board control the lights on a lego creation for a school project.
Button1 should make lights brighter
Button2 should make ligts shine less
Button3 should make the light blink
Button4 is supposed to make the light run after each other.
*/
//Setting up all the lights and buttons
const int lights[] = {9, 8, 7};
int light = 0;
const int button1 = 24;
int buttonstate1 = 0;
const int button2 = 25;
int buttonstate2 = 0;
const int button3 = 26;
int buttonstate3 = 0;
const int button4 = 27;
int buttonstate4 = 0;
int lightStrength = 50;
int blinkToggle = 0;
//Setting up the input's and output's
void setup() {
pinMode(button1, INPUT);
pinMode(button2, INPUT);
pinMode(button3, INPUT);
pinMode(button4, INPUT);
pinMode(lights[0], OUTPUT);
pinMode(lights[1], OUTPUT);
pinMode(lights[2], OUTPUT);
//Here i have a problem with make the list take all in one line of code.
analogWrite(lights[0], lightStrength);
analogWrite(lights[1], lightStrength);
analogWrite(lights[2], lightStrength);
}
void loop() {
//checking if the buttons are being pressed
buttonstate1 = digitalRead(button1);
buttonstate2 = digitalRead(button2);
buttonstate3 = digitalRead(button3);
buttonstate1 = digitalRead(button4);
//Make the lights brighter
while (lightStrength <= 235){
if (buttonstate1 == HIGH){
delay(10);
lightStrength = lightStrength + 1;
delay(10);
analogWrite(lights[0], lightStrength);
analogWrite(lights[1], lightStrength);
analogWrite(lights[2], lightStrength);
}
}
//make the lights darker
while (lightStrength >= 45){
if (buttonstate2 == HIGH){
delay(5);
lightStrength = lightStrength - 1;
delay(5);
analogWrite(lights[0], lightStrength);
analogWrite(lights[1], lightStrength);
analogWrite(lights[2], lightStrength);
}
}
//Blink the lights
while(blinkToggle == 1){
if (buttonstate3 == HIGH){
delay(100);
blinkToggle = 0;
}
}
while(blinkToggle == 0){
if (buttonstate3 == HIGH){
delay(100);
blinkToggle = 1;
}
}
while(blinkToggle == 1){
delay(150);
analogWrite(lights[0], 0);
analogWrite(lights[1], 0);
analogWrite(lights[2], 0);
delay(150);
analogWrite(lights[0], lightStrength);
analogWrite(lights[1], lightStrength);
analogWrite(lights[2], lightStrength);
}
//make the lights run (Not completed because the other code didn't work)
if (buttonstate4 == HIGH){
delay(100);
}
}
First of all, asking "need help" is kind of general.. You should definitely ask a better question. For instance I could not understand fully what you meant, what the problems are and what is the expected behavior in some cases (for instance, what happens if I press more buttons?).
Anyway this is not a comment but an answer, because there are a few general mistakes in your code, and maybe these are enough to make your code worl.
for instance, you wrote all your tests as
while (lightStrength <= 235){
if (buttonstate1 == HIGH){
Well, if your button is low then lightStrength will not be incremented, the loop will never reach its ending and so the program will be stuck in there. I suggest you to change your code into
if (buttonstate1 == HIGH){
while (lightStrength <= 235){
This will not halt your code.
Then the tests for blinkToggle are wrong. You should not test them in a while, but with an if (e.g. if(blinkToggle == 1){).
The button 4 is not implemented, and I don't understand what is its behavior, so I cannot tell you how to implement it.
I did not understand the //Here i have a problem with make the list take all in one line of code. comment. If you want to write the same value without repeating it use a for loop:
byte i;
for (i = 0; i < 3; i++)
analogWrite(lights[i], lightStrength);
And now, some advices for your program.
First of all, debouncing. If you don't know what bouncing is, look on wikipedia or search on google. Anyway I found that the Bounce2 library is very useful whenever you have to deal with buttons. Search for its examples or simply ask to see some more examples.
And.. I suggest you to change your approach in this program. A FSM (Finite State Machine) approach is more suitable for this. Even without using complicated libraries, just plain C, you can make a very solid program
I am trying to create an array and be able to compare the second to last and last item in an array. It needs to be constantly adding and comparing to work correctly. This is just a function I am trying to get running to help control a stepper motor function. I have a loop that is going to fast for me to be able to compare directly. I do know that some of it is wrong but as I haven't coded in C very much I can't figure out how to use an array correctly. Thank you in advance.
int P[10],V[10],i,x,y;
Serial.print("checkvalue = ");
Serial.print(checkvalue);Serial.print("\n");
Serial.print("P = "); Serial.print(P[i]); Serial.print("\n"); //attempting to print array
Serial.print("V = "); Serial.print(V[i]); Serial.print("\n"); //to see if it is collecting
//data correctly
//these variables are declared above in my code, just didn't copy in
Dgreadpb = digitalRead(13);
PBcheck = Dgreadpb;
//Serial.print("Button in = ");Serial.print(Dgreadpb); Serial.print("\n");
Dgreadvls = digitalRead(12);
VLScheck = Dgreadvls;
//Serial.print("Photo in = ");Serial.print(Dgreadvls); Serial.print("\n");
for (i = 0; i < 10; i++){
x = Dgreadpb;
y = Dgreadvls;
P[i] = x;
V[i] = y;
if (P[i-1] == P[i] && V[i-1] == V[i]){ //trying to compare second to
checkvalue == 0; //last term to the last term
return;
}
else if(P[i-1] != P[i] || V[i-1] != V[i]){
checkvalue == 1;
return;
}
}
delay (1000);
By "trying to compare second to last term to the last term", do you mean "Trying to compare second to last term with their previous"? If that's the case your indices are wrong, it should be for(i = 1; i<10; i++).
Also both conditions are opposite (Either both are equal or AT LEAST one of them is different), there is no need for else if. Even more, cause both conditions are opposite it will never complete the loop. I think that's not the intention, if you're trying to say that only one of them are different you should do:
if (P[i-1] == P[i] && V[i-1] == V[i]){ //If both are equal
checkvalue == 0;
return;
}
else if(P[i-1] == P[i] || V[i-1] == V[i]){ //If only one is equal
checkvalue == 1;
return;
}
Ok, then I'd make a different thing.
Looking at your comment, it looks like you want to do something like this: read the value of two pins, compare them to the last value you read and, if they are differernt, start the motor, otherwise stop it.
Now, a lot of info are missing (e.g. how do you check the motor? how often do you want to check the sensor? what sensor?) but IMHO you should do something like this.
In this code I suppose that
you want to check the sensor every 100 milliseconds
if the values differ, you want to turn on the motor for the next 100 ms
the motor is a DC motor turned on by setting the corresponding pin (e.g. 10)
the sensors have a binary output on pins 12 and 13, since you wrote that in the code
BTW I used the millis() function because I hate the delay, since it blocks the uC. Using my function you'll be able to perform other operations while it is idle.
const byte motorPin = 10;
const byte sensorPPin = 12;
const byte sensorVPin = 13;
#define LOOP_TIME_MS 100
unsigned long lastLoopTime;
boolean lastPval, lastVval;
void setup()
{
pinMode(motorPin, OUTPUT);
pinMode(sensorPPin, INPUT);
pinMode(sensorVPin, INPUT);
lastPval = digitalRead(sensorPPin);
lastVval = digitalRead(sensorVPin);
lastLoopTime = millis();
}
void loop()
{
if ((millis() - lastLoopTime >= LOOP_TIME_MS)
{
boolean Pval = digitalRead(sensorPPin);
boolean Vval = digitalRead(sensorVPin);
if ((Pval != lastPval) || (Vval != lastVval))
{
digitalWrite(motorPin, HIGH);
}
else
{
digitalWrite(motorPin, LOW);
}
lastLoopTime += LOOP_TIME_MS;
}
/* Here you can do something else */
}
EDIT: If, on the other side, you want to use arrays (because you want to test the last N values instead of just the previous one) please provide further info on what are the changing conditions (or better provide examples)
We are developing the code for the DC motor controller using AT89S51 microcontroller. We use embedded C for code development, Keil microvision as IDE, Progisp for uploading .hex files to microcontroller and PUTTY for serial interfacing.
Here is the code:
#include <reg51.h>
#include <stdio.h>
unsigned int k;
sbit motor = P1^0;
void delay ( int q ) {
int w;
for ( w = 0; w < q; w++ );
}
void next_line()
{
SBUF = 10; // go to next line
while(TI == 0);
TI = 0;
SBUF = 13; // go to the beginning of the line
while(TI == 0);
TI = 0;
}
unsigned char receive() //Function to receive serial data
{
unsigned char value;
while ( RI == 0 );
value=SBUF;
P1=value;
RI=0;
return value;
}
void start()
{
SCON=0x50;
TMOD=0x20;
TH1=0xFD;
TR1=1;
TI=1;
}
int i;
main()
{
while (1)
{
unsigned char speed = 0;
start();
speed=receive();
switch (speed)
{
case '1':
k=90; // 90 msec out of 100 msec
next_line();
break;
case '0':
k=10; // 10 msec out of 100 msec
next_line();
break;
};
for(i=0; i<100; i++)
{
if (i<k) {
motor = 0;
}
else {
motor = 1;
}
}
}
}
We expect the motor to work on 90% power when the '1' button is pressed and to switch to 10% power when the '0' button is pressed. However, what we see is that some keyboard buttons (1,4,5,8) switch the motor ON and some buttons (2,3,6,7) switch the motor OFF. I cannot understand the nature of the improper working. Please, could you help us with this issue. Thanks in advance
I am going to hazard a guess as to the problem and risk being downvoted for it. The main loop is only writing to the motor bit for a very short period of time before committing to a read of the serial port, and that motor write leaves a 1 in the control port bit no matter what duty cycle was selected, so the motor should be left either running or stopped. But OP says pressing a key either stops or runs the motor. The receive() function waits for input and then writes it to the motor port (which is not bit-defined) before returning. It's tempting to think that is what is controlling the motor, but the LSB of OP's key presses is not consistent with the motor control. So what is it? The keys that start the motor all have bit 1 clear and the keys that stop the motor all have bit 1 set. So my first guess is that OP has defined the wrong bit for motor control and that the correct declaration is
sbit motor = P1^1;
Then remove this line from the receive() function
P1 = value;
My second guess from bit 1 of the key presses is that the motor logic is inverted so that 0 runs the motor and 1 stops it. On top of that, the main loop should check for serial char input and here is my (untested!) rewrite of main()
main()
{
unsigned char speed;
int k = 10; // default is 'slow'
int i;
start(); // moved outside of loop
while (1) // repeat until power off
{
while (RI == 0) // repeat until serial data in
{
for(i=0; i<100; i++) // duty cycle
if (i<k)
motor = 1; // off: or 0x02 if required for b1
else
motor = 0; // on: I have inverted the logic
}
speed=receive(); // get key press
switch (speed)
{
case '1':
k=90; // 90 msec out of 100 msec
next_line();
break;
case '0':
k=10; // 10 msec out of 100 msec
next_line();
break;
}
}
}
Your while loop in main appears to be setting the 1-bit motor control with a 10% or 90% duty cycle, it does this by writing to motor which has been equated to P1. But after 100 writes it calls receive(), and that should leave the motor running, because the function won't return until a key is pressed. So I don't understand why the motor is sometimes stopped. When the function does return, your case statements do not take into account what other key might have been pressed, so you will be simply using k set from the previous key press. In addition, receive() waits for RXD and then writes the character received to P1 the motor control. So on the face of it, the LSB of RXD is being used to control the motor. But that's a bug, because on return from receive() P1 is again written to.
int i = 1;
void setup() {
Serial.begin(9600);
}
void loop() {
if(i == 1){
Serial.print(i);
}
i++;
}
This is intended to only print the value of i once. Why does it keep printing 1 forever?
This code works properly only writing i once:
int i = 1;
void setup() {
Serial.begin(9600);
}
void loop() {
if(i == 1){
Serial.print(i);
}
i = 2;
}
Assuming loop() is called in a loop:
i will overflow in the first example.
In the second example it is fixed to the value of 2 after the first iteration.
You may also want to add some delay because sometimes you can miss the first Serial.println();.
Something like that:
int i = 1;
void setup() {
Serial.begin(9600);
delay(1000); //wait for one second
}
Hope it helps!
If you want your first example to work longer. Change "int" to "long".
int can only store 2 bytes. -32,768 to 32,767. You will reach this number really fast.
long can store 4 bytes. -2,147,483,648 to 2,147,483,647. This will take a whiiiile.