How to read bits

Hi! I'm starting to go more deeply in programming and I want to start to not use librarys but write myself the code. It's of course inevitable to know how to work with bits. Now, I know that a bit can assume a low and an high state, that 8 bits make a byte, but I completely don't know how to "read" those bits. Sensors and ICs in general communicate with bus, but does those bus have a different "way" to send bits? Then, I have read my bits and stored them in a variable, then does I apply a function for convert my byte in a decimal number?
Thanks very much!!

bitRead ?
bitWrite ?

Not ideal, but pick them apart, and see how they work

You're overthinking this. You can send and receive numbers or ASCII through various comm methods. They are bits and bytes.

No need to apply a 'function' to convert to whatever. If you mean you want to rewrite something like the wire.h library, then yeah, I guess you have to manage bits. You can open up wire.h wire.cpp to see how they do it.

Then, I have read my bits and stored them in a variable, then does I apply a function for convert my byte in a decimal number?

Yes... Context! Of course, everything in the computer is stored in binary. ...When you write a program, the C/C++ compiler knows if something represents a decimal number or text or something else, and it makes the appropriate conversion to binary.

By default, input and output are converted from/to decimal numbers (and [u]ASCII[/u] characters).

When an application reads a byte (or a word) from memory or from a file, the context determines what it means.

For example, a byte in a file might represent part of a pixel color in an image file, an ASCII character in a Word document, or part of an audio sample in a WAV file, etc. In the case of a computer program, a byte might represent a machine-language instruction for the CPU.

If you open a file with a [u]Hex Editor[/u] it will show you all of the bytes (in hexadecimal) and wherever there is a value that converts to an ASCII character, it will show the ASCII character, even if that byte doesn't really represent ASCII because the hex editor doesn't know the context. For example, everywhere there is a byte with the value 65 (=41 hex =0100 0001 binary) it will show an upper case 'A'.

The Windows Calculator in Programmer View can convert between decimal, hex, octal, and binary. When programmers work with binary, they usually use hexadecimal in the program because it's easy to convert between hex and binary. You can easily learn to convert numbers of any size between hex and binary in your head because each group of 4-bits converts exactly to one hex digit. Converting between decimal and binary is not so easy! (I looked-up 65 Decimal and 41 Hex on the ASCII chart, but I converted 41 Hex to binary in my head.)

http://playground.arduino.cc/Code/BitMath

What you need to know.

Subsea:
but does those bus have a different "way" to send bits?

Generally speaking data can be sent in one of two ways - in parallel where there is a separate wire for each of the 8 bits in a byte. The old PC parallel printer port worked like that.

Or in serial (which is almost universal) where a byte is transmitted one bit at a time and reassembled into a byte by the receiver. For example that is how Serial works in the Arduino (and also SPI and I2C) and the USB system.

For the most part the programmer does not need to concern him/herself with internals of the transmission process. You can use Serial.write() to send a byte and Serial.read() to receive a byte.

If you want to study what goes on in between you might like to look at the code in yet another software serial - it is probably a bit simpler than the Arduino Serial code. However if you are new to programming it may appear complex.

One way in which you may encounter bits is if you want to assemble the values from several I/O pins into a single byte to save SRAM or for some other reason. Or the converse of that where you want the different bits in a byte to be output on different I/O pins.

...R

Wow guys!! Thanks very very much for replys! So, as I could understand I don't have to worry about "how to read bits" because there's librarys that do this for me. For example in the wire.h library for i2c

Wire.write("hello");

sends 5 bytes, which every one is composed by 8 bit selected by ascii tabels?
And so for example if I have a sensor that sends 12 bit I can read those by

MyByte=Wire.read();

and then with the bitRead function to read the bits that I need (if for example the first 4 bits are useless)
And if I need the SPI I need to search for a library that reads the byte send from an SPI device and so on.
Have I understood? :slight_smile:

P.s. I don't know if there's something in commerce that matches my description, I invented the values only for understang.

Wire read only reads 8 bits at a time. It works by 8's.

You didn't read the BitMath tutorial. If you only care about the high 4 bits of a read you can mask the low bits

byteVar = byteVar & 0xF0; // 8 bit masks off the lower 4 bits, all become cleared = 0.

or if the value of those 4 bits, 0-15, matters then

byteVar = byteVar >> 4; // right shift the high 4 bits into the lower 4, now the bits are 0 to 15

You can set any or all bits in 1 command using

byteVar = byteVar | 0xF0; // 8 bit mask to set the top 4 bits all at once.

When you can do bit logic you can manipulate a whole port, input or output at once on every open pin which on an UNO is six pins on three different ports. For any one port you can say "same time" about six pins.

I use 2 bits to detect changes in pin state. One bit is the (just read) present state and the other bit is the previous state. If the value is 0 or 3 then the pin state has not changed. If the value is 1 or 2 then it has changed with the new state in the first bit.

Perfect thanks!! I'll read BitMath, sorry for haven't... However, you made this very cleare! I hope someone in the future can open this page and clarify his ideas ;D :wink:

I've just peeled a corner back and you've had a smell is all so far.

You can count 0 to 15 on four fingers.