MicroPython Hardware: I2C Devices with Tony D! @micropython

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hey it's Tony from Adafruit and in this video I wanted to look at micro Python and how to talk to I squared C devices and I squared C is just another way for two devices to communicate with each other usually on a board or like with a small connection between them so typically like a sensor or maybe a little OLED display has an i2c interface which you can connect to a board like an Arduino or Raspberry Pi or a micro Python board and we'll see in this video stream how to use i2c operations like reads and writes to registers and memory to interact with the device so in this case I'm gonna look at the mCP 9808 high precision temperature sensor really nice little temperature sensor just tells you what the temperature is in celcius and is a very simple I squared C interface so it's a good example of just looking at how you could talk to an I squared C sensor with micro Python so we'll just kind of dive in here and get started I'll jump to the main view let's see we'll turn on desktop and everything else so you can see here's desktop view and in the upper right hand corner so what I have here is the feather huzzah esp8266 running the latest micro Python firmware for it so just a very typical board check out if you're not familiar with micro python in the description below when this goes up on YouTube I'll have a link to the what is micro Python guide that I did so start there if you're new to micro Python you can learn about like what are all the different boards that run micro Python how to get started how to load the firmware that type of stuff but basically you'll need a board that runs micro Python obviously and then right here is the mCP 9808 temperature sensor and again real simple nice little low cost temperature sensor great example of talking to an I squared C device with it and then on the desktop here so I've just got a guide that was just published that goes into detail about how to talk to I squared C devices with micro Python so I'm just gonna kind of walk through this real quickly I'm not gonna spend too much time explaining what I squared C is you can check out the Wikipedia page it's so little complex you know you skim it a little bit but it's not gonna really give you the main idea but again I squared C it's very similar to like spy or serial connections you know two devices talking to each other with a few different wires the I squared C is an interesting kind of protocol or bust because it only really uses two wires there's a clock line and a data line and of course you have to have a power and a ground line so there's really like usually four wires connected to a device but just with those two wires multiple devices can talk to each other so in the last video I talked about spy devices the serial peripheral interface and how with that you basically have one device that controls the bus and like specifically controls the clock line that all the other devices connected to it used to synchronize the communication so they can read and write data whereas with I squared C it's a little more interesting and that there's a clock line but no single device controls that clock line well actually any device can take control of it there's no device that's designated like the master that has exclusive rights to it so some device can just pick up the bus and they have a way to tell if it's in use or not that's actually their pull-up resistors on the bus so that it normally stays at a high level and then if someone pulls it low then they kind of know if it's in use or not but you don't need to really understand all those details the basic idea is that multiple devices can be connected to this communication bus and any device can talk to any other device so they're assigned an address and even inside of a device you might have like memory addresses that you're talking to and we'll look at some of these basic operations so again it's just a really a common way for devices to talk to each other sensors in particular usually have an I squared C interface but you'll also see see things like little OLED displays might have that I think like the motor and the PWM drivers that we have use I squared C so really really common interface and there are just some basic operations to learn with it and once you get those down it's pretty straightforward and really all the complexity is just gonna come around to what device you're talking to what data it has what format that data is and you know that kind of stuff and so we'll kind of dig into a data sheet here and see maybe give you some pointers on how to figure that stuff out yourself the other thing that you mentioned if you're curious check out this video and I'll put a link to this in the description below when this goes up on YouTube boy maybe nine months ago almost no no maybe eight months ago or so it's been awhile I did this video on more in the context of with the Raspberry Pi what I squared C is in this video is kind of cool though I use the logic analyzer you can actually see right here this alien logic analyzer and I looked at on the wires like what that actual I squared C communication looks like so you might check out this video if you're kind of curious what it's out works and a little bit different since then that that's me there trust me that's the same person okay we'll come back to this this is the datasheet I will will get started with a guide here so basically in this guide I talk about two different things I make a mention of like an I squared C master mode versus slave mode this is really common in embedded stuff you know there's sometimes like a master device that controls the communication between a bunch of other slave devices like I said with I squared C though really any device can kind of be the master that talks to other devices on this bus any device can kind of take control of that clock and data line so there really isn't as much of a distinction here but micro Python does make a little bit of distinction because you could put some boards not all of them into a mode where they can act as an ITC slave where they advertise themselves as a device not necessary advertise but they listen for requests against a certain address so you'll see with I squared C devices each one is assigned a unique address and with some microbiome boards you can actually put it into a mode where you say ok I should act like a device that has this address and listen for requests and send responses back so that would be good for if you're building like a sensor that's powered by micro Python for example then you'd want to expose it potentially as an I squared C device or a peripheral or slave mode device like that but it's usually not as common because typically you have a board like a micro Python board or nardoo we know or something that's running some code and talking to sensors and in that case you really just care about acting as a client or a master of the I squared C bus so that's what I'm gonna focus on in this videos just looking at how to talk to other I squared C devices not so much how to advertise yourself as an I squared C device and then the other big thing too like a lot of things with micro Python you know it's still pretty early in development so things are changing a little bit but it's still pretty cool and stable in and worth checking out but for I squared C in particular look at the documentation for your board because there are some small differences between the boards and some big differences - with some of the boards but over time they're all starting to become very similar but so I call out in this guide I look mostly at the esp8266 but I do call out where there are differences the pi board has a few differences right now it's using this older interface from this pyb module eventually that's gonna change to use this machine module that everything else uses so just be aware of check out the pi board documentation and the function names are a little bit different with the pi board why pi is pretty similar to esp8266 there's just one difference where you have to tell it to be an I squared C master instead of a slave device and then the micro bid is actually really different than everything else it has a very simple API basically you just read and write I squared C data I'm not sure that their API is good enough to talk to most devices so you know just a word of warning the micro bit you if you're expecting to do some crazy I squared C thing with it look at the documentation first and make sure it's gonna work for it it looks like it can really just read and write just bits of data on the bus I'm not sure can interact with devices but that's at least the current state of the world I'm sure it's gonna change over time so again check out your board documentation to just see how things work then for this guide like I said I have wired up the mCP 9808 temperature sensor really easy to connect I squared C devices to boards with the esp8266 you do have some flexibility in that the I squared C protocol is implemented in software so you can use any GPIO pins now there are some downsides like it's not going to be as fast but for things like sensors you typically don't need like super high refresh rates most fast devices use like a spy interface where you can use the clock at whatever speed you want usually like multiple megahertz whereas with I squared C there's a fixed clock rate it's like 400 kilohertz usually and I think there's like a 1 megahertz high-speed mode so usually it's a little bit slower with I squared C so you don't have like massive LCDs with huge amounts of pixels to push very quickly but anyway so with ESP you have a lot of flexibility you just have to connect up you know your voltage input voltage to power the device ground obviously you need those basic connections and then there's the SCL the clock line so that connects usually to GPIO number five on the esp8266 and if you're using the feather huzzah it's got nice little labels here so just connect SEL SEL and then the SDA the data line that's connected to GPIO number four and so again you've got a nice little labeled port there but you could use any other GPIO s just be aware though on the esp8266 some of the GPIO lines have like pull-up and pulldown resistors connected to them like I think GPIO 15 has a pulldown resistor I want to say connect it to it so you might run into weird behavior if you try and use some of these pins you know stick with 5 and for those ones are known to work pretty well for it so that's the basics wired up and you're pretty much good to go at that point so let's just dive in and start playing with some of the code for this so I'm gonna connect to the serial repple for my board and this is just you know micro pythons repple and the first thing I'll do is I'll import the machine module so this is the module it has the hardware access API you see this all the time you know if you want to access GPIO spy I squared see everything with hardware you're using this module and again on the PI board it's called pyb but check the documentation that's gonna change eventually and then the next thing is you create an instance of this I squared seat class and for the esp8266 you have to pass in the pin number for the clock line a not the pin number but an actual pin instance for the clock line and the data line in that order so in this case I'm going to create an I squared C device will create an instance die spritzee class and we'll pass it pin number 5 as the clock line and pin number 4 as the data line so that's pretty simple and straightforward for other boards like the pi board and the y pi they use a hardware I squared C interface where instead of passing in the GPIO pins you pass in the number of the interface to use so look at your board documentation usually you use like interface 0 or 1 just because most boards have like only one or two I squared C interfaces and one thing to know too is that for those boards when you do use a hardware I squared C interface you usually have to use a specific set of pins like there's a very specific clock line and data line for that hardware I squirts the interface so when in doubt check the board documentation the quick reference for all of the boards usually has a pin out description that just shows here all the pins and you know you should look for like what is the I squared C clock and data line and that should help you find out which ones to connect to so okay so at that point then you're pretty much set now there's a really cool thing with I squared C like I mentioned every device on the I squared C bus has an address assigned to it and it's just a seven bit value so 0 to 127 and I think the first few values are reserved but you know mostly about 100 devices can be connected into the bus now that is a limitation like you cannot have more than that 127 uniquely addressed devices on the bus like it's just not physically possible if two devices have the same address you're gonna get a lot of confusion there each one's gonna try and respond to the same thing and it's your bad things will happen so in those cases maybe I squared C isn't a good you know protocol for you or maybe you need multiple buses to have more devices or I think there are I squared C multiplexers which are pretty complex things but you know that could be an option to to look at but the neat thing is you can actually scan for what devices are on the I squared C bus so with my trip I thought it's beautiful they have this nice little scan function that you just call and this returns an array a list of devices that it found and the address of those devices and this is in binary or in a decimal like just you know base 10 so this is a value 24 now you'll want to usually go to your datasheet and this is the mCP 9808 datasheet data sheet that I have right here for your device because you're gonna have to look up what is the address that the device exposes itself as and so I'll go through this data sheet and we'll see if we can find it in here so you can see yeah like right here there's a concept of these address pins and it's actually exposed on the breakout there's these a a 0 a 1 a 2 I think pins out here and so if you pull these I think if you pull them down or set them high check the the tutorial on this little safer specifically you can actually set the address it's advice but you can't completely change the address so you can see right here some of these high order bits are always set and then you can control the lower three bits here and so I think by default or zero so just think of this as the binary value one one zero zero zero so if I go to calculator here and we just set this as one one zero zero zero and then base ten you can see the unit value twenty four so that's good that basically tells us that we see a device on this I squared C bus that has an address of twenty four in decimal or in base ten so we see the exactly device we expect we see the mCP 9808 if I had multiple devices connected this and each device just shares the exact same clock and data line like you can daisy-chain all these connections you can put them all in parallel it's it really doesn't matter how you do it but as long as they're all connected to the same clock and data line and they have unique addresses you should get back a list of each of those devices there so it's a good little sanity check to be able to test like is the device there that I expect to see and again you don't really get this with other protocols like spy because you know they don't have a concept of each device having an address that's like a you know higher level thing to add on top of the spy protocol so that's kind of a neat thing that you get with this and then let's see the next thing to do is to interact with the device so this is where you get into some of the basic I squared C operations and you really do need to dig into your data sheet at this point to figure out like how do you talk to this device so for the mCP 9808 and usually in the datasheet there's like a section here on the serial communication and this kind of goes into boy I just went to different page you're on accident this kind of goes through what what it looks like at like the physical level so there's usually a diagram you know like this that's showing you okay here's how the bits on the wire look and here's how the clock line changes and here's how the data line changes but the nice thing is you usually don't have to worry about that because a lot of the I squared see details are taken care of for you by the software so like the micro Python code it knows when it's talking to a device how to send the address and there's a certain act bit knack bit and like you know an acknowledgment that things have been received that's all taken care for you so don't really focus on that so much the thing you want to look at for I squared C devices in particular look to see if the device exposes data using registers or memory this is a really common thing where a device usually has an address assigned to it so that you have to use that address when you talk to it and then within the device there's also an address of a register or memory that you want to interact with so there's usually two bits of data that you need to know when you talk to a device the address of the device and the address of the register or memory that you're talking to and so this data sheet goes through all of the registers on this device and actually talks about so like right here these are the registers so there's like this reserved one there's a config register temperature alert upper bound lower bound critical alert there's a temperature register this is actually the one that we care about right here that has the temperature value from the device and then all kinds of other stuff here so this is kind of handy and then it the rest of the data sheet usually goes through each register like registered by register to say okay you know here is the sensor config register and here is you know this is 16-bit so you can see and here's exactly what each bit inside of here means and so you can go through and it even tells you like okay you know this alert control this thing is readable and writeable whereas this alert status is only readable you know this R here so you know different things might behave differently and you really need to look at the data sheet to see how it works now let's go down to that temperature register on the datasheet here so it's a little bit further down it's registered number five if I remember it correctly yeah the ambient temperature register and you can see here so they're they're showing the address here is the value 1 0 1 in binary so that's 5 in base 10 so that's uh that's what we want to read if I read this register and you can see it's 16 bits long there's some data inside of here so there's actually these upper bits that tell you if you've exceeded like your lower boundary your upper boundary your critical threshold got an easy way to check like you can set this upper bound your boundary and then just look for that bit to tell if you've gone above some high level you know maybe you're building like a barbecue temperature monitor or something and you know you can set your upper boundary temperature to like 200 something degrees and if it goes above that just look for your bit to know that something went wrong or that you know you're burning your ribs but then you can see the lower 14 bits or no sorry lower 13 bits here are the actual temperature data so there's a sign bit and this is all pretty typical stuff in that this is a two's complement signed integer value the annoying thing is that you know this isn't like a 16-bit or a 32-bit value that in Python kind of can natively understand and unpack so I've got to do a little more work to interpret this value but I'll show you I actually have a library for this already it's really simple 3/4 one of these days though I'm gonna sit down and write a library that's an arbitrary bit length two's complement value converter you know just throw in a a 16-bit register say here's where the value starts and it's a 12 bit signed value or a 14 bit unsigned value because I end up doing this like almost every time I deal with a sensor and I'm reinventing the wheel a lot but anyways this is what I want to do so I want to read this register register 5 on device with address 24 so the way to do that is with a simple function from micro Python there's the read from underscore mem function and so I show first it's kind of helpful let's make some variables here so I'm gonna make an address variable set this to the value 24 so that's the address of my I squared C device and then we'll make a tempest temperature register variable will set this to 5 that's the address of the temperature register and then there's also a resolution register that's a value of 8 and we'll come back to this because this is one that I can write to and so I'll show you how to write to one of these registers also in a second ok so now that I have these let's grab the value of the temperature register so you just need to call ITC dot read from underscore mem and then you pass in the address of the device the the register that you want to read from so you know number 5 the temperature register and then the number of bytes that you want to read so 2 bytes in this case and when I do that I get back this value here so this is basically giving me back a bite string and this /x format this is basically just saying that this is a hex value so it's not a printable character and then this is a printable character but it's escaped because it's a slash it's a little confusing but you know you can see I can call this thing and if I hold my finger over this and heat it up we'll see the value should change so yeah like these lower bits change like they probably increased and that's good because I know from the datasheet that lower bit or byte rather the this lower byte is the temperature data so that should be increasing if it's going up and it looked like at least a change there so that's cool that's one way to read the data and I could save this and say okay you know data equals i2c dot read from underscore mem address tenth register and then two bytes from that oops read wrong no that's not what I want read from memory and so now the data value has that inside of there too another way that you can do this and I showed this before in this five video you can save the data into a buffer that you allocate ahead of time because when you call this function it's actually creating a bit of memory that's two bytes long and using that to return the value to you and that's fine in some cases but if you're doing this in a loop on a device with limited memory like remember this ESP only has like the I think 96 kilobytes of memory and some of that's taken up by micro Python so you know if you're constantly allocating little to byte chunks of memory in a loop that's gonna add up and there is a garbage collector like it will kick in at some point and maybe find unused memory and reclaim it but that takes time that's gonna be performance hit and you can fragment memory to the point where maybe you can't allocate any memory anymore so it's the kind of thing where if you're used to like desktop Python programming where memory is effectively unlimited you know like every machine these days has at least probably four gigabytes of memory or more and that's you know to an embedded programmer that's unlimited memory so you're not really used to having to worry about that where is you come to an embedded or like this you do have to kind of think about even though python is garbage collected and dynamic and you know really amazing for what it is you still can't really break the laws of physics or the laws of limited memory on here so you know you really have to be aware of that anyways though so here's how this works you create a byte array first and the size of the byte array is basically how much data you want to read from the device so I want to read two bytes so I create a byte array like this and if I look at this you can see it has just two bytes and they're set to the value zero and then I want to call the function I to see dot read from underscore mem underscore into and then I pass it the address and the register to the temperature register again and then I passed the buffer that I created and I don't need to pass it this size because the Python buffer the byte array knows how big it is so it's just going to fill that buffer with data and so I call that and now you can see this thing has some value and it looks kind of similar to the other values that I had there so again just a different way to use the to read data this is smart if you're doing something in a loop you know you can allocate this buffer once ahead of time and then every time you call this function no memory is allocated like it's using this buffer that you passed in and it's just filling that with with memory or with the value that are read so really had anything to remember you know in a lot of cases you probably want to use this format but if you're just playing around it doesn't hurt to try out you know these functions here if it's just like a one-off thing don't worry about it you know you're probably okay for that so okay so I've got this and then real fast I'll just show you how to interpret the value for this I don't want to run too much longer on this stream but again the beautiful thing because this is Python you know I can just write some really simple Python code right here like a function that converts this temperature into degrees Celsius because remember I have to pull out that fixed point about are not fixed point put that that signed value in a to complement value from the register and I'm actually I pulled this code from Python code that I wrote to use this sensor with the Raspberry Pi and I can't remember I wrote this code I might have ported it from the previous raspberry pi code that we had but anyways this is the code right here like you're literally just grabbing those lower bits of data and then converting from tooth compliments to just a floating point value effectively so let's just throw this function in our code here real fast and again it's the beautiful thing I love about microfiber on so let's see I'll try to make both these visible I can just define a function to do this and then I can use that function forever in in my repple window here to easily do this conversion so I'm just gonna grab so I'm gonna make a function you're gonna pass in this byte array of data and then it's going the first thing has to do is convert this into an integer value because the byte array is like an array of bytes but I want to be able to reason about this as a 16-bit value so I'm just gonna take the first bite and shift it over eight bits so it's the upper eight bits of a 16-bit value and I'll put parentheses in here just to be a little more explicit about the order of operations and then I'll or in the look of the next byte so that this is the lower eight bits of data so basically the first byte is the upper eight bits the second byte is the lower eight bits really common way to do this is you know using the boolean or or the bitwise or operator here okay and then now I'll grab the temperature and it's the lower the lower 12 bits of data here so if I and my value with oxf FF that's basically gonna grab those twelve bits of data and then the sign bit isn't that thirteenth bit that we'll look at in a second and if I divide that by 16 and that's gonna do some of this conversion into the floating-point kind of value and now I want to check if that sign bit was set and so I'm gonna look and see is that thirteenth bit set by just checking the end of that bit so we grab that bit right there and if that's true if that's a nonzero value then we need to negate this by 256 so that we get kind of the proper negative value for this and then we just want to return the temperature here so that's cool a neat little tip I learned about microfiber on enter three times it will end the indentation that you're in so we'll do one two three oh I guess yeah there we go three so so it ended that so a little little tip I just learn recently for that okay now if I call this function and I passed in that buffer of data 21 point nine three seven five so that looks like a degree Celsius temperature and if I hold my finger on here and let's grab another reading oops actually I'm gonna have to type this out again let's do I to see dot read from mm into and then the address and the temperature register and the data buffer all right so I'll hold my finger on there warm that sensor up a little bit so we grab the value and then if I read this again twenty five point eight seven five so a little bit warmer temperature for that so it looks like that's working so that's pretty straightforward and pretty easy you know you're just season this read from function or read from them into and you're getting the data here and again I should note the pi board has different function names for this and the microbe it has like totally different functions so go look at the documentation for those but the basic idea is similar that you have a device with registers and you're reading from those registers there's also a write to or you can write to date it to a register I guess I'm kind of running short on time so I'm not gonna go into this in the video here but I explained the guide and there's a register on this device the resolution register and so if I go down to the datasheet here it explains a little bit more about this let's see I think yeah here we go the resolution register this changes how accurate the sensor is so by default it's in this mode where it will give you temperature in increments of 0.06 to 5 degrees Celsius but you can see it takes 250 milliseconds to get a temperature measurement so you can put it into a faster mode where you're only going to get half a degree Celsius of resolution but it only takes 30 milliseconds so you'll get faster temperature updates with less precision or less accuracy rather so it's a trade off you know nothing's for free here but the cool thing is you just have to write this these two bits here in this register and you can change the behavior of this device really easily so check out the guide I explained you just have to call right to mem and it's that easy you pass the address the register and then a byte string that has the value that you want to write out of this device so that's how you read and write to the device on with those basic operations you could probably talk to almost every I squared C sensor because most of use that kind of register format now I do mention there are device operations and this is for devices that don't have that register or memory interface so for those devices you only need to know the address of the device and then you can just send and receive strings of data with them a little less common I can't think of a device offhand that uses this approach but there are some out there so just something to be aware of and there are functions for that so that's read from read from into and write too so there's just no underscore mem for these functions exactly the same as the underscore member tchan you just don't pass in the address of that register but you still pass in to address the device and on the PI board it's the different there's like a rec fee and a send function that they have so check out the documentation for that so that's the device operations and then for the esp8266 port they do have these raw or primitive operations I'm not going to get into these but at a very low level and I talked about this more in the video that I mentioned I squared C is made up of there's like a start bits there's a read operation a write operation and a stop bit and you put all those together into like a transaction and there's an acknowledgment of each thing that happens so you can actually get really low-level control with the esp8266 port I don't think you can do this with the other boards though at least it doesn't look like it's implemented there and for most Hardware I squared C interfaces you don't usually get very low level control because the hardware is doing that for you so just I'm gonna be aware of there it is possible to mess with the bus at a low level if you need to for this so check that out and then like I said the I squared C slave mode I don't really get into it in the guide here the pi board does support it so check it out if that's something you want to do like create a peripheral but check out the documentation for that because it'll show a little bit more details about how to do it it's a little less common but it's a cool thing that you can do with that board so that said I think I'm gonna wrap this up then this was the end of the stream oh I just realized I had this off half the screen for a while so I think everyone kind of got the gist of it though so uh let's see I don't see you anyone in the chat so I think well we'll skip the questions for now and just kind of end this stream so we'll go back to the main shot here so thanks a lot for watching check out youtube.com slash Adafruit you can see this video and all kinds of other fun videos check out twitch.tv slash Adafruit that's where I'd like to do these live streams I like to do a couple live streams a week usually one on Monday this week I couldn't do it on Monday I was just coming back from a busy weekend in Portland Oregon so I had the Portland Mini Maker Faire Rose City Comicon like Portland Comic Con and then the xoxo festival so all of them were amazing events check out the blog I put up some photos of the Mini Maker Faire and Rose City Comic Con and hopefully later I'll do a post about like impressions of the xoxo festival everything was really awesome I love the Rose City Comic Con the cosplayers there were just out of this world the amount of work and effort and just the quality of what people do is really really impressive so okay so that's it I'll wrap this up this was I squared C devices with micro Python so Tony from Adafruit and until next time I'll see you guys later so thanks
Info
Channel: Adafruit Industries
Views: 10,887
Rating: undefined out of 5
Keywords: adafruit, electronics, diy, arduino, hardware, opensource, projects, raspberry, computer, raspberrypi, microcontrollers, limor, limorfried, ladyada, STEAM, STEM
Id: SJTk7V7iC1I
Channel Id: undefined
Length: 32min 22sec (1942 seconds)
Published: Wed Sep 14 2016
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.