Code generation for MIK32 (Illuminance meter)¶
This demo presents the development of the Engee model for a photoresistor-based illumination meter, followed by code generation and execution on the MIK32 NUKE V0.3 debug board.
Introduction¶
The target device used in this demo is a MIK32 NUKE V0.3 debug board based on the K1948VC018 MIK32 Amur microcontroller. The Engee model developed in this example performs illuminance calculation using the simulated signal from the controller's analogue-to-digital converter (ADC), and connects the controller peripherals. The code is compiled and loaded into the microcontroller from VS Code with PlatformIO extension.
Hardware part¶
The illuminance measurement in this example is made with a photoresistor from the GL55 family. The ADC input signal is the voltage drop across the current limiting resistor in the photoresistor circuit. At high illumination, the resistance of the photoresistor $R_{LDR}$ decreases and the voltage drop $V_{R_1}$ across the current limiting resistor $R_1 = 83\ Ом$ increases. The supply voltage level is equal to $V_{CC} = 3.3 В$. The connection diagram of the elements is shown below.
The circuit is powered from the debug board (pins 3V3
, GND
). The analogue signal received from the circuit is fed to ADC 4 of the microcontroller (ADC1.4
), pin P0.7
.
Model description¶
The model of this example is mik32_adc_lux.engee
. Blocks C Function
are used to connect and operate the peripherals of the microcontroller. The simulation time block Clock
transfers the current simulation time to the block ADC4
to simulate the voltage drop measured on the resistor $R_1$ during the simulation.
To calculate illuminance, the model includes a subsystem for calculating photoresistor resistance Get_LDR_Resistance
and a approximate one-dimensional function block illuminance_from_resistance
.
Connecting peripherals¶
To work with MIC32 peripherals, the model uses the following blocks C Function
: systemClockConfig
, EnableInterrupts
, ADC4
and USART1_print
. Each of these blocks connects a header file for the corresponding peripheral from the MIK32 HAL library. Block EnableInterrupts
among other things connects header file with interrupt handling function, and USART1_print
connects header file stdlib.h
of standard C library for converting integer format to string.
The header files to be connected are contained in the directory include/
of the example. Below is an example of connecting the HAL library header file in the block systemClockConfig
.
The table below gives information about assignment of C Function
blocks and files of MIK32 HAL library connected by them.
| Block C Function
| Purpose | Header files to be plugged in |
| :--------------------: | :----------- | :-----------: |
| systemClockConfig
| Initialising the HAL library, configuring the clocking subsystem and frequency monitor | mik32_hal.h
| |
| EnableInterrupts
| Enabling hardware interrupts, connecting interrupt handling | mik32_hal_irq.h
mik32_hal_adc_isr.h
|
| ADC4
| Setting up the ADC and getting new values | mik32_hal_adc.h
|
| USART1_print
| Setting up USART and sending messages to it | mik32_hal_usart.h
|
A more detailed description of the principles of code operation in C Function
blocks is given in the comments to the code.
Calculation of illumination¶
The built-in ADCs of the MIC32 have 12-bit digit capacity, therefore the signal ADCvalue
received from the ADC takes values in the range [0, 4095]. As stated earlier, this signal corresponds to the voltage drop $V_{R_1}$ on the current limiting resistor in the photoresistor circuit in the range [0, 1.2] V. In the block Get_LDR_Resistance
of the model, based on this signal, the resistance of the photoresistor $R_{LDR}$ is calculated by the formula
$$R_{LDR} = \left( \frac{V_{CC}}{V_{R_{1}}} - 1 \right ) \cdot R_1 = \left( \frac{11261}{V_{R_{1}}} - 1 \right ) \cdot 83$$
Based on the received signal Ohm
, the block 1-D Lookup Table
illuminance_from_resistance
generates an output illuminance signal Lux
. The approximate function parameterised by block illuminance_from_resistance
and linking illuminance and resistance is determined by the following points:
Освещенность = [4624,1895,1412,1129,929,773,646,538,445,363,290,223,162,107,55,7];
Сопротивление = [1,50,100,150,200,250,300,350,400,450,500,550,600,650,700,750];
using Plots, LaTeXStrings
gr( size = (400, 400), legend=:top, format=:svg )
plot(Сопротивление, Освещенность;
label = L"Lux = f(R_{LDR})", marker = (:circle, 3, :blue),
xaxis = ("Сопротивление фотодиода, Ом"), yaxis = ("Освещенность, Лк"))
These points are derived from the data sheets for the GL55 family of photoresistors.
Modelling results¶
To simulate the illuminance meter download and run model mik32_adc_lux.engee
:
if "mik32_adc_lux" in [m.name for m in engee.get_all_models()]
m = engee.open( "mik32_adc_lux" );
else
m = engee.load( "$(@__DIR__)/mik32_adc_lux.engee" );
end
данные = engee.run(m);
From the obtained simulation data we plot the signals: the value obtained from the ADC (simulation of sinusoidal variation of voltage drop) and the calculated illuminance. As in the block 1-D Lookup Table
the method of approximation "nearest" is chosen, illuminance as a result of calculations will take only those values, which were entered in the table of the block.
gr( size = (800, 300), legend=:top, format=:svg )
plot(данные["ADCvalue"].time, данные["ADCvalue"].value;
label = "Данные АЦП", lw = 2)
plot!(данные["Lux"].time, данные["Lux"].value*4;
label = "Освещенность, 4⋅лк", st = :step, lw = 2)
As can be seen from the obtained graphs, changing the signal from the ADC leads to corresponding changes in the calculated illuminance signal.
Code generation¶
Generate code from the model to then load the algorithm developed in the model into the microcontroller:
engee.generate_code( "$(@__DIR__)/mik32_adc_lux.engee",
"$(@__DIR__)/mik32_adc_lux_code")
The files created in the folder mik32_adc_lux_code
- header mik32_adc_lux.h
and source mik32_adc_lux.c
are used further on when building the project. The generated file of the main program main.c
will not be used in the project, for code execution in the development environment prepared by main.cpp
, located in the root folder mik32_adc_lux
of the example.
Preparing the project in the development environment¶
The development environment through which the project is built and loaded into the target device is VS Code with the PlatformIO add-on. The environment configurations and connections are not considered in this example, as they are described in detail at resources) of the controller developer.
From the example directory, let's transfer the generated files, main.cpp
, mik32_hal_adc_isr.h
and the configuration file platformio.ini
to the PlatformIO project.
After that you can proceed to build the project and load the programme.
Code execution on MIK32¶
Let's connect the debug board MIK32 NUKE V0.3 to the USB-port of the computer, then in PlatformIO we can observe the connected device. To correctly identify the connection of this board requires a USB driver. The driver used in the example is libusbK
.
After successful connection, let's proceed to the project building:
"PLATFORMIO -> PROJECT TASKS -> mik32v2 -> General -> Build ".
If there are no build errors, load the compiled code into the microcontroller:
"PLATFORMIO -> PROJECT TASKS -> mik32v2 -> General -> Upload ".
To output the calculation results we use the graph builder from the SerialPlot programme, which receives data from the serial port.
When the illumination on the photodiode changes (by shining a torch on it or shading it), a level-appropriate illumination value from the Lookup Table
model block is output to the serial port.
Conclusion¶
In this example we have considered the development of Engee model for the program of illumination calculation on the basis of ADC signal and output of the obtained value to the serial port on K1948VK018 MIK32 Amur microcontroller as a part of MIK32 NUKE V0.3 debug board. The developed model is embedded by generated files in the PlatformIO environment project for VS Code with further assembly, loading and execution on the target device.