PDA

View Full Version : Index a bit through a portion of a port



ecoli-557
- 11th March 2012, 18:04
Hello All-
I have a unique problem and I am trying to think of a better way to perform a feddback indication for packets received on a project. The project is essentially a chain of serial to parallel ports and parallel to serial ports. The serial data comes in RS485 and is detected via interrupt (Thanks DT!) via DT_INTS-18.
What I want to do is provide a visual that I have received a packet of data by turning on one LED in a group of 4. Each time I get a packet of data, I will turn ON the next in the series of 4 but also turn off the LED preceeding . It looks like the useless circle swirl on Windoze 7 - except it is useful here.

I got it working using a less efficient use of variables, lookup, and arrays - all which is not effecient. I have worked with snippets from
http://www.picbasic.co.uk/forum/showthread.php?t=14038
http://www.picbasic.co.uk/forum/showthread.php?t=12667

And while they work, I don't want to set a timer to turn the LED off.

Code fragment:
'Define configuration bits - kewl new use of PBP3!
#CONFIG
__config _CONFIG1H, _OSC_ECIO6_1H & _FCMEN_OFF_1H & _IESO_OFF_1H
__config _CONFIG2L, _PWRT_ON_2L & _BOREN_OFF_2L
__config _CONFIG2H, _WDT_OFF_2H
__config _CONFIG3H, _CCP2MX_PORTE_3H & _LPT1OSC_OFF_3H & _MCLRE_OFF_3H
__config _CONFIG4L, _STVREN_ON_4L & _LVP_OFF_4L & _XINST_OFF_4L
#ENDCONFIG
'---------------------------------------------------------------------------------------
'Define the oscillator and setup the INCLUDE files
DEFINE OSC 20 '20 MHz oscillator, external
INCLUDE "DT_INTS-18.bas" 'Base Interrupt System
INCLUDE "ReEnterPBP-18.bas" 'Include if using PBP interrupts
'---------------------------------------------------------------------------------------
'OKAY, Lets set up the registers.....
OSCCON= %01110100 '16 MHz internal clock
ADCON0= %00000000 'Turns ON ADC
ADCON1= %00001101 'Vref is AVdd and AVss, ANO and AN1 are used, all others are digital
ADCON2= %10000101 'RIGHT justified, 0 TAD A2D aq time select, Fosc/16
PSPCON= %00000000 'Parallel slave port is general I/O
CMCON= %00000111 'Turns OFF comparators
CVRCON= %00000000 'Comparator voltage ref is OFF
HLVDCON=%00000000 'High Low Voltage Detect is DISABLED
CCP1CON=%00000000 'Turns OFF capture, compare, pwm
CCP2CON=%00000000 'Turns OFF capture, compare, pwm
CCP3CON=%00000000 'Turns OFF capture, compare, pwm
CCP4CON=%00000000 'Turns OFF capture, compare, pwm
CCP5CON=%00000000 'Turns OFF capture, compare, pwm

INTCON2=%00000000 'ENABLE pullups on PORTB
'---------------------------------------------------------------------------------------
'Direction registers
TRISA = %10000111 'Set PORTA for bit7 is clk in, 4 led out, 3 A/D in
TRISB = %11000000 'PORTB is OUTPUT, except B6&B7
TRISC = %10000000 'Set RC7 (RX), rest are outputs, low 6 bits not used
TRISD = %11111111 'Set PORTD for high order INPUTS
TRISE = %11111111 'Set PORTE for low order INPUTS
TRISF = %00000000 'PORTF is low order OUTPUT
TRISG = %00100100 'PORTG is mixed '-----------------------------------------------------------------------------------------
'Additional I/O Definitions
error var PORTG.3 'ERROR output, ACTIVE LOW (LED)
heart var PORTG.0 'Heartbeat to know we are online - ACTIVE LOW
CTS Var PORTG.4 'Goes high to xmit on RS485
L1 VAR PORTA.3 'Network activity LED1
L2 VAR PORTA.4 'Network activity LED2
L3 VAR PORTA.5 'Network activity LED3
L4 VAR PORTA.6 'Network activity LED4
AC var PORTA.2 '110 VAC present or not - low if present
'------------------------------------------------------------------------------------------
'Variable List
i var byte 'Loop counter var
j var byte 'Loop counter var
rxbyte var byte 'serial receive byte
sync var byte 'data byte 1 - $54
chksum var word '16 bit checksum
bad_data var bit 'Bad data indicator
adval5 var word 'A2D conversion result 5v
adval24 var word 'A2D conversion result 24v
pcounter var byte 'Variable to rotate the 4 LES indicating received packets
pout var byte '1st LED in rotation variable
pled_old var byte 'Previous packet LED indicator to turn OFF
CRC16 var word 'CRC16 holder
'-------------------------------------------------------------------------------------

Pseudo-code here:
If packet_rcvd = 1 then
turn on L1
all others (L2, L3, L4) off
endif

If packet_rcvd = 1 then
turn on L2
all others off

And so on in a round-robin fashion.

I have tried addrerssing the ports such as:
'Subroutines here
Packet_LEDs:
l1=pout.1
l2=pout.2
l3=pout.3
l4=pout.4
return
and refrencing them in the program which does work but for the turning off of the LEDs.

A.0, A.1 are used for analog, A.3 is digital in, A.3-A.6 are the LEDs as listed in the variables, and A.7 is used for clock in.

What I am curious about is if I can address the ports directly using assembler (?) and just cycle a '1' through the memory (couldnt figure that out) in a cyclic way??
I also tried using bitwise manipulation but that didnt seem to work well either.

Curious if anyone has done this or has any ideas from which I can learn?? Then I can tackle the CRC16 debockle..........

Regards to All,
Ecoli

ecoli-557
- 11th March 2012, 18:36
Hey Again-
With this thread : http://www.picbasic.co.uk/forum/showthread.php?t=14038 I have tried the following, but it does NOT compile. The errors are too many but the 1st couple are:
Syntax error, redefinition of label pLED, syntax error. So I think it may be a dumb thing on my part....

Pertinant code below:
'-----------------------------------------------------------------------------------------
'Additional I/O Definitions
error var PORTG.3 'ERROR output, ACTIVE LOW (LED)
heart var PORTG.0 'Heartbeat to know we are online - ACTIVE LOW
CTS Var PORTG.4 'Goes high to xmit on RS485
pLED[1] VAR PORTA.3 'Network activity LED1
pLED[2] VAR PORTA.4 'Network activity LED2
pLED[3] VAR PORTA.5 'Network activity LED3
pLED[4] VAR PORTA.6 'Network activity LED4
AC var PORTA.2 '110 VAC present or not - low if present
'------------------------------------------------------------------------------------------
'Variable List
i var byte 'Loop counter var
j var byte 'Loop counter var
rxbyte var byte 'serial receive byte
sync var byte 'data byte 1 - $54
chksum var word '16 bit checksum
bad_data var bit 'Bad data indicator
adval5 var word 'A2D conversion result 5v
adval24 var word 'A2D conversion result 24v
pkt_cntr var byte 'Variable to rotate the 4 LES indicating received packets
CRC16 var word 'CRC16 holder

Actual code:
start1:
' DEBUG "5 volt= ",DEC adval5 DIG 3,".",DEC3 adval5, 10, 13
if packetRcvd=1 then 'Packet has arrived!
pkt_cntr = pkt_cntr+1 'Increase the counter so we can turn on new LED
toggle pLED[pkt_cntr] 'Turns on new packet LED
' debug HDB2, HDB1, source_h, source_l, dest_h, dest_l, datab1, crc_high, crc_low, 10, 13
endif
if pkt_cntr=4 then pkt_cntr=0 'We have run through all 4 LEDs so reset counter
PacketRcvd=0 'Done processing packet data so reset flag
goto start1

Again, this is to test the theory but it does not work.
Any help??

Regards

ecoli-557
- 11th March 2012, 18:58
Sorry about the last post - it had errors.....

WHY won't this work? The array IS contigous, isn't it?

pLED var bit[4]

SYMBOL pLED[1]=PORTA.3 'Network activity LED1
SYMBOL pLED[2]=PORTA.4 'Network activity LED2
SYMBOL pLED[3]=PORTA.5 'Network activity LED3
SYMBOL pLED[4]=PORTA.6 'Network activity LED4

Then:
start1:
if packetRcvd=1 then 'Packet has arrived!
pkt_cntr = pkt_cntr+1 'Increase the counter so we can turn on new LED
toggle pLED[pkt_cntr] 'Turns on new packet LED
endif
if pkt_cntr=4 then pkt_cntr=0 'We have run through all 4 LEDs so reset counter
PacketRcvd=0 'Done processing packet data so reset flag
goto start1

ecoli-557
- 11th March 2012, 19:28
This has been fun, I found a who;e new set of threads!
According to this http://www.picbasic.co.uk/forum/showthread.php?t=4074&p=22065 what I have below should work, but no LEDs come on...... Any help??

start1:
if packetRcvd=1 then 'Packet has arrived!
pkt_cntr = pkt_cntr+1 'Increase the counter so we can turn on new LED
lookup pkt_cntr, [6, 5, 4, 3],j 'Lookup (better) for the offsets from A.0
toggle PORTA.0[j] 'Should toggle the required port
endif
if pkt_cntr=4 then pkt_cntr=0 'We have run through all 4 LEDs so reset counter
PacketRcvd=0 'Done processing packet data so reset flag
goto start1

ecoli-557
- 12th March 2012, 14:52
I found out how to post code in a more readable manner so I have posted again.But, why won't this work? Can't you toggle a port pin addressed this way??
start1: if packetRcvd=1 then 'Packet has arrived! pkt_cntr = pkt_cntr+1 'Increase the counter so we can turn on new LED lookup pkt_cntr, [0,6, 5, 4, 3],j 'Lookup (better) for the offsets from A.0 toggle PORTA.0[j] 'Should toggle the required port ON as all started OFF endif if pkt_cntr=4 then pkt_cntr=0 'We have run through all 4 LEDs so reset counter PacketRcvd=0 'Done processing packet data so reset flag goto start1

ecoli-557
- 12th March 2012, 15:08
Ran out of time before I could get ALL of the code submitted......

OK, why won't this work????



start1:
if packetRcvd=1 then 'Packet has arrived!
pkt_cntr = pkt_cntr+1 'Increase the counter so we can turn on new LED
lookup pkt_cntr, [0,6, 5, 4, 3],j 'Lookup (better) for the offsets from A.0
toggle PORTA.0[j] 'Should toggle the required port ON as all started OFF
endif
if pkt_cntr=4 then pkt_cntr=0 'We have run through all 4 LEDs so reset counter
PacketRcvd=0 'Done processing packet data so reset flag
goto start1

Darrel Taylor
- 12th March 2012, 16:18
Your toggle command is not doing what you think it is.


toggle PORTA.0[j]
That will read the PIN specified by the [j] offset from PORTA.0.
Then toggle the resulting PIN, either 0 or 1. (0 = PORTB.0, 1 = PORTB.1)

You could use this instead ...
PORTA.0(j) = !PORTA.0(j)
But you'll need to set the TRIS/PORT bits to OUTPUT/LOW first.

ecoli-557
- 12th March 2012, 16:28
Wow, so simple. This is MUCH better than what I started with. However, the LEDs do come on one at a time until they are all on. Then they go off one at a time untill all are off.I understand what you said and are doing by using the logical NOT.Is there a way to turn on only onle LED at a time? eg, 1st packet = LED1 on and all others are off, 2nd packet in=LED2 on and all others off, 3rd packet=LED3 on all others off, 4th packet =LED4 on and all others off, 5th packet=LED1 on all others off, etc??BTW, solved my CRC16 issue - it now works!Thanks again Darrel.

Darrel Taylor
- 12th March 2012, 16:50
LED1 = !!(packetRcvd=1)
LED2 = !!(packetRcvd=2)
LED3 = !!(packetRcvd=3)
LED4 = !!(packetRcvd=4)

ecoli-557
- 12th March 2012, 17:47
It added it but ALL the LEDs came on. What I added was (can't seem to master the code posting.....) I added LED1=!!(pkt_cntr=1) and so on.

Darrel Taylor
- 12th March 2012, 18:36
It added it but ALL the LEDs came on.
Do your LED's go to ground or VDD?

If they go to VDD, only use 1 "!"


LED1 = !(pkt_cntr=1)
LED2 = !(pkt_cntr=2)
LED3 = !(pkt_cntr=3)
LED4 = !(pkt_cntr=4)

ecoli-557
- 12th March 2012, 18:41
Thanks, They are pulled up to +5v via 1K. I just tried the single '!' and none light.The base address and offset I understood, the suggestion LED1 = !(pkt_cntr=1) and so on I do not understand. Care to enlighten?

ecoli-557
- 12th March 2012, 19:35
Darrel-Your add DOES work. SOmehow my variable 'pkt_cntr' is getting weird values like $94, $46, $19, $C0. Strange for such a simple counter.I will continue to look into it.I would like to fully understand the command 'LED1 = !(pkt_cntr=1) so I can learn.....Thanks and Regards,Ecoli-557

Darrel Taylor
- 12th March 2012, 19:57
Yes, it does work.
But you seem to come to those conclusions while I'm working on something to prove it.
That's twice now today.

>> .I would like to fully understand the command 'LED1 = !(pkt_cntr=1) so I can learn
Think about it. Then tell me how it works.


http://support.melabs.com/DT/Ecoli.jpg

ecoli-557
- 12th March 2012, 20:14
Sorry about my misplaced enthusiasm..... I have a few days to fool around with this without too much interruption and I get excited. My apologies.

Re the boolian math, I get the inversion, but I don't think I get the connection written the way it is.LED1 (the port) = (will follow) ! (NOT or inverse of) (pkt_cntr=1) <-- here is where I get fuzzy.

We take the inverse of the variable which is hard-coded but which is in a loop which is increased each time I get a packet?? I am befuddled. I will takes my whippin' now.....

I do understans the NOT of the port pin so the LED will fire, what I don't see is the hard-code inside a loop which is increasing the var??

Darrel Taylor
- 12th March 2012, 21:24
LED1 = !(pkt_cntr=1)

pkt_cntr=1 gives a "Logical" result of True or False.
Logical results can't be assigned to a BIT value.

The ! (NOT) will convert a Logical Value to a BIT value (0 or 1), but the logic is inverted due to the NOT.
Using two !! changes to a non-inverted bitwise value.

With your LED's tied to VDD, you need the inverted version, which gives either a 1 or 0 according to the Logical comparison.
So the LED will be ON when the comparison evaluates True.

With all 4 of the LEDs given a different comparison, only one of them will be ON at a time.

ecoli-557
- 12th March 2012, 22:22
Darrel-
Thanks for that. I was not aware that PBP could separate logical from actual or physical values. Trying to do this has allowed me to learn 2 more things, one which is not documented, and one which was overlooked.
Thanks again,
Steve