Init_Vars(): A STANDARD USER CODE ROUTINE FOR ALL V-TFT PROJECTS.
Here is a pre-release of a new topic coverage addition to the tutorial PDF for those following this thread.
If you do not already do this with your projects, you should find it useful.
(the pdf coverage will include figures, images and example code listings of other tricks/tips)
V-TFT provides a number of code editing/input windows in the advanced project options areas depending on what HW profile
you have selected and option boxes checked or not.
(the content will also change when changes to target compiler or target HardWare options are changed in V-TFT)
They are each actually a separate sub routine code editor for us to add our own code to be executed when that routine gets called and
they all get called (if present because enabled in V-TFT project settings and options), from the "Start_TP()" instruction that gets executed first
in the project 'main' file. This call sends program execution to that routine located (implemented) in the projects 'driver' file/module.
Other start up routines V-TFT needs executed get called from here and some can be called from a routine called from here too.
All V-TFT projects have a few routines that are always present in a project and get called from the "Start_TP()" routine, and one
always present is also the first routine code editor you see in the V-TFT project options dialog window labeled "
Init Code".
Code in this window shows up in the projects driver file in the routine named "
Init_MCU()".
A V-TFT project will not function correctly or at all if these 'Start-Up' routines do not get executed or you make a change to the code that
corrupts the HW configurations or prevents proper execution of those tasks.
The explanation of those tasks is not covered here, and will be covered in a different topic section.
I have mentioned them because just like their importance to making a functioning V-TFT project,
Your 'User Code' that you have to make to bring life to what you designed in V-TFT will require its own initializing routine to preset
many of the 'User Variables' your code uses in order to work (correctly) when it is started up and other MCU HW you need to use in the project initialized or preconfigured (PORT inputs/outputs).
Sounds like reasonable requirements assumption yes?
The problems V-TFT users have mostly with trying to comply to this requirement usually comes down to where to place the code where
it is safe from being overwritten by V-TFT when editing project in V-TFT.
Here is a practice/method I have developed and use that I find easy to implement and provides consistent successful results.
With its usage in all projects created, it also means you are keeping a lot of code that could be responsible for making your
project work or not in one consistent location for easier debugging checks and tests.
Here is a code listing of the CNC controller projects 'events_code' file and example User "Init_Vars()" routine and the first event handler routine that changes the menu buttons, and a listing of the 'main' file with the call that is also required:
*These are not completed/finished program code, it is work in progress and opportunity for me to put out V-TFT tips and tricks faster than updating the PDF manual right now. So enjoy while it lasts for this project.
Code: Select all
module PIC33EP_CNC_Stepper_events_code
include PIC33EP_CNC_Stepper_objects
include PIC33EP_CNC_Stepper_resources
include PIC33EP_CNC_Stepper_driver
sub procedure Scrn1Btn_Menu2_EDIT_OnClick()
.... '* edited to save space in post
sub procedure Scrn1Btn_MenuCHANGE_OnClick()
.... '* edited to save space in post
sub procedure Scrn1CrclBtn_HOME_OnClick()
'--------------------- Externals ---------------------'
'----------------- End of Externals ------------------'
'-------------- User code declarations ---------------'
' V-TFT Driver File DrawObject Routines for Project List
' DrawScreen()
' DrawButton(@)
' DrawRoundButton(@)
' DrawCRoundButton(@)
' DrawCLabel(@)
' DrawCircle(@)
' DrawCCircle(@)
' DrawCircleButton(@)
' DrawCCircleButton(@)
' User Code Routines declaration List (only routines called from outside this module need to be listed)
sub procedure Init_Vars()
' User Code Global Variables declarations
dim MENU_PAGE as byte
STEP_MODE as byte
PRESS_COUNT AS byte
X_AXIS as float
Y_AXIS as float
Z_AXIS as float
' User Code Global Array Variables for Shapes and Measurements and Axis Limits
dim SHAPE_RECTANGLE as float[3][8][2] '[3]x[4x2-POINT(X,Y)] [CUBED(Hi/Lo Z)] RECTANGLES
SHAPE_TRIANGLE as float[3][6][2] '[3]x[3x2-POINT(X,Y)] [CUBED(Hi/Lo Z)] TRIANGLES
SHAPE_CIRCLE as float[3][3][2] '[3]x[X, Y, Radius] [CUBED(Hi/Lo Z)] CIRCLES
MEASURE_X as float[3] '[X Axis StartX, EndX, Result]
MEASURE_Y as float[3] '[Y Axis StartY, EndY, Result]
MEASURE_Z as float[3] '[Z Axis StartZ, EndZ, Result]
LIMIT_X as float[3] '[2 X-points(Start,End), Inside(1)/Outside(0) Marked travel limits]
LIMIT_Y as float[3] '[2 Y-points(Start,End), Inside(1)/Outside(0) Marked travel limits]
LIMIT_Z as float[3] '[2 Z-points(Start,End), Inside(1)/Outside(0) Marked travel limits]
' User Code Global Constants declarations
'----------- End of User code declarations -----------'
implements
'--------------------- User code ---------------------'
sub procedure Init_Vars()
' Presets User Code Global Variables
' [Tutorial Comments]- Making this routine and code to Call-It (in main project file),
' first in all projects makes the Compiler include the variables and their memory
' allocations in the compilation result. Otherwise, the compiler would determine
' any declared variables not actually referenced by any code as something to eliminate
' from the program code and will not be accounted for in compiled memory usage results.
'
' This ensures you get a better sense of the resources your User Code will be using
' as you develop the application. As you add/declare Global variables to the code,
' put an entry here to assign a preset value so project statistics are accurate
' after a successful project build. Just declaring a variable does not ensure it
' stays present and accounted for in the final build.
dim X, Y as byte ' local temp variables
MENU_PAGE = 1
STEP_MODE = 1
PRESS_COUNT = 0
X_AXIS = 0
Y_AXIS = 0
Z_AXIS = 0
for X = 0 to 2 ' clear X,Y,Z measurement arrays
MEASURE_X[X] = 0
MEASURE_Y[X] = 0
MEASURE_Z[X] = 0
' clear X,Y,Z limits arrays
LIMIT_X[X] = 0
LIMIT_Y[X] = 0
LIMIT_Z[X] = 0
next X
X = 0
LIMIT_X[2] = 1 ' set default enforced areas to Inside axis points
LIMIT_Y[2] = 1
LIMIT_Z[2] = 1
for X = 0 to 2 ' clear the 3 rectangle shapes
for Y = 0 to 7
SHAPE_RECTANGLE[X][Y][0] = 0
SHAPE_RECTANGLE[X][Y][1] = 0
next Y
next X
X = 0 Y = 0
for X = 0 to 2 ' clear the 3 triangle shapes
for Y = 0 to 5
SHAPE_TRIANGLE[X][Y][0] = 0
SHAPE_TRIANGLE[X][Y][1] = 0
next Y
next X
X = 0 Y = 0
for X = 0 to 2 ' clear the 3 circle shapes
for Y = 0 to 2
SHAPE_CIRCLE[X][Y][0] = 0
SHAPE_CIRCLE[X][Y][1] = 0
next Y
next X
end sub
'----------------- End of User code ------------------'
' Event Handlers
'---------- Start of Screen1 Menu-1 Buttons handling
sub procedure Scrn1Btn_MenuCHANGE_OnClick()
' changes Active, Visible, Press color properties of 2 menu button sets (5 each)
if (MENU_PAGE = 1) then ' flip menus
MENU_PAGE = 2
else
MENU_PAGE = 1
end if
select case MENU_PAGE ' change properties and redraw current active set
case 1 ' Menu 1 set active
Scrn1Btn_MenuCHANGE__Caption = "MENU 1"
Scrn1Btn_MenuSMODE_.Visible = 1 '
Scrn1Btn_MenuSMODE_.Active = 1 ' Button 1
Scrn1Btn_MenuSMODE_.PressColEnabled = 1 '
Scrn1Btn_MenuLIMITS_.Visible = 1 '
Scrn1Btn_MenuLIMITS_.Active = 1 ' Button 2
Scrn1Btn_MenuLIMITS_.PressColEnabled = 1 '
Scrn1Btn_MenuALOCK_.Visible = 1 '
Scrn1Btn_MenuALOCK_.Active = 1 ' Button 3
Scrn1Btn_MenuALOCK_.PressColEnabled = 1 '
Scrn1Btn_MenuPLAY_.Visible = 1 '
Scrn1Btn_MenuPLAY_.Active = 1 ' Button 4
Scrn1Btn_MenuPLAY_.PressColEnabled = 1 '
Scrn1Btn_MenuRECORD_.Visible = 1 '
Scrn1Btn_MenuRECORD_.Active = 1 ' Button 5
Scrn1Btn_MenuRECORD_.PressColEnabled = 1 '
' set 2 buttons to false (inactive)
Scrn1Btn_Menu2_SHAPE_.Visible = 0 '
Scrn1Btn_Menu2_SHAPE_.Active = 0 ' Button 1
Scrn1Btn_Menu2_SHAPE_.PressColEnabled = 0 '
Scrn1Btn_Menu2_MEASUR_.Visible = 0 '
Scrn1Btn_Menu2_MEASUR_.Active = 0 ' Button 2
Scrn1Btn_Menu2_MEASUR_.PressColEnabled = 0 '
Scrn1Btn_Menu2_SAVREC_.Visible = 0 '
Scrn1Btn_Menu2_SAVREC_.Active = 0 ' Button 3
Scrn1Btn_Menu2_SAVREC_.PressColEnabled = 0 '
Scrn1Btn_Menu2_EDIT_.Visible = 0 '
Scrn1Btn_Menu2_EDIT_.Active = 0 ' Button 4
Scrn1Btn_Menu2_EDIT_.PressColEnabled = 0 '
Scrn1Btn_Menu2_SETUP_.Visible = 0 '
Scrn1Btn_Menu2_SETUP_.Active = 0 ' Button 5
Scrn1Btn_Menu2_SETUP_.PressColEnabled = 0 '
DrawButton(@Scrn1Btn_MenuSMODE_) ' redraw buttons to make visible.
DrawButton(@Scrn1Btn_MenuLIMITS_)
DrawButton(@Scrn1Btn_MenuALOCK_)
DrawButton(@Scrn1Btn_MenuPLAY_)
DrawButton(@Scrn1Btn_MenuRECORD_)
case 2 ' Menu 2 set active
Scrn1Btn_MenuCHANGE__Caption = "MENU 2"
Scrn1Btn_MenuSMODE_.Visible = 0 '
Scrn1Btn_MenuSMODE_.Active = 0 ' Button 1
Scrn1Btn_MenuSMODE_.PressColEnabled = 0 '
Scrn1Btn_MenuLIMITS_.Visible = 0 '
Scrn1Btn_MenuLIMITS_.Active = 0 ' Button 2
Scrn1Btn_MenuLIMITS_.PressColEnabled = 0 '
Scrn1Btn_MenuALOCK_.Visible = 0 '
Scrn1Btn_MenuALOCK_.Active = 0 ' Button 3
Scrn1Btn_MenuALOCK_.PressColEnabled = 0 '
Scrn1Btn_MenuPLAY_.Visible = 0 '
Scrn1Btn_MenuPLAY_.Active = 0 ' Button 4
Scrn1Btn_MenuPLAY_.PressColEnabled = 0 '
Scrn1Btn_MenuRECORD_.Visible = 0 '
Scrn1Btn_MenuRECORD_.Active = 0 ' Button 5
Scrn1Btn_MenuRECORD_.PressColEnabled = 0 '
' set 2 buttons to True (active)
Scrn1Btn_Menu2_SHAPE_.Visible = 1 '
Scrn1Btn_Menu2_SHAPE_.Active = 1 ' Button 1
Scrn1Btn_Menu2_SHAPE_.PressColEnabled = 1 '
Scrn1Btn_Menu2_MEASUR_.Visible = 1 '
Scrn1Btn_Menu2_MEASUR_.Active = 1 ' Button 2
Scrn1Btn_Menu2_MEASUR_.PressColEnabled = 1 '
Scrn1Btn_Menu2_SAVREC_.Visible = 1 '
Scrn1Btn_Menu2_SAVREC_.Active = 1 ' Button 3
Scrn1Btn_Menu2_SAVREC_.PressColEnabled = 1 '
Scrn1Btn_Menu2_EDIT_.Visible = 1 '
Scrn1Btn_Menu2_EDIT_.Active = 1 ' Button 4
Scrn1Btn_Menu2_EDIT_.PressColEnabled = 1 '
Scrn1Btn_Menu2_SETUP_.Visible = 1 '
Scrn1Btn_Menu2_SETUP_.Active = 1 ' Button 5
Scrn1Btn_Menu2_SETUP_.PressColEnabled = 1 '
DrawButton(@Scrn1Btn_Menu2_SHAPE_) ' redraw buttons to make visible.
DrawButton(@Scrn1Btn_Menu2_MEASUR_)
DrawButton(@Scrn1Btn_Menu2_SAVREC_)
DrawButton(@Scrn1Btn_Menu2_EDIT_)
DrawButton(@Scrn1Btn_Menu2_SETUP_)
end select
end sub
Code: Select all
' *
' * Project name:
' PIC33EP_CNC_Stepper.vtft
' * Generated by:
' Visual TFT
' * Date of creation
' 6/20/2014
' * Time of creation
' 11:25:43 AM
' * Test configuration:
' MCU: P33EP512MU810
' Dev.Board: Mikromedia_for_dsPIC33_EP
' Oscillator: 140000000 Hz
' SW: mikroBasic PRO for dsPIC
' http://www.mikroe.com/mikrobasic/dspic/
' *
program PIC33EP_CNC_Stepper_main
main:
' the "Init_Vars()" call could go here also and be executed first if needed
Start_TP()
Init_Vars() ' preload User Variables for start-up values
WS_Init()
while TRUE
Check_TP()
' the "Init_Vars()" call should NOT GO here inside the Main Loop.
wend
end.
The "Init_Vars()" call can also be placed in the V-TFT user "
Init_MCU()" routine that resides in the projects driver file as shown below.
- V-TFT User Init code editor.jpg (190.59 KiB) Viewed 15489 times
(Adding the routine call "Init_Vars()" code instruction to the "Init_MCU()" routine by editing in a compiler will get overwritten/erased
when project is rebuilt in V-TFT, it must be added to that routine by using the "Init Code" editing window in V-TFT.)
One thing I am trying to figure out if it can be done, is to have all of those properties in each button set
being pointed to a single variable that then is changed between 0 and 1 to basically turn off or on the whole
set of buttons and only require 1 instruction line to affect them all.??
*Additionally, a method that does this would be best if it did not require editing the objects properties listings in the project 'driver' or 'objects' file.
(trying to find a way that is safe from being overwritten by V_TFT when project is loaded back in for any editing)
This may not be possible though, pointers and references to variables is an area in programming I am still trying to get my head around,
so I am not sure there is a way to 'group' the properties desired together so they all 'look' at the same variable or memory location
by some code that exists only in the 'User Code' or 'User Declarations' safe areas in the "events_code" module.
Maybe aCkO will read this and understand what I'm attempting and show a solution. It is one of the things I
wanted to get a method figured out for this year for you other users to be able to take advantage of.
I think it could be a very useful trick for being able to manage multiple objects better, like making it easier to have 'pop-up' windows/panels
for additional input or messages displayed on the same screen.
The problem I am having trying to figure this out, is that the objects properties are in a structure and need to affect certain properties in multiple objects,
without breaking anything so V-TFT won't work when it is done.
The method should work out like this (simple example for one objects properties):
In 'events_code' user declarations a variable of type needed to hold the properties possible values (byte or word usually) for True and False is declared.
Now references or pointers are declared so the value in the User Code variable gets assigned to the objects properties we want tied together.
changing the User Code variable to either a 1 or 0 would be like changing each property tied together in the object just like doing it with
an assignment instruction for each property, without the need to execute that many instructions, then a redraw of either all objects
grouped like this or a complete screen redraw will reflect and show the changes it caused to those objects.
How to tie many structured variables (in different objects) to one variable or memory location?
Anyone with good understanding of variable pointers and references have any ideas? or questions for more info about this?
One solution I am contemplating is to make a copy of either the 'driver' or 'objects' files and try the most obvious pointer implementation
of modifying those properties declarations or assignments in the copy and change its module name slightly and change the includes to use it instead of the original.
This way, V-TFT will not overwrite the files contents because it will not load that module file in to V-TFT if project is opened in V-TFT again.
Editing changes will be reflected and done to the original file and need to be replicated by user to the alternate file and the includes declaration changed again to use it.
(opinions, comments or questions on this very welcomed)
But back to the posting topic now to close it out, I think this methodology with User variables is a good practice that everyone should consider using.
It has made my work with V-TFT projects go a lot smoother and allowed for easier editing of the variable elements when needed.
(and it works for all 3 compiler languages!)
Hope this installment gives you guys some ideas and insight for your projects, Robert.