Reading sensor data and not getting results

11 Feb 2013

Hi

I am just working on line follower using LPC1768 and I have problem with driving a motor and at the same time reading sensors. With my implementation, it seems that while motors are running, reading from sensors do not change. On the other when I only implement reading sensors they work fine. Here is my code could you tell me what could be a problem. Many thanks!

#include "mbed.h"

//------MOTOR----------
I2C i2c(p9, p10);        // sda, scl

PwmOut pwm0(p22);
PwmOut pwm1(p23);

const int addr = 0x40; // define the I2C Address

DigitalOut   led(LED1);                                  // status LED
DigitalOut   test(p27);                                  // test pin

DigitalInOut ir_rx0(p11);  // IR recieves
DigitalInOut ir_rx1(p12);  // IR recieves
DigitalInOut ir_rx2(p15);  // IR recieves
DigitalInOut ir_rx3(p16);  // IR recieves
DigitalInOut ir_rx4(p17);  // IR recieves
DigitalInOut ir_rx5(p18);  // IR recieves
DigitalInOut ir_rx6(p25);  // IR recieves
DigitalInOut ir_rx7(p26);  // IR recieves

PwmOut ir_tx(p24);                                       // IR transmitter

Serial pc(USBTX, USBRX);                                 // USB serial port
 
// Black  : 4.2x200us   = 840us
// White  : 2 x 100us   = 200us
// Silver : 1.2 x 100us = 120us
          
int main() {

  bool ir_set[8];
  int  ir_value[8];
  
  int  ir_buffer;
  int  i, j, k;
   
  ir_tx.period_us(100);       // a 20ms period
  ir_tx.pulsewidth_us(100);    // 
  
  led  = 1;   
  test = 0;
  
  
  char cmd[2];
  pwm0.period_ms(50);     
  pwm0.pulsewidth_ms(5);  
    
  pwm1.period_ms(50);      
  pwm1.pulsewidth_ms(5);  

  while(true)
  {
  
    pc.printf("Drive Motor\n");
    
    cmd[0] = 0x99;           
    cmd[1] = 0x00;           
    i2c.write(addr, cmd, 1); 
    
    
    
    ir_rx0.output();
    ir_rx1.output();
    ir_rx2.output();
    ir_rx3.output(); 
    ir_rx4.output();
    ir_rx5.output();
    ir_rx6.output();
    ir_rx7.output(); 
  
    ir_rx0 = 1;
    ir_rx1 = 1;
    ir_rx2 = 1;
    ir_rx3 = 1;
    ir_rx4 = 1;
    ir_rx5 = 1;
    ir_rx6 = 1;
    ir_rx7 = 1; 
    
    for(i=0; i<8; i++)
    {
      ir_set[i]=true;
      ir_value[i]=0;
    }

    wait_us(50);
    
    ir_rx0.input(); 
    ir_rx1.input();  
    ir_rx2.input(); 
    ir_rx3.input(); 
    ir_rx4.input(); 
    ir_rx5.input();  
    ir_rx6.input(); 
    ir_rx7.input(); 
         
    test = 1;
    
    for(i=0; i<20; i++)
    {
      wait_us(50);
      
      if ((ir_buffer && 0x01) == 0)
        test = 0;
        
      if((ir_rx0==0) & ir_set[0])
      {
        ir_set[0]=false; ir_value[0]=i; 
      }  
      if((ir_rx1==0) & ir_set[1])
      {
        ir_set[1]=false; ir_value[1]=i; 
      }  
      if((ir_rx2==0) & ir_set[2])
      {
        ir_set[2]=false; ir_value[2]=i; 
      }  
      if((ir_rx3==0) & ir_set[3])
      {
        ir_set[3]=false; ir_value[3]=i; 
      }  
      if((ir_rx4==0) & ir_set[4])
      {
        ir_set[4]=false; ir_value[4]=i; 
      }  
      if((ir_rx5==0) & ir_set[5])
      {
        ir_set[5]=false; ir_value[5]=i; 
      }  
      if((ir_rx6==0) & ir_set[6])
      {
        ir_set[6]=false; ir_value[6]=i; 
      }  
      if((ir_rx7==0) & ir_set[7])
      {
        ir_set[7]=false; ir_value[7]=i; 
      }  
         
    }
    
    
    printf( "ADC conversion\n" );
    printf( "chan 0 = %d\n", ir_value[0] );  
    printf( "chan 1 = %d\n", ir_value[1] );     
    printf( "chan 2 = %d\n", ir_value[2] );  
    printf( "chan 3 = %d\n", ir_value[3] );          
    printf( "chan 4 = %d\n", ir_value[4] );  
    printf( "chan 5 = %d\n", ir_value[5] );     
    printf( "chan 6 = %d\n", ir_value[6] );  
    printf( "chan 7 = %d\n", ir_value[7] );      
      
    wait(1);

  }
}

11 Feb 2013

Hi,

When you stop the motors from running I assume you are commenting out lines 47-51 which apply pwm to p22 & p23.

Note that your ir_tx pin is p24 - this might be being "adjusted" by noise created by p22 & p23. I suggest moving to another pin further away on the board and see if this helps and also separate any wires. Can't see any logic issue in your code though to have so much printing in a fast(ish) while loop is not generally a good idea.

11 Feb 2013

Hi, The problem is probably due to a limitation of the mbed where all PWM channels must share the same period.

Quote:

On the mbed LPC2368 and LPC1768, the PwmOut hardware is limited to share the period value between all outputs. Therefore, if you change the period of one output, you change them all. The pulsewidth can be set independently for each output.

This means when you increase the PWM period to 50 ms you will be changing the ir_tx period as well (but the duty cycle will remain the same)

12 Feb 2013

Hi

I understand the problem. So what could be the possible solution? Making the period for PWM the same as IR? I have done this but this hasn't solved the problem.

07 Apr 2016

Hi,

I've never needed to use the Digital IN/OUT simulataneously before so this might also be a question disguised as an answer, but I would like to clarify it even though your having a read issue. In your main loop, at first you call,

ir_rx0.output(); You set the pin register as output ect....

then set the value, ir_rx0 = 1; Set Pin High ect...

then you move on and set the pin register to input, ir_rx0.input(); ect...

then you go on to reference the value of those pins, if((ir_rx0==0) & ir_set[0]) { ir_set[0]=false; ir_value[0]=i; }

My thought is if you are referencing the Pin register value directly, wouldn't you need a, if_rx0.read() call value of pin

if((ir_rx0.read()==0) & ir_set[0]) { ir_set[0]=false; ir_value[0]=i; }

if it was a variable then you could write eg..,

int ir_rx0a; ir_rx0a = ir_rx0.read();

if((ir_rx0a==0) & ir_set[0]) { ir_set[0]=false; ir_value[0]=i; }

Is this correct? or can you just write the pin object name directly into the if statement when reading it?