The variable argument type String of the method removePersonDev must be the last parameter

本文详细解释了如何在Python方法中正确使用可变参数,强调了可变参数仅允许在参数列表末尾出现,并提供了相关实例。
部署运行你感兴趣的模型镜像

您可能感兴趣的与本文相关的镜像

Python3.8

Python3.8

Conda
Python

Python 是一种高级、解释型、通用的编程语言,以其简洁易读的语法而闻名,适用于广泛的应用,包括Web开发、数据分析、人工智能和自动化脚本

请查看以下的C++代码的编写要求,请根据代码要求开始编写代码 PURPOSE: This file is a proforma for the EEET2246 Laboratory Code Submission/Test 1. This file defines the assessment task which is worth 10% of course in total - there is no other documentation. At the BASIC FUNCTIONAL REQUIREMENTS level, your goal is to write a program that takes two numbers from the command line and perform and arithmetic operations with them. Additionally your program must be able to take three command line arguments where if the last argument is 'a' an addition is performed, and if 's' then subtraction is performed with the first two arguments. At the FUNCTIONAL REQUIREMENTS level you will be required to extend on the functionality so that the third argument can also be 'm' for multiplication,'d' for division and 'p' for exponential operations, using the first two arguments as the operands. Additionally, at this level basic error detection and handling will be required. The functionality of this lab is relatively simple: + - / * and "raised to the power of" The emphasis in this lab is to achieve the BASIC FUNCTIONALITY REQUIREMENTS first. Once you a basic program functioning then you should attempt the FUNCTIONALITY REQUIREMENTS and develop your code so that it can handle a full range of error detection and handling. ___________________________________________________________________________________________ ___ GENERAL SPECIFICATIONS (mostly common to all three EEET2246 Laboratory Code Submissions): G1. You must rename your file to lab1_1234567.cpp, where 1234567 is your student number. Your filename MUST NEVER EVER contain any spaces. _under_score_is_Fine. You do not need to include the 's' in front of your student number. Canvas will rename your submission by adding a -1, -2 etc. if you resubmit your solution file - This is acceptable. G2. Edit the name/email address string in the main() function to your student number, student email and student name. The format of the student ID line is CSV (Comma Separated Variables) with NO SPACES- student_id,student_email,student_name When the program is run without any operands i.e. simply the name of the executable such as: lab1_1234567.exe the program MUST print student ID string in Comma Separated Values (CSV) format with no spaces. For example the following text should be outputted to the console updated with your student details: "1234567,s1234567@student.rmit.edu.au,FirstName_LastName" G3. All outputs are a single error character or a numerical number, as specified by the FUNCTIONAL REQURMENTS, followed by a linefeed ( endl or \n). G4. DO NOT add more than what is specified to the expected console output. Do NOT add additional information, text or comments to the output console that are not defined within the SPECIFICATIONS/FUNCTIONAL REQURMENTS. G5. DO NOT use 'cin', system("pause"), getchar(), gets(), etc. type functions. Do NOT ask for user input from the keyboard. All input MUST be specified on the command line separated by blank spaces (i.e. use the argv and argc input parameters). G6. DO NOT use the characters: * / \ : ^ ? in your command line arguments as your user input. These are special character and may not be processed as expected, potentially resulting in undefined behaviour of your program. G7. All input MUST be specified on the command line separated by blank spaces (i.e. use the argc and argv[] input parameters). All input and output is case sensitive unless specified. G8. You should use the Integrated Debugging Environment (IDE) to change input arguments during the development process. G9. When your code exits the 'main()' function using the 'return' command, you MUST use zero as the return value. This requirement is for exiting the 'main()' function ONLY. A return value other than zero will indicate that something went wrong to the Autotester and no marks will be awarded. G10. User-defined functions and/or class declarations must be written before the 'main()' function. This is a requirement of the Autotester and failure to do so will result in your code scoring 0% as it will not be compiled correctly by the Autotester. Do NOT put any functions/class definitions after the 'main()' function or modify the comments and blank lines at the end of this file. G11. You MUST run this file as part of a Project - No other *.cpp or *.h files should be added to your solution. G12. You are not permitted to add any other #includes statements to your solution. The only libraries permitted to be used are the ones predefined in this file. G13. Under no circumstances is your code solution to contain any go_to labels - Please note that the '_' has been added to this description so that this file does not flag the Autotester. Code that contains go_to label like syntax will score 0% and will be treated as code that does not compile. G14. Under no circumstances is your code solution to contain any exit_(0) type functions. Please note that the '_' has been added to this description so that this file does not flag the Autotester. Your solution must always exit with a return 0; in main(). Code that contains exit_(0); label like syntax will score 0% and will be treated as code that does not compile. G15. Under no circumstances is your code solution to contain an infinite loop constructs within it. For example usage of while(1), for(int i; ; i++) or anything similar is not permitted. Code that contains an infinite loop will result in a score of 0% for your assessment submission and will be treated as code that does not compile. G16. Under no circumstances is your code solution to contain any S_l_e_e_p() or D_e_l_a_y() like statements - Please note that the '_' has been added to this description so that this file does not flag the Autotester. You can use such statements during your development, however you must remove delays or sleeps from your code prior to submission. This is important, as the Autotester will only give your solution a limited number of seconds to complete (i.e. return 0 in main()). Failure for your code to complete the required operation/s within the allotted execution window will result in the Autotester scoring your code 0 marks for that test. To test if your code will execute in the allotted execution window, check that it completes within a similar time frame as the provided sample binary. G17. Under no circumstances is your code solution to contain any characters from the extended ASCII character set or International typeset characters. Although such characters may compile under a normal system, they will result in your code potentially not compiling under the Autotester environment. Therefore, please ensure that you only use characters: a ... z, A ... Z, 0 ... 9 as your variable and function names or within any literal strings defined within your code. Literal strings can contain '.', '_', '-', and other basic symbols. G18. All output to console should be directed to the standard console (stdout) via cout. Do not use cerr or clog to print to the console. G19. The file you submit must compile without issues as a self contained *.cpp file. Code that does not compile will be graded as a non-negotiable zero mark. G20. All binary numbers within this document have the prefix 0b. This notation is not C++ compliant (depending on the C++ version), however is used to avoid confusion between decimal, hexadecimal and binary number formats within the description and specification provided in this document. For example the number 10 in decimal could be written as 0xA in hexadecimal or 0b1010 in binary. It can equally be written with leading zeroes such as: 0x0A or 0b00001010. For output to the console screen you should only ever display the numerical characters only and omit the 0x or 0b prefixes (unless it is specifically requested). ___________________________________________________________________________________________ ___ BASIC FUNCTIONAL REQUIREMENTS (doing these alone will only get you to approximately 40%): M1. For situation where NO command line arguments are passed to your program: M1.1 Your program must display your correct student details in the format: "3939723,s3939723@student.rmit.edu.au,Yang_Yang" M2. For situation where TWO command line arguments are passed to your program: M2.1 Your program must perform an addition operation, taking the first two arguments as the operands and display only the result to the console with a new line character. Example1: lab1_1234567.exe 10 2 which should calculate 10 + 2 = 12, i.e. the last (and only) line on the console will be: 12 M3. For situations where THREE command line arguments are passed to your program: M3.1 If the third argument is 'a', your program must perform an addition operation, taking the first two arguments as the operands and display only the result to the console with a new line character. M3.2 If the third argument is 's', your program must perform a subtraction operation, taking the first two arguments as the operands and display only the result to the console with a new line character. The second input argument should be subtracted from the first input argument. M4. For situations where less than TWO or more than THREE command line arguments are passed to your program, your program must display the character 'P' to the console with a new line character. M5. For specifications M1 to M4 inclusive: M5.1 Program must return 0 under all situations at exit. M5.2 Program must be able to handle integer arguments. M5.3 Program must be able to handle floating point arguments. M5.4 Program must be able to handle one integer and one floating point argument in any order. Example2: lab1_1234567.exe 10 2 s which should calculate 10 - 2 = 8, i.e. the last (and only) line on the console will be: 8 Example3: lab1_1234567.exe 10 2 which should calculate 10 + 2 = 12, i.e. the last (and only) line on the console will be: 12 Example4: lab1_1234567.exe 10 4 a which should calculate 10 + 4 = 14, i.e. the last (and only) line on the console will be: 14 ___________________________________________________________________________________________ ___ FUNCTIONAL REQUIREMENTS (to get over approximately 50%): E1. For situations where THREE command line arguments (other than 'a' or 's') are passed to your program: E1.1 If the third argument is 'm', your program must perform a multiplication operation, taking the first two arguments as the operands and display only the result to the console with a new line character. E1.2 If the third argument is 'd', your program must perform a division operation, taking the first two arguments as the operands and display only the result to the console with a new line character. E1.3 If the third argument is 'p', your program must perform an exponential operation, taking the first argument as the base operand and the second as the exponent operand. The result must be display to the console with a new line character. Hint: Consider using the pow() function, which has the definition: double pow(double base, double exponent); Example5: lab1_1234567.exe 10 2 d which should calculate 10 / 2 = 5, i.e. the last (and only) line on the console will be: 5 Example6: lab1_1234567.exe 10 2 p which should calculate 10 to power of 2 = 100, i.e. the last (and only) line on the console will be: 100 NOTE1: DO NOT use the character ^ in your command line arguments as your user input. Question: Why don't we use characters such as + - * / ^ ? to determine the operation? Answer: Arguments passed via the command line are processed by the operating system before being passed to your program. During this process, special characters such as + - * / ^ ? are stripped from the input argument stream. Therefore, the input characters: + - * / ^ ? will not be tested for by the autotester. See sections G6 and E7. NOTE2: the pow() and powl() function/s only work correctly for given arguments. Hence, your code should output and error if there is a domain error or undefined subset of values. For example, if the result does not produce a real number you code should handle this as an error. This means that if the base is negative you can't accept and exponent between (but not including) -1 and 1. If you get this then, output a MURPHY's LAW error: "Y" and return 0; NOTE3: zero to the power of zero is also undefined, and should also be treated MURPHY's LAW error. So return "Y" and return 0; In Visual Studio, the 0 to the power of 0 will return 1, so you will need to catch this situation manually, else your code will likely calculate the value as 1. ___ REQUIRED ERROR HANDLING (to get over approximately 70%): The following text lists errors you must detect and a priority of testing. NB: order of testing is important as each test is slight more difficult than the previous test. All outputs should either be numerical or upper-case single characters (followed by a new line). Note that case is important: In C, 'V' is not the same as 'v'. (No quotes are required on the output). E2. Valid operator input: If the third input argument is not a valid operation selection, the output shall be 'V'. Valid operators are ONLY (case sensitive): a addition s subtraction m multiplication d division p exponentiation i.e. to the power of: 2 to the power of 3 = 8 (base exponent p) E3. Basic invalid number detection (Required): Valid numbers are all numbers that the "average Engineering graduate" in Australia would consider valid. Therefore if the first two arguments are not valid decimal numbers, the output shall be 'X'. For example: -130 is valid +100 is valid 1.3 is valid 3 is valid 0.3 is valid .3 is valid ABC123 is not valid 1.3.4 is not valid 123abc is not valid ___ ERROR HANDLING (not marked by the autotester): E4. Intermediate invalid number detection (NOT TESTED BY AUTOTESTER - for your consideration only): If the first two arguments are not valid decimal numbers, the output shall be 'X'. Using comma punctuated numbers and scientific formatted numbers are considered valid. For example: 0000.111 is valid 3,000 is valid - NB: atof() will read this as '3' not as 3000 1,000.9 is valid - NB: atof() will read this as '1' not as 1000.9 1.23e2 is valid 2E2 is valid -3e-0.5 is not valid (an integer must follow after the e or E for floating point number to be valid) 2E2.1 is not valid e-1 is not valid .e3 is not valid E5. Advanced invalid number detection (NOT TESTED BY AUTOTESTER - for your consideration only): If the first two arguments are not valid decimal numbers, the output shall be 'X'. 1.3e-1 is valid 1,00.0 is valid - NB: if the comma is not removed atof() will read this as '1' not as 100 +212+21-2 is not valid - NB: mathematical operation on a number of numbers, not ONE number 5/2 is not valid - NB: mathematical operation on a number of numbers, not ONE number HINT: consider the function atof(), which has the definition: double atof (const char* str); Checking the user input for multiple operators (i.e. + or -) is quite a difficult task. One method may involve writing a 'for' loop which steps through the input argv[] counting the number of operators. This process could also be used to count for decimal points and the like. The multiple operator check should be considered an advanced task and developed once the rest of the code is operational. E6. Input number range checking: All input numbers must be between (and including) +2^16 (65536) or -2^16 (-65536). If the operand is out of range i.e. too small or too big, the output shall be 'R'. LARGE NUMBERS: is 1.2e+999 acceptable input ? what happens if you enter such a number ? try and see. Hint: #INF error - where and when does it come up ? SMALL NUMBERS: is 1.2e-999 acceptable input ? what happens if you enter such a number ? try and see. Test it by writing your own test program. E7. ERROR checks which will NOT be performed are: E7.1 Input characters such as: *.* or / or \ or : or any of these characters: * / ^ ? will not be tested for. E7.2 Range check: some computer systems accept numbers of size 9999e999999 while others flag and infinity error. An infinity error becomes an invalid input Therefore: input for valid numbers will only be tested to the maximum 9.9e99 (Note: 9.9e99 is out of range and your program should output 'R') E8. Division by zero should produce output 'M' E9. Error precedence: If multiple errors occur during a program execution event, your program should only display one error code followed by a newline character and then exit (using a return 0; statement). In general, the precedence of the error reported to the console should be displayed in the order that they appear within this proforma. However to clarify the exact order or precedence for the error characters, the precedence of the displayed error code should occur in this order: 'P' - Incorrect number of input command line arguments (see M4) 'X' - Invalid numerical command line argument 'V' - Invalid third input argument 'R' - operand (command line argument) value out of range 'M' - Division by zero 'Y' - MURPHY'S LAW (undefined error) Therefore if an invalid numerical command line argument and an invalid operation argument are passed to the program, the first error code should be displayed to the console, which in this case would be 'X'. Displaying 'V' or 'Y' would be result in a loss of marks. E10. ANYTHING ELSE THAT CAN GO WRONG (MURPHY'S LAW TEST): If there are any other kinds of errors not covered here, the output shall be 'Y'. Rhetorical question: What for example are the error codes that the Power function returns ? If this happens then the output shall be 'Y'. See section E1.3, NOTE2. ___________________________________________________________________________________________ ___ HINTS: - Use debug mode and a breakpoint at the return statement prior to program finish in main. - What string conversion routines, do you know how to convert strings to number? Look carefully as they will be needed to convert a command line parameter to a number and also check for errors. - ERROR CHECKING: The basic programming rules are simple (as covered in lectures): 1) check that the input is valid. 2) check that the output is valid. 3) if any library function returns an error code USE IT !!! CHECK FOR IT !!! - Most conversion routines do have inbuilt error checking - USE IT !!! That means: test for the error condition and take some action if the error is true. If that means more than 50% of your code is error checking, then that's the way it has to be. ____________________________________________________________________________________________ */ // These are the libraries you are allowed to use to write your solution. Do not add any // additional libraries as the auto-tester will be locked down to the following: #include <iostream> #include <cstdlib> #include <time.h> #include <math.h> #include <errno.h> // leave this one in please, it is required by the Autotester! // Do NOT Add or remove any #include statements to this project!! // All library functions required should be covered by the above // include list. Do not add a *.h file for this project as all your // code should be included in this file. using namespace std; const double MAXRANGE = pow(2.0, 16.0); // 65536 const double MINRANGE = -pow(2.0, 16.0); // All functions to be defined below and above main() - NO exceptions !!! Do NOT // define function below main() as your code will fail to compile in the auto-tester. // WRITE ANY USER DEFINED FUNCTIONS HERE (optional) // all function definitions and prototypes to be defined above this line - NO exceptions !!! int main(int argc, char *argv[]) { // ALL CODE (excluding variable declarations) MUST come after the following 'if' statement if (argc == 1) { // When run with just the program name (no parameters) your code MUST print // student ID string in CSV format. i.e. // "studentNumber,student_email,student_name" // eg: "3939723,s3939723@student.rmit.edu.au,Yang_Yang" // No parameters on command line just the program name // Edit string below: eg: "studentNumber,student_email,student_name" cout << "3939723,s3939723@student.rmit.edu.au,Yang_Yang" << endl; // Failure of your program to do this cout statement correctly will result in a // flat 10% marks penalty! Check this outputs correctly when no arguments are // passed to your program before you submit your file! Do it as your last test! // The convention is to return Zero to signal NO ERRORS (please do not change it). return 0; } //--- START YOUR CODE HERE. // The convention is to return Zero to signal NO ERRORS (please do not change it). // If you change it the AutoTester will assume you have made some major error. return 0; } // No code to be placed below this line - all functions to be defined above main() function. // End of file.
08-16
帮我翻译:Bindings for LVGL This repo is a submodule of lv_micropython. Please fork lv_micropython for a quick start with LVGL MicroPython Bindings. See also Micropython + LittlevGL blog post. (LittlevGL is the previous name of LVGL.) For advanced features, see Pure MicroPython Display Driver blog post. For questions and discussions - please use the forum: https://forum.lvgl.io/c/micropython MicroPython MicroPython Binding for LVGL provides an automatically generated MicroPython module with classes and functions that allow the user access much of the LVGL library. The module is generated automatically by the script gen_mpy.py. This script reads, preprocesses and parses LVGL header files, and generates a C file lv_mpy.c which defines the MicroPython module (API) for accessing LVGL from MicroPython. Micopython's build script (Makefile or CMake) should run gen_mpy.py automatically to generate and compile lv_mpy.c. If you would like to see an example of how a generated lv_mpy.c looks like, have a look at lv_mpy_example.c. Note that its only exported (non static) symbol is mp_module_lvgl which should be registered in MicroPython as a module. lv_binding_micropython is usually used as a git submodule of lv_micropython which builds MicroPython + LVGL + lvgl-bindings, but can also be used on other forks of MicroPython. It's worth noting that the Micropython Bindings module (lv_mpy.c) is dependent on LVGL configuration. LVGL is configured by lv_conf.h where different objects and features could be enabled or disabled. LVGL bindings are generated only for the enabled objects and features. Changing lv_conf.h requires re running gen_mpy.py, therefore it's useful to run it automatically in the build script, as done by lv_micropython. Memory Management When LVGL is built as a MicroPython library, it is configured to allocate memory using MicroPython memory allocation functions and take advantage of MicroPython Garbage Collection ("gc"). This means that structs allocated for LVGL use don't need to be deallocated explicitly, gc takes care of that. For this to work correctly, LVGL is configured to use gc and to use MicroPython's memory allocation functions, and also register all LVGL "root" global variables to MicroPython's gc. From the user's perspective, structs can be created and will be collected by gc when they are no longer referenced. However, LVGL screen objects (lv.obj with no parent) are automatically assigned to default display, therefore not collected by gc even when no longer explicitly referenced. When you want to free a screen and all its descendants so gc could collect their memory, make sure you call screen.delete() when you no longer need it. Make sure you keep a reference to your display driver and input driver to prevent them from being collected. Concurrency This implementation of MicroPython Bindings to LVGL assumes that MicroPython and LVGL are running on a single thread and on the same thread (or alternatively, running without multithreading at all). No synchronization means (locks, mutexes) are taken. However, asynchronous calls to LVGL still take place periodically for screen refresh and other LVGL tasks such as animation. This is achieved by using the internal MicroPython scheduler (that must be enabled), by calling mp_sched_schedule. mp_sched_schedule is called when screen needs to be refreshed. LVGL expects the function lv_task_handler to be called periodically (see lvgl/README.md#porting). This is usually handled in the display device driver. Here is an example of calling lv_task_handler with mp_sched_schedule for refreshing LVGL. mp_lv_task_handler is scheduled to run on the same thread MicroPython is running, and it calls both lv_task_handler for LVGL task handling and monitor_sdl_refr_core for refreshing the display and handling mouse events. With REPL (interactive console), when waiting for the user input, asynchronous events can also happen. In this example we just call mp_handle_pending periodically when waiting for a keypress. mp_handle_pending takes care of dispatching asynchronous events registered with mp_sched_schedule. Structs Classes and globals The LVGL binding script parses LVGL headers and provides API to access LVGL classes (such as btn) and structs (such as color_t). All structs and classes are available under lvgl micropython module. lvgl Class contains: functions (such as set_x) enums related to that class (such as STATE of a btn) lvgl struct contains only attributes that can be read or written. For example: c = lvgl.color_t() c.ch.red = 0xff structs can also be initialized from dict. For example, the example above can be written like this: c = lvgl.color_t({'ch': {'red' : 0xff}}) All lvgl globals (functions, enums, types) are available under lvgl module. For example, lvgl.SYMBOL is an "enum" of symbol strings, lvgl.anim_create will create animation etc. Callbacks In C a callback is a function pointer. In MicroPython we would also need to register a MicroPython callable object for each callback. Therefore in the MicroPython binding we need to register both a function pointer and a MicroPython object for every callback. Therefore we defined a callback convention that expects lvgl headers to be defined in a certain way. Callbacks that are declared according to the convention would allow the binding to register a MicroPython object next to the function pointer when registering a callback, and access that object when the callback is called. The MicroPython callable object is automatically saved in a user_data variable which is provided when registering or calling the callback. The callback convention assumes the following: There's a struct that contains a field called void * user_data. A pointer to that struct is provided as the first argument of a callback registration function. A pointer to that struct is provided as the first argument of the callback itself. Another option is that the callback function pointer is just a field of a struct, in that case we expect the same struct to contain user_data field as well. Another option is: A parameter called void * user_data is provided to the registration function as the last argument. The callback itself receives void * as the last argument In this case, the user should provide either None or a dict as the user_data argument of the registration function. The callback will receive a Blob which can be casted to the dict in the last argument. (See async_call example below) As long as the convention above is followed, the lvgl MicroPython binding script would automatically set and use user_data when callbacks are set and used. From the user perspective, any python callable object (such as python regular function, class function, lambda etc.) can be user as an lvgl callbacks. For example: lvgl.anim_set_custom_exec_cb(anim, lambda anim, val, obj=obj: obj.set_y(val)) In this example an exec callback is registered for an animation anim, which would animate the y coordinate of obj. An lvgl API function can also be used as a callback directly, so the example above could also be written like this: lv.anim_set_exec_cb(anim, obj, obj.set_y) lvgl callbacks that do not follow the Callback Convention cannot be used with micropython callable objects. A discussion related to adjusting lvgl callbacks to the convention: lvgl/lvgl#1036 The user_data field must not be used directly by the user, since it is used internally to hold pointers to MicroPython objects. Display and Input Drivers LVGL can be configured to use different displays and different input devices. More information is available on LVGL documentation. Registering a driver is essentially calling a registration function (for example disp_drv_register) and passing a function pointer as a parameter (actually a struct that contains function pointers). The function pointer is used to access the actual display / input device. When implementing a display or input LVGL driver with MicroPython, there are 3 option: Implement a Pure Python driver. It the easiest way to implement a driver, but may perform poorly Implement a Pure C driver. Implemnent a Hybrid driver where the critical parts (such as the flush function) are in C, and the non-critical part (such as initializing the display) are implemented in Python. An example of Pure/Hybrid driver is the ili9XXX.py. The driver registration should eventually be performed in the MicroPython script, either in the driver code itself in case of the pure/hybrid driver or in user code in case of C driver (for example, in the case of the SDL driver). Registering the driver on Python and not in C is important to make it easy for the user to select and replace drivers without building the project and changing C files. When creating a display or input LVGL driver, make sure you let the user configure all parameters on runtime, such as SPI pins, frequency, etc. Eventually the user would want to build the firmware once and use the same driver in different configuration without re-building the C project. This is different from standard LVGL C drivers where you usually use macros to configure parameters and require the user to re-build when any configurations changes. Example: # Initialize ILI9341 display from ili9XXX import ili9341 self.disp = ili9341(dc=32, cs=33, power=-1, backlight=-1) # Register xpt2046 touch driver from xpt2046 import xpt2046 self.touch = xpt2046() Example: # init import lvgl as lv lv.init() from lv_utils import event_loop WIDTH = 480 HEIGHT = 320 event_loop = event_loop() disp_drv = lv.sdl_window_create(WIDTH, HEIGHT) mouse = lv.sdl_mouse_create() keyboard = lv.sdl_keyboard_create() keyboard.set_group(self.group) In this example we use LVGL built in LVGL driver. Currently supported drivers for Micropyton are LVGL built-in drivers such use the unix/Linux SDL (display, mouse, keyboard) and Frame Buffer (/dev/fb0) ILI9341 driver for ESP32 XPT2046 driver for ESP32 FT6X36 (capacitive touch IC) for ESP32 Raw Resistive Touch for ESP32 (ADC connected to screen directly, no touch IC) Driver code is under /driver directory. Drivers can also be implemented in pure MicroPython, by providing callbacks (disp_drv.flush_cb, indev_drv.read_cb etc.) Currently the supported ILI9341, FT6X36 and XPT2046 are pure micropython drivers. Where are the drivers? LVGL C drivers and MicroPython drivers (either C or Python) are separate and independent from each other. The main reason is configuration: The C driver is usually configured with C macros (which pins it uses, frequency, etc.) Any configuration change requires rebuilding the firmware but that's understandable since any change in the application requires rebuilding the firmware anyway. In MicroPython the driver is built once with MicroPython firmware (if it's a C driver) or not built at all (if it's pure Python driver). On runtime the user initializes the driver and configures it. If the user switches SPI pins or some other configuration, there is no need to rebuild the firmware, just change the Python script and initialize the driver differently on runtime. So the location for MicroPython drivers is https://github.com/lvgl/lv_binding_micropython/tree/master/driver and is unrelated to https://github.com/lvgl/lv_drivers. The Event Loop LVGL requires an Event Loop to re-draw the screen, handle user input etc. The default Event Loop is implement in lv_utils.py which uses MicroPython Timer to schedule calls to LVGL. It also supports running the Event Loop in uasyncio if needed. Some drivers start the event loop automatically if it doesn't already run. To configure the event loop for these drivers, just initialize the event loop before registering the driver. LVGL native drivers, such as the SDL driver, do not start the event loop. You must start the event loop explicitly otherwise screen will not refresh. The event loop can be started like this: from lv_utils import event_loop event_loop = event_loop() and you can configure it by providing parameters, see lv_utils.py for more details. Adding MicroPython Bindings to a project An example project of "MicroPython + lvgl + Bindings" is lv_mpy. Here is a procedure for adding lvgl to an existing MicroPython project. (The examples in this list are taken from lv_mpy): Add lv_bindings as a sub-module under lib. Add lv_conf.h in lib Edit the Makefile to run gen_mpy.py and build its product automatically. Here is an example. Register lvgl module and display/input drivers in MicroPython as a builtin module. An example. Add lvgl roots to gc roots. An example. Configure lvgl to use Garbage Collection by setting several LV_MEM_CUSTOM_* and LV_GC_* macros example lv_conf.h was moved to lv_binding_micropython git module. Make sure you configure partitions correctly in partitions.csv and leave enough room for the LVGL module. Something I forgot? Please let me know. gen_mpy.py syntax usage: gen_mpy.py [-h] [-I <Include Path>] [-D <Macro Name>] [-E <Preprocessed File>] [-M <Module name string>] [-MP <Prefix string>] [-MD <MetaData File Name>] input [input ...] positional arguments: input optional arguments: -h, --help show this help message and exit -I <Include Path>, --include <Include Path> Preprocessor include path -D <Macro Name>, --define <Macro Name> Define preprocessor macro -E <Preprocessed File>, --external-preprocessing <Preprocessed File> Prevent preprocessing. Assume input file is already preprocessed -M <Module name string>, --module_name <Module name string> Module name -MP <Prefix string>, --module_prefix <Prefix string> Module prefix that starts every function name -MD <MetaData File Name>, --metadata <MetaData File Name> Optional file to emit metadata (introspection) Example: python gen_mpy.py -MD lv_mpy_example.json -M lvgl -MP lv -I../../berkeley-db-1.xx/PORT/include -I../../lv_binding_micropython -I. -I../.. -Ibuild -I../../mp-readline -I ../../lv_binding_micropython/pycparser/utils/fake_libc_include ../../lv_binding_micropython/lvgl/lvgl.h Binding other C libraries The lvgl binding script can be used to bind other C libraries to MicroPython. I used it with lodepng and with parts of ESP-IDF. For more details please read this blog post. MicroPython Bindings Usage A simple example: advanced_demo.py. More examples can be found under /examples folder. Importing and Initializing LVGL import lvgl as lv lv.init() Registering Display and Input drivers from lv_utils import event_loop WIDTH = 480 HEIGHT = 320 event_loop = event_loop() disp_drv = lv.sdl_window_create(WIDTH, HEIGHT) mouse = lv.sdl_mouse_create() keyboard = lv.sdl_keyboard_create() keyboard.set_group(self.group) In this example, LVGL native SDL display and input drivers are registered on a unix port of MicroPython. Here is an alternative example for ESP32 ILI9341 + XPT2046 drivers: import lvgl as lv # Import ILI9341 driver and initialized it from ili9XXX import ili9341 disp = ili9341() # Import XPT2046 driver and initialize it from xpt2046 import xpt2046 touch = xpt2046() By default, both ILI9341 and XPT2046 are initialized on the same SPI bus with the following parameters: ILI9341: miso=5, mosi=18, clk=19, cs=13, dc=12, rst=4, power=14, backlight=15, spihost=esp.HSPI_HOST, mhz=40, factor=4, hybrid=True XPT2046: cs=25, spihost=esp.HSPI_HOST, mhz=5, max_cmds=16, cal_x0 = 3783, cal_y0 = 3948, cal_x1 = 242, cal_y1 = 423, transpose = True, samples = 3 You can change any of these parameters on ili9341/xpt2046 constructor. You can also initialize them on different SPI buses if you want, by providing miso/mosi/clk parameters. Set them to -1 to use existing (initialized) spihost bus. Here's another example, this time importing and initialising display and touch drivers for the M5Stack Core2 device, which uses an FT6336 chip on the I2C bus to read from its capacitive touch screen and uses an ili9342 display controller, which has some inverted signals compared to the ili9341: from ili9XXX import ili9341 disp = ili9341(mosi=23, miso=38, clk=18, dc=15, cs=5, invert=True, rot=0x10) from ft6x36 import ft6x36 touch = ft6x36(sda=21, scl=22, width=320, height=280) Driver init parameters Many different display modules can be supported by providing the driver's init method with width, height, start_x, start_y, colormode, invert and rot parameters. Display size The width and height parameters should be set to the width and height of the display in the orientation the display will be used. Displays may have an internal framebuffer that is larger than the visible display. The start_x and start_y parameters are used to indicate where visible pixels begin relative to the start of the internal framebuffer. Color handling The colormode and invert parameters control how the display processes color. Display orientation The rot parameter is used to set the MADCTL register of the display. The MADCTL register controls the order that pixels are written to the framebuffer. This sets the Orientation or Rotation of the display. See the README.md file in the examples/madctl directory for more information on the MADCTL register and how to determine the colormode and rot parameters for a display. st7789 driver class By default, the st7789 driver is initialized with the following parameters that are compatible with the TTGO T-Display: st7789( miso=-1, mosi=19, clk=18, cs=5, dc=16, rst=23, power=-1, backlight=4, backlight_on=1, power_on=0, spihost=esp.HSPI_HOST, mhz=40, factor=4, hybrid=True, width=320, height=240, start_x=0, start_y=0, colormode=COLOR_MODE_BGR, rot=PORTRAIT, invert=True, double_buffer=True, half_duplex=True, asynchronous=False, initialize=True) Parameter Description miso Pin for SPI Data from display, -1 if not used as many st7789 displays do not have this pin mosi Pin for SPI Data to display (REQUIRED) clk Pin for SPI Clock (REQUIRED) cs Pin for display CS dc Pin for display DC (REQUIRED) rst Pin for display RESET power Pin for display Power ON, -1 if not used power_on Pin value for Power ON backlight Pin for display backlight control backlight_on Pin value for backlight on spihost ESP SPI Port mhz SPI baud rate in mhz factor Decrease frame buffer by factor hybrid Boolean, True to use C refresh routine, False for pure Python driver width Display width height Display height colormode Display colormode rot Display orientation, PORTRAIT, LANDSCAPE, INVERSE_PORTRAIT, INVERSE_LANDSCAPE or Raw MADCTL value that will be OR'ed with colormode invert Display invert colors setting double_buffer Boolean, True to use double buffering, False to use single buffer (saves memory) half_duplex Boolean, True to use half duplex SPI communications asynchronous Boolean, True to use asynchronous routines initialize Boolean, True to initialize display TTGO T-Display st7789 Configuration example import lvgl as lv from ili9XXX import st7789 disp = st7789(width=135, height=240, rot=st7789.LANDSCAPE) TTGO TWatch-2020 st7789 Configuration example import lvgl as lv from ili9XXX import st7789 import axp202c # init power manager, set backlight axp = axp202c.PMU() axp.enablePower(axp202c.AXP202_LDO2) axp.setLDO2Voltage(2800) # init display disp = st7789( mosi=19, clk=18, cs=5, dc=27, rst=-1, backlight=12, power=-1, width=240, height=240, rot=st7789.INVERSE_PORTRAIT, factor=4) st7735 driver class By default, the st7735 driver is initialized with the following parameters. The parameter descriptions are the same as the st7789. st7735( miso=-1, mosi=19, clk=18, cs=13, dc=12, rst=4, power=-1, backlight=15, backlight_on=1, power_on=0, spihost=esp.HSPI_HOST, mhz=40, factor=4, hybrid=True, width=128, height=160, start_x=0, start_y=0, colormode=COLOR_MODE_RGB, rot=PORTRAIT, invert=False, double_buffer=True, half_duplex=True, asynchronous=False, initialize=True): ST7735 128x128 Configuration Example from ili9XXX import st7735, MADCTL_MX, MADCTL_MY disp = st7735( mhz=3, mosi=18, clk=19, cs=13, dc=12, rst=4, power=-1, backlight=15, backlight_on=1, width=128, height=128, start_x=2, start_y=1, rot=PORTRAIT) ST7735 128x160 Configuration Example from ili9XXX import st7735, COLOR_MODE_RGB, MADCTL_MX, MADCTL_MY disp = st7735( mhz=3, mosi=18, clk=19, cs=13, dc=12, rst=4, backlight=15, backlight_on=1, width=128, height=160, rot=PORTRAIT) Creating a screen with a button and a label scr = lv.obj() btn = lv.button(scr) btn.align(lv.scr_act(), lv.ALIGN.CENTER, 0, 0) label = lv.label(btn) label.set_text("Button") # Load the screen lv.scr_load(scr) Creating an instance of a struct symbolstyle = lv.style_t(lv.style_plain) symbolstyle would be an instance of lv_style_t initialized to the same value of lv_style_plain Setting a field in a struct symbolstyle.text.color = lv.color_hex(0xffffff) symbolstyle.text.color would be initialized to the color struct returned by lv_color_hex Setting a nested struct using dict symbolstyle.text.color = {"red":0xff, "green":0xff, "blue":0xff} Creating an instance of an object self.tabview = lv.tabview(lv.scr_act()) The first argument to an object constructor is the parent object, the second is which element to copy this element from. Both arguments are optional. Calling an object method self.symbol.align(self, lv.ALIGN.CENTER,0,0) In this example lv.ALIGN is an enum and lv.ALIGN.CENTER is an enum member (an integer value). Using callbacks for btn, name in [(self.btn1, 'Play'), (self.btn2, 'Pause')]: btn.set_event_cb(lambda obj=None, event=-1, name=name: self.label.set_text('%s %s' % (name, get_member_name(lv.EVENT, event)))) Using callback with user_data argument: def cb(user_data): print(user_data.cast()['value']) lv.async_call(cb, {'value':42}) Listing available functions/members/constants etc. print('\n'.join(dir(lvgl))) print('\n'.join(dir(lvgl.btn))) ...
最新发布
12-24
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ZHOU_VIP

您的鼓励将是我创作最大的动力!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值