The uln2803 only drive the relay not valve.The ULN2803 has internal diodes so that's OK.
...
Good luck.
The uln2803 only drive the relay not valve.The ULN2803 has internal diodes so that's OK.
...
Good luck.
So the valve is not suppressed???The uln2803 only drive the relay not valve.
He seems didn't mention that.So the valve is not suppressed???
Max.
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;
}
}
}
Or why not use a device designed for this application?Why ULN2803 to drive a single relay ? Why not use a BC337 ?
.
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 VALVE 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 CLOSE 0
#define OPEN 1
#define ENABLE_WATCH_DOG_TIMER {OPTION_REG = 0xCF;}
#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)
#define CLOSE_VALVE {VALVE = OFF;}
#define OPEN_VALVE {VALVE = ON;}
#define FUNCTION_SELECTED ((FUNCTION_1_SELECTED) || (FUNCTION_2_SELECTED) || (FUNCTION_3_SELECTED) || (FUNCTION_4_SELECTED) || (FUNCTION_5_SELECTED) || (FUNCTION_6_SELECTED) || (FUNCTION_7_SELECTED) || (FUNCTION_8_SELECTED) || (FUNCTION_9_SELECTED) || (FUNCTION_A_SELECTED) || (FUNCTION_B_SELECTED) || (FUNCTION_C_SELECTED))
/*
#define FUNCTION_SELECTED ((FUNCTION_1_SELECTED) || (FUNCTION_2_SELECTED)
|| (FUNCTION_3_SELECTED) || (FUNCTION_4_SELECTED)
|| (FUNCTION_5_SELECTED) || (FUNCTION_6_SELECTED)
|| (FUNCTION_7_SELECTED) || (FUNCTION_8_SELECTED)
|| (FUNCTION_9_SELECTED) || (FUNCTION_A_SELECTED)
|| (FUNCTION_B_SELECTED) || (FUNCTION_C_SELECTED))
*/
char myFlags = 0;
char msg[20];
unsigned int onTimeDelayCountValue = 0, offTimeDelayCountValue = 0, milliSecCounter = 0;
unsigned short systemRestarted = 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";
const char msg15[] = "System Restarted";
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) {
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 == onTimeDelayCountvalue) {
CLOSE_VALVE
milliSecCounter = 0;
toggleOnTimeOffTime = 0;
}
}
else if(!toggleOnTimeOffTime) {
if(milliSecCounter == offTimeDelayCountValue) {
OPEN_VALVE
milliSecCounter = 0;
toggleOnTimeOffTime = 1;
}
}
}
TMR1IF_bit = 0;
}
}
//copy const to ram string
char *CopyConst2Ram(char *dest, const char *src) {
char *d;
asm clrwdt
d = dest;
for(;*dest++ = *src++;);
asm clrwdt
return d;
}
void DebouncSwitch() {
asm clrwdt
Delay_ms(50);
asm clrwdt
}
void CheckSelectedFunction() {
LCD_Cmd(_LCD_CLEAR);
if(runOnceFlag) {
asm clrwdt
if(FUNCTION_1_SELECTED) {
DebouncSwitch();
if(FUNCTION_1_SELECTED) {
LCD_Out(1,1,CopyConst2Ram(msg, msg2));
onTimeDelayCountvalue = 250;
offTimeDelayCountValue = 500;
}
}
else if(FUNCTION_2_SELECTED) {
DebouncSwitch();
if(FUNCTION_2_SELECTED) {
LCD_Out(1,1,CopyConst2Ram(msg, msg3));
onTimeDelayCountvalue = 200;
offTimeDelayCountValue = 400;
}
}
else if(FUNCTION_3_SELECTED) {
DebouncSwitch();
if(FUNCTION_3_SELECTED) {
LCD_Out(1,1,CopyConst2Ram(msg, msg4));
onTimeDelayCountvalue = 167;
offTimeDelayCountValue = 333;
}
}
else if(FUNCTION_4_SELECTED) {
DebouncSwitch();
if(FUNCTION_4_SELECTED) {
LCD_Out(1,1,CopyConst2Ram(msg, msg5));
onTimeDelayCountvalue = 143;
offTimeDelayCountValue = 285;
}
}
else if(FUNCTION_5_SELECTED) {
DebouncSwitch();
if(FUNCTION_5_SELECTED) {
LCD_Out(1,1,CopyConst2Ram(msg, msg6));
onTimeDelayCountvalue = 125;
offTimeDelayCountValue = 250;
}
}
else if(FUNCTION_6_SELECTED) {
DebouncSwitch();
if(FUNCTION_6_SELECTED) {
LCD_Out(1,1,CopyConst2Ram(msg, msg7));
onTimeDelayCountvalue = 111;
offTimeDelayCountValue = 222;
}
}
else if(FUNCTION_7_SELECTED) {
DebouncSwitch();
if(FUNCTION_7_SELECTED) {
LCD_Out(1,1,CopyConst2Ram(msg, msg8));
onTimeDelayCountvalue = 100;
offTimeDelayCountValue = 200;
}
}
else if(FUNCTION_8_SELECTED) {
DebouncSwitch();
if(FUNCTION_8_SELECTED) {
LCD_Out(1,1,CopyConst2Ram(msg, msg9));
onTimeDelayCountvalue = 83;
offTimeDelayCountValue = 166;
}
}
else if(FUNCTION_9_SELECTED) {
DebouncSwitch();
if(FUNCTION_9_SELECTED) {
LCD_Out(1,1,CopyConst2Ram(msg, msg10));
onTimeDelayCountvalue = 72;
offTimeDelayCountValue = 144;
}
}
else if(FUNCTION_A_SELECTED) {
DebouncSwitch();
if(FUNCTION_A_SELECTED) {
LCD_Out(1,1,CopyConst2Ram(msg, msg11));
onTimeDelayCountvalue = 63;
offTimeDelayCountValue = 126;
}
}
else if(FUNCTION_B_SELECTED) {
DebouncSwitch();
if(FUNCTION_B_SELECTED) {
LCD_Out(1,1,CopyConst2Ram(msg, msg12));
onTimeDelayCountvalue = 56;
offTimeDelayCountValue = 112;
}
}
else if(FUNCTION_C_SELECTED) {
DebouncSwitch();
if(FUNCTION_C_SELECTED) {
LCD_Out(1,1,CopyConst2Ram(msg, msg13));
onTimeDelayCountvalue = 50;
offTimeDelayCountValue = 100;
}
}
asm clrwdt
toggleOnTimeOffTime = 1;
OPEN_VALVE
INTE_bit = 1;
INTF_bit = 0;
runFlag = TRUE;
InitTimer1();
EEPROM_Write(0x01, 1);
runOnceFlag = CLEAR;
asm clrwdt
}
}
void main() {
ENABLE_WATCH_DOG_TIMER
asm clrwdt
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;
asm clrwdt
Delay_ms(200);
systemRestarted = EEPROM_Read(0x01);
Delay_ms(20);
LCD_Init();
LCD_cmd(_LCD_CURSOR_OFF);
LCD_Cmd(_LCD_CLEAR);
if(systemRestarted) {
LCD_Out(1,1,CopyConst2Ram(msg, msg15));
Delay_ms(2000);
LCD_Cmd(_LCD_CLEAR);
}
else {
LCD_Out(1,1,CopyConst2Ram(msg, msg1));
}
asm clrwdt
runOnceFlag = 1;
INTEDG_bit = 1;
asm clrwdt
while(1) {
asm clrwdt
if(FUNCTION_SELECTED) {
asm clrwdt
if(START_BUTTON_PRESSED) {
DebouncSwitch();
while(START_BUTTON_NOT_YET_RELEASED)asm clrwdt;
CheckSelectedFunction();
}
else if(systemRestarted) {
CheckSelectedFunction();
systemRestarted = 0;
}
}
if(resetFlag == TRUE) {
asm clrwdt
LCD_Cmd(_LCD_CLEAR);
LCD_Out(1,1,CopyConst2Ram(msg, msg14));
CLOSE_VALVE
runOnceFlag = TRUE;
EEPROM_Write(0x01, systemRestarted);
Delay_ms(20);
resetFlag = CLEAR;
asm clrwdt
}
}
}
for(;*dest++ = *src++;);
for(;*dest++ = *src++;)asm clrwdt;
Please mention code in which post your tried ?Hi, i tried the solenoid code on the circuit
How to you say PIC is resetting ? You say it shows "Stopped". To show "Stopped" the PIC should be running according to my code. If it shows "Stopped" after the solenoid runs for a while then it means INT0 pin (I guess) is picking moise and getting activated and as this button is used for stop the system is stopping (turning off solenoid) and showing "stopped" message. Did you try starting the system again with start button after it showed "stopped" message ? Does the syatem start again ? If you use the code in post# 52 then eeprom is implemented and it will remember the last state of the system. If you test this you will know whether system is resetting or stopping. If it resets then it will restart and show the message "System Restarted" and then previous function will start again. If it only stopped then it will show "Stopped" message.Hi, i tried the solenoid code on the circuit, but as soon as i pressed the button solenoid started stuttering continuously. display showed "stopped" continuosly..
Then the problem was with INT0 pin. Please test the code in post #52 and reply. In that code EEPROM is implemented and if PIC resets due to any reason then previous function is automatically started on restart.OK i will try that next time for now i have overcome the problem by using toggle switch and modified my previous code accordingly. so i think it was some latching issue..Now on one position of toggle switch my controller checks which rotary position is connected and shows output accordingly n valve is working fine. and on the other position of toggle it switches off system shows stopped. so far it is working properly.