# Arduino Uno R4 WiFi LESSON 98: Digital Compass with Graphical Dial on SSD1306 OLED

## Метаданные

- **Канал:** Paul McWhorter
- **YouTube:** https://www.youtube.com/watch?v=Mg-MHuoAj2Y

## Содержание

### [0:00](https://www.youtube.com/watch?v=Mg-MHuoAj2Y) Segment 1 (00:00 - 05:00)

Hello guys, this is Paul McCarter with topteboy. com and we're here today with episode number 98 in our incredible new tutorial series where you are learning how to think like an engineer using the Arduino Uno R4 Wi-Fi. 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 Sunfounder Elite Explorer Kit. Now, hopefully most of you guys already have your gear. If you don't, take a look down in the description. there is a link over to Amazon and you can hop on over there and pick your kid 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 this shameless self-promotion. Let's jump in and talk about what I am going to teach you today. And what I'm is I am going to teach you or I'm going to show you my solution to the homework assignment that I gave you last week. So I must ask, were you able to do it? If you were able to do it, go ahead and leave a comment down below. I am legend. And if you weren't able to do it, leave a comment down below. I folded up like a cheap Walmart lawn chair. Now, hopefully most of you guys were able to do this, but I will admit that if you hadn't played around with the OLED in a little while, it might have been a little bit of review and catching up. Never fear. I'm going to show you my solution. What was the homework assignment? Right. Where are we now on the project? We have a working IMU. We're accurately measuring roll, pitch, and yaw. We're applying complimentary filters so that we get readings that are stable, fast, accurate, no drift, and no vibrational noise. That's great. We've also tilt compensated the compass where we get accurate readings even if the project is tilted. So, that's really good. What did we do last week? We added the OLED to the project and then just on the OLED we printed out roll, pitch, and yaw. Well, that's good, but it's not very snazzy. So, what your homework was for today was to build a compass dial, a graphic on the OLED and then have the needle of the compass graphic always pointing north. Okay, so hopefully some of you guys were able to do it. If you weren't, never fear. I'm going to show you my solution now. So, let me get out of your way. Let me have a sip of my goat juice. And then what we're going to do is we're going to have you go over to the most excellent www. topteboy. com. You're going to use this happy little search tool here and you're going to search on something like Arduino digital compass project with SSD306 OLED display. This is a schematic. This is the uh GY87 module that we've been using for like the last 10 or 15 lessons. And then last week we uh added to it the SSD306 OLED. And this was the code that we ended up last week that basically on the little OLED shows roll, pitch, and yaw. Okay. So, let's start where we ended last week and let's come over here to our Arduino IDE and let me make sure I didn't see for sure. Let me show you my little OCD a little bit here. I want to make sure. Yep. Copied. Okay. Now, if I went back and checked three more times, then we would have a problem. But you get a free pass on one check. Okay. I that. And we're going to paste it here. Now, what I will do is I will come over here and let's just run it. And when we run it, we should see no errors. And then up, you can see where I'm going with the project. That was from last week. I showed you this is the graphic that we want to get working. We're not going to do all three of them today, but we're going to do the first one. Okay, the compass. Okay, it is downloading and compiling. And here it goes. And that looks good. We'll come over here. And then what you see is roll, pitch, and yaw. Roll is working.

### [5:00](https://www.youtube.com/watch?v=Mg-MHuoAj2Y&t=300s) Segment 2 (05:00 - 10:00)

Pitch is working and yaw is working. So the universe is in proper working order and we can copy and paste and things work. And so that is good. Now, we're going to have to come back over here and what we're going to do is we are going to try to get that graphic now up and working. Okay, we're going to try to get that graphic up and working. So, let me do a tiny bit of Windows management. So, up here at the top, turn that serial monitor off. up here at the top. We've already set up the display, imported the libraries, we have come over here and we have set up the screen and then in the void setup we have uh started it and cleared it. That's good. Then we came down here and what we did was we cleared the display, right? We cleared the display and then we put the text on there for the roll, the pitch, and the yaw. And all that we're going to kind of hang on to. We're going to sort of hang on to all of that. And then what we're going to do, though, is now we're going to add that dial. So, I come up here. I still want to clear the display. print all of these things on there. Okay. And then I still want to do a display. But now I'm going to add a dial that uh compass dial. And I think what I'll just call it is update dial because we will want to we'll build the dial in the function and then every time through the loop we want to update it. Okay, we'll build the function and every time through the loop we will update it. Okay, and that way the little needle will be live. So all we're going to have to do down here is just call the function update dial. So that part is pretty easy, but we're going to have to come up to the top now and build that function. So I think I'll do it after the calibrate sensors and before the void loop. I think this would be a most excellent place to do it. And it's going to be pretty straightforward. I think it's I think probably either this was easy for you or it was impossible. There's really not a hard way to do this because the only way to do it is really the easy way. But the easy way does require you to do some thinking. Okay? And so let's come in here and I'm going to say void update dial like that. And then I'm going to have to put in some variables. So I'm going to start with if I'm going to have a circle, what are we certainly going to need for the circle? A radius. And I'm going to set the radius equal to 20. Okay, 20 pixels. Now, why the whole thing is like uh 64 pixels and then we're using the first two rows, which would be like 10 pixels, 10 pixels. So, a radius of about 20 would be a diameter about 40. And so, I think that would be a good first guess for how big that circle should be. And now we're going to set an offset. We won't be using the offset this week, but we'll use it next week. So, we're going to go ahead and set it up. Now, what does that offset do? That offset is going to be the amount of space between one circle, one dial, and the next. And so, we'll have three pixels. And so, those dials won't be on top of each other. All right. Now, if we're going to have a circle, what are we going to need? We are going to need a center. So the x center and that is going to be kind of surprising but it's going to be the radius. Okay. Why is it going to be the radius? Because I want that circle right to the edge of the screen. I don't want to waste any space. I want that circle as big as possible. So it's going to be right on the edge of the screen, which would mean that I would want the center at 20. Okay? and then it would start at zero, meaning that there's kind of like a one pixel buffer. If I'm thinking about this right, if I went to with a radius of 19, uh I mean, I guess what I'm saying is I'm going to have a radius that is 20, but it's actually going to start at zero. Okay? And so that should work. So, and why do I do this? If I make the radius smaller, it's going to adjust its position. So, its center position is going to depend on radius. And so, all I would have to do is change the radius. And then that first circle, that first dial would always be in the right place. Okay. So, I've got the X1 center. And then I'm going to need the

### [10:00](https://www.youtube.com/watch?v=Mg-MHuoAj2Y&t=600s) Segment 3 (10:00 - 15:00)

Y1 center. Now what I wish you guys could learn like this is the mark of a really good engineer and that's to be thinking parametrically. Okay. So for the radius in the center how many things do I set? One. And as the radius changes the center resets to be in the right place. Now I want to do the same thing with the Y1 center. Where do I want the center to be? I want it to be relative to the bottom of the screen. Now, it's 64 pixels. The first pixel is zero. So, the last pixel is 63. So, where would I want the center? I would want it 63. That's the last pixel minus the radius. So now as the radius changes it's always going to be in the right position in X and Y. Do you see I am thinking how parametrically. So for all this business really the only thing that I set is just the radius and the offset. Okay, I just set offset and everything else is going to be right no matter what radius and offset I use. I hope it makes sense what I'm saying. Okay, now I'm going to be drawing some lines, right? lines like that needle and then I'm also going to be drawing the tick marks on the compass. Those are all lines. In a line, you need sort of a starting value x and y and an ending value x and y. You need two points, the two end points of the line. So, I need to go ahead and declare those variables. And so, I'll say an int and I'll just call it x1. That's kind of uh that's kind of the convention x1. And I'm not going to give it a value because I don't know, right? We'll calculate those later, but I got to declare them. And int1, and we don't want an equal there. So that's the first point x1 y1. Now you guessed it x2 y2. So now I have my two end points of any line that I might want to draw. Now when we put those tick marks around the circle I'm going to need an angle. So, I'm going to call it float and I'm going to have the angle keep track of it in rads because all those trig trigonometry calculations, they want radians. And so, I'll name my angle rad to remind me that it is radians. Now, also I'm going to need a tick scale. Okay. So if you think the end of the tick is always going to be on the circle, but then how long do you want the tick? You could have it a very short tick or long tick. So I need the tick scale and that would be like the fraction of the radius, you know, like how much of the radius do you want uh do you want this thing to be? And we'll set that down in a minute. Okay. So now let's just do a DSP dot draw circle and I'm going to go X1 center, Y1 center. Okay. And then the radius. So I give it the center point of the circle and the radius. And then we got to tell it white, meaning that we want that pixel on. Can you believe? Are we really already to the point? Are we already to the point of running this and seeing if we get a circle? Oh my. I want to check this because I really want a success here. I really want this thing to run. I did a lot of stuff here. Text scale X1 center Y1 radius white. X1 Y1 radius white. Okay, here we go. Look at that. Looking good. Look. Hey, broken token. What did I do? Oh, I thought I fixed that. Denied. Your friend is Mr. Semicolon, not Mr. Colon. Okay, so D9. I really wanted that one to run. That one hurt. Okay. And then what we want is we want all eyes on the compass. And boom. Is that not a perfect circle? And what is so cool about that? that is all I really set or chose the only

### [15:00](https://www.youtube.com/watch?v=Mg-MHuoAj2Y&t=900s) Segment 4 (15:00 - 20:00)

thing that I really chose that you can see here is the offset. It's the only thing that I mean set was the radius and then the position was based on the radius and we didn't really use offset. We'll use that next week. Okay, that is like a huge big deal to me. That is like just an uh success, incredible pro progress that we are making here. Okay. Uh ladies and gentlemen, I think we need to put the tick marks on now. Okay. So, I'm going to say for int. Okay. And then I'm going to think of I as a degree angle. So I'm going to start at 0 degrees and then I'm going to go I'm going to start at 0 degrees. I'm well 0 degrees would actually be here. I'm going to start at 0 degrees. I'm going to go all the way around the circle and periodically I'm going to drop tick marks. Okay? Periodically I am So, I'll start at I equals 0 and then I'm going to go as long as I is less than or equal to 360°. And then I don't want to put 360 tick marks, but really between 0 and 90, I could kind of get three tick marks. So, I'm going to go 0 30 60 90. And so, what is my jump? My jump's going to be 30°. So, I'll say I is equal to I + 30. Okay. And who is your friend? mister semicolon there between the uh between the things. So that is my for loop set up. Now what do I want to do in that for loop? Well, first of all, I got to calculate the radians. The angle in radians is going to be equal to that index i * pi / 360. What are we doing? We are converting from degrees to radians. Okay. Now, why didn't I just step through in radians? Because radians are hard to think in. I went in degrees. I did the math in degrees. And then I just convert to radians. And hopefully you can see hope that makes sense. So tick scale I'm going to set equal to. 9. So what does that mean? That means that from the center I want to go 90% of the radius out. And then right there I'll start the tick. Okay, if I set it at 50, I would come 50% of the radius and I would have a huge long tick mark. But if I set it at 0. 9, that means it's a real little bitty tick mark. A And we'll have to look and see if that's any good. Okay, so that is my tick scale. Now, what I'm going to do is now I've got to go in and I have to put those ticks in. Well, the tick is a line and it has a starting point and an ending point. So, it's got an x1 y1 and it's got an x2 y2. So, let's see what would x1 be. Well, everything has got to be reference to the center of the circle. So, I've got to start at X1 center, and I've got to add to that the tick scale times the radus. And so, I'm going to go out not all the way to the radius, but I'm going to go out 90% of the radius. And then that is where I'm going to start my point. So, that would be tick scale time radius times what is the x value? It is the cosine of the angle. X is the radius time Y is the radius of the sign time the angle. And we are doing what? X. And so this would be what? Cosine of the angle in rads because these math functions on most microprocessors, microcontrollers, they always are working in radians. Okay. So now that is all good. But one thing we have to see that those tick marks are individual pixels like you're on pixel 1 2 3 4 5. Okay. So we don't want this to be some crazy floatingoint number which it would be. So we're going to convert it to an int like that. Okay. So that's my x1. Well then what would my y1 be? My y1 would be almost the same thing. it Okay, but we are going to be referencing not the x center but the y center point and then y

### [20:00](https://www.youtube.com/watch?v=Mg-MHuoAj2Y&t=1200s) Segment 5 (20:00 - 25:00)

is sign right the y value is always sign the x value is cosine so I think that should be right okay so that's the start point nothing nothing when you're almost to the radius you have the first point x1 y1 and then you want to draw on out to the radius. And so x2 is going to be almost the same thing. Almost this same thing. Okay? But this time you're not going to go out to tick scale. You're going to go all the way to the radius. Right? You start before you get to the radius by multiplying by tick scale. But now you're just going to go on out to the radius. Now the y2 is going to be almost the same thing. Okay. I think it'd be easier to copy this one. Okay. And now here again we're going to go all the way out to the radius. And this time it is sign. Now what are we going to do? dspraw line. And where do we start? at x1 comma y1 our first point where do we go to x2 comma y2 and then we say why we want those pixels on and then like that could it really be that easy I don't think it's that easy I think I got a I must have just done something wrong I don't think it could be that easy but we are going to keep before in where was that I got an error Houston we have a problem. What is that? Before the int. Oh. Oh. Oh. I think that was a terrible mistake. Okay. The int is inside there. I'm not taking the int of. I'm making I and it end. All right. That's uh that's understandable. Okay. And I think that is looking like it might run this time. So, all eyes on our display. And boom. Look at that. Almost almost. Why did we not get all of them? That is kind of That is perplexing. So somewhere in here I have a mistake. So I starts at zero and it goes to 360 and it jumps in 30°. Okay. The angle in radians is I * p<unk> / divided by 180. That was terrible. And I used to be a math. Wait a minute. Let me show you. You didn't see that. Okay, I had divided by 360 and it should be divided by 180 here. Okay, that was the mistake. Okay, now look at that. Okay, so look, I've got 0, 30, 60, n 90, and then I have 120. I have 150, 180, 210, 240, 270, 310, uh, did I do that? 270, 300, and then 330, and 360. And you can see I wouldn't want those tick marks to be any smaller than that. Okay? I wouldn't want them But what I kind of like is I would like those to be the minor tick marks. Okay? And then at 0 and 90 and 180 and 270 at the sort of northeast, south, and west points, I would like those to be major tick marks. So I want them to be larger at those four points. So if I want them larger, would tick scale go up or down? Well, it's a scaling factor. So I make the scaling factor less, which would mean I'm scaling less, which would be it would be a bigger tick mark. Okay. Now, all of those tick marks are set at 0. 9. If I wanted a bigger tick mark, what would I do to tick scale? I would make it smaller, which means I would reduce the scaling. I would be closer to the whole thing. So what I'm going to do is I'm going to say if modded I modded with 90 that's equal zero. What is that nonsense that I just did? Mod gives you the remainder. So if I was at 1, 1 / 90 is

### [25:00](https://www.youtube.com/watch?v=Mg-MHuoAj2Y&t=1500s) Segment 6 (25:00 - 30:00)

0ero with a remainder of one. So the the result of this would be 1, not zero. Two, it'd be two, not zero. When's the only time the mod is 90 at 0? At 90, right? 90 divided by 90 is one with no remainder. At 180, 180 divided by 90 is two with no remainder. So only on those multiples of 90 would the remainder equal zero. Well in that case what do I want to do? Tick scale is going to be equal to. 7 like that. Okay. And all the other ones it's going to be 0 n5. So I should get a big tick mark at north east southwest. I love that mod function. I think it is the most one of the most powerful and notused functions. And if you guys could understand mod so many times, it'll get you out of a bind. Okay, I think that I am confident in enough in this that I'm going to run it. I'm going to come over here and then you guys keep your eyes on this and let's see what is going to happen. What is that? I missed a token. Come back over here. I was so sure that thing was going to run. Okay. Where is my problem? Draw a line. That should be good. So, it should be somewhere. I think what happened was it closed the if for me and then I closed it as well. And so, I think I had two closed there. So, let's go ahead and let's run this thing again. And I think this time it is going to run. And then we are going to Okay, it's going to run. We're going to come over here and all eyes on this. And boom. Look at that. North, east, south, west have big tick marks. And then the 30, 60, the 30 increments, they have a smaller tick mark. And so I think that's just really a very kind of like perfect dial. And I don't think I would want to do anything else because I don't think that you really would want more tick marks than at 30° because then they're just going to start running into each other. And so that is like I think that's most of the hard work. Okay. I think that is So now let's come over here and now we got to bring this thing to life. And so what are we going to do? We're going to need to draw that line. Now, this is everything that put the tick marks on. And then this ends the function. So after we got the tick marks on, I'm going to have to come in now and for what is the dial? What is the needle? The needle is a line. Where is the needle line going to start? Well, X1 is going to start where? Where do you want the needle to start? The first point needs to be at the center. So, that's going to be X1, the center of circle one. Y1 is equal to Y1 center. So, that line has how many points? The needle Two. The first point is x1 y1 is going to be at the center of circle one. Okay. Now where is the other end going to be? Well the x2 is going to be equal to we reference everything to the center. So it's going to be x1 center plus the radius times the coign. Okay. of the yaw compensated, right? That's the heading, the yaw. This is going to bring it to life. Times pi divided by 180 because that yaw was in degrees and we need to change it back to radians if we're going to do this. Okay. Now, I'm going to say y 2. Y2 is going to be equal to Y1 center plus the rate. Let me get these things lined up better. Plus the radius times what? The Y value is always the sign of same thing. yaw compensated times pi / 180

### [30:00](https://www.youtube.com/watch?v=Mg-MHuoAj2Y&t=1800s) Segment 7 (30:00 - 35:00)

like that. I think I have everything to draw a line. DSP dot draw line. It is going to be x1 comma y1 comma x2 comma y2. And now we've got to make it what? White. Like that. I think we're going to draw a line there. Let's run this thing and see what happens. Whoa. X1 center. Helps if we can spell X1 center. Were you guys yelling at me? That looks good. Let's try it again. Looking good. Do you think it could really be that easy? Let's look. So, watch this here. We should see a needle come on this time. Hopefully. Boom. We got a needle. Okay. Now, if I turn this, that needle is turning. But what you got to see is there is one little bit of an issue. The needle is turning as I turn and it's moving the right amount. But you see north is up here and the needle is pointing east. And so why is that? Because in math and trigonometry, this is an angle of zero. If you're going out the positive x axis, that's 0 degrees. And so when I told trigonometry that I wanted 0 degrees, it put it along the x axis. Okay? So you can see that the yaw, if we bring it on over here, you see with a yaw of zero, it is putting it at 0 degrees in math land. But we're not in math land. Where are we? We're in compass land. And compass land says zero is straight up. So, we're going to have to do a little bit of an adjustment here. So, instead of this, what I'm going to want to do is add 90 degrees to get that baby up to pointing north. So I'm and then I'm going to say plus 90 and then who are your friends? Your friends are the parentheses so that you get your order of operation right. That was one thing as a math teacher I told people man use those parentheses. Okay. So now that should add 90° and it should bring that needle back around where we get compass land and math land working together. So now let's try Oh man, you didn't see that. I'm sorry. Let me show you here. What I did was I put parentheses around this and I added 90. Okay, I'm sorry. I'm not doing very well in the control room today. I really wish I had somebody to run the control room for me. Okay, so let's come over here and let's see this. Okay, well kind of almost that didn't work very well. Okay, so what two problems do I have? It's pointing south instead of north and it's rotating the wrong way. So I want to flip it, right? it and I want it to go the other way. How can I do that? I can do that by making both of these things minus and make minus. Now if I do that, what is going to happen? It's going to rotate the right way and it's going to flip the needle up to the top. Really, I kind of understand this. You It might look like trial and error. And you didn't see that either, did you? Okay. So, man, I'm sorry. So, we had y + 90 in parenthesis. We've made it negative. parentheses, we made it negative. So now let's see what happens. And boom. The good news is that the needle is pointing north. Now if I rotate this way, I want the

### [35:00](https://www.youtube.com/watch?v=Mg-MHuoAj2Y&t=2100s) Segment 8 (35:00 - 37:00)

needle to keep pointing up. Okay? Now watch this. Look at that. You see the needle is always pointing up. Okay? And if I turn it the other way, the needle is always pointing up. So what do I have? I have a working compass display. display that is tilt compensated. Okay guys, that was kind of a fun lesson. What did you uh what did you all think? Let me show you what the homework assignment is for next week. I want you to add the next graphic next week. And I showed you kind of how to think about these things. So hopefully if you guys couldn't do this one by yourself, you'll be able to do the next one by yourself. Okay? And so this is the next one. So I have the yaw. Now this one is the roll. You see right wing up, right wing or left wing up. And then that's the one you're going to do. You're going to do this one. You're going to show row on there. And then the week after that, you're going to get the pitch working, which is the third one. But for next week, you get this one working. Okay. All right, guys. That was kind of a fun lesson, I thought. I hope you guys enjoyed it. It's kind of like I think these things are sort of cool myself. I think it's kind of a cool thing for us to be uh doing. And I hope that you're having as much fun with these classes as I am. I think this is getting to be like a really cool little display and you've gone through a lot of work but now we're getting to where some really fun stuff is coming out. It's at this point that I always like to give a shout out to my Patreons. Without your support, I would not be able to continue to produce fresh new in-depth content every single week. So, a big thank you to you guys. You can help this video by leaving a comment down below and giving it a thumbs up. If you haven't already, subscribe to the channel. When you do, make sure that you ring that bell so you'll get notification when future lessons drop. And most importantly, share this video with other people because the world needs more people doing engineering and fewer people sitting around watching sillyat videos. Paul McCarter with topteboy. com. I will talk to you guys later.

---
*Источник: https://ekstraktznaniy.ru/video/39323*