FreeRTOS 8.2.3 Arduino Mega2560 issue with alphanumeric screen HD44780

admbrt wrote on Thursday, September 22, 2016:

Hi,
I’m working on robot controller based on Arduino Mega 2560 with alphanumeric lcd screen and 4x4 keyboard. Robot is controlled pneumatically with 8 relay dedicated board. I’m using FreeRTOS 8.2.3 port for Arduino by Phillip Stevens and Richard Berry with 4 threads running. The screen is HD44780 compatible and I use standard Arduino Liquid Crystal library for handling screen display. All threads are running perfectly fine, there are no issues with stack overfloting etc, there is just one problem with screen displaying. At the start of the program, the screen displays normally what it should display, but after some time there are errors in the displayed content or even the content is not displayed. It looks like some sort of synchronization issue or so. To avoid concurecy interrupts i suspend other threads when communicating with display, but this does not solve the problem. I conducted some tests and left the controller not connected to robot but simulating normal working conditions and there were no problems with displaying. I wonder if there is some sort of backgroud mechanism, that may have impact on communication with the screen? I’ve checked the power source and there are no voltage drops. If this is not a software issue, then faulty is the connection between board and the screen or the problem is hiddent very deep in the hardware. I ad example of display communication handling:

 Screen.noBlink();
	Screen.clear();
	if (!movementsController->GetAutoMode()) {
		#if (SUSPENDING_ALL == 1)
            vTaskSuspendAll();
           #endif
        #if (PRIORITY_SWITCHING == 1)
            vTaskPrioritySet(xTaskGetCurrentTaskHandle(), tskIDLE_PRIORITY + 4);
        #endif
        #if (CRITICAL_SECTION == 1)
            taskDISABLE_INTERRUPTS();
        #endif
		Screen.println("A-Ustawienia Rozdzi.");
		Screen.println("B-Ustawienia Robota");
		if (splitter->GetBearingsReady()) {
			Screen.println("WSAD WYKRYTY");
		} else {
			Screen.println("WSAD NIE WYKRYTY");
		}
	} else {
		if (splitter->GetHeated()) {
			PrepareScreen();
			Screen.print("Cykle: ");
			Screen.print(movementsController->GetCounter());
		} else {
			PrepareScreen();
			Screen.println("NAGRZEWANIE");
			Screen.println("0 - nagrzane");
		}
		Screen.setCursor(0, 2);
	}
    Screen.print("Tryb:");
	if (movementsController->GetAutoMode())
		Screen.print("AUTO");
	else
		Screen.print("REKA");
	Screen.print(" Temp ");
	Screen.print(splitter->GetTemperature());
	Screen.print((char) 223);
	Screen.print("C");
	Screen.setCursor(14, 3);
	Screen.display();
	#if (SUSPENDING_ALL == 1)
		xTaskResumeAll();
    #endif
    #if (PRIORITY_SWITCHING == 1)
		vTaskPrioritySet(xTaskGetCurrentTaskHandle(), tskIDLE_PRIORITY + 3);
    #endif
    #if (CRITICAL_SECTION == 1)
		taskENABLE_INTERRUPTS();
    #endif

After displaying, the thread waits for the notification.

heinbali01 wrote on Friday, September 23, 2016:

Hi Adam,

You have been trying-out several methods:

    CRITICAL_SECTION
    SUSPENDING_ALL
    PRIORITY_SWITCHING

I think there are two more methods worth considering:

    LCD_USE_SEMAPHORE

meaning: acquire a semaphore before accessing the display.

    LCD_USE_DISPLAY_TASK

meaning: create a separate task that will handle all requests for the display.
You can give that task a message queue that accepts all types of commands ( clear / write / scroll / invert / LED ).

I think I would prefer the LCD_USE_DISPLAY_TASK solution. That LCD-task will own the display-controller and it can run at whatever priority it likes. All other tasks may produce LCD output without loosing time on the controller itself.

I conducted some tests and left the controller not connected
to robot but simulating normal working conditions and there
were no problems with displaying

Can you explain that more, maybe rephrase that? I don’t understand under what circumstance it does work without problems.

then faulty is the connection between board and the
screen or the problem is hidden very deep in the hardware

Have you tried to update the LCD at a high frequency but from a single task? E.g. just have it constantly display an increasing 64-bit number or so? Will you see errors?

Hardware problems: it is always worth double-checking the hardware: are all lines well defined? Are the LCD and your system at the same voltage level?

The HD44780 needs time to process your command. I used the same controller and my source code comment says: “wait 45 µS”. That is just before sending 2 nibbles of a byte. Are you using some Busy line or a fixed delay?

Please report how things go.

Regards.