Am I bit shifting correctly>

For Flowcode users to discuss projects, flowcharts, and any other issues related to Flowcode 2 and 3.

Moderators: Benj, Mods

Post Reply
Ron
Posts: 225
Joined: Wed Apr 11, 2007 6:15 pm
Has thanked: 2 times
Contact:

Am I bit shifting correctly>

Post by Ron »

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

User avatar
Steve
Matrix Staff
Posts: 3422
Joined: Tue Jan 03, 2006 3:59 pm
Has thanked: 114 times
Been thanked: 422 times
Contact:

Re: Am I bit shifting correctly>

Post by Steve »

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

Ron
Posts: 225
Joined: Wed Apr 11, 2007 6:15 pm
Has thanked: 2 times
Contact:

Re: Am I bit shifting correctly>

Post by Ron »

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

User avatar
Steve
Matrix Staff
Posts: 3422
Joined: Tue Jan 03, 2006 3:59 pm
Has thanked: 114 times
Been thanked: 422 times
Contact:

Re: Am I bit shifting correctly>

Post by Steve »

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.

Ron
Posts: 225
Joined: Wed Apr 11, 2007 6:15 pm
Has thanked: 2 times
Contact:

Re: Am I bit shifting correctly>

Post by Ron »

Thanks Steve.....

Ron

User avatar
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>

Post by JonnyW »

Hi Ron.
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.
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.

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
And no, none of the above will alter the SLV28AB_DI.Calc_Temp_1 value.

I hope this helps,

Jonny

Ron
Posts: 225
Joined: Wed Apr 11, 2007 6:15 pm
Has thanked: 2 times
Contact:

Re: Am I bit shifting correctly>

Post by Ron »

Hi JonnyW,

Thank you, I appreciate it.

Ron

Post Reply