Friday 4 July 2014

mbed 4D Systems Display Tutorial with a rockerSW object

I have been continuing to play around with the mbed microcontroller and the 4D Systems 4.3" Capacitive touch screen display.  I thought I would document my findings and write a tutorial.  One of the objects I have been struggling to use is the 'rocker switch' object.  It's a an object provided by 4D systems in the visi-genie development suite.  I decided that I really need to be able to use all of the objects available properly and control them via the mbed.  I will try and write posts which show how to use and control each object.  Hopefully this will make things easier for other people who are looking to develop hardware using the mbed and the 4D systems displays.

Lets set up a simple demonstration circuit - the schematic is below.  You will need an mbed, an LED (any colour or size will do), a breadboard, a 1k resistor, a 270R resisor, some connection wires and all the programming cabling required to program the mbed and the 4D systems display.

Make up the connections as shown in the diagram between the mbed and the LED and connection wires.


Next connect the 4D systems programming cable to the display, ensure the microSD card is present and all the drivers are loaded - it's time to program a touch screen!

1. Load up 4D workshop by double clicking on the appropriate icon


2.  Start a new project by clicking on the appropriate option


3.  Select the appropriate display - in my case a 4.3" touch screen display in landscape format


4.  Now select the Visi-Genie development environment


5.  You will then be presented with the WYSIWYG development screen and object inspector - select a 'RockerSW' object from the 'input' tab and drop it somewhere on the display.  I put mine on the left side.  I also resized the object to make it bigger



6.  Now click on the 'Events' tab in the object inspector and set the 4Dbutton0 object to report a message on activation.


7.  Now add a 'Slider' object and a 'User LED' object and set their 'onActivate' events to report message.  For the slider object set both the onChange and onChanging attributes to report a message.


8.  Now is a good time to save your project - I called mine mbed flash tutorial!



9.  Now click on the 'Project' tab and set the serial communications speed to 115200 baud, this is the speed at which the display and mbed will communicate (115200 characters a second) - I have found that the display does not respond properly unless driven at this speed... 


10.  Next click on the 'Comms' tab and ensure that the display is connected and that the correct com port is selected - if all is correct a blue dot should be visible and the correct display information provided.

11.  Now it is time to upload the design to the display and copy the relevant data to the microSD card.  Click on the 'Home' tab and then click on the 'BuildCopyLoad' Icon.  You will be prompted to copy some files to the microSD card.  Ensure you have the microSD card in a suitable reader and click on the tick!

At this point the design for the display is complete.  If you replace the microSD card into the display and power cycle it you should see the design being displayed.  You should be able to touch the 'rocker switch' object and 'slider' objects and see them change state - cool huh!

12.  Now click on the 'Tools' tab and then click on the 'Terminal 115200' icon.


13.  A simple serial terminal window will appear - if you then actuate the objects on the display messages will be returned in hexadecimal (base 16 numbers).  These are the serial messages that the display sends out when an area of the display containing an object is present and a touch has been detected.  It's a very useful way of checking the display is working and debugging objects.


Anyway....now its time to code the mbed!  Connect up the display to the mbed and breadboard as shown in the schematic diagram earlier and then lets get programming!

Load up a web brower window and point it towards the mbed online compiler...or click on the link below:

http://mbed.org/

Log in to your account and navigate to the online compiler.  You can then either import my code and check it works or copy and paste the code below, you will need to import the library files written by the legendary Christian B (the very kind and helpful mbed user who ported the arduino visi-genie library across to the mbed)

mbed 4Dgenie Library - The library files (note I updated the library to change the screen baud rate and reset function in order to make this demonstration work for my purposes!

I decided to write a simple program to Flash the LED On or OFF with control being provided from the touch screen display.  The 4DButton Object will initialise the LED flashing and then the slider object will manipulate the flash rate of the LED.  The LED object on the display will mirror the real LED...

Here is the code:

#include "mbed.h"
#include "mbed_genie.h"

Mbed4dGenie lcd4d(p9,p10,p11); //

DigitalOut whiteLED(p26); //LED 1 for indication
int rockersw_val = 0;  //holds the status of the 4Dbutton0 Object

int sliderRead = 0;
float flashRate = 1;        //variable to store LED flash rate
int flag = 0;               //flag variable to store rockerswitch state

//Event handler for the 4d Systems display
void myGenieEventHandler(void)
{
    genieFrame Event;
    lcd4d.genieDequeueEvent(&Event);
    
    //event report from an object
    if(Event.reportObject.cmd == GENIE_REPORT_EVENT) {
        if (Event.reportObject.object == GENIE_OBJ_ROCKERSW) { // If the Reported Message was from a rocker switch
            if (Event.reportObject.index == 0) {
                printf("Rocker switch 0 pressed!\n\r");
                rockersw_val = lcd4d.genieGetEventData(&Event);  //extract the MSB and LSB values and pass them to rockersw_val

                if (rockersw_val == 0) {                   //if Rockerswitch0 is off
                    flag = 0;                              //"turn off" the LED
                    printf("Rocker switch switch in off state\n\r"); //print a serial message for debugging
                }

                else if (rockersw_val == 1) {              //if Rockerswitch0 is on
                    flag = 1;                              //"turn on" the LED
                    printf("Rocker switch switch in ON state\n\r"); //print a serial message for debugging
                }
            }
        }

        if (Event.reportObject.object == GENIE_OBJ_SLIDER) {    // If the Reported Message was from a slider object
            if (Event.reportObject.index == 0) {                // If the slider object was slider0
                printf("Slider object changed!\n\r");           // Display a serial message for debugging
                sliderRead = lcd4d.genieGetEventData(&Event);   // Read the current silder0 value
                printf("SliderRead = %d \n\r", sliderRead);     // Display the Slider0 value
                flashRate = 0.01;                               // Set flash rate initially to 10 ms On / Off
                flashRate = 1 - (flashRate * sliderRead);       // Apply the value of slider0 object to flashRate
                

            }

            //Cmd from a reported object (happens when an object read is requested)
            if(Event.reportObject.cmd == GENIE_REPORT_OBJ) {

            }
        }
    }
}

int main()

{
    lcd4d.genieAttachEventHandler(&myGenieEventHandler);    // Call the event handler for the 4D display

    lcd4d.genieWriteContrast(0);                            // Set the display contrast to 0 initially

    lcd4d.genieWriteContrast(15);                           // Set the display contrast to 15 (full brightness)

    printf("Langsters's mbed Visi-Genie LED Flash demo \n\r");  // Display a welcome message on the serial monitor

    while(1) {                                                  // initialise an infinite while loop
        
        if(flag == 1) {                                          // Check if rockerSW object has been activated
            whiteLED = 1;                                        // turn real LED ON
            wait(flashRate);                                     // keep LED on for a short period of time
            whiteLED = 0;                                        // turn real LED ON
            wait(flashRate);                                     // turn LED off for a short period of time
            
        }

        if(flag == 0) {                                          // Check if rockerSW object has been deactivated
            whiteLED = 0;                                        // turn real LED OFF
        }
    }
}

You can import the code directly from mbed here:

LEDFlash import

The code itself is fairly self explanatory and should be easy enough to follow.  It imports two library files to control the 4D systems display, defines the pin assignments for the display and initialises some variables to store data.

The event handler function for the display is comes next which checks if an event associated with the 4D systems display occurred.  If it did what type of event was it and what action should be taken.

The main function calls the event handler function for the display and then sets the display contrast  and prints a welcome message to the serial monitor.  A while loop is then called which checks the status of the event handler and depending on the status of the variables flashes an LED ON and OFF.

Here is a picture of my breadboard showing the mbed and the display in action:


Here is the ubiquitous Youtube video showing the display in action...Enjoy:


Some of you may notice that the userLED object does absolutely nothing!  Well that is because when I first starting writing this post I had every intention of mirroring the real LED with a virtual LED on the display.  When I tried this however I found that the genieWriteObject implementation in the library causes the display to crash and lose communications with the mbed.  This is something that is being addressed and hopefully will be sorted soon.  Until then take care people and have fun - Langster!