PDA

View Full Version : PLz Help! Serin and Serout Confusion



noor31
- 13th June 2014, 11:04
I used to do uart using mikroC but now i need to do a simple serial communication between two pics the sender has a button on portb.0 acts as a start button and a led on the other receiver pic has a led on portb.0 to blink when button pressed Here's The Code

Sender:

INCLUDE "modedefs.bas"
#CONFIG


#endconfig


Define OSC 8


' Main program loop
start:
if portb.1==0 then 'button pressed


Serout portc.6, 2, ["A"]
endif


Goto start
End



Reciever:

#CONFIG
#endconfig


Define OSC 8


' Main program loop
start:


Serin portc.7,2,["A"]
if portc.7=="A" then
high portb.0
pause 500
low portb.0
pause 500
endif
Goto start
End

HenrikOlsson
- 13th June 2014, 11:22
Hi,
Welcome to the forum.
Which PIC are you using? Depending on which on it is you might need to enable digital mode on the pins you're using. Check comparator and ADC section of the datasheet to find out if it's applicable in your case.

Your send code looks alright although I'd probably introduce some delay or interlock mechanism so that it sends "A" one time for each button press. As it's currently written it keeps sending "A" (rapidly) as long as the button is held down - perhaps that's what you want, I don't know.

Your receiver code on the other hand isn't quite alright.

Serin portc.7,2,["A"]
if portc.7=="A" then

You need to create a variable, use that in the SERIN statment and then check the content of the variable with the IF statement.

char VAR BYTE
SERIN PortC.7, 2, [char]
IF char = "A" THEN
Something like that.

Also, your CONFIG/ENDCONFIG block is blank and that's probably not that great. You either don't include it at all thus relying on the PBP default for the particlar chip OR you include it with ALL the settings (or at least those you want changed from what the hardware default (see datasheet) is.)

Finally, whenever you're posting code to the forum please do use the appropriate code tags, see here. (http://www.bbcode.org/reference.php)

/Henrik.

/Henrik.

noor31
- 13th June 2014, 12:04
Thanks for your response um using pic 16f877a so portb and c is away from adc and comparator section, for the delay i put it but how it sends "A" one time for each button press if um pressing the button more than the delay time, for the CONFIG/ENDCONFIG block it makes error at the end of the compiling um using mikroCode studio PBP3
Here's The Edit I did using code tags :D

Sender Code


#CONFIG

#endconfig

Define OSC 8

portc=255
char var byte

' Main program loop
start:

if portc.1==0 then 'button pressed
char = "A"
Serout portb.0, 2,[char]
pause 500
endif

Goto start
End



Recieve Code


'Reciever Code
#CONFIG
#endconfig

Define OSC 8

char var byte
' Main program loop
start:

Serin portb.0,2,char
pause 500
if (char == "A" ) then
high portb.1
pause 500
low portb.1
pause 500
endif
Goto start
End

HenrikOlsson
- 13th June 2014, 13:07
Hi,
In order to have it send once for each buttonpress you could do something like

Start:
IF PortC.1 = 0 then ' Button is pressed
Serout portb.0, 2,["A"]
Pause 10 ' Allow for debounce, may need tweaking, or can possibly be removed
While PortC.1 = 0 : WEND ' Loop here untill button is released.
Pause 25 ' Allow for debounce on release
ENDIF
Goto Start

If the #CONFIG/#ENDCONFIG gives you an error then I'd concentrate on fixing that error. Don't leave the block blank like that, either set it properly or remove it altogether and let PBP insert its default. If you don't know what the default is for your particular PIC then look in the DEVICE_ If you leave it empty like that I think what you'll end up with is what the CONFIG word is by default on an erased PIC - is that what you want?

/Henrik.

noor31
- 13th June 2014, 15:52
Yes I guess i needed the default it worked better alone but when i added it to the main code the button works when its pressed and also when its released! according to the code (the two pwm should be off and the lcd should be clear too)

another thing is when i simulate it the pwm works only 30% duty cycle whatever the voltage is

Here's the main code

DEFINE OSC 8 'LCD CONFIGURATION
DEFINE LCD_DREG PORTB 'Define PIC port used for LCD Data lines
DEFINE LCD_DBIT 4 'Define first pin of portb connected to LCD DB4
DEFINE LCD_RSREG PORTB 'Define PIC port used for RS line of LCD
DEFINE LCD_RSBIT 3 'Define Portb pin used for RS connection Communication
DEFINE LCD_EREG PORTB 'Define PIC prot used for E line of LCD
DEFINE LCD_EBIT 0 'Define PortB pin used for E connection
DEFINE LCD_BITS 4 'Define the 4 bit communication mode to LCD
DEFINE LCD_LINES 2 'Define using a 2 line LCD
DEFINE LCD_COMMANDUS 2000 'Define delay between sending LCD commands
DEFINE LCD_DATAUS 50 'Define delay time between data sent.
'PWM CONFIGURATION
DEFINE CCP1 REG PORTC 'Port to be used by HPWM1
DEFINE CCP1_BIT 2 'Pin to be used by Hpwm1
DEFINE CCP2 REG PORIIC 'Port to be used by HPWM2
DEFINE CCP2_BIT 1 'Pin to be used by hwmp2
'ADC CONFIGURATION
Define ADC_BITS 10 '10 bit result
define ADC_clock 3 '8mhz external clock
define ADC_Samplus 50
trisA= 255 'all PORTA pins are inputs
adcon1= %10000010 ' Set PORTA analog and right justify
trisc=0
portc=0


Temp var word 'Temp out of Lm35
Vp var word 'Voltage out of Pressure Sensor
Vl var word 'Voltage out of Level Sensor
char var byte

main:
Serin portc.7,2,char 'Receive data sent from the transmitting pic
if (char == "A" ) then 'if data is character A

pause 50
Adcin 0, Temp ' Read channel 0 to Temp (0-1023)
Temp = (Temp */ 500)>>2 ' Equates to: (Temp * 500)/1024
LCDOut ,$fe,$80,"Temp= ",DEC2 Temp 'Display Temp On The First Line

Adcin 1, Vp 'Read channel 1 to Vp (0-1023)
Vp = (Vp */ 500)>>2 'Equates to: (Vp * 500)/1024
LCDOut $fe,$c0 ,"Pressure = ",DEC (Vp/100),".", DEC2 Vp," volt" 'Display Voltage out of pressure sensor on second line

Adcin 2, Vl 'Read channel 2 to Vl (0-1023)
Vl = (Vl */ 500)>>2 'Equates to: (Vl * 500)/1024
LCDOut $fe,$94 ,"Level= ",DEC (Vl/100),".", DEC2 Vl," volt" 'Display Voltage out of Level sensor on third line


if portd.0==0 then 'Soil Moisture is lower than preset value
if Vp<3 then 'Voltage From Pressure Sensor is Less than preset value (3 volt)
Hpwm 2, 179,5000 'Solenoid is on with 70% duty cycle at 5 khz
if Vl<3 then 'If voltage of Level sensor is Less than preset value (3 volt)
hpwm 1,179,5000 'Pump is on with 70% duty cycle at 5 khz
elseif Vl>=3 then 'If voltage of Level sensor is more than or equal preset value
hpwm 1,77,5000 'Pump is on with 30% duty cycle at 5 khz
ENDIF
elseif Vp>=3 then 'Voltage From Pressure Sensor is more than or equal preset value (3 volt)
hpwm 2,77,5000 'Solenoid is on with 30% duty cycle at 5 khz
if Vl<3 then 'If voltage of Level sensor is less than preset value (3 volt)
hpwm 1,179,5000 'Pump is on with 70% duty cycle at 5 khz
elseif Vl>=3 then 'If voltage of Level sensor is more than or equal preset value
hpwm 1,77,5000 'Pump is on with 30% duty cycle at 5 khz
endif
endif
elseif portd.0!=0 then 'Soil Moisture is high or equal to preset value
hpwm 1,0,5000 'Turn off Pump
hpwm 2,0,5000 'Turn off Solenoid
endif
elseif char!="A" then
lcdout $fe,1 'Clear LCD
hpwm 1,0,5000 'Turn off Pump
hpwm 2,0,5000 'Turn off Solenoid
endif





Goto main 'Do it forever



End

HenrikOlsson
- 13th June 2014, 18:24
Hi,
Well, I think the issue is that when you press the button the first time it sends "A" and the receiver responds by setting the PWM outputs etc. But when you release the button the sending PIC does nothing, thus the receiver sits at the SERIN command waiting for something to come while the PWM outputs are active in the background.

You need to change it so that sends sends "A" when the button is pressed and something else when it's released.

At least that's what I think is going on.

/Henrik.

noor31
- 14th June 2014, 13:34
i really appreciate ur help but I did what u said and the problem still there and the pwm is fixed at 30% duty even when um changing the volt here's the code

sender:


'Sender Code


Define OSC 8

char var byte

' Main program loop
start:

if (portb.0==0) then 'button pressed
char = "A" 'character A sent to the other pic
Serout portc.6, 2,[char]

pause 50
elseif (portb.0!=0) then
char = "B"
Serout portc.6, 2,[char]

pause 50

endif

Goto start
End

Reciever

DEFINE OSC 8
'LCD CONFIGURATION
DEFINE LCD_DREG PORTB 'Define PIC port used for LCD Data lines
DEFINE LCD_DBIT 4 'Define first pin of portb connected to LCD DB4
DEFINE LCD_RSREG PORTB 'Define PIC port used for RS line of LCD
DEFINE LCD_RSBIT 3 'Define Portb pin used for RS connection Communication
DEFINE LCD_EREG PORTB 'Define PIC prot used for E line of LCD
DEFINE LCD_EBIT 0 'Define PortB pin used for E connection
DEFINE LCD_BITS 4 'Define the 4 bit communication mode to LCD
DEFINE LCD_LINES 2 'Define using a 2 line LCD
DEFINE LCD_COMMANDUS 2000 'Define delay between sending LCD commands
DEFINE LCD_DATAUS 50 'Define delay time between data sent.
'PWM CONFIGURATION
DEFINE CCP1 REG PORTC 'Port to be used by HPWM1
DEFINE CCP1_BIT 2 'Pin to be used by Hpwm1
DEFINE CCP2 REG PORIIC 'Port to be used by HPWM2
DEFINE CCP2_BIT 1 'Pin to be used by hwmp2
'ADC CONFIGURATION
Define ADC_BITS 10 '10 bit result
define ADC_clock 3 '8mhz external clock
define ADC_Samplus 50
trisA= 255 'all PORTA pins are inputs
adcon1= %10000010 ' Set PORTA analog and right justify
trisc=0
portc=0

Temp var word 'Temp out of Lm35
Vp var word 'Voltage out of Pressure Sensor
Vl var word 'Voltage out of Level Sensor
char var byte

main:
Serin portc.7,2,char 'Receive data sent from the transmitting pic
if (char == "A" ) then 'if data is character A

pause 50
Adcin 0, Temp ' Read channel 0 to Temp (0-1023)
Temp = (Temp */ 500)>>2 ' Equates to: (Temp * 500)/1024
LCDOut ,$fe,$80,"Temp= ",DEC2 Temp 'Display Temp On The First Line

Adcin 1, Vp 'Read channel 1 to Vp (0-1023)
Vp = (Vp */ 500)>>2 'Equates to: (Vp * 500)/1024
LCDOut $fe,$c0 ,"Pressure = ",DEC (Vp/100),".", DEC2 Vp," volt" 'Display Voltage out of pressure sensor on second line

Adcin 2, Vl 'Read channel 2 to Vl (0-1023)
Vl = (Vl */ 500)>>2 'Equates to: (Vl * 500)/1024
LCDOut $fe,$94 ,"Level= ",DEC (Vl/100),".", DEC2 Vl," volt" 'Display Voltage out of Level sensor on third line

if portd.0==0 then 'Soil Moisture is lower than preset value
if Vp<3 then 'Voltage From Pressure Sensor is Less than preset value (3 volt)
Hpwm 2, 179,5000 'Solenoid is on with 70% duty cycle at 5 khz
if Vl<3 then 'If voltage of Level sensor is Less than preset value (3 volt)
hpwm 1,179,5000 'Pump is on with 70% duty cycle at 5 khz
elseif Vl>=3 then 'If voltage of Level sensor is more than or equal preset value
hpwm 1,77,5000 'Pump is on with 30% duty cycle at 5 khz
ENDIF
elseif Vp>=3 then 'Voltage From Pressure Sensor is more than or equal preset value (3 volt)
hpwm 2,77,5000 'Solenoid is on with 30% duty cycle at 5 khz
if Vl<3 then 'If voltage of Level sensor is less than preset value (3 volt)
hpwm 1,179,5000 'Pump is on with 70% duty cycle at 5 khz
elseif Vl>=3 then 'If voltage of Level sensor is more than or equal preset value
hpwm 1,77,5000 'Pump is on with 30% duty cycle at 5 khz
endif
endif
elseif portd.0!=0 then 'Soil Moisture is high or equal to preset value
hpwm 1,0,5000 'Turn off Pump
hpwm 2,0,5000 'Turn off Solenoid
endif
elseif char=="B" then
lcdout $fe,1 'Clear LCD
hpwm 1,0,5000 'Turn off Pump
hpwm 2,0,5000 'Turn off Solenoid
endif



Goto main 'Do it forever

End

HenrikOlsson
- 14th June 2014, 20:45
Hi,
Without looking at the code in detail it's possible that the two devices are getting out of sync due to the fact that sender is constantly sending either "A" or "B".
What if you, boil the code down to a bare minimum and instead of comparing with "B" compare with anytning but "A"?


SERIN PortC.7, 2, Char
IF Char = "A" THEN
HPWM 1, 77, 5000
ELSE
HPWM 1, 0, 5000
ENDIF

/Henrik.

EarlyBird2
- 15th June 2014, 09:46
another thing is when i simulate it the pwm works only 30% duty cycle whatever the voltage is


This code


Vp = (Vp */ 500)>>2 'Equates to: (Vp * 500)/1024
LCDOut $fe,$c0 ,"Pressure = ",DEC (Vp/100),".", DEC2 Vp," volt" 'Display Voltage out of pressure sensor on second line


Divides Vp by 100 to display volts. So this line for example


if Vp<3 then 'Voltage From Pressure Sensor is Less than preset value (3 volt)


should be


if Vp<300 then 'Voltage From Pressure Sensor is Less than preset value (3 volt)

EarlyBird2
- 15th June 2014, 11:03
Many of your elseif comparators could simply be else. The code also sets Hpwm then enters "if then" potentially changing the value again the first Hpwm is not needed. Just to give you some ideas here is an example of what could be done. I have included a space either side of the comparators, Vp < 300 not Vp<300. Just personal preference on my part? Probably but I have learned to be very strict with code syntax.



main:
Serin portc.7,2,char 'Receive data sent from the transmitting pic
if (char = "A" ) then 'if data is character A

pause 50
Adcin 0, Temp ' Read channel 0 to Temp (0-1023)
Temp = (Temp */ 500)>>2 ' Equates to: (Temp * 500)/1024
LCDOut ,$fe,$80,"Temp= ",DEC2 Temp 'Display Temp On The First Line

Adcin 1, Vp 'Read channel 1 to Vp (0-1023)
Vp = (Vp */ 500)>>2 'Equates to: (Vp * 500)/1024
LCDOut $fe,$c0 ,"Pressure = ",DEC (Vp/100),".", DEC2 Vp," volt" 'Display Voltage out of pressure sensor on second line

Adcin 2, Vl 'Read channel 2 to Vl (0-1023)
Vl = (Vl */ 500)>>2 'Equates to: (Vl * 500)/1024
LCDOut $fe,$94 ,"Level= ",DEC (Vl/100),".", DEC2 Vl," volt" 'Display Voltage out of Level sensor on third line

if portd.0 = 0 then 'Soil Moisture is lower than preset value
if Vp < 300 then 'Voltage From Pressure Sensor is Less than preset value (3 volt)
if Vl < 300 then 'If voltage of Level sensor is Less than preset value (3 volt)
hpwm 1,179,5000 'Pump is on with 70% duty cycle at 5 khz
else 'If voltage of Level sensor is more than or equal preset value
hpwm 1,77,5000 'Pump is on with 30% duty cycle at 5 kHz
endif 'vl <
endif 'vp<
if Vp >= 300 then 'Voltage From Pressure Sensor is more than or equal preset value (3 volt)
if Vl < 300 then 'If voltage of Level sensor is less than preset value (3 volt)
hpwm 1,179,5000 'Pump is on with 70% duty cycle at 5 khz
else 'If voltage of Level sensor is more than or equal preset value
hpwm 1,77,5000 'Pump is on with 30% duty cycle at 5 khz
endif 'vl<
endif 'vp>
endif '=

if portd.0 != 0 then 'Soil Moisture is high or equal to preset value
hpwm 1,0,5000 'Turn off Pump
hpwm 2,0,5000 'Turn off Solenoid
endif '!=
endif 'A

if (char = "B") then
lcdout $fe,1 'Clear LCD
hpwm 1,0,5000 'Turn off Pump
hpwm 2,0,5000 'Turn off Solenoid
endif



Goto main 'Do it forever


I am now thinking why sending "B" does not work and an answer eludes me. I need time for more thought.

noor31
- 15th June 2014, 17:01
I appreciate your response due to pwm it did helped me :D in addition to some modifications the code is now working with zero error except its a little bit slow while simulating but thats okai xD

Here's my final code :
reciever:


Include "modedefs.bas"
DEFINE OSC 20
'LCD CONFIGURATION
DEFINE LCD_DREG PORTB 'Define PIC port used for LCD Data lines
DEFINE LCD_DBIT 4 'Define first pin of portb connected to LCD DB4
DEFINE LCD_RSREG PORTB 'Define PIC port used for RS line of LCD
DEFINE LCD_RSBIT 3 'Define Portb pin used for RS connection Communication
DEFINE LCD_EREG PORTB 'Define PIC prot used for E line of LCD
DEFINE LCD_EBIT 0 'Define PortB pin used for E connection
DEFINE LCD_BITS 4 'Define the 4 bit communication mode to LCD
DEFINE LCD_LINES 2 'Define using a 2 line LCD
DEFINE LCD_COMMANDUS 2000 'Define delay between sending LCD commands
DEFINE LCD_DATAUS 50 'Define delay time between data sent.
'PWM CONFIGURATION
DEFINE CCP1 REG PORTC 'Port to be used by HPWM1
DEFINE CCP1_BIT 2 'Pin to be used by Hpwm1
DEFINE CCP2 REG PORIIC 'Port to be used by HPWM2
DEFINE CCP2_BIT 1 'Pin to be used by hwmp2
'ADC CONFIGURATION
Define ADC_BITS 10 '10 bit result
define ADC_clock 3 '8mhz external clock
define ADC_Samplus 50
trisA= 255 'all PORTA pins are inputs
adcon1= %10000010 ' Set PORTA analog and right justify
trisc=0
portc=0

Temp var word 'Temp out of Lm35
Vp var word 'Voltage out of Pressure Sensor
Vl var word 'Voltage out of Level Sensor
char var byte

SCL VAR PORTC.3 ' Clock pin
SDA VAR PORTC.4 ' Data pin
B0 VAR BYTE
B1 VAR BYTE
B2 var byte
B3 var byte
address VAR WORD
address=17


main:

Serin portc.7,2,char 'Receive data sent from the transmitting pic
if (char == "A" ) then 'if data is character A
pause 10

Adcin 0, Temp ' Read channel 0 to Temp (0-1023)
Temp = (Temp */ 500)>>2 ' Equates to: (Temp * 500)/1024
lcdout $fe,$80,"Temp= ",dec2 Temp 'Display Temp On The First Line

Adcin 1, Vp 'Read channel 1 to Vp (0-1023)
Vp = (Vp */ 500)>>2 'Equates to: (Vp * 500)/1024
LCDOut $fe,$c0 ,"Pressure = ",DEC (Vp/100),".", DEC2 Vp 'Display Voltage out of pressure sensor on second line

Adcin 2, Vl 'Read channel 2 to Vl (0-1023)
Vl = (Vl */ 500)>>2 'Equates to: (Vl * 500)/1024
LCDOut $fe,$94 ,"Level= ",DEC (Vl/100),".", DEC2 Vl 'Display Voltage out of Level sensor on third line

i2cwrite SDA,SCL,%10100000,address,[B0,B1] 'Writes two data to i2c
pause 10
I2CRead SDA,SCL,%10100001,address,[B2,B3] 'Read 2 locations in a row
pause 10
LCDOut $fe,$D4,#address,":",#B1,"%P ",#B0,"%S "

if portd.0==0 then 'Soil Moisture is lower than preset value

if Vp<300 then 'Voltage From Pressure Sensor is Less than preset value (3 volt)
hpwm 2,179,5000 'Solenoid is on with 70% duty cycle at 5khz
B0=70 'Data (70%duty cycle of the soloneid)

if Vl<300 then 'If voltage of Level sensor is Less than preset value (3 volt)
hpwm 1,179,5000 'Pump is on with 70% duty cycle at 5 khz
B1=70 'Data (70%duty cycle of the Pump)
else
hpwm 1,77,5000 'Pump is on with 30% duty cycle at 5 khz
B1=30 'Data (30%duty cycle of the Pump)
endif
else
hpwm 2,77,5000
B0=30

if Vl<300 then
hpwm 1,179,5000
B1=70
else
hpwm 1,77,5000
B1=30
endif

endif
else 'Soil Moisture is high or equal to preset value
hpwm 1,0,5000 'Turn off Pump
hpwm 2,0,5000 'Turn off Solenoid
B0=0
B1=0

endif

else
lcdout $fe,1 'Clear LCD
hpwm 1,0,5000 'Turn off Pump
hpwm 2,0,5000 'Turn off Solenoid
Serin portc.7,2,char 'Receive data sent from the transmitting pic
ENDIF


Goto main 'Do it forever

End

Sender:



'Sender Code


Define OSC 20

char var byte

' Main program loop
start:

if (portb.0==0) then 'button pressed
char = "A" 'character A sent to the other pic
Serout portc.6, 2,[char]

pause 10

else
char = "B"
Serout portc.6, 2,[char]

pause 10

endif

Goto start
End
although i didnt get what it means endif like this( endif 'vl < ) but i will search for it for sure .Thanks again for the help and the fast response ^_^

EarlyBird2
- 16th June 2014, 09:44
although i didnt get what it means endif like this( endif 'vl < ) but i will search for it for sure .


Is just my annotation to indicate the if-endif pair. I find this useful when there are many if-endif commands but it is not necessary.

Now it is working are you going to make any improvements?

noor31
- 16th June 2014, 19:51
For the code? no not right now i need to know how to make the power supply for this circuit then doin the pcb layout