[Moved] LPC2138 PWM to control servo motor

Status
Not open for further replies.
The condition works well when i set the condition using adc value
Code:
Code:

if ((adc_val>=0x0000022B) && (adc_val<0x0000024D))
{
PWMMR2 = 0x0000004C;
PWMMR4 = 0x0000004A;
PWMLER = 0x0000014;

but it fails to work when i assign using angle which is calculated using formula.
Code:
Code:

if ((angle >= 7.996409) && (angle < 18.20971))
{
PWMMR2 = 0x0000004C;
PWMMR4 = 0x0000004A;
PWMLER = 0x0000014;

}
Is there any thing wrong with the above condition ?
It works great in keil when i executed and checked by step one line ,But it fails to work in proteus simulation .
 

I have already replied in the same question yesterday.
What I can add is make the variables global volatile and use breakpoints in proteus to review the values and check if they are correct.
 

I have already replied in the same question yesterday.
What I can add is make the variables global volatile and use breakpoints in proteus to review the values and check if they are correct.
Thanks alex

can you tell me how to display a floating point value in lcd say 10.2356
 

one way is to mupliply it so that it becomes an integer and convert it to ASCII characters with a custom function
Another way is to use sprintf()

In order to debug in proteus you don't need to show the value in a display, you have access to all variable values in the watch window
 

in keil i have the access to variables in watch window. But to display that i am looking . i tried with sprint f but it didn't work

- - - Updated - - -

in keil i have the access to variables in watch window. But to display that i am looking . i tried with sprint f but it didn't work

Code:
#include <stdio.h>
 
 
  char buffer [21];  // Set size to LCD width plus one null
  
  sprintf (buffer, "ADC Value: %X", adc_val);
  lcd_puts(buffer);
the code works well but i wanted to display some floating point number say 21.356. it fails to display the value even after changing the representation from %x to %f or %4.2f

what change i should do to achieve that?
 

I don't see a problem, this works fine

Code:
float my_float=1.2345;
char buffer [21];  // Set size to LCD width plus one null
  
int main(void)
{
....
sprintf (buffer, "ADC Value: %f", my_float);
...
}

When I check the content of the array in the debugger after the sprintf line it contains the converted float.
I assume there is a problem with the LCD function.

You have included <stdio.h> right?
 


Code:
#include <LPC21xx.H>
#include <stdio.h>

void delay( )
{
		unsigned int i;
		for(i=0;i<4000;i++);
}

void lcddata(unsigned char c)
{
		IOCLR1=0x00ff0000; // output p1.16 to p1.24
		IOSET0=0x00000001; // rs =1 p0.0
		IOCLR0=0x00000002; // rw =0 p0.1
		IOSET0=0x00000004; // en=1  p0.2
		IOSET1 = c<<16;
		delay();
		IOCLR0=0x00000004; //en=0 p0.2
}

void lcdcmd(int c)
{
		IOCLR1=0x00ff0000;
		IOCLR0=0x00000001; // rs =0 p0.0
		IOCLR0=0x00000002; // rw =0 p0.1
		IOSET0=0x00000004; // en=1 p0.2
		IOSET1 = c<<16;
		delay();
		IOCLR0=0x00000004; //en=0 p0.2
}


void lcdinit()
{
		lcdcmd(0x38);
		delay();
		lcdcmd(0x0e);
		delay();

		lcdcmd(0x06);
		delay();
		lcdcmd(0x80);
		delay();
}

void lcdputs(const char * s)
{
	while(*s)
		lcddata(*s++);
}

Ya even me too checked in the debugger .i have posted the lcd code . it displays integers , characters but if i. change to %f in the below code lcd just turn on even cursor is not blinking
Code:
sprintf (buffer, "ADC Value: %f", my_float);
 

What happens if you use a predefined float value like I did and not the calculated one?
For example
Code:
float my_float=1.2345;
 

What happens if you use a predefined float value like I did and not the calculated one?
For example
Code:
float my_float=1.2345;
i tried even like that but same problem lcd just turns on . on other change in that .

- - - Updated - - -

What happens if you use a predefined float value like I did and not the calculated one?
For example
Code:
float my_float=1.2345;
i tried even like that but same problem lcd just turns on . on other change in that .
 

Then it is clear that sprintf is not the problem, there is something wrong with the LCD function.
Maybe the problem is the array length?
Do you use 16x2 LCD?

Does it print:
Code:
char buffer [16]= "ADC Val: 1.2345"
 

Then it is clear that sprintf is not the problem, there is something wrong with the LCD function.
Maybe the problem is the array length?
Do you use 16x2 LCD?

Does it print:
Code:
char buffer [16]= "ADC Val: 1.2345"
Ya it prints the value now.

yes am using 16x2 lcd, if i use %f in sprintf statement lcd goes blank,
but how to print a value without assigning as before ?
 
Last edited:

Limit the length of the string to 16 characters, check the %f parameter to round the value in less digits (like %0.4f) and make sure that the total is not more than 16 char
 

Limit the length of the string to 16 characters, check the %f parameter to round the value in less digits (like %0.4f) and make sure that the total is not more than 16 char

No it doesn't work,again lcd just blinks.
 

Show me what you have done

Code:
#include <LPC213X.H>
#include <stdio.h>
#include <math.h>
#include "lcdx.h"
//char buffer [16]= "ADC Val: 1.2345";


		
//VBC CLOCK 12MHZ
void delay();
void adc_datax();
void adc_inix();
void adc_datay();
void adc_iniy();

unsigned long val,adc_val,val1,adc_val1;
unsigned char buffer [16];  // Set size to LCD width plus one null
float y,s,v,m;
float angle,b;

 

int main(void)
{
		

			while(1)
				
			{
					adc_inix(); //initializing adc
					adc_datax();//extracting data
				  
			
				/*code for lcd print*/
					//PINSEL0=0X00000000; // gpio pin 0.0 to 0.15
				//	PINSEL2=0X00000000; // gpio pin 1.16 to 1.31
					IODIR0=0X00000007; //p0.0 rs p0.1 r/w p0.2 e	
					IODIR1=0X00ff0000; //p1.16 to p1.24 output
					lcdinitx();
					
					m=(3.3/1023);/*3.3/1023 for adc conversion*/
					y=1.65;/*offset voltage */	
					s=0.8;/*sensitivity 800mv/g*/
					b=57.295;/* pi/180 for radian to degree conversion */
					/* formula tetha= arcsin( (vout - voffset)/sensitivity) */ 
					v=asin(((adc_val*m)-y)/s);
					angle=v*b;

					
					sprintf (buffer, " adc %0.4f", angle);
					lcdputs(buffer);
				
}

void adc_inix(void)
{
		
	
	//	PINSEL = 0X05000000; //pin 13,14 p0.28,0.29 adc 0 channel 1 &2
		PCONP |=  0X00001000;	//select adc 0 bit 12
		AD0CR &=  0X00000000;
		AD0CR |=  0X00200206; // WITH PCLK 12/(2+1)=4MHZ ADC0 and 1 CHANNEL 1 PIN 13
		AD0INTEN &= 0x00000000; //Completion of a conversion on ADC channel 0 will not generate an interrupt.


}
void adc_datax(void)
{
					AD0CR  |= 0x01000000;                   /* Start A/D Conversion               */
					while((AD0DR & 0x80000000)==0); //until bit 31 is high (DONE)
					val = AD0DR; //read a/d data register
					adc_val = ((val >> 6) & 0x3FF);    // Extract AD result
					

}
 

unsigned char buffer [16]; // Set size to LCD width plus one null

To do that you need 16 char + null so the length should be buffer [17] but this shouldn't be a problem.

Move the initialization out of the while loop, why is it still inside the while loop?

You are also printing the lcd several timer per second and I'm not sure it this causes your problem.

What is the value of angle when you reach sprintf, maybe that is the problem.

What if you try without changing anything else
Code:
[COLOR="#FF0000"]angle= 123.4567; [/COLOR]  // add this before sprintf to see if you get output
sprintf (buffer, " adc %0.4f", angle);  
        lcdputs(buffer);
 


I have done the initialization inside the while loop only then the adc is getting converted in real tin=me or else it stops with only one conversion at a time,

PFA lcd again there lies a problem when i use %f in sprintf
 

You get a blank result even after using
Code:
angle= 123.4567;

What is the content of buffer array when you reach the lcdputs line?
 

Status
Not open for further replies.
Cookies are required to use this site. You must accept them to continue using the site. Learn more…