From cbebbf73d2523d88593560e4b9d62a392a0e55c1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juraj=20Mich=C3=A1lek?= Date: Tue, 17 Dec 2024 15:10:39 +0100 Subject: [PATCH] doc: add missing content --- .../workshops/flowcode/01-planning/index.md | 164 +++++++++++++++++- .../flowcode/02-using-the-display/index.md | 40 ++++- .../flowcode/03-switch-io-pins/index.md | 4 +- .../flowcode/04-the-bezel-encoder/index.md | 37 +++- .../flowcode/05-i2c-expansion/index.md | 51 ++---- .../flowcode/06-menu-system/index.md | 39 +++-- .../flowcode/07-mobile-phone-app/index.md | 124 ++++++++++--- .../flowcode/08-full-project/index.md | 42 ++++- .../flowcode/assets/7-5-home-screen.webp | Bin 27100 -> 20864 bytes 9 files changed, 411 insertions(+), 90 deletions(-) diff --git a/content/workshops/flowcode/01-planning/index.md b/content/workshops/flowcode/01-planning/index.md index 52a11070..54d251d9 100644 --- a/content/workshops/flowcode/01-planning/index.md +++ b/content/workshops/flowcode/01-planning/index.md @@ -14,14 +14,10 @@ But if you don’t plan then there can be all sorts of pain later: you end up redoing work, falling out with colleagues and customers, and it’s a lot less fun later on in the project. -{{< figure - default=true - src="../assets/m5stack-test-screen-01.webp" - >}} - In part 1 we show you how we plan the project. -Specification: +### Specification + We are going to show you how to make an electronic door lock based on the M5stack dial with the following features: - Based on M5 stack dial @@ -36,10 +32,166 @@ based on the M5stack dial with the following features: src="../assets/hardware.webp" >}} +Actually what we really want to do is teach you how to create a project based on the M5 stack dial. We have come up with the specification above so that we can teach you about the following: + +- [Assignment 1: Planning](01-planning) +- [Assignment 2: Using the Display](02-using-the-display) +- [Assignment 3: Switch and I/O Pins](03-switch-io-pins) +- [Assignment 4: The Bezel Encoder](04-the-bezel-encoder) +- [Assignment 5: I2C Expansion](05-i2c-expansion) +- [Assignment 6: Menu System](06-menu-system) +- [Assignment 7: Mobile Phone App](07-mobile-phone-app) +- [Assignment 8: Full Project](08-full-project) + +### Graphic designer’s brief + +Usually we need a graphic designer in a project like this. They just have a knack of making stuff look right. In this case we gave the designer a brief of creating an image that allowed us to teach how to display text, vector graphics, and bitmap graphics in an Electronic safe/door lockproject. This is what he came up with: +Fantastic. + +{{< figure + default=true + src="../assets/m5stack-test-screen-01.webp" + >}} + +From this we get a create colour scheme and a theme for our project. +What we need to do next is analyse this and turn it into information that we can use. The easiest way to do that is to redraw it. We are going to have to do that anyway to plan our menus. + +After doing that we get this: + +{{< figure + default=true + src="../assets/home.webp" + >}} + +As you can see we have taken the opportunity to draw a pixel grid on the diagram and we now understand the colours text sizes and position of all the graphical and text elements. + +We also need to plan our menu and functionality. Once we have the main screen done this easily falls out of the design and we get the following screens: + +{{< figure + default=true + src="../assets/combo.webp" + >}} + +If the code is incorrect then this screen tells them they have the +wrong combination. They can ring a mobile number and the +door can be unlocked by someone with the mobile phone app. + +{{< figure + default=true + src="../assets/noentry.webp" + >}} + + +If they are successful then this screen is displayed. The door +unlocks and they get a summary of the weather! + +{{< figure + default=true + src="../assets/unlocked.webp" + >}} + + +So that has defined our functionality. We can then show this to colleagues and customers and be really clear about what we are doing before we start. A real time saver! + +Now that we know what we are doing some other elements of the design easily come from this: + +### Colours + +We need to know the colours of all the items on the display. We will declare some constants in the program to save us time as well. So we have a list: + +| Name | R | G | B | Constants | +|------|---|---|---|-----------| +|Purple| 64| 33| 87 |PURPLER, PURPLEG, PURPLEB| +|Light purple| 85| 47| 108| LIGHTPURPLER, LIGHTPURPLEG, LIGHTPURPLEB| +|Orange| 255| 102| 0| ORANGER, ORANGEG, ORANGEB| +|White| 255| 255| 255| WHITER, WHITEG, WHITEB| +|Red| 255| 0| 0| +|Yellow| 255| 255| 0| +|Green| 0| 255| 255| + +### Graphics + +We also have a rough plan for the home screen graphics: +Purple circle background +- Grid at 20 Pixel intervals +- Text Heading and subheading +- Red circles 30, 120 210, 120 22 diameter +- Orange circles 40, 170 200, 170 18 diameter +- Yellow circles 75,205 165, 205 15 diameter +- Green triangle 120, 225 – can’t do triangles so we can use some diminishing rectangles +- Bitmap is 80 x 80 pixels. Top left is 80, 80. + +### Fonts +|Type|Size|Font face|Colour|Font Index|Const| +|-------|----------------|----------|-------|-------|---------| +|Heading| 15 pixels high |Arial bold| Orange| Font 0| HEADINGF| +|Subheading| 24 pixels high| Arial bold| Orange| Font 1| SUBHEADINGF| +|Instructions| 10| pixels high| Arial White| Font 2| INSTRUCTIONSF| +|Combo| 60 pixels high| Arial bold| Orange| Font 3| COMBOF| +|Digit| 35| pixels high| Arial bold| Orange| Font 4| DIGITF| + +We now know roughly what fonts we are gong to use. In Flowcode every font is assigned a number so again we declare constants for the fonts as you can see in the table. That saves us from having to remember what font is what. + +### Bitmaps + +There is only one bitmap. Like fonts in Flowcode bitmaps are represented by numbers, but as there is only 1 - bitmap 0 - its easy enough to remember. + +### Screens + +| Screen| number| Constants| +|-------|-------|----------| +|Home screen| 0| HOMES| +|Code entry screen| 1| CODES| +|Enter screen| 2| ENTERS| +|Denial Screen| 3| DENIALS| + +Each screen is represented by a number in the Flowcode program. We set up Global constants for these numbers so that we don’t have to remember what the numbers are. + +### Connections + +We can also define the connections both inside the M5 stack dial and outside. Flowcode needs the actual processor connections in order to drive the various chips and I/O inside the Dial. This is what we get when we dig into it: +Display is GC9A01A round, 240 x 240 pixel + +SPI bus with the following connections: + +- MOSI A5 (GPIO5) +- MISO A1 (GPIO1) +- CLK A6 (GPIO6) +- CS A7 (GPIO7) +- DC RS A4 (GPIO4) +- Reset A8 (GPIO8) +- Backlight A9 (GPIO9) +- Bezel switch B10 (GPIO5) +- Buzzer A3 (GPIO) +- Bezel encoder +- A B9 (GPIO41) +- B B8 (GPIO40) +- I2C +- SCL A15 (GPIO15) +- SDA A13 (GPIO13) +- Relay on I/O pin A1 (GPIO1), A2 (GPIO2) + ## Video {{< youtube gjOI7aVCoqA >}} +## Over to you + +Now we need to set up the hardware for the project. You can see this on the photograph. We have an M5stack Dial connected to the PC via USB. + +There is a board with two relays on that are connected to the general purpose IO pins G10 and G2. That allows us to switch 24A AT 28V - should be enough for a Maglock. For prototyping purposes I have put a small solenoid on the board to simulate the Maglock function. This is powered by a 24V plug top power supply. + +There is a Grove board with a SHT21 temperature and humidity sensor. This is connected to the Dial I2C pins GPIO13 and GPIO15. + +Get your M5stack Dial, relay board and SHT31 board and a suitable power supply and set up your project. + +You can see ours here: + +{{< figure + default=true + src="../assets/hardware.webp" + >}} + ## Next step [Assignment 2: Using the Display](../02-using-the-display) \ No newline at end of file diff --git a/content/workshops/flowcode/02-using-the-display/index.md b/content/workshops/flowcode/02-using-the-display/index.md index cf4971f8..6be5b134 100644 --- a/content/workshops/flowcode/02-using-the-display/index.md +++ b/content/workshops/flowcode/02-using-the-display/index.md @@ -38,15 +38,15 @@ get the correct settings. src="../assets/2-2-backlight-properties.webp" >}} +If you need more information then you can left +click on the display and click on HELP to get +more information from the Flowcode Wiki. {{< figure default=true src="../assets/2-3-display-properties-1.webp" >}} -If you need more information then you can left click on the -display and click on HELP to get more information from the -Flowcode Wiki. Notice that we have not got the exact fonts that we wanted - Flowcode does not include all fonts - although more can be @@ -67,6 +67,10 @@ made - but the fonts that we have should be fine. src="../assets/2-6-display-properties-4.webp" >}} +You can also set up the Bitmap drawer. This +will need the central graphic copying to the +same directory as the Flowcode file so that it +simulates properly. {{< figure default=true @@ -90,15 +94,45 @@ made - but the fonts that we have should be fine. src="../assets/2-10-constants.webp" >}} +## Over to you + +Now that you understand the basics of how to control +the graphics and text you can complete the design of the first +screen using the specification: + +Download the program to the M5 stack dial and check is all works ok! +Note that if you want to you can also create your program in C code or in Pseudocode: + {{< figure default=true src="../assets/2-11-pseudocode.webp" >}} +Open the program ‘Using the display.fcfx’ and +download it to your M5 stack Dial. + +- Use Flowcode to create the Home screen you can +see here. + +- Make sure you include the light purple cross hatch - you may want to make a separate macro to print +those. + +{{< figure + default=true + src="../assets/2-12-c-code.webp" + >}} + +- You will need to have the bitmap ‘M5Stack Lock +Test Purple.bmp’ in the same directory as the +Flowcode program. + + + ## Video {{< youtube A0fKmmufJRk >}} + ## Resources A Flowcode example file accompanies this tutorial. This is diff --git a/content/workshops/flowcode/03-switch-io-pins/index.md b/content/workshops/flowcode/03-switch-io-pins/index.md index b5ee5a72..28ccbd41 100644 --- a/content/workshops/flowcode/03-switch-io-pins/index.md +++ b/content/workshops/flowcode/03-switch-io-pins/index.md @@ -20,12 +20,14 @@ This is a simple program that reads the value of the switch on the bezel (B10 or GPIO42) and sends it to the pins on A1 and A4 (GPIO10 and GPIO2). You can simulate this and you can check it works by sending it to your hardware. + So what? + You will notice that the switch logic is reversed: when the bezel is pressed the input at Port B10 (GPIO42) goes low. +## Over to you -Over to you: Modify the program so that the output stays on for 5 seconds when the bezel is pressed. Try the same program but use GPIO pins 13 and 15 rather than diff --git a/content/workshops/flowcode/04-the-bezel-encoder/index.md b/content/workshops/flowcode/04-the-bezel-encoder/index.md index 59e0555f..3418b024 100644 --- a/content/workshops/flowcode/04-the-bezel-encoder/index.md +++ b/content/workshops/flowcode/04-the-bezel-encoder/index.md @@ -26,16 +26,22 @@ Add an Encoder and connect it to B.9 (GPIO41) and B.8 (GPIO40). Alter the properties as you can see in the image here. -Your panel should look like this: - +{{< figure + default=true + src="../assets/4-1-encoder-properties.webp" + >}} -Alter your program so that it looks like the flow chart here. +Your panel should look like this: {{< figure default=true - src="../assets/4-1-encoder-properties.webp" + src="../assets/4-2-encoder-panel.webp" >}} + +Alter your program so that it looks like the flow chart here. + + Note that you will need to set up an Interrupt Macro with just one command in it. @@ -45,10 +51,6 @@ the display by altering the encoder counter to reset when the Bezel switch is pressed. You can use the Encoder hardware macro ‘Resetcounter’ for this. -{{< figure - default=true - src="../assets/4-2-encoder-panel.webp" - >}} {{< figure @@ -66,6 +68,25 @@ macro ‘Resetcounter’ for this. src="../assets/4-4-bezel-program-c.webp" >}} +This program sets up interrupts for the +GPIO pins 40 and 41 - the internal Bezel connections. The interrupts call the +Encoderint macro which just checks for +changes on the Encoder. + +{{< figure + default=true + src="../assets/4-5-bezel-program-c.webp" + >}} + +Alter your program so that it looks like the flow chart here. + +Note that you will need to set up an Interrupt Macro with just one command in it. + +## Over to you + +Combine the functionality of the Bezel encoder, the switch and the display by altering the encoder counter to reset when the Bezel switch is pressed. You can use the Encoder hardware macro ‘Resetcounter’ for this. + + ## Video {{< youtube dVPpjeCYYsE >}} diff --git a/content/workshops/flowcode/05-i2c-expansion/index.md b/content/workshops/flowcode/05-i2c-expansion/index.md index 2d577bc6..97cf019c 100644 --- a/content/workshops/flowcode/05-i2c-expansion/index.md +++ b/content/workshops/flowcode/05-i2c-expansion/index.md @@ -8,8 +8,10 @@ showAuthor: false In this section we are going to read a sensor value using the I2C connection on the M5 Stack Dial. + In this case we will use a small Grove sensor that contains a SH31 temperature and humidity chip. + Of course it’s a bit odd having a temperature and humidity sensor on a door lock! But it allows us to teach you how you can take advantage of the huge range of I2C sensors and @@ -23,25 +25,38 @@ Dial. Start with the program you made in the previous section. - Add a SHT31 Temp / Humidity sensor from the Sensors component section. + Adjust its properties as you can see here: +{{< figure + default=true + src="../assets/5-1-sht31-properties.webp" + >}} You should have a panel that looks like this: -Add two variables of type INT: Temperature and Humidity. {{< figure default=true - src="../assets/5-1-sht31-properties.webp" + src="../assets/5-2-panel.webp" >}} +Add two variables of type INT: Temperature and Humidity. + Then develop the program you can see below. + The program is easy to read but there are a few things of note: + The program initialises the display and the SHT31 sensor. Initialisation is used on many components to set up registers inside the microcontroller. + +{{< figure + default=true + src="../assets/5-3-variables.webp" + >}} + When reading and display a value like this one issue you have is that you are writing new numbers on top of old ones. When the number changes the display becomes hard to read. So we @@ -49,12 +64,7 @@ need to clear the area of the screen before we rewrite the number. Clearing the screen takes time - its quicker to draw a rectangle of the background colour (black here). -Over to you: - -{{< figure - default=true - src="../assets/5-2-panel.webp" - >}} +## Over to you In practice the temperature and humidity are quantities that change very slowly. So there is no need to constantly rewrite @@ -70,29 +80,6 @@ You should have a panel that looks like this: Add two variables of type INT: Temperature and Humidity. Then develop the program you can see below. -{{< figure - default=true - src="../assets/5-3-variables.webp" - >}} - -The program is easy to read but there are a few things of note: -The program initialises the display and the SHT31 sensor. -Initialisation is used on many components to set up registers -inside the microcontroller. -When reading and display a value like this one issue you have -is that you are writing new numbers on top of old ones. When -the number changes the display becomes hard to read. So we -need to clear the area of the screen before we rewrite the -number. Clearing the screen takes time - its quicker to draw a -rectangle of the background colour (black here). - -Over to you: -In practice the temperature and humidity are quantities that -change very slowly. So there is no need to constantly rewrite -the values on the screen. -Develop a program that only redraws the values when they -change. - {{< figure default=true src="../assets/5-4-temp-hum-program.webp" diff --git a/content/workshops/flowcode/06-menu-system/index.md b/content/workshops/flowcode/06-menu-system/index.md index 5acc36d2..73e2d127 100644 --- a/content/workshops/flowcode/06-menu-system/index.md +++ b/content/workshops/flowcode/06-menu-system/index.md @@ -30,33 +30,38 @@ cycle. This structure might be a little unfamiliar to some engineers, but it is actually really flexible and it allows us to prevent while loops from not being closed - and hence the microcontroller subroutine stack clean - good coding practice. + At the core of this is a Switch or Case statement in the Main macro. This is driven by numbers so we declare some global constants representing the screens as follows: -Home screen 0 HOMESCREEN -Code entry screen 1 CODESCREEN -Enter screen 2 ENTERSCREEN -Denial Screen 3 DENIALSCREEN -Let’s see how this works: -The code in the main screen is shown on the left. +| Screen| number| Constants| +|-------|-------|----------| +|Home screen| 0| HOMESCREEN| +|Code entry screen| 1| CODESCREEN| +|Enter screen| 2| ENTERSCREEN| +|Denial Screen| 3| DENIALSCREEN| +Let’s see how this works: {{< figure default=true src="../assets/6-2-main.webp" >}} - -We initialise the screen and set the brightness then jump -straight into the main look with the Switch statement which - {{< figure default=true src="../assets/6-3-home-screen.webp" >}} +We initialise the screen and set the brightness then jump +straight into the main look with the Switch statement which controls navigation between screens. +In the Homescreen macro we print a message on the screen and then wait for the Bezel stiwch to be pressed. Remember that the swith is active low - it gives logic 0 when pressed so the test in the If statement is ‘Bezelswitch=0’.The Newscreen variable is altered to be the CODESCREEN. + +You can see the other three macros for the other menus here. The code is similar to the Home screen. + +So this program just cycles between the screens on the press of the Bezel switch. {{< figure default=true @@ -73,6 +78,20 @@ controls navigation between screens. src="../assets/6-6-denial-screen.webp" >}} +## Over to You + +We will not ask you to construct this program from scratch as there are now quite a few elements to it. Instead open the “6 - driving a menu.fcfx” Flowcode file and download it to your M5 stack Dial. Make sure that you can get it working and that you understand the program. + +In this example we simply navigated between the screens, one after the other, using the bezel switch. In practice you might want a slightly different menu system driven from the front panel using the bezel encoder to select the screen that will be navigated to and the Bezel switch to make the selection. To implement this: + +Alter the Home screen so that it prints ENTER, CODE, DENIAL above each other on the M5 Stack Dial. +- Print these in white text to start with. +- Modify the program to select the value of a new variable, Nextcreen, between 1 and 3 +- Overprint the ENTER, CODE, DENIAL text with red text as the encoder cycles the value of Nextscreen. Overprint in white the screen text as it is deselected. +- When the bezel switch is pressed change the program so that it navigates to the selected screen. + +Now you understand how to do menu selection with the bezel encoder and switch. You can use this simple technique to implement your own menu selection system. + ## Video {{< youtube 8z-WcH0wGcY >}} diff --git a/content/workshops/flowcode/07-mobile-phone-app/index.md b/content/workshops/flowcode/07-mobile-phone-app/index.md index 6f1ed014..8d1c25b6 100644 --- a/content/workshops/flowcode/07-mobile-phone-app/index.md +++ b/content/workshops/flowcode/07-mobile-phone-app/index.md @@ -11,6 +11,7 @@ app to control the M5stack Dial. This works on Wifi and on the local router. Controlling the Dial from outside the range of the local router involves the use of a web Broker which we will not look at here. + The mobile phone app will allow you to control the Dial from anywhere in the range of the router. @@ -19,78 +20,159 @@ anywhere in the range of the router. src="../assets/7-3-web-panel.webp" >}} -Phone image to create Flowcode Web Developer allows you to create Apps that work in a browser. It does this using the same PC interface as Flowcode Embedded - but it creates Javascript programs. If you have not used Javascript before there are three fundamental changes that you will need to get to grips with: -Firstly Javascript is not like other programming languages - it - is an object orientated programming language where one - event or object calls another. -Secondly Browsers can not be ‘talked to’ cold. Pages and their - content can only be fetched by browsers from the server. - That means that to send commands to an embedded system - it needs to detect which pages have been accessed. So - detecting a fetch of page “on.htm” might turn a light on and - detecting a fetch of page “off.htm” might turn a light off. - Correspondingly if we detect a page access of “getinfo.htm” - then the returning HTML content can be the temperature - value - or status of a switch etc. That allows us to have two - way communication - but only instigated by the Javascript - program in the browser on - in this case - the mobile phone. -You will need to develop 2 programs: a Flowcode Embedded - program that goes into the M5Stack Dial and a Flowcode + +- Firstly Javascript is not like other programming languages - it +is an object orientated programming language where one +event or object calls another. +- Secondly Browsers can not be ‘talked to’ cold. Pages and their +content can only be fetched by browsers from the server. +That means that to send commands to an embedded system +it needs to detect which pages have been accessed. So +detecting a fetch of page “on.htm” might turn a light on and +detecting a fetch of page “off.htm” might turn a light off. +Correspondingly if we detect a page access of “getinfo.htm” +then the returning HTML content can be the temperature +value - or status of a switch etc. That allows us to have two +way communication - but only instigated by the Javascript +program in the browser on - in this case - the mobile phone. +- You will need to develop 2 programs: a Flowcode Embedded +program that goes into the M5Stack Dial and a Flowcode {{< figure default=true - src="../assets/7-1-embedded-initialise.webp" + src="../assets/7-4-embedded-panel.webp" >}} +This builds on the panels in the previous programs. To the panel we have added a Web server, a Network comms layer component and a Wireless LAN component for the ESP32 chip. They all link together. + +We need to pass information to and from the M5stack Dial Embedded system and the mobile phone. So how do we do this? Here is the strategy: + +Embedded system initialisation +1. Connect to the wifi. +2. Router assigns an IP address – in this case automatically assigned to 192.168.1.141 (you will have a slightly different number). +3. Create a socket for communications to take place + +## Controlling the state of an output on an embedded system + +1. Mobile phone browser requests page “192.168.1. 141/Enter.html”. +2. Embedded system detects “192.168.1. 141/Enter.html” request. +3. Embedded system navigates to the Enter screen macro and the door is opened for 4 seconds +4. Embedded system responds with “Door opened” + +## Getting a temperature variable from the embedded system + +1. Client browser requests page “192.168.1. 141/gettemp.html”. +2. Embedded system detects “192.168.1. 141/gettemp.html” request in the HTML Callback macro +3. Embedded system takes temperature sample from SHT31 sensor. +4. Embedded system responds with the relevant data served HTML +5. Client browser picks up the HTML data and displays it on the mobile phone + {{< figure default=true - src="../assets/7-2-htmlcallback.webp" + src="../assets/7-1-embedded-initialise.webp" >}} +This shows the Main routine in the embedded system: + {{< figure default=true - src="../assets/7-4-embedded-panel.webp" + src="../assets/7-2-htmlcallback.webp" >}} +We initialise the Wifi component and connect to the Router. This is a standard domestic Router and you will need to enter your Wifi network and password details. + +If the connection is unsuccessful then we print an error on the Dial screen. + +If the connection is successful we print the IP address and open a socket. Then we include the menu system from the previous program. + +The next thing we need to do is periodically check the Web connection to see if a page has been requested. We do this by putting a `CheckSocketActivity()` command in the loop on each screen macro as you can see here: + {{< figure default=true src="../assets/7-5-home-screen.webp" >}} +When there is activity then the HTMLcallback macro is automatically triggered: + {{< figure default=true src="../assets/7-6-html-callback.webp" >}} +The IP address is generated automatically by the server: in this case “192.168.1.141”. + +To open the door lock remotely the phone/browser accesses the web page: “192.168.1. 141/Enter.html”. The HTML callback macro is automatically activated. If “enter.html“ is fetched then the Newscreen variable is changed to Enterscreen and the program continues from there at the end of the HTMLcallback macro. The message “unlocked” is returned as the fetched HTML. + +If “gettemp.htm” is fetched then the temperature sensors is read, converted to a string and this string is served up as the fetched HTML. + +Lets now look at the Web Developer program that creates the Javascript file: + +The Web Developer program panel looks like this: +It contains an Enter button, A text field, A HTTP Fetch command component - FetchForEnter - a read Temp button, a + +Dial indicator and a second HTTP Fetch component FetchForReadTemp. + {{< figure default=true src="../assets/7-7-fetch-for-enter.webp" >}} +The Enter button calls the Macro Enter: +The Enter macro calls the HTTP +Fetch component FetchForEnter. +This sends a page request to the +server for page “http://192.168.1.141/enter.htm” which is +set as a property of the FetchForEnter component. + +{{< figure + default=true + src="../assets/7-3-web-panel.webp" + >}} + +FetchForEnter component.has as a property the EnterConfirmation macro which is called after the Fetch is executed. Any returning HTML - in this case the confirmation text - is passed to the EnterConfirmation macro as a parameter. + +The EnterConfirmation macro sets the text field to the HTML returned by the FetchForEnter call, then it waits 4seconds and sets the text field to “Locked”. + {{< figure default=true src="../assets/7-8-enterconfirmation.webp" >}} +Similarly the ReadTemp macro calls the macro GetTemp. This +simply calls the HTTP Fetch component FetchForReadTemp +which accesses the page “http://192.168.1.141/gettemp.htm” +which is set as a property of the FetchForReadTemp component. +The FetchForReadTemp component.has as a property the +SetGaugeValue macro which is called after the Fetch is executed. +Any returning HTML - in this case the temperature value - is passed to the SetGaugeValue macro as a parameter. - content can only be fetched by browsers fromthe server. {{< figure default=true src="../assets/7-9-gettemp.webp" >}} +The SetGauge macro sets the value of the Gauge to the temperature. + {{< figure default=true src="../assets/7-10-setgaugevalue.webp" >}} +## Over to you + +The web program and the embedded program only examined the Temperature. + +Expand both programs so that the Humidity is also read from the SHT31 and displayed on the mobile phone on a separate dial. + +Alter the text in the message box on the mobile phone so that it displays a different message + ## Video {{< youtube hX9Ko3KUDQc >}} diff --git a/content/workshops/flowcode/08-full-project/index.md b/content/workshops/flowcode/08-full-project/index.md index 33417065..fcfcbe39 100644 --- a/content/workshops/flowcode/08-full-project/index.md +++ b/content/workshops/flowcode/08-full-project/index.md @@ -11,31 +11,55 @@ lot about embedded programming, about developing apps for mobile devices and about electronics in general. You have learned the basics of how to construct all the individual elements of the system. Its up to you now to complete it. + What we have done is completed the project for you so that you can refer to it when you get stuck. There are two final files: “7 - Connecting to web FE.fcfx” and “7 - Connecting to web FWD.fcfx”. -Over to you: + +## Over to you + You have all the bones of the system in place. To get to the final design you need to do the following: -Design all the individual screen graphics. Refer to the Planning +1. Design all the individual screen graphics. Refer to the Planning section for details of the graphics, colours, fonts etc. We suggest that you embed the graphic of the menus needed onto your Embedded program panel so it looks like this: -Get the navigation between screens working properly. -Get the logic for a successful combination to be entered - properly in place. -Get the communication between the Mobile phone and the - M5Stack Dial working properly. - {{< figure default=true src="../assets/8-0-panel.webp" >}} +2. Get the navigation between screens working properly. +3. Get the logic for a successful combination to be entered + properly in place. +4. Get the communication between the Mobile phone and the + M5Stack Dial working properly. + + This is a great creative challenge. We suggest that you alter the Embedded program panel to look like this: -Good luck and have fun! +## Video + +{{< youtube gjOI7aVCoqA >}} + +We hope that you have enjoyed this course. + +Additional free courses that are available from the Flowcode team are: + +- [CAN bus communications](https://matrixtsl.com/wp-content/uploads/2024/09/CP2793-CAN-Bus-Communications-11.07.24.pdf) +- [Embedded internet communications](https://matrixtsl.com/wp-content/uploads/2024/09/CP4895-Embedded-Internet-Communications-14.08.24.pdf) +- [Bluetooth communications](https://matrixtsl.com/wp-content/uploads/2024/09/CP1795-Bluetoooth-Communications-04.07.24.pdf) +- [GSM communications](https://matrixtsl.com/wp-content/uploads/2024/08/CP2832-GSM-Communications.pdf) +For further information on Flowcode see: + +[www.flowcode.co.uk](https://www.flowcode.co.uk) + +For further information on Educational hardware products from the Matrix team see: + +https://www.matrixtsl.com/eblocks/ + +Good luck and have fun! diff --git a/content/workshops/flowcode/assets/7-5-home-screen.webp b/content/workshops/flowcode/assets/7-5-home-screen.webp index f9925ea725f8afb6f67fc66a39d41948ff3649b2..9b3360d89c68c3d2cb85951bbb104308ee8705ae 100644 GIT binary patch literal 20864 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 bqp#M^{-_puPB0#c1kfO~p9i`}S|9)bV8_0w literal 27100 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