
{"id":502,"date":"2018-10-17T10:27:05","date_gmt":"2018-10-17T10:27:05","guid":{"rendered":"http:\/\/blogs.plymouth.ac.uk\/embedded-systems\/?page_id=502"},"modified":"2019-09-20T15:18:54","modified_gmt":"2019-09-20T15:18:54","slug":"topic-5-analogue-output","status":"publish","type":"page","link":"https:\/\/blogs.plymouth.ac.uk\/embedded-systems\/microcontrollers\/mbed-os-2\/courses\/embedded-systems-in-context-level-4\/topic-5-analogue-output\/","title":{"rendered":"Topic 5 &#8211; Analogue Output (introduction)"},"content":{"rendered":"<p><a href=\"http:\/\/blogs.plymouth.ac.uk\/embedded-systems\/mbed-os-2\/courses\/embedded-systems-in-context-level-4\/\">Back to ToC<\/a><\/p>\n<hr \/>\n<p>This is section,we look at ways to output <a href=\"http:\/\/blogs.plymouth.ac.uk\/embedded-systems\/glossary-2\/glossary\/\" target=\"_blank\" rel=\"noopener\">analogue signals.<\/a> For this we use two techniques: <a href=\"http:\/\/blogs.plymouth.ac.uk\/embedded-systems\/glossary-2\/pulse-width-modulation-pwm-glossary-entry\/\" target=\"_blank\" rel=\"noopener\">Pulse Width Modulation (PWM)<\/a> and a <a href=\"http:\/\/blogs.plymouth.ac.uk\/embedded-systems\/glossary-2\/digital-to-analogue-converter-dac-glossary-entry\/\" target=\"_blank\" rel=\"noopener\">Digital to Analogue Converter (DAC)<\/a>. The microcontroller we are using does in fact have an on-chip DAC, but as no all devices do, we have included an example of interfacing to an external device. We achieve this using an industry de facto standard known as the Serial Peripheral Interface (SPI).<\/p>\n<h1>Intended Learning Outcomes<\/h1>\n<ol>\n<li>Define the meaning of PWM and calculate the RMS voltage of a PWM signal<\/li>\n<li>Use PWM to create a known average voltage<\/li>\n<li>Program a PWM peripheral<\/li>\n<li>Program the internal DAC with the DigitalOut class<\/li>\n<li>Use the SPI interface to interface to an external DAC<\/li>\n<\/ol>\n<hr \/>\n<h1>Activity 5.1 Pulse Width Modulation (PWM)<\/h1>\n<p><a href=\"http:\/\/blogs.plymouth.ac.uk\/embedded-systems\/glossary-2\/pulse-width-modulation-pwm-glossary-entry\/\">Pulse Width Modulation<\/a> (or PWM) is a simple technique used to generate an alternating voltage signal with an known \u201caverage DC voltage\u201d. The technique is commonly used in control systems, including the control of DC motors.<\/p>\n<h2>TASK 5.1.1<\/h2>\n<table style=\"border-collapse: collapse;border: 1px solid black\" cellspacing=\"0\" cellpadding=\"0\">\n<tbody>\n<tr>\n<td valign=\"middle\">Read the <a href=\"http:\/\/blogs.plymouth.ac.uk\/embedded-systems\/glossary-2\/pulse-width-modulation-pwm-glossary-entry\/\" target=\"_blank\" rel=\"noopener\">glossary entry on PWM<\/a><\/td>\n<\/tr>\n<tr>\n<td valign=\"middle\">\u00a0Attempt the short quiz below.<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>&nbsp;<\/p>\n<p>Q1.For a PWM system, using a pulse of 1V, <img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/blogs.plymouth.ac.uk\/embedded-systems\/wp-content\/ql-cache\/quicklatex.com-17e7c1f9a17d715088c61be699f37a5f_l3.png\" class=\"ql-img-inline-formula quicklatex-auto-format\" alt=\"&#84;&#61;&#49;&#48;&#48;&#32;&#92;&#109;&#117;&#32;&#115;\" title=\"Rendered by QuickLaTeX.com\" height=\"16\" width=\"82\" style=\"vertical-align: -4px;\"\/> and <img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/blogs.plymouth.ac.uk\/embedded-systems\/wp-content\/ql-cache\/quicklatex.com-121c387d9fc1009c612e8433674b54e0_l3.png\" class=\"ql-img-inline-formula quicklatex-auto-format\" alt=\"&#84;&#95;&#123;&#109;&#97;&#114;&#107;&#125;&#32;&#61;&#32;&#49;&#48;&#32;&#92;&#109;&#117;&#32;&#115;\" title=\"Rendered by QuickLaTeX.com\" height=\"16\" width=\"105\" style=\"vertical-align: -4px;\"\/>, which of the following is true?<br \/>\n(hover your mouse over the correct answer).<br \/>\n<a style=\"cursor: help\" title=\"Incorrect\">A. The duty is 0.1%<\/a><br \/>\n<a style=\"cursor: help\" title=\"CORRECT\">B. The duty is 10%<\/a><br \/>\n<a style=\"cursor: help\" title=\"Incorrect\">C. The mean voltage is 0.1\u03bcV<\/a><br \/>\n<a style=\"cursor: help\" title=\"Incorrect\">D. The mean voltage is 10V<\/a><\/p>\n<p>Q2. For a PWM system, using a pulse of 10V, <img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/blogs.plymouth.ac.uk\/embedded-systems\/wp-content\/ql-cache\/quicklatex.com-609a331078f5c5855383838921d6b7c3_l3.png\" class=\"ql-img-inline-formula quicklatex-auto-format\" alt=\"&#84;&#61;&#49;&#48;&#48;&#32;&#92;&#32;&#109;&#115;\" title=\"Rendered by QuickLaTeX.com\" height=\"12\" width=\"93\" style=\"vertical-align: 0px;\"\/> and <img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/blogs.plymouth.ac.uk\/embedded-systems\/wp-content\/ql-cache\/quicklatex.com-fe2da65e0cfd55ef1999e25b8ea45e12_l3.png\" class=\"ql-img-inline-formula quicklatex-auto-format\" alt=\"&#84;&#95;&#123;&#109;&#97;&#114;&#107;&#125;&#61;&#49;&#32;&#92;&#32;&#109;&#115;\" title=\"Rendered by QuickLaTeX.com\" height=\"15\" width=\"107\" style=\"vertical-align: -3px;\"\/>, what is the mean voltage?<\/p>\n<p><a title=\"CORRECT\">A. 0.1V%<\/a><br \/>\n<a title=\"Incorrect\">B. 1V<\/a><br \/>\n<a title=\"Incorrect\">C. 10V<\/a><br \/>\n<a title=\"Incorrect\">D. 100V<\/a><\/p>\n<p>Q3. For a PWM system driving a DC motor, using a pulse of 5V, <img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/blogs.plymouth.ac.uk\/embedded-systems\/wp-content\/ql-cache\/quicklatex.com-3a6dc76e49d5ddb298b240ad5a433023_l3.png\" class=\"ql-img-inline-formula quicklatex-auto-format\" alt=\"&#84;&#61;&#49;&#32;&#92;&#32;&#109;&#115;\" title=\"Rendered by QuickLaTeX.com\" height=\"12\" width=\"75\" style=\"vertical-align: 0px;\"\/> and <img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/blogs.plymouth.ac.uk\/embedded-systems\/wp-content\/ql-cache\/quicklatex.com-dec3bb20e96fef4f82567eff5f295019_l3.png\" class=\"ql-img-inline-formula quicklatex-auto-format\" alt=\"&#84;&#95;&#123;&#115;&#112;&#97;&#99;&#101;&#125;&#61;&#53;&#48;&#48;&#32;&#92;&#109;&#117;&#32;&#83;\" title=\"Rendered by QuickLaTeX.com\" height=\"19\" width=\"118\" style=\"vertical-align: -6px;\"\/>, which of the following is true?<\/p>\n<p><a title=\"CORRECT\">A. The choice of T means motor would be louder than applying a constant voltage<\/a><br \/>\n<a title=\"Incorrect\">B. This makes no sense as T<sub>mark<\/sub> &gt; T<\/a><br \/>\n<a title=\"Incorrect\">C. The output voltage would be 3.3V<\/a><br \/>\n<a title=\"Incorrect\">D. The duty is 20%<\/a><\/p>\n<h1>Activity 5.2 Pulse Width Modulation (PWM) with Timers<\/h1>\n<p>In this task we will implement PWM using a a simple timer.<\/p>\n<table style=\"border-collapse: collapse;border: 1px solid black\" cellspacing=\"0\" cellpadding=\"0\">\n<tbody>\n<tr>\n<td valign=\"middle\">Build and run the code shown below (also on mbed)<\/td>\n<\/tr>\n<tr>\n<td valign=\"middle\">What are the ON and OFF times?<\/td>\n<\/tr>\n<tr>\n<td valign=\"middle\">Try different values of R<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<pre class=\"lang:c++ decode:true\">#include \"mbed.h\"\r\n\r\n\/\/Time period\r\n#define T 0.001\r\n\r\n\/\/Mark-Space Ratio\r\n#define R 0.1\r\n\r\n\/\/Mark and Space times\r\n#define Tmark (R*T)\r\n#define Tspace ((1.0-R)*T)\r\n\r\nDigitalOut onboardLed(LED1);\r\nDigitalOut redLED(D7);\r\n\r\nint main() {\r\n   printf(\"\\nWelcome to ELEC143\\n\");\r\n   \r\n   while (1) {\r\n      redLED = 0; \/\/Space\r\n      wait(Tspace);\r\n      redLED = 1;\t\/\/Mark\r\n      wait(Tmark);\r\n   }\r\n}<\/pre>\n<h2>Task 5.2.2<\/h2>\n<p>Perform the following:<\/p>\n<table style=\"border-collapse: collapse;border: 1px solid black\" cellspacing=\"0\" cellpadding=\"0\">\n<tbody>\n<tr>\n<td valign=\"middle\">Now try and modify task 5.2.1 to also <b>independently<\/b> set the brightness of the green LED. <em>If you spend more that 10 minutes on this task<\/em>, maybe stop. The point of this exercise is to illustrate the difficulty (there is an easier way)!<\/td>\n<\/tr>\n<tr>\n<td valign=\"middle\">If you have succeeded, consider how you might now also control the brightness of the yellow LED?<\/td>\n<\/tr>\n<tr>\n<td valign=\"middle\">Describe what problems you encounter<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>There are many ways to try and solve this problem. I have gone for a <a href=\"https:\/\/os.mbed.com\/teams\/Students-Plymouth-University-UK-SoCEM\/code\/Task522Solution\/file\/4e6cbb427cd7\/main.cpp\" target=\"_blank\" rel=\"noopener\">solution<\/a> that uses timer interrupts (although even this is not perfect).<\/p>\n<p>What you might find is that your solution does not \u201cscale\u201d beyond one or two LEDs. One of the fundamental problems here is that the wait statement is \u201cblocking\u201d (you cannot do anything else unless you use an interrupt).<\/p>\n<p>There are a number of elegant solutions. Timers are one possibility (as I have used), but you might want to reserve those timers for other tasks. I\u2019ve kept the interrupt routines as short as possible to avoid latency issues (in the event two overlap in time such that one has to wait for the other to finish).<span class=\"Apple-converted-space\">\u00a0<\/span><\/p>\n<p>Luckily, PWM is a common requirement and this problem was recognized a long time ago, and this microcontroller comes with PWM controllers built in! These controllers have their own timers and logic to control the output, so all run independently in parallel.<span class=\"Apple-converted-space\">\u00a0<\/span><\/p>\n<p><b>Remember:<\/b> a single core microcontroller can only really execute one instruction at a time. Any attempt at multitasking is always an illusion and often comes with compromises.<span class=\"Apple-converted-space\">\u00a0<\/span><\/p>\n<p>Look at the code below to see how simple it is to use a PWM in Mbed-os on this device. Note for the F429 board, I&#8217;ve moved the RED LED to pin D6. You should modify your hardware accordingly.<\/p>\n<pre class=\"lang:c++ decode:true\">#include \"mbed.h\"\r\n\r\nDigitalOut OnBoardLed(LED1);\r\n\r\n#ifdef TARGET_NUCLEO_F429ZI\r\nPwmOut pwmRed(D6);  \/\/D7 is not a PWM output on the F429, so use D6 instead\r\n#else\r\nPwmOut pwmRed(D7);\r\n#endif\r\n\r\nint T = 10;\r\nint Tmark = 5;\r\n\r\nint main() {\r\n    \r\n    pwmRed.period_us(T);\r\n    pwmRed.pulsewidth_us(Tmark);\r\n    \r\n    while(1) {\r\n        \/\/Heartbeat\r\n        wait(1);\r\n        OnBoardLed = !OnBoardLed;\r\n    }\r\n}<\/pre>\n<p>The following should be noted:<\/p>\n<ul>\n<li>Not all pins support PWM. See the <a href=\"https:\/\/os.mbed.com\/platforms\/ST-Nucleo-F429ZI\/\">Mbed hardware page<\/a> for this board or the figure below (colour coded purple)<\/li>\n<li>The <code>sleep()<\/code> function may be woken periodically by interrupts. This will be covered in level 6 when we discuss real-time operating systems.<\/li>\n<\/ul>\n<figure id=\"attachment_586\" aria-describedby=\"caption-attachment-586\" style=\"width: 1280px\" class=\"wp-caption aligncenter\"><img loading=\"lazy\" decoding=\"async\" class=\"size-full wp-image-586\" src=\"http:\/\/blogs.plymouth.ac.uk\/embedded-systems\/wp-content\/uploads\/sites\/94\/2018\/10\/nucleo_f429zi_2017-07-25_slide4.png\" alt=\"\" width=\"1280\" height=\"960\" srcset=\"https:\/\/blogs.plymouth.ac.uk\/embedded-systems\/wp-content\/uploads\/sites\/94\/2018\/10\/nucleo_f429zi_2017-07-25_slide4.png 1280w, https:\/\/blogs.plymouth.ac.uk\/embedded-systems\/wp-content\/uploads\/sites\/94\/2018\/10\/nucleo_f429zi_2017-07-25_slide4-300x225.png 300w, https:\/\/blogs.plymouth.ac.uk\/embedded-systems\/wp-content\/uploads\/sites\/94\/2018\/10\/nucleo_f429zi_2017-07-25_slide4-768x576.png 768w, https:\/\/blogs.plymouth.ac.uk\/embedded-systems\/wp-content\/uploads\/sites\/94\/2018\/10\/nucleo_f429zi_2017-07-25_slide4-1024x768.png 1024w\" sizes=\"auto, (max-width: 1280px) 100vw, 1280px\" \/><figcaption id=\"caption-attachment-586\" class=\"wp-caption-text\">Showing the Pin Connections on CN7 connector for the Nucleo FZ420ZI. Note which pins support PWM (purple)<\/figcaption><\/figure>\n<h2>Task 5.2.3<\/h2>\n<p>Complete the following:<\/p>\n<table style=\"border-collapse: collapse;border: 1px solid black\" cellspacing=\"0\" cellpadding=\"0\">\n<tbody>\n<tr>\n<td valign=\"middle\">Using a Ticker object, make the red LED slowly brighten and dim (check the pin can be used for PWM)<\/td>\n<\/tr>\n<tr>\n<td valign=\"middle\">(you need to smoothly ramp the value of Tmark up and down between 0 and T)<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p><a href=\"https:\/\/os.mbed.com\/teams\/Students-Plymouth-University-UK-SoCEM\/code\/Task523Solution-FZ429ZI\/\">My solution is here<\/a><\/p>\n<h2>Additional Task 5.2.4<\/h2>\n<p>If you have time, try the following:<\/p>\n<table style=\"border-collapse: collapse;border: 1px solid black\" cellspacing=\"0\" cellpadding=\"0\">\n<tbody>\n<tr>\n<td valign=\"middle\">Modify the solution in 5.2.3 to use the mathematical sine (sin) function instead of a linear ramp.<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p><a href=\"https:\/\/os.mbed.com\/teams\/Students-Plymouth-University-UK-SoCEM\/code\/Task524Solution-FZ429\/\">A solution is provided here.<\/a><\/p>\n<h2>Advanced Task 5.2.5<\/h2>\n<p>If you feel confident, maybe try the following:<\/p>\n<table style=\"border-collapse: collapse;border: 1px solid black\" cellspacing=\"0\" cellpadding=\"0\">\n<tbody>\n<tr>\n<td valign=\"middle\">Write some code uses two switches to switch the red LED on and OFF.<\/td>\n<\/tr>\n<tr>\n<td valign=\"middle\">Press SW1 and the LED fades ON to full brightness<\/td>\n<\/tr>\n<tr>\n<td valign=\"middle\">Press SW2 and the LED fades OFF<\/td>\n<\/tr>\n<tr>\n<td valign=\"middle\">Use a PWM object to achieve this<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p><a href=\"https:\/\/os.mbed.com\/teams\/Students-Plymouth-University-UK-SoCEM\/code\/Task525Solution-FZ429\/\">A solution is provided here<\/a>.<\/p>\n<h2>Digital to Analogue Conversion<\/h2>\n<p>PWM is a popular solution for a number of reasons. One reason is that it is relatively simply to connect the microcontroller PWM output directly to power transistors. Such devices are capable of switching the large currents involved in applications such as DC motor control.<\/p>\n<p>You might want to read the <a href=\"http:\/\/blogs.plymouth.ac.uk\/embedded-systems\/glossary-2\/h-bridge-glossary-entry\/\" target=\"_blank\" rel=\"noopener\">glossary entry on the <b>H-Bridge<\/b><\/a><\/p>\n<blockquote><p><b>Important:<\/b> you must NEVER connect a the microcontroller pin directly to a DC motor. It cannot supply sufficient current and you may even damage the microcontroller!<\/p><\/blockquote>\n<p>The downside of PWM is that in the absence of additional electronics, the output is pulsed. What if you wanted to generate a smooth audio output signal, such as a sinewave?<span class=\"Apple-converted-space\">\u00a0<\/span>With careful design and additional electronics, you can use a PWM for some applications, but a superior solution is to use a <a href=\"http:\/\/blogs.plymouth.ac.uk\/embedded-systems\/glossary-2\/digital-to-analogue-converter-dac-glossary-entry\/\" target=\"_blank\" rel=\"noopener\">Digital to Analogue Converter (DAC)<\/a>.<\/p>\n<p>Some micro controllers have an on-chip DAC. Alternatively you might use an external device, especially if you want something more specialist (e.g. for professional audio). As we have an internal DAC on the STM32F429ZI, we will use this first. Then we will look at using an external device.<\/p>\n<h2>Task 5.2.6 Digital Output with DigitalOut<\/h2>\n<p>The micro controller you are using in these labs has an on-chip 12-bit DAC. The Mbed-os library provides an object <code>AnalogOut<\/code> which encapsulates all the necessary code to access the DAC.<\/p>\n<p>Complete the following:<\/p>\n<table style=\"border-collapse: collapse;border: 1px solid black\" cellspacing=\"0\" cellpadding=\"0\">\n<tbody>\n<tr>\n<td valign=\"middle\"><span style=\"color: #4d4d4d;font-family: 'Helvetica Neue Light';font-size: medium\">Modify the code below to generate a 5Hz sinusoidal tone (use the sin function).<\/span><\/td>\n<\/tr>\n<tr>\n<td valign=\"middle\"><span style=\"color: #4d4d4d;font-family: 'Helvetica Neue Light';font-size: medium\">Observe the output on the scope to check the frequency<\/span><\/td>\n<\/tr>\n<tr>\n<td valign=\"middle\"><span style=\"color: #4d4d4d;font-family: 'Helvetica Neue Light';font-size: medium\">If you zoom in close, see the quantisation of the signal?<\/span><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<pre class=\"lang:c++ decode:true \">#include \"mbed.h\"\r\n#include \u201cmath.h\"\r\n\r\nAnalogOut  aOut(PA_5);\r\n\r\nint main(void) {\r\n    while (true) {\r\n       for (float i=0.0f; i&lt;1.0f; i+=0.01f) {\r\n           aOut = i;\r\n           wait(0.001f);  \/\/approx. 1kHz\r\n        }\r\n    }\r\n}<\/pre>\n<p>This code is very simple thanks to the <code>AnalogOut<\/code> class.<\/p>\n<blockquote><p>It should be pointed out that this code is written for simplicity as opposed to precision &#8211; the rate at which the samples are converted is not particularly consistent so this does not reflect best practise<\/p><\/blockquote>\n<h1>Activity 5.3 Using an external DAC<\/h1>\n<p>For this section, we are going to use\u00a0an 8-pin MCP4921 12-bit DAC from <a href=\"http:\/\/www.microchip.com\/wwwproducts\/Devices.aspx?product=MCP4921\">Microchip<\/a>\u00a0as depicted in the figure below:<\/p>\n<figure id=\"attachment_571\" aria-describedby=\"caption-attachment-571\" style=\"width: 400px\" class=\"wp-caption aligncenter\"><img loading=\"lazy\" decoding=\"async\" class=\"wp-image-571\" src=\"http:\/\/blogs.plymouth.ac.uk\/embedded-systems\/wp-content\/uploads\/sites\/94\/2018\/10\/MCP4921.png\" alt=\"\" width=\"400\" height=\"338\" srcset=\"https:\/\/blogs.plymouth.ac.uk\/embedded-systems\/wp-content\/uploads\/sites\/94\/2018\/10\/MCP4921.png 843w, https:\/\/blogs.plymouth.ac.uk\/embedded-systems\/wp-content\/uploads\/sites\/94\/2018\/10\/MCP4921-300x253.png 300w, https:\/\/blogs.plymouth.ac.uk\/embedded-systems\/wp-content\/uploads\/sites\/94\/2018\/10\/MCP4921-768x649.png 768w\" sizes=\"auto, (max-width: 400px) 100vw, 400px\" \/><figcaption id=\"caption-attachment-571\" class=\"wp-caption-text\">MCP4921 12-Bit DAC. note the position of pin 1 relative to the cutout in the package (or dot).<\/figcaption><\/figure>\n<p>The circle on the package indicates PIN 1. The device we are using is a <b>D<\/b>ual <b>I<\/b>nline <b>P<\/b>ackage (<a href=\"https:\/\/en.wikipedia.org\/wiki\/Dual_in-line_package\">DIP<\/a>) which is compatible with prototyping boards. More compact versions are also available if you review the <a href=\"http:\/\/ww1.microchip.com\/downloads\/en\/DeviceDoc\/22248a.pdf\">data sheet<\/a>.<\/p>\n<figure id=\"attachment_572\" aria-describedby=\"caption-attachment-572\" style=\"width: 1814px\" class=\"wp-caption aligncenter\"><img loading=\"lazy\" decoding=\"async\" class=\"size-full wp-image-572\" src=\"http:\/\/blogs.plymouth.ac.uk\/embedded-systems\/wp-content\/uploads\/sites\/94\/2018\/10\/ExternalDAC.png\" alt=\"\" width=\"1814\" height=\"1833\" srcset=\"https:\/\/blogs.plymouth.ac.uk\/embedded-systems\/wp-content\/uploads\/sites\/94\/2018\/10\/ExternalDAC.png 1814w, https:\/\/blogs.plymouth.ac.uk\/embedded-systems\/wp-content\/uploads\/sites\/94\/2018\/10\/ExternalDAC-297x300.png 297w, https:\/\/blogs.plymouth.ac.uk\/embedded-systems\/wp-content\/uploads\/sites\/94\/2018\/10\/ExternalDAC-768x776.png 768w, https:\/\/blogs.plymouth.ac.uk\/embedded-systems\/wp-content\/uploads\/sites\/94\/2018\/10\/ExternalDAC-1013x1024.png 1013w, https:\/\/blogs.plymouth.ac.uk\/embedded-systems\/wp-content\/uploads\/sites\/94\/2018\/10\/ExternalDAC-989x999.png 989w\" sizes=\"auto, (max-width: 1814px) 100vw, 1814px\" \/><figcaption id=\"caption-attachment-572\" class=\"wp-caption-text\">Here we see the MCP4921 12-bit DAC connected via the <b>SPI<\/b> interface. Note also that the power rails have been extended all around the prototyping board. When you do this, BE CAREFUL to get it right before you plug in your Nucleo board. Decoupling capacitors are not shown but strictly should be added.<\/figcaption><\/figure>\n<p>The relevant part of the schematic is shown below<\/p>\n<figure id=\"attachment_574\" aria-describedby=\"caption-attachment-574\" style=\"width: 450px\" class=\"wp-caption aligncenter\"><img loading=\"lazy\" decoding=\"async\" class=\"wp-image-574\" src=\"http:\/\/blogs.plymouth.ac.uk\/embedded-systems\/wp-content\/uploads\/sites\/94\/2018\/10\/SPI_DAC_Schematic.png\" alt=\"\" width=\"450\" height=\"327\" srcset=\"https:\/\/blogs.plymouth.ac.uk\/embedded-systems\/wp-content\/uploads\/sites\/94\/2018\/10\/SPI_DAC_Schematic.png 1197w, https:\/\/blogs.plymouth.ac.uk\/embedded-systems\/wp-content\/uploads\/sites\/94\/2018\/10\/SPI_DAC_Schematic-300x218.png 300w, https:\/\/blogs.plymouth.ac.uk\/embedded-systems\/wp-content\/uploads\/sites\/94\/2018\/10\/SPI_DAC_Schematic-768x558.png 768w, https:\/\/blogs.plymouth.ac.uk\/embedded-systems\/wp-content\/uploads\/sites\/94\/2018\/10\/SPI_DAC_Schematic-1024x744.png 1024w\" sizes=\"auto, (max-width: 450px) 100vw, 450px\" \/><figcaption id=\"caption-attachment-574\" class=\"wp-caption-text\">Connecting a MCU to an external DAC over SPI<\/figcaption><\/figure>\n<p>In this schematic, we see the SPI interface.<\/p>\n<ul>\n<li>The Microcontroller is the master device<\/li>\n<li>The MCP4921 DAC is the slave<\/li>\n<\/ul>\n<p>Data is sent one bit at a time from MOSI of the MCU to the MOSI pin of the DAC. To synchronise this, a serial <b>clock<\/b> is used SCLK. Many SPI devices can be connected, but only one slave device can be selected. We pull the Chip Select (CS) LOW to enable it. This is connected to a GPIO pin D10.<\/p>\n<h2>Task 5.3.1<\/h2>\n<p>Perform the following tasks:<\/p>\n<table style=\"border-collapse: collapse;border: 1px solid black\" cellspacing=\"0\" cellpadding=\"0\">\n<tbody>\n<tr>\n<td>TEMPORARILY remove JP6 from your Nucleo Board (to avoid a collision between the Ethernet and the SPI pin D11). Remember to replace it after this experiment!<\/td>\n<\/tr>\n<tr>\n<td valign=\"middle\">Wire up the MCP4921 as shown above<\/td>\n<\/tr>\n<tr>\n<td valign=\"middle\">Build and run the code below<\/td>\n<\/tr>\n<tr>\n<td valign=\"middle\">Using a multimeter, measure the voltage output (PIN8) of the MCP4921<\/td>\n<\/tr>\n<tr>\n<td valign=\"middle\">For an unsigned 12-bit data value, what is the maximum possible value in decimal and HEX?<\/td>\n<\/tr>\n<tr>\n<td valign=\"middle\">Try changing the variable <code>val<\/code> to the maximum and minimum 12-bit values. Do the output voltages correspond?<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<pre class=\"lang:c++ decode:true\">#include \"mbed.h\"\r\n\r\n\/\/This GPIO is used for Chip Select\r\nDigitalOut DAC_CS(D10);\r\n\r\n\/\/Status LED\r\nDigitalOut led(LED1,1);\r\n\r\n\/\/SPI Object (temporarily remove JP6 when running this)\r\nSPI spi(D11, D12, D13);\r\n\r\n\/\/Ticker for setting the output sampling rate\r\nTicker t;\r\n\r\n\/\/Prototype for the ticker ISR\r\nvoid writeSample();\r\n\r\nint main() {\r\n\r\n    \/\/Set speed of the SPI interface\r\n    spi.frequency(20000);\r\n    \r\n    \/\/16 bit words, mode 0 clock\r\n    spi.format(16,0);\r\n    \r\n    \/\/Write at 1000Hz    \r\n    t.attach(writeSample, 0.001);\r\n    \r\n    while(1) {\r\n        sleep();\r\n    }\r\n}\r\n\r\n\/\/ISR for ticker\r\nvoid writeSample()\r\n{\r\n    \/\/Enable the selected slave device\r\n    DAC_CS = 0;\r\n    \r\n    \/\/Write a header (top 4 bits) and value (bottom 12 bits) \r\n    unsigned int val = 2048;\r\n    spi.write(0x7000 | val);\r\n    \r\n    \/\/Disable the selected slave device (and update the output)\r\n    DAC_CS = 1;\r\n    \r\n    \/\/Status\r\n    led = !led;\r\n}<\/pre>\n<h2>Task 5.3.2<\/h2>\n<p>Perform the following if you have time:<\/p>\n<table style=\"border-collapse: collapse;border: 1px solid black\" cellspacing=\"0\" cellpadding=\"0\">\n<tbody>\n<tr>\n<td valign=\"middle\">Modify the code in 5.3.1 to generate a 100Hz sinusoid waveform, and show it on the scope<\/td>\n<\/tr>\n<tr>\n<td valign=\"middle\">The frequency of the wave is f=10Hz<\/p>\n<p>The output rate Fs = 1000, and T=1\/Fs<\/p>\n<p>If n is discrete time (increments every T seconds)<\/p>\n<p>PI=3.1415926<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/blogs.plymouth.ac.uk\/embedded-systems\/wp-content\/ql-cache\/quicklatex.com-f1ec10ad6d22d37e470c7e60c57c0849_l3.png\" class=\"ql-img-inline-formula quicklatex-auto-format\" alt=\"&#121;&#40;&#110;&#41;&#61;&#99;&#111;&#115;&#40;&#50;&#42;&#32;&#92;&#112;&#105;&#32;&#42;&#110;&#42;&#102;&#42;&#84;&#41;\" title=\"Rendered by QuickLaTeX.com\" height=\"19\" width=\"215\" style=\"vertical-align: -5px;\"\/> where <img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/blogs.plymouth.ac.uk\/embedded-systems\/wp-content\/ql-cache\/quicklatex.com-e105bf527d4a0adc88ce372e94711c16_l3.png\" class=\"ql-img-inline-formula quicklatex-auto-format\" alt=\"&#92;&#112;&#105;&#61;&#51;&#46;&#49;&#52;&#49;&#53;&#57;&#50;&#54;&#53;&#52;&#49;\" title=\"Rendered by QuickLaTeX.com\" height=\"13\" width=\"137\" style=\"vertical-align: 0px;\"\/>.<\/p>\n<p>Note <img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/blogs.plymouth.ac.uk\/embedded-systems\/wp-content\/ql-cache\/quicklatex.com-ab82adefea941328c4ec96f8e10bb2b0_l3.png\" class=\"ql-img-inline-formula quicklatex-auto-format\" alt=\"&#121;&#40;&#110;&#41;\" title=\"Rendered by QuickLaTeX.com\" height=\"19\" width=\"33\" style=\"vertical-align: -5px;\"\/> will range from -1.0 to +1.0, so you need to offset and scale to a 12-bit range.<\/td>\n<\/tr>\n<tr>\n<td valign=\"middle\">View the result on the scope (you should see something similar to the diagram below)<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<figure id=\"attachment_577\" aria-describedby=\"caption-attachment-577\" style=\"width: 600px\" class=\"wp-caption aligncenter\"><img loading=\"lazy\" decoding=\"async\" class=\"wp-image-577\" src=\"http:\/\/blogs.plymouth.ac.uk\/embedded-systems\/wp-content\/uploads\/sites\/94\/2018\/10\/ScopeOutputSinusoid.png\" alt=\"\" width=\"600\" height=\"250\" srcset=\"https:\/\/blogs.plymouth.ac.uk\/embedded-systems\/wp-content\/uploads\/sites\/94\/2018\/10\/ScopeOutputSinusoid.png 929w, https:\/\/blogs.plymouth.ac.uk\/embedded-systems\/wp-content\/uploads\/sites\/94\/2018\/10\/ScopeOutputSinusoid-300x125.png 300w, https:\/\/blogs.plymouth.ac.uk\/embedded-systems\/wp-content\/uploads\/sites\/94\/2018\/10\/ScopeOutputSinusoid-768x320.png 768w\" sizes=\"auto, (max-width: 600px) 100vw, 600px\" \/><figcaption id=\"caption-attachment-577\" class=\"wp-caption-text\">Scope output for the MCP4921 DAC. Note the timebase on the scope is 50ms\/division.<\/figcaption><\/figure>\n<p><a href=\"https:\/\/os.mbed.com\/teams\/Students-Plymouth-University-UK-SoCEM\/code\/Task532Solution\/file\/c616f46e44a5\/main.cpp\" target=\"_blank\" rel=\"noopener\">A solution is available<\/a>.<\/p>\n<h2>Task 5.3.3<\/h2>\n<p>Perform the following tasks:<\/p>\n<table style=\"border-collapse: collapse;border: 1px solid black\" cellspacing=\"0\" cellpadding=\"0\">\n<tbody>\n<tr>\n<td valign=\"middle\">Build and run the <a href=\"https:\/\/os.mbed.com\/teams\/Students-Plymouth-University-UK-SoCEM\/code\/Task532Solution\/file\/c616f46e44a5\/main.cpp\" target=\"_blank\" rel=\"noopener\">solution to 5.3.2<\/a><\/td>\n<\/tr>\n<tr>\n<td valign=\"middle\">Now change the frequency f to 100Hz<\/td>\n<\/tr>\n<tr>\n<td valign=\"middle\">What do you notice? If this was an audio tone, do you think it would sound good?<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p><!--more--><\/p>\n<p>Below is the output viewed on a scope. Two things are more clearly visible here:<\/p>\n<ul>\n<li>Quantisation &#8211; the steps are clearly visible here. We sometimes call this an \u201cartifact\u201d created by the electronics and\/or software<\/li>\n<li>Noise &#8211; for each step, you can visibly see noise superimposed on top of the waveform. Noise is not created by the software, but might be a property of the electronics and needs to be reduced. Often it is interference from other electrical systems.<\/li>\n<\/ul>\n<p>This is clearly not a perfect 100Hz sinusoid, so is not going to sound like one if played through an amplifier and speaker. There are some steps we could (and probably should) now take:<\/p>\n<ul>\n<li>Ensure \u201cde-coupling capacitors\u201d are used on the power-supplies of all switching devices. This maintains a smooth DC power supply for each device .<\/li>\n<li>\u201cFilter\u201d the output to make it smoother. For this, we need additional electronics.<\/li>\n<\/ul>\n<p>You can (and will) use mathematics to better predict and understand the quantisation noise, and design electronic \u201cfilters\u201d to significantly reduce unwanted components. In this application, they are known as \u201canti-imaging\u201d filters. Strictly speaking, we should also use similar filters for the ADC as well.<\/p>\n<figure id=\"attachment_578\" aria-describedby=\"caption-attachment-578\" style=\"width: 1492px\" class=\"wp-caption aligncenter\"><img loading=\"lazy\" decoding=\"async\" class=\"size-full wp-image-578\" src=\"http:\/\/blogs.plymouth.ac.uk\/embedded-systems\/wp-content\/uploads\/sites\/94\/2018\/10\/QuantisedScopeOutputSinusoid.png\" alt=\"\" width=\"1492\" height=\"869\" srcset=\"https:\/\/blogs.plymouth.ac.uk\/embedded-systems\/wp-content\/uploads\/sites\/94\/2018\/10\/QuantisedScopeOutputSinusoid.png 1492w, https:\/\/blogs.plymouth.ac.uk\/embedded-systems\/wp-content\/uploads\/sites\/94\/2018\/10\/QuantisedScopeOutputSinusoid-300x175.png 300w, https:\/\/blogs.plymouth.ac.uk\/embedded-systems\/wp-content\/uploads\/sites\/94\/2018\/10\/QuantisedScopeOutputSinusoid-768x447.png 768w, https:\/\/blogs.plymouth.ac.uk\/embedded-systems\/wp-content\/uploads\/sites\/94\/2018\/10\/QuantisedScopeOutputSinusoid-1024x596.png 1024w\" sizes=\"auto, (max-width: 1492px) 100vw, 1492px\" \/><figcaption id=\"caption-attachment-578\" class=\"wp-caption-text\">Illustrating the quantised output of the DAC<\/figcaption><\/figure>\n<p>&nbsp;<\/p>\n<blockquote><p><strong>REMEMBER to replace JP6 when you&#8217;ve completed the SPI tasks.<\/strong><\/p><\/blockquote>\n<p>&nbsp;<\/p>\n<hr \/>\n<p><a href=\"http:\/\/blogs.plymouth.ac.uk\/embedded-systems\/mbed-os-2\/courses\/embedded-systems-in-context-level-4\/\">Back to ToC<\/a><\/p>\n<p>[contact-form][contact-field label=&#8221;Name&#8221; type=&#8221;name&#8221; required=&#8221;true&#8221; \/][contact-field label=&#8221;Email&#8221; type=&#8221;email&#8221; required=&#8221;true&#8221; \/][contact-field label=&#8221;Website&#8221; type=&#8221;url&#8221; \/][contact-field label=&#8221;Message&#8221; type=&#8221;textarea&#8221; \/][\/contact-form]<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Back to ToC This is section,we look at ways to output analogue signals. For this we use two techniques: Pulse Width Modulation (PWM) and a Digital to Analogue Converter (DAC). The microcontroller we are using does in fact have an on-chip DAC, but as no all devices do, we have included an example of interfacing&hellip; <a class=\"more-link\" href=\"https:\/\/blogs.plymouth.ac.uk\/embedded-systems\/microcontrollers\/mbed-os-2\/courses\/embedded-systems-in-context-level-4\/topic-5-analogue-output\/\">Continue reading <span class=\"screen-reader-text\">Topic 5 &#8211; Analogue Output (introduction)<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"parent":130,"menu_order":5,"comment_status":"closed","ping_status":"closed","template":"","meta":{"footnotes":""},"class_list":["post-502","page","type-page","status-publish","hentry","entry"],"_links":{"self":[{"href":"https:\/\/blogs.plymouth.ac.uk\/embedded-systems\/wp-json\/wp\/v2\/pages\/502","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blogs.plymouth.ac.uk\/embedded-systems\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/blogs.plymouth.ac.uk\/embedded-systems\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/blogs.plymouth.ac.uk\/embedded-systems\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/blogs.plymouth.ac.uk\/embedded-systems\/wp-json\/wp\/v2\/comments?post=502"}],"version-history":[{"count":34,"href":"https:\/\/blogs.plymouth.ac.uk\/embedded-systems\/wp-json\/wp\/v2\/pages\/502\/revisions"}],"predecessor-version":[{"id":710,"href":"https:\/\/blogs.plymouth.ac.uk\/embedded-systems\/wp-json\/wp\/v2\/pages\/502\/revisions\/710"}],"up":[{"embeddable":true,"href":"https:\/\/blogs.plymouth.ac.uk\/embedded-systems\/wp-json\/wp\/v2\/pages\/130"}],"wp:attachment":[{"href":"https:\/\/blogs.plymouth.ac.uk\/embedded-systems\/wp-json\/wp\/v2\/media?parent=502"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}