简体   繁体   中英

Arduino - 5 questions for real Wire.write() and Wire.read() explanation

I Googled this a lot, and it seems that I am not the only one having problems with really understanding Wire.write() and Wire.read(). Being novice, I almost never use libraries that are already written by somebody, I try to create my class for module in order to truly understand how this module works and to learn how to manipulate with it. I've read few books and too many tutorials, but I could summarise these in two: a) all tutorials are just showing the very basics of how to use these methods and b) they don't actually explain the steps, like everything is totally self explanatory. Call me stupid, but I have the feeling like somebody told me that 1 + 1 = 2, and then gave me some polynomial equation to solve :(
All book examples and almost all tutorials look like this imaginary example:

Wire.beginTransmission(Module_Address); //Use this to start transmission    
Wire.write(0); // go to first register    
Wire.endTransmission(); // end this    

//To read

Wire.requestFrom(Module_Address, 3); //Read three registers   
Wire.read(); //Read first register   
Wire.read(); //Read second register   
Wire.read(); //Read third register

And that's it about reading. When it comes to writing, it's even worse:

Wire.beginTransmission(Module_Address); //Use this to start transmission     
Wire.write(0); // go to first register   
Wire.write(something); //Write to first register   
Wire.write(something); //write to second register   
Wire.endTransmission(); // end this

So far, working with ANY module I got, it was NEVER that easy. Usually, every register has more than one "option" inside. For example, lets say that imaginary module has First read register like this:

ADDRESS | BIT 7 | BIT 6 | BIT 5 | BIT 4 | BIT 3 | BIT 2 | BIT 1 | BIT 0
data Byte1 | mute .| option2.........|.....................option3.......................

To read only option 3, I would use this code:

Wire.beginTransmission(module_address);    
Wire.write(0);        
Wire.endTransmission();    

Wire.requestFrom(module_address, 1);    
byte readings = Wire.read() & 0x1F; //0x1F is hexadecimal of binary 0001111 for option 3 in register 1    

QUESTION 1
What does this '&' after Wire.read() REALLY means? (I know that it points to option within register, but I do not really understand this, why is it there)

QUESTION 2
Why the previous problem isn't written anywhere? So many tutorials, so many books, but I "discovered" it by accident when I tried to figure out how one library was working.

QUESTION 3
Imagine that hypothetical module has third register in write mode looking like this:

ADDRESS | BIT 7 | BIT 6 | BIT 5 | BIT 4 | BIT 3 | BIT 2 | BIT 1 | BIT 0
data Byte3 | write flag.......| option2.........|......................option3........

How to write flag without affecting option 2 and option 3? Or in other words, how to write to register 3's write flag? If I take 11000000 could affect because maybe I do not know what exactly option 2 and 3 do, or I do not wish to interfere with default setup.

QUESTION 4
Certain modules have to be written in binary-coded decimal. Let's say, that you have a timer and you wish to set 17 seconds for countdown to 0.And to do that, you need to write number 17 to register one, but number should be binary-coded decimal. 17 as binary-coded is: 0001 0111. But when you do this:

Wire.beginTransmission(module_address);         
Wire.write(0);    
Wire.write(00010111);    
Wire.endTransmission();        

You get different number, 13 or 10 (can't recall what number, I know it was wrong). However, when doing this conversion: 17/10*16 + 17%10 it writes correct number 17. Yes, I also accidentally found this out. BUT, where is this equation from? I searched (obviously wrong) as much as I could, but there was nothing about it. So, how did somebody come with this equation?

QUESTION 5
Probably a dumb off-topic question, BUT:
should Arduino library be written in a way that others could find it difficult to figure out the idea behind it? In other words, to figure out what the developer was exactly doing? I remember that one person used a lot of messy code to read something from sensor and then formula to convert it from binary-coded decimal to print it to Serial Monitor, while the same thing could be done with simply
Serial.print(read_byte, HEX);
It's not that I am smarter (or better) than them, I just don't understand why somebody would write a complex code when there is no(really) need for that.

Thanks a lot for any help :)

Questions 1. - 4.: Are all covered by Bit Manipulation tutorial on AVRFreaks forum Tutorials . So in short:

  • 1) The & is used for bit masking in this case.
  • 2) If you look for "Bit manipulation" then there are loads of Tutorials.
  • 3) It's possible by Bit manipulation. How? For in memory variable just use bit masking. To clear two bits: var &= 0b00111111 to set two bits: var |= 0b11000000 . If you don't have register value, you have to Read & Modify & Write it back. If you can't read the value (for example it's internal address like for eeproms) you have to have this value in memory anyways.
  • 4) In C++ numbers starting by zero are in Octal base. If you want binary, you have to use 0b00010111. For the HEX base you have to use 0xFF. This is not explicitly mentioned in that tutorial, but both are used here.
  • 5) It should be as clear as possible. But for the begginers without good knowlege of C++ it's hard anyway. For me is most difficult to read the code without indentation or even worst with bad indentation, bad variable names. The libraries are usually written by advanced users, so it's not so hard to understand with some background like knowing the datasheet for used MCUs and so on.

BTW: wrong comments are also bad for understanding:

//0x1F is hexadecimal of binary 0001111 for option 3 in register 1

The value 0x1F is definitely not 0001111 in binary but 00011111 (or better: 0b00011111 )

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM