I2C - Raspberry Pi, Pico and an Arduino

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hello in an earlier video on the raspberry pi pico i said i'd been unsuccessful with getting i squared c working this was because i was trying to use the raspberry pi as a primary controlling device communicating with the raspberry pi pico as a peripheral device well i've now got that working and i've done the same for the arduino in this video i'll go through both examples using python on the raspberry pi to communicate a c code on the pico and the arduino i won't be using micropython on the pico as far as i can tell that's not possible using the standard libraries this was far from easy so i'll explain some issues i had and cover some of the things i had used to debug both devices using this uart on the raspberry pi pico and the usb connection on the arduino the end result is a situation where the raspberry pi the arduino and the pico are all on the same i squared c bus the raspberry pi will take a value from the pico and then separately from the arduino i'll be implementing a variation of my voltmeter project for this but it's not intended as a real project but more as a way to show how i could incorporate i squared c in a project i'm also planning to use i squared c in another project very soon so this is going to be the theory so that the future video can concentrate on the more practical aspects so if you'd like to see my future video please subscribe to my channel and you'll get notified about those in future as i usually do i've split this video into chapters so if you want to jump ahead to a particular example then you can do so through the timeline or through the description i'm going to start by looking at i squared c and how it can be used for communicating between devices i squared c is an abbreviation of inter integrated circuit you'll also see it written and referred to as i2c this is particularly popular in code examples or online where creating the superscript for the two is not so convenient it was created by philips sodium conductor as a way to communicate between integrated circuits needing minimal connections it is a common protocol often used for connecting devices to a computer or a microcontroller i've already covered uart serial and spi in other videos so i'll start by comparing it with those it's not possible to fully compare with just a few bullet points but i'll cover a few of the important ones i'm going to be looking at a specific focus at the instance where we're creating a connection between a computer and a microcontroller the first obvious difference is that the uart is designed for only one pair of devices to communicate whereas both the i squared c and spi support multiple devices using a single bus this can be a limitation for uart if you want to connect to multiple devices next we can look at the number of wires needed these exclude the ground which is also needed for all the protocols both i squared c and uart use two wires although in the case of uart that is for only one pair of devices whereas the other protocols can be used for multiple devices for spi i've put four wires plus that's because whilst there are four wires going to each of the peripheral devices the controller needs an additional enable output pin for each additional device so the controller end needs to use more the i squared c protocol uses a unique address for each device this has some pros and cons in terms of address conflicts which will be explained later the uart is a point-to-point connection so that makes it simple in terms of which device to connect to spi uses an enable pin finally looking at the speed although i've intentionally left this to the bottom as in the projects where i use serial communications it's really a limited factor but it could be for other projects uart is the slowest typically up to 115 kilobits per second i squared c is typically around 400 kilobits per second whereas spi can be around 12 megabits per second note however that these values can vary a lot depending upon the particular device distance and cabling the one thing i haven't listed is distance between the devices this is because it can depend upon a number of different factors and for most intended purposes of around 10 meters or less then all three can be used for uart and spi then 10 meters or more is fairly typical whereas for i squared c the official guidance is about 2 meters however with i squared c it should be possible to achieve distance of 10 meters by running at a lower speed the final thing i'll mention at this point is that the choice between spi and i squared c may also depend upon what are the devices you want to connect to although many devices are available in both i squared c and spi variants if you're already using a particular device then you may want to use the same protocol to reduce the number of connections needed so which protocol is best well it really depends upon your needs you should look at the different pros and cons for each project that you do i'm going to use a specific example here but only so i can nominate a winner if i use a different project i may choose a different technology the projects i have in mind is a model railway project i'd like to have a single raspberry pi which can control various different peripherals with things such as house lights traffic lights etc the peripherals i'm wanting to control are going to use arduino-like circuits built around a custom pcb so the first elimination is clear there's only one uart on the raspberry pi gpio whereas i want to be able to control multiple peripherals the uart isn't really suitable so that goes in third both spi and i squared c are suitable contenders for the top spot my decision comes down to available pins as i'd like to be able to control as many devices as possible from a single ic in this case the atmega328p the 18 mega 328p has 14 digital pins i'll discount the serial uart pins as they're needed if i want to reprogram the chip although it is possible to use them as an output it's not so convenient so that's down to 12 pins using 4 for spi leaves only 8 digital pins i squared c uses only two ports compared to four for spi in addition so that doesn't use the digital ports instead using the analog inputs although they can be configured as digital outputs anyway based on using only two pins versus four pins makes i squared c the winner the fact is it's really too close to call you could just as easily use i squared c or spi but the crucial thing is that i've already created video on spi and not on i squared c so this gives me a reason to use i squared c the project is real though and i probably will use i squared c just because it uses less wires even though the result is close it's worth going through an evaluation exercise for each project rather than just going with what you've used before hopefully i'll be creating this project over the next few weeks as i've said the project i'm considering is based on the processor in the arduino the atmega328p there are only six analog in ports on the atmega328p as you can see in the top right of this diagram if you do need more than four analog inputs then spi may have been a better choice but in my experience it's not often that you use all those anyway before we move on i'd like to dispel a possible misunderstanding just because i2c uses the pins that are known as analog pins does not mean that i squared c is an analog signal it's a judicial signal driven using an open drain it's just that the internal i squared c circuitry is connected to the same pins that i used for two of the analog to digital converter inputs the motor of the pin can be changed through your code on the arduino i'm also wanting to use this with the raspberry pi pico and perhaps other microcontrollers so that i can use those peripherals without needing to create my own custom pcb board the same advantage of i squared c applies for any microcontroller as it uses less pins compared with spi here i'll show how devices are connected to the i squared c bus there are different terminologies that can be used i am going to be using controller to indicate which device is controlling the bus and peripheral to refer to the other devices you may also see other sites which refer to these as master and slave and you may see those used in the code as well in i squared c then you can have multiple controllers the same device can switch between being a controller and in peripheral mode to keep this simple i'm going to show you just one controller and two peripherals this will keep it fairly simple to follow and we'll cover what we need to know when implementing it if you want to understand how multiple controllers work then i suggest you read the ice word c specification first we need a data line which is known as sda for serial data this goes from sda on a controller to any of the peripherals the controller sends information to say when it's going to use this line or when each peripheral can use the line the second wire is known as scl which is the serial clock signal this is needed to ensure that all the devices clocks are in sync for sending and receiving information there also needs to be a pull up resistor for both the data and clock lines this is because the i squared c connections are open drain connections i've explained this in more details in my earlier video on mosfet logic level shift circuits this should normally be external connecting to the positive supply voltage some devices already have built-in pull-up resistors although that can introduce problems with multiple devices which i'll explain later to add a second peripheral then it just needs the additional device to be connected to the same bus to identify which peripheral the controller is communicating with then each device has a unique address this unique address is used even when there's only one peripheral connected but now it's important to ensure that you don't have two devices with the same address the controller does not need an address as that is the one directing the communications as i said you'll normally need to use pull up resistors which should be external some devices may include them which can sometimes work the internal pull-ups on a microcontroller are normally too weak to be reliable for i squared c typical values of pull ups are between about two kilo ohms and five kilo ohms for short connections then you can use a higher values perhaps using just the standard 10 kilo ohm on a level shifter but for longer distances then you may need to use lower values when you create a bus then you need one pair of resistors one for the data and one for the clock line if you have devices that run at different voltages such as a raspberry pi at 3.3 volts and an arduino at 5 volts but it's important that you connect these to the lower voltage connecting to a 5 volt supply could cause permanent damage to a 3.3 volt device in some circumstances you may need to use level shifters it may be a good idea anyway just in case a 5 volt device does include a pull-up resistor you don't need to add additional resistors when you add more devices as long as there is one pair of resistors an exception is if you do use a level shifter when you need to ensure there's a pull up for both sides of the level shifter the example i used in my earlier video includes a 10k ohm pull-up resistor anyway but you may want to add a smaller resistor watch out for devices which include pull-up resistors on the pcb first there is a risk that they may add 5 volts to a 3.3 volt device and these usually have high resistance pull up resistors you may still need to use a lower resistance if you need to use it on a longer run also if you have a lot of devices then you end up may end up with too lower value as effectively every pull-up is in parallel if you don't add your own external resistance then you can probably install about seven devices with their internal pull-ups before the resistance becomes a problem the address for i squared c is normally 7 bits long the standard does allow for 10 bits but that is rare so using the 7 bits would allow for digits 0 to 128 but some are reserved the address is normally in hex so that's what i'll be using and the valid range is from 8 to hex 77. there are different ways that the address can be defined so i'm going to list these in order of the most flexible addresses can be defined in software this is normally the best as it means that you can potentially set any address this is what we'll be doing on the arduino and pico the only negative thing is that the way i implement it means that you'll have to recompile the code to change the address although it does mean that you don't have to lose any of the pins of the processor to code the address with some devices may allow you to change the address using a dip switch or a jumper usually these will have a reduced range of addresses that can be used but by selecting appropriate values you can get multiple devices to work correctly next is that some pcbs have small pads that can be soldered to or where tracks can be cut with a knife these offer a small amount of flexibility it's okay when you only intend to use the pcb in a single setup or isn't so convenient if you need to change the address finally some other devices have a fixed address which cannot be changed this means you cannot use more than one of those devices with that address on the bus there are some ways around it some have an enable pin which could be polled or you could get an i squared c multiplexer but really these shouldn't exist as all because you should always be able to change the address of a device somehow that's the theory out of the way let's look at some practical examples the first example i'll use is the raspberry pi pico i was hoping to use this in my earlier video using micropython but unfortunately mica python does not currently support the pico as a peripheral device whilst it would be possible to use this to communicate with a raspberry pi computer using the picot as the controller the raspberry pi is a peripheral that would mean i could only ever use one picot unless i was using multiple controllers so in this video i'll be using c on the picot i'll still be using python on the raspberry pi as that allows me to create a simple gui using pygame zero although this introduces a bit of a problem with incompatible implementations the python library i used is known as the sm bus which implements system management bus this is based upon i squared c but uses a different messaging they do work together but i wasn't able to send multiple data blocks and i did implement a little trick to be able to send data 16 bits at a time the physical wiring is straightforward the picot is a 3.3 volt device so it's easy to physically interface with the raspberry pi computer i used i2c 1 on the raspberry pi which is the i squared c that is user accessible on the gpio this is on gpio 2 and 3 which are physical pins 3 and 5. on the pico there's a choice of two i squared c devices between them they can be mapped to virtually any pair of gpio ports i used i2c1 which is assigned to gp2 and gp3 on the physical pins this is four and five they also need to have their grounds connected together i included physical 4.7 kilo ohm pull up resistors to the 3.3 volt output on the pico you could do this on either the pico or the raspberry pi but ensure that you use an output that is labeled as 3.3 volts out do not connect to any of the pins which are at 5 volts either on the raspberry pi or the v6 or vbus on the pico doing so could damage the pico and the raspberry pi for debugging purposes i also connected the uarts for the raspberry pi and the pico there are also debugging pins that could be used on the picot but i've already implemented the uart code and so i was able to reuse this this is explained in my earlier video on the voltmeter project which i'll link to in the description let's take a look at the code there's quite a bit of code which is for the uart debug and the analog to digital converter which i've already covered in the previous video so i'll be skipping over those quite quickly and if you want to get the full details then if you take a look at that previous video you'll be able to see that there i'm going to mainly concentrate on the i squared c part of the code and starting with this so this is the hardware i2c.h file so that's the library file that includes the i squared c code and remember that needs to go into the cmaglist.txt file as well this is for the the uart for the debugging so the next thing is the address so this is the peripheral address for this picot and i've put 0x3 e and then the analog to digital converter the one change i've made here is to turn this into millivolts previously this was in volts 3.3 volts as you as you can see there and by multiplying it by a thousand we'll get that in millivolts and then we can use it as an integer value which is easy to send whereas before i was sending that as a string so set up the analog to digital converter i'm going to use the one pin this time which is pin 26 and lock zero set up the uart for the debugging at the one bit i've dropped from this is that i've taken out all the code that's for the interrupt handling that was on before because we're only going one way we're only going from the pico to the raspberry pi we don't need to be able to handle any traffic in the other direction so this is really the section we're interested in this is the i squared c setup we're initializing using uh i2c one so that's the the number one of the modules setting it and and it refers to here as slave mode that's the same as peripheral mode it's a it's a different terminology uh i prefer to refer to these as peripherals but they've used that and this is where the address is defined then these are the functions the the set function is used to determine what pin these have been put on so this is saying that gpio pin 2 will be used for the i squared c and then it's got two pull-ups so these are the pull-up resistors i've actually used external pull-ups on this so these aren't required and these are quite high value pull-up resistors inside the integrated circuit anyway so may work for a short distance and if you've got them quite close together but really you're better off with the external ones anyway a bit of a debug message on the uart set up some variables and then all the handling really is in this while loop we use itc get read available to see is there anything ready to be read and if so then it will read it reads three bytes now the code you're going to see in a minute on the python on the raspberry pi um uses a slightly different protocol it uses sm bus and that sends the data three bytes i'll i'll go into more detail in there but basically what i'm doing i'm taking the first byte which is received as the lower eight bits of an integer number the second byte as the higher eight bits and then the third byte is just zero so we'll ignore that and i've just got a debug message there that i've actually removed so i was showing the individual bytes but this is the uh the debug message um how how we add the two together so the first byte is there and the second byte is shifted by eight bits that's that one about on the up so that's how the receive part works and that's purely here just so that you can see how you can send data to the pico and then this is the bit which is going to read the analog to digital converter and send that data on the i squared c to the raspberry pi so it just uses standard unlock to digital read multiplies by conversion factor so now we've got an integer value notice it's effectively this is like using the floor command it's round down just dropping anything below at the fraction part but as that's fractions of millivolts that's really irrelevant we don't need that level of detail here anyway so that's fine splitting it into two bytes here using a bit mask so just to get the the bottom eight bits and then shifting to the right to get the top eight bits as a single byte puts that on the up just so that we can see what's being sent and then it uses the i2c right raw blocking sends that as the data here sends us two bytes now just go on on both these it's there's different functions available for the ic i2c code in this case i'm using the raw and you see that the word raw and that means it's been used as the peripheral device and it's not looking for an address um it's just whatever comes into it in the case the read and when you're writing out it's just writing it out to the bus it's not addressing it to a as to another peripheral device that's the code for the pico site so that's compiled and then pushed out to the pico so now i'm going to look at the python code which runs on the raspberry pi so the reason i was using the code before in my previous version is because i wanted to be able to use a graphical user interface with this i'm not implementing that here but that's the same theory is that i can then use that and also i think python is quite easy to understand and quite easy to write so it's quite easy to get into one of the issues here is that the i squared c implementation of python is through the module sm bus sm bus is system management bus and it's actually a variant of i2c so it uses the same physical layer protocols as sm bus solder there's some little differences in in the voltage and things like that essentially it's it's it's a variant of i2c and that means it behaves a little bit differently so we have to use certain functions to be able to get these to talk um so i i'm really i did a lot of playing around really rather than it being um systematic you couldn't really tell which which functions were going to work i just plugged them in and used the debug until i got something working so i'll just explain how these work then so the address here is the address of the peripheral the the raspberry pi here is the controller so it doesn't have an address it just sends out the commands to the the peripherals it creates the bus and then everything else is in this loop i is going to be the value i'm going to send to the pico that was the value we just received and then squirted out to the uart doesn't matter what this value is i made it a thousand because i wanted it to use the full range of the integer if it was less than 256 then you wouldn't get to test the higher bits so that's why i started at a thousand and debugging to let you know what's happening and then it does a write to the i2c block data now this is um this function uses um uses the address to send it to then it uses a command and then a list for the data and when you're just using this on python and talking to another smbus device you can set this command and then you can put multiple bytes of data in this list however when i tried that i wasn't able to get to do it what happens though is that the pico can receive both these bytes if i just put one byte in this list then and use that byte as well and effectively would receive two bytes per thing it doesn't matter whether that's an address or a value so what it's doing is sending the lower part by masking it with ff just to get the lower eight bits and the higher part by shifting it eight bits and you notice the square brackets is to create this as a list of one object because if you don't do that then it doesn't work and also i wasn't able to get it to send multiple blocks of data it would just fail to send it but using it that way it works you can send one 16-bit value at a time which is an integer then read inside similar sort of thing we're using this read i2c block data and in this case we're telling it how many bytes to receive and it's going to read two bytes and again that can be used as an address as a command when using um other sm bus devices but in our case it just means we're going to get try and read two bytes and it stores them in rx bytes and i'm just turning those back into a 16 bit value by adding the byte zero as the lower eight bits and then byte one shifting it eight bits to get the higher value add them together and then that's our value so that's the python code and now we can just give a quick demonstration of this working so said i've set up uart debugging so i can use it minicom on here i'll use the options minus b for baud rate 115 200. and it's how to force it and the device that we've got it connected to is the serial port zero on the raspberry pi so again i've explained that in in my previous video if you want to see about that in more detail we're now connected to the pico for debugging but that's not i square c that's just the up and this is the one that is going to run the i squared c and talk to the vco and as you can see it's sending the data so this is the value being written writing data 1009 1010 and here it is on the pico that that value there and then transmitting wise it's sending this value which is 1835 44 ish which is millivolts so that's 1.8 volts and it's showing you how it's split into the two bytes that it's sending there and we can make sure that that corresponds with here and as you can see these are the two bytes being received and that's the value 1842 millivolts and i can actually adjust that i've got a variable resistor on and if i just turn this slightly then you'll see that value go up there we go so we're into the 2 volts region here so we're talking about 2157s around that so it's fluctuating because this is this is millivolts there's a slight change essentially so what we've got here is we've got this python program writing data to the pico that you can see here and then again this is the raspberry pi so this is asking to read the value from the picot and the pico is responding with this value here which is the voltage and we can see that that's been received successfully here i won't be creating a project for the arduino example instead i'm just going to be creating a simple demonstration to show how it works as with the pico i'll be using c on the arduino this time using the wire library for the arduino this will work using event handlers rather than having a loop to keep checking for requests it's a different method which has its own pros and cons something to be careful about is the voltage difference between the raspberry pi and the arduino some models of the arduino such as the uno and leonardo work at 5 volts whereas the maker series are 3.3 volts the raspberry pi uses 3.3 volts if you connect 5 volts to the raspberry pi then that could damage it it's possible to position the pull-up resistors on the 3.3 volt side and then that should work for both devices however the concern is that if the pin used on the arduino was activated as a normal output or pull-up resistors were enabled then that could damage the raspberry pi i therefore recommend using a logic level converter such as this one from adafruit i've already created a video explaining how they work this will need pull-up resistors for both sides of the level shifter here's the wiring details the raspberry pi side is the same as before the arduino uses analog port a4 for the serial data connection and i'm log port a5 for the clock the arduino can easily use the usb connection for debugging so there's no additional connections needed for that so now i'm going to show the code for the arduino which is written in c i'm not going to be using this like as a practical example in the same way as the other one could be used as a voltmeter and it's sending a value this is purely as a demonstration so i'm just going to be sending static value um from the arduino to the uh console so that we can debug this and and see it working for the arduino then we're going to be using event handlers instead of the the loop code and this has got some pros and cons and it's going to actually in in some ways make this a a little bit easier and we'll see how this works the arduino is set up to use the usb connection for debugging so we're going to use that instead of having set up all the uart separately uh they'll just go over the the uart which is built in to the arduino and communicates with the usb could use minicom but i'll be using a console here which is part of the ide for the arduino ide so i'll just go through the code so the library that's used here is wire.h which is a library for i squared c for the arduino uh you'll see that i've defined the address as being different from the other one so the other one was zero x three e this one's zero x three f and then one one number up but that will mean that these are unique um if i go on to put them onto the same bus later i've just set a value here to send and it's just uh one two three four i've just set that as now there's one of the things the ways that this works it's only going to be able to send the data one byte at a time i'm wanting to send a 16-bit integer number as i did before so i'm going to have to split that into a lower byte and an upper byte and i need to keep track of whether i've sent the low byte or not so that's what this variable is going to do the setup is basically three lines so saying join the i2c bus using that address and then here's the interrupt handlers when you get a request then call the request when you get a received data as in data is pushed to you then use the receive event function this is the debugging code see it's quite straightforward it's just just one basically said just set up a serial connection and then it's sending um a single string to say that the device is starting and then we'll we'll be able to just use this using the serial.println later on there's a loop here which is just doing nothing effectively it's a delay but this would allow you to put your own code in here which could be running separately to the events so that's as the events are called then it will handle the event and then just carry on running this loop and then everything else is inside these event handlers effectively so if we receive an event and this is that some data has been sent from the computer the controller to this uh arduino is a peripheral device it will tell you the bytes received if it's less than two then ignore that um we've if you get for instance wants to just send zero bytes they are used as part of the i2c detect to detect devices on the bus so it means we don't need to return anything it's only when we get the two bytes requested which is what we know we need to send so the that's sorry when the it's only when we get the two bytes being received which is what we're expecting to receive uh just set up somewhere to store that and then as long as there's data available store that inside this uh array here using the y dot read and then as we did before we're taking the first byte as our lower eight bits and the second byte by one as the upper eight bits and just shifting that along adding them together printing it out onto the serial view art and we'll be able to see that on here the request event is would actually be really straightforward except for this aspect of it being only requesting one bite at a time so when it's asked send a bite if it's the first time it asks the lower center is set to false and it sends the lower byte of the integer value just by landing it with the the bit mask for the lower bytes lower bits and if that's already been sent and it's called again then it knows it needs to send the operate bits that's done by shifting the value and then whatever it is it sends that down the wire and that's it so it's actually quite a bit simpler i think in some ways for the the arduino um a bit less setting up things like that and we can see that in action so now look at the python code that we're going to use to test this and you'll see in many ways it's it's similar to the one we did before we're still using that same right i2c block and and all this is is pretty much the same where we are different is the reading data this is the command that we used before and i couldn't get that to work with the arduino so what works with the arduino doesn't work with the the pico and vice versa instead we use the bus read byte and this is just a a more basic just read one byte of data and and save it here and likewise we call it twice the first one is the lower byte and the second one is the is the upper eight bits and we could just print that as a value and so let's we put it so that you can see python code on the right and the console on the left and we can run that and hopefully yeah so it's writing data is incrementing one thousand one thousand one one thousand two you can see that one thousand ten thousand ten and remember we sent this it's always sending the same value one two three four so i've not got it showing on here but we always know this value is one two three four if you change that in the code it will work but for this just get this nice and simple and that just demonstrates how we can talk to the arduino using the i squared c bus so now i've connected both the arduino and the picot to the same bus remember they've got their separate addresses the pico's on 0x3e and the arduino is on 0x3f and that's how we're going to differentiate between the two and basically what i've done is copy and pasted both sets of code into the same program i'm going to run the picot first then the arduino and the only thing i've really changed is the address instead of referring to p address for the picot and a address for the arduino there's obviously much better ways of writing this and keeping the code clean but just for this demonstration literally all i've done is copied the two into the one program and just to illustrate how multiple devices can sit on the same bus and i'm going to run this on the command line just because it's there's big chunks between the lines it's easy to see this way and it's just let's see test times two and when we see this we're going to see it running one pause for a second running the other so it's only pausing for a second so it's just going to jump quite quickly and writing data we don't have the console to see that's definitely been received but we know it is because we've already seen that code work and we've not done anything to the peak or arduino now since the previous example and we can see that we're always getting one two three four back from the arduino and we're getting the value of the analog to digital back from the pico and there we are multiple devices talking on the same bus so using those same two pins sda and sclk the data in the clock and talking to multiple devices and we can add lots and lots more devices here it's it's not limited to two we have multiple picots multiple arduinos and we can have other devices as well in this video i've shown how you can connect multiple devices using the i squared c bus this has been tested with the raspberry pi running python and a picot and an arduino both running c code you can also add many other devices to the i squared c bus in the past i've used it to send data to displays for an lcd display and other peripherals unfortunately it does not look like micropython on the pico currently supports this mode although perhaps that may be added in the future the one downside so far is that i had to use different commands to collect data from the pico as i did from the arduino this was through trial and error that i managed to get this working if you know of a better way then please let me know in the comments and i may be able to use that in a future project i hope you've found this useful i'm looking at creating a new project using this in future so please subscribe to my channel if you haven't already so you can see that when it's available thanks for watching and i hope to see you again in a future video
Info
Channel: Penguin Tutor
Views: 5,413
Rating: undefined out of 5
Keywords: Raspberry pi, Arduino, spi, serial, communications, networking, primary, secondary, main, master, slave, SS, cs, chip, select, raspberry, pi, rpi, atmega328, atmega328p, atmel, microcontroller, microprocessor, freeduino, python, cpp, c++, linux, data, transfer, asynchronous, synchronous, duplex, half-duplex, full-duplex, digital, pin, analog, digitalread, digitalwrite, analogread, computers, computing, somputer, science, stem, electronics, level-shifter, logic, level, convertor, led, pico, i2c, wire.h, smbus, hardware, i2c.h, system, management, bus
Id: Wh-SjhngILU
Channel Id: undefined
Length: 46min 6sec (2766 seconds)
Published: Mon Feb 15 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.