Pages: [1]   Go Down
Author Topic: the best way to set multlple input and outputs  (Read 765 times)
0 Members and 1 Guest are viewing this topic.
0
Offline Offline
Newbie
*
Karma: 0
Posts: 34
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

hi.
i am trying to run ping, lcd and servo , i am not sure which is the best way and order to have the ping, lcd and servo in the program the way i have it right now is as follows:( i am a newbie)
Code:
// include the library code:
#include <LiquidCrystal.h>
#include <Servo.h>
#define trigPin 2
#define echoPin 3

// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(10, 11, 12, 13, 14, 15, 16);

Servo myservo;  // create servo object to control a servo                
int pos = 0;    // variable to store the servo position

void setup() {
  {
  myservo.attach(9);  // attaches the servo on pin 9 to the servo object
}
  // set up the LCD's number of columns and rows:
  lcd.begin(16, 2);
  pinMode(trigPin, OUTPUT);
  pinMode(echoPin, INPUT);
  
}

void loop()
{
  for(pos = 0; pos < 180; pos += 1)  // goes from 0 degrees to 180 degrees
  {                                  // in steps of 1 degree
    myservo.write(pos);              // tell servo to go to position in variable 'pos'
    delay(15);                       // waits 15ms for the servo to reach the position
  }
  for(pos = 180; pos>=1; pos-=1)     // goes from 180 degrees to 0 degrees
  {                                
    myservo.write(pos);              // tell servo to go to position in variable 'pos'
    delay(15);                       // waits 15ms for the servo to reach the position
  }
}


{  long duration, distance;
  lcd.setCursor(0, 1);
  digitalWrite(trigPin, LOW);  // Added this line
  delayMicroseconds(102); // Added this line
  digitalWrite(trigPin, HIGH);

  delayMicroseconds(1000); // Added this line
  digitalWrite(trigPin, LOW);
  duration = pulseIn(echoPin, HIGH);
  distance = (duration/2) / 29.1* 10;
  
    lcd.print(distance);
    lcd.print(" mm");
    delay(500);
lcd.clear();
}
the arduino seems to be unable to move the servo and the lcd goes blank (power issue ?) or a programming issue any help would appreciated.

thanks Chilliman smiley-sad
« Last Edit: March 30, 2013, 03:52:09 pm by chilliman » Logged

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 601
Posts: 48543
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

The code you posted won't even compile. You have code outside of the loop() function. When you fix that, the missing functionality might appear.

How are you powering the servo? Not from the Arduino, I hope.
Logged

UK
Offline Offline
Shannon Member
****
Karma: 222
Posts: 12541
-
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

the program the way i have it right now is as follows

You need to put your code in [ code ] [ /code ] tags to stop the forum software munging it. You can fix that by editing your post, selecting all the code and clicking the # button in the edit window to add the tags.
Logged

I only provide help via the forum - please do not contact me for private consultancy.

0
Offline Offline
Newbie
*
Karma: 0
Posts: 34
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

sorry about the code i have changed it now could you please look at it

thanks

chilliman
Logged

USA, FL
Offline Offline
God Member
*****
Karma: 14
Posts: 688
A life? Where can I download one of those?
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

See PaulS' reply.
Logged

//LiNK

0
Offline Offline
Newbie
*
Karma: 0
Posts: 34
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

thanks guys u will check it out over the next few day.
those curly brackets are going to drive me crazy i through i had them right

thanks chilliman smiley
   
Logged

Pittsburgh, PA, USA
Offline Offline
Faraday Member
**
Karma: 93
Posts: 4743
I learn a bit every time I visit the forum.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

thanks guys u will check it out over the next few day.
those curly brackets are going to drive me crazy i through i had them right

thanks chilliman smiley
   

Some tips and techniques will help you there.

1) as you write the sketch, us the Autoformat tool -often-. It will take care of indents for you -if- your braces match up and tell you when they don't. If you don't put in a mass of the things before autoformat then you should have a real good idea where to look when one try doesn't work and the last one did.

2) every so often save your code that has compiled even if you select all, copy and paste to an editor. Put the date and time in each version. Keep them in an easy to find folder and you can back trace your progress.

3) When you code a function, put the braces { } on their own lines. It's easier to find and match them when the open and close are indented the same, easier on the eyes and quicker too.

Code:
void setup()
{
}

void loop()
{
}


Code:
void setup() {
}

void loop() {
}

The second way takes less lines and enter key hits but 3 or 4 indents in and a couple of screens long your eyes won't have it so easy finding line ends to check for { and then back to find the }. It may be nothing when you're young but it gets older as you get older.
Logged

I find it harder to express logic in English than in Code.
Sometimes an example says more than many times as many words.

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 601
Posts: 48543
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Also, when you type an if, while, for, or other statement that should have curly braces, add both curly braces right away. Then, go back and add the code between the braces.
Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 34
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Thanks all for the tips ,i shall remember them, is there a right way to add multiple input and out that you what to happen at the same time i.e . what order etc.

thanks chilliman
 smiley
Logged

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 601
Posts: 48543
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
is there a right way to add multiple input and out that you what to happen at the same time
The first thing to do is get past the idea that things can happen "at the same time". The Arduino is a single processor, non-threaded, system. One thing at a time happens.

The second thing is to ask your question with your hands in your pockets. We can't see your hand-waving, and get the extra context that goes with that.
Logged

East Anglia (UK)
Offline Offline
Faraday Member
**
Karma: 109
Posts: 4054
May all of your blinks be without delay()
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Inputs will be processed in the order that the program reads them.  Outputs will happen in the order that the program does them.  Although the Arduino is not fast in absolute terms it is fast enough to make things appear to happen at the same time when in fact they are happening one after the other.
Logged

Please do not send me PMs asking for help.  Post in the forum then everyone will benefit from seeing the questions and answers.

Pittsburgh, PA, USA
Offline Offline
Faraday Member
**
Karma: 93
Posts: 4743
I learn a bit every time I visit the forum.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Thanks all for the tips ,i shall remember them, is there a right way to add multiple input and out that you what to happen at the same time i.e . what order etc.

thanks chilliman
 smiley

I write sketches that need to do multiple things responsively as Finite State Machine (please look it up for details as that saves a lot of typing) sketches.

Only one thing happens at a time but what happens can be broken down into small parts that run quickly, in perhaps 100 microseconds or often less to much less and sometimes a bit more.

Those small parts I have execute different sub-tasks; the inputs, outputs and processes; in turn.

One natural separator of sub-tasks is when any one has to wait for the next step it does. In that waiting time other parts of other sub-tasks get done. In as little as 1 millisecond many things may get done. For example, the time between Serial characters arriving can take 1000's of Arduino-cycles of which there are 16,000 per millisecond.

I break up Serial input into pieces that logically follow each other or branch depending on what characters arrive. My method checks each character as it comes in and acts then while some people will collect all the characters and then check and act, but either way is valid.
So if I am looking for user codes that always end with a carriage return (I set up serial monitor to add one to every line, there's a box in the monitor lower-right near the baud rate box) and start with G (for Go) or S (for Stop) and after G expect 3 digits then if the user sends S my code looks for the carriage return to know the command is valid and then the code does the stop action. 
If the user sends G then the code goes on to try and collect the 3 digits and carriage return before acting on that input.
Anything else, any input that does not match the pattern is rejected with an error message output back to the user and new input is awaited.

Just to get S then carriage return and do the stop action, I have done in 2 parts. The break is after receiving S since there is a wait time before the next character arrives. If a G is received then there are essentially 5 parts to get G # # # '/r' (carriage return). If the user message starts with neither then my code handles the message as an input error.

I coordinate all these actions by putting the code for each part inside an if() { ... } block or a case block within a switch-case statement. Sometimes I use an else if() { ... } or else { ... } to extend the logic of an if() block.

Each if() or case block checks the value of a variable used to track the process state of that sub-task. If the first character is S, the process would get changed to a different state than if the first character is a G.

Using the state method I can have the code for each part stand alone inside its own block inside of loop() and not inside an if() or while() for some other process. Keeping the parts code separate is key to simpler, easier to change or add-to code.

Side-excursion on -why- you want to keep the parts separate:
A simple example of the other way is code to push a switch and led goes on we have an if ( digitalRead ) for the switch with the digitalWrite to turn the led on inside -- and then more logic to know when to turn the led off. And then of course more actions must be fit in, the levels of nested control statements like if()'s can and usually does get very complicated/messy quickly. Code like that is hard to change except in ways that "go with the grain" of the original idea; that idea changing is what leads to spaghetti code, probably the root of more programming headaches than any other and usually the hallmark of poor to bad management, a think-it-through approach rather than a think-ahead approach. But even using think-ahead and flow-plans, a load of top-down approach nesting generally results in a spaghettified mess.

In the G # # # /r input example, my state 0 will be the 'waiting for input' state. The code block that runs when a character is read and state is 0 will look for S or G, anything else is error. ALWAYS handle errors.
When the 0 state code sees a G it may change state to 2 and sets a variable to put the expected number following G to zero. Then that code is done.
Next time a character is received the state 2 code runs and it is looking for a digit. When it gets the digit, it counts the digit and starts evaluating the expected number entered. Since 3 digits are expected, state stays at 2 and the count of digits is used to track the process of number entry.
Each digit gets turned into a value by subtracting the character '0' ('9' - '0' == 9), the variable for the input number is multiplied by 10 and then the value for the digit just received is added. So for G123, the final number variable goes through 0 x 10 + 1, 1 x 10 + 2, 12 x 10 + 3 = 123.
When the digit count gets to 3 and there's been no errors, the state may be changed to 4 or any other number not used and the code for that state looks for the carriage return to finish the input process then change state to one that runs the G### action part of the sketch.

Any time there is an error, say instead of G### there was G#F, the state should be changed to either a general error state that handles all errors the same way or one with special handling. The next time through loop the error code runs in its own block, you don't need to wedge it into the code where the error was found or find a way out of a loop or other logic except to change the state and return from loop() which... runs loop() again with that state changed!

You can have as many state variables as you want but I caution against too many as you can end up with 'battling states'. It is best to keep a simple plan of what you want the sketch to do and then break the parts down and assign sub-tasks and states until that gets down to code level. Use all the lines of the plan as comments and that will help you immensely with your code.

If you go read up on finite state machines, find and play with some examples before you go making your own then the time you spend doing that will pay off well in time saved learning by mistakes when you don't.

Good luck and remember to take breaks when you get tired, walk away and come back for a fresh look when you get stuck. The logical-focus part of the brain will miss simple things that it has dismissed ("I know that's right") but minutes spent away will usually help clear that block.

See ya when you hit the next big snag but I will expect you to ask more specific questions then.


Logged

I find it harder to express logic in English than in Code.
Sometimes an example says more than many times as many words.

0
Offline Offline
Newbie
*
Karma: 0
Posts: 34
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

thanks
Logged

Pages: [1]   Go Up
Jump to: