Text Output on Medianut LCD

From Nutwiki
Revision as of 17:03, 27 October 2016 by Harald (Talk | contribs) (1 revision imported)

(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to: navigation, search

Description

This example demonstrates the usage of an LCD screen with the Medianut add-on board.

You will need an Ethernut board (or something comparable running Nut/OS) and an attached Medianut board. Your LCD display must be hooked up to the Medianut before turning the power on.

Source Code

Unfortunately there are no Nut/OS internal functions for controlling the LCD yet. To run this example you'll need this ZIP archive:

Source file archive: LCD example sources

The source file of interest for us is the file "lcdex.c" which contains this:

<source lang="c">

  1. include <cfg/os.h>
  2. include <dev/board.h>
  1. include <stdio.h>
  2. include <string.h>
  3. include <io.h>
  4. include <fcntl.h>
  5. include <errno.h>
  1. include <sys/thread.h>
  2. include <sys/timer.h>
  3. include <sys/event.h>
  1. include <mn2ctrl.h>
  1. include "media2spi.h"
  2. include "avrtarget.h"
  1. define ACS_PORT PORTD
  2. define ACS_DDR DDRD
  3. define ACS_BIT 7
  1. ifndef MEDIA2_FUSES
  2. define MEDIA2_FUSES 0x00F9DFE2UL
  3. endif

/*

* Main application routine. 
*/

int main(void) {

   u_long baud = 115200;
   char txt[20] = { ' ' };
   int i = 0;
   NutRegisterDevice(&DEV_DEBUG, 0, 0);
   freopen(DEV_DEBUG_NAME, "w", stdout);
   _ioctl(_fileno(stdout), UART_SETSPEED, &baud);
   puts("\nMedianut LCD Demo");
   sbi(ACS_DDR, ACS_BIT);
   cbi(ACS_PORT, ACS_BIT);
   NutSleep(1000);
   AvrTargetReset(1);
   NutSleep(100);
   AvrTargetReset(0);
   NutSleep(1000);
   puts("Initializing SPI...");
   AvrTargetInit();
   NutSleep(1000);
   puts("Setting up LCD mode...");
   if (Media2DisplayMode(LCD_MODE_4X20)) {
       puts("Error: Can't set LCD mode");
   }
   Media2DisplayClear();
   Media2DisplayScrollMode(DISPLAY_SCROLL_SPEED_SLOW);
   Media2DisplayAttrib(DISPLAY_ATTRIB_NONE);
   Media2DisplayWriteRow(0, "Welcome to the LCD");
   Media2DisplayWriteRow(1, "demonstration! You");
   Media2DisplayWriteRow(2, "will see some of the");
   Media2DisplayWriteRow(3, "available features.");
   NutSleep(10000);
   for (i = 10; i > 0; i--) {
       sprintf(txt, "      %d", i);
       Media2DisplayClear();
       Media2DisplayScrollMode(DISPLAY_SCROLL_SPEED_SLOW);
       Media2DisplayAttrib(DISPLAY_ATTRIB_NONE);
       Media2DisplayWriteRow(1, "   Demo in...");
       Media2DisplayWriteRow(2, txt);
       NutSleep(1000);
   }
   Media2DisplayClear();
   Media2DisplayScrollMode(DISPLAY_SCROLL_SPEED_SLOW);
   Media2DisplayAttrib(DISPLAY_ATTRIB_BLINK);
   Media2DisplayWriteRow(0, "Geez, blinking text!");
   Media2DisplayScrollMode(DISPLAY_SCROLL_SPEED_FAST);
   Media2DisplayAttrib(DISPLAY_ATTRIB_SCROLL);
   Media2DisplayWriteRow(1, "Scrolling as well! ");
   Media2DisplayScrollMode(DISPLAY_SCROLL_SPEED_SLOW);
   Media2DisplayAttrib(DISPLAY_ATTRIB_NONE);
   Media2DisplayWriteRow(2, "Your media player?");
   Media2DisplayScrollMode(DISPLAY_SCROLL_SPEED_SLOW);
   Media2DisplayAttrib(DISPLAY_ATTRIB_SCROLL);
   Media2DisplayWriteRow(3, "[Example Song - Example Artist] 2:31/3:44 ");


   for (;;);
   return 0;

} </source>

Details

<source lang="c">

  1. include "media2spi.h"
  2. include "avrtarget.h"
  1. define ACS_PORT PORTD
  2. define ACS_DDR DDRD
  3. define ACS_BIT 7

</source>

You will need the provided media2spi and avrtarget files since there are no drivers yet. We also have to manually define the data for the level shifter.

<source lang="c"> u_long baud = 115200;

char txt[20] = { ' ' }; int i = 0;

NutRegisterDevice(&DEV_DEBUG, 0, 0); freopen(DEV_DEBUG_NAME, "w", stdout); _ioctl(_fileno(stdout), UART_SETSPEED, &baud); puts("\nMedianut LCD Demo"); </source>

In the program itself we first set up the debug device as usual and declare 2 variables that we'll need later in our demo. The debug device isn't really required this time around but it can't hurt setting up for some diagnostics along the way.

<source lang="c"> sbi(ACS_DDR, ACS_BIT); cbi(ACS_PORT, ACS_BIT);

NutSleep(1000); </source>

Here we activate the level shifter and wait for a moment. This is required because Ethernut and Medianut work on different currents and communication between the two would fail otherwise.

<source lang="c"> AvrTargetReset(1); NutSleep(100); AvrTargetReset(0);

NutSleep(1000); </source>

Then we reset the Medianut. This is not strictly required but recommended since the Medianut does not reset when you press the reset switch on your board. So it may still be working on whatever application was running before and we don't want that.

<source lang="c"> puts("Initializing SPI..."); AvrTargetInit();

NutSleep(1000); </source>

Next we initialize communication between the Ethernut and the Medianut board. This may take a moment for them to exchange data so we'll wait for a second.

<source lang="c"> puts("Setting up LCD mode...");

if (Media2DisplayMode(LCD_MODE_4X20)) {

   puts("Error: Can't set LCD mode");

} </source>

In order to be able to print to our LCD, we have to set it to a display mode. The display I used has 4 rows, 20 columns so I chose LCD_MODE_4x20.

<source lang="c"> Media2DisplayClear(); Media2DisplayScrollMode(DISPLAY_SCROLL_SPEED_SLOW); Media2DisplayAttrib(DISPLAY_ATTRIB_NONE); Media2DisplayWriteRow(0, "Welcome to the LCD"); Media2DisplayWriteRow(1, "demonstration! You"); Media2DisplayWriteRow(2, "will see some of the"); Media2DisplayWriteRow(3, "available features."); </source>

This chunk of code clears the display, sets up some attributes and fills all 4 lines with text. More on the specifics in a moment. If you're wondering where those Media2 functions are declared, have a look at media2spi.c and see how they work.

Media2DisplayClear() clears the contents of the display. If your display has a backlight, that might flicker for a moment when calling this function.

Media2DisplayScrollMode() sets the scrollmode of the display. This does not enable scrolling itself, rhough. There are several scrolling modes available, DISPLAY_SCROLL_SPEED_SLOW and DISPLAY_SCROLL_SPEED_FAST are used throughout this demo. Here we set it to slow.

Media2DisplayAttrib() sets attributes for the text printed on the display. Some available attributes are DISPLAY_ATTRIB_NONE (just display the text without any effects), DISPLAY_ATTRIB_BLINK (display blinking text) and DISPLAY_ATTRIB_SCROLL (displays scrolling text, speed depends on the setting used with Media2DisplayScrollMode. We put DISPLAY_ATTRIB_NONE here because we want simple, static text.

Media2DisplayWriteRow() actually prints a string to the LCD. The first parameter is the row you want to write, the second parameter is the char pointer with the string we want to write. It is your responsibility to ensure the string is not too long for the display, otherwise you might get strange wrapping or overflowing effects.

<source lang="c"> Media2DisplayScrollMode(DISPLAY_SCROLL_SPEED_SLOW); Media2DisplayAttrib(DISPLAY_ATTRIB_BLINK); Media2DisplayWriteRow(0, "Geez, blinking text!"); </source>

Here you can see how to get blinking text on the LCD. Just set the attribute BEFORE writing to the screen and the text will be blinking automatically.

<source lang="c"> Media2DisplayScrollMode(DISPLAY_SCROLL_SPEED_FAST); Media2DisplayAttrib(DISPLAY_ATTRIB_SCROLL); Media2DisplayWriteRow(1, "Scrolling as well! "); </source>

Scrolling text is achieved in much the same way. Set scrollspeed, set the attribute to scroll and voilá, you can write text that scrolls on it's own.

One final note on setting attributes: They will not return to their default state after writing one line. If you write a blinking line and then immediately follow up with another line (no matter where on the LCD you write it to) that line will be blinking as well. Same goes for scrolling. So make sure you set the correct attributes before writing to the screen or you may get funky results.

Output

See also





Template:Languages