Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

ADC with PWM to drive proportional solenoid

Status
Not open for further replies.

mshh

Full Member level 6
Joined
May 30, 2010
Messages
349
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,296
Location
usa
Activity points
3,871
i wrote this code to control proportional solenoid valve with analog input 0-5 v . i made ramp by multiply the input signal by constant k to change the input signal slightly to the final value. but if the signal changed after running the program it can't go into the for loop so i put a condition while (r!=rold) // check if the input changed .but it gives me error

"


Code dot - [expand]
1
2
Warning: D:\Micro Controller\my projects\proportional valve amplifier\pwm2.c(107): local variable 'r' is used before its value is set
Warning: D:\Micro Controller\my projects\proportional valve amplifier\pwm2.c(107): local variable 'rold' is used before its value is set



here is the code using codevision


Code dot - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
/*****************************************************
Chip type               : ATmega8
Program type            : Application
AVR Core Clock frequency: 8.000000 MHz
Memory model            : Small
External RAM size       : 0
Data Stack size         : 256
*****************************************************/
 
#include <mega8.h>
 
#include <delay.h>
 
#define ADC_VREF_TYPE 0x00
 
// Read the AD conversion result
unsigned int read_adc(unsigned char adc_input)
{
ADMUX=adc_input | (ADC_VREF_TYPE & 0xff);
// Delay needed for the stabilization of the ADC input voltage
delay_us(10);
// Start the AD conversion
ADCSRA|=0x40;
// Wait for the AD conversion to complete
while ((ADCSRA & 0x10)==0);
ADCSRA|=0x10;
return ADCW;
}
 
// Declare your global variables here
 
void main(void)
{
// Declare your local variables here
   long r;  
   long rold; 
   const unsigned int k[4]={4,6,8,10};  
   int i; // number of words in the Sentence
   long x;  
   long y;
 
PORTB=0x00;
DDRB=0x02;
PORTC=0x00;
DDRC=0x00;
PORTD=0x00;
DDRD=0xFF;
TCCR0=0x00;
TCNT0=0x00;
 
// Timer/Counter 1 initialization
// Clock source: System Clock
// Clock value: 8000.000 kHz
// Mode: Ph. & fr. cor. PWM top=ICR1
// OC1A output: Non-Inv.
// OC1B output: Discon.
// Noise Canceler: Off
// Input Capture on Falling Edge
TCCR1A=0x80;
TCCR1B=0x11;
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x03;
ICR1L=0x20;
OCR1AH=0x00;
OCR1AL=0x00;
OCR1BH=0x00;
OCR1BL=0x00;
 
ASSR=0x00;
TCCR2=0x00;
TCNT2=0x00;
OCR2=0x00;
 
MCUCR=0x00;
 
// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=0x00;
 
// USART initialization
// USART disabled
UCSRB=0x00;
 
// Analog Comparator initialization
// Analog Comparator: Off
// Analog Comparator Input Capture by Timer/Counter 1: Off
ACSR=0x80;
SFIOR=0x00;
 
// ADC initialization
// ADC Clock frequency: 1000.000 kHz
// ADC Voltage Reference: AREF pin
ADMUX=ADC_VREF_TYPE & 0xff;
ADCSRA=0x83;
 
SPCR=0x00;
TWCR=0x00;
 
 
while (1)
      {
  while (r!=rold) // check if the input changed
      {
      ///////// ramp up or down
 for(i=0;i<4 ;i++)
 {
 r=read_adc(0);
 PORTD=r;
 x=r/10;   // as i will multiply by K on the next step r from 0-5v
 y=k[i]*x;
  OCR1A=y*800/1023;
  delay_ms(10);
 } 
 } 
    r=read_adc(0);
     x=r/10;   // as i will multiply by K on the next step     
     y=k[3]*x;//  stable at final value of x
    OCR1A=y*800/1023;
    rold=r;
      } 
 
   
}

 
Last edited by a moderator:

variables defined within a function body are not initialised by default (they take whatever values are in the memory allocated to the variable), hence
Code:
void main(void)
{
// Declare your local variables here
   long r;  
   long rold; 

     ...
   while (r!=rold) // check if the input changed
 ...
r and rold are not initialised so you get the warning messages "local variable 'r' is used before its value is set" etc at the statement
Code:
   while (r!=rold) // check if the input changed
give r and rold initial values, e.g.
Code:
   long r=1;  
   long rold=2;
 

i wrote this code to control proportional solenoid valve with analog input 0-5 v . i made ramp by multiply the input signal by constant k to change the input signal slightly to the final value. but if the signal changed after running the program it can't go into the for loop so i put a condition while (r!=rold) // check if the input changed .but it gives me error

Actually, they are warning, not error messages:

Warning: D:\Micro Controller\my projects\proportional valve amplifier\pwm2.c(107): local variable 'r' is used before its value is set
Warning: D:\Micro Controller\my projects\proportional valve amplifier\pwm2.c(107): local variable 'rold' is used before its value is set

They are alerting you to the fact the varialbes, r and rhold, are being accessed before being properly initialized with a value.

A more prudent code technique would initialize those variables when declared:

Instead of:
Code:
   long r;  
   long rold;

Try something like this:
Code:
   long r = 0;  
   long rold = 0;

Or whatever value is appropriate.

A warning alerts the programmer of a possible issue, which could present a problem for the code to function as expected, semantics, however warnings typically do not prevent the code from completing compilation.

An error, on the other hand, alerts the programmer of syntactical violation of the programming language grammar, structure or rules, which will typically halt the completion of compilation and preventing the creation of a HEX file.

Another issue apparent in your code is, once code execution leaves the while(r != rold) loop, code execution eventually leaves the main() routine, which should not be permitted to happen.

Code:
while (1)
{
  while (r!=rold) // check if the input changed
  {
      ///////// ramp up or down
		 for(i=0;i<4 ;i++)
		 {
		 r=read_adc(0);
		 PORTD=r;
		 x=r/10;   // as i will multiply by K on the next step r from 0-5v
		 y=k[i]*x;
			OCR1A=y*800/1023;
			delay_ms(10);
		 } 
	} 
    r=read_adc(0);
     x=r/10;   // as i will multiply by K on the next step     
     y=k[3]*x;//  stable at final value of x
    OCR1A=y*800/1023;
    rold=r;

[COLOR="#FF0000"]// Nothing to prevent code execution from exiting the main() routine, once the above statements are executed
[/COLOR]
 }


BigDog
 

thank you all , i initialized them
HTML:
long r = 0;  
   long rold = 0;
and the warning disappeared but it didn't enter the for loop.
 

thank you all , i initialized them
HTML:
long r = 0;  
   long rold = 0;
and the warning disappeared but it didn't enter the for loop.
initialise with different values, e.g.
Code:
long r = 0;  
   long rold = 1;
therefore it will enter the while() loop
 

Actually, they are warning, not error messages:

Another issue apparent in your code is, once code execution leaves the while(r != rold) loop, code execution eventually leaves the main() routine, which should not be permitted to happen.

Code:
while (1)
{
  while (r!=rold) // check if the input changed
  {
      ///////// ramp up or down
		 for(i=0;i<4 ;i++)
		 {
		 r=read_adc(0);
		 PORTD=r;
		 x=r/10;   // as i will multiply by K on the next step r from 0-5v
		 y=k[i]*x;
			OCR1A=y*800/1023;
			delay_ms(10);
		 } 
	} 
    r=read_adc(0);
     x=r/10;   // as i will multiply by K on the next step     
     y=k[3]*x;//  stable at final value of x
    OCR1A=y*800/1023;
    rold=r;

[COLOR="#FF0000"]// Nothing to prevent code execution from exiting the main() routine, once the above statements are executed
[/COLOR]
 }


BigDog
how could it exit it is still trapped in the endless while loop ?

- - - Updated - - -
 
Last edited:

how could it exit it is still trapped in the endless while loop ?

- - - Updated - - -

i changed it
HTML:
long r = 0;  
   long rold = 1;
and it enters the for loop without changing the input voltage. and the pwm changed up and down automatically
not sure what you are attempting to do?
describe ethe problem
try moving the assignment of rold to the start of the while() loop
Code:
while (1)
{
  while (r!=rold) // check if the input changed
  {
       rold=r;
    .....
 

ok i moved it to the start of the while loop and it works , thank you very much for your help
 

i updated the code to ramp up and down using d and k but new problem comes up . when i decreased the input signal the duty of pwm decreased then when i decreased it again the duty increased for single pulse then it return back to decrease as it should be. the same thing happens when increasing the input double times it gives duty for example when i increase the input to 80% and the start is 20 % it gives 40% 60 % 80% then when i increase it to 100 % the duty should increased to 100% but it decreased to 80 % then increased to 100 %
 

could you put some printf() statements in the code to print critical variable values to check what your algorithm is doing?
this may help in working out what is going wrong
 

Status
Not open for further replies.

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top