Silicon ChipMake it with Micromite - August 2020 SILICON CHIP
  1. Outer Front Cover
  2. Contents
  3. Subscriptions: PE Subscription
  4. Subscriptions: PicoLog Cloud
  5. Back Issues: PICOLOG
  6. Publisher's Letter
  7. Feature: The Fox Report by Barry Fox
  8. Feature: Techno Talk by Mark Nelson
  9. Feature: Net Work by Alan Winstanley
  10. Project: Micromite LCD BackPack V3 by Tim Blythman
  11. Project: Steering Wheel audio BUTTON TO INFRARED Adaptor by John Clarke
  12. Project: JUNK MAIL REPELLER! by Allan Linton-Smith
  13. Back Issues by Jim Rowe
  14. Project: Bargain Modules Class-D Stereo Plus Subwoofer Amplifier by Allan Linton-Smith
  15. Feature: Circuit Surgery by Ian Bell
  16. Feature: AUDIO OUT by Jake Rothman
  17. Feature: Make it with Micromite by Phil Boyce
  18. Feature: Practically Speaking by Mike Hibbett
  19. Feature: Max’s Cool Beans by Max the Magnificent
  20. Feature: Electronic Building Blocks by Julian Edgar
  21. PCB Order Form
  22. Advertising Index

This is only a preview of the August 2020 issue of Practical Electronics.

You can view 0 of the 72 pages in the full issue.

Articles in this series:
  • Techno Talk (August 2020)
  • Techno Talk (August 2020)
  • Techno Talk (September 2020)
  • Techno Talk (September 2020)
  • Techno Talk (October 2020)
  • Techno Talk (October 2020)
  • (November 2020)
  • (November 2020)
  • Techno Talk (December 2020)
  • Techno Talk (December 2020)
  • Techno Talk (January 2021)
  • Techno Talk (January 2021)
  • Techno Talk (February 2021)
  • Techno Talk (February 2021)
  • Techno Talk (March 2021)
  • Techno Talk (March 2021)
  • Techno Talk (April 2021)
  • Techno Talk (April 2021)
  • Techno Talk (May 2021)
  • Techno Talk (May 2021)
  • Techno Talk (June 2021)
  • Techno Talk (June 2021)
  • Techno Talk (July 2021)
  • Techno Talk (July 2021)
  • Techno Talk (August 2021)
  • Techno Talk (August 2021)
  • Techno Talk (September 2021)
  • Techno Talk (September 2021)
  • Techno Talk (October 2021)
  • Techno Talk (October 2021)
  • Techno Talk (November 2021)
  • Techno Talk (November 2021)
  • Techno Talk (December 2021)
  • Techno Talk (December 2021)
  • Communing with nature (January 2022)
  • Communing with nature (January 2022)
  • Should we be worried? (February 2022)
  • Should we be worried? (February 2022)
  • How resilient is your lifeline? (March 2022)
  • How resilient is your lifeline? (March 2022)
  • Go eco, get ethical! (April 2022)
  • Go eco, get ethical! (April 2022)
  • From nano to bio (May 2022)
  • From nano to bio (May 2022)
  • Positivity follows the gloom (June 2022)
  • Positivity follows the gloom (June 2022)
  • Mixed menu (July 2022)
  • Mixed menu (July 2022)
  • Time for a total rethink? (August 2022)
  • Time for a total rethink? (August 2022)
  • What’s in a name? (September 2022)
  • What’s in a name? (September 2022)
  • Forget leaves on the line! (October 2022)
  • Forget leaves on the line! (October 2022)
  • Giant Boost for Batteries (December 2022)
  • Giant Boost for Batteries (December 2022)
  • Raudive Voices Revisited (January 2023)
  • Raudive Voices Revisited (January 2023)
  • A thousand words (February 2023)
  • A thousand words (February 2023)
  • It’s handover time (March 2023)
  • It’s handover time (March 2023)
  • AI, Robots, Horticulture and Agriculture (April 2023)
  • AI, Robots, Horticulture and Agriculture (April 2023)
  • Prophecy can be perplexing (May 2023)
  • Prophecy can be perplexing (May 2023)
  • Technology comes in different shapes and sizes (June 2023)
  • Technology comes in different shapes and sizes (June 2023)
  • AI and robots – what could possibly go wrong? (July 2023)
  • AI and robots – what could possibly go wrong? (July 2023)
  • How long until we’re all out of work? (August 2023)
  • How long until we’re all out of work? (August 2023)
  • We both have truths, are mine the same as yours? (September 2023)
  • We both have truths, are mine the same as yours? (September 2023)
  • Holy Spheres, Batman! (October 2023)
  • Holy Spheres, Batman! (October 2023)
  • Where’s my pneumatic car? (November 2023)
  • Where’s my pneumatic car? (November 2023)
  • Good grief! (December 2023)
  • Good grief! (December 2023)
  • Cheeky chiplets (January 2024)
  • Cheeky chiplets (January 2024)
  • Cheeky chiplets (February 2024)
  • Cheeky chiplets (February 2024)
  • The Wibbly-Wobbly World of Quantum (March 2024)
  • The Wibbly-Wobbly World of Quantum (March 2024)
  • Techno Talk - Wait! What? Really? (April 2024)
  • Techno Talk - Wait! What? Really? (April 2024)
  • Techno Talk - One step closer to a dystopian abyss? (May 2024)
  • Techno Talk - One step closer to a dystopian abyss? (May 2024)
  • Techno Talk - Program that! (June 2024)
  • Techno Talk - Program that! (June 2024)
  • Techno Talk (July 2024)
  • Techno Talk (July 2024)
  • Techno Talk - That makes so much sense! (August 2024)
  • Techno Talk - That makes so much sense! (August 2024)
  • Techno Talk - I don’t want to be a Norbert... (September 2024)
  • Techno Talk - I don’t want to be a Norbert... (September 2024)
  • Techno Talk - Sticking the landing (October 2024)
  • Techno Talk - Sticking the landing (October 2024)
  • Techno Talk (November 2024)
  • Techno Talk (November 2024)
  • Techno Talk (December 2024)
  • Techno Talk (December 2024)
  • Techno Talk (January 2025)
  • Techno Talk (January 2025)
  • Techno Talk (February 2025)
  • Techno Talk (February 2025)
  • Techno Talk (March 2025)
  • Techno Talk (March 2025)
  • Techno Talk (April 2025)
  • Techno Talk (April 2025)
  • Techno Talk (May 2025)
  • Techno Talk (May 2025)
  • Techno Talk (June 2025)
  • Techno Talk (June 2025)
  • Techno Talk (July 2025)
  • Techno Talk (July 2025)
Make it with Micromite Phil Boyce – hands on with the mighty PIC-powered, BASIC microcontroller T he two LED 8×8 matrix modules added last month provide the Micromite buggy with a nicelooking pair of eyes. They enable you to give your robot some personality, especially when they are animated. For example, why not make the eyes appear to look left when the robot is turning left, or possibly make them blink at random intervals. Maybe the eyes could close when the robot has not moved for a while, giving the appearance of it snoozing. They could then open immediately before the robot does anything, making it look as if it has just woken up. An MMBasic program has been written to make all the above possible; so this month we are going to explore the detail of how to use the code. By the way, why not use these eyes as the basis for some other fun projects. For example, add a PIR sensor to create a spooky Halloween ghost that appears to stare at you as you move around the room! This month, we will also discuss how to provide basic control of your robot with an infrared (IR) remote transmitter. We will use the 44-button IR transmitter from the Micromite Moodlight in Part 13 (PE, February 2020). This will allow you to move the robot forward and back, turn it left and right, and also adjust its speed. Naturally, these actions will be combined with eye animations. MRB Chassis Before we go any further, several readers have asked for the MRB chassis dimensions so they can make their own – all is revealed in Fig.31 (see end of article). If you have access to a laser cutter or CNC machine then you will find these measurements will give you a perfectly accurate result. Be sure to use a material that is from 3mm to 6mm in thickness. Acrylic or modelling plywood is perfect; you could 52 use aluminium, but in this scenario it should be painted (at least two coats) to avoid potential shorts with the underside of the MRB daughterboard. If you intend to cut the chassis by hand, then the hole positions for the wheel mounts and motor mounts are critical (as are the hole diameters). If they are positioned too far apart, then the siliconetracks will be too tight. This will then apply sideways tension to the motor spindles resulting in the motors being over-worked (shortening their life-span). On the other hand, if the wheel and motor mounts are positioned too close together, then the silicone tracks will be too loose and will keep falling off the toothed wheels they are wrapped around. For the three slots for the MKC/Bluetooth module, and the two slots for the motors; there is a fair bit of tolerance in the size and positions of all of these, so cutting by hand shouldn’t be too much of an issue. If you do make your own chassis, then please do send in pictures – we are always interested in seeing how you get on. Thanks to all of you who have done just that – there are some great MRB builds out there. Animated eyes – theory If you loaded last month’s test program then you have probably taken a quick look at the code to try and understand how the animated eyes work. If not, then don’t worry – all will be revealed below. Even if you did look at the code, then this month we have added some new functionality; so let’s work through what is involved, step-by step. It is a lot easier than you may imagine. A summary of the individual steps is as follows:  Define eyeball shape (8×8)  Overlay pupil pattern (2×2)  Overlay any blinking (by row(s))  Display result on LEDs (anywhere) x = 1 x = 2 x = 3 x = 4 x = 5 x = 6 x = 7 x = 8 Part 19: Controlling your MRB with an IR transmitter and animating its eyes y= 1 y= 2 y= 3 y= 4 y= 5 y= 6 y= 7 y= 8 eye(1)=&b00111100 eye(2)=&b01111110 eye(3)=&b11111111 eye(4)=&b11111111 eye(5)=&b11111111 eye(6)=&b01111110 eye(7)=&b00111100 eye(8)=&b00000000 Fig.32. The values in the Leye() and Reye() arrays determine the shape of the two solid eyeballs. Note that both eyes (left and right) are independently controllable. This allows for a lot more character to be added compared to if we were only able to display the same image on both eyes. All variables are prefixed with either an L or an R (you can work out the logic there!) – and any variable in the following discussion without an L or an R prefix is just to make the diagrams and explanations less congested. The eyeball The whole animated eye process begins by defining the shape of each eyeball; ie, the solid ‘white’ part of the eye. In our application, the eyeball will be a solid colour of whatever LED matrix colour you have – here we are using red. Typically, the two eyeballs are either identical (symmetrical), or are a ‘mirror’ image of each other (but, this does not have to be the case). In Fig.32 you can see that the eyeball is a pattern no bigger than 8×8 pixels. Here we have defined an eyeball that is 8 pixels wide, and 7 Micromite code The code in this article is available for download from the PE website. Practical Electronics | August | 2020 Fig.33. The values in the Lpupil() and Rpupil() arrays define how each 2×2 pupil will look. There are 16 different permutations for each pupil. high. This pattern is stored in an array named eye(). So Leye(1) contains the required pixel pattern of the top row of the left eye, and Reye(8) stores the pixel pattern of the bottom row of the right eye. The 8 bits that define the pixel pattern in a horizontal row translate nicely into an 8-bit binary value and hence we are using the MMBASIC &b binary prefix to show how these values are easily generated from the required pattern (1 represents ON, and 0 represents OFF). An important point to note here is that each 8×8 eyeball pattern is not defining the ON/OFF LEDs on a matrix, it is just the 8×8 eyeball pixel image that we will ultimately be able to position anywhere on the 8×8 matrix (as we shall see in the last step). So this step has simply defined the eyeball shape as a set of ON pixels, stored in the Leye() and Reye() arrays. Behind the scenes in the code, the eye() arrays are stored into temporary arrays: LeyeTemp() and ReyeTemp(). These two temporary arrays allow the overall eye images to be ‘constructed’. The pupil Referring to Fig.33, you will see that the eye’s ‘pupil’ is a 2×2 block of pixels. Again, we will use the &b binary prefix to make things easier to understand. The concept here is to use OFF pixels to represent the pupil shape. The binary notation shown here uses a 1 to represent a dark part of pupil (ie, pixel off) and a 0 to represent ‘no change’ to the background. This allows us to have any shape pupil in the 2×2 block (yes, that’s 16 different pupil shapes if you do the maths!). Here we are showing a pupil shape with the top-right corner not darkened. You may be wondering why we are saying ‘no change’ rather than simply turning ON the pixel (bearing in mind the eyeball comprises of pixels that are ON). Well, the pupil can be placed anywhere over the eyeball image, and if it were to be placed next to the edge of the eyeball (great for ‘sad’ eye impressions) then we don’t want to affect the shape of the eyeball by turning ON ‘un-darkened’ pupil pixels that hang outside the eyeball shape. So pupil(1) contains the top row of the 2×2 block, and pupil(2) contains the bottom row. A 1 represents a dark pixel in the pupil, and a 0 represents no change. Now that we have defined the pupil shapes, we need to position them within the eyeball image (stored in LeyeTemp() Practical Electronics | August | 2020 and ReyeTemp() – see above). This is just a matter of defining where the topleft pupil pixel is positioned within the eyeball 8×8 image by using a simple x,y co-ordinate system. The top left corner of the eyeball is defined as x=1, y=1. So Lx=4 and Ly=4 would position the 2×2 left pupil in the central position of the 8×8 left eyeball. Similarly, Rx=3, Ry=5 would position the right pupil near the lowerleft corner of the right eyeball. So this step has simply defined the pupil shapes as a set of OFF pixels stored in the Lpupil() and Rpupil() arrays; and positioned both pupils into the correct positions within LeyeTemp() and ReyeTemp() by defining Lx and Ly, and Rx and Ry values. Blinking First, a bit of background. We are currently working through how to construct a static image of two eyes to be displayed on the two LED matrix modules. Consider the result as a ‘frame’ image. If we were to display one frame, followed in quick succession by another frame (that has a slight difference in content), then continuing this process we would end up with animated eyes – you can liken this to the early days of film animation. So a closing-eye effect can be generated by effectively switching OFF appropriate rows of LEDs in each frame and displaying them in quick succession. However, you can’t simply switch the LEDs back ON again to simulate an opening-eye effect otherwise you will end up with all LEDs being turned ON. By using LeyeTemp() and ReyeTemp() each and every time we draw a frame, we can overcome this opening-eye issue. The eyeball shape, and pupil shape, are stored in the eyeball() and pupil() arrays, and the image is constructed in the eyeTemp() arrays (piece by piece) to create the single ‘frame’. To create a single frame within a blinking effect (sequence of frames), we ideally need a method to turn off the pixels in any row(s) in the current eyeTemp() arrays (currently containing the eyeball, and correctly positioned pupil). We could have simply defined new x = 3 pupil(1)=&b10 pupil(2)=&b11 y= 4 Fig.35. The eye image after defining the eyeball, the pupil, and any Blink setting. Values of Lx/Rx=3 and Ly/Ry=4 define the pupil position (shown highlighted). eye() arrays, but this would destroy the original eyeball pattern stored. We have a better method as we will now see. Referring to Fig.34 you will see that the Blink variable is used to store a value to represent any complete row(s) of pixels that we wish to turn OFF in the eyeTemp() arrays. Once again, binary notation is used to simplify the explanation. A 0 bit in Blink means that the associated row is unaffected (and will be displayed as currently defined in eyeTemp(), and a 1 means that a row will be switched OFF in the displayed image. The 8-bit value contained in Blink uses one bit per row of pixels – the most-significant bit relates to the top row, and the least-significant bit relates to the bottom row. Note once again, this is not referring to the rows on the matrix module, it is referring to the built up image in the eyeTemp() arrays (which can ultimately be positioned anywhere on the LED matrix modules). Here we are effectively switching OFF the top and bottom rows of our 8×7 eyeball image. So this step has simply defined which rows of pixels we wish to switch OFF in order to create a frame within a sequence of frames that can be used to create a blinking effect. At this stage it is worth seeing the result stored in the eyeTemp() arrays from the values shown in Fig.32, 33, and 34. Referring to Fig.35, you can see the result of using x=3 and y=4 as the pupil position values. Here, the (circled) pixel at 3,4 is defining the top-left pixel of the pupil. – – Blink=&b10000011 ShiftX=-1 ShiftY=1 x + y + Fig.34. The values in Blink determine which row(s) of pixels in the eye image need to be switched off. Here, the top and bottom rows are switched off in our 8×7 eyeball. Fig.36. The LShiftX / LShiftY, and RShiftX / RShiftY variables determine where the eye image is positioned on each LED matrix. Here they are moved one pixel to the left, and one down. 53 Lpupil(1)=&b10 Lpupil(2)=&b11 Lx=3 Ly=4 LShiftX=0 LShiftY=0 eye(1)=&b00111100 eye(2)=&b01111110 eye(3)=&b11111111 eye(4)=&b11111111 eye(5)=&b11111111 eye(6)=&b01111110 eye(7)=&b00111100 eye(8)=&b00000000 Rpupil(1)=&b01 Rpupil(2)=&b11 Rx=5 Ry=4 RShiftX=0 RShiftY=0 Fig.37.The demo program (MRB_SampleEyes.txt) is configured to output the image shown here. Try altering variables in the code to see how they affect the displayed image. The other circled pixel at 1,1 is used to define where this 8×8 image is positioned on the 8×8 matrix module (explained in the next step). Displaying the eyes As mentioned several times already, the image contained in the eyeTemp() arrays can be positioned anywhere on the LED matrix. This is where two more variables come into play for each eye: ShiftX and ShiftY. Referring to Fig.36, you can see how by setting these values, you can place the image wherever you like on the LED matrix modules. Here we have ShiftX=1, which means the image is positioned 1 pixel over to the left; and ShiftY=1, which means it is also positioned one pixel down. The dotted line in Fig.36 represents the 8×8 image stored in the eyeTemp() arrays with its top-left pixel circled. ShiftX and ShiftY simply give coordinates relative to the top-left pixel on the LED matrix module. Note that values bigger than 8, or smaller than -8 will make the image disappear. Now that ShiftX and ShiftY have been defined, we need to call a subroutine to actually draw the eyes onto the LED matrix modules. This subroutine is simply called DrawEye and will work out all the logic in order to create the desired result. By altering the ShiftX and/or the ShiftY values, the eyes can be made to scroll. Note that there is no wrap-around when scrolling. A quick example To demonstrate all of the above, we will now draw a pair of simple eyes on the robot (ie, draw a single frame). This is easy; it’s really just a matter of loading the variables and arrays, and then calling the DrawEye subroutine. All the information required is shown in Fig.37; and you can download the code (MRB_SampleEyes.txt) from the August 2020 page of the PE website. To begin with, the Leye(1) to Leye(8) and Reye(1) to Reye(8) arrays are loaded with the eyeball pattern as shown. Next, the pupils are defined by loading arrays Lpupil(1) and Lpupil(2), and Rpupil(1) and Rpupil(2). To position the pupils, load the variables Lx, Ly and Rx, Ry. Here, we are not setting LBlink or RBlink (but you can set them to 0 for 54 now so you can see the effect later). To finish defining the ‘frame’, set LShiftX and LShiftY, and RShiftX and RShiftY as shown. Nothing will appear on the LEDs until you call the subroutine DrawEye – so go ahead and do this to see the result. If all has been typed in correctly, you should see the image (as shown in Fig.37) displayed on the robot’s eyes. Now have a play by altering some of the above values and see how it affects what is displayed on the LEDs. This is the best way to learn. If you look at the code, there are also some DO…LOOPs contained in subroutines, which when called, will show a sequence of frames – in other words, will show you some eye animations. Now have a go at creating your own animations! IR control – theory Last month, the MRB had IR functionality added by implementing just a single component – the now-familiar TSOP IR receiver. As we have seen in previous articles, MMBASIC makes it very easy to add IR control into program code. As a reminder, we use the IR command to define an interrupt subroutine (SUB) that will then automatically get called whenever an IR signal is detected. MMBASIC passes two variables into the interrupt subroutine: the KeyCode (representing the unique button number that has been pressed), and the DeviceCode (representing which IR transmitter is being used). Within the IR interrupt subroutine, we can simply use the command structure: for each CASE to simply alter the values of certain variables; variables that you are using (and continually checking) in your main program. We will now show you this in practice. Bringing it all together Now that you have an understanding of how to create, draw, and animate some eye effects, let us quickly show you how to apply them to some robot movements – all controlled by the 44button IR remote control. The program code we’ll be using (MRB_ IR_Control.txt) is available for download from the August 2020 page of the PE website. We are not going to go into all the specific detail here because the code is commented throughout. Instead, we want to provide you with an overview of the techniques being used. There is nothing new, and a lot of the topics have already been covered. I hope the code will inspire you to create your own much better program, which is customised to your own needs. Fig.38 provides an overview of the code. It has four sections, with which you should now be familiar:  Set up  Main program  Subroutines  Interrupt subroutines. The Set up code just sets a few things that need setting – take a look at the code and I promise that if you’ve followed this series then it will all make sense. The Main program comprises of a DO… LOOP and works through two main blocks Set up C C D D Main program DO onfigure O P T I O Ns onfigure pins eclare v ariables efine eyeball pattern T est MR B move ment va riables to set motors as req uired ( direction and speed) or ( off) U pdate T FT SELECT CASE KeyCode … CASE x … CASE y … CASE z… END SELECT where x, y, and z are the values of specific buttons on the IR transmitter that we wish to respond to. So in order to make the robot do something useful on specific button presses, we will need to write some code for each CASE. As with any interrupt subroutine, it is good practice that each CASE in the IR subroutine contains minimal code. That way, the time spent in the interrupt routine is minimised, and hence the program will always be able to respond to other interrupts – in this case, immediately respond to other button presses. The best way to minimise code is LOOP Subroutines  I nitialise 8 x8 matrix modules  Load eye pattern ( left, right, straight)  E ye animations ( blink)  D raw eyes IR SELECT CASE KeyCode interrupt SU B Set relev ant MR B move ment va riables D isplay releva nt eye pattern/ animation END SELECT Fig.38. The IR controller program used this month (MRB_IR_Control.txt) comprises four simple sections. Do read the comments contained in the code to understand things better. Practical Electronics | August | 2020 in the appropriate action. For example, a button can be made to act as an immediate brake (if the robot is about to crash!) by simply setting MRB_Move=0 and MRB_ Turn=0. Another example is a specific button that could call a subroutine that runs a sequence of frames to provide a blinking effect (try it by pressing the ‘Flash’ button). That is all the detail we are going to discuss here. Have a play and see which buttons respond on the remote. Comments are in the code to guide you. the TFT. Basically, it displays the values of the above variables, converting some of them into a more ‘human-friendly’ format (for example MRB_Turn is displayed as the word ‘Left’ rather than the value -1). The presence of the DO…LOOP in the code means the Main program is continually using the values of all the variables. Any change in value in a variable will result in a nearinstant change in what the robot is doing. The Subroutines are used to make the Main program easier to follow. If you take a look at each of them in the program, they are all commented to guide you through what they do. The most complex one is DrawEye so do not panic if you don’t follow the logic. It comprises a lot of logical operations on the variables discussed above. The point is, you know how to load the variables, and what effect each one has on the displayed output. Last, the IR interrupt subroutine alters the function the robot is performing. By simply changing the appropriate variable values in the code for each CASE, the change in value of any variable(s) will be picked up in the Main program, resulting of code. The first uses some variables that define what the motors are doing:  MRB_Move defines whether the robot is moving or not (0=no, 1=yes).  M R B _ D i r defines the direction (-1=backwards, 1=forwards).  MRB_Turn defines which way it is turning (-1=left, 0=not turning, 1=right).  MRB_TurnDuration defines how long to turn for before stopping (there are two turn buttons for each direction; one does a large step, the other a smaller step (to fine tune).  MRB_Speed defines the speed of the robot. This is a PWM percentage and varies between 60% (slow) and 100% (fast) in steps of 5%. The speed is displayed on the TFT screen. There is a series of IF…THEN…ELSE…END IF statements that use all of the above variables to control the four I/O pins connected to the two motors. In essence, the end result is that the robot moves, turns or stops as required. The other block of code in the Main program puts relevant information onto Next month To enable our MRB to roam independently (without crashing into anything) it will need to have some form of collision detection. Next month we will show how easy it is to implement this feature by adding a low-cost ultrasonic distance sensor to the front of your MRB. Questions? Please email Phil at: contactus<at>micromite.org 14 5 A 1- 4 : φ 2. 5 B1- 4 : φ 3 C 1- 8 : φ 1. 5 D 1: 3 x 12 D 2: 3 x 12 D 3 : 3 x 3 5 D 4 : 3 x 3 7 D 5: 3 x 10 4 7 4 7 Notes 1) View from above MR B 2) A ll dimension in mm 3 ) B3 and B4 are NO T ve rtically co- linear 4 ) Low er side of D 4 and upper side of D 5 are co- linear 3 7 26 18 12 3 7 26 18 12 8 21 22 3 8 22 24 26 A 3 A 1 B1 D 1 B3 3 8 3 9 D 2 A 4 A 2 107 123 D 3 B2 C 1- 4 11. 7 5 13 D 4 B4 3 7 D 5 11. 7 5 C 5- 8 14 16 4 . 25 4 . 25 18 18 23 23 55 3 0 6 0 4 5 Fig.31. The MRB chassis dimensions – a PDF of this diagram is available for download from the August 2020 page of the PE website. Practical Electronics | August | 2020 55