Raspberry Pi Pico W LESSON 76: MicroPython Program to Use an Infrared IR Remote in Projects

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hello guys this is Paul mcarter with toptechboy dcom and we're here today with episode number 76 in our incredible new tutorial Series where you are unleashing the power of your Raspberry Pi picw what I will need you to do is pour yourself a nice tall glass of ice cold coffee that would be straight up black coffee poured over ice no sugar no sweeteners none needed and as you're pouring your coffee as always I want to give a shout out to our friends over at sunfounder sunfounder is actually sponsoring this most excellent series of video lessons and in this class we will be using the Kepler kit for Raspberry Pi Pico W now most of you guys probably already have your gear but if you don't look down in the description there is a link over to Amazon and you can hop on over there and pick your kit up and believe me your life and my life are going to be a whole lot simpler if we are working on identical Hardware but enough of the Shameless self-promotion let's jump in and talk about what I am going to teach you today and what I'm going to do is I'm going to show you my solution to the homework assignment that I gave you in lesson number 75 but I'm must start by asking were you successful if you were successful leave a comment down below I Am Legend double chest bump and if you were not successful leave a comment down below I fold it up like a cheap Walmart lawn chair okay now hopefully most of you guys were successful but I will admit that this required some real thinking about how to make this thing work now what was the homework assignment you were to use the IR remote and connect the IR receiver to your Raspberry Pi Pico W and then create a useful command stre stream and what I said was you would start the command by hitting the power button you would then enter a series of key strokes and then you would press the EQ button and that would then create an array of that useful set of key strokes that you had created and then once you have that useful set of keystrokes you could go out and do something useful with them but it was to just create that array that recorded the keystrokes now last week I showed you how to just read a digit from the remote and so we loaded the libraries and we learned how to create that callback function we learned how to do all of that where you could read individual uh button pushes from the remote but the problem is down in your main program you could be doing whatever and you can't just have random keystrokes coming in you have to compile those keystrokes into a useful array okay now I say that you've very much have to go back and watch lesson number 75 because I showed you how to install the libraries and I showed you how to get an individual button push from the remote so you need to go back and watch that but let me just show you very briefly how we have this thing hooked up I will get out of your way I will have a little bit of my go juice and I need you to just pretend that this happy little blue Servo isn't here because in today's lesson we're just going to be using the infrared receiver and the infrared remote now I showed you last week how to hook this up and what we saw is we saw that that when the little half LED is pointing towards you the left pin the left pin is the control pin and we have that hooked up to GPO pin 17 can't remember last week if I used GPI pin 17 or not but this week the control signal is hooked to GPI pin 17 okay then the center the center pin on the uh led the the IR receiver is connected to the brown the ground Rail and then the positive the the the rightmost the rightmost leg of the receiver is connected to the power and the power comes over and it goes to 3.3 volts which is physical pin 38 so you've got physical pin 38 is that right we've got ground is 38 I'm sorry ground is pin 38 and then we have physical pin 36 coming down and creating our power rail So Physical pin 36 creates our power Rail and uh ground creates ground and we are connected to GPI pin 17 hopefully I didn't confuse you I might have said it wrong one time but I think you can see how we have it hooked up and now what was the assignment the assignment was to do something like this I think you can see this where we learned last week that we can individually see that a button has been pushed but we want to compile button pushes into a useful command and so I I press power let's see I wonder if I can back this off okay so I'm going to press power okay and then that tells I guess I should I guess I should run the program first so this is what the assignment was you were to get something like this so I create I press power and that lets the system know I'm going to enter my command and then I'm going to type a four and a five and then the EQ and then boom what do I get power meaning that I'm starting my command I'm getting an array that has power meaning the command was started I entered a four I entered a five and then I pressed EQ EQ and then that was the enter so I could do start I could do start with the power button and then I could press minus + 1 2 3 and then enter and then look I get power and then I see that minus was pressed plus was pressed 1 2 3 and then I ended the command with the enter now if I just come in and start pressing keys nothing is going to happen why because I didn't uh because I didn't actually go in I now this just tacked it onto the n one because I didn't press the power but if I just come in and press keys nothing happens nothing happens until I press power and then one 2 3 and then equal to enter and I've got power 1 2 3 so the sequence is power to start recording the keystrokes and then the EQ to go in and finish it up okay so if you guys were successful you did pretty good because this wasn't a really very easy thing to do it required a lot of thought but I had taught you all the things that you needed in order to write this program so let's come over here and let's jump in and start let's start doing our coding okay and so the first thing that we are going to want to do is we're going to want to import time okay and then from machine import mimport pin uh and do I need frequency I don't think I need frequency no I don't need that there so I'm just going to import pin there like that and then I'm going to import those libraries that installed last week so what do I need to do from _ rx. printor error so this will give us error messages if we need it from that I'm going to import print uncore error like that that looks good now from iore RX do NEC NEC I'm going to import n ecore 8 and I explained all that last week okay now let's just run it to make sure that we can import those libraries okay what Ned 8 H good thing I checked it that is NE C8 I said c and I type D so that all looks good now I need to create a dictionary that will look at the strange but yet unique integer that is associated with each button pushed and assign that to a more meaningful uh identifier now it could be a number an integer for the 0 through n and then it could be a command or a string associated with the other ones so what does that sound like we need it sounds like we need a dictionary to keep track of that data so IR dictionary is equal to now I went through with the program from last week and just put pressed each button to see what the unique integer was that was coming off of each of those buttons and what I learned was I learned that 69 was returned when I pressed the power button so if I press the power button it Returns the number 69 so I want to map 69 to what power and I will just make that a string okay then I found that the next button over returned a 70 and that was the back button okay and so this well that no no 70 was down here these aren't in any particular order okay so I just assigned the uh the number that I got from the button to a meaningful to a meaningful uh thing so 70 was the next one over over and that was mode okay I just mistyped so if you press the mode button it gives you a 70 so if I see a 70 I know what button was pushed the mode button okay then pin 71 or I found that pin off returned to 71 so this button here if you press that it Returns the integer 71 like that okay and then I put a comma now if I hit an enter uh let's see so that's that comma that okay and then a comma I don't know why that came all the way over I probably ah there's an error here let's just use all single quotes I'm getting sloppy and switching back and forth so that and let's just use all single quotes to make a string you can do it either way but you know like this okay there it comes over and remember this is all one long line and so you really don't have to worry about indent here I'm just breaking one long line up into multiple lines in th just to make it easier now what I found is a 68 was returned if I pressed the play button so I want to map play which is this one to 68 because when I pressed this button I saw that it it was returning a 68 okay then uh what I found is that if I press the back button I got a 64 so 64 needs to be mapped to back so if I see a 64 I look it up in the dictionary and I know that the button that was pressed was the back button like that okay and this is a little bit tedious I will admit okay then I found that if I got a 67 that that was from a 67 came from if I pressed forward so if I press forward it will return a 67 so 67 needs to map to forward like that close it and then a comma let's see you can still you can still read that and so then what I will do over here is I found that if I did the I'm going to go to the next line okay just so to make sure that you can see it I found that if I press the enter key this EQ this EQ which I'm calling the enter key it returned a seven and so seven corresponds to enter like that okay and then after enter the next one over is minus I found that minus corresponded to 21 so 21 was returned if I typed in the minus so if I see a 21 return I'm going to map it to minus like that okay so let's come on over all right I think I am going to go ahead and hit a new line okay so I've gotten all the way through minus okay now I should probably do plus and I found that it returned a nine an integer nine if the plus button was pressed like that comma this is tedious isn't it then I found what's next if I press zero I got a zero back no if I press zero I got a 22 back so 22 if I see a 22 I know that that corresponds to a Zer now I'm going to map that to the integer zero because if I'm pressing numbers I might as well get a number okay so I've got 22 okay and uh then what I found is that if I pressed a next one over a a zero returned zero press returns a 22 then this Loop this Loop button it returned a 25 so if I see a 25 what do I need to do I need to uh make that Loop the string okay we're going to keep going I found that if I press the USD button I got a 13 back so I'm going to say 13 if I see a 13 I want to map that to USD okay and then going to go to the next line now I found if I pressed one I would get 12 back so if I see a 12 I know that that corresponds to a one and then if I pressed a two I would get a 24 back so that needs to map to the number two and then uh I found that if I press three I got 94 so 94 needs to map to a three like that okay and now I found if I pressed the next one over which was uh that was nine right I did no I did three the next one be would be four and if I press four that returned an eight so if I see an eight that should really be a four now can you imagine doing this without a dictionary this is showing you the power of the dictionary and that is why I taught you how to do dictionaries I find that if I press a five it will return 28 so 28 should map to to five like that 28 should map to five and then I put a comma in and then if I press six if I press six I got a 90 back so if I see a 90 that really means a what a six okay a comma and then what I found is I'll just do 66 was returned if I press seven okay an 82 was returned if I pressed eight and a 74 was returned if I pressed a n and so if I see a 9 if I see a 74 it really means a nine now how many mistakes did I make in here I better just run this okay line eight is a mistak so I have nine is a plus 22 is a zero n uh 25 is a loop 13 is a USD I am not seeing my error there maybe I need to do it like that okay line eight ah I didn't put a comma after 21 maps to minus comma like that so let's try that okay so at least it took the values so I have the dictionary now okay I wonder if I could print it out down here IR dictionary uh yeah it still knows it so what if I have what would I dictionary of I let's see that I see a nine okay I am reading a nine and that would I'm reading a nine and that would correspond to a plus okay so if I see a nine that means I hit the plus so the dictionary looks good now I might have put a wrong value in here so we'll have to verify that that dictionary really Maps this but this is really the heart of the program and that is the part that is going to be the most tedious now we can jump in what do I want to do I want to build a command and it will have power comma and then the keystrokes and then comma and enter so I need to have an array to keep those values in but initially it is empty so I'm going to call it the new command array and it is empty okay now I need to figure out do I need to start recording key strokes well I record keyst Strokes if I see the power button but I am going to need to have a variable begin record Well appear haven't seen the power button yet so I'm just going to initialize that to false and then also once I hit the power then it's going to it's going to make uh it's going to make be begin record true and then similarly once I hit hit e uh the EQ or the enter button Buton then that is going to mean that I complete that array so I need a variable to say that I need to start recording and I need a variable to say that the command is finished so CMD ready certainly we don't have a command yet and so this is false now I'm just setting these up because I know I'm going to need them later and I've got to initialize the variables as I use them it will make more sense okay now where is our our IR our IR pin was equal to pin of ir pin no IR pin is 17 I got a set up IR pin so IR pin we said was connected to gpio pin 17 and now I need to create an object for that pen so my I my IR is going to be equal to the method pin of what the IR pin and then that is a pin. in like that all this this stuff the IR pin and my myir I explained last week so we've got that set up now what do we have to do we have to set that call back function that callback function so when a button is pressed the library will call callback okay now I'll go ahead before I Define my callback function I'll go ahead and remind you that we create our IR object is equal to neore 8 the method okay and then my IR the IR pen so I've got to tell the library my IR pen I've got to pass that to it not pen 17 not IR pen but my IR which is the object associated with that pen that we created and then I've got to tell it when I see a button pressed which of my functions should the library call to pass it what the button press was and we're going to call that call back so I load the libraries when a button is pressed their Library calls what my callback function now I've got to what I've got to come up and I have to Define that callback function so Define call back and so their Library calls call back I never call call back their Library calls call back and what does it do well it's going to return a number and it's going to return one of these doofus numbers like 68 and 69 or 22 and then I'm going to have to map that to a meaningful designator okay so I'm going to call this R IR bit because it returns just one number the number associated with the button so it just gives me one at a time no organization press a button it calls call back and it sends call back the number of the pin that was pressed now you have to put in addr and you have to put in CTR L and we don't know what those do they don't do anything but they've got to be there okay now this function has to interact with the main program so I have to say that Global is new command and so if this callback function changes new command everywhere in the program knows what the the new command is and similarly Go Global begin record and then Global and CMD ready okay and then global IR dictionary okay I don't think I'm really going to need that I don't think that needs to be Global because that's only going to be used here inside the function like that so I think it's these three that have to be Global so what does new command mean it means that I have a new command that I'm building that is the command itself which would be the array the array that I set here and that would be like power comma one comma 2 comma 3 and then enter so that will be the array so what am I doing inside of Define callback I am or what am I doing inside of the Callback function I am going to build this new command and other people are going to need that new command so I make it Global and then begin record is when I start it and then command ready I don't even think I need begin record I need it but I don't I don't yeah I need to make it Global and that way it will know that begin record starts as a false okay so yeah it does need to be Global okay so now I've got those three things defined as Global all right and I have to Define call back before I have it show up here so I have to define the call back function and then when I create my IR object and it sees call back it knows what call back is okay now what is the power key so I want to kind of it's going to be sending if I just start typing things here it's going to be receiving inside of callback it's going to be receiving those uh IR bits one at a time but basically I want to ignore them unless I I have seen the power the start the start record the power key I want to ignore those bits unless I have seen that and the power key is the number 69 and so what I can do here is I can say if ibit equal equal 69 that tells it that the power button has been pressed well what do I want to do there I want to say it's time to begin recording so begin record is equal to True why it's all the power button so I need to start recording okay and then what I need to do is I need to reset new command equal to the empty why do I do that because I might have defined new command last time through and then the next time through I've got to reset it to nothing so I start with it nothing and then once I get in here I want to make sure that it's nothing I'm wondering you might be able to just do it in in just here but you have to at least do it here so the second time you send a command it doesn't just tack it onto the old command and now is my command ready see MD ready no it's not ready why I'm just starting to record it so so I've got to make sure that it says you don't have a command yet so I set it to false because I'm just starting to record it now how do we build the command well if begin record is true okay so it saw the power button it saw 69 so it set things up and it says you're ready to record begin record is going to be true because it saw the power button 69 it clears out the new command and it says no the new command is not ready yet so now if begin record equal equal true and I bit is not equal to minus one well what was that last week we saw that if I sat and just held the button down it would give me the number associated with that button and then it would just give minus one -1- one minus one unless you took your finger off real quick so if I press it and I hold it too long what do I want to do I want to ignore those minus one so only if begin record is true and I haven't gotten a rep repeated button push by holding it down too long I want to ignore those but what do I want to do I want to build my new command and how do I add that new value I append and what do I append well I could append IR bit but if I appended IR bit what would I be getting I would be getting 69 68 922 I would be getting the confusing numbers what do I want I want the intuitive number so like I don't want it to return or put in that command 68 I want to put in put in that command that new command play so how would I do that well here I would not do IR bit I would do IR dictionary of ibit like that so now as I'm building the new command it is going to look something I don't have it there but it's going to look something like open the list and and then power because that starts it and then comma things like 1 2 3 4 or mode or play or rewind so I'm getting the intuitive values that are put in the new command okay now we we've got this we've got it started and we're tacking those things on now we have to see if we should end if I bit is equal equal to what the enter or the EQ well what is the enter or the EQ it is seven so I come down here and I can say seven okay or what I could also say is if I no I if IR bit is equal equal 7 because I'm just working with that last keystroke just the raw number coming off if that IR bit that's the raw number if that raw number is seven what do I want to do I now have a command that's ready to use so command ready is going to be equal to True okay so when it sees the Power when it sees 69 the power it does what it says it's time to record you're going to clear out the old command and you're going to say command ready is false because you're just starting to record it all right now if begin record is true which it will be true if you hit the power button and if it's not a repeated Key by holding that key down too long then what do you do you build the command okay now if you see the seven that means you saw the equal now you want to stop the command and you say command ready is true okay you say command ready is true that tells the rest of the program that you you have a what that you have a command now I'm going to get rid of these blank spaces here does that make sense if it doesn't make sense stop and watch that part again okay now what I'm going to do is I'm going to come down here and I want to do it cleanly so I can exit cleanly so I'm going to do a try and then what am I going to do and uh what am I going to do and try that is a big ugly mess isn't it I think I messed up twice okay then I'll say while true okay and then I'm just going to pass because I want to finish the rest of this program I'm going to say ex accept keyboard interrupt okay so if I'd get a control C I want to close my IR what is IR that is that infrared object I created where did I create it create it here I'm going to close it out now so next time I run the program there isn't anything lingering going on and then print program terminated okay now I haven't really done anything yet but I just want to see if the program works yeah so the program works and then if I press keys nothing particular happens okay and so there's nothing particular happening is I'm pressing keys because those key strokes are going in there but I'm not doing anything with them yet here so let's just come in and let's just make sure this is working so what I'm going to do is I'm going to print an IR bit just to make sure that this callback is working so if I do that and I come up here and I press one I get a 12 in the minus one you see if I press the two I get a 24 and a bunch of minus ones and so this is just simply printing the wrong uh the the raw bit now you can see I've got to ignore those those negative ones so if I press a zero I get a 22 I want to ignore the minus one and I don't want to put 22 in my new command I want to put what in my new command I want to put a zero because zero goes with 22 and that's why I did it like this new command. append IR dictionary of ir bit and then that will give me the good things that I want so new command is global why because when I get down here it will know what new command is and then command ready I don't want to try to get the command before it's ready so I need command ready and I I need command ready and I need new command to be Global and then I really don't think I'm going to live dangerously I don't think I need begin record AS Global okay so let's see here let's just run it I'm just trying to see if this thing runs okay so I'm putting ah maybe I did need that I think I did need that let's think about that so what did I take out I took out begin record uh yeah so it has to have a value it has to have a value value because I say if begin record and it doesn't have a value yet so I need to make it Global so it gets it uh it gets it okay so it gets it from up here so it knows what it is it crashed because it didn't have a value okay now let's try it okay and if I punch a ah okay I misspelled it record okay so now I press a bunch of buttons and it's just showing me the individual buttons that I'm pressing okay now let's just see just for fun let's come down here and let's print just to make sure that we're getting it because I want to make sure this call back Works before I go down and develop the uh the uh main program so now I'm going to print new command okay and so now I'm going to run it okay and then if I press one I just get it's m you know I I get the 12 that's associated with the one okay one corresponds to 12 so the raw bit if I press one it's a 12 but you see how it's not going in new command new command is remaining empty even though I'm reporting what the individual button push are so now I'm going to press the power button and boom it has power okay in the array now if I press one it adds one to it two it adds two to it and three it adds three to it but what do you see that's kind of cool it's building it but down here it would not use it because I'm only going to use it if command ready is true and command ready is not true because I haven't pressed that equal button yet does that make sense and so let's let's try it this way what if I say only print if command red D is equal equal true only if it's true will I print it and then I need to tab this over so then I come here okay now I'm going to go one 2 3 I get those raw numbers but they are not going in now I'm going to to press power and it got the 69 1 2 3 why is it not printing new command because command ready isn't ready yet it's not true yet because I haven't pressed EQ which is seven so I press EQ and boom I got it saw the power which means it's going to start recording it recorded the one the two the three and then it got the inner and so now now what command ready is true well it is command ready is true up here but it is also true down here so what do I want to do down here now I want to start working on that program so while true now I want to say if command ready meaning that I now have a complete Command if that's equal to true what do I want to do I want to print new command and then what I think I should do is I should also say command ready because I've read it now I have it command ready is equal to false okay meaning you sent me a new command I got the new command now I'm going to clear it out okay let's see if I really need to do that so now let's see line 38 what did I do red command ready why did I get a error there oh no no colon this is not Arduino okay so now I'm going to do power I'm going to do one 2 3 and now I'm going to do enter and I've got power 1 two 3 enter now that negative one don't worry about it because that came from up here so now that we see it's working let's take that out and now let's run it so I'm going to hit power and then 1 2 3 and then EQ for enter and then what do I get power one two 3 enter so now in the main program I've got a complete I've got a complete I've got a complete Command that's ready to use now I don't know if I really need to set it false there because that might have been taken care of so let's run it and I say power and 1 2 3 and then equal and I get power 1 2 3 now what's the problem now it's just looping and printing and looping and printing and so I do need that there just so that once I get that it stops it so I've got to stop it here as well so CMD ready is equal to false like that okay now what I do is I come here I run it and now let's look at all the values I'm going to say start Rec recording I'm going to do mode I'm going to do off I'm going to do play I'm going to do rewind I'm going to do forward I'm going to skip EQ because I don't want that to end my command I'm going to do minus plus zero Loop USD 1 2 3 4 5 6 7 8 9 and now I'm going to I'm going to enter it there let's see there okay maybe I didn't stop it last time let me control C I'm going to have to crash this thing okay there it is let me try it again I think I didn't rerun the program it doesn't like line 37 command ready is equal to false man why do I keep putting that colon there isn't that twice I've done that other than that I feel like this has been an excellent lesson what do you think think okay so I'm going to press power and then mode and then stop and then play and then rewind and then forward and then I'm SK skipping equal minus plus and then 0er Loop USD 1 2 3 4 5 6 7 8 9 and now what am I going to do I'm going to press equal and then boom look at that I got let's check and make sure I've got power mode off and then I've got play back forward I skip equal I've got minus plus and then I've got zero Loop USD 1 2 3 4 5 6 7 8 n and then brought it on Home with an inner look at that so now I have a useful command down here that I could do things with so if the command was play I could play something if command was stop I could stop something I could put in parameters with the numbers so you see now we've turn this next to useless little Gadget into something that will actually create for us a usable create for us a usable program now there were some things I was wondering about up here okay so here what if I what if I did not make Command ready what if I didn't put that there okay I don't think that has to be Global okay but I will set it command ready equal false I think like that let's see if that will work okay so now I'm going to do power 1 2 3 and equal let me try it again power 1 2 3 equal no it's got to be up there because here every digit resets it to false okay every digit resets it to false so I need to do a global uh and then what was that that was uh command ready and then it gets it from up here so it doesn't keep setting it to false every time something is hit so there was a reason to do that but I think begin record begin record has to come in the same way as false otherwise it would set it false with each additional digit so there was a reason that I did it that way and it was a good reason and then command ready has to be set here false or otherwise it would just keep printing the command because it stays true so between here here in this part of the code you can put all the things that you want to do okay all the things that you would want to do you can do there okay guys this might be one that you have to watch a couple of times but if you follow through it hopefully it will make sense and it was kind of a little bit of a challenging this would be an Uber Legend if you did this on your own but if you were not able to do it on your own then turn my video off and think through through it and see if you can do it on your own after you saw me do it okay it's time for us to talk about homework okay time for us to talk about home homework so what I want you to do is I want you to add a Servo to your setup and then what I want you to do is I want you to come in I'm going to press power I better run the program okay I better run the program okay this is the homework okay so I'm going to press power and then I'm going to say that I want to go to35 Dees and then I want to press enter and boom look at that went to 135 ah I didn't really want that I really wanted 45 enter boom really no no I really wanted five equal look at that I really wanted 1 79 enter boom okay guys I am really hoping that this next homework assignment will be pretty easy because if you I've done the hard part here which is generating the command now that you can generate the command what I want you to do is go do something us useful with the new command that you generate from this and as a demonstration we are controlling this Servo now notice if I just come in and do a bunch of nonsense and then say equal nothing happens but I can come in and say power and [Music] then 45 and equals and there it is at 45 degrees so you see I'm ignoring also notice that I'm not deliberately doing short button pushes to avoid the negative one the software avoids the negative one for long uh button pushes also though see that it works I could do star and I could do 22 and it will recognize that because it's ignoring the minus ones but a two let up a two it would be like 2 negative 1 negative 1 negative 1 and a two it works for that so you can get repetitive button pushes you can get repetitive button pushes but the long button push doesn't uh doesn't hurt you okay guys man this is some heavy duty stuff that we're doing here let me know if I'm making these things too hard I don't want to make them too hard but what are we doing we learned how to do dictionaries we learned how to use callback functions that are not called by us but that are called by the library that we're using and then we've thought very carefully about how to coordinate what is going on in the call back with what is going on in our main program and this is actually something that a lot of the devices that we interact with a lot of the devices that we interact with are going to use callback functions so you've got to get really comfortable in using callback so what have we learned in object-oriented programming we've learned how to do classes we've learned how to do methods we've learned how to do functions we've learned how to create our own libraries and we've learned how to use both cores on the Raspberry Pi PE o w and hopefully today what you've learned is the power of knowing how to use a dictionary now on this particular on this particular homework we didn't need to use we didn't need to use that other core because the main library that NEC library or that R iore RX it's taking care of all that and I don't think it's using the other core it is probably just using interrupts or something like that to make it work so they done the hard part and then we just had to figure out how to get the call back going okay guys I hope you're having as much fun taking this class these classes as I am making them as always shout out to you guys who are helping me out over at patreon great big thanks to you guys also you can help me by giving me a thumbs up and leaving comment down below that will help me with the you YouTube juice and this video will be shown to more people if you haven't already subscribed to the channel when you do ring the Bell so you'll get notifications When Future lessons drop and most importantly share the video with other people because the world needs more people doing engineering and fewer people sitting around watching silly cat videos Paul mcorder with toptech boy.com I will talk to you guys later
Info
Channel: Paul McWhorter
Views: 1,863
Rating: undefined out of 5
Keywords: STEM, LiveStream, TopTechBoy
Id: 6_ue3kXGADU
Channel Id: undefined
Length: 49min 52sec (2992 seconds)
Published: Tue Jul 02 2024
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.