Wednesday, 29 January 2014

mbed controlling a 4D Systems uLCD-43PCT and four LEDS

Hi, I have been playing with the Mbed Microcontroller and the 4D Systems Capacitive 4.3' touchscreen.  In order to familiarise myself with the nuances of the system and because I was asked by a reader of the blog if something was possible....So here we go - this is an example of how to use the 4D systems touch screen to turn four leds on and off.  To keep things simple I am using the four LEDS already present on the Mbed LPC1768 however any LEDS connected to any pins could be used.

So here is the schematic - I'm a great believer in schematics!


I then loaded up 4D Systems graphical development environment - Workshop 4 ready to develop the touchscreen display:


Next to start a completely new project I clicked on the appropriate 'Create a new Project Button'  When presented with the following screen I scrolled down to the appropriate display type - in my case a 4.3 inch capacitive touch screen.  I chose the landscape non reversed orientation because I'm lazy and haven't really decided how I am going to mount the display, all possible permutations of orienting the display are catered for.


Click next when you are ready to continue and the following choose your development environment screen is displayed - Lets choose Visi-Genie because its the most simple and quick to use; I can't stress how good and easy this development environment is!!


The next screen displayed is the workshop for graphical development environment.  On the left side of the screen is what is referred to in the manual as the 'WYSIWYG' of the touch screen.  What you see is what you get - quite literally.  On the right side of the screen are all of the attributes available for the graphical screen objects that you as the designer may place on the WYSIWYG screen:


As I'm doing an example of lighting some external LEDS with some buttons lets add some button objects:

Click on the 'Buttons' tab and then on the fancy buttons icon ( icon with a spanner on an orange background) :-


Next click on the WYSIWYG touch screen to place a 'fancy button' - it will automatically be called winButton0:


On the right side of the screen the 'object inspector' will show all of the pertinent attributes for the winButton0 object.  Lets modify the button so that it is no longer a momentary button and give it a better label than winButton0 and lets also have the display show when the button has been actuated 'On' and 'Off':

Make sure the properties tab is selected

Click on the caption field and change it from winButton0 to something more appropriate - I chose LED 1

Click on the momentary field and change it from 'Yes' to 'No'

Expand the 'StatusWhenOff' field and change the BGcolor to Green and the caption to 'Off' or whatever you like

Expand the 'StatusWhenOn' field and change the BGcolor to Red and the caption to 'On' or whatever you like


You might notice that the WYSIWYG display updates the winButton0 object with your changes...and displays the correct caption and shows the button in 'Off' state.

Next click on the Digits tab and select a userLed object and then click on the WYSIWYG screen:


Update the object attributes for the userLed0 object so that it shines blue on activation - you could choose any colour you liked however the LEDS on the Mbed are blue so I thought it should match!

Once you have done all of that which should only take about five minutes we can then get on with the interactive part of the display control.  What we want to do is have the display send a message to the host microcontroller when the button state changes from 'off' to 'on'.  At the same time we would like to update the userLed0 object on the display from 'off' to 'on' so that the display userLed0 object matches the Mbed LED.  So what we are going to do is use the host microcontroller (Mbed) to poll for an event concerning the winButton objects.  If the winButton Objects report a message then we know that a button has been pressed and it's state will have changed from Off to On.  All we then have to do is get the host micro to send a message to the display telling the virtual LED to change state also and at the same time turn the corresponding actual LED on.

The way this is achieved is to click on the winButton0 object on the WYSIWYG screen and then click on the events tab and then click on the onChanged field.  There should be three options - Report Message, Form0 and userLed0Set - choose ReportMessage and click ok.




As there are four LEDS on the Mbed LPC1768 I repeated this process three more times so that there are four button objects and four virtual LED objects.  All the winButton objects need to be set up to respond on touch to light the corresponding virtual LED and report a message when their state changes.

This is what you should see now if you are ready for compiling and sending to the display:


Now is the time to save your project and ensure all settings are correct.  Save the project as something sensible - I called mine mbedTest but it can be called anything you like.  Click on the comms tab and ensure that your display is connected and the COM port for controlling the display is present. Next click on the project tab - Set the appropriate COM port speed for your project.  In this case speed is not an issue so I chose 9600 baud:


Now its time to upload our touchscreen layout to the display.  Click on the home tab and then click on the 'Build Copy Load' icon.  The design will be compiled and uploaded to the display.  You will be prompted to copy the files to the microSD also.  Once complete remove the microSD card from the reader and put it into the display.  You should be presented with your design on the display and when you touch the buttons they should respond appropriately  - <BIG GRIN>

That should have taken about ten minutes - it probably took longer to read all of this text, it certainly takes me longer to type it!

Now we are on to coding the firmware for Mbed LPC1768 which I am using as the host microcontroller.
Load up and log into the online compiler for the Mbed  in the browser of your choice:

Then start a new program using the blinky LED template, call the program something sensible.


Next import the library files mbed_genie.cpp and mbed_genie.h.  These are the library files which tell the mbed how to control the 4D systems touchscreen display.  Finally paste in the following code:

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

DigitalOut led1(LED1);
DigitalOut led2(LED2);
DigitalOut led3(LED3);
DigitalOut led4(LED4);

bool winButton0Status = false; //holds the "status" of winButton0 object.
bool userLed0Status = false;   //hold the "status" of userLed0 object.

bool winButton1Status = false; //holds the "status" of winButton1 object.
bool userLed1Status = false;   //hold the "status" of userLed1 object.

bool winButton2Status = false; //holds the "status" of winButton2 object.
bool userLed2Status = false;   //hold the "status" of userLed2 object.

bool winButton3Status = false; //holds the "status" of winButton3 object.
bool userLed3Status = false;   //hold the "status" of userLed3 object.


//Event handler for the 4d Systems display
void myGenieEventHandler(void)
{
    genieFrame Event;
    genieDequeueEvent(&Event);

    if(Event.reportObject.cmd == GENIE_REPORT_EVENT) {

        // If the Reported Message was from winbutton0 and userLed0 is off

        if (Event.reportObject.object == GENIE_OBJ_WINBUTTON) {
            if ((Event.reportObject.index == 0) && (userLed0Status==false)) {
                printf("LED1 High \r\n");
                wait(0.1);
                winButton0Status=true;
            }
        }

        // If the Reported Message was from winbutton0 and userLed0 is on

        if (Event.reportObject.object == GENIE_OBJ_WINBUTTON) {
            if ((Event.reportObject.index == 0) && (userLed0Status == true)) {
                printf("LED1 Low \r\n");
                wait(0.1);
                winButton0Status=false;
            }
        }

        // If the Reported Message was from winbutton1 and userLed1 is off

        if (Event.reportObject.object == GENIE_OBJ_WINBUTTON) {
            if ((Event.reportObject.index == 1) && (userLed1Status==false)) {
                printf("LED2 High \r\n");
                wait(0.1);
                winButton1Status=true;
            }
        }

        // If the Reported Message was from winbutton1 and userLed1 is on

        if (Event.reportObject.object == GENIE_OBJ_WINBUTTON) {
            if ((Event.reportObject.index == 1) && (userLed1Status == true)) {
                printf("LED2 Low \r\n");
                wait(0.1);
                winButton1Status=false;
            }
        }

        // If the Reported Message was from winbutton2 and userLed2 is off

        if (Event.reportObject.object == GENIE_OBJ_WINBUTTON) {              
            if ((Event.reportObject.index == 2) && (userLed2Status==false)) {
                printf("LED High \r\n");
                wait(0.1);
                winButton2Status=true;
            }
        }

        // If the Reported Message was from winbutton2 and userLed2 is on

        if (Event.reportObject.object == GENIE_OBJ_WINBUTTON) {              
            if ((Event.reportObject.index == 2) && (userLed2Status == true)) {
                printf("LED Low \r\n");
                wait(0.1);
                winButton2Status=false;
            }
        }
        
        // If the Reported Message was from winbutton3 and userLed3 is off

        if (Event.reportObject.object == GENIE_OBJ_WINBUTTON) {              
            if ((Event.reportObject.index == 3) && (userLed3Status==false)) {
                printf("LED High \r\n");
                wait(0.1);
                winButton3Status=true;
            }
        }

        // If the Reported Message was from winbutton3 and userLed3 is on

        if (Event.reportObject.object == GENIE_OBJ_WINBUTTON) {              
            if ((Event.reportObject.index == 3) && (userLed3Status == true)) {
                printf("LED Low \r\n");
                wait(0.1);
                winButton3Status=false;
            }
        }
    }
}


int main()
{

    SetupGenie();

    genieAttachEventHandler(&myGenieEventHandler);

    printf("Langsters's mbed Visi-Genie LED demo \r\n");

    genieWriteContrast(15); //set screen contrast to full brightness

    while(1) {

        //check if winButton0 is High & set LED0 High 

        if (winButton0Status == true) {
            printf("Button 0 in On State! \r\n");     //send button status message
            genieWriteObject(GENIE_OBJ_USER_LED, 0x00, 1); // set virtual LED0 High     
            wait(0.1); // wait 100uS
            led1 = 1; // set actual LED1 High
            userLed0Status = true; // set userLed0Status High

        }

        //check if winButton0 is low & set LED low 

        else if (winButton0Status == false) {
            printf("Button 0 in Off state! \r\n");    //send button status message
            genieWriteObject(GENIE_OBJ_USER_LED, 0x00, 0); // set virtual LED0 Low      
            wait(0.1); // wait 100uS
            led1 = 0; // set actual LED1 Low
            userLed0Status = false; //set userLed0Status Low

        }
        
        //check if winButton1 is High & set LED High 
        
        if (winButton1Status == true) {
            printf("Button 1 in On State! \r\n");     //send button status message
            genieWriteObject(GENIE_OBJ_USER_LED, 0x01, 1); // set virtual LED0 High     
            wait(0.1); // wait 100uS
            led2 = 1; // set actual LED2 High
            userLed1Status = true; // set userLed1Status High

        }

        //check if winButton1 is low & set LED low 

        else if (winButton1Status == false) {
            printf("Button 1 in Off state! \r\n");    //send button status message
            genieWriteObject(GENIE_OBJ_USER_LED, 0x01, 0); // set virtual LED0 Low      
            wait(0.1); // wait 100uS
            led2 = 0; // set actual LED1 Low
            userLed1Status = false; //set userLed1Status Low

        }
        
        //check if winButton2 is High & set LED High 
        
        if (winButton2Status == true) {
            printf("Button 2 in On State! \r\n");     //send button status message
            genieWriteObject(GENIE_OBJ_USER_LED, 0x02, 1); // set virtual LED0 High     
            wait(0.1); // wait 100uS
            led3 = 1; // set actual LED2 High
            userLed2Status = true; // set userLed1Status High

        }

        //check if winButton2 is low & set LED low 

        else if (winButton2Status == false) {
            printf("Button 2 in Off state! \r\n");    //send button status message
            genieWriteObject(GENIE_OBJ_USER_LED, 0x02, 0); // set virtual LED0 Low      
            wait(0.1); // wait 100uS
            led3 = 0; // set actual LED1 Low
            userLed2Status = false; //set userLed1Status Low

        }
        
        //check if winButton3 is High & set LED High 
        
        if (winButton3Status == true) {
            printf("Button 3 in On State! \r\n");     //send button status message
            genieWriteObject(GENIE_OBJ_USER_LED, 0x03, 1); // set virtual LED0 High     
            wait(0.1); // wait 100uS
            led4 = 1; // set actual LED2 High
            userLed3Status = true; // set userLed1Status High

        }

        //check if winButton2 is low & set LED low 

        else if (winButton3Status == false) {
            printf("Button 3 in Off state! \r\n");    //send button status message
            genieWriteObject(GENIE_OBJ_USER_LED, 0x03, 0); // set virtual LED0 Low      
            wait(0.1); // wait 100uS
            led4 = 0; // set actual LED1 Low
            userLed3Status = false; //set userLed1Status Low

        }        
        

    }

}

------------------------------------------------------------------------------------------------------------

You can also import the code as an example from the Mbed cookbook here:

mbed 4D LED Test

The code is fairly simple to understand and is well documented so I'm not going to discuss it more here.

Here is a video showing the screen working - Enjoy.



That's all for now - Langster!




Tuesday, 14 January 2014

mbed SD Card tutorial

I have been playing with the mbed microcontroller again.  I'm really liking this particular microcontroller development platform!  The potential is huge for what can be achieved with this thing.  The only thing I continually struggle with is the documentation.  Whilst the mbed website is good there are still issues that cause the inexperienced to become frustrated...myself included!

One of the most common tasks I need a microcontroller to perform is to log data from instrumentation.  The best way I know of currently doing that is to use an SD card.  I have done this with an arduino so often I almost can do it without thought.  At the moment I am developing some instrumentation with the mbed and need to achieve the same thing - I need a way of logging data measurements.  The data will be stored as text files in ASCII.  I will probably use comma separated values....It makes it easy to import into a spreadsheet or graphing program of choice.

If you are going to try this you will need the following:

An mbed and mini USB cable
An SD card - partitioned and formatted for use on your operating system of choice
An SD card breakout board - try Adafruit or Sparkfun for all your breakout needs!
Some connection wire
Patience!



So I looked at the mbed documentation on the website and searched for SD card tutorial.  A lot of pages appeared but nothing that actually shouted this is how to connect an SD card, here is the circuit diagram and how to connect it up and here is the demonstration code with an explanation of how things work....

https://mbed.org/search/?type=&q=SD+card+tutorial - a lot of pages but nothing definitive

What I actually needed to find was here:


The mbed cookbook is useful but often difficult to navigate - a work in progress.

There is a lot of information on the programming of the mbed - libraries and usage but no pictures on how to connect things up and no schematics.  Lets remedy that!


SD cards normally communicate with the host microcontroller via the SPI protocol - Serial Peripheral Interface.  The mbed has two SPI ports - pins 5, 6 and 7 - MOSI, MISO and SCK and pins 11,12 and 13 - also MOSI, MISO and SCK.  You can use either three pins but they are not interchangeable.  In my testing I used 11,12 and 13 because I have already made plans for pins 5 and 7!

Here is a picture of the connections:


I used an SD breakout board so my connections are a little different from the above schematic.  I am connecting +5V to Vdd because my breakout board has a logic level converter to convert 5V to 3.3V.  The breakout board was designed for use with TTL logic based microcontrollers like the arduino.  If you are using just an SD card connector the information in the schematic is correct.  Change your connections to suit your breakout board as necessary.

Once I had checked and rechecked my connections!  I keep having to do that at the moment - I imported the example code into the online compiler and then uploaded it to my mbed

Here is the the link to the example code again so people can find it easily:


It should compile with no errors.  Ensure that you update the code with the relevant information with where you have made the connections.  If like me you are using pins 11, 12 and 13 for MOSI, MISO and SCK you need to change the line highlighted to reflect that.

#include "mbed.h"
#include "SDFileSystem.h"

SDFileSystem sd(p11, p12, p13, p8, "sd"); // the pinout on the mbed Cool Components workshop board

int main() {
    printf("SD card test!\r\n");   

    mkdir("/sd/mydir", 0777);
    
    FILE *fp = fopen("/sd/mydir/sdtest.txt", "w");
    if(fp == NULL) {
        error("Could not open file for write\r\n");
    }
    fprintf(fp, "Hello fun SD Card World!\r\n");
    fclose(fp); 

    printf("File successfully written and closed!\r\n");
}

I suppose I should try and explain what the code does:

The first line tells the compiler to include the core header file for the mbed and the second include statement tells the compiler to use the header file containing the instructions relating to SD cards.

The third line SDFileSystem sd(p11, p12, p13, p8, "sd");  tells the compiler that the SD card is connected to pins 11, 12 , 13 and pin 8. 

NB - Pin 8 is the control line for the SD card it's known as CS or SS depending on which information you read or what is printed on the breakout boards silk screen - mine was SS.

The rest of the code prints a message to the mbed com port, makes a directory on the SD card and then creates a text file called sdtest.txt.  If for some reason the file cannot be created or opened an error message is displayed on the serial terminal; the program then finishes.  If the file was created and opened successfully a message will be written inside the text file and then the test file is closed. A further message is sent to the serial terminal to document the program's success.

I use a free terminal program called PuTTy for my serial, Telnet or SSH requirements.  It is a great piece of software!  You can get it from here:


I suggest people try it out - it's useful...

Anyway...back to the cool stuff.  Connect up your mbed to your PC and copy the compiled .bin file to your mbed and press the reset button.  If all is well the blue power / programming LED will flash and then the program will exit.  No other LEDs should be illuminated.  

If you load up PuTTy and point it towards your mbed serial terminal with the settings:

COMXX - 9600, n, 8, 1 with no flow control - where XX is the COM port number of your mbed you can view the output:


Open the terminal window and view the results...


Actually that was amazing for me...I couldn't get this to work for love nor money at first - I'm losing my touch!

If you remove your SD card and view it in a file explorer there will be a new directory on your SD card called mdir and inside this folder there will be a text file called sdtest.txt.  Open it and verify it is all correct.

If things are wrong and they often are...then the four LEDS at the bottom of the mbed will flash from outer to inner and the following messages will be shown in PuTTy:


The flashing LEDS of SD card failure...


If you see this then unfortunately something is wrong either with the wiring, the SD card or your mbed.  In my case I was struggling for a long time because I was using the unregulated +5V input to power the SD card.  My computer couldn't power both the mbed and the SD card.  As soon as I swapped to the regulated +5V everything worked perfectly.  If it doesn't work for you, all I can suggest is check check and re-check connections and then ask for help!  I didn't but perhaps I should have...I even checked the MOSI, MISO and SCK where occurring using an oscilloscope and a logic analyser.  I re-wired at least ten times and checked continuity with a multimeter.  It wasn't until I measured the voltages with a digital multimeter that I noticed that there was not enough voltage to power the SD card.  If I had been using a breakout board without a logic level converter and wired as shown in the schematic diagram this would have worked first time....No matter - all is working and well now and more information and confidence gained - bonus!

There are so many reasons to want to log data to external memory with microcontrollers - it's the corner stone of instrumentation.  I'm going to turn this into a memory stick of sorts so that I just have to connect a USB cable to the mbed (not the programming cable) so that I can browse the SD card data!  Simples!

That's all for now people - take care

Langster!









Sunday, 5 January 2014

4D Systems mbed Tutorial

uLCD-43 display mbed tutorial

Recently I have been playing with a new microcontroller - NXP's LPC1768 using the mbed development platform.

'mbeds' are incredibly powerful microcontroller development boards handily on a 40 pin dip package which makes it easy for prototyping.  Getting into prototyping with ARM microcontrollers is difficult because the devices are usually QFP (read lots of pins, really closely packed together in a surface mounting configuration) - or quad flat packed.....This makes it very hard for the development engineer to quickly prototype circuits.  Before protyping begins some sort of development breakout board has to be made which quickly turns into a design of it's own right.  There are so many facets and features to microcontrollers these days that prototyping and learning to use the device is a daunting prospect.  This is why the arduino development system is so popular....The arduino community have taken the stress out of development by making programming and using the Atmel 328p processor as simple as possible.  By then making addon PCBs (shields) available and easy to use the arduino family becomes one of the first development systems I would reach for when designing a microcontroller based electronic circuit

The mbed is a relatively new kid on my block.  I have heard about them and given them a cursory glance two years ago.  I found the device itself incredibly appealing - mbeds seem to have everything the arduino does and more...the issue was with coding the firmware for the device.  The development environment is completely online and this probably puts most professional designers off....control is something inherently closed in electronics design and not sharing is quite common.  I am attempting to rectify the situation a little. The other issue is that the mbed is coded entirely in C++.  I have dabbled with C++ in the past but I am by no means an expert.  To be honest my coding skills lack my electronics considerably!  Experienced software developers will revel in coding for the mbed; electronics engineers will struggle but hopefully catch up.

The mbed community website

There are plenty of beginner examples on how to use the mbed on the community website, I'm not going to repeat all of their good work here.  Sometimes though I still feel there isn't quite enough detail.  If I feel so inclined I might write some tutorials depending on how frustrated I get!

mbed Cookbook

I have recently been tasked with writing the firmware for controlling a touch screen display.  I have never played with one of these before and was quite excited at the prospect.  The display selected was the uLCD-43 PCT from 4D Systems:

uLCD_43 LCD display
I chose the capacitive touch version as for my application there is going to be a lot of touching and use on the display.  Resistive screens tend to get easily scratched and then not work as well, they can be covered but then the responsivity of the display is significantly affected.  Capacitive touch screens on the other hand don't lose responsitivity as much when covered and therefore won't be so affected by scratches!

This display was selected because it is controlled via a standard RS232 serial protocol.  Only 5 wires required! This should make controlling the display very simple to achieve.  I have used touch screen displays in the past that were parallel controlled and 16 wires were required to control the display....16 pins from the microcontroller used to control the display....painful!

There are several versions of touch screen displays available and prices to suit - the smaller the display with less features the cheaper the price!

One trap I found is that if you don't opt to buy one of the development kits 4D systems don't provide a programming cable with the screen.  Make sure you buy one or else you will be scuppered in trying to program the display!  You will also need a micro-SD card for storing the 'forms' on the display...It would also be beneficial to make sure you have a converter to change the microSD card into a standard SD card or a microSD card reader...I spent forever searching for one!


The development environment for the display provided by 4D Systems is excellent!  There are four flavours of environment available.  


Designer is for the hardcore software programming enthusiast with experience in coding the display using 4D's own development code.

Visi is a drag and drop object oriented programming experience for the controlling the device.  It is slightly more simple to use than the Designer option.

Visi-Genie is another even better version of the object oriented drag and drop system.  All the designer has to do is drag and drop the pre-coded objects and layout the screen as required.  Nothing could be easier and I found this to be the most efficient method of quickly getting the display up and running.

Serial - I haven't really looked into this section much, but according to the information provided it's a method of making the display completely controlled via the serial terminal.  I should really investigate further!

There is a very active forum for the use and control of the displays on 4D's website.


If a designer ever got stuck then posting their questions and issues on the forum soon yields some help.

Using Visi-Genie is very similar to a visual development environment and most people who have done any visual programming before will be quite at home.


 So to the business of using the screen with the mbed!

I looked at the application notes for using the display on the 4D Systems website and noticed that there were several examples available for use with the arduino and the raspberry Pi.  Unfortunately nothing for the mbed.  The application notes provided by 4D Systems discuss in great detail how to use the display but connection to the microcontroller is not discussed until the end of the document.  It took me a while to find it!  There is a specific shield for connecting the display to the arduino and the raspberry Pi and a photograph showing the wired connections to a micro if required.  It still wasn't particularly clear to me...so here is how you make connections to any microcontroller with just wires....


+5V is connected to the 5V positive supply - one will have to be provided for a 3.3V microcontroller
GND is connected to the 0V connection.
RES is connected to a 1k resistor and then to a digital GPIO pin on the microcontroller or not connected.
TX is connected to the TX pin of the RS232 Uart pin of choice on the microcontroller.
RX is connected to the RX pin of the RS232 Uart pin of choice on the microcontroller.

For the mbed connections see the following schematic:


I've added a potentiometer as in this tutorial like the arduino tutorial we are going to make a simple touchscreen controlled voltmeter.

I then connected the display to the programming cable and loaded up 4D workshop 4.  I selected the Visie-Genie environment and dragged and dropped the following objects onto the display to match the arduino tutorial -


  • an angularMeter object
  • an LEDdigits object 
  • two 4Dbuttons object
  • three staticText objects 




The original arduino tutorial used a rockerSwitch object but I wasn't able to get this working with the mbed....more on this later...

Make sure you set the display's serial communication rate to the same as the one you intend to use with the microcontroller.  In my case I selected 115200 as I wanted to see if speed made a difference to the display response.

Set the 4Dbutton objects to Report Message in OnChanged in the events tab.  This ensures the display outputs a serial message when the buttons have been pressed.

 
Once you have the display objects arranged to your satisfaction go ahead and upload the project to the display by clicking on the BuildCopyLoad button.  The 'form' will be compiled and loaded onto the display's firmware and then placed on the microSD card.  The software will prompt you as required.  Once complete remove the SD card and put it in the display.  The display will then load up with the form just designed in the development environment - Cool huh!

If you like you can check the display is working by probing the serial port using the serial terminal within 4D systems workshop.  When the buttons are pressed a hex message should appear in the serial terminal window.

If however you are like me you will want to connect it to your host micro of choice and use the display as intended - <very big grin>

So remove the USB programming cable and connect the wires up as shown in the schematic diagram previously.

Once you apply power to the mbed the display should load up but not do anything.

You will now need to load up the mbed's online compiler and log in and then you can either develop your own firmware or copy mine...I used a port of the arduino Visi-Genie library helpfully written by Christian B one of the other mbed users:

mbedVoltmeter code

Here is the text version for those that prefer to read through and copy and paste:

/* A port test of the arduino voltmeter example using the 
4.3' PCT 4d systems touch screen display.  

uses the mbed_genie library ported from the arduino
visie-genie library by Christian B

The display serial TX and RX pins are connected to pin 9
and pin 10 of the mbed

The reset pin is not connected as reset function is not implemented

Pin 15 of the mbed has a potentiometer wiper connected to it
The other connections of the potentiometer are connected to +3.3V
and 0V 

For setting up the display in Visie-Genie

The display has an angular meter objecr, a LED digits object, two buttons 
and three static text objects.

The program sends digital voltage readings to the LED digits and 
angular meter of the display module.

The On and Off button has been set to report on change

The baud rate of the display is set to 115200 baud

*/

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

AnalogIn voltReading(p15);  //Potentiometer wiper connected to pin 15      

int flag = 0;        //holds the "power status" of the voltmeter. flag = 0 means voltmeter is "off", flag = 1 means the voltmeter is "on".
float voltMeter;       //holds the digital voltage value to be sent to the angular meter
float voltLED;         //holds the digital voltage value to be sent to the LED digits

//Event handler for the 4d Systems display
void myGenieEventHandler(void) 
{
  genieFrame Event;
  genieDequeueEvent(&Event);
  //event report from an object
  if(Event.reportObject.cmd == GENIE_REPORT_EVENT)
  {
    /*
    for example here we check if we received a message from 4dbuttons objects
    the index is the button number, refer to the 4dgenie project to know the     index
    */
    if (Event.reportObject.object == GENIE_OBJ_4DBUTTON)                // If the Reported Message was from a button
    {
        if (Event.reportObject.index == 0) 
        {
             //printf("Off Button pressed!\n\r");
             wait(0.2);
             flag=1;
        }
        if (Event.reportObject.index == 1) 
        {
             //printf("On Button pressed!\n\r");
             wait(0.2);
             flag=0;           
        }
    }
  }
  
  //Cmd from a reported object (happens when an object read is requested)
  // if(Event.reportObject.cmd == GENIE_REPORT_OBJ)
  // {

  // }

}

int main() 


    SetupGenie();
    genieAttachEventHandler(&myGenieEventHandler);
     
    printf("Langsters's mbed Visi-Genie Voltmeter demo \n\r");

    genieWriteContrast(15); //set screen contrast to full brightness

            while(1) 
            {                  
                if (flag == 1)
                    {
                        //printf("Flag status: %d \r\n", flag);
                        wait (0.1); 
                        voltLED = voltReading; 
                        wait (0.1);    
                        //printf("Volt bit Reading: %f \n\r",voltLED);
                        voltLED = voltLED * 3.3;                                    //convert float reading to voltage
                        //printf("voltLED: %f\r\n",voltLED);
                
                        voltLED = voltLED * 1000;
                        genieWriteObject(GENIE_OBJ_LED_DIGITS, 0x00, voltLED);      //write to Leddigits0 the value of voltLED 
                        wait (0.1);
                        
                        voltMeter = voltLED/100;
                        genieWriteObject(GENIE_OBJ_ANGULAR_METER, 0x00, voltMeter); //write to Angularmeter0 the value of voltMeter     
                    }
                
                else if(flag == 0)
                    
                    {
                        //printf("Flag status: %d \r\n", flag); 
                        wait (0.1);
                        voltLED = 0;
                        genieWriteObject(GENIE_OBJ_LED_DIGITS, 0x00, 0);      //write to Leddigits0 the value of voltLED 
                        wait (0.1);
                        
                        //voltMeter = voltLED/100;
                        genieWriteObject(GENIE_OBJ_ANGULAR_METER, 0x00, 0); //write to Angularmeter0 the value of voltMeter   
                    }                            
                                
            }
      
}

Import the program into your online compiler and then compile and download it.  You will then need to copy the associated .bin file onto your mbed.  Once complete, press the mbed's reset button and the magic shall begin!  If you press the 'On' button the display will show the voltage being applied at the analogue input pin 15 which is connected to the potentiometer wiper and should be somewhere between 0V and 3.3V.  If turn the wiper on the pot then the voltage displayed will update accordingly.  If you press the 'Off' button all measurement will stop and any changes on the potentiometer will not update the display.  Doesn't sound like much but the potential is huge (that and it took me ages to get this working...)

Here is a description of the code and how it works:

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

These two lines tell the online compiler to include the header files mbed.h and mbed_genie.h.  These are header files which tell the compiler how to understand the syntax written in the program

AnalogIn voltReading(p15);  //Potentiometer wiper connected to pin 15      

int flag = 0;        //holds the "power status" of the voltmeter. flag = 0 means voltmeter is "off", flag = 1 means the voltmeter is "on".
float voltMeter;       //holds the digital voltage value to be sent to the angular meter
float voltLED;         //holds the digital voltage value to be sent to the LED digits

The next lines are some variable declarations: 

AnalogIn voltReading(p15); tells the compiler that pin 15 on the microcontroller will be using pin 15 to measure an analogue value.  In this case it will be measuring the voltage present on the potentiometer wiper pin between 0V and 3.3V

int flag = 0; tells the compiler to assign some memory for storing an 8 bit integer value, refer to this value as flag and give it an initial value of zero.  I could have and probably should have used a boolean value here to save memory and it's better practice however I am not a professional coder and this worked!

float voltMeter; tells the compiler to assign some memory for storing a 16bit floating point value or to keep things simple a number with decimals!  Refer to this memory location as voltMeter.  We will be using this memory location to store the decimal value we are going to display.

float voltLED; As above but in this case we are storing the decimal value to be displayed on the seven segment LED digits.

//Event handler for the 4d Systems display
void myGenieEventHandler(void) 
{
  genieFrame Event;
  genieDequeueEvent(&Event);
  //event report from an object
  if(Event.reportObject.cmd == GENIE_REPORT_EVENT)
  {
    /*
    for example here we check if we received a message from 4dbuttons objects
    the index is the button number, refer to the 4dgenie project to know the     index
    */
    if (Event.reportObject.object == GENIE_OBJ_4DBUTTON)                // If the Reported Message was from a button
    {
        if (Event.reportObject.index == 0) 
        {
             printf("Off Button pressed!\n\r");
             wait(0.2);
             flag=1;
        }
        if (Event.reportObject.index == 1) 
        {
             //printf("On Button pressed!\n\r");
             wait(0.2);
             flag=0;           
        }
    }
  }

The above function is the 'Event Handler' for the display.  An event handler is the section of a program for handling interrupts.  Basically the microcontroller and display will spend most of it's time showing the pictures of what the designer has provided.  When someone touches the display the microcontroller will receive a message from the display interrupting the program flow.  This function deals with that 'interruption' by processing it and providing the required response.

In the case above the event handler the following is occurring:

genieFrame Event; Call to the mbed_genie library function that deals with a touch being registered on the display.

genieDequeueEvent(&Event); If the event registered is genuine place it in the queue to be processed as an interrupt. 

if(Event.reportObject.cmd == GENIE_REPORT_EVENT)
  {

The above line is a conditional check that tells the microcontroller to perform the code below if the result of the check is 'true'.  If the result is false the function ends and the microcontroller stops processing this section of code.

if (Event.reportObject.object == GENIE_OBJ_4DBUTTON)
    { 

Another conditional check asking the microcontroller if  a 4Dbutton object was pressed.

        if (Event.reportObject.index == 0) 
        {
             printf("Off Button pressed!\n\r");
             wait(0.2);
             flag=1;
        }

Was the button pressed the 4Dbutton0 object - the 'Off' button? If it was then send a message via the serial terminal to advise the user it was (not required but useful for debugging) and then wait 200ms to allow the required processing to occur and then set the flag variable from 0 to 1 to let the microcontroller know the button was pressed.

        if (Event.reportObject.index == 1) 
        {
             //printf("On Button pressed!\n\r");
             wait(0.2);
             flag=0;           
        }

The above code section is exactly the same as before but for the 'On' button.

int main() 


    SetupGenie();
    genieAttachEventHandler(&myGenieEventHandler);
     
    printf("Langsters's mbed Visi-Genie Voltmeter demo \n\r");

    genieWriteContrast(15); 

The int main() function is the part of the program that tells the microcontroller to process the functions in order from here.

The SetupGenie(); line is a call to the mbed_genie library telling the microcontroller how to setup the display. Tell the microcontroller what size of display is connected, in what orientation and at what speed the serial Uart is set at.  In this case I set it to 115200 baud.  If this needed to be changed you would need to search through the mbed_genie library for screen.baud (115200) and change it to whichever value you like.  You will need to ensure the display firmware is updated to reflect this change.  I hope to change this in the library to make it easier to change the screen serial baud rate.

printf("Langsters's mbed Visi-Genie Voltmeter demo \n\r");

The above line sends a message via the serial terminal to inform the viewer which program is running.  Not strictly necessary but useful for debugging purposes.  It lets the programmer know which section of the code is running.

genieWriteContrast(15);

The above line sets the displays contrast (brightness really).  You can set the display from 0 to 15.  15 is full brightness.  Useful if you wanted to turn the display off or down to conserve power when not in use.

while(1) 
            {                  
                if (flag == 1)
                    {
                        //printf("Flag status: %d \r\n", flag);
                        wait (0.1); 
                        voltLED = voltReading; 
                        wait (0.1);    
                        //printf("Volt bit Reading: %f \n\r",voltLED);
                        voltLED = voltLED * 3.3;                                    //convert float reading to voltage
                        //printf("voltLED: %f\r\n",voltLED);
                
                        voltLED = voltLED * 1000;
                        genieWriteObject(GENIE_OBJ_LED_DIGITS, 0x00, voltLED);      //write to Leddigits0 the value of voltLED 
                        wait (0.1);
                        
                        voltMeter = voltLED/100;
                        genieWriteObject(GENIE_OBJ_ANGULAR_METER, 0x00, voltMeter); //write to Angularmeter0 the value of voltMeter     
                    }
                
                else if(flag == 0)
                    
                    {
                        //printf("Flag status: %d \r\n", flag); 
                        wait (0.1);
                        voltLED = 0;
                        genieWriteObject(GENIE_OBJ_LED_DIGITS, 0x00, 0);      //write to Leddigits0 the value of voltLED 
                        wait (0.1);
                        
                        //voltMeter = voltLED/100;
                        genieWriteObject(GENIE_OBJ_ANGULAR_METER, 0x00, 0); //write to Angularmeter0 the value of voltMeter   
                    }                            
                                
            }
      
}

The rest of the code runs in a continuous while loop initiated in the while(1)section.  Every line of code beyond this point will run over and over until power is removed.  

The if statement checks if the flag variable has been set and if it is set (the 'On' button has been pressed) then the analogue voltage signal measured on analogue pin 15 is stored and placed in the voltLED memory location.  The floating point value is then converted to decimal and formated for a measurement from 0 - 3.3V and then passed to the ledDigit0 display object.  The display then shows the result.  The same process is then performed to display the voltage measurement on the angularMeter0 display object.

That's it for the code explanation.  I hope it's understandable.  It took far too long for me to get this working and almost as long to write about it!

Here is a picture of the display and microcontroller in action:




   And finally here is the almost ubiquitous youtube video proving I didn't fake getting it working!



Well that's it for now.  I am hoping that given time I can help improve the ported 4D systems mbed library as there are still a few functions missing - resetting the display being one thing I found not present.  I also didn't manage to get the rocker switch object to work which is why I used two momentary buttons.  All in all I think both the mbed microcontrollers and the 4D systems display have great potential and hopefully more people will be able to use them with help from this tutorial.

Take care people - Langster!