Silicon ChipMicromite Plus Advanced Programming, Pt.2 - December 2016 SILICON CHIP
  1. Outer Front Cover
  2. Contents
  3. Publisher's Letter: Controversial topics should be able to be discussed
  4. Feature: A Look At Nuclear Submarines by Dr David Maddison
  5. Project: Automotive Sensor Modifier by John Clarke
  6. Feature: Keep Track Of Anything With TrackR by Ross Tester
  7. Feature: Altronics: 40 Years And Going Strong by Leo Simpson
  8. Project: Arduino-Based Digital Theremin by Bao Smith
  9. Product Showcase
  10. Serviceman's Log: Two crook MacBook Pro laptops by Dave Thompson
  11. Project: Voltage/Current Reference With Touchscreen, Pt.2 by Nicholas Vinen
  12. Feature: Micromite Plus Advanced Programming, Pt.2 by Geoff Graham
  13. Project: El Cheapo Modules From Asia - Part 2 by Jim Rowe
  14. Subscriptions
  15. Vintage Radio: Grundig’s 1958 Taschen-Transistor-Boy 58 by Ian Batty
  16. PartShop
  17. Market Centre
  18. Advertising Index
  19. Notes & Errata: 50A Battery Charger Controller, Nov 16; WiFi Switch Using A Raspberry Pi, Nov 16; Precision Voltage & Current Reference With Touchscreen Control, Oct 16
  20. Outer Back Cover

This is only a preview of the December 2016 issue of Silicon Chip.

You can view 45 of the 104 pages in the full issue, including the advertisments.

For full access, purchase the issue for $10.00 or subscribe for access to the latest issues.

Items relevant to "Automotive Sensor Modifier":
  • Automotive Sensor Modifier PCB [05111161] (AUD $10.00)
  • PIC16F88-E/P programmed for the Automotive Sensor Modifier [0511116A.HEX] (Programmed Microcontroller, AUD $15.00)
  • Firmware (ASM and HEX) files for the Automotive Sensor Modifier [0511116A.HEX] (Software, Free)
  • Automotive Sensor Modifier PCB pattern (PDF download) [05111161] (Free)
Items relevant to "Arduino-Based Digital Theremin":
  • Firmware (.ino and .c) files for Giving the Ultrasonic Theremin a Volume Control (Software, Free)
  • Firmware (INO and C) files for the Arduino Theremin (Software, Free)
Articles in this series:
  • Arduino-Based Digital Theremin (December 2016)
  • Arduino-Based Digital Theremin (December 2016)
  • Giving the Ultrasonic Theremin A Volume Control (January 2017)
  • Giving the Ultrasonic Theremin A Volume Control (January 2017)
Items relevant to "Voltage/Current Reference With Touchscreen, Pt.2":
  • Touchscreen Voltage/Current Reference PCB [04110161] (AUD $12.50)
  • PIC32MX170F256B-50I/SP programmed for the Micromite-based Touchscreen Voltage/Current Reference v1.00 [0411016A.HEX] (Programmed Microcontroller, AUD $15.00)
  • Short Form Kit for the Touchscreen Voltage/Current Reference (Component, AUD $120.00)
  • Translucent Blue UB1 Lid for the Precision Voltage & Current Reference with Touchscreen Control (PCB, AUD $10.00)
  • Firmware (HEX) file and BASIC source code for the Micromite-based Touchscreen Voltage/Current Reference v1.00 [0411016A.HEX] (Software, Free)
  • Touchscreen Voltage/Current Reference PCB pattern (PDF download) [04110161] (Free)
Articles in this series:
  • Voltage/Current Reference With Touchscreen, Pt.1 (October 2016)
  • Voltage/Current Reference With Touchscreen, Pt.1 (October 2016)
  • Voltage/Current Reference With Touchscreen, Pt.2 (December 2016)
  • Voltage/Current Reference With Touchscreen, Pt.2 (December 2016)
Articles in this series:
  • Micromite Plus Advanced Programming (November 2016)
  • Micromite Plus Advanced Programming (November 2016)
  • Micromite Plus Advanced Programming, Pt.2 (December 2016)
  • Micromite Plus Advanced Programming, Pt.2 (December 2016)
Articles in this series:
  • El Cheapo Modules From Asia - Part 1 (October 2016)
  • El Cheapo Modules From Asia - Part 1 (October 2016)
  • El Cheapo Modules From Asia - Part 2 (December 2016)
  • El Cheapo Modules From Asia - Part 2 (December 2016)
  • El Cheapo Modules From Asia - Part 3 (January 2017)
  • El Cheapo Modules From Asia - Part 3 (January 2017)
  • El Cheapo Modules from Asia - Part 4 (February 2017)
  • El Cheapo Modules from Asia - Part 4 (February 2017)
  • El Cheapo Modules, Part 5: LCD module with I²C (March 2017)
  • El Cheapo Modules, Part 5: LCD module with I²C (March 2017)
  • El Cheapo Modules, Part 6: Direct Digital Synthesiser (April 2017)
  • El Cheapo Modules, Part 6: Direct Digital Synthesiser (April 2017)
  • El Cheapo Modules, Part 7: LED Matrix displays (June 2017)
  • El Cheapo Modules, Part 7: LED Matrix displays (June 2017)
  • El Cheapo Modules: Li-ion & LiPo Chargers (August 2017)
  • El Cheapo Modules: Li-ion & LiPo Chargers (August 2017)
  • El Cheapo modules Part 9: AD9850 DDS module (September 2017)
  • El Cheapo modules Part 9: AD9850 DDS module (September 2017)
  • El Cheapo Modules Part 10: GPS receivers (October 2017)
  • El Cheapo Modules Part 10: GPS receivers (October 2017)
  • El Cheapo Modules 11: Pressure/Temperature Sensors (December 2017)
  • El Cheapo Modules 11: Pressure/Temperature Sensors (December 2017)
  • El Cheapo Modules 12: 2.4GHz Wireless Data Modules (January 2018)
  • El Cheapo Modules 12: 2.4GHz Wireless Data Modules (January 2018)
  • El Cheapo Modules 13: sensing motion and moisture (February 2018)
  • El Cheapo Modules 13: sensing motion and moisture (February 2018)
  • El Cheapo Modules 14: Logarithmic RF Detector (March 2018)
  • El Cheapo Modules 14: Logarithmic RF Detector (March 2018)
  • El Cheapo Modules 16: 35-4400MHz frequency generator (May 2018)
  • El Cheapo Modules 16: 35-4400MHz frequency generator (May 2018)
  • El Cheapo Modules 17: 4GHz digital attenuator (June 2018)
  • El Cheapo Modules 17: 4GHz digital attenuator (June 2018)
  • El Cheapo: 500MHz frequency counter and preamp (July 2018)
  • El Cheapo: 500MHz frequency counter and preamp (July 2018)
  • El Cheapo modules Part 19 – Arduino NFC Shield (September 2018)
  • El Cheapo modules Part 19 – Arduino NFC Shield (September 2018)
  • El cheapo modules, part 20: two tiny compass modules (November 2018)
  • El cheapo modules, part 20: two tiny compass modules (November 2018)
  • El cheapo modules, part 21: stamp-sized audio player (December 2018)
  • El cheapo modules, part 21: stamp-sized audio player (December 2018)
  • El Cheapo Modules 22: Stepper Motor Drivers (February 2019)
  • El Cheapo Modules 22: Stepper Motor Drivers (February 2019)
  • El Cheapo Modules 23: Galvanic Skin Response (March 2019)
  • El Cheapo Modules 23: Galvanic Skin Response (March 2019)
  • El Cheapo Modules: Class D amplifier modules (May 2019)
  • El Cheapo Modules: Class D amplifier modules (May 2019)
  • El Cheapo Modules: Long Range (LoRa) Transceivers (June 2019)
  • El Cheapo Modules: Long Range (LoRa) Transceivers (June 2019)
  • El Cheapo Modules: AD584 Precision Voltage References (July 2019)
  • El Cheapo Modules: AD584 Precision Voltage References (July 2019)
  • Three I-O Expanders to give you more control! (November 2019)
  • Three I-O Expanders to give you more control! (November 2019)
  • El Cheapo modules: “Intelligent” 8x8 RGB LED Matrix (January 2020)
  • El Cheapo modules: “Intelligent” 8x8 RGB LED Matrix (January 2020)
  • El Cheapo modules: 8-channel USB Logic Analyser (February 2020)
  • El Cheapo modules: 8-channel USB Logic Analyser (February 2020)
  • New w-i-d-e-b-a-n-d RTL-SDR modules (May 2020)
  • New w-i-d-e-b-a-n-d RTL-SDR modules (May 2020)
  • New w-i-d-e-b-a-n-d RTL-SDR modules, Part 2 (June 2020)
  • New w-i-d-e-b-a-n-d RTL-SDR modules, Part 2 (June 2020)
  • El Cheapo Modules: Mini Digital Volt/Amp Panel Meters (December 2020)
  • El Cheapo Modules: Mini Digital Volt/Amp Panel Meters (December 2020)
  • El Cheapo Modules: Mini Digital AC Panel Meters (January 2021)
  • El Cheapo Modules: Mini Digital AC Panel Meters (January 2021)
  • El Cheapo Modules: LCR-T4 Digital Multi-Tester (February 2021)
  • El Cheapo Modules: LCR-T4 Digital Multi-Tester (February 2021)
  • El Cheapo Modules: USB-PD chargers (July 2021)
  • El Cheapo Modules: USB-PD chargers (July 2021)
  • El Cheapo Modules: USB-PD Triggers (August 2021)
  • El Cheapo Modules: USB-PD Triggers (August 2021)
  • El Cheapo Modules: 3.8GHz Digital Attenuator (October 2021)
  • El Cheapo Modules: 3.8GHz Digital Attenuator (October 2021)
  • El Cheapo Modules: 6GHz Digital Attenuator (November 2021)
  • El Cheapo Modules: 6GHz Digital Attenuator (November 2021)
  • El Cheapo Modules: 35MHz-4.4GHz Signal Generator (December 2021)
  • El Cheapo Modules: 35MHz-4.4GHz Signal Generator (December 2021)
  • El Cheapo Modules: LTDZ Spectrum Analyser (January 2022)
  • El Cheapo Modules: LTDZ Spectrum Analyser (January 2022)
  • Low-noise HF-UHF Amplifiers (February 2022)
  • Low-noise HF-UHF Amplifiers (February 2022)
  • A Gesture Recognition Module (March 2022)
  • A Gesture Recognition Module (March 2022)
  • Air Quality Sensors (May 2022)
  • Air Quality Sensors (May 2022)
  • MOS Air Quality Sensors (June 2022)
  • MOS Air Quality Sensors (June 2022)
  • PAS CO2 Air Quality Sensor (July 2022)
  • PAS CO2 Air Quality Sensor (July 2022)
  • Particulate Matter (PM) Sensors (November 2022)
  • Particulate Matter (PM) Sensors (November 2022)
  • Heart Rate Sensor Module (February 2023)
  • Heart Rate Sensor Module (February 2023)
  • UVM-30A UV Light Sensor (May 2023)
  • UVM-30A UV Light Sensor (May 2023)
  • VL6180X Rangefinding Module (July 2023)
  • VL6180X Rangefinding Module (July 2023)
  • pH Meter Module (September 2023)
  • pH Meter Module (September 2023)
  • 1.3in Monochrome OLED Display (October 2023)
  • 1.3in Monochrome OLED Display (October 2023)
  • 16-bit precision 4-input ADC (November 2023)
  • 16-bit precision 4-input ADC (November 2023)
  • 1-24V USB Power Supply (October 2024)
  • 1-24V USB Power Supply (October 2024)
  • 14-segment, 4-digit LED Display Modules (November 2024)
  • 0.91-inch OLED Screen (November 2024)
  • 0.91-inch OLED Screen (November 2024)
  • 14-segment, 4-digit LED Display Modules (November 2024)
  • The Quason VL6180X laser rangefinder module (January 2025)
  • TCS230 Colour Sensor (January 2025)
  • The Quason VL6180X laser rangefinder module (January 2025)
  • TCS230 Colour Sensor (January 2025)
  • Using Electronic Modules: 1-24V Adjustable USB Power Supply (February 2025)
  • Using Electronic Modules: 1-24V Adjustable USB Power Supply (February 2025)

Purchase a printed copy of this issue for $10.00.

Micromite Plus Advanced Programming, Pt.2 Last month, we went over some of the new features of the Micromite Plus, including reading and writing files on an SD card and defining GUI (graphical user interface) controls. Now we’re going to take a look at some extra features which allow even more advanced GUI controls to be built very easily. By Geoff Graham A S‌ EXPLAINED in Pt.1 last month, it’s trivial to create a GUI control using the Micromite Plus. In most cases, a single line of BASIC will create a check box, text input control or one of nine other different types of GUI elements. The Micromite Plus firmware manages these controls for you, taking care of display and user interaction via the touch interface. The BASIC program can query the state of the controls at a later time, to see what changes the user has made. Sometimes when a control is touch­ ed, you need your program to respond immediately. One way to do this would be with a simple IF statement in the main program loop. For example: IF CTRLVAL(PwrSwitch) = 1 THEN . . . However, with a complex program, it is more efficient to use an interrupt to detect when a control has been touched. This is especially true if the program is performing background processing while the user is interacting with the GUI. To use a touch interrupt, you must first set it up. For example: GUI INTERRUPT IntTouchDown 74  Silicon Chip After this command, touching the screen will cause MMBasic to interrupt whatever the main program is doing and execute the code in the subroutine IntTouchDown. When this subroutine exits, the main program will continue as if nothing happened (apart from any state changes which occur in that subroutine). Within the interrupt subroutine, you can discover what control was touched by using the TOUCH(REF) function which will return the reference number of the control currently being touched. Note that REF is a keyword and should not be replaced with a reference number or variable in this case. In a large program with many controls, it is best to use the SELECT CASE statement to select the appropriate code for each control. For example: With this sort of structure, you can process almost any touch completely within the interrupt. As a result, the main program could consist of just the commands to set up the controls and then continue with its main job. Sub IntTouchDown SELECT CASE TOUCH(REF) CASE PwrSwitch ' do some action CASE OTHERCTRL ' do some other action END SELECT END SUB CONST PwrSwitch = 41 CONST RedLED = 42 Interrupt example code As an example of how an interrupt could be useful, consider the situation where you would like to run a motor whenever an on-screen switch is touched. This requires the BASIC program to activate the motor’s power relay and illuminate a virtual LED on the screen. First, you need to define two constants. The first is the reference number for the switch control and the second is the reference for the on-screen LED control: Then you would create the controls as follows: GUI SWITCH PwrSwitch, c$, x, y, etc GUI LED RedLED, c$, x, y, etc Next, the main program should set siliconchip.com.au up the GUI interrupt and initiate a never-ending loop: GUI INTERRUPT IntTouchDown DO : LOOP The interrupt subroutine would look something like this: Sub IntTouchDown SELECT CASE TOUCH(REF) CASE PwrSwitch PIN(1) = CTRLVAL(PwrSwitch) CTRLVAL(RedLED) = CTRLVAL(PwrSwitch) END SELECT END SUB In the above code fragment, we assume that the motor’s relay is connected to pin 1. The CTRLVAL() function will get the state of the switch (0 for off and 1 for on) and copy that to pin 1 which will control the relay (ie, “1” means close the relay). We also get that value a second time and apply it to the on-screen LED so that it will reflect the state of the motor. GUI programming This concept of handling on-screen activity within an interrupt is common in GUI (graphical user interface) programming but it may be unfamiliar to newcomers. Conventional programs start by setting everything up, then doing something and then ending. GUI programming is different and this is because it is the user who is in control of the program flow, not the program. The user might touch this control or that; there is no predicting which control will be siliconchip.com.au touched next and a linear program is not the ideal way to handle this. In a GUI environment, the program should set everything up and wait to see which control the user touches. When the user does touch a control, the appropriate action can be taken and when that action is complete, the program should resume waiting. This can be referred to as an “event-driven program”. The exception is when there is some lengthy processing that must be done as soon as a control is touched. When an interrupt occurs, MMBasic will only run the program in the interrupt subroutine and that means that other interrupts and the main program are blocked. This is fine when the interrupt action is quick (say, less than a millisecond) but if it is lengthy (say, over 100 milliseconds) the effect could be disastrous, as the main loop will freeze while the interrupt is processed. For example, when a button is touched, you might want your program to send a message to some other item of equipment. Sending a message over a communications link can take some time (eg, half a second) and if that was done within the interrupt routine, it would appear to the user that the program has frozen for this time. Also, if the main loop is performing any realtime tasks, such as monitoring a motor and controlling its speed, the fact that this is not occurring for a significant amount of time could cause real problems. To avoid this, the interrupt subroutine can set a flag which will let the main program loop know that an action is required. Setting a flag means that the program will write a value into a variable which can then be recognised in another part of the program as a signal to do something. The main loop can then handle that flag in any way it requires. For example, if the flag indicates that a message is to be sent, that message could be sent one character at a time while the main loop continues to run, so that it is not interrupted for a long period. Here is an example of how you could tackle the above requirement. You first define the flag, then set up the button and the touch-down interrupt: DIM CommFlag = 0 CONST ButtonRef = 42 GUI BUTTON ButtonRef, c$, x, y, etc GUI INTERRUPT IntTouchDown The interrupt would simply set the flag whenever the button is touched: Sub IntTouchDown SELECT CASE TOUCH(REF) CASE ButtonRef CommFlag = 1 END SELECT END SUB The main program loop would then monitor this flag: DO IF CommFlag = 1 THEN . . . code to send the message . . . CommFlag = 0 ENDIF LOOP Note that it is the responsibility of the main program to reset the flag so that it then can detect when another message must be sent. If you want the code to avoid blocking the main loop while sending the message, you could increment CommFlag as each byte is sent and only reset it to zero at the end. If doing this, the interrupt subroutine could disable the button (using the GUI DISABLE command) until the message has been sent. It could then be reenabled when the flag is reset, to avoid interrupting a message when transmission has already begun. Touch-up interrupt In most cases, you can process all user input in the touch-down interrupt. But there are always exceptions and a typical example is when you need to change the characteristics of the control that is being touched. For example, you might want to change the foreground colour of a button from white to red when it is “down”. When it is returned to the “up” state, the colour should revert to white. Setting the button colour when it is pressed is easy. Just define a touchdown interrupt and change the colour in the interrupt handler routine when that control is touched. However, to return the colour to white when it is released, you need to detect when the touch has been removed from the control (ie, touch-up). This can be done with a touch-up interrupt. To specify a touch-up interrupt, you add the name of the subroutine for this interrupt to the end of the GUI INTERRUPT command. For example: GUI INTERRUPT IntTouchDown, IntTouchUp Within the touch-up subroutine, December 2016  75 ated with a specific page, you use the following command immediately before the controls are created: GUI SETUP nn where “nn” is the page number that is being set up. In the following example, page 1 has two controls and page 3 has two different controls: GUI SETUP 1 GUI SWITCH 41, c$, x, y, etc GUI LED 42, c$, x, y, etc GUI SETUP 3 GUI CHECKBOX 43, c$, x, y, etc GUI CHECKBOX 43, c$, x, y, etc will hide all the controls used for page 1 and reveal (un-hide) all the controls associated with page 2. You can have up to 32 pages, ranging from page 1 to page 32 and you can display two or more pages at the same time. For example, When a program starts up, the set-up page will default to page 1. This means that if you do not use the GUI SETUP command, all GUI elements will be associated with page 1. Also, the page to be displayed will default to page 1 so your program will run perfectly as a single-page application. Note that the control reference numbers must be unique across all controls, regardless of what page they are on. It is also perfectly legal for the program to change the characteristics of a control on a page which is not displayed. When that page is eventually displayed, the control will be drawn with its new characteristics. For example, a hidden control might be on a page that's not active. If that page was selected for display, the control will still be hidden when the page is shown. However, the BASIC program can un-hide that control even if the page is not displayed and then, when the page is subsequently selected for display, the control will be visible and active. PAGE 1, 5 Message boxes Fig.6: the Micromite Plus can drive an LCD panel with up to 800x480 pixels in true (24-bit) colour as demonstrated by this image. It was loaded from the SD card using the LOAD IMAGE command. The speed of loading is not super fast so you would not use this as a photo frame but it is useful for loading logos and background images. you can use the same structure as in the touch-down subroutine but you need to find the reference number of the last control that was touched. This is because no control is currently being touched. To get the number of the last control touched you need to use the TOUCH(LASTREF) function. The following example shows how you could meet the above requirement and implement both a touch-down and a touch-up interrupt: SUB IntTouchDown SELECT CASE TOUCH(REF) CASE ButtonRef GUI FCOLOUR RGB(RED), ButtonRef END SELECT END SUB SUB IntTouchUp SELECT CASE TOUCH(LASTREF) CASE ButtonRef GUI FCOLOUR RGB(WHITE), ButtonRef END SELECT END SUB Switching screen pages Most GUI interfaces will have a number of screens or pages that will be displayed for the user. For example, there may be a main screen which is first displayed but when the user touches a button labelled “Options”, the screen switches to another display which allows the user to set various options. 76  Silicon Chip With the Micromite Plus, this can be easily achieved using the PAGE command. For example, PAGE 1 will hide all controls currently on the screen and show all the controls associated with page 1. Similarly, PAGE 2 will display both pages 1 and 5. This is useful if you have a set of controls that is common on a number of screens; this set can be defined on one page and that page’s number then used in the list for each page switch. To define which controls are associ- YouTube Video The author has produced a video which describes and demonstrates the capabilities of the Micromite Plus. You’ll find it at: https://youtu.be/j12LidkzG2A One very useful GUI function is MSGBOX(). This will display a dialog box in the centre of the screen, with a message and up to four customisable buttons. When it is invoked, the message box will wait for the user to touch one of the buttons, then return with the number of the button touched. At the same time, MMBasic will redraw any controls that were obscured by the box. The syntax of the function is as follows: MSGBOX(caption$, b1$, b2$, b3$, b4$) All the arguments are strings and caption$ is the message to be displayed siliconchip.com.au Fig.7: one of the more powerful controls is the NUMBERBOX which is an onscreen box that can hold a number. When it is touched, a number pad will appear, allowing the user to enter any number, including floating point numbers, using scientific notation. Displaying the number pad and entering the number are both done without involving the main BASIC program which can continue with other duties, such as monitoring sensors and other inputs. in the centre of the box. Multiple lines can be displayed by inserting the “|” (pipe) character into the caption where the new line is to start. b1$ and b2$ etc are the captions for the various buttons. The number of buttons displayed is determined by the number of captions specified. The following is an example of how this function could be used: IF MSGBOX("Start Failed","Cancel","Retry") = 0 THEN GOTO EXIT ELSE GOTO RETRY ENDIF When run, the MSGBOX function would display a box containing the words “Start Failed” and two buttons labelled “Cancel” and “Retry”. The user will be forced to select either button and when this is done, MMBasic will restore the display to normal and return the number of the button to the BASIC program. Mixing GUI controls with general graphics You may be tempted to mix the general graphics commands (CIRCLE, BOX, etc) with GUI controls but the best advice is simply don’t do it. When you use the GUI controls, MMBasic keeps track of where they are on the screen and their state (ie, visible, hidden, etc) and it will use this information while it is managing the screen. For example, when the user touches a text box, MMBasic will disable all GUI controls on the screen and display them in dull colours. MMBa- sic will then draw the QWERTY keyboard (to enable user input) over these controls. The reason that MMBasic disables these controls, by the way, is to indicate to the user that the on-screen keyboard is the only active part of the screen. On the other hand, MMBasic does not track the location and state of any general graphics commands and they will not be dimmed. Even worse, they may be partially overwritten by the onscreen keyboard and when the user has finished with the keyboard, MMBasic will not redraw them. You should therefore use either the general graphics commands (CIRCLE, BOX, etc) or the GUI controls but not both on the same screen display. The one exception is the clear screen command (CLS) which will first run through the GUI table and set any visible GUI controls to hidden before it then clears the screen. If you do want to mix the two types of graphics commands, you should intercept the touch-down and touch-up interrupts for any text box and number box controls. This will indicate that a virtual keyboard has been displayed or removed. During these interrupts, you could then redraw any general graphics that you may have used. Similarly, you should redraw these graphics immediately after the MSGBOX() function has been used, as it will have also overwritten parts of the screen. Finally, MMBasic for the Micromite Plus will be improved and updated into the future, with new features already planned. To access these updates and other information relating to the Micromite Plus, please check the author’s website at geoffg.net/ SC micromite.html The Australian Arduino experts! Tronixlabs is owned and operated by Arduino experts including "Arduino Workshop" author John Boxall Check out our wide range of quality Arduino and compatible boards, modules, and so much more! Order online • Visit tronixlabs.com.au/arduino support<at>tronixlabs.com • $5 flat-rate delivery Australia wide! • Latest updates on twitter - follow <at>tronixlabs siliconchip.com.au December 2016  77