How to Print & Scroll string on Dot Matrix Display

This tutorial is the PART 3 of the mini series where we are covering how to interface the dot matrix display with STM32 using the SPI. In the previous tutorial we saw how to cascade multiple displays and how to print the data arranged in the columns.

Note that I still don’t know the type of the dot matrix hardware I am using. But we still managed to interface it using some trial and errors.

In today’s tutorial, we will see how to print & scroll the string on this display. We will also use a font library which contains the data for all the characters.

Connection & configuration

The connection and cubeMX configuration will remain the same as we covered in previous tutorial.

You must Read the PART1 and PART2 before continuing with this one. These parts are written in series, and I am not going to cover the functions which have already been explained previously.



Shifting the Display

We will start by shifting the display towards the left. This is needed to create a scroll like effect. Below is the function for the same.

void shiftLeft (void)
{
	for (int cnt=NUM_DEV*8-2; cnt>=0; cnt--)
	{
		bufferCol[cnt+1] = bufferCol[cnt];
	}
	bufferCol[0] = 0;
	flushBuffer();
}

The shiftLeft function will shift the entire display to the left by 1 position. We know that the columns are arranged such that the rightmost column is COL1 and the leftmost is COL31. To shift the display to the left, we need to copy the data from the current column to the left column, which is 1 higher than the current column. The copying must start from the higher end, so that we can avoid the same data being passed to all the columns.

The cnt variable keep track of the current column we are working with.

Imagine when the cnt value is 31. Inside the for loop, we will copy the content of the COL31 into COL32. But COL32 can not exist for a cascade of 4 devices, hence we must start the cnt value from NUM_DEV*8-2, i.e 30.

Again when the cnt value is 0, the content of COL0 will be copied into COL1. But the for loop will end here and the content of the COL0 will remain unchanged. Here we need to manually update the content of COL0. We can either set it to 0, or we can assign the COL31 value to it so that there will be a circular effect.

The flushBuffer function will then flush the updated column data to the display.

Let’s test this function. Below is the code from the main()

const uint8_t data[] ={	0x00, 0x22, 0x41, 0x49, 0x49, 0x49, 0x36, 0x00};  // NUM 3
int main()
{
  ....
  matrixInit();
  clearDisplay();
  for (int i=0; i<8; i++)
  {
	  bufferCol[i] = data[7-i];  
  }
  flushBuffer();
  while (1)
  {
	  shiftLeft();
	  HAL_Delay(100);
  }
}

Here we will first copy the data for the number 3 into the start of the column buffer. Then call the function flsuhBuffer to display this number on the device.

Then call the shiftLeft function is the while loop every 100ms. This will continuously shift the entire display to the left.

Below is the video showing the output of the above code.

You can see the number 3 has been shifted all the way to the left. The shiftLeft function will shift everything on the display, hence we will utilise this function for scrolling string.



How to use the font file

I have fount a font library which can almost work with our setup. The font file contain the data for all the possible characters.

Below is the data for the number 1 from the font file.

  { 0x40, 0x42, 0x7F, 0x7F, 0x40, 0x40, 0x00, 0x00 }, // '1''

If we plot this data on the character generator tool with our setup, we will get the character as shown in the image below.

We got a inverted 1. That is why I said the library can “almost” work with our setup. We will get all the characters inverted if we use the library as it is.

Below is the image showing the data output, if we generate the number 1 with our setup.

The data output above does not look similar to what we have in the font file. But if we change the endianness in the character generator tool, we will get the exact data that we have in the font file. This is shown below.

This means that the font data is fine, we just need to change the endianness of each byte. The data in the font file is in Little Endian format and we need to change it to the Big Endian.

Changing the endianness is not that hard. Below are the images showing what it means.

As shown in the images above, Little Endian means that the data in the columns is arranged such that the Least Significant Bit is at the TOP. Whereas in Big Endian format, the Least Significant Bit is at the Bottom. So we just need to change the order of the bits before storing them to the main column buffer.



Shifting a character from the font file

Below id the function for shifting a character on the display.

void shiftchar (uint8_t ch, int delay)
{
	int indx=0;
	for (int i=0; i<FONT_WIDTH-1; i++)  // loop for all the bytes of the font
	{
		uint8_t data = 0;
		/* Chnage the order of the bits */
		for (int j=7; j>=0; j--)  // extract bits from a single byte
		{
			if ((MAX7219_Dot_Matrix_font[ch][indx])&(1<<j))  // if the bit is 1 // start extracting from the 7th bit of byte
			{
				data |= (1<<(7-j));  // start writing it from the 0th bit of data
			}
		}
		bufferCol[0] = data;  // store the modified byte to the first element only. It will shift later
		flushBuffer();
		shiftLeft();
		indx++;
		HAL_Delay(delay);
	}
}

Inside this function we will change the order of the bits for a single byte and then store the updated data byte in the bufferCol[0]. This column will print on the display and then its content will shift to bufferCol[1]. We will repeat this process for the entire font width, so that we can get the complete character on the display.

To change the order of the bits, we will take a single byte data for the specified character from the font file. Then check the bit at the 7th position of this byte. If the bit is a 1, we will write a 1 to the 0th position of the data byte. Next we will check the bit at the 6th position and update the 1st position of the data byte according to it.

The delay function controls how quickly we want to shift each column of the specific character.

Let’s test the above function. Below is the code for the main file.

int main()
{
  ....
  matrixInit();
  clearDisplay();
  shiftchar('C', 250);
  while (1)
  {}
}

Here we will simply call the function shiftchar to display the character ‘C’ on the device. Below is the video showing the output of the above code.

The character ‘C’ is successfully shifted on the display. We printed this character using the font library, so this means that we can use the font library for rest of the project as well.



Scrolling String

Scrolling the string is same as shifting a character. Here we will pass all the characters from the string to the shiftChar function.

void scrollString (char *str, int delay)
{
	while (*str)
	{
		shiftchar(*str, delay);
		*str++;
	}
}

int main ()
{
  ....
  matrixInit();
  clearDisplay();
  while (1)
  {
     scrollString((uint8_t *)"Hello World      ", 100);
  }
}

Here we will call the scrollString function inside the while loop, so that we can have a continuous scrolling effect. Below is the gif showing the output of the above code.



Print String

We were able to scroll the string on the display. Now we will see how to print a string on it. Below is the function to print a string on the display.

void printString (uint8_t *str)
{
	int strindx = 0;
	for (int k = NUM_DEV*8-1; k>=0; )
	{
		int indx=0;
		for (int i=0; i<FONT_WIDTH-1; i++)  // loop for all the bytes of the font
		{
			uint8_t data = 0;
			/* Chnage the order of the bits */
			for (int j=7; j>=0; j--)  // extract bits from a single byte
			{
				if ((MAX7219_Dot_Matrix_font[str[strindx]][indx])&(1<<j))  // if the bit is 1 // start extracting from the 7th bit of byte
				{
					data |= (1<<(7-j));  // start writing it from the 0th bit of data
				}
			}
			bufferCol[k--] = data;  // store the modified byte to the first element only. It will shift later
			indx++;
		}
		strindx++;
	}
	flushBuffer();
}

Inside this function, we will do the same as we did for the shiftChar function. We will get the data bytes for the respective character from the font library, and then change the order of the bits.

The updated data byte will be stored, starting from the COL31. This is necessary for the string to display from left to right.

Let’s test the above function. Below is the code from the main function.

int main ()
{
  ....
  matrixInit();
  clearDisplay();
  printString("1234");
  while (1)
  {}
}

Here we will print the number 1234 on the display. Below is the image showing the output of the above code.

You can see the number has been printed on the display. The display acts as one single unit, and therefore the characters are overlapping between the devices.



Result

You can watch the video to see the complete working of the process explained above.

Check out the Video Below




Info

You can help with the development by DONATING Below.
To download the project, click the DOWNLOAD button.

Subscribe
Notify of

0 Comments
Newest
Oldest Most Voted
Inline Feedbacks
View all comments
keyboard_arrow_up