while loop in arduino refuse to work (simple prog) - arduino

Im writing a basic program that take 20 mms and control the on and off of the small light in the motherboard.
But the it always shows me an error
Can please someone help me fix it?
void setup() {
pinMode(13, OUTPUT);
}
int cycle = 1;
int time_t=20;
int time_on = 0;
int time_off= (time_t-time_on);
int big=0.05;
while (cycle<=100) {
if (cycle%10==0) {
time_on=time_t*big;
time_off= time_t-time_on;
big=big+0.05;
}
digitalWrite(13, HIGH);
delay(time_on);
digitalWrite(13, LOW);
delay(time_off));
cycle++;
}

The arduino program syntax specifies that a program consists of two functions setup() and loop(). Hence the part to be repeated again and again must be written inside the loop function. So your code Will go inside a void function named loop. And it becomes :
void loop(){
while (cycle<=100) {
if (cycle%10==0) {
time_on=time_t*big;
time_off= time_t-time_on;
big=big+0.05;
}
digitalWrite(13, HIGH);
delay(time_on);
digitalWrite(13, LOW);
delay(time_off));
cycle++;
}
Arduino reference :
http://arduino.cc/en/Reference/Loop

i've not used this language yet but i see an issue with "int big=0.05;" you're trying to assign a floating point value to an integer. should it be a double, float or similar data type? and then inside the while loop you have
time_on=time_t * big;
once again you are trying to multiply an integer with a floating point value and assign that back to an integer. the result being the value of time_on will be some rounded version of time_t times big. the value of time_on will only change as the value of big approaches or equals 1. and the value of big will always equal 0. you need to change your big and time_on variables to floating point data types.

Related

Arduino timer not counting accuratly

I am working on a school project for which I rotate a servo after a cable disconnects and a specific delay is over. This is my current code. We are using an Arduino Uno powered from the USB port
#include <Servo.h>
int reader=4;
int servo1Pin=8;
Servo servo1;
int value;
int pos=10;
int wacht=5000;
void setup() {
pinMode(reader, INPUT);
servo1.attach(servo1Pin);
}
void loop() {
value = digitalRead(reader);
servo1.write(pos);
if (value == LOW) {
delay(wacht);
pos=180;
}
else {
pos=10;
}
}
wacht is the specific delay. When we disconnected pin 4 to break that circuit we don't have a consistent time between the interruption of the power flow and the opening of the servo. It seems to vary from anywhere between 5 to 40 seconds of delay after triggering. Does anyone have any ideas to solve this issue?
try change
pinMode(reader, INPUT);
to
pinMode(reader, INPUT_PULLUP);
And for clarification delay don't use timer.
The order of your instructions seem strange. the usual order is:
Read
Decide
Act
Also, you may want to avoid sending useless instructions to the servo. For example, when you know the servo is already in the correct position. You should not rely on eternal code to do the right thing. In other terms, you have no idea how long servo1.write() takes to execute.
Which would give for your loop()
void loop()
{
if (digitalRead(reader) == LOW)
{
if (pos != 180)
{
delay(wacht); // delay() is only called once, when circuit breaks.
// this guarantees immediate response when circuit
∕/ closes again.
pos = 180;
servo1.write(pos);
}
}
else if (pos != 10)
{
pos = 10;
servo1.write(pos);
}
}
Also, have a look and implement Peter Plesník's answer. This will probably solve some of your problems. You input will definitely still have a random lag of up to 5 seconds when closing the circuit, though.

Trying to build a counter/stopwatch with arduino. is this wired correctly?

i am trying to make a stopwatch and counter project for arduino. Code aside, is this wired correctly?
The top button is to start the stopwatch, second is the button to start the counter (every press increases by one), and the bottom button should be to reset any of them. the green light is to show the stopwatch is selected and blue is to show the counter is selected. the lcd is to display everything obviusly. Also, what is the best way to learn to code this and how long would it take? Thanks.
This is the code as per your requirement. I have defined pins as per above connections. counter mode has minutes and seconds and it does not contain milliseconds as I am encountering problem to implement it. You can suggest me if you have got any way. Counter mode selection button is the same button which is going to be used to increment the counter.
#include <LiquidCrystal.h>
LiquidCrystal mylcd(7,6,5,4,3,2);
int counter_sel=12,stopwatch_sel=11,reset1=10,stopwatch_led=9,counter_led=8;
void setup()
{
mylcd.begin(16,2);
mylcd.setCursor(0,0);
mylcd.print("Counter and ");
mylcd.print("Stopwatch");
delay(1000);
pinMode(counter_sel,INPUT);
pinMode(stopwatch_sel, INPUT);
pinMode(reset1, INPUT);
pinMode(counter_led,OUTPUT);
pinMode(stopwatch_led, OUTPUT);
}
void loop()
{ int state1=digitalRead(counter_sel);
int state2=digitalRead(stopwatch_sel);
if (state1==0) {delay(300); counter(); } // call counter function
else if (state2==0) {delay(300); stopwatch(); } // call stopwatch function
}
void counter()
{ mylcd.clear();
digitalWrite(counter_led,1);
mylcd.setCursor(0,0);
mylcd.print("Counter Mode :");
short int i=0;
while(1)
{
int rst=digitalRead(reset1);
if (rst==0) { delay(300); break;}
int state1=digitalRead(counter_sel);
if (state1==0) { i++; delay(200);}
mylcd.setCursor(0,1);
mylcd.print(i);
}
digitalWrite(counter_led,0);
}
void stopwatch()
{
mylcd.clear();
digitalWrite(stopwatch_led,1);
long int ms=millis();
byte sec=0, mins=0;
mylcd.setCursor(0,0);
mylcd.print("Stopwatch Mode : ");
while(1)
{
mylcd.setCursor(0,1);
int state1=digitalRead(reset1);
if (state1==0){delay(300); break; }
if (sec==59) {mins++; sec=0;}
if ((millis()-ms)>1000) {sec++; ms=millis(); }
mylcd.print(mins);
mylcd.setCursor(3,1);
mylcd.print(":");
mylcd.setCursor(5,1);
mylcd.print(sec);
mylcd.print(":");
//mylcd.print(millis()-ms);
}
digitalWrite(stopwatch_led,0);
}
As much as I can see, and considering what you explained above, the connections are correct. But the thing is you need to make it clear as much as you can, because due to intersecting point in LCD connection, it would be very much harder to debug and resolve the connection problem, for that you must make it neat. To learn to code this stuff there is no rocket science, just use your wisdom, and start reading books, blogs, articles on arduino ide(which is too simple too use), c programming and microcontrollers , and youtube videos are the great source to learn to code, you should have handful experience of c programming, that's all.

Arduino to generate a rising waveform (sine or triangle)

I would like to apply an increasing voltage and hold to my output from my arduino UNO. I realize that the arduino does not allow me to output analog values, and thus I decided to use an R2R ladder (with R- 22kohms and 2R- 47kohms). This would allow me to convert to an analog voltage. I made use of the eight digital pins on the arduino, to set up an 8 bit R2R ladder. I am able to output a sine wave, with my current setup, but a little bit unsure on how to output a wave which goes up to the maximum value and stops. (i.e. a wave like given in the picture below).
This wave is basically a triangle wave or even a sine wave which goes up to a max value and stays there (with 200 micro second pulse duration).
I have created a visual of my circuit to better demonstrate my problem:
I also attempted my problem, by outputting a sine wave. My code is as follows:
void setup() {
//set pins 0-7 as outputs
for (int i=0; i<8; i++){
pinMode(i, OUTPUT);
}
}
void loop() {
double value =0;
int check=0; int t=0;
while(check==0){
if (value<254){
value = 127+127*sin(2*3.14*t/100);
//this sends a sine wave centered around (127/255 * 5)=2.5V
//max will reach when t=25
PORTD=value;
delayMicroseconds(4); //wait 4 micro seconds
//this means that the max value will reach at ~25*6 =150 microseconds
}
else{
value =255;
PORTD=value; //just output the max of the sine wave (i.e. 255)
delayMicroseconds(50); //delay to ensure total duration is 150+50=200 microseconds
PORTD=0; //output back a 0
check=1; //condition to exit the loop
}
t=t+1;
}
}
For some reason, the pulse generated is not exactly what I am looking for. Is there something I am doing wrong? Or is there a better implementation for something like this? Additionally, if there is something I am missing in my question, please let me know.
I realize that the arduino does not allow me to output analog values
In order to output analog values use one of the analog outputs of the Arduino.
They are marked with a ~
Here' an example from the Arduino reference:
int ledPin = 9; // LED connected to digital pin 9
int analogPin = 3; // potentiometer connected to analog pin 3
int val = 0; // variable to store the read value
void setup() {
pinMode(ledPin, OUTPUT); // sets the pin as output
}
void loop() {
val = analogRead(analogPin); // read the input pin
analogWrite(ledPin, val / 4); // analogRead values go from 0 to 1023, analogWrite values from 0 to 255
}

LED from Arduino board doesn't switch off using the click of a button

So I've been busy dealing with my programming homework during the afternoon, and I cannot seem to solve the issue in the code found below.
The exercise is that I need to toggle a LED by the press of a button. In my code, the LED goes on when I click the button, but it doesn't turn off when I click the button again.
int pinButton = 5;
int LED = 10;
int currentState;
int previousState;
void setup() {
Serial.begin(9600);
pinMode(pinButton, INPUT);
pinMode(LED, OUTPUT);
}
void toggleLed(){
if (previousState == 1 && currentState == 0){
digitalWrite(LED, HIGH);
Serial.println(currentState);
Serial.println(previousState);
delay(100);
} else {
digitalWrite(LED, LOW);
Serial.println(currentState);
Serial.println(previousState);
delay(100);
}
}
void loop() {
int currentState = digitalRead(pinButton);
if (currentState == 0 && previousState == 1) {
Serial.println("Knop is losgelaten");
toggleLed();
}
previousState = currentState;
}
I guess that in the first if statement the else code block doesn't make sense, because in this case previousState and currentState will always be 1 and 0 respectively.
Do you guys have any tips?
This Arduino is an Arduino Uno by the way.
I can see in your code, that you are not switching the light off again after you pressed the Button. It would have gone off if you would have put the if statement into a "while" statement.
EDIT: Expanded on most points to address the additional questions in the comments.
You have two different variables named currentState, a global one and one local to loop(). The global one is defined near the top of the program, not inside another function. In loop(), you start with this line:
int currentState = digitalRead(pinButton);
Because you've included the int there, this actually creates a second variable that happens to have the same name as the global one. The values of the two versions of currentState can change independently. Within loop(), every time you reference currentState, you'll be referencing the local copy. Everywhere else (like in toggleLed) will be referencing the global copy. If you just wanted to set the global one (which is what I assume you meant to do), then you need to drop the int:
currentState = digitalRead(pinButton);
This will change the global version of currentState without creating a new one.
You're not doing any debouncing, so you could see sporadic results depending upon the type of button. With many buttons and switches, the transition between on and off can be noisy. Debouncing filters out that noise. Edit: The delay in toggleLed() is probably sufficient to debounce, but usually debouncing is done before responding to a state change.
You should probably initialize previousState. Since it's a global, and globals have static storage duration, and it's not otherwise initialized, the system will ensure that it's initialized to 0. Explicit initialization would be more obvious to anyone who has to read the code, especially if they don't know all the rules of C as well. Also, you probably want to initialize it to LOW rather than 0. Which leads to my final point.
The return value of digitalRead() is HIGH or LOW. On the Uno, it probably doesn't matter that you use 1 or 0 instead of HIGH or LOW, but I believe it might matter if you ever port your code to certain other boards. The HIGH and LOW constants exist to hide details, but that helps only if you use them consistently. Using HIGH and LOW some of the time and 1 and 0 other times just makes it harder for people to understand your code, and it might cause portability problems if you ever want to try your code on a different board.
You could achieve that by reading the state of the pin defined as 'LED'. If it is in a HIGH state, turn it LOw and vice versa.
void toggleLed(){
// check if pin state is low, turn it on
if (digitalRead(LED) == 0)
digitalWrite(LED, HIGH);
} else {
digitalWrite(LED, LOW);
}
}

Repeat blink sketch for a specified time

I need help with an Arduino sketch , I want to repeat the blink sketch for a specified amount of time (3minutes for example) , then Stop .As we know , the loop() keeps runing forever which is not what I want . Any ideas how I can achieve this , blinking an LED for X minutes and Stopping ?
You should probably make use of some timer library. A simple (maybe naive) way to achieve what you want to do is to make use of a boolean that is set to 0 when 3 minutes has passed or simply digitalWrite the led to low when the timer has passed.
Check this link:
http://playground.arduino.cc/Code/Timer
I suggest that you use int after(long duration, callback).
Below is a (very) simple example of how you probably could do:
#include "Timer.h"
Timer t;
LED = 1;
void setup() {
int afterTime = t.after(180000, cancelLED);
}
void loop() {
t.update();
if(LED) {
//The "write HIGH" statement in your sketch here.
}
else {
//Write the led to LOW
}
}
void cancelLED() {
LED = 0;
}
I haven't used the library myself, I just checked the the docs and wrote an example to give you some ideas. Don't expect it to work right away.

Resources