Pages: [1]   Go Down
Author Topic: how to enhance this  code?  (Read 385 times)
0 Members and 1 Guest are viewing this topic.
0
Offline Offline
Newbie
*
Karma: 0
Posts: 3
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi there!
 
Ive been working on a arduino based robot it has wireless comunications servos and h bridge and 2 dc motors, the mecanical part is quite done and te code im posting below is able to test all the motion and comunication stuff, now my new problem is that as mi code is very basic it cant make more than one action at a time ex i cant move eyes and mouth at the same time or move forward and blink the way my code is made is so basic it has to wait for one condition to finish to pass to another


how can i skip this linear wayof working of the code?
working with functions can do this?

i dont need th hole solution but some hints to develop for some kind of multitasking
 
Thanks a lot!

 
 
#include <SoftwareSerial.h>;
 
#define rxPin 2
#define txPin 1
 
 
 
char prevChar = 0;
int i = 0;
 
int a = 0;
SoftwareSerial rfSerial =  SoftwareSerial(rxPin, txPin);
 
void setup(){
  
  pinMode(rxPin, INPUT);
  pinMode(13, OUTPUT);
  pinMode(12, OUTPUT);
  pinMode(11, OUTPUT);
  pinMode(10, OUTPUT);
  pinMode(9, OUTPUT);
  pinMode(8, OUTPUT);
  pinMode(7, OUTPUT);
  pinMode(6, OUTPUT);
  pinMode(5, OUTPUT);
  pinMode(4, OUTPUT);
  pinMode(3, OUTPUT);
 
  rfSerial.begin(2400); // begin serial connection with RF Link unit
  Serial.begin(2400); // begin serial communication over USB to the computer
   digitalWrite(13, HIGH);
   digitalWrite(4, HIGH);
   digitalWrite(3, HIGH);
}
 
void loop(){
  
  
  
    
  byte someChar = 0;  
  someChar = rfSerial.read(); // read whatever the RF Link has to offer
 
  if(someChar==45){
    //move bot forward with h bridge

    digitalWrite(12, HIGH);
    digitalWrite(9, HIGH);
    digitalWrite(11, LOW);
    digitalWrite(10, HIGH);
    digitalWrite(8, HIGH);
    digitalWrite(7, LOW);
    delay(200);
}
 
 
  if(someChar==54){
    //move bot backwards
    digitalWrite(12, HIGH);
    digitalWrite(9, HIGH);
    digitalWrite(11, HIGH);
    digitalWrite(10, LOW);
    digitalWrite(8, LOW);
    digitalWrite(7, HIGH);
    delay(200);
}
 
 
 
  if(someChar==73){
    //move bot to the right
    digitalWrite(12, HIGH);
    digitalWrite(9, HIGH);
    digitalWrite(11, HIGH);
    digitalWrite(10, LOW);
    digitalWrite(8, HIGH);
    digitalWrite(7, LOW);
    delay(200);
}
 
 
 
  if(someChar==77){
    //move bot to the left
    digitalWrite(12, HIGH);
    digitalWrite(9, HIGH);
    digitalWrite(11, LOW);
    digitalWrite(10, HIGH);
    digitalWrite(8, LOW);
    digitalWrite(7, HIGH);
    delay(200);  
  }
 
 
  if(someChar==34){
    // blink eyes
    for(i=0;i<20;i++){
      
      
     digitalWrite(6, HIGH);
     delayMicroseconds(850);
     digitalWrite(6, LOW);
     delay(20);  
  }
    delay(50);
 
for(i=0;i<20;i++){
     digitalWrite(6, HIGH);
     delayMicroseconds(300);
     digitalWrite(6, LOW);
     delay(20);
    }
    delay(50);
  }
 
  if(someChar==43){
    //open close mouth
    for(i=0;i<20;i++){
      
      
     digitalWrite(5, HIGH);
     delayMicroseconds(750);  
     digitalWrite(5, LOW);  
     delay(20);
    }
    delay(50);
 
 
    for(i=0;i<20;i++){
     digitalWrite(5, HIGH);  
     delayMicroseconds(550);
     digitalWrite(5, LOW);  
     delay(20);
    }
    delay(50);
  }
 
 
 // digitalWrite(12,LOW);
  digitalWrite(11,LOW);
  digitalWrite(10,LOW);
  digitalWrite(9,LOW);
  digitalWrite(8,LOW);
  digitalWrite(7,LOW);
  Serial.println(someChar,DEC);
 
}
« Last Edit: March 23, 2008, 10:41:25 am by psthandier » Logged

Australia
Offline Offline
Jr. Member
**
Karma: 0
Posts: 63
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Try something like this:

enum
{
 forward_action
 backward_action
 stop_action
 rolleyes_action
} action_enum;

uint16_t actions;

void forward()
{
  setMotor(mLeft, 255);
  setMotor(mRight, 255); // or whatever you do to go forwards
  actions &= ~forward_action; // we're going forwards now, don't need to come back to this function
}

void backward()
{
  setMotor(mLeft, 0);
  setMotor(mRight, 0); // or whatever you do to go backwards
  actions &= ~backward_action; // we're going backwards now, don't need to come back
}

void stop()
{
  setMotor(mLeft, 128);
  setMotor(mRight, 128); // or whatever you do to stop
  actions &= ~(forward_action | backward_action | stop_action); // make sure we kill all movement commands
}

void rolleyes()
{
  setMotor(mEyes, 255);     // or however you do this in your robot
  if (digitalInput(inEyesHome))  // detect when eyes have returned to start point
    actions &= ~rolleyes_action; // and only then disable this action, otherwise we do it again every loop
}

void main()
{
  setup();  // this does all your I/O and serial and whatever else setup

  for (;smiley-wink
  {
    /*
      these functions should never wait for anything. If you have to wait for something, simply don't make it disable itself until that thing has happened. They'll be called tens of thousands of times per second, so don't worry too much about missing things.
      in fact, nothing in this loop should ever wait. don't even use delay(). If you want to delay, count a variable down every time your function is called, do something when it reaches zero. Alternatively, use the clock that the timers use, or even a whole timer.
      the less time it takes each function to sort itself out, the faster they'll be called. fast is good.
    */
    if (actions & (1<<forward_action)) forward();
    if (actions & (1<<backward_action)) backward();
    if (actions & (1<<stop_action)) stop();
    if (actions & (1<<rolleyes_action)) rolleyes();

    if (rfSerial.canread())  // critically important that we never sit and wait - the loop *must* keep looping or actions won't be able to stop themselves when they want to
    {
      switch (rfSerial.read())
      {
        case 'F':
          actions |= forward_action; break;
        case 'B':
          actions |= backward_action; break;
        case 'S':
          actions |= stop_action; break;
        case 'R':
          actions |= rolleyes_action; break;
      }
    }
  }
}


note that the above needs *lots* of filling in and adapting to your needs, also you can't have more than 16 actions unless you add another variable. It's purely a demonstration of what you're probably heading towards anyway.

Note that if you want sequences, all you have to do is make one action enable the next one before disabling itself

If you want to abstract this into a reusable code block, you'll want to define a struct act { uint8_t enabled; void (*func)(struct act *); }; then a struct act actarray[MAXACTIONS]; then initialise all the fuction pointers to 0 so you know which actions aren't in use. set enabled to 1 to start the action, set it to a larger nonzero number if you want timed stuff then decrement it within the action function itself. pass the function a pointer to it's struct action so it can change its own enable state. Then, just for (;smiley-wink { for (i=MAXACTIONS-1;i;i--) actarray.enabled && actarray.func(&actarray); enableActionsHere(); }
Logged

Pages: [1]   Go Up
Jump to: