The universal touch display can be used to virtualize monochrome or full color LCD displays of any resolution.
Developing embedded display applications just got way easier. The touch LCD display component can be used with any graphics library to develop and test all of your display menus and business logic on your local computer.
Writing to the touch LCD display from firmware simply involves writing to a memory buffer that contains the data for the LCD to display. You first need to create an LCD buffer to write to, and then expose the LCD buffer to Virtuoso. If your graphics library driver already uses a byte array internally, you can just expose that byte array without needing a virtual display driver. Creating a virtual display driver is simply a matter of routing display draw commands to write to some buffer, like this:
#define DISPLAY_WIDTH 640 // VGA Width
#define DISPLAY_HEIGHT 480 // VGA Height
#define PIXEL_SIZE 2 // RGB565 = 2 Bytes Per Pixel
unsigned char SIM_LCDBuffer[DISPLAY_WIDTH * DISPLAY_HEIGHT * PIXEL_SIZE];
Expose the byte array to your Target Model using the Target Model Builder, as shown.
Writes to the LCD buffer will automatically get detected by the Virtuoso framework, and be forwarded to the LCD. If you prefer to manually synchronize writes to the display buffer to avoid flickering for high update rates, you can also declare a flag variable in your target:
unsigned char SIM_LCDBufferUpdateFlag = 0;
Then select Manual Change Notification, using your update flag as the change notification. You can write this flag to 1 when you’re done writing to your LCD buffer, and everything will be taken care of for you.
If your LCD has a backlight, you’ll need a floating point variable to control the backlight intensity. Your virtual driver will just need to write a value from 0.0f to 1.0f to set the backlight intensity. Backlights can only be used with 1-, 4-, or 8-bits per pixel monochrome displays. Declare the variable in your virtual driver:
float SIM_LCDBacklightIntensity = 0.0f;
And expose this float as an output on the Target Model:
The last thing to set up, if you need it, is the touch input variables. An X and Y position are written to these firmware variables to update the position of the touch, and the LCDIsTouched variable is written when the touched state changes. You can also create a callback function to be called to notify your firmware whenever the LCDIsTouched variable changes, if you like.
float SIM_LCDTouchXPosition = 0.0f;
float SIM_LCDTouchYPosition = 0.0f;
unsigned char SIM_LCDIsTouched = 0;
// Handle like an interrupt
Add the variables to the target model, again all as inputs this time.
Note the selection of the SIM_LCDIsTouched callback handler for the SIM_LCDIsTouched variable below.
We now have the ability to write to our virtual display, control the backlight if needed, and receive touch inputs from the control.
Now add the LCD display control to the host view by opening MainWindow.xaml in the Solution Explorer, and dragging and dropping the TouchLCDDisplay control from the Virtuoso Standard Control Library Toolbox.
To the right of the LCD control, click the topmost icon to open the LCD Design Wizard.
The wizard dialog will open as shown below.
The configuration setting fields are described as follows:
- LCD View Model – Specifies the name to be used for the LCD view model property that is created for this view.
- Target – Specifies which Target contains the LCD properties to be bound to. A Virtuoso solution may host multiple embedded targets, and a separate view model is created for each target. These target view models are themselves a property of the ShellViewModel. This setting specifies which target view model property on the shell view model has the LCD buffer to be displayed, the touch screen input related variables.
- Target Variable Access Mode – Specifies the variable access mode type you will be binding to for the LCD display buffer. The LCD can bind to “Target Model Property” bindings or “Model Property Interface” bindings. Only variables created in the Target Model Builder with the specified Variable Access Mode will be available to select as the Display Buffer Property. The use of Model Property Interface bindings is recommended.
- Display Buffer Property – Specifies the property or property interface to be bound to on the target specified by the Target selection above. The LCD buffer must be first added to the Target Model class using the Target Model Builder, which manages and renders the Target Model class at design time. Add the LCD display buffer as a byte array to the Target Model using the Target Model Builder if you haven’t yet. It should be configured as an “OUTPUT [C->C#]”. The variable can be added as either a conventional target model property, or a “property interface”, which is itself an object. The use of a property interface is recommended. Start typing your LCD display buffer name after the target has been compiled, and text completion options will be presented to help find and select your variable. If your variable is not found, you might need to close the design wizard, rebuild your target project, and then reenter the design wizard settings.
- LCD Width – Specifies the display resolution width of the physical LCD display, in pixels. The Display Buffer size and format should match the LCD display resolution.
- LCD Height – Specifies the display resolution height of the LCD display, in pixels. The Display Buffer size and format should match the LCD display resolution.
- Display Width – Specifies the display width of the LCD, in pixels, as seen on the host view window. This can also be set in the Visual Studio properties for the control itself.
- Display Height – Specifies the display height of the LCD, in pixels, as seen on the host view window. This can also be set in the Visual Studio properties for the control itself.
- Pixel Format – Specifies the pixel format of the display buffer. The following pixel formats are supported:
- Monochrome 1 Bit Per Pixel
- Monochrome 4 Bits Per Pixel
- Monochrome 8 Bits Per Pixel
- Pixel Off Color – Specifies the pixel “Off” color for monochrome (1-, 4-, or 8-bits per pixel) color formats. This setting is not needed for non-monochrome pixel formats. Pixel values are converted from logical ranges to displayed colors. Logical ranges are 0-1 for 1bpp, 0-15 for 4bpp, and 0 to 255 for 8bpp. A pixel that is logically off has a value of 0, and a pixel that is logically at full intensity is thus 1, 15, or 255, respectively. The Pixel Off Color determines what color corresponds to a pixel being off. Usually, this is white or a white gray.
- Pixel On Color – Specifies the pixel “On” color for monochrome (1-, 4-, or 8-bits per pixel) color formats. This setting is again not needed for non-monochrome pixel formats. The Pixel On Color determines what color corresponds to a monochrome pixel being on at full intensity. Usually, this is black or close to black.
- Invert Pixel Intensity – This setting inverts the pixel logic used in the display buffer, in case it is needed to match the LCD control without having to modify graphic library source code. For 1bpp, the bit is inverted. For 4bpp, the result equals 15 minus the pixel buffer value. For 8bpp, the result equals 255 minus the pixel buffer value.
- Viewing Angle – Specifies the viewing angle for the LCD display. This setting can be used when the physical LCD is rotated in a product, but the display buffers of the graphics driver correspond to the unrotated pixels when being pushed to the physical LCD.
- Display Name – Can be used to add a label below the LCD.
- Touch Enabled – Specifies whether the LCD being virtualized supports touchscreen input from the user.
- Touch Point Units.
- Touch Pos X Property – Specifies a variable binding for specifying the X position of the screen being touched, when it is touched. A value of 0.0 corresponds to the left edge of the LCD, and a value of 1.0 corresponds to the right edge of the LCD. The variable binding should be a floating point ‘INPUT’ type binding that is added to the Target Model./li>
- 18. Touch Pos Y Property – Specifies a variable binding for specifying the Y position of the screen being touched, when it is touched. A value of 0.0 corresponds to the top edge of the LCD, and a value of 1.0 corresponds to the bottom edge of the LCD. The variable binding should be a floating point ‘INPUT’ type binding that is added to the Target Model.
- 19. IsLCDTouched Property – Specifies the variable binding to be used to notify the firmware that the virtual device user is currently left-clicking on the LCD. The firmware variable should be an unsigned char, and added to the Target Model as a Boolean ‘INPUT’ type variable binding. A callback in firmware can also be specified the Target Model Builder variable binding to provide event-driven notification of when the IsLCDTouched value changed. The firmware should use the state of this Boolean along with the X and Y position properties to read touch inputs from the user.
- Backlight Enabled – Specifies whether a monochrome LCD supports a backlight. This setting is only valid for monochrome (1-, 4-, or 8-bpp) display formats, since color LCDs use white LEDs. The virtual backlight is supported by using a ‘float’ variable binding with a value ranging from 0.0f to 1.0f. The control converts a combination of the logical pixel intensity and the backlight intensity to a correct color as seen by the eye with a physical transflective or transmissive LCD. If the pixel intensity is at fully intensity, this means it is blocking the backlight and absorbing sunlight, thus the viewed color will be independent of the backlight intensity for this color. With a pixel intensity set to zero, the viewed color for that pixel will be determined completely by the backlight intensity. When the pixel intensity and backlight intensities are at intermediate ranges, the corresponding correct color is computed and displayed.
- Backlight Intensity – If the backlight is enabled, you will be able to select a float variable binding to control the backlight intensity at runtime. The variable should be added to the Target View Model as an ‘OUTPUT’ variable binding, and at runtime the variable should range from 0.0f to 1.0f, with 0.0f corresponding to ‘Backlight Off’ and 1.0f corresponding to ‘Backlight On’.
- Backlight On Color – When a backlight is being virtualized, the ‘Backlight On Color’ specifies the color of the backlight LED. When the pixel intensity is zero and the backlight is at full intensity, the viewed color will match the ‘Backlight On’ color. This setting is only available when the ‘Backlight Intensity’ checkbox is checked. A Preview window shows the result of the color format, Pixel On Color, Pixel Off Color, and Backlight On Color selections at varying backlight intensities. The backlight intensity in the preview window can be adjusted using the ‘Backlight Intensity’ slider beneath the Preview LCD in the design wizard.
- Intensity Preview Slider – Controls the intensity for the preview view of the backlight configuration. This allows you to control the intensity of the background for the LCD in the preview window, so you can see how your LCD backlight will look with your current color settings (LCD Off, LCD On, and Backlight On). This slider shows what the Backlight Intensity input above will produce at different backlight intensities.
- Launch Image Converter… – Launches the image converter application to convert an image to a corresponding byte array declaration.
- Click “Submit” to submit the LCD configuration once all items have been specified. You may need to build your project to see the results updated in the XAML design view. The gauge may be resized as needed by clicking on the gauge in the XAML design time viewer and using the resize handles. When deleting a gauge from a view after it has been configured by the wizard, you should use the “Delete” icon below the “Wizard” icon. If a gauge hasn’t been configured yet, you will need to just click on the gauge and press the delete button to remove it from the view.The Image Converter application allows byte arrays to be generated from images using the appropriate display resolution and format. The resulting byte arrays can be compiled directly into your code. Clicking on the Launch Image Converter button launches the application, as shown.
You can load any image using the Browse Image… button, and then select the pixel format and resolution for the output image and click the “Convert” button to convert the image. Then you can either save the byte array for the converted image to a text file, or just copy the byte array ASCII text to the clipboard so you can paste it into an image array declaration in your code. The image data is a string of ASCII decimal byte values, i.e. “156, 158, … 255”.
When an LCD is dragged from the Virtuoso Standard Control Library to a window, this results in the XAML declaration as shown below to be added to the view.
The TouchLCDDisplay component wizard automates the configuration of the LCD view component as a normal MVVM view component, just like a TextBox or a Button. Using the wizard to configure the LCD as outlined above performs the following standard MVVM design tasks in the background:
1) A TouchLCDDisplayViewModel<Type, Type > component is added as a property of the specified Target ViewModel class, as shown below:
private TouchLCDDisplayViewModel _TouchLCDDisplayViewModel1;
public TouchLCDDisplayViewModel TouchLCDDisplayViewModel1
2) The TouchLCDDisplayViewModel component is constructed in the TargetViewModel initialization function based on the desired configuration. This is added as construction code in the Target ViewModel’s InitializeComponents method, as shown below.
_TouchLCDDisplayViewModel1 = new TouchLCDDisplayViewModel<IInt32Property,IInt32Property>(this,
SIM_LCDBuffer, 400, 272, LCDPixelFormat.Monochrome_1bpp, null, Color.FromArgb(0,0,0,0),
Color.FromArgb(255,220,221,220), Color.FromArgb(255,1,1,1), false, LCDViewingAngle._0, false, "");
3) The DataContext property for the TouchLCDDisplayView is bound to the new TouchLCDDisplayViewModel property exposed by the Target ViewModel, as shown below.