Referencing individual pins, in Hex, Bit masking - hex

I'm using a netduino plus 2, and need to understand how to convert an individual pins's number into hex for bit masking, eg:
PERSUDO
if counter_value_bit_1 is 1, do:
write 1 to D0 pin
else
write 0 to D0 pin
..... counting from bit_1 through bit_9.
if counter_value_bit_9 is 1, do:
write 1 to D0 pin
else
write 0 to D0 pin
Answer
if (counter_value & 0x01) { //bit_1
...}
if (counter_value & 0x200) { //bit_9
...}
My question: how do you get 0x200 = bit 9, ect?
An example or two for bits in between 1 and 9 would be great.
THANKS

Which language do you use?
In C you cant handle a bit "9" in a portable way, see byte ordering. If you know the byte order you could extract the byte with bit 9.
#define BYTE_WITH_BIT_9 ...
int counter_value = 42;
((char*)counter_value)[BYTE_WITH_BIT_9]
Cast to char* to access the raw bytes. Then chose the byte and now you can do magic bit operations.

Related

Data loss via serial port (RS232)

I am trying to read a series of data via serial port. Below are my test scenarios:
I have a sender (POS terminal) and a receiver (dll) on windows 10. Both connected via RS232 cable (9 pins).
The sender writes 16 bytes of data at one time. The receiver is able to read the data, 1 byte per read, by looping 16 times.
The sender writes 114 bytes of data at one time. The receiver is able to read the data , 1 byte per read, by looping 114 times.
The sender writes 115 bytes of data at one time. The receiver is able to read the data, 1 byte per read, by looping 115 times. But the last character is lost. In other words, the last character seems to be corrupted.
E.g. Data written: ABCDEFGHIJKLMNOPQRSTABCDEFGHIJKLMNOPQRSTABCDEFGHIJKLMNOPQRSTABCDEFGHIJKLMNOPQRSTABCDEFGHIJKLMNOPQRSTABCDEFGHIJKLMNO
I am able to get "ABCDEFGHIJKLMNOPQRSTABCDEFGHIJKLMNOPQRSTABCDEFGHIJKLMNOPQRSTABCDEFGHIJKLMNOPQRSTABCDEFGHIJKLMNOPQRSTABCDEFGHIJKLMN" correctly. But the last character 'O' is corrupted. Instead the data read in place of last character is (ASCII value) 205, 255, 234 etc. The data is not consistent during multiple read attempts.
Can anyone please put some light on this? Can anyone guide me if I am missing something-somewhere?
I referred this article for my project: Serial Port Communication
Below is the code snippet:
//Port opening.
HANDLE hPortDailUp = CreateFile(portfinal,
GENERIC_READ | GENERIC_WRITE,
0,
NULL,
OPEN_ALWAYS,
0,
NULL);
//Setting COM timeouts.
SetCommMask(hPortDailUp, 0);
SetupComm(hPortDailUp, 2048, 2048);
GetCommTimeouts (hPortDailUp, &commTimeOuts);
commTimeOuts.ReadIntervalTimeout = 100;
commTimeOuts.ReadTotalTimeoutMultiplier = 70;
commTimeOuts.ReadTotalTimeoutConstant = 1000; //1000
commTimeOuts.WriteTotalTimeoutMultiplier = 0;
commTimeOuts.WriteTotalTimeoutConstant = 0;
SetCommTimeouts(hPortDailUp, &commTimeOuts);
//Setting port configuration.
DCB PortDCB;
PortDCB.DCBlength = sizeof(DCB);
PortDCB.BaudRate = BaudRate;
PortDCB.ByteSize = 8;
PortDCB.Parity = NOPARITY;
PortDCB.StopBits = ONESTOPBIT;
PortDCB.fOutxCtsFlow = RTS_CONTROL_DISABLE;
PortDCB.fRtsControl = RTS_CONTROL_DISABLE;
SetCommState(hPortDailUp, &PortDCB)
//Reading data from serial port.
unsigned char tempRecvBuf[3001] = {'\0'};
ReadFile(hPortDailUp, tempRecvBuf + nBytesRead, 1, &TempLen, NULL);
//PortDCB Value at runtime.
PortDCB {DCBlength=28 BaudRate=115200 fBinary=1 ...} _DCB
DCBlength 28 unsigned long
BaudRate 115200 unsigned long
fBinary 1 unsigned long
fParity 0 unsigned long
fOutxCtsFlow 0 unsigned long
fOutxDsrFlow 0 unsigned long
fDtrControl 1 unsigned long
fDsrSensitivity 0 unsigned long
fTXContinueOnXoff 0 unsigned long
fOutX 0 unsigned long
fInX 0 unsigned long
fErrorChar 0 unsigned long
fNull 0 unsigned long
fRtsControl 0 unsigned long
fAbortOnError 0 unsigned long
fDummy2 0 unsigned long
wReserved 0 unsigned short
XonLim 2048 unsigned short
XoffLim 512 unsigned short
ByteSize 8 '\b' unsigned char
Parity 0 '\0' unsigned char
StopBits 0 '\0' unsigned char
XonChar 17 '\x11' char
XoffChar 19 '\x13' char
ErrorChar 0 '\0' char
EofChar 0 '\0' char
EvtChar 0 '\0' char
wReserved1 0 unsigned short
It's possible your loop doesn't get the characters read out quite fast enough, so that by the 115th time, a new character is already overwriting the last one that is being read out too late.
To test this, you can add a very short delay between characters on the transmitter side, then see if the receiver acts differently.

Why does this binary math fail when adding 00000001, but work correctly otherwise?

I've tried everything I can think of and cannot seem to get the below binary math logic to work. Not sure why this is failing but probably indicates my misunderstanding of binary math or C. The ultimate intent is to store large integers (unsigned long) directly to an 8-bit FRAM memory module as 4-byte words so that a micro-controller (Arduino) can recover the values after a power failure. Thus the unsigned long has to be assembled from its four byte words parts as it's pulled from memory, and the arithmetic of assembling these word bytes is not working correctly.
In the below snippet of code, the long value is defined as four bytes A, B, C, and D (simulating being pulled form four 8-bit memory blocks), which get translated to decimal notation to be used as an unsigned long in the arrangement DDDDDDDDCCCCCCCCBBBBBBBBAAAAAAAA. If A < 256 and B, C, D all == 0, the math works correctly. The math also works correctly for any values of B, C, and D if A == 0. But if B, C, or D > 0 and A == 1, the 1 value of A is not added during the arithmetic. A value of 2 works, but not a value of 1. Is there any reason for this? Or am I doing binary math wrong? Is this a known issue that needs a workaround?
// ---- FUNCTIONS
unsigned long fourByte_word_toDecimal(uint8_t byte0 = B00000000, uint8_t byte1 = B00000000, uint8_t byte2 = B00000000, uint8_t byte3 = B00000000){
return (byte0 + (byte1 * 256) + (byte2 * pow(256, 2)) + (byte3 * pow(256, 3)));
}
// ---- MAIN
void setup() {
Serial.begin(9600);
uint8_t addressAval = B00000001;
uint8_t addressBval = B00000001;
uint8_t addressCval = B00000001;
uint8_t addressDval = B00000001;
uint8_t addressValArray[4];
addressValArray[0] = addressAval;
addressValArray[1] = addressBval;
addressValArray[2] = addressCval;
addressValArray[3] = addressDval;
unsigned long decimalVal = fourByte_word_toDecimal(addressValArray[0], addressValArray[1], addressValArray[2], addressValArray[3]);
// Print out resulting decimal value
Serial.println(decimalVal);
}
In the code above, the binary value should result as 00000001000000010000000100000001, AKA a decimal value of 16843009. But the code evaluates the decimal value to 16843008. Changing the value of addressAval to 00000000 also evaluates (correctly) to 16843008, and changing addressAval to 00000010 also correctly evaluates to 16843010.
I'm stumped.
The problem is that you're using pow(). This is causing everything to be calculated as a binary32, which doesn't have enough precision to hold 16843009.
>>> numpy.float32(16843009)
16843008.0
The fix is to use integers, specifically 65536 and 16777216UL.
Do not use pow() for this.
The usual way to do this is with the shift operator:
uint32_t result = uint32_t(byte3 << 24 | byte2 << 16 | byte1 << 8 | byte0);

Arduino Serial.ParseInt() Alternative

I need to read in exactly 1 three digit integer (example: 134) from the serial monitor. I am currently using Serial.parseInt() and getting the behavior I want, but it is very slow. What would be a faster alternative to this method?
Edit: All parts of the integer must be read in at the same time, so using Serial.available() and Serial.read() is not an option.
Edit2: I attempted using
while (Serial.available()) {
int val = Serial.read();
int val2 = Serial.read();
int val3 = Serial.read();
Serial.print("Val1: ");
Serial.println(val);
Serial.print("Val2: ");
Serial.println(val2);
Serial.print("Val3: ");
Serial.println(val3);
}
In the loop portion, but got the output
Val1: 97
Val2: -1
Val3: -1
Val1: 98
Val2: -1
Val3: -1
Val1: 99
Val2: -1
Val3: -1
when I typed abc into the serial monitor.
It's okay to use Serial.parseInt.
For me, in my setup function
//this will allow the parseInt to read faster and
//the arduino board will responsd faster
Serial.setTimeout(50);
This is because parseInt() will continue to read from serial until either
it reaches a non-integer value e.g. alphabet, or
the serial timeouts.

About pointers and ASCII code

im learning more about c language and i have 1 doubt about 1 code that i have seen.
main(){
int i = (65*256+66)*256+67;
int* pi;
char* pc;
pi = &i;
pc = (char*)pi;
printf("%c %c %c \n", *pc, *(pc+1), *(pc+2));
}
Output is: C B A
I know that ASCII code of A is 65, B is 66, and C is 67 but the variable i is none of them.
If i put variable i=65, the output is just A and dont show B or C, why?
And i would like to know why this code have that output. Thanks for any help.
The line
int i = (65*256+66)*256+67;
turns i into the following
00000000 01000001 01000010 01000011
int = 4 bytes or 4 groups of 8 bits
char = 1 byte or 1 group of 8 bits.
What happens is that a char pointer is used to point to a subset of the original int bits.
At first the pointer points to the 8 least significant bits (the group to the right).
And the letter C is printed. Then, the pointer it self is incremented by 1 which makes it point to the next group of 8 bits in the memory which happens to be B. And once more for the A.
*256 means left shift by 8 bit (1 byte) so the line
int i = (65*256+66)*256+67;
actually put A,B,C on 3 adjacent bytes in memory
then pi pointer made point to the address of integer i, then same address down cast to char pointer pc, so pc actually hold the address to a byte that contains 'A', and of course if you add 1 and 2 to the address that means the adjacent 'B' and 'C' get pointed to and print out.
EDIT: just to clarify a bit more int is 32 bit long but char is 8 bit, that's why u need a char pointer to represent an address valid for 8 bit long.
Characters are stored as bytes, as you probably know. The initializing of the variable 'i' has the following meaning:
65*256 // store 65 ('A') and left shift it by 8 byte (= '*256')
(65*256+66)*256 // add 66 ('B') and shift the whole thing again
(65*256+66)*256+67 // add 67 ('C')
'pi' is initialized as a INT pointer to 'i'
'pc' is initialized as a CHAR pointer to 'pi'
So 'pc' then holds the address of the beginning of the 3 bytes stored in 'i', which holds 'A'.
By adding 1 and 2 to the address in pc, you get the second and third bytes (containing 'B' and 'C'), as follows:
printf("%c %c %c \n", *pc, *(pc+1), *(pc+2));
Working on the bits here ;D

Convert little endian to big endian including 0 (zero)

Im trying to convert little endian to big endian and having trouble.
I have an array that has 2 bytes of unsigned char which is hex values.
and i would like to make it big endian by the zeros are gone and i cant get the values i want.
For example,
My goal is to get
array[0] = 0b
array[1] = 40
output = 0b40 so i can see this value as 2880 when %d
so i used
output = (array[1]>>4) | (array[0]<<4);
but in reality, i see
printf("output = %x04\n", output);
output = 00b4
I want that output to be 0b40 so i can get 2880 when i do
printf("output = %x\n", output);
output = 0b40
printf("output = %d\n", output);
output = 2880
thanks guys any help will be appreciated
You need to shift the bottom up by eight bits, not four, and not shift the top:
output = (array[0]<<8) | array[1];
See convert big endian to little endian in C for more discussion and code.

Resources