View previous topic :: View next topic |
Author |
Message |
talhahs
Joined: 14 Oct 2010 Posts: 14
|
Visual Basic 6.0 serial communication with PIC 16F877A |
Posted: Mon Oct 18, 2010 10:16 pm |
|
|
Hi all,
I am working on the micro controller programming part of the following VB app. http://www.rentron.com/sending_data.htm
I am using CCS info and my MCU is PIC 16F877A. I am stuck at how to retrieve back the characters sent from VB, I need to separate them and apply them accordingly.
VB sends the pin number and its state, I need to turn ON the corresponding LED.
VB code:
Code: |
' Send Out Data
MSComm1.Output = Chr$(PinNumber) & Chr$(PinState)
|
This is the MCU code I have come up with. But I don't know how to retrieve the Pin number and pinstate, kindly guide me.
Code: |
#include "D:\Documents\Talha's documents\FAST\FYP\codes_CCS\SerialCom-VB\scomvb.h"
void main()
{
setup_adc_ports(NO_ANALOGS);
setup_adc(ADC_CLOCK_DIV_2);
setup_psp(PSP_DISABLED);
setup_spi(SPI_SS_DISABLED);
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
setup_timer_1(T1_DISABLED);
setup_timer_2(T2_DISABLED,0,1);
setup_comparator(NC_NC_NC_NC);
setup_vref(FALSE);
char cmd;
do{
if(kbhit())
{output_b(0x00);
cmd=getch();
switch (cmd)
{
case 0:output_bit(PIN_B0,1 );
break;
case 1:output_bit(PIN_B1,1 );
break;
case 2:output_bit(PIN_B2,1 );
break;
case 3:output_bit(PIN_B3,1 );
break;
case 4:output_bit(PIN_B4,1 );
break;
case 5:output_bit(PIN_B5,1 );
break;
case 6:output_bit(PIN_B6,1 );
break;
case 7:output_bit(PIN_B7,1 );
break;
}
}
}while(1);
} |
Please refer to above URL for full VB part. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Tue Oct 19, 2010 1:03 pm |
|
|
Quote: | VB sends the pin number and its state, I need to turn ON the corresponding LED.
VB code:
' Send Out Data
MSComm1.Output = Chr$(PinNumber) & Chr$(PinState)
|
Run the VB program and display the output on a Terminal window (such
as TeraTerm) so you can see the actual numeric strings sent by VB.
Then post an example of the output. |
|
|
John Morley
Joined: 09 Aug 2004 Posts: 97
|
|
Posted: Tue Oct 19, 2010 6:46 pm |
|
|
Hi,
As PCM alluded, the problem is what the VB program is outputting vs. what your MCU code is trying to read. Another way to see the VB output is to use the 'Immediate Window' in the VB IDE. Add the following line, and make sure the Immediate Window is visible:
Code: |
debug.print Chr$(PinNumber) & Chr$(PinState)
|
Hopefully, this will give you a clue into what you are doing wrong. You might also add a printf statement to your MCU code to print what is being received by your C code (assuming you have an LCD or similar for diagnostics...
Realistically, you are only a few lines of code away from your goal, but you'll learn a whole lot more if you recognize and solve the problem yourself!
John _________________ John Morley |
|
|
talhahs
Joined: 14 Oct 2010 Posts: 14
|
Motor keeps running... |
Posted: Tue Oct 26, 2010 12:47 am |
|
|
This is the final code I am using but the problem is in the CCS code as it gets stuck in the loop, sometimes the motor keeps on running and doesn't stop.
Kindly help me out
The VB code I am using is
Code: |
Dim PinState As Long
If optState(0).Value = True Then
PinState = 0 //motor stopped
Else
PinState = 1 //motor running
End If
Private Sub cmdSend_Click()
MSComm1.Output = Chr$(PinState)
End Sub
|
Code: |
#include "C:\Documents and Settings\vb_dcmotor.h"
#define LED PIN_D0
#define LEFT_CONTROL_2A PIN_C0 //2A
#define LEFT_CONTROL_1A PIN_C1 //1A
#define LEFT_MOTOR PIN_C2 //1,2EN
void main()
{
setup_adc_ports(NO_ANALOGS);
setup_adc(ADC_CLOCK_DIV_2);
setup_psp(PSP_DISABLED);
setup_spi(SPI_SS_DISABLED);
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
setup_timer_1(T1_DISABLED);
setup_timer_2(T2_DISABLED,0,1);
setup_comparator(NC_NC_NC_NC);
setup_vref(FALSE);
char cmd;
do{
if(kbhit())
{cmd=getch();
switch (cmd)
{
case 0: // motor stop
output_bit(LED,0);
output_low(LEFT_CONTROL_1A); //all H bridge ports set to 0
output_low(LEFT_CONTROL_2A);
output_low(LEFT_MOTOR);
delay_ms(200);
break;
case 1: // motor running, code stucks here
output_bit(LED,1);
output_high(LEFT_CONTROL_1A);
output_low(LEFT_CONTROL_2A);
output_high(LEFT_MOTOR);
delay_ms(200);
break;
}
}
}while(1);
}
|
|
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9243 Location: Greensville,Ontario
|
|
Posted: Tue Oct 26, 2010 5:29 am |
|
|
Since you don't show the use rs232(....) info
it..
Could be the classic 'need to add 'errors' to the use rs232(......) instruction. |
|
|
talhahs
Joined: 14 Oct 2010 Posts: 14
|
rs232 function |
Posted: Tue Oct 26, 2010 1:00 pm |
|
|
this is what i have in .h file
Code: | #use rs232(baud=9600,parity=N,rcv=PIN_C7,bits=8,invert) |
I am using invert to avoid MAX232 (level shifter IC).. |
|
|
AK
Joined: 20 Apr 2004 Posts: 33
|
|
Posted: Tue Oct 26, 2010 1:22 pm |
|
|
Maybe I'm not understanding something, but in VB6, the Chr$ function returns the character string of the ASCII value that you pass to it. So you are sending the NULL for 0 and SOH for 1. Will the getch() recognize that as 0 or 1? |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Tue Oct 26, 2010 1:23 pm |
|
|
Quote: | MSComm1.Output = Chr$(PinState)
cmd=getch();
switch (cmd)
{
case 0: // motor stop
output_bit(LED,0);
output_low(LEFT_CONTROL_1A); //all H bridge ports set to 0
output_low(LEFT_CONTROL_2A);
output_low(LEFT_MOTOR);
delay_ms(200);
break;
case 1: |
What type of value does chr$ create and what are you testing for ?
Answer that and you will see the problem. |
|
|
talhahs
Joined: 14 Oct 2010 Posts: 14
|
|
Posted: Wed Oct 27, 2010 1:03 am |
|
|
I tried changing VB code to :
Code: | Option Explicit
Dim PinState As Integer
Private Sub cmdbackward_Click()
PinState = 48 'char 0
MSComm1.Output = Chr$(PinState)
End Sub
Private Sub cmdforward_Click()
PinState = 49 'char 1
MSComm1.Output = Chr$(PinState)
End Sub
Private Sub cmdleft_Click()
PinState = 50 'char 2
MSComm1.Output = Chr$(PinState)
End Sub
Private Sub cmdright_Click()
PinState = 51 'char 3
MSComm1.Output = Chr$(PinState)
End Sub
Private Sub cmdSend_Click()
MSComm1.Output = Chr$(PinState)
End Sub
Private Sub cmdstop_Click()
PinState = 52 'char 4
MSComm1.Output = Chr$(PinState)
End Sub
Private Sub Form_Load()
Dim Pins As Long
Dim PinState As Integer
MSComm1.CommPort = 1
MSComm1.Settings = "9600,N,8,1"
MSComm1.DTREnable = False
MSComm1.PortOpen = True
End Sub
Private Sub Form_Unload(Cancel As Integer)
MSComm1.PortOpen = False
End Sub
|
but it never runs
Its working fine with the following code. the only problem is when i keep the motor running for a longer time, it never stops. Though motor performs well in all directions when operated for few seconds.
Code: |
Option Explicit
Dim PinState As Integer
Private Sub cmdbackward_Click()
PinState = 0 'char 0
MSComm1.Output = Chr$(PinState)
End Sub
Private Sub cmdforward_Click()
PinState = 1 'char 1
MSComm1.Output = Chr$(PinState)
End Sub
Private Sub cmdleft_Click()
PinState = 2 'char 2
MSComm1.Output = Chr$(PinState)
End Sub
Private Sub cmdright_Click()
PinState = 3 'char 3
MSComm1.Output = Chr$(PinState)
End Sub
Private Sub cmdSend_Click()
MSComm1.Output = Chr$(PinState)
End Sub
Private Sub cmdstop_Click()
PinState = 4 'char 4
MSComm1.Output = Chr$(PinState)
End Sub
Private Sub Form_Load()
Dim Pins As Long
Dim PinState As Integer
MSComm1.CommPort = 1
MSComm1.Settings = "9600,N,8,1"
MSComm1.DTREnable = False
MSComm1.PortOpen = True
End Sub
Private Sub Form_Unload(Cancel As Integer)
MSComm1.PortOpen = False
End Sub
|
|
|
|
arunb
Joined: 08 Sep 2003 Posts: 492 Location: India
|
RE: |
Posted: Wed Oct 27, 2010 2:25 am |
|
|
I normally use a 10 microF cap instead of a 1 microF cap. |
|
|
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
Re: rs232 function |
Posted: Wed Oct 27, 2010 6:08 am |
|
|
talhahs wrote: | this is what i have in .h file
Code: | #use rs232(baud=9600,parity=N,rcv=PIN_C7,bits=8,invert) |
I am using invert to avoid MAX232 (level shifter IC).. | You didn't post your schematic, but the RS232 output of a PC is between +15V and -15V. Your 5V PIC will not be happy to have these voltage at the input pins. What does your input circuit look like? With a bad design your PIC will die.
For the difference between your two programs: have a look at the ASCII table. For example the value 4 is the 4th character in the table. The character '4' however is at location 52 in the table.
As already mentioned by other people in this thread, you should read about what the CHR function is doing.
And then think about the difference in the C program when you write: Code: | case 0: // motor stop | or Code: | case '0': // motor stop |
|
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19539
|
|
Posted: Wed Oct 27, 2010 7:14 am |
|
|
Quite a lot of other little comments to make:
1). You need to understand that because you are using 'invert', you are not using the hardware UART. Since you are using a software UART, if a character starts to arrive, and you don't 'poll' it in time, you _will_ receive garbage. With the software sampling latter edges in the byte and thinking these are the start.
If anything arrives in the long delays you have, you will get problems...
You would get far 'better' results by accepting that you have to invert the signal. Use a couple of resistors and a transistor if you don't want to use a MAX232, and avoid the risk of damaging both the PIC, and the UART in the PC....
2) Your VB code, needs handshaking disabled on the com port (Handshaking = comNone), and the com 'mode' should be set to Binary (though this really only affects input), and 'NullDiscard' set to false.
3) Then your biggest problem. Your PIC code is receiving _one_ byte, but your VB code is sending two. '&' is the string concatenation character in VB string handling, not the mathematical 'and'. You need to perform the arthmetic _before_ converting the data to a string. The 'AND' operator in VB, is the word 'and'.
MSComm1.Output = Chr$(PinNumber AND PinState)
Best Wishes |
|
|
|