Marlin: Full graphic controller issues under Arduino >1.0.6

Created on 22 May 2016  路  82Comments  路  Source: MarlinFirmware/Marlin

I have a Reprap discount full graphic smart controller connected to a K8200 (3DRag derivative).
U8glib is installed and #define REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER uncommented.

When compiling RC6 with Arduino 1.6.9 I get weird artefacts on the display:
img

Under 1.0.6 (version check in SanityCheck.h commented) it compiles with no errors and the display is working fine.

My configuration.h: http://pastebin.com/L0B7iak6

Confirmed ! Solved

Most helpful comment

Just hit this with a Tevo Tornado with a MKS GEN L board, and RRD Full Graphic Smart Controller, trying to install Marlin 1.1.8 then 1.1.9. Going to try some of the steps further up the thread with disabling the optims and changing timing. Ive also got a replacement display coming soon to hopefully prove/disprove whether its hardware. If it is, would be happy to forward the faulty one on to someone if it helps to troubleshoot or come up with workarounds.

Edit 1: commenting out #pragma GCC optimize (3) doesn't have any notable effect.

Edit2: @webliya has the solution that worked for me.

Added the 3 delays to configuration.h and after a bit of trial and error with the numbers, getting a perfect screen now.

#define REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER
#define ST7920_DELAY_1 DELAY_NS(0)
#define ST7920_DELAY_2 DELAY_NS(250)
#define ST7920_DELAY_3 DELAY_NS(250)

All 82 comments

@Gaffalover could you try to remove you current U8glib and do the following command:

# Install: Monochrome Graphics Library for LCDs and OLEDs
arduino --install-library "U8glib"

Compile with 1.6.9 and check if the error is still there ? Yesterday night I compiled my Marlin with 1.6.9 without issues.

Thanks for your reply.
Just gave it another shot:
Uninstalled 1.0.6 and deleted the %USERPROFILE%/Documents/Arduino folder.
Installed 1.6.9 and did your command -> same result as shown in the picture.
Just 4 fun I reinstalled 1.0.6 without touching the library folder or Program (except commenting the version check in SanityCheck.h) an it works fine.

For me it looks like an issue with the IDE at versions >1.0.6.
I even tried installing U8glib 18.0.0 instead of 19.x and lcddisplay 1.0 but without success.
I couldn't find anything noticeable in the changelogs of the Arduino IDE.

Do you mind trying with 1.6.8 ?

I even tried it with 1.6.5 and still no improvement.
In another forum somebody had exactly the same issue: http://fpv-community.de/showthread.php?69744-Hilfe-bei-Marlin-Mega-2560-Ramps-1-4-Full-Graphic-Display/page3
He used RC2 and 1.5.x with the same artifacts.

And clicking on the encoder to go into the menu doesn't clear the error ?

I have the same problem using Arduino 1.6.9 compiling Marlin 1.1.0-RC6
configured for the REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER

It seems to be caused by the compiler optimisation line in 'ultralcd_st7920_u8glib_rrd.h'
Change line 31
FROM:
#pragma GCC optimise (3)

TO:
//#pragma GCC optimize (3)

This will disable the optimisation and the LCD should display correctly.

NOTE: I haven't run full tests on this to see if printing is adversely affected but I suspect the later optimisation in Arduino 1.6.x has messed up the timing when sending data to the display.

@MarlinFirmware/general-maintainers Guys, this might be our chance to figure out what was going wrong with building Marlin with certain versions of Arduino. I may be wrong, but can't we remove that one line of code:

#pragma GCC optimise (3)

from the .h file and place it further and further down in the .cpp file until things work again? When things start working, we will know the location of the optimization failure and be able to figure out what keeps killing us????

This strategy is very crude, because if the LCD file has multiple failures, we may not get a good build until we have the #pragma line below them all. So if this strategy did produce results, we might want to change the code and start the search again to see if there are any other failures with the LCD file.

With that said... With this new information, we might be able to figure out what has been killing us.

@SwiftNick Thank You for the help! Do you have any comments on what I just suggested?

Dear @Roxy-3DPrintBoard
We are not killed. With 5 ST7920 from different sources we do not having any problems here.

Using Arduino 1.6.9 we do not see any speed differences but compiling without #pragma GCC optimise (3) saves about 2k of progmem.
With earlier Arduino versions there used to be a good speed impovement. (Don't ask what versions - versions from about a year ago)

So for now we can comment the #pragma GCC optimise (3) because it does not find faster code (just biger). But as soon it will do that again we definitely want to use that!

Using the standard configuration with just added REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER
and idelecounter patch (https://github.com/AnHardt/Marlin/commit/fd20acceb6e74f587287108d26a05503093f6a78)
System just booted and nothing to do.

//#pragma GCC optimize (3)

Der Sketch verwendet 83.886 Bytes (33%) des Programmspeicherplatzes. Das Maximum sind 253.952 Bytes.
Globale Variablen verwenden 3.842 Bytes (46%) des dynamischen Speichers, 4.350 Bytes f眉r lokale Variablen verbleiben. Das Maximum sind 8.192 Bytes.

23:45:05.556 : echo:idles/second: 10499
23:45:06.559 : echo:idles/second: 10520
23:45:07.559 : echo:idles/second: 10509
23:45:08.558 : echo:idles/second: 10509
23:45:09.557 : echo:idles/second: 10509
23:45:10.556 : echo:idles/second: 10521
23:45:11.560 : echo:idles/second: 10509
23:45:12.559 : echo:idles/second: 10505
23:45:13.558 : echo:idles/second: 10521
23:45:14.557 : echo:idles/second: 10497


#pragma GCC optimize (3)

Der Sketch verwendet 85.922 Bytes (33%) des Programmspeicherplatzes. Das Maximum sind 253.952 Bytes.
Globale Variablen verwenden 3.842 Bytes (46%) des dynamischen Speichers, 4.350 Bytes f眉r lokale Variablen verbleiben. Das Maximum sind 8.192 Bytes.

23:47:25.140 : echo:idles/second: 10517
23:47:26.139 : echo:idles/second: 10514
23:47:27.138 : echo:idles/second: 10515
23:47:28.138 : echo:idles/second: 10527
23:47:29.141 : echo:idles/second: 10515
23:47:30.140 : echo:idles/second: 10512
23:47:31.139 : echo:idles/second: 10527
23:47:32.138 : echo:idles/second: 10502
23:47:33.138 : echo:idles/second: 10527

So for now we can comment the #pragma GCC optimise (3) because it does not (generate) faster code (just big(g)er). But as soon it will do that again we definitely want to use that!

@Blue-Marlin Yes, but we have seen build problems on many versions of Arduino. And not all of those problem scenarios had graphics controllers. (In fact, as you know we are refusing to build with older versions of Arduino because we had too many weird problems that could not be explained.) Isn't this an opportunity to find out what code constructs are causing us problems? Maybe we have something declared wrong. Or maybe we are linking something wrong. Or maybe we have something else strange going on.

Even though we can get around this (for the moment) by commenting out the optimization, it bothers me we have to do that just because we have no idea why that is necessary.

It may be worth investigating the changes in the optimisation algorithm in newer versions of gcc that are shipped with Arduino. I have known bugs in optimisers that do stupid things like take items out of loops to make them run faster! Something has definitely changed as compiling with older tools seems to work. 03 turns on all optimisations so if size is the main reason for the optimisation it may be worth tweaking the flag.

If we knew which function required the relaxed optimization, we can compile it both ways and see what is going on. It may be a bug in the optimization. But it is also possible we have something declared in a way that the optimizer makes a bad decision (which I guess is still a bug). If we understood what was going wrong, it may be that we can harden the code (every where... Not just in the Graphics Controller code) to keep this from happening in the future.

How about doing some binary search in the file in question using push/pop options? Easiest first test would be just to move the "optimize" to the middle of the file.

#pragma GCC push_options
#pragma GCC optimize (3)


#pragma GCC pop_options

_I'd do it myself if I had my stuff setup and could see this happening_
Ah I see @Roxy-3DPrintBoard basically recommended this earlier

Yeah, but I didn't know about push & pop. That is cool! If I had a graphics controller, I would be trying to isolate it. I would still need help to get it to generate and leave the .ii files around. Every time I need to look at the generated assembly code, I can never get the files to stick around. But I know jbrazio can do it because he was posting instruction cycle timing for various code constructs.

-O3 turns on all optimizations specified by -O2 and also turns on the -finline-functions, -funswitch-loops, -fpredictive-commoning, -fgcse-after-reload, -ftree-vectorize and -fipa-cp-clone options.

-funswitch-loops and -fpredictive-commoning will produce bigger code and apply some optimization that could break loops().

The only person who is able to test which exact function/piece of code breaks with -O3 is @Blue-Marlin which seems to have access to this specific LCD.

And... given what you just communicated... Once we identified the function with the optimization problem, we could even just turn on one more optimization at a time for the function until we find the one causing problems.

Yes we can either keep behavior of optimizing all and exclude that specific part, or has @Blue-Marlin suggested disable all the optimization has it seems not to have a positive effect with the latest gcc toolset.

Concerning this being the reason for other IDE issue we had.. I don't believe so and this only activates optimization for this file and I did a quick grep a no other #pragma were found.

I've done the binary search and the optimisation fails for the first function in the file:
If you move the push just below and the pop at the end of the file, to exclude this function the display works just fine.

static void ST7920_SWSPI_SND_8BIT(uint8_t val) {
  uint8_t i;
  for (i = 0; i < 8; i++) {
    WRITE(ST7920_CLK_PIN,0);
    #if F_CPU == 20000000
      __asm__("nop\n\t");
    #endif
    WRITE(ST7920_DAT_PIN,val&0x80);
    val<<=1;
    WRITE(ST7920_CLK_PIN,1);
    #if F_CPU == 20000000
      __asm__("nop\n\t""nop\n\t");
    #endif
  }
}

Can you selectively turn on more of those flags for the first function and find out which one is causing the problem?

And then using that information we may need to look at the generated assembly code. But there is very little going on there. It might be a timing problem. Or maybe the GCC is optimizing away one of the writes to ST7920_CLK_PIN. (Don't have time to look at those macros right now. But will in the morning.)

@SwiftNick
What board do you use?

The 3drag with the ATMega2560 (shipped with the Velleman k8200)

<a href="http://reprap.org/wiki/File">http://reprap.org/wiki/File</a>:3Drag_controller_top.jpg

@SwiftNick
Please make a test with O3 but activated nop's.

I would bet on the WRITE(ST7920_CLK_PIN,0); and WRITE(ST7920_CLK_PIN,1); ending out of the cycle due to -fpredictive-commoning. But your suggestion is interesting.. you believe optimization is going "too fast" for bit banging so it requires the delay.

@jbrazio
I suppose a bad display, to long cables, to much noise, not enough voltage or a wrong crystal on the board - a hardware problem what requires a relaxed timing.
If @Gaffalover and @SwiftNick have the same problem and both have a K8200, but "noone" else sees the problem, i suppose a systematic problem, like too long cables, with the K8200. Than a fix for K8200 is better then maybe slowing down all ST7920 displays.

In theory the impact of adding 3 nop's should be smaller than not unrolling the loop (about 5 nop's - increase i in a register, jump back, compare i). I'm just interested in how far off some K8200's are.

I thought it was those too so I commented them out and the screen worked just fine.
The ATMega2560 has a 16Mhz clock so I guess they are disabled in my case anyway by the F_CPU definition.

Right final comment tonight then I'm going to bed!
The 3drag board runs at 16Mhz so the nop's are disabled.
if I enable the nop's for 16Mhz+ the display works just fine with the optimisations enabled.
so my function now looks like this: and the optimisation is enabled.

static void ST7920_SWSPI_SND_8BIT(uint8_t val) {
  uint8_t i;
  for (i = 0; i < 8; i++) {
    WRITE(ST7920_CLK_PIN,0);
    #if F_CPU >= 16000000
      __asm__("nop\n\t");
    #endif
    WRITE(ST7920_DAT_PIN,val&0x80);
    val<<=1;
    WRITE(ST7920_CLK_PIN,1);
    #if F_CPU >= 16000000
      __asm__("nop\n\t""nop\n\t");
    #endif
  }
}

@jbrazio @SwiftNick @Blue-Marlin

I would think this is a different problem than a hardware problem with the cables.

Lets collect what we know now:

  • For older Arduino IDEs it works well.
  • With newer Arduino versions you need to deactivate optimizations or enable the ASM-NOP sequences for 16 MHz, too.
  • For older IDEs you need the ASM-NOP sequences for 20 MHz boards, for 16MHz or slower they are omitted.
  • NOPs are used to pause the program one cycle because it would be to fast. Mostly they are put in by trial and error.
  • Optimization makes programs faster.
  • The new GCC is sometimes significantly faster with activated optimization.

Conclusion(s):

  • The new IDE speeds up the code.
  • For fast execution the code needs NOPs.
  • Now it needs them for 16 MHz, too.

@SwiftNick I have a K8200 too, but only with LCD2004 display module.

Could you please test the following:

1)

  • first #if F_CPU to == 20000000
  • second #if F_CPU to >= 16000000:
static void ST7920_SWSPI_SND_8BIT(uint8_t val) {
  uint8_t i;
  for (i = 0; i < 8; i++) {
    WRITE(ST7920_CLK_PIN,0);
    #if F_CPU >= 20000000
      __asm__("nop\n\t");
    #endif
    WRITE(ST7920_DAT_PIN,val&0x80);
    val<<=1;
    WRITE(ST7920_CLK_PIN,1);
    #if F_CPU >= 16000000
      __asm__("nop\n\t""nop\n\t");
    #endif
  }
}

2)

  • first #if F_CPU to >= 16000000
  • second #if F_CPU to >= 20000000:
static void ST7920_SWSPI_SND_8BIT(uint8_t val) {
  uint8_t i;
  for (i = 0; i < 8; i++) {
    WRITE(ST7920_CLK_PIN,0);
    #if F_CPU >= 16000000
      __asm__("nop\n\t");
    #endif
    WRITE(ST7920_DAT_PIN,val&0x80);
    val<<=1;
    WRITE(ST7920_CLK_PIN,1);
    #if F_CPU >= 20000000
      __asm__("nop\n\t""nop\n\t");
    #endif
  }
}

3)

  • first #if F_CPU to == 20000000
  • second #if F_CPU to == 16000000: with only one NOP, two NOPs for 20MHz
static void ST7920_SWSPI_SND_8BIT(uint8_t val) {
  uint8_t i;
  for (i = 0; i < 8; i++) {
    WRITE(ST7920_CLK_PIN,0);
    #if F_CPU >= 20000000
      __asm__("nop\n\t");
    #endif
    WRITE(ST7920_DAT_PIN,val&0x80);
    val<<=1;
    WRITE(ST7920_CLK_PIN,1);
    #if F_CPU >= 16000000
      __asm__("nop\n\t");
    #endif
    #if F_CPU >= 20000000
      __asm__("nop\n\t");
    #endif
  }
}

4)

  • first #if F_CPU to >= 16000000
  • second #if F_CPU to == 16000000: with only one NOP, two NOPs for 20MHz
static void ST7920_SWSPI_SND_8BIT(uint8_t val) {
  uint8_t i;
  for (i = 0; i < 8; i++) {
    WRITE(ST7920_CLK_PIN,0);
    #if F_CPU == 16000000
      __asm__("nop\n\t");
    #endif
    WRITE(ST7920_DAT_PIN,val&0x80);
    val<<=1;
    WRITE(ST7920_CLK_PIN,1);
    #if F_CPU >= 16000000
      __asm__("nop\n\t");
    #endif
    #if F_CPU >= 20000000
      __asm__("nop\n\t");
    #endif
  }
}

We should then use the fastest running variant.

BTW: This should not work on the Arduino DUE, too. Definitely a point for the HAL.
BTW 2: The == 20000000 is stupid: If you have 25 MHz, it won't work. But definitely need NOPs...

Wow, all you guys got my biggest respect!
I tried all 4 of CONSULitAS snippets:
1 trough 3 generated slightly different artefacts, but #4 did the trick!
Fully operational display! :)
Thank you so much.

@CONSULitAS
I agree with your statements only if you are explicitly talking about not working K8200 with 3drag. For all other configurations we do not have any hint for misbehaviour. My displays run flawlessly even with a more aggressive timing.

@Blue-Marlin if we can create a new baseline which works for all having one additional "nop" I would prefer it rather than spaghetti #ifdef..

I'm willing to get beat up for this... But now that it works, I would add an extra NOP or two at each of those locations.

Next week you will put delays in the stepper interrupt,for all, because a new stepper driver is too slow.

That's not a logic reasoning from you..

  1. We're discussing one nop
  2. This is the LCD vs. the stepper which is critical code

We are discussing two from several 1000 displays.

Next week you will put delays in the stepper interrupt,for all, because a new stepper driver is too slow.

@Blue-Marlin You not being fair and objective. Remember... You were the one that was totally comfortable with turning off all optimization to slow ALL OF THIS CODE down to keep the problem from happening.

We are discussing two from some 10000 displays.

Is it possible that it is not the displays, but instead we are seeing noise and/or ringing on the signals going to the display? If it is only 2 out of 10000 that might be a more likely explanation of things.

@Blue-Marlin

  • How many MHz has your board? Perhaps 20MHz?
  • Did you check your conclusion that it is noise on the lines with a scope?
  • Did you check that you have the same hardware version and batch of the display like @SwiftNick and @Gaffalover ?

BTW:

  • Marlin tries to work for every hardware combination.
  • This is a verified bug (see labels).
  • How do you know that it works on 10000 displays?

    • You have one (working).

    • I have one (working, but different model).

    • thinkyhead has one...

When i found the M117 bug which has broken SD file access, too, we had only a few complains. This has more than one reason:

  • Only few users know about the Marlin Github repository and how to flash theirselves.
  • Fewer dare to use a "non stable" version.
  • Many of the rest say "Oh a bug, lets try an other version".
  • Many don't know to make an issue and complain in other forums (ask foosel and others).
  • ...

So

  • We have found a (verified) bug.
  • We have a solution.
  • We know why my proposed code works (timing can be really critical).
  • This will not affect overall speed of Marlin.

What the hell is the problem now?

Perhaps we go to

Sorry, but i feel that your feedback is not fair and objective, too.

@jbrazio @Roxy-3DPrintBoard
I think we need a pull request right now. Shall i, will you?

@CONSULitAS Initially I said:

Please prepare a pull request that conforms to the fourth solution that seems much more reliable. I don't have one of these boards. But I would feel more comfortable if we could check to see if it is a signal / noise issue. The problem is we need one that is failing to be at the same place as somebody with an Oscilloscope.

But let's tie out with jbrazio and Blue-Marlinfirst. Jbrazio is thinking:

if we can create a new baseline which works for all having one additional "nop" I would prefer it rather than spaghetti #ifdef..

The reason I want to move a little bit slower is two-fold. First I'm in agreement we don't want extra #ifdef's in the code. But to me, this seems like a good place to use them. They are at the very lowest level of the code where it is bit banging data across a serial interface. And they are controlling a very small amount of code that you can still see exactly what is happening with them turned on or off. Let's talk through this.

The second part of why I want to move slower is Blue-Marlin does know his stuff and he is uncomfortable with extra delays being added to the code. And even though we are only talking about a couple of NOP's, they are inside a loop (of 1 to 8) that gets called again and again until the whole display is painted.

With that said, we really do want to support all flavors of hardware. Even hardware that is wired less than ideally.

Let's get everybody comfortable with the direction we are going before we move.

@Gaffalover Would you mind sending us some pictures of your cabling going to the display? Is the wiring close to or running for some distance next to high current lines like the stepper motor wires?

Do what you want. I'm perfectly able to change it to my taste.

I'm very sorry for my obviously to bad writing. Most of you seem to read things in my messages i have never written, or do miss things, where i think, i have written about. Or is it your reading?

With 5 ST7920 from different sources we do not having any problems here.

Using the standard configuration with just added REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER

So for now we can comment the #pragma GCC optimise (3) because it does not find faster code (just biger). But as soon it will do that again we definitely want to use that!

Thanks, that helps make it easier to move to resolution. Let's see what Jbrazio is thinking about the #ifdef's.

@Roxy-3DPrintBoard

Would you mind sending us some pictures of your cabling going to the display? Is the wiring close to or running for some distance next to high current lines like the stepper motor wires?

Sure.
The cable is a bit improvised but technically checked with a ohm meter.
The oscillogramms are taken as close to the connectors as possible:

The shots are taken with RC6 and the #4 modification mentioned by @CONSULitAS

img_0338
pic_22_1.jpg seems to be some kind of enabling:
pic_22_1
pic_22_5.jpg is the display data
pic_22_5
and pic_22_6.jpg is a closeup of the first bytes from pic_22_5.jpg.
pic_22_6

Those signal pictures are taken at the graphics display? Or are they taken at the processor board. They look fairly clean.

I pierced the cables running to the connectors of the controller. :/
I personally won't believe its an noise error.
Maybe tomorrow I can do some more shots without the modification so there is a comparison,
but thats all the time I got for tonight.
Thanks again guys.

You can rule out any interference from other cabling, as the problem occurs when the machine is at idle and powering up. All stepper motors are disabled.
My cables are crimped at one end and soldered at the other and are very short.
wp_20160602_20_42_56_pro

I haven't had any display issues in any other version of Marlin I've used so it is something introduced in the later releases. It would seem that there is a timing issue for faster boards as the no-ops have been added already for CPUs with a 20Mhz clock. (they aren't in earlier releases). It seems with the improved optimisation, some 16Mhz board / display combinations are now on the edge timing wise.

CONSULitAS
My test results:

1) Fails with display artefacts but slightly better than the original firmware

2) Fails with display artefacts but slightly better than the original firmware but worse than #1)

3) Fails with display artefacts similar to #2)

4) Works just fine.

@CONSULitAS

BTW: This should not work on the Arduino DUE, too. Definitely a point for the HAL.

I don't see clearly that the following infomation about Due-based system is helpful to solve the problem in this thread or not, but I'd like to help as much as possible.

In case of Marlin4Due, it has been implementing by _delay_us() that it was written by inline assembler.
It seems that roots of this function is HAL::delayMicroseconds() in Repetier-Firmware.

In case of Marlin4Due, it has been implementing by delayMicroseconds().
Waits are 2渭s + 2渭s.

static void ST7920_SWSPI_SND_8BIT(uint8_t val)
{
  uint8_t i;
  for( i=0; i<8; i++ )
  {
    WRITE(ST7920_CLK_PIN,0);
    delayMicroseconds(2);
    WRITE(ST7920_DAT_PIN,val&0x80); 
    val<<=1;
    WRITE(ST7920_CLK_PIN,1);
    delayMicroseconds(2);
  }
}

And in case of Marlin Duo that it's ported version from Marlin4Due and MK4due to newest RCBugFix by me,
Code in HAL is similar to Marlin4Due, and I use the function for delay in HAL instead of the delayMicroseconds(), and I decreased waits to 1渭s + 1渭s.
My RRD full graphic smart controller + long signal cable(about 800mm) with Due-based system(Arduino Due + RAMPS Duo(it's similar to RAMPS4DUE))
is working without problems with that setting.
Arduino IDE version is 1.6.10 Hourly Build 2016/05/31 11:13, U8glib version is 1.19.1, version of package for SAM is 1.6.8.

  static FORCE_INLINE void HAL_delayMicroseconds(uint32_t usec) { //usec += 3;
    uint32_t n = usec * (F_CPU / 3000000);
    asm volatile(
      "L2_%=_delayMicroseconds:"       "\n\t"
      "subs   %0, #1"                 "\n\t"
      "bge    L2_%=_delayMicroseconds" "\n"
      : "+r" (n) :  
    );
  }
static void ST7920_SWSPI_SND_8BIT(uint8_t val) {
  uint8_t i;
  for (i = 0; i < 8; i++) {
    WRITE(ST7920_CLK_PIN,0);
    #ifdef __SAM3X8E__
      HAL_delayMicroseconds(1);
    #else
      #if F_CPU == 20000000
        __asm__("nop\n\t");
      #endif
    #endif
    WRITE(ST7920_DAT_PIN,val&0x80);
    val<<=1;
    WRITE(ST7920_CLK_PIN,1);
    #ifdef __SAM3X8E__
      HAL_delayMicroseconds(1);
    #else
      #if F_CPU == 20000000
        __asm__("nop\n\t""nop\n\t");
      #endif
    #endif
  }
}

dscn1618

@Blue-Marlin

Do what you want. I'm perfectly able to change it to my taste.

Yes. We know you can do that. But if you have strong feelings, we want to understand them because we are concerned about the less technical users. We don't want to go against good, solid technical advice.

I'm very sorry for my obviously to bad writing. Most of you seem to read things in my messages i have never written, or do miss things, where i think, i have written about. Or is it your reading?

That is something that happens when people highly respect your opinion. If you say something, even if it is poorly worded, they are going to listen! They are going to try to make sense of it. And it is possible (at least in my case) it is the reading of the message too. With so many highly technical topics going by everyday, there is only time to skim a lot of them. So everybody needs to be patient with everybody.

May i suggest https://github.com/AnHardt/Marlin/pull/43 ?
Where all party's would have their profit.

It needs some further test by you to find the right delays
All our REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER clones do work completely without nops at our RAMPS boards - but your mileage may vary

An other micro second can be saved by replacing u8g_10MicroDelay() with delayMicroseconds(5) but here our displays differed more. (2x4碌s, 2x5碌s, 1x6碌s)

@SwiftNick @Blue-Marlin @CONSULitAS Can we all test Andreas solution ? It's a lot more verbose source code wise but has huge savings: 1k memory, the only issue is it will change code path for all.. working and non working LCDs so validation is more crucial.

All our REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER clones do work completely without nops (on) our RAMPS boards - but your mileage may vary

@AnHardt This is an example of where sending out a few loaner units helps everybody. It is very difficult to test the firmware side without hardware but the people doing the firmware can't buy every piece of hardware. Right now I'm trying to get consensus to make some changes to the Readme file that basically say to the hardware vendors we are going to support your hardware and your users no matter what. But it would make our life a lot easier if we had real hardware on loan that we can code against.

@SwiftNick @Gaffalover
The timing of the ST7920 depends on the voltage it gets. Please measure GND - 5V at the display side of the cables.
https://github.com/AnHardt/Marlin/pull/43#issuecomment-223574911

@AnHardt Do you feel your PR https://github.com/AnHardt/Marlin/pull/43 is ready, or does it need more testing?

More testing definitely, no one replied yet.

Sorry away over the weekend, will test on Monday

I replaced my function with the new code below and I get very minor character corruption.
The top line of the ? on the info screen are corrupted until the second flash.
If I increase the first delay to 3uS there is no corruption.

Compiled using Arduino 1.6.9, UG8Lib v1.19.1, Marlin 1.1.0-RC6

static void ST7920_SWSPI_SND_8BIT(uint8_t val)
{
  uint8_t i;
  for( i=0; i<8; i++ )
  {
    WRITE(ST7920_CLK_PIN,0);
    delayMicroseconds(2);
    WRITE(ST7920_DAT_PIN,val&0x80); 
    val<<=1;
    WRITE(ST7920_CLK_PIN,1);
    delayMicroseconds(2);
  }
}

VCC at the edge connector of the LCD PCB is 4.98v

@SwiftNick
Thank you for your tests.
Would you please now be so kind to test how many delays you need for your machine in https://github.com/AnHardt/Marlin/pull/43.
That PR saves a bit of memory, speeds up copying one byte from memory to the display a bit in general, but allows to easily insert waits tor those who need them. Adjusting with _nop's_ can be much more exact than with delayMicroseconds().
The defines for

#elif MOTHERBOARD == BOARD_3DRAG || (MOTHERBOARD == BOARD_K8200)
   #ifndef ST7920_DELAY_1
     #define ST7920_DELAY_1 DELAY_0_NOP
   #endif
   #ifndef ST7920_DELAY_2
     #define ST7920_DELAY_2 DELAY_0_NOP
   #endif
   #ifndef ST7920_DELAY_3
     #define ST7920_DELAY_3 DELAY_1_NOP
   #endif
 #elif F_CPU == 16000000

The values are already adjusted for the theoretically needed pauses at 4.5V and above.
We already know your display - controller combination needs more waits. Your job is to find out, _how many_.

Edited

The lowest number of nop's I had to insert to prevent display corruption was 3

#elif MOTHERBOARD == BOARD_3DRAG || (MOTHERBOARD == BOARD_K8200)
   #ifndef ST7920_DELAY_1
     #define ST7920_DELAY_1 DELAY_0_NOP
   #endif
   #ifndef ST7920_DELAY_2
     #define ST7920_DELAY_2 DELAY_3_NOP
   #endif
   #ifndef ST7920_DELAY_3
     #define ST7920_DELAY_3 DELAY_0_NOP
   #endif

The following nop configurations are all good and will stop the display corruption.
Taken in the order:
delay_1, delay_2, delay_3
0,3,0
1,1,2
1,2,1
2,1,1

anything smaller does reduce the corruption but does not eliminate it.
These combinations do not work.
0,0,3
3,0,0
0,1,2
0,2,0
1,1,1

@SwiftNick
Strange. At the place of DELAY_2 the datasheet requires 50ns - less than an instruction.
However. Thank you for testing. I'll make the PR ready tomorrow with 0,3,0.

I guess what we really need is to test a few more boards to see if the pattern is the same and the issue isn't down to a single rogue display.

Disabling optimisation works for me too. My configuration: melzi ardentissimo atmega1284P and full graphic rrd smart controller. Using Arduino IDE 1.6.9.

@roglio
Did you have a problem before?

Yes and no: the first patch to use a melzi with those lcd was mine but it was a lot of time ago (see https://github.com/MarlinFirmware/Marlin/pull/1386).

Now I decided to upgrade to the latest Marlin RC version but both RC and 1.0.x suffer of this problem.
Then looking for a solution, I stumbled on this issue and found a fix.

@roglio
Ah. I see. I have prepared a slightly more exact tunable version ( #4002). Would you please be so kind to test it? If Melzi needs a special timing i'd make a special case.

@AnHardt: Sure! This afternoon (Italy GMT+2) I should be able to give it a try an let you know the result.

@AnHardt: From an optimisation point of view, with my configuration I obtain these values.

original with #pragma: 109,918 bytes
original without #pragma: 106,962 bytes (working for me)
AnHardt fix: 107,426 bytes (not yet tested)

@AnHardt: nope your patch does not work on my Aurora Z605. My board is a Melzi Ardentissimo equipped with an atmega1284p clocked at 16mhz. My build environment is Windows 10 Pro 64bit, Arduino IDE 1.6.9 (portable) with latest u8glib and latest Marlin RC.

Disabling optimization it works like a charm!

@roglio
Thanks for testing.
What delays did you try? Likely you have to add some more.

Hi @AnHardt, I tested only the default ones. IMHO it should be better to disable optimizations only for the ST7920_SWSPI_SND_8BIT function.

Closed by #4148

FYI have upgraded my controller to the 3DualDrag which has the same timing requirements as the 3DRag.

Hi. I followd your post with interest because i have the same problem.
I did remove the "//" in the line "//#pragma GCC optimize (3)". That solved one problem. Now the screen shows no garbled artafacts anymore like in the photo from Gaffalover. The screen is now spaced out like it should.
However; the problem i have is that i ONLY get graphical content on my screen. It shows only the nozzle icon, heatbed icon, fan icon, X,Y,Z bar, SD-Card icon & progress-bar.
You can watch this to see what i mean: https://youtu.be/o_hSNFkWCd8.

I don't know a tiny little bit about programming. I did once made basic programs but c++ is out of my leage. The examples in this post i did try but with no result.

I am using a Velleman K8200 with the Reprap Discount Full Graphic Controller with Arduino 1.6.11 and Firmware Release Candidate -- Marlin 1.1.0-RC3 - 01 December 2015 from Github.

I don't think it's the flatcable because in Marlin 1.0.6 with the stock firmware 2.1.1 everyting is working fine accept the Auto bed leveling (wich is not implemented in versin 2.1.1). Even the Reprap Discount Full Graphic Controller is working fine.
The only reason of changing to the new firmware is the Auto Bed Leveling.
Til now it only gives me troubles so if ths could be solved i realy jump a hole in the air.

Thank you

VenHeelun,
Try a later build.
There are fixes in RC7 already.
https://github.com/MarlinFirmware/Marlin/archive/RC.zip
It looks like the fonts are missing.

Dear SwiftNick
Thank you, Thank you.
I uploaded the firmware and did get an error regarding the LCD_PROGRESS_BAR.
I put "//" before "#define LCD_PROGRESS_BAR" in the Configuration_adv.h file and everything finaly works.
Now i finaly can setup the rest of my printer.
I don't think i can be very helpfull in this discussion but i will follow it further.
Again thank you.

Sorry for unburying this old thread, but I have some issues with my

Reprap Discount Full Graphic Controller on a MKS Base 1.4 with the latest RCBugFix.

With short cables everything works as intended, but as soon as I switch to a longer cable (about 60cm, even ordered a shielded ribbon cable that was ridiculously expensive, no dice) the display doesn't turn on anymore and only emits a "ticking" sound.
My guess is that the long cable somehow screws up the comunication. Will playing around with the Delays as possible through the configuration solve this problem?

Can I start with large delays and work my way down until it works?

Try to change EXP1 with EXP2. A dark display is never caused by to short delays. The tick sound means the buzzer is connected to one of the SPI lines.

Welp, turns out not one but both the ribbon cable orientations is flipped on either my board or my display. Bit the bullet and forced them in reversed and everything works flawlessly. Thanks for the hints.

Hey, I just want to confirm this bug on Melzi (some spin-off by Malyan for M150, as some pins don't match) with some kind of "Reprap Discount Full Graphic Controller" display. Compiling with Arduino 1.6.4 (disabled sanity check) supplied by Fedora 25, U8glib 1.19.1.

I was not able to fix display fragments by NOP sequence 0,3,0 (nor 0,0,4, nor 1,2,0 - almost random pick-ups, trying to figure out the pattern), but 0,4,0 and 2,2,0 sequences work great (1,2,1 and 2,1,1 gave few random pixels). As if there have to be 4 NOPs before WRITE(ST7920_CLK_PIN, HIGH);, DELAY_1 doesn't matter at all, and none after. No idea why. Looking at the assembly, there are all four of NOP.

But for now, I have working firmware for Malyan M150 and 1.1.0-RC8. I will test it a bit, and then share example_configuration.

There is a source dump by vendor, that seems to be based on 1.0.2-2. Assuming they got it somehow (I did not) working with some past versions of Arduino, this issue may be related to newer versions of arduino. (as stated before).

Thanks!

Hi @AnHardt @Gaffalover @FHeilmann @thinkyhead and the rest....

I just ended up here by googleing the same issues on the first screenshot of this thread.
Mine is a CR-10 Creation Reality printer, that comes with a Melzi variant where I burned the bootloader and upgraded Marlin 1.0 to Marlin 1.1.3

For that, I used Arduino 1.6.8, a MEGA256 (Genuino) and u8glib_arduino_v1.18.1.zip

Stock board, LCD and Marlin 1.0 had the LCD working fine.
Now, with 1.1.3 aboard, I have the issues pictured on the first thread (aka https://camo.githubusercontent.com/ae36cee75437f8ad2ca2cc709c04b52d9e1f34dd/687474703a2f2f696d616765732e7461706174616c6b2d63646e2e636f6d2f31352f31302f32372f39636431646139363238626533656130343366396137643037353938383765312e6a7067)

Mine are a bit more readable and once I move the knob and position on a Menu option, the font shows it clearly and readable. Once you move out to point to a new option, new option reads fine but the option before becomes unreadable again.

When compiling I had a warning I reported to u8glib and they only pointed out I could try with u8glib2.

Is this related or shall I seek somewhere else? I couldnt understand the problem since it's the very same hardware and wire that was working fine with 1.0 so it must be software related?

Thanks!

I had the same problem. It is a clock issue. Just changing the delays worked perfect.

in ultralcd_st7920_u8glib_rrd.h I found this and copied to configuration.h to the end of lcd definitions;

// If you want you can define your own set of delays in Configuration.h
//#define ST7920_DELAY_1 DELAY_0_NOP
//#define ST7920_DELAY_2 DELAY_0_NOP
//#define ST7920_DELAY_3 DELAY_0_NOP

and to give some delay I changed it to;

// If you want you can define your own set of delays in Configuration.h
//#define ST7920_DELAY_1 DELAY_0_NOP
//#define ST7920_DELAY_2 DELAY_3_NOP
//#define ST7920_DELAY_3 DELAY_0_NOP

And screen is clear and brilliant than ever.

This problem is using a reprapdiscount full graphic smart controller with Melzi board. I build a special cable with the instructions below;
https://www.thingiverse.com/thing:488884
which works perfect.

You can see the photos of all at;
https://www.dropbox.com/sh/34a0ebds318r3th/AABkLBRiUXoFWGCz7eVX-tkwa?dl=0

Thanks for the ideas here.

i have an issue with the same lcd, i have 2 identical displays, one works fine but when i plug they other one in i get the same thing, some of the display shows, some is missing, swap it back to the 1st lcd gain and it works fine again

Just hit this with a Tevo Tornado with a MKS GEN L board, and RRD Full Graphic Smart Controller, trying to install Marlin 1.1.8 then 1.1.9. Going to try some of the steps further up the thread with disabling the optims and changing timing. Ive also got a replacement display coming soon to hopefully prove/disprove whether its hardware. If it is, would be happy to forward the faulty one on to someone if it helps to troubleshoot or come up with workarounds.

Edit 1: commenting out #pragma GCC optimize (3) doesn't have any notable effect.

Edit2: @webliya has the solution that worked for me.

Added the 3 delays to configuration.h and after a bit of trial and error with the numbers, getting a perfect screen now.

#define REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER
#define ST7920_DELAY_1 DELAY_NS(0)
#define ST7920_DELAY_2 DELAY_NS(250)
#define ST7920_DELAY_3 DELAY_NS(250)

Thanks for the solution Chompworks. This solved my issues going from 1.1.8 to 1.1.9. Running a bespoke Jgaurora Z603s motherboard. Can release an update now.

Steve

This issue has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.

This issue has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.

Was this page helpful?
0 / 5 - 0 ratings