10 years, 8 months ago.

i cant drive motors with respect to my ir sensor output

I have made a basic robo with ir sensor. with freedom kl25z board. my IR sensor has +5V,+5V,CTRL,A out, D out and GND pins. here is my program code:

#include "mbed.h"
#include "MMA8451Q.h"



#define MMA8451_I2C_ADDRESS (0x1d<<1)
  PinName const SDA = PTE0;
  PinName const SCL = PTE1;

Serial pc(USBTX, USBRX);
DigitalOut myled(LED1);
AnalogIn a(PTB0);
DigitalOut myled1(LED2);

PwmOut m1(PTD4);
PwmOut m2(PTA12);
PwmOut m3(PTA4);
PwmOut m4(PTA5);

float i;

 void forward(float i)
{
  
    m1=0;
    m2=i;
    m3=0;
    m4=i;
    
    
}

 void backward(float i)
{

         m1=i;
        m2=0;
        m3=i;
        m4=0;
     
}

 void right(float i)
{
    m1=0;
    m2=i;
    m3=0;
    m4=0;
}

void left(float i)
{
    m1=0;
    m2=0;
    m3=0;
    m4=i;
    }
    
 void stop()
{
    m1=0;
    m2=0;
    m3=0;
    m4=0;
}


float t;

int main()
{
  while(1)
  {
   MMA8451Q acc(SDA, SCL, MMA8451_I2C_ADDRESS);
   
    printf("MMA8451 ID: %d\n", acc.getWhoAmI());
    acc.getWhoAmI();
    t=a;
    
    pc.printf("IR Sensor = %f\n\r",t);
    
    wait(0.1f);
    
    if(a<0.3f)
    {
        myled=1;
        myled1=0;
        backward(1);
    }
    else
    {
        myled1=1;
        myled=0;
        forward(1);
    }
    
    
}

}

The problem is when i power my robot , it just keeps executing the 'if' part. it doesnt jump to 'else' part when i'm bringing any object near to the sensor.

What do you mean by "'if' part"? There is no 'if' nor 'else' in your code.

posted by Yoichi Hamazaki 16 Mar 2015

Please use <<code>> and <</code>> to format your code into something readable on the forum pages.

posted by Andy A 16 Mar 2015

I corrected the code. Now its perfect , n yeah it should be if and else. Now you can take a look.

posted by Mridul Sharma 16 Mar 2015

1 Answer

10 years, 8 months ago.

You have some slightly odd things going on, you create and destroy the sensor object every time around your loop. You also have two while loops that if you got bad sensor readings could lock the code up forever.

The code below changes things to move the parts that don't need to be in the loop out of the loop and made some changes to ensure that it never gets into a state where it stops outputting status to the serial port. Also it also limits the serial port debug output to once per second in order to avoid swamping the port but runs the motor control loop as fast as possible.

All of the changes are commented so hopefully they make sense.

#include "mbed.h"
#include "MMA8451Q.h"
#define MMA8451_I2C_ADDRESS (0x1d<<1)

PinName const SDA = PTE0;
PinName const SCL = PTE1;

Serial pc(USBTX, USBRX);

DigitalOut myled(LED1); 
AnalogIn a(PTB0);
DigitalOut myled1(LED2);

PwmOut m1(PTD4);
PwmOut m2(PTA12);
PwmOut m3(PTA4);
PwmOut m4(PTA5);

MMA8451Q acc(SDA, SCL, MMA8451_I2C_ADDRESS); // Create this once not every loop.

// float i; // not used.

void forward(float i) { 
  m1=0;
  m2=i;
  m3=0;
  m4=i;
}

void backward(float i) {
  m1=i;
  m2=0;
  m3=i;
  m4=0;
}

void right(float i) {
  m1=0;
  m2=i;
  m3=0;
  m4=0;
 }

void left(float i) {
  m1=0;
  m2=0;
  m3=0;
  m4=i;
 }

void stop() { m1=0; m2=0; m3=0; m4=0; }

// float t; // moved to being local to main

Ticker screenUpdate; // timer to only update the screen at a fixed rate.
volatile bool screenUpdateDue = false; // flag to indicate that the screen should be updated.

void onScreenUpdate(void) {  // function called when we need to update the screen
  screenUpdateDue = true;
}


int main() { 

  float range; // replacement for global t. No performance hit for variable names with more than one letter so make the code readable.

  printf("MMA8451 ID: %d\n", acc.getWhoAmI()); // only do this on startup not every loop

  screenUpdate.attach(&onScreenUpdate,1); // attach the update timer

  while(1) {  // main loop
    range=a;        // read the ADC
    if (screenUpdateDue) {  // if we are due to update the screen
      pc.printf("IR Sensor = %.3f\n\r",range); // limit to 3 decimal places.
      screenUpdateDue  = false;
    }

    if (range<0.3) {          // if too close more backwards
     myled=1; myled1=0; backward(1);
    } else {
     myled1=1; myled=0; forward(1); 
    }

    // optionaly add a small delay here 
  } // end while(1)
}

Yeah ! it has to be if and else. my bad. thanks for replying. but it still doesnt work. it keeps executing the if part.

posted by Mridul Sharma 16 Mar 2015

One more thing, when the freedom board is connected to usb, the the LEDs are responding to IR sensor, but when m giving an external +5V supply through 'H-Bridge' only the motor keeps running backward and led is green.

posted by Mridul Sharma 16 Mar 2015

And what value is the sensor giving you according to the serial output?

posted by Andy A 16 Mar 2015

How should i check that?

posted by Mridul Sharma 17 Mar 2015

I can just see the values on terminal. the light switches at 0.3

posted by Mridul Sharma 17 Mar 2015

If the terminal is outputting the correct values and the LED is switching on and off as expected then the code is working fine. Check you have the motors wired up correctly.

posted by Andy A 17 Mar 2015

Everything is okay. the ir sensor alone working fine ( with a program only for IR sensor). and motor is running in its own separate program. There's somethin wrong when i download the above program to freedom board. Is there anything that they cant work together.? or is it IR sensor connections? My IR sensor has 6 pins. { +5V, +5V, CTRL, Aout, Dout,GND}. +5V goes to +5v Freedom board opt.

posted by Mridul Sharma 17 Mar 2015

The other +5V pin of ir sensor goes to its own CTRL pin, and Aout goes to PTB0, Dout is open and GND goes to Ground of freedom board. Is this fine?

posted by Mridul Sharma 17 Mar 2015