Go Down

Topic: arduino code works slower than arduino code generated by ldmicro (Read 458 times) previous topic - next topic

parksplit

hello comunity, please don´t get me wrong i do not pretend to sponsor ldmicro, i am using a h bridge (l293d) with a 12vdc motor, l293d is powered with 5vdc, i have tested and does what i want, the problem is that my motor moves slowly, but when i use ldmicro for 328 mcu my motor works fast, it works fast also with arduino code generated by ldmicro, see video please for better descrption:


https://www.youtube.com/watch?v=Z3LNw8eBW8A&feature=youtu.be




i am using arduino uno with both arduino IDE and ldmicro, in my arduino code from arduino IDE i declared millis() 3 times, i also declares "extern byte" for some names because i am using tabs, sorry for attachment zip file , i attach ldmicro /arduino code generated by ldmicro and my arduino code with arduino IDE. circuit diagram too.

what am i doing wrong with my arduino code? thanks a lot

westfw

Well, from the video, it seems that the motor is actually operating more slowly when being driven by the Arduino code than when being driven by the ldmicro code.  To me, that implies that somehow your loops are essentially creating some sort of PWM waveform for the motor, instead of what I assume is supposed to be "if (button1()) go_forward_until_limit(); if (button2()) go_backward_until_otherlimit()" logic.

I can't actually follow your program code, though (where are the comments and meaningful variable names!)   Here's the code, merged and with some slight formatting changes (designed to make it more readable on a forum, I guess.)


Code: [Select]
/*
 * L293D_test2.ino
 */
void setup()
{
botones_setup();
salidas_setup();
}

void loop()
{
debounce_loop();
salidas_loop();
}

/*
 * salidas.ino
 */

const byte enable = 8;
const byte input1 = 9;
const byte input2 = 10;
extern byte d;

byte condicion=0;

void salidas_setup()
{
  pinMode (enable, OUTPUT);
  pinMode (input1, OUTPUT);
  pinMode (input2, OUTPUT);
}

void salidas_loop()
{
  if (d>=5) {
   digitalWrite(enable,HIGH);
   digitalWrite(input1,HIGH);
   digitalWrite(input2,LOW);
  }  else  {
   digitalWrite(enable,LOW);
   digitalWrite(input1,LOW);
   digitalWrite(input2,LOW);
  }

  if (e>=5)  {
   digitalWrite(enable,HIGH);
   digitalWrite(input1,LOW);
   digitalWrite(input2,HIGH);
  }  else  {
   digitalWrite(enable,LOW);
   digitalWrite(input1,LOW);
   digitalWrite(input2,LOW);
  }
}

/*
 * botones.ino
 */

unsigned long a = 0;
unsigned long b = 0;
unsigned long c = 0;
const long debounce = 41;
const long intervalo = 1000;

const byte boton_start = 2;
const byte boton_stop = 3;
const byte boton_input1 = 4;
const byte boton_input2 = 5;

byte estadoanterior_start=LOW;
byte estadoanterior_stop=LOW;
byte estadoanterior_input1=LOW;
byte estadoanterior_input2=LOW;

byte habilitado=0;

byte d = 0;
byte e = 0;

extern const byte enable;
extern const byte input1;
extern const byte input2;

void botones_setup()
{
  pinMode (boton_start,INPUT);
  pinMode (boton_stop,INPUT);
  pinMode (boton_input1,INPUT);
  pinMode (boton_input2,INPUT);
}

void debounce_loop()
{
  if(millis() - a >= debounce)  {
    a=millis();
    start_loop();
    stop_loop();
    input1_loop();
    input2_loop();
  }
}

void start_loop()
{
  if (estadoanterior_start != digitalRead(boton_start))  {
    estadoanterior_start=digitalRead(boton_start);
    if(digitalRead(boton_start)==HIGH)
    {
      habilitado=1;
    }
  }
}

void stop_loop()
{
  if (estadoanterior_stop != digitalRead(boton_stop))  {
    estadoanterior_stop=digitalRead(boton_stop);
    if (digitalRead(boton_stop)==HIGH) {
      habilitado=0;
      d=0;
      e=0;
      digitalWrite(enable,LOW);
      digitalWrite(input1,LOW);
      digitalWrite(input2,LOW);
    }
  }
}

void input1_loop()
{
  if (digitalRead(boton_input1)==HIGH and habilitado==1)  {
    if(millis() - b >= intervalo)    {
      b=millis();
      e=0;
      d++;
    }
  }
}

void input2_loop()
{
  if (digitalRead(boton_input2)==HIGH and habilitado==1)  {
    if (millis() - c >= intervalo)  {
      c=millis();
      d=0;
      e++;
    }
  }
}

parksplit

thank you very much for your reply, yeah you are right, i forgot the comments and names, bad from me, i will try, your idea, about the loops, how should i make lops. i mean is there some way to do a recommended loop structure?

westfw

I would start by adding debug code:

Code: [Select]
void salidas_loop()
{
  if (d>=5) {
   Serial.println("Motor forward");
   digitalWrite(enable,HIGH);
   digitalWrite(input1,HIGH);
   digitalWrite(input2,LOW);
  }  else  {
  Serial.println("Motor off from forward");
   digitalWrite(enable,LOW);
   digitalWrite(input1,LOW);
   digitalWrite(input2,LOW);
  }

  if (e>=5)  {
   Serial.println("Motor backward");
   digitalWrite(enable,HIGH);
   digitalWrite(input1,LOW);
   digitalWrite(input2,HIGH);
  }  else  {
  Serial.println("Motor off from backward");
   digitalWrite(enable,LOW);
   digitalWrite(input1,LOW);
   digitalWrite(input2,LOW);
  }
}


Wait ... is that the bug?  I think if d>5, you'll run the motor in one direction, but then immediately after that, if e<5, you'll turn the motor off again...

It's hard to recommend a loop structure without having any picture of what your final goals will be.
The current structure is sort-of
Code: [Select]
loop() {
  read_switches();
  run_motors();
}

that's not too bad, but I think the debounce code is obscuring the read_switches() part...


parksplit

thanks, actually when motor goes to one direction and arrives to a limit switch 1 (boton_input1) it stops waits 5 seconds and goes back, finds another limit switch 2 (boton_input2) it stops again, waits 5 seconds and goes  until limit switch 1 stops motor , and repeat process for ever.

I have attached loop process picture i am not good at it so i hope it is understandable


I don´t use delay i just used milli() to counts 1000 milliseconds:  



Code: [Select]


const long intervalo = 1000;
unsigned long b = 0;
byte d = 0;
byte e = 0;

void input1_loop()
{
  if (digitalRead(boton_input1)==HIGH and habilitado==1)  //forget habilitado, don´t use it
    {
      if(millis() - b >= intervalo)
      {
        b=millis();
        e=0; //it stops motor , has to be >= 5 to start motor
        d++; //counts every 1000 milliseconds
        
      }
    }
 


 


GoForSmoke

Use unsigned integers for time variables, not signed values. I see you use type long which will take almost 24 days to affect the sketch.

I don't think that you can/are debouncing all the switches with the code I see.

1) http://gammon.com.au/blink  <-- tasking Arduino 1-2-3
2) http://gammon.com.au/serial <-- techniques howto
3) http://gammon.com.au/interrupts
Your sketch can sense ongoing process events in time.
Your sketch can make events to control it over time.

westfw

I'd set up a state machine.  They're a very powerful concept, though they tend to be classified as a "somewhat advanced" programming topic, for reasons that aren't entirely clear (perhaps because they tend to be implemented as tables, that are frequently difficult to debug.  And I guess identifying exactly what your states are, and how many you need, can be a bit non-intuitive...)

Code: [Select]
switch (state) {
case ATRIGHTLIMIT:
  if (timeElapsed(stopTime) > 5000) {  // wait 5 seconds at right.
     motorLeft();   // then start moving toward left...
     state = MOVINGLEFT;
  }
  // else keep waiting
  break;
case MOVINGLEFT:
  if (leftLimitReached()) {
    motorOff();   // stop when the limit switch is activated
    stopTime= millis();   // save the stop time
    state = ATLEFTLIMIT;
  }
  // else keep moving
  break;
// ... etc
}

parksplit

thanks for your reply westfw, ill make again with switch case and more organized

GoForSmoke

Also by using direct port manipulation    https://www.arduino.cc/en/Reference/PortManipulation

you can read and write pins about 5x faster than with the pre-safed Arduino functions.
Pin safety is up to you then, take care if/when changing modes and access like when running a switch matrix.

1) http://gammon.com.au/blink  <-- tasking Arduino 1-2-3
2) http://gammon.com.au/serial <-- techniques howto
3) http://gammon.com.au/interrupts
Your sketch can sense ongoing process events in time.
Your sketch can make events to control it over time.

parksplit

hello again, it is me, i have made again my code a little smaller than before, it moves faster but not as fast as ldmicro generated hex, i willl do it again without debounce because it is not necessary, i try to figure it out if my millis way to use it, makes my code work not as fast as it should.

https://www.youtube.com/watch?v=Sn03l2s6mbk&feature=youtu.be

Code: [Select]


void setup()
{
  Serial.begin(9600);
  boton_setup();
  salida_setup();
}

void loop()
{
  boton_loop();
  salida_loop();
}

//..boton_setup ()  and  boton_loop()

//boton 1
const byte boton1=2; //pin button1
unsigned long a1=0; //value for millis() if (millis() - a1 >= debounce)
byte estadoanterior_boton1=LOW; //last state

//boton 2
const byte boton2=3; //pin button2
unsigned long a2=0; 
byte estadoanterior_boton2=LOW;


//boton 3
const byte boton3=4; //pin button3
unsigned long a3=0;
byte estadoanterior_boton3=LOW;
byte valor3=0;

//boton 4
const byte boton4=5; //pin button4
unsigned long a4=0; 
byte estadoanterior_boton4=LOW;
byte valor4=0;

//debounce
const unsigned long debounce=41; //time for debouncing

//intervalo
const unsigned long intervalo=1000; //time 1 second

//inicio
byte inicio=0; // byte for avaliable for working (if inicio = 0 ....not working)
                                                 (if inicio = 1 ....working)
void boton_setup()
{
  pinMode(boton1,INPUT);
  pinMode(boton2,INPUT);
  pinMode(boton3,INPUT);
  pinMode(boton4,INPUT);
 
}

void boton_loop()
{
  //millis boton1
  if (millis() - a1 >= debounce)
  {
    a1=millis();
    if(estadoanterior_boton1 != digitalRead(boton1))
    {
      estadoanterior_boton1=digitalRead(boton1);
      if (digitalRead(boton1)==HIGH)
      {
      inicio=1; //working
      Serial.println(inicio);
     
      }
     
     }
  }
  //millis boton2
  if (millis() - a2 >=debounce)
  {
    a2=millis();
    if (estadoanterior_boton2 != digitalRead(boton2))
    {
      estadoanterior_boton2 = digitalRead(boton2);
      if (digitalRead(boton2)==HIGH)
      {
        inicio=0; //not working
        Serial.println(inicio);
      }
    }
  }

  if (inicio == 1)
  {
  //millis boton3
  if (millis() - a3 >= intervalo)
  {
    a3=millis();
    if (digitalRead(boton3)==HIGH)
    {
      valor3++; //increase every 1000ms
      Serial.println(valor3);
    }
    else
    {
      valor3=0;
    }
  }
 
  //millis boton4
  if (millis() - a4 >= intervalo)
  {
    a4=millis();
    if (digitalRead(boton4) == HIGH)
    {
      valor4++;
      Serial.println(valor4);
    }
    else
    {
      valor4=0;
    }
  }
 
  }
}


//..salida_setup() and salida_loop()

//enable
const byte enable = 8;
//input1
const byte input1 = 9;
//input2
const byte input2 = 10;
//extern
extern byte inicio;

void salida_setup()
{
  pinMode(enable,OUTPUT);
  pinMode(input1,OUTPUT);
  pinMode(input2,OUTPUT);
}

void salida_loop()
{
  if ( inicio == 1) //working
  {
   if (valor3 >= 5) //waits 5 seconds then "enable pin" and "input1 pin" are HIGH
   {
    digitalWrite (enable,HIGH);
    digitalWrite (input1,HIGH);
    digitalWrite (input2,LOW);
   }

   if (digitalRead(boton4)==HIGH and valor4<5)
   {
    digitalWrite (enable,LOW);
    digitalWrite (input1,LOW);
    digitalWrite (input2,LOW);
   }

   if (valor4 >= 5) //waits 5 seconds then "enable pin" and "input2 pin" are HIGH
   {
    digitalWrite (enable,HIGH);
    digitalWrite (input1,LOW);
    digitalWrite (input2,HIGH);
   }

   if (digitalRead(boton3)==HIGH and valor3<5)
   {
    digitalWrite (enable,LOW);
    digitalWrite (input1,LOW);
    digitalWrite (input2,LOW);
  }
  }

  if (inicio == 0)
  {
    digitalWrite (enable,LOW);
    digitalWrite (input1,LOW);
    digitalWrite (input2,LOW);
    valor3=0;
    valor4=0;
  }

}




david_2018

Are you sure the limit switches are normally open, and close when the limit is reached?  I can't see anything in the code that would affect the speed of the motor, once it is turned on it should be running at full speed, which program you use to turn it on shouldn't matter.

parksplit

Thanks for your reply david_2018 i use a h-bridge, in this case L293D module, limit switches are buttons in pull down configuration that i use in my protoboard to stop motor, well, when the motor reaches the right end i press boton2 (which is milit switch) it stops motor and then it starts to count to 5, when it reaches 5 motor starts again to the oppsite end.

Go Up