Hi,
I receive a BYTE via RS485. The low nibble (bits 0 - 3) are 4 digital input states. I need to separate them into 4 BYTES, each of the new bytes represents a single input. If the value in the LSB is == 1 then the input is HI, if the LSB is == 0 then the Input is LO.
bit 0 of the received BYTE is input 1 (DI_01)
bit 1 of the received BYTE is input 2 (DI_02)
bit 2 of the received BYTE is input 3 (DI_03)
bit 3 of the received BYTE is input 4 (DI_04)
// MOVE VALUE RECIEVED IN TEMP CALC VAR
SLV28AB_DI.Calc_Temp_1 = RS485_RX_DATA_001_LO
// SET INPUT 1 BIT 0 TO PROPER VALUE
DI_01_RS485_NODE_6 = SLV28AB_DI.Calc_Temp_1 << 7 // SHIFT LEFT TO GET RID OF ALL OTHER INPUT VALUES
DI_01_RS485_NODE_6 = DI_01_RS485_NODE_6 >> 7 // SHIFT RIGHT SO ONLY THIS INPUT IS REMAINING = 1 HI, =0 LO
// SET INPUT 2 BIT 1 TO PROPER VALUE
DI_02_RS485_NODE_6 = SLV28AB_DI.Calc_Temp_1 << 6 // SHIFT LEFT TO GET RID OF ALL OTHER INPUT VALUES
DI_02_RS485_NODE_6 = DI_02_RS485_NODE_6 >> 7 // SHIFT RIGHT SO ONLY THIS INPUT IS REMAINING = 1 HI, =0 LO
// SET INPUT 3 BIT 2 TO PROPER VALUE
DI_03_RS485_NODE_6 = SLV28AB_DI.Calc_Temp_1 << 5 // SHIFT LEFT TO GET RID OF ALL OTHER INPUT VALUES
DI_03_RS485_NODE_6 = DI_03_RS485_NODE_6 >> 7 // SHIFT RIGHT SO ONLY THIS INPUT IS REMAINING = 1 HI, =0 LO
// SET INPUT 4 BIT 3 TO PROPER VALUE
DI_04_RS485_NODE_6 = SLV28AB_DI.Calc_Temp_1 << 4 // SHIFT LEFT TO GET RID OF ALL OTHER INPUT VALUES
DI_04_RS485_NODE_6 = DI_04_RS485_NODE_6 >> 7 // SHIFT RIGHT SO ONLY THIS INPUT IS REMAINING = 1 HI, =0 LO
Does my local VAR SLV28AB_DI.Calc_Temp_1 get altered when I do SLV28AB_DI.Calc_Temp_1 << 6?
Will I get the desired results I am looking for?
Thank you,
Ron
Am I bit shifting correctly>
- Steve
- Matrix Staff
- Posts: 3429
- Joined: Tue Jan 03, 2006 3:59 pm
- Has thanked: 114 times
- Been thanked: 422 times
Re: Am I bit shifting correctly>
Personally, I would approach this issue using masking techniques. Something like the following:
Code: Select all
if (RS485_RX_DATA_001_LO & 0x01)
DI_01_RS485_NODE_6 = 1
else
DI_01_RS485_NODE_6 = 0
end if
if (RS485_RX_DATA_001_LO & 0x02)
DI_02_RS485_NODE_6 = 1
else
DI_02_RS485_NODE_6 = 0
end if
if (RS485_RX_DATA_001_LO & 0x04)
DI_03_RS485_NODE_6 = 1
else
DI_03_RS485_NODE_6 = 0
end if
if (RS485_RX_DATA_001_LO & 0x08)
DI_04_RS485_NODE_6 = 1
else
DI_04_RS485_NODE_6 = 0
end if
Re: Am I bit shifting correctly>
Hi,,,
Few questions....
First question - am I using bit shifting correctly to get the desired results??
I did it with bit shifting as it allowed me to enter it in a single CALC block...
Second question - can I enter the code you supplied as you entered it above in a CALC block??
If I cannot enter it in a CALC blokc, as you have above then I think I would need to use a "C" block and put the FCV_ in front of all the vars OR use a whole bunch of decision blocks for the "IF" statements, then use VAR = 1 or VAR = 0 in CALC blocks based on Yes/No path taken.
Third question - Is my statment above correct??
Thanks....
Ron
Few questions....
First question - am I using bit shifting correctly to get the desired results??
I did it with bit shifting as it allowed me to enter it in a single CALC block...
Second question - can I enter the code you supplied as you entered it above in a CALC block??
If I cannot enter it in a CALC blokc, as you have above then I think I would need to use a "C" block and put the FCV_ in front of all the vars OR use a whole bunch of decision blocks for the "IF" statements, then use VAR = 1 or VAR = 0 in CALC blocks based on Yes/No path taken.
Third question - Is my statment above correct??
Thanks....
Ron
- Steve
- Matrix Staff
- Posts: 3429
- Joined: Tue Jan 03, 2006 3:59 pm
- Has thanked: 114 times
- Been thanked: 422 times
Re: Am I bit shifting correctly>
Hi Ron,
I'll try to answer all of these questions together by explaining a general approach I have about programming. Bear in mind that this is a personal preference and others may disagree.
There are often multiple ways of completing a programming task, but I tend to favour an approach that makes the intention of the code as obvious as possible. It may not be the most "elegant", concise or optimised way possible, but it should be the most readable. There are times where you need to overcome code size limitations or produce code that is as quick as possible, and in such cases a compromise is needed - but these cases tend to be rare.
Another thing to note is that a concisely-written flowchart (or C code routine) does not necessarily produce a small or quick piece of assembly code. I have seen cases where a single "neat" statement in C has used up 10 times as much program memory as a more verbose set of statements.
Coming back to your questions...
Q1 - You should be able to create a simple program to test this code if you want. But if you are producing code that you are unsure of, then it's probably best to adopt an approach that is easier to understand.
Q2 - No - the code I have written is "pseudocode". You will need to reproduce this in a way that suits you.
Q3 - You could do either, but I would strongly recommend a series of decision blocks. It will be more readable, and will also work in Flowcode simulation.
I hope this helps.
I'll try to answer all of these questions together by explaining a general approach I have about programming. Bear in mind that this is a personal preference and others may disagree.
There are often multiple ways of completing a programming task, but I tend to favour an approach that makes the intention of the code as obvious as possible. It may not be the most "elegant", concise or optimised way possible, but it should be the most readable. There are times where you need to overcome code size limitations or produce code that is as quick as possible, and in such cases a compromise is needed - but these cases tend to be rare.
Another thing to note is that a concisely-written flowchart (or C code routine) does not necessarily produce a small or quick piece of assembly code. I have seen cases where a single "neat" statement in C has used up 10 times as much program memory as a more verbose set of statements.
Coming back to your questions...
Q1 - You should be able to create a simple program to test this code if you want. But if you are producing code that you are unsure of, then it's probably best to adopt an approach that is easier to understand.
Q2 - No - the code I have written is "pseudocode". You will need to reproduce this in a way that suits you.
Q3 - You could do either, but I would strongly recommend a series of decision blocks. It will be more readable, and will also work in Flowcode simulation.
I hope this helps.
- JonnyW
- Posts: 1230
- Joined: Fri Oct 29, 2010 9:13 am
- Location: Matrix Multimedia Ltd
- Has thanked: 63 times
- Been thanked: 290 times
- Contact:
Re: Am I bit shifting correctly>
Hi Ron.
If you wish to use a single calculation block your code should work OK - all the following alternatives offer the same result:
And no, none of the above will alter the SLV28AB_DI.Calc_Temp_1 value.
I hope this helps,
Jonny
In general, I would avoid the use of C blocks as this can not be picked up in the simulation (C blocks are ignored). The approach you suggest will work, but as Steve points out, this can be a little unclear.I think I would need to use a "C" block and put the FCV_ in front of all the vars OR use a whole bunch of decision blocks for the "IF" statements, then use VAR = 1 or VAR = 0 in CALC blocks based on Yes/No path taken.
If you wish to use a single calculation block your code should work OK - all the following alternatives offer the same result:
Code: Select all
DI_03_RS485_NODE_6 = SLV28AB_DI.Calc_Temp_1 << 5 // SHIFT LEFT TO GET RID OF ALL OTHER INPUT VALUES
DI_03_RS485_NODE_6 = DI_03_RS485_NODE_6 >> 7 // SHIFT RIGHT SO ONLY THIS INPUT IS REMAINING = 1 HI, =0 LO
Code: Select all
DI_03_RS485_NODE_6 = (SLV28AB_DI.Calc_Temp_1 & (1 << 2)) != 0 // 1 if not equal zero, else 0
Code: Select all
DI_03_RS485_NODE_6 = (SLV28AB_DI.Calc_Temp_1 >> 2) & 1 // 1 if not equal zero, else 0
I hope this helps,
Jonny