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.

PIC resets when connected to 12V solenoid valve

Status
Not open for further replies.
I think the problem is in the code. Just let the code run without solenoid connected. It will only forward bias the transistor driving the solenoid. See if PIC still resets. Put a LED and add 1 sec delay after port initialization and then lit an LED. If PIC resets then LED will turn OFF and then turn ON after 1 sec and you will come to know if PIC resets. Zip and post the complete project (code) files.

You driving solenoid using ULN2803 ? If yes, it will not work. ULN can only sink 500 mA current per channel. Your solenoid draws 2 A current. Use 8A power MOSFET or Darlington transistor of 8 or 12A to drive the solenoid.

Why you don't show the full schematic which includes solenoid circuit ? Zip and post the proteus file also.

Hi, the problem comes only when i connect solenoid valve. See this is my connection:

PIC's PIN 18 is connected to ULN2803 pin1 and output from uln2803 pin18 is connected to a relay which takes about 30mA and that relay is used to drive the solenoid valve.

Now, Till this relay part my code works perfectly. But as soon as i connect the valve to relay, it reaches to the last line that im displaying on LCD (i.e "stopped" ) and doesnt do anything.

- - - Updated - - -

What my program dioes is, when i press start button solenoid valve switches on for a few seconds and switches off for some seconds and this continues until i press stop button, for which im using a button on ext interrupt pin of PIC. if i connect LED it shows on off continuously without prob but when i connect valve through relay it stops.
 

As mentioned earlier, according to the description of the problem, there is a strong indication that the cause is due to layout issues. Without seeing your board PCB is difficult to give an accurate guess.
 

In your code do you have a while(1) loop and do the main processing in it ? Post your code here and also the config settings.
 

@pic.programmer,

Although you are interested in focusing some attention on the code as a possible action to turnaround the problem, the evidence presented above do not support any action on that scope. Solenoids are notoriously devices prone to carry a large amount of induced electromagnetic spikes around.

We're still awaiting for the OP's feedback concerning to the guesses remarked.
 

Have you added the diodes and the capacitors recommended, also on the solenoid?
Do you have another power supply you could use for the solenoid, just to separate the two circuits?

Have you got a link to the solenoid datasheet?

Have you got an oscilloscope, if so have you looked at the 5V when running the solenoid?
 

@Andre

The OP is asking the same questions in other forums.

She has posted code and schematic in this forum.

https://forum.allaboutcircuits.com/...-when-connected-to-12v-solenoid-valve.115279/

I see that there are no debounce delays in code and she is using while(s1 == 1) loops and turning ON and OFF the relays rapidly. She doesn't show the config settings. The while(s1 == 1) loop sbreak only when INT0 interrupt is detected and she forgets to set INTE_bit during port initialization.

She doesn't post the PCB layout when asked.
 

Regardless any other discussion currently in course elsewhere, we must only consider the information provided here, that still lacks of more details. Please keep awaiting for OP's reply.
 

In your code do you have a while(1) loop and do the main processing in it ? Post your code here and also the config settings.

Yes i have a while(1) loop in my code please check attached code in text format


Code C - [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
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
sbit LCD_RS at RB1_bit;
sbit LCD_EN at RB2_bit;
sbit LCD_D4 at RB3_bit;
sbit LCD_D5 at RB4_bit;
sbit LCD_D6 at RB5_bit;
sbit LCD_D7 at RB6_bit;
sbit LCD_RS_Direction at TRISB1_bit;
sbit LCD_EN_Direction at TRISB2_bit;
sbit LCD_D4_Direction at TRISB3_bit;
sbit LCD_D5_Direction at TRISB4_bit;
sbit LCD_D6_Direction at TRISB5_bit;
sbit LCD_D7_Direction at TRISB6_bit;
 
 int s1,x=0,m;
void main()
 {
 
   OPTION_REG.INTEDG = 1; // Set Rising Edge Trigger for INT
  INTCON.GIE=1;
  INTCON.INTE=1;
 
  
  TRISE.RE0=0;
  TRISE.RE1=0;
  TRISE.RE2=0;
   PORTE=0x00;
 
 PORTA=0;
 TRISA=0x00;
 
    
 // ADCON1=7;
 ADCON1=0x0F;
  CMCON=0x0F;
  
  /*TRISC.RC0=0;
  TRISC.RC1=0;
  TRISC.RC2=1;
  TRISC.RC3=0;
 
  TRISC.RC4=1;
  TRISC.RC5=1;
  TRISC.RC6=1;
  TRISC.RC7=1;       */
 
  PORTC=0b11110100;   //MODIFIED ON 15JUN
   TRISC=0b11110100;
 
 
  TRISD=1;
  PORTD=0b11111111;
  PORTB=0b00000001;
  TRISB=0b00000001;
  // TRISB.RB0=1;
   
        LCD_Init();
      delay_ms(100);
      LCD_Cmd(_LCD_CLEAR); // Clear display
      LCD_cmd(_LCD_CURSOR_OFF);
      LCD_Out(1,1,"Select BPM rate");
 
  while(1)
    {
 
 
     
      if(PORTC.RC2==0)
      {
 
         /*****************8 bpm**************************/
          if(PORTD.RD0==0)
          {
          // LCD_Init();
           LCD_Cmd(_LCD_CLEAR); // Clear display
            LCD_cmd(_LCD_CURSOR_OFF);
              LCD_Out(1,1,"8 BPM ");
                s1=1;
          // }
           while(s1==1)
           {
 
        PORTC.RC3=1;
        delay_ms(2500);
        
        PORTC.RC3=0;
        delay_ms(5000);
 
            }
          }
        /*************10 bpm*******************************/
      
 
      else if(PORTD.RD1==0)
           {
         // LCD_Init();
        LCD_Cmd(_LCD_CLEAR); // Clear display
        LCD_cmd(_LCD_CURSOR_OFF);
        LCD_Out(1,1,"10 BPM ");
        s1=1;
          while(s1==1)
          {
        // PORTC.RC6=0;
         PORTC.RC3=1;
        delay_ms(2000);
 
         PORTC.RC3=0;
         delay_ms(4000);
 
            }
           }
        /*************12 bpm*******************************/
        else if(PORTD.RD2==0)
        {
          //LCD_Init();
        LCD_Cmd(_LCD_CLEAR); // Clear display
        LCD_cmd(_LCD_CURSOR_OFF);
        LCD_Out(1,1,"12 BPM");
        s1=1;
     while(s1==1)
         {
         PORTC.RC3=1;
         delay_ms(1670);
         
         PORTC.RC3=0;
         delay_ms(3330);
 
           }
         }
         /*************14 bpm*******************************/
         else if(PORTD.RD3==0)
        {
          //LCD_Init();
        LCD_Cmd(_LCD_CLEAR); // Clear display
        LCD_cmd(_LCD_CURSOR_OFF);
        LCD_Out(1,1,"14 BPM");
         s1=1;
 
       while(s1==1)
          {
         PORTC.RC3=1;
         delay_ms(1430);
         
         PORTC.RC3=0;
         delay_ms(2850);
           }
         }
         /******************16 bpm*********************/
          else if(PORTC.RC4==0)
          {
         // LCD_Init();
           //delay_ms(10);
            LCD_Cmd(_LCD_CLEAR); // Clear display
            LCD_cmd(_LCD_CURSOR_OFF);
            LCD_Out(1,1,"16 BPM ");
             s1=1;
 
               while(s1==1)
               {
               //PORTC.RC7=0;
                PORTC.RC3=1;
                 delay_ms(1250);
                 
                PORTC.RC3=0;
               delay_ms(2500);
                }
           }
         /************18 bpm**************/
 
 else if(PORTC.RC5==0)                //USING SW10
       {
 
         //LCD_Init();
        LCD_Cmd(_LCD_CLEAR); // Clear display
        LCD_cmd(_LCD_CURSOR_OFF);
        LCD_Out(1,1,"18 BPM");
         s1=1;
 
     while(s1==1)
        {
         PORTC.RC3=1;
         delay_ms(1110);      //4th jul
         
         PORTC.RC3=0;
         delay_ms(2220);
      //    break;
          }
         }
 
   /************20 bpm**************/
 
      else  if(PORTC.RC6==0)                  //USING SW11
     {
 
          //LCD_Init();
          LCD_Cmd(_LCD_CLEAR); // Clear display
          LCD_cmd(_LCD_CURSOR_OFF);
          LCD_Out(1,1,"20 BPM");
           s1=1;
 
     while(s1==1)
       {
         PORTC.RC3=1;
         delay_ms(1000);         //4th jul
         
         PORTC.RC3=0;
         delay_ms(2000);
        }
      }
  /************24 bpm**************/
 
     else if(PORTC.RC7==0)                      //USING SW12
     {
          //LCD_Init();
        LCD_Cmd(_LCD_CLEAR); // Clear display
        LCD_cmd(_LCD_CURSOR_OFF);
        LCD_Out(1,1,"24 BPM ");
          s1=1;
          
     while(s1==1)
       {
         PORTC.RC3=1;
         delay_ms(830);
 
         PORTC.RC3=0;
         delay_ms(1660);
         }
       }
  /************28 bpm**************/
 
          else if(PORTD.RD4==0)
    {
 
          //LCD_Init();
        LCD_Cmd(_LCD_CLEAR); // Clear display
        LCD_cmd(_LCD_CURSOR_OFF);
        LCD_Out(1,1,"28 BPM ");
         s1=1;
 
    while(s1==1)
      {
 
        //PORTC.RC7=0;
         PORTC.RC3=1;
        delay_ms(720);
 
         PORTC.RC3=0;
        delay_ms(1440);
 
       }
      }
 /************32 bpm**************/
 
    else if(PORTD.RD5==0)
     {
 
       // LCD_Init();
        LCD_Cmd(_LCD_CLEAR); // Clear display
        LCD_cmd(_LCD_CURSOR_OFF);
        LCD_Out(1,1,"32 BPM");
        s1=1;
 
     while(s1==1)
       {
 
        // PORTC.RC6=0;
         PORTC.RC3=1;
         delay_ms(630);
 
         PORTC.RC3=0;
         delay_ms(1260);
 
          }
       }
 /************36 bpm**************/
 
      else if(PORTD.RD6==0)
     {
 
         // LCD_Init();
        LCD_Cmd(_LCD_CLEAR); // Clear display
        LCD_cmd(_LCD_CURSOR_OFF);
        LCD_Out(1,1,"36 BPM ");
        s1=1;
 
     while(s1==1)
       {
         PORTC.RC3=1;
         delay_ms(560);
 
         PORTC.RC3=0;
         delay_ms(1120);
         }
       }
 /************40 bpm**************/
 
      else if(PORTD.RD7==0)
     {
 
        // LCD_Init();
        LCD_Cmd(_LCD_CLEAR); // Clear display
        LCD_cmd(_LCD_CURSOR_OFF);
        LCD_Out(1,1,"40 BPM");
        s1=1;
 
     while(s1==1)
       {
         PORTC.RC3=1;
         delay_ms(500);
 
         PORTC.RC3=0;
         delay_ms(1000);
         }
       }
 
      //END OF START BUTTON
        }
 
      else if(x==1)
       {
       delay_ms(10);
        LCD_Init();
      LCD_Cmd(_LCD_CLEAR); // Clear display
      LCD_cmd(_LCD_CURSOR_OFF);
      LCD_Out(1,1,"Stopped");
        x=0;
       }
 
     
   }
  }
  
  
  void interrupt()
{
      PORTD=0b11111111;
      TRISD=1;
      
 
     // TRISC=0b11110100;
      //PORTC.RC2=1;
     PORTC.RC3=0;
     s1=0;
     x=1;
    INTCON.INTF=0;
 }

 
Last edited by a moderator:

@prerna123

You have not yet provided any detail of your layout. As repeatedly informed before, the error behaviour, as described is a clear indication of EMI problems ( w/solenoid = failure | w/o solenoid = works). Unless some information related to PCB can be provided, all cues will fall in the field of the guesses.
 

Thank you andre, i am posting my code to make sure there is no error in the code. i will send PCB pictures tomorrow. i tried keeping the valve far away from the circuit but the as soon as i press start button (please refer the code), the LCD shows 8 BPM (depending on where the rotary switch is) then immediately "stopped" is displayed and it does not repeat ..
 
RC2 is button ? Is it lockable switch or tact switch ? Where is the full code ? I don't see code which turn ON / OFF the LEDs. Why ? Initially you have 12 LEDs for showing which function is selected but later you used RC2 for button (start button). So, you have 11 LEDs. Now how will you show status of 12 functions using 11 LEDs ?

Do you want me to eliminate the start button ?

Try this code with 4 MHz crystal. If you want for other frequency then mention it. I have to change the Timer1Init() code. I have not tested it in Proteus but I guess there are no mistakes in the code but I am not sure whether this will solve your problem or not. If it still doesn't solve your problem then show the PCB layout and switch to PIC18F device.


Code C - [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
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
sbit LCD_RS at RB1_bit;
sbit LCD_EN at RB2_bit;
sbit LCD_D4 at RB3_bit;
sbit LCD_D5 at RB4_bit;
sbit LCD_D6 at RB5_bit;
sbit LCD_D7 at RB6_bit;
 
sbit LCD_RS_Direction at TRISB1_bit;
sbit LCD_EN_Direction at TRISB2_bit;
sbit LCD_D4_Direction at TRISB3_bit;
sbit LCD_D5_Direction at TRISB4_bit;
sbit LCD_D6_Direction at TRISB5_bit;
sbit LCD_D7_Direction at TRISB6_bit;
 
sbit SOLENOID at RC3_bit;
 
#define ON 1
#define OFF 0
 
#define TRUE 1
#define FALSE 0
 
#define INPUT 1
#define OUTPUT 0
 
#define SET 1
#define CLEAR 0
 
char myFlags = 0;
char msg[20];
unsigned int onTimeInMilliSec = 0, offTimeInMilliSec = 0, milliSecCounter = 0;
 
const char msg1[] = "Select BPM rate";
const char msg2[] = "8 BPM";
const char msg3[] = "10 BPM";
const char msg4[] = "12 BPM";
const char msg5[] = "14 BPM";
const char msg6[] = "16 BPM";
const char msg7[] = "18 BPM";
const char msg8[] = "20 BPM";
const char msg9[] = "24 BPM";
const char msg10[] = "28 BPM";
const char msg11[] = "32 BPM";
const char msg12[] = "36 BPM";
const char msg13[] = "40 BPM";
const char msg14[] = "Stopped";
 
sbit runFlag at myFlags.B0;
sbit resetFlag at myFlags.B1;
sbit solenoidControlFlag at myFlags.B2;
sbit toggleOnTimeOffTime at myFlags.B3;
sbit runOnceFlag at myFlags.B4;
sbit executeOnce at myFlags.B5;
 
//Timer1
//Prescaler 1:1; TMR1 Preload = 64536; Actual Interrupt Time : 1 ms
//Place/Copy this part in declaration section
void InitTimer1() {
    T1CON = 0x01;
    TMR1IF_bit = 0;
    TMR1H = 0xFC;
    TMR1L = 0x18;
    TMR1IE_bit = 1;
    INTCON = 0xC0;
}
 
void interrupt() {
    if(INTF_bit) {
        PORTC.F3 = 0;
        runFlag = CLEAR;
        resetFlag = TRUE;
        TMR1ON_bit = 0;
        INTF_bit = CLEAR;
    }
    
    if(TMR1IF_bit) {
        TMR1H = 0xFC;
        TMR1L = 0x18;
        
        if(runFlag) {
            ++milliSecCounter;
            if(toggleOnTimeOffTime) {
                if(milliSecCounter == onTimeInMilliSec) {
                        SOLENOID = OFF;
                        milliSecCounter = 0;
                        toggleOnTimeOffTime = 0;
                }
            }
            else if(!toggleOnTimeOffTime) {
                if(milliSecCounter == offTimeInMilliSec) {
                        SOLENOID = ON;
                        milliSecCounter = 0;
                        toggleOnTimeOffTime = 1;
                }
            }
        }
    
        TMR1IF_bit = 0;
    }
}
 
//copy const to ram string
char *CopyConst2Ram(char *dest, const char *src) {
    char *d;
    
    d = dest;
    for(;*dest++ = *src++;);
 
    return d;
}
 
void main() {
 
    CMCON = 0x07;
    CVRCON = 0x00;
    ADCON1 = 0x87;
 
    TRISA = 0x00;
    TRISB = 0x01;
    TRISC = 0xF4;
    TRISD = 0xFF;
    TRISE = 0x00;
 
    PORTA = 0x00;
    PORTB = 0x00;
    PORTC = 0x00;
    PORTD = 0x00;
    PORTE = 0x00;
 
    LCD_Init();
    Delay_ms(200);
    LCD_cmd(_LCD_CURSOR_OFF);
    LCD_Cmd(_LCD_CLEAR);
    LCD_Out(1,1,CopyConst2Ram(msg, msg1));
 
    INTEDG_bit = 1;
    
    runOnceFlag = 1;
    
    while(1) {
    
          if(!PORTC.F2) {
              Delay_ms(50);
              while(!PORTC.F2);
              
                  runOnceFlag = TRUE;
              
                  if(!PORTD.F0) {
                      Delay_ms(50);
                      if(!PORTD.F0) {
                            if(runOnceFlag) {
                                LCD_Cmd(_LCD_CLEAR);
                                LCD_Out(1,1,CopyConst2Ram(msg, msg2));
                                runFlag = TRUE;
                                onTimeInMilliSec = 2500;
                                offTimeInMilliSec = 5000;
                            }
                      }
                  }
                  else if(!PORTD.F1) {
                      Delay_ms(50);
                      if(!PORTD.F1) {
                            if(runOnceFlag) {
                                LCD_Cmd(_LCD_CLEAR);
                                LCD_Out(1,1,CopyConst2Ram(msg, msg3));
                                runFlag = TRUE;
                                onTimeInMilliSec = 2000;
                                offTimeInMilliSec = 4000;
                            }
                      }
                  }
                  else if(!PORTD.F2) {
                      Delay_ms(50);
                      if(!PORTD.F2) {
                            if(runOnceFlag) {
                                LCD_Cmd(_LCD_CLEAR);
                                LCD_Out(1,1,CopyConst2Ram(msg, msg4));
                                runFlag = TRUE;
                                onTimeInMilliSec = 1670;
                                offTimeInMilliSec = 3330;
                            }
                      }
                  }
                  else if(!PORTD.F3) {
                      Delay_ms(50);
                      if(!PORTD.F3) {
                            if(runOnceFlag) {
                                LCD_Cmd(_LCD_CLEAR);
                                LCD_Out(1,1,CopyConst2Ram(msg, msg5));
                                runFlag = TRUE;
                                onTimeInMilliSec = 1430;
                                offTimeInMilliSec = 2850;
                            }
                      }
                  }
                  else if(!PORTC.F4) {
                      Delay_ms(50);
                      if(!PORTC.F4) {
                            if(runOnceFlag) {
                                LCD_Cmd(_LCD_CLEAR);
                                LCD_Out(1,1,CopyConst2Ram(msg, msg6));
                                runFlag = TRUE;
                                onTimeInMilliSec = 1250;
                                offTimeInMilliSec = 2500;
                            }
                      }
                  }
                  else if(!PORTC.F5) {
                      Delay_ms(50);
                      if(!PORTC.F5) {
                            if(runOnceFlag) {
                                LCD_Cmd(_LCD_CLEAR);
                                LCD_Out(1,1,CopyConst2Ram(msg, msg7));
                                runFlag = TRUE;
                                onTimeInMilliSec = 1110;
                                offTimeInMilliSec = 2220;
                            }
                      }
                  }
                  else if(!PORTC.F6) {
                      Delay_ms(50);
                      if(!PORTC.F6) {
                            if(runOnceFlag) {
                                LCD_Cmd(_LCD_CLEAR);
                                LCD_Out(1,1,CopyConst2Ram(msg, msg8));
                                runFlag = TRUE;
                                onTimeInMilliSec = 1000;
                                offTimeInMilliSec = 2000;
                            }
                      }
                  }
                  else if(!PORTC.F7) {
                      Delay_ms(50);
                      if(!PORTC.F7) {
                            if(runOnceFlag) {
                                LCD_Cmd(_LCD_CLEAR);
                                LCD_Out(1,1,CopyConst2Ram(msg, msg9));
                                runFlag = TRUE;
                                onTimeInMilliSec = 830;
                                offTimeInMilliSec = 1660;
                            }
                      }
                  }
                  else if(!PORTD.F4) {
                      Delay_ms(50);
                      if(!PORTD.F4) {
                            if(runOnceFlag) {
                                LCD_Cmd(_LCD_CLEAR);
                                LCD_Out(1,1,CopyConst2Ram(msg, msg10));
                                runFlag = TRUE;
                                onTimeInMilliSec = 720;
                                offTimeInMilliSec = 1440;
                            }
                      }
                  }
                  else if(!PORTD.F5) {
                      Delay_ms(50);
                      if(!PORTD.F5) {
                            if(runOnceFlag) {
                                LCD_Cmd(_LCD_CLEAR);
                                LCD_Out(1,1,CopyConst2Ram(msg, msg11));
                                runFlag = TRUE;
                                onTimeInMilliSec = 630;
                                offTimeInMilliSec = 1260;
                            }
                      }
                  }
                  else if(!PORTD.F6) {
                      Delay_ms(50);
                      if(!PORTD.F6) {
                            if(runOnceFlag) {
                                LCD_Cmd(_LCD_CLEAR);
                                LCD_Out(1,1,CopyConst2Ram(msg, msg12));
                                runFlag = TRUE;
                                onTimeInMilliSec = 560;
                                offTimeInMilliSec = 1120;                                                                                           ;
                            }
                      }
                  }
                  else if(!PORTD.F7) {
                      Delay_ms(50);
                      if(!PORTD.F7) {
                            if(runOnceFlag) {
                                LCD_Cmd(_LCD_CLEAR);
                                LCD_Out(1,1,CopyConst2Ram(msg, msg13));
                                runFlag = TRUE;
                                onTimeInMilliSec = 500;
                                offTimeInMilliSec = 1000;
                            }
                      }
                  }
                  
                  if(runOnceFlag) {
                      toggleOnTimeOffTime = 1;
                      SOLENOID = ON;
                      InitTimer1();
                      runOnceFlag = CLEAR;
                  }
          }
          
          if(resetFlag == TRUE) {
                  LCD_Cmd(_LCD_CLEAR);
                  LCD_Out(1,1,CopyConst2Ram(msg, msg14));
                  resetFlag = CLEAR;
          }
    }
}

 
Last edited:
Hi, no i have completely removed LEDs it was not a necessary requirement. Thank you so much, code works really well in proteus however i will check on the circuit as well. This is totally different than how i had programmed which means i have to learn a lot about PIC programming. Can you help me with some tutorials on PIC programming?
 

I have only learnt by reading embedded programming books and practically doing the projects. If you want I can provide you a list of books that you can read.

Here is the final code.

Rotary position has to be set and then start button has to be pressed. If system is running and rotary position is changed then LCD data doesn't change and also function doesn't change. To change function you have to stop the system and change the rotary position and then start the system.


Code C - [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
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
sbit LCD_RS at RB1_bit;
sbit LCD_EN at RB2_bit;
sbit LCD_D4 at RB3_bit;
sbit LCD_D5 at RB4_bit;
sbit LCD_D6 at RB5_bit;
sbit LCD_D7 at RB6_bit;
 
sbit LCD_RS_Direction at TRISB1_bit;
sbit LCD_EN_Direction at TRISB2_bit;
sbit LCD_D4_Direction at TRISB3_bit;
sbit LCD_D5_Direction at TRISB4_bit;
sbit LCD_D6_Direction at TRISB5_bit;
sbit LCD_D7_Direction at TRISB6_bit;
 
sbit SOLENOID at RC3_bit;
 
#define ON 1
#define OFF 0
 
#define TRUE 1
#define FALSE 0
 
#define INPUT 1
#define OUTPUT 0
 
#define SET 1
#define CLEAR 0
 
#define START_BUTTON_PRESSED (!PORTC.F2)
#define START_BUTTON_NOT_YET_RELEASED (!PORTC.F2)
 
#define FUNCTION_1_SELECTED (!PORTD.F0)
#define FUNCTION_2_SELECTED (!PORTD.F1)
#define FUNCTION_3_SELECTED (!PORTD.F2)
#define FUNCTION_4_SELECTED (!PORTD.F3)
#define FUNCTION_5_SELECTED (!PORTC.F4)
#define FUNCTION_6_SELECTED (!PORTC.F5)
#define FUNCTION_7_SELECTED (!PORTC.F6)
#define FUNCTION_8_SELECTED (!PORTC.F7)
#define FUNCTION_9_SELECTED (!PORTD.F4)
#define FUNCTION_A_SELECTED (!PORTD.F5)
#define FUNCTION_B_SELECTED (!PORTD.F6)
#define FUNCTION_C_SELECTED (!PORTD.F7)
 
char myFlags = 0;
char msg[20];
unsigned int onTimeInMilliSec = 0, offTimeInMilliSec = 0, milliSecCounter = 0;
 
const char msg1[] = "Select BPM rate";
const char msg2[] = "8 BPM";
const char msg3[] = "10 BPM";
const char msg4[] = "12 BPM";
const char msg5[] = "14 BPM";
const char msg6[] = "16 BPM";
const char msg7[] = "18 BPM";
const char msg8[] = "20 BPM";
const char msg9[] = "24 BPM";
const char msg10[] = "28 BPM";
const char msg11[] = "32 BPM";
const char msg12[] = "36 BPM";
const char msg13[] = "40 BPM";
const char msg14[] = "Stopped";
 
sbit runFlag at myFlags.B0;
sbit resetFlag at myFlags.B1;
sbit solenoidControlFlag at myFlags.B2;
sbit toggleOnTimeOffTime at myFlags.B3;
sbit runOnceFlag at myFlags.B4;
 
//Timer1
//Prescaler 1:1; TMR1 Preload = 15536; Actual Interrupt Time : 10 ms
 
//Place/Copy this part in declaration section
void InitTimer1() {
    T1CON = 0x01;
    TMR1IF_bit = 0;
    TMR1H = 0x3C;
    TMR1L = 0xB0;
    TMR1IE_bit = 1;
    INTCON = 0xC0;
}
 
void interrupt() {
    if(INTF_bit) {
        PORTC.F3 = 0;
        runFlag = CLEAR;
        resetFlag = TRUE;
        TMR1ON_bit = 0;
        INTE_bit = 0;
        INTF_bit = CLEAR;
    }
 
    if(TMR1IF_bit) {
        TMR1H = 0xFC;
        TMR1L = 0x18;
 
        if(runFlag) {
            ++milliSecCounter;
            if(toggleOnTimeOffTime) {
                if(milliSecCounter == onTimeInMilliSec) {
                        SOLENOID = OFF;
                        milliSecCounter = 0;
                        toggleOnTimeOffTime = 0;
                }
            }
            else if(!toggleOnTimeOffTime) {
                if(milliSecCounter == offTimeInMilliSec) {
                        SOLENOID = ON;
                        milliSecCounter = 0;
                        toggleOnTimeOffTime = 1;
                }
            }
        }
 
        TMR1IF_bit = 0;
    }
}
 
//copy const to ram string
char *CopyConst2Ram(char *dest, const char *src) {
    char *d;
 
    d = dest;
    for(;*dest++ = *src++;);
 
    return d;
}
 
void main() {
 
    CMCON = 0x07;
    CVRCON = 0x00;
    ADCON1 = 0x87;
 
    TRISA = 0x00;
    TRISB = 0x01;
    TRISC = 0xF4;
    TRISD = 0xFF;
    TRISE = 0x00;
 
    PORTA = 0x00;
    PORTB = 0x00;
    PORTC = 0x00;
    PORTD = 0x00;
    PORTE = 0x00;
 
    LCD_Init();
    Delay_ms(200);
    LCD_cmd(_LCD_CURSOR_OFF);
    LCD_Cmd(_LCD_CLEAR);
    LCD_Out(1,1,CopyConst2Ram(msg, msg1));
 
    INTEDG_bit = 1;
 
    runOnceFlag = 1;
 
    while(1) {
 
          if(START_BUTTON_PRESSED) {
              Delay_ms(50);
              while(START_BUTTON_NOT_YET_RELEASED);
 
                  runOnceFlag = TRUE;
                  LCD_Cmd(_LCD_CLEAR);
 
                  if(FUNCTION_1_SELECTED) {
                      Delay_ms(50);
                      if(FUNCTION_1_SELECTED) {
                            if(runOnceFlag) {
                                LCD_Out(1,1,CopyConst2Ram(msg, msg2));
                                runFlag = TRUE;
                                onTimeInMilliSec = 250;
                                offTimeInMilliSec = 500;
                            }
                      }
                  }
                  else if(FUNCTION_2_SELECTED) {
                      Delay_ms(50);
                      if(FUNCTION_2_SELECTED) {
                            if(runOnceFlag) {
                                LCD_Out(1,1,CopyConst2Ram(msg, msg3));
                                runFlag = TRUE;
                                onTimeInMilliSec = 200;
                                offTimeInMilliSec = 400;
                            }
                      }
                  }
                  else if(FUNCTION_3_SELECTED) {
                      Delay_ms(50);
                      if(FUNCTION_3_SELECTED) {
                            if(runOnceFlag) {
                                LCD_Out(1,1,CopyConst2Ram(msg, msg4));
                                runFlag = TRUE;
                                onTimeInMilliSec = 167;
                                offTimeInMilliSec = 333;
                            }
                      }
                  }
                  else if(FUNCTION_4_SELECTED) {
                      Delay_ms(50);
                      if(FUNCTION_4_SELECTED) {
                            if(runOnceFlag) {
                                LCD_Out(1,1,CopyConst2Ram(msg, msg5));
                                runFlag = TRUE;
                                onTimeInMilliSec = 143;
                                offTimeInMilliSec = 285;
                            }
                      }
                  }
                  else if(FUNCTION_5_SELECTED) {
                      Delay_ms(50);
                      if(FUNCTION_5_SELECTED) {
                            if(runOnceFlag) {
                                LCD_Out(1,1,CopyConst2Ram(msg, msg6));
                                runFlag = TRUE;
                                onTimeInMilliSec = 125;
                                offTimeInMilliSec = 250;
                            }
                      }
                  }
                  else if(FUNCTION_6_SELECTED) {
                      Delay_ms(50);
                      if(FUNCTION_6_SELECTED) {
                            if(runOnceFlag) {
                                LCD_Out(1,1,CopyConst2Ram(msg, msg7));
                                runFlag = TRUE;
                                onTimeInMilliSec = 111;
                                offTimeInMilliSec = 222;
                            }
                      }
                  }
                  else if(FUNCTION_7_SELECTED) {
                      Delay_ms(50);
                      if(FUNCTION_7_SELECTED) {
                            if(runOnceFlag) {
                                LCD_Out(1,1,CopyConst2Ram(msg, msg8));
                                runFlag = TRUE;
                                onTimeInMilliSec = 100;
                                offTimeInMilliSec = 200;
                            }
                      }
                  }
                  else if(FUNCTION_8_SELECTED) {
                      Delay_ms(50);
                      if(FUNCTION_8_SELECTED) {
                            if(runOnceFlag) {
                                LCD_Out(1,1,CopyConst2Ram(msg, msg9));
                                runFlag = TRUE;
                                onTimeInMilliSec = 83;
                                offTimeInMilliSec = 166;
                            }
                      }
                  }
                  else if(FUNCTION_9_SELECTED) {
                      Delay_ms(50);
                      if(FUNCTION_9_SELECTED) {
                            if(runOnceFlag) {
                                LCD_Out(1,1,CopyConst2Ram(msg, msg10));
                                runFlag = TRUE;
                                onTimeInMilliSec = 72;
                                offTimeInMilliSec = 144;
                            }
                      }
                  }
                  else if(FUNCTION_A_SELECTED) {
                      Delay_ms(50);
                      if(FUNCTION_A_SELECTED) {
                            if(runOnceFlag) {
                                LCD_Out(1,1,CopyConst2Ram(msg, msg11));
                                runFlag = TRUE;
                                onTimeInMilliSec = 63;
                                offTimeInMilliSec = 126;
                            }
                      }
                  }
                  else if(FUNCTION_B_SELECTED) {
                      Delay_ms(50);
                      if(FUNCTION_B_SELECTED) {
                            if(runOnceFlag) {
                                LCD_Out(1,1,CopyConst2Ram(msg, msg12));
                                runFlag = TRUE;
                                onTimeInMilliSec = 56;
                                offTimeInMilliSec = 112;                                                                                           ;
                            }
                      }
                  }
                  else if(FUNCTION_C_SELECTED) {
                      Delay_ms(50);
                      if(FUNCTION_C_SELECTED) {
                            if(runOnceFlag) {
                                LCD_Out(1,1,CopyConst2Ram(msg, msg13));
                                runFlag = TRUE;
                                onTimeInMilliSec = 50;
                                offTimeInMilliSec = 100;
                            }
                      }
                  }
 
                  if(runOnceFlag) {
                      toggleOnTimeOffTime = 1;
                      SOLENOID = ON;
                      INTF_bit = 0;
                      INTE_bit = 1;
                      InitTimer1();
                      runOnceFlag = CLEAR;
                  }
          }
 
          if(resetFlag == TRUE) {
                  LCD_Cmd(_LCD_CLEAR);
                  LCD_Out(1,1,CopyConst2Ram(msg, msg14));
                  resetFlag = CLEAR;
          }
    }
}

 
Last edited:

Ensure that all 12V and 12V return lines are twisted pair or low transmission line impedance and shielded to reduce stray coupling of H fields into high impedance reset lines. If Reset is low impedance then the problem is conducted ground shift.

Also ensure 12V return is not in series with 5V return so that ground shift does not occur during turn off.

There are two potential causes; Radiated and Conducted depending on your layout.

Decoupling caps with low ESR help isolate the ground shift along with path control.

Small RF caps across the coil serve to lower the resonant frequency below diode conduction to reduce the E field coupling. Often a CM choke is necessary to reduce E field radiation close to signal wires. as Diode capacitance and coil inductance creates a resonant frequency during decay < 0.7V . Sometimes a dampening resistor reduces this decay time across the coil. Coupling E fields increases with frequency.
 

MCLR.PNG

Remove this voltage divider form MCLR, just conect "MCLR" pin to Vdd (or use 1K resistor) as it needs a strong pull-up.
What is your power supply capacity? Can it handle your solonoid?
When solonoid get on/off it introduce noise into the power lines, do you have any noise filtering section for 12V to 5V converter section?
What is your brown-out voltage of PIC?
 

I built projects for years without using inductors and filtered only with caps both large and small. Then I got hold of a hand full of small 15uH inductors and started using them in front of a 220uF cap any time a voltage went from part of a circuit to another to supply a rail.
This made a vast improvement to noise immunity of the micro and other circuits.
Regards,
John.
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top