PDA

View Full Version : Going Loopy - How do i get my Loops sorted out ???



gtvmarty
- 21st September 2009, 07:01
Hi All,

I'm working on a small project that reads a 2-digit Ascii charcter (e.g. "23") into a Pic16F84 and displaying it onto 2x 7Seg displays.
The 2digit data comes from a temperature sensor unit, but for testing on the bench i use Hyperterm, and simply type "2" then "3" to see "23" appear on the 7-Segs.

Briefly, Port-B is the 7-segment data, and Port A.0 / A.1 are the cathode enables (via driver tranny) to the displays.

By alternating 2 variables (MSB & LSB) onto Port-B and toggling the 2 cathodes i have a 2 digit multiplexed display....

However, as simple as this sounds, i can't get my loops to work correctly.

I need the main part of my code to constantly send data to the 7-segs, while also taking a look at the serial pin for new data to be displayed..

At the moment, the following code works, but the 7seg data disappears almost immediately after it's displayed.
I realised when my code is idling it's 'blanking' my LSB/MSB variables, hence no display.
I can't find the right condition to keep data looping on the 7segs while still looking for new RS232 data.....

After a few changes, i can get the data to display nicely, but ONLY if i lock the loop into itself, which means it then doesnt read incoming data.
After resetting the Pic, i can enter new data, but only Once!


I know i'm probably only 2-3 lines of code from perfecting this, and i know most of you will probably re-write my code into 10 lines, but i thought i'd scream out for help and how what happens ;-)



'---------------------------------------------------------------------------------------------------------

DEFINE OSC 4 'set OSC to 4Mhz

INCLUDE "modedefs.bas" 'Enables RS232 comms library....

RS_Data VAR BYTE 'RS232 Data assigned into "RS_Data"

LSB VAR BYTE 'RS232 -UNITS- Data assigned into "LSB"
MSB VAR BYTE 'RS232 -TENS- Data assigned into "MSB"

Counter VAR BIT 'A 1-bit "status" to indicate the 1st or 2nd digit is being processed.

Digits VAR BYTE 'Search "Digits" for a number value 0-9 (lookdown)

Units_com VAR PORTA.0 'COMmon Cathode Transistor driver (Hi-enable) for "Units" display.
Tens_com VAR PORTA.1 'COMmon Cathode Transistor driver (Hi=enable) for "Tens" display.
Neg_seg VAR PORTA.2 'NEGative Segment Transistor driver (Hi=enable) - for NEGATIVE Temperature.
Spare VAR PORTA.3 'spare
RS232 VAR PORTA.4 'RS232 RX Data Pin (A.4) read into PIC.

Seg7 VAR PORTB '7 segment display data (7 bits=number, 8th bit=decimal point).


'-----[ INITIALISE ALL the PORTS and setup bits in a CLEAN startup condition ]------------------------------------

Init:

seg7 = $00 '7-Seg data (portB) to $00 (Blank).
Units_com = 0 'cathode "Units" OFF.
Tens_com = 0 'cathode " Tens" OFF.
Neg_seg = 0 'NEG-segment LEDs OFF.
Counter = 0 'set as the "1st" digit to be processed.
TRISA = $10 'PortA all OUTPUTS on bits 0,1,2,3 and set Bit4 as INPUT (Serial IN).
TRISB = $00 'PortB all OUTPUTS
RS_Data = $00 'cleared, until serial data arrives.
Digits = $00 'cleared, until Lookups fill it.
LSB = $00 'cleared, until Lookups fill it.
MSB = $00 'cleared, until Lookups fill it.


GoTo Start 'Goto start of program...


'-----[ Get RS232 Data input, and assign into MSB & LSB Data to be displayed ]------------------------------------

GetData:

SerIn RS232,T9600,RS_Data 'Read Serial Data on Pin RS232 (A.4) and assign value into "RS_Data"

'Assign any of the "0123456789-" characters to "digits".
LookDown RS_Data,["0123456789-"],Digits
'Match number from RS_Data, and assign 7seg data to it into Digits.

IF Counter = 0 Then
LookUp Digits,[$3F,$06,$5B,$4F,$66,$6D,$7D,$07,$7F,$6F,$00],MSB 'If "Counter" is "0" then store in MSB.
Else '( 0 1 2 3 4 5 6 7 8 9 - )
LookUp Digits,[$3F,$06,$5B,$4F,$66,$6D,$7D,$07,$7F,$6F,$00],LSB 'If "Counter" is "1" then store in LSB.
EndIF


IF Counter = 0 Then 'If counter=0, then this is the first digit to be processed.
Counter = 1 'Now make counter=1, to show (next time) that the 2nd digit will be processed.
GoTo GetData 'Repeat to get 2nd digit to process.
Else '
Counter = 0 'Otherwise, make counter=0, ready to process 1st digit of the next "2 numbers to arrive".
EndIF '

Return 'Return back to Start, and display MSB & LSB onto the 2x 7-Seg displays.


'-----[ Display MSB & LSB Data onto 2x 7-Segment Displays ]-------------------------------------------------------

Start:

'UNITS:
seg7 = LSB 'place data "LSB" onto PortB 7Seg info.
units_com = 1 'ENable UNITs cathode.
Pause 10 'Keep UNITs ON for 10mS before going back to TENS
units_com = 0 'DISable UNITs cathode.

'TENS:
seg7 = MSB 'place data "MSB" onto PortB 7Seg info.
tens_com = 1 'ENable TENs cathode.
Pause 10 'Keep TENs ON for 10mS before going back to UNITS
tens_com = 0 'DISable TENs cathode.

GoSub GetData 'Go and check for new serial numbers arriving.
GoTo Start 'Repeat this section again, dispaying the 7-Seg data etc.


'-----[ END ]-----------------------------------------------------------------------------------------------------



Thanx greatly in advance,
Marty.

mackrackit
- 21st September 2009, 19:33
I think it may be getting stuck the second time around at the serial part.

Could give this a try...


'-----[ Get RS232 Data input, and assign into MSB & LSB Data to be displayed ]------------------------------------
GetSerial:
SerIn RS232,T9600,RS_Data 'Read Serial Data on Pin RS232 (A.4) and assign value into "RS_Data"
GetData:
'Assign any of the "0123456789-" characters to "digits".
LookDown RS_Data,["0123456789-"],Digits
'Match number from RS_Data, and assign 7seg data to it into Digits.

IF Counter = 0 Then
LookUp Digits,[$3F,$06,$5B,$4F,$66,$6D,$7D,$07,$7F,$6F,$00],MSB 'If "Counter" is "0" then store in MSB.
Else '( 0 1 2 3 4 5 6 7 8 9 - )
LookUp Digits,[$3F,$06,$5B,$4F,$66,$6D,$7D,$07,$7F,$6F,$00],LSB 'If "Counter" is "1" then store in LSB.
EndIF


IF Counter = 0 Then 'If counter=0, then this is the first digit to be processed.
Counter = 1 'Now make counter=1, to show (next time) that the 2nd digit will be processed.
GoTo GetData 'Repeat to get 2nd digit to process.
Else '
Counter = 0 'Otherwise, make counter=0, ready to process 1st digit of the next "2 numbers to arrive".
EndIF '

Return 'Return back to Start, and display MSB & LSB onto the 2x 7-Seg displays.


'-----[ Display MSB & LSB Data onto 2x 7-Segment Displays ]-------------------------------------------------------

Start:

'UNITS:
seg7 = LSB 'place data "LSB" onto PortB 7Seg info.
units_com = 1 'ENable UNITs cathode.
Pause 10 'Keep UNITs ON for 10mS before going back to TENS
units_com = 0 'DISable UNITs cathode.

'TENS:
seg7 = MSB 'place data "MSB" onto PortB 7Seg info.
tens_com = 1 'ENable TENs cathode.
Pause 10 'Keep TENs ON for 10mS before going back to UNITS
tens_com = 0 'DISable TENs cathode.

GoSub GetSerial 'Go and check for new serial numbers arriving.
GoTo Start 'Repeat this section again, dispaying the 7-Seg data etc.


'-----[ END ]-----------------

gtvmarty
- 21st September 2009, 22:47
Thanx for that, but isn't that doing the same as my original code???
Doesn't it flow down into the next label (GetData) and execute thsoe commands as previously?).

Anyway, i tried it, and it's still the same, except now the SAME digit appears on both 7-Segs during each keypress in Hyperterm.

I know this code is probably only missing 1-2 lines, or a nested loop somewehre, it's probably so obvious that i still can't see it :)

Marty.

mackrackit
- 21st September 2009, 23:45
Thanx for that, but isn't that doing the same as my original code???
Doesn't it flow down into the next label (GetData) and execute thsoe commands as previously?).

No, I have it reading the serial once not twice. I was thinking in your example you were sending 23. But after rereading you are sending 2 and then 3. So you want to read the serial twice. Sorry.

Try adding a time out to the serin command, if no serial data comes in after a certain amount of time the code will go to the display routine to light the LEDs up. Then go take a quick look for some serial data.

gtvmarty
- 21st September 2009, 23:53
Thanx, i'll keep digging......

gtvmarty
- 24th September 2009, 00:45
Update:

After sorting out my SerIn problem (i didnt know SerIn waits for eternity until data arrives), I managed to get my Serial to 7-seg project 'roughly' work.

However, due to to the time it takes to read/wait for SerIn data and go back to multiplex the 7-seg displays, i dont think this will EVER work in the correct fashion i anticipated.
If i shorten the timeout on SerIn then i miss incoming data, if i lengthen the timeout to get data, then the 7segs are too flickery.
With several adjusments, i have PERFECT 7seg multiplexed displays but with no ability to read SerIn data.

So, I don't think i have any option but to upgrade to a Pic'877 (i have a boxful) and use 2 ports for the 2x 7seg displays, where they can hold LATCHED data onto the 7segs, whilst the SerIn can be left to sit for eternity waiting for new data without upsetting the 7seg displays.


I encourage anyone who thinks they can make it work to prove me wrong :D

Regards,
Marty.

Jerson
- 24th September 2009, 01:56
Marty

I do not want to take up your challenge, but, have you considered putting the display update to be on RTCC interrupt? Solves all your problems of serin waiting.

Archangel
- 24th September 2009, 05:02
Update:

After sorting out my SerIn problem (i didnt know SerIn waits for eternity until data arrives), I managed to get my Serial to 7-seg project 'roughly' work.

However, due to to the time it takes to read/wait for SerIn data and go back to multiplex the 7-seg displays, i dont think this will EVER work in the correct fashion i anticipated.
If i shorten the timeout on SerIn then i miss incoming data, if i lengthen the timeout to get data, then the 7segs are too flickery.
With several adjusments, i have PERFECT 7seg multiplexed displays but with no ability to read SerIn data.

So, I don't think i have any option but to upgrade to a Pic'877 (i have a boxful) and use 2 ports for the 2x 7seg displays, where they can hold LATCHED data onto the 7segs, whilst the SerIn can be left to sit for eternity waiting for new data without upsetting the 7seg displays.


I encourage anyone who thinks they can make it work to prove me wrong :D

Regards,
Marty.
Hi Marty,
There's a lot of real estate between old grandpa F84 and an F877, despite your boxful of them . . . a 16F648A has the same footprint and pin orientation as the F84 with tons of memory and an USART to use HSERIN, and it's much simpler to breadboard. Then you don't have all those timing issues (as with grandpa). Sure Electronics has some nice SPI type 7 segment displays and some dot matrix types too (available direct or through eBay). Use 'em with old GrandPa too. :D