# ADC with PWM to drive proportional solenoid

Status
Not open for further replies.

#### mshh

##### Full Member level 6
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>

{
// Delay needed for the stabilization of the ADC input voltage
delay_us(10);
// Wait for the AD conversion to complete
}

// 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 Clock frequency: 1000.000 kHz
// ADC Voltage Reference: AREF pin

SPCR=0x00;
TWCR=0x00;

while (1)
{
while (r!=rold) // check if the input changed
{
///////// ramp up or down
for(i=0;i<4 ;i++)
{
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);
}
}
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:

#### horace1

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;

#### bigdogguru

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:

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++)
{
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);
}
}
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

#### mshh

##### Full Member level 6
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.

#### horace1

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

#### mshh

##### Full Member level 6
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++)
{
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);
}
}
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:

#### horace1

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;
.....

#### mshh

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

#### bigdogguru

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

Yes, you are correct, my mistake. I only glanced at the code briefly and the formatting or lack of it was misleading.

#### mshh

##### Full Member level 6
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 %

#### horace1

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.