Joe S. and mackrackit,
I have some success by going farther back to basics (sending ASCII numbers from a terminal). I'll try to post the code and results later today.
Thank you for your help and patience,
Bob
Joe S. and mackrackit,
I have some success by going farther back to basics (sending ASCII numbers from a terminal). I'll try to post the code and results later today.
Thank you for your help and patience,
Bob
Joe S. and mackrackit,
Background: I had written a program with PBCC (PowerBASIC Console Compiler for WinXP) that:
1) Waits for the PIC to send a "0" to the PC, then
2) the PC sends 12 consecutive 16-bit words to the PIC expecting the PIC to receive them and do other things with them.
I had never been able to get the PIC to receive them. It would always just "hang up" at the SERIN2 statement.
I went back to basics and worked to send a set of characters (numeric) to the PIC via a PC terminal program and had the PIC send them back. I (finally) got it to work just fine:
My TX-RX code for this simple test is:
'--------------------------------------------------------
INCLUDE "MODEDEFS.BAS"
ADCON1 = 7 'set analog pins to digital
TRISA = 1 'set port A to inputs
TRISB = 0 'set port B to outputs
TRISC = 0 'make it an OUTPUT for serial comm on it's pins, even though
'RX is sort of an INPUT.
DEFINE OSC 20
MD VAR WORD
LedPin VAR PORTC.3
RXData VAR WORD
RXPin VAR PORTC.5
TXPin VAR PORTC.4
MD = 16780 '16780 = 2400 driven, 8 bit, 1 stop, no parity, inverted
main:
SERIN2 RXpin, MD, [DEC RXdata] 'waits for a character then moves on
SEROUT2 TXpin, MD, ["I am sending it back -> ", DEC RXdata, 10, 13]
HIGH LedPin 'hook LED to Pin 14 = RC3
PAUSE 20 'a flash of the LED means we got
LOW Ledpin 'this far OK
PAUSE 20
GOTO main
'--------------------------------------------------------
I got this to work with Hyperterm and with a simple terminal program I wrote in PBCC (PowerBASIC Console Compiler for WinXP).
I used a Serial Port Monitor to look at all the bytes going and coming.
What I learned:
1) I need a 1k resistor in the TX line and another 1k resistor in the RX line (I am not using an RS232 converter). Gee, this is exactly what the PBP manual said to do! Other references to a 22k or 10k resistor in the RX line were not good for me. What a wild goose chase that was. It really masked the problem for a long time.
2) The PC transmit end must be set for 8-bit whenever the DEC qualifier is used for variables within the SERIN2 statement. A transmitted 7-bit byte will not do (even though a 7-bit byte can still represents an ascii number).
3) When I use the qualifer DEC, SERIN2 will accept ONLY NUMERIC ascii characters, and it will keep accepting them until any NON-numeric character is received. THIS IS AS IT HAS TO BE. I turns out that my PBCC program had been sending a space character prior to the string of numeric characters. Then DEC caused that variable to be bypassed and nothing was stuffed into that variable at all.
4) The character that tells SERIN2 (with DEC) that the string of numeric characters has ended can be any non-numeric character. It does not have to be a CR.
5) When testing the TX-RX code, remember to send NUMERIC keystrokes in addition to alpha keystrokes. Afterall, wasn't it NUMERIC values I was trying to stuff in there? How could I have missed that one?
6) Breaking my 16-bit value into two bytes (high and low) then sending them to the PIC while SERIN2 uses the DEC qualifier will not work either! That technique must need some other qualifier (or no qualifier ... will have to try that again later).
7) If I set the baud rate mode via a variable, and that mode number is larger than a single byte's worth (like 16780) , then that variable better be defined as a WORD, not as a BYTE. Yet another noobie mistake!
8) SERIN2 is UNFORGIVING and will tell you nothing if:
* DEC is used and if
* Non-numeric STRING characters are sent, or
* If a non-numeric string character is sent
before the numeric string characters are sent.
9) SERIN2 with the DEC qualifier will accept lots of numeric characters, but if they represent a number higher than 65535 (max 16-bit word), the numbers that are stuffed into the variable will not be accurate.
10) While one would think that a Receive pin should be set as an INPUT, no, set both TX and RX pins as outputs. Learned that one by luck.
Now I can even get my 12 word transmission to work with the PIC. Hooray! Now I will move on to making the PIC program do more than receive the needed values. Progress at last!
It has been a painful learning experience. But I am stronger for it, I suppose.
Once I understood it, the PBP manual was right afterall. Ha! How dumb could I be?
Many thanks for your suggestions. One of the reasons I did this long post was to (hopefully) help other beginners navigate around some of these TX/RX and SERIN2 DEC traps.
Best regards to all,
Bob
My hat's off to you Bob, I don't know where you found that, it's not in the manual that I can find . . . But it works! I've spent 1/2 the night trying to make it work some other way and NADA. You have earned your keep, fixing your own problem . . . Thanks for the lesson !
If you do not believe in MAGIC, Consider how currency has value simply by printing it, and is then traded for real assets.
.
Gold is the money of kings, silver is the money of gentlemen, barter is the money of peasants - but debt is the money of slaves
.
There simply is no "Happy Spam" If you do it you will disappear from this forum.
I looked at the resistors that I used successfully. My previous post was in error with regard to the resistor value used in the TX line from the PIC. I used a 10k, not a 1k. I don't know if a 1k will work in the TX line, but I know the 10k works.
I still use the 1k in the RX line to the PIC, though.
I am next going to install an RS232 converter to avoid all this resistor roulette!
Best regards to all,
Bob
Bob,
I've used the ubiquitous MAX232 to a PC RS232 port with success in an automated tester using Hserin and Hserout. I'm jumping on on this cause I use the PIC16F876A also.
The DB9 on this end is Female so you can use a standard male to female cable to the PC.
Here's some syntax and I'll drop in the related schematic. I have it set at 4800 baud, but I'm sure it'll run much faster. I deleted a bunch of stuff from the diagram, but I left the ISP hookup, as well as the reset button.
This bit of code will wait for *T from the PC, run the TECH subroutine, then after sending the A/D results, waits for 3 numbers, converts them into decimal, uses that for the PWM value, then waits for FN to go on it's way.
The formating stuff in the HSEROUT code is to pad 0s cause the PC (running Labview) was looking for precisely 3 bytes at that point.
Then more of the same for the Red channel.Code:DEFINE OSC 8' USE 8MHZ CRYSTAL OSC. DEFINE ADC_BITS 10' +VREF= 2VDC 1 = .00195V OR ~ 2MV DEFINE ADC_SAMPLEUS 50' SAMPLE TIME .1MS DEFINE CCP1_REG PORTC' Hpwm channel 1 pin port DEFINE CCP1_BIT 2' Hpwm channel 1 pin bit DEFINE CCP2_REG PORTC' Hpwm channel 2 pin port DEFINE CCP2_BIT 1' Hpwm channel 2 pin bit DEFINE HSER_RCSTA 90h' Set RECIEVE Enabled DEFINE HSER_TXSTA 24h' Set XMIT Enabled HS DEFINE HSER_BAUD 4800' IL1700 BAUD RATE DEFINE HSER_CLROERR 1' CLEAR OVER RUN ERRORS DEFINE CHAR_PACING 1000' CHAR PACING(uSEC) TO 1MS TRISA=%00001111' SET UP PORTA I/O (1=IN,0=OUT) TRISB=%11001000' SET UP PORTB I/O TRISC=%10000000' SET UP PORTC I/O ADCON1=%10100101' USE PORTA.3 PIN5 AS VREF+ @ 2.0VDC ADCON0=%01000000' A/D OFF -- RIGHT JUSTIFY. 6MSB=0 ADRESH HSERIN[WAIT("*"),BUNDONE] IF BUNDONE = "T" THEN GOTO TECH ' T FOR TECH TECH:' **************** TECH ************ ' BLEDOUT = 0' TURN BLUE LED ON HPWM 1, BLUELVL, 5000' CCP1=BLUE SET CURRENT ADCON0 = %01001101' BLUE ADC ADCIN 1, BLUSNS' READ IT BLEDOUT = 1' TURN BLUE OFF RLEDOUT = 0' TURN RED ON HPWM 2, REDLVL, 5000' CCP2 =RED SET CURRENT ADCON0=%01000001' RED A/D ADCIN 0, REDSNS:REDSNS=REDSNS MIN 999 RLEDOUT = 1' TURN RED OFF 'HPWM 1, 0, 5000' STOP PWM 'HPWM 2, 0, 5000 IF BLUELVL <10 THEN HSEROUT["00",DEC BLUELVL]:GOTO RED1 ENDIF IF BLUELVL <100 THEN HSEROUT["0",DEC BLUELVL]:GOTO RED1 ELSE HSEROUT [DEC BLUELVL] ENDIF GOTO RED1 RED1: IF REDLVL <10 THEN ' FORMATING HSEROUT["00",DEC REDLVL]:GOTO BLU1 ENDIF IF REDLVL <100 THEN HSEROUT["0",DEC REDLVL]:GOTO BLU1 ELSE HSEROUT [DEC REDLVL] ENDIF GOTO BLU1 BLU1: IF BLUSNS <10 THEN HSEROUT["00",DEC BLUSNS]:GOTO RED2 ENDIF IF BLUSNS <100 THEN HSEROUT["0",DEC BLUSNS]:GOTO RED2 ELSE HSEROUT [DEC BLUSNS] ENDIF GOTO RED2 RED2: IF REDSNS <10 THEN HSEROUT["00",DEC REDSNS]:GOTO WAITF ENDIF IF REDSNS <100 THEN HSEROUT["0",DEC REDSNS]:GOTO WAITF ELSE HSEROUT [DEC REDSNS] ENDIF GOTO WAITF WAITF: HSERIN [WAIT ("F"),EFF] IF EFF = "N" THEN GOTO BEGIN ELSE GOTO BLULEDSET ENDIF GOTO TECH BLULEDSET:'----------------------SET BLUE-------------------------- HSERIN [WAIT("@"),STR INCOM\3] INCOM[0] = (INCOM[0]-"0") ' INCOM[1] = (INCOM[1]-"0") ' Convert to decimal INCOM[2] = (INCOM[2]-"0") X = 0 ' RESET THE VARIABLE X = X + INCOM[0] * 100 X = X + INCOM[1] * 10 X = X + INCOM[2] BLUELVL = (X MIN 255) X = 0 HPWM 1, BLUELVL, 5000' CCP1 AND SET CURRENT
I hope this helps, and I pasted everything correctly!
Bron
The less you expect, the more you get.
Bookmarks