Artifact on Giga Display shield

TL;DR: Giga Display Shield displays artifacts from previous code despite flashing new code

Got my Giga R1 and the display shield literally 2 days ago, trying out today.

I tried the "basic" example from Arduino_GigaDisplay_GFX.h, which worked as expected. Then I moved on and tried using the Arduino_H7_Video.h, ArduinoGraphics.h, lvgl.h and custom picture library. However, after reboot or reset, the display shows artifacts from the first example for the brief moment. In the second code, I have used display.clear(), it didn't help. However, the custom photo is displayed properly though. Please ignore the Due in the picture, the shield is connected to Giga.

To make it clear:

Steps that I did:

  1. Tried Arduino_GigaDisplay_GFX.h library
    1.1. The code works as intended
  2. Tried Arduino_H7_Video.h, lvgl.h, customImage.h
    2.1. After reset, there is an artifact (same everytime) from the step 1.1
    2.2. Custom photo from customImage.h is displayed properly
  3. Added display.clear()
    3.1. Issue still exists
    My question is about 2.1, is this normal?

Received a GIGA R1 just yesterday and notice the same thing. Similarly I ran the example sketches, and for brief moment can see the previously loaded graphic/text after new upload and subsequent resets. But, um, today, did not bother to notice it.

1 Like

I have the same problem.
My Giga Display has worked for days, then after the Nth sketch uploading the display started to show artifact.

Now also the basic examples are not working

Any solution ?

Perhaps...encountered similar such goings on...

Regards.

Thanks for the reply.
The strange is the the Giga Wifi works perfectly (the sketch runs as expected) but suddenly the display stopped to work.

Do you think os a matter of OS crash ?

Followed the STM32CubeProgrammer instructions and uploaded the boot loader.
Bootloader completed...but the GIGA Display stil not working.
Green artefact.

It was OK until one hour ago.

I am blocked....

I haven't delved into it yet. But it seems like it is still there. I will inform if I find something

Thanks !

I wonder if there is a way to reset the GIGA Display via some sketch...

I thought loading blank sketches to both cores might clear up my situation, but no-joy.

@Dozie 's response got me back in the game.

Tried to upload a blank sketch... NO lucky.
The Display stil has green artefacts and some time a green rectangle covering the full screen.

I am asking to Arduino for the replacement.
Purchased just few days ago.
Has worked for many days and now looks out of order..

I should qualify a previous response made in re this topic. At the time I had assumed there was some buffer that was getting dumped to the display prior to beginning the new sketch. As such, what I observed was to be taken in stride for this particular display.

My apologies if my response may have seemed vague and mis-leading.

EDIT: After uploading sketch, you see something looks out of place, hit RESET on the sketch, see what happens. Please update with your progress.

I can't see any "reset" on sketch.

This morning I have loaded the example for touch screen.
The touch screen is working !
All the examples for display text or graphics generate artifacts.

If I try to only display.begin() and display.fillScreen(BLACK) I get a green filled screen.

If I try to write something dynamically I can see black artefacts running all around the screen.

No way to exit from this problem.

The GIGA WIFI runs perfectly as expected.

Hello @giubio51 could you please provide images of these artifacts so we can take a deeper look?
I think @bambuino recommendation was the RESET (RST) button on the board:
image

By changing the text in my sketch or by changing the background color I can see different artifacts.
Changing the examples also changes the type of artifacts, but I can not understand what is written.

It looks a problem on the "scanning refresh" of the display.
May be "only" a software problem of the GIGA DISPLAY firmware.

May be a firmware reset of the display will solve the problem, but I can not find any documentation on how to do it.

I think the product is not "mature" since no cases are presented by users.

I am wondering if the choice of this display is a good one...

This is the sketch (see the "static void refreshDisplay()") that has worked for many day until yesterday night:

/***************************************************/
/* INCLUDE LIBRARIES                               */
/***************************************************/
#include "Arduino_GigaDisplay_GFX.h"
#include <mbed.h>
#include <digitalWriteFast.h>
#include <Arduino_AdvancedAnalog.h>
#include <Wire.h>
//#include "LedControl.h"
/***************************************************/
/* DEFINE CONSTANT                                 */
/***************************************************/
#define encA            28    // Encoder A
#define encB            29    // Encoder B

#define potA            39    // Encoder pot A
#define potB            41    // Encoder pot B

#define speedSel0       22   // TX used as Output pin
#define speedSel1       24   // RX used as Output pin
#define speedSel2       26   // RX used as Output pin

#define buttonSet       30    // Button Set (red)
#define buttonFun       31   // Button Function (green)
#define buttonHome      32   // Button Home (black)
#define buttonOpt       33   // Button Optional (blue)

#define pwmGatePin      23   // Enable train of PWM pulses
#define pwmInPin        25   // Read PWM and count pulses
#define watchdog        27   // blink forever until system crshes

#define ledAxisPlus     34   // Led axis +
#define ledAxisMinus    35   // Led axis -
#define ledZero         36   // Led zero
#define ledHome         37   // Led home
#define ledGate         38   // Led Gate (run)
#define gateOn          43   // Check if gate is on
#define pwmPin          40   // PWM out

#define din             2   // Max7219 Data In
#define clk             5   // Max7219 Clock    
#define cs              4   // Max7219 Chip Select
#define nDis            2   // Number of MAX7219


#define cyan    0x07FF
#define red     0xf800
#define blue    0x001F
#define green   0x07E0
#define magenta 0xF81F
#define white   0xffff
#define black   0x0000
#define yellow  0xFFE0

/***************************************************/
/* CREATE OBJECTS                                  */
/***************************************************/
GigaDisplay_GFX display;
AdvancedADC adc(A0, A1, A2); // A0 = Pot, A1 = Ground, A2 = 3.3V
PinName pwmOut = digitalPinToPinName(D40);
mbed::PwmOut* pwm = new mbed::PwmOut(pwmOut);
//LedControl lc0=LedControl(din, clk, cs, nDis);
/***************************************************/
/* VARIABLES DECLARATION                           */
/***************************************************/
volatile long encoderPulses = 0;
volatile long pwmInPulses = 0;

volatile int  speedSel;
volatile int  curEncA;
volatile int  oldEncA;
volatile bool encDir;

volatile int  curPotA;
volatile int  oldPotA;

unsigned long wdCnt = 0;
bool toggleWD = false;

float pwmFrequency = 100000; // Hz  = Hertz
float pwmFrequencyTarget = 100000;
float pwmFrequencyRamp = 1.0;

float feedSpeed;
float feedRange = 0;

volatile float potPerc = 0;

float oldPotPerc = 0;
float minPot = 0;
float maxPot = 0;

float kmV = 0;

int oldSpeedSel = -1;


/***************************************************/
/* SETUP                                           */
/***************************************************/
void setup() {
 // Wire.begin();
  Serial.begin(115200);  
  
  
  if (!adc.begin(AN_RESOLUTION_16, 16000, 8, 32)) {
      Serial.println("Failed to start analog acquisition!");
      while (1);
  }

  attachInterrupt(digitalPinToInterrupt(encA), readEncoder, CHANGE);
  pinMode(encA,  INPUT_PULLUP); 
  attachInterrupt(digitalPinToInterrupt(encB), readEncoder, CHANGE);
  pinMode(encB,  INPUT_PULLUP);
  delay(100);

 
  attachInterrupt(digitalPinToInterrupt(potA), readSpeedSelector, CHANGE);
  pinMode(potA,  INPUT_PULLUP); 
  attachInterrupt(digitalPinToInterrupt(potB), readSpeedSelector, CHANGE);
  pinMode(potB,  INPUT_PULLUP);
  delay(100);

  attachInterrupt(digitalPinToInterrupt(pwmInPin), pwmCount, RISING);
  pinMode(pwmInPin,  INPUT_PULLUP);
  delay(100);

  oldEncA = digitalRead(encA);
  oldPotA = digitalRead(potA);

  pinMode(ledAxisPlus, OUTPUT);
  pinMode(ledAxisMinus, OUTPUT);

  pinMode(speedSel0, OUTPUT);
  pinMode(speedSel1, OUTPUT);
  pinMode(speedSel2, OUTPUT);

  pinMode(buttonSet, INPUT);
  pinMode(buttonFun, INPUT);
  pinMode(buttonHome, INPUT);
  pinMode(buttonOpt, INPUT);

  pinMode(pwmGatePin, OUTPUT);
  pinMode(ledGate, OUTPUT);
  pinMode(gateOn, INPUT);
  pinMode(watchdog, OUTPUT);
  
  digitalWrite(speedSel0, 1);
  digitalWrite(speedSel1, 1);
  digitalWrite(speedSel2, 1);
  
  digitalWriteFast(pwmGatePin, LOW);
  digitalWriteFast(ledGate, HIGH);
 
  encoderPulses = 0;
  pwmInPulses = 0;
  wdCnt = 0;
  speedSel = 0;
  feedSpeed = pwmFrequencyTarget * 0.0048828125;
  oldPotA = HIGH;

  display.begin();
  display.setRotation(1);
  display.fillScreen(black);
  generatePwm();
}

/***************************************************/
/* ISR - Interrupt Service Rputine to count pulses */
/***************************************************/
void pwmCount() {
   
    //if (abs(encoderPulses - pwmInPulses) >= 1) {
    if (encoderPulses != pwmInPulses) {
      digitalWriteFast(ledAxisPlus, HIGH);
      digitalWriteFast(ledAxisMinus, HIGH);
      digitalWriteFast(pwmGatePin, HIGH);
      digitalWriteFast(ledGate, LOW);
      
      if ((encoderPulses - pwmInPulses) >= 1) {
        pwmInPulses++;
        digitalWriteFast(ledAxisPlus, LOW);
        digitalWriteFast(ledAxisMinus, HIGH);
      } else if ((encoderPulses - pwmInPulses) <= -1) {
        pwmInPulses--;
        digitalWriteFast(ledAxisPlus, HIGH);
        digitalWriteFast(ledAxisMinus, LOW);
      }
  /*
  if (encoderPulses > pwmInPulses) {
    pwmInPulses++;
  }
  if (encoderPulses < pwmInPulses) {
    pwmInPulses--;
  }
  */
  if ((pwmInPulses == encoderPulses) && digitalReadFast(gateOn)) { 
    digitalWriteFast(pwmGatePin, LOW);
    digitalWriteFast(ledGate, HIGH);
  }
    }
}

/***************************************************/
/* 1 Hz Watchdog                                   */
/***************************************************/
void watchdogRun() {
   if ((millis() - wdCnt) >= 500) {
     toggleWD = !toggleWD;
     if (toggleWD) {
       digitalWrite(watchdog, HIGH);
     } else {
       digitalWrite(watchdog, LOW);
     }
     wdCnt = millis();
   }
}

/***************************************************/
/* Read encoder feed speed range selection         */
/***************************************************/
void readSpeedSelector() {
	curPotA = digitalReadFast(potA);
  if (curPotA != oldPotA  && curPotA == 1){
    if (digitalReadFast(potB) != curPotA) {
      if (speedSel > 0) {
			  speedSel -= 1;
      }
		} else {
      if (speedSel < 7) {
			  speedSel += 1;
      }
		}
	}
  oldPotA = curPotA;
}

/***************************************************/
/* Read encoder feed speed                         */
/***************************************************/
void readEncoder() {
	curEncA = digitalReadFast(encA);
  if (curEncA != oldEncA  && curEncA == 1){
    if (digitalReadFast(encB) != curEncA) {
			encoderPulses += 16;
			encDir = false;
		} else {
			encoderPulses -= 16;
			encDir = true;
		}
	}
  oldEncA = curEncA;
}

/***************************************************/
/* Generate the PWM signal                         */
/***************************************************/
void generatePwm() {
    pwm->period_us(1000000 / pwmFrequency);    // Period = 1000000 microseconds / frequency
    pwm->pulsewidth_us(500000 / pwmFrequency); // Duty cycle 50% 
}

/***************************************************/
/* Select the speed range                          */
/***************************************************/
void setSpeedSelection() {
  if ((speedSel != oldSpeedSel) || (abs(potPerc - oldPotPerc)) > 0.1) {
    pwmFrequencyTarget = 1 + (potPerc * 999.99);
    switch (speedSel) {
    case 0:
      digitalWrite(speedSel0, 1); digitalWrite(speedSel1, 1); digitalWrite(speedSel2, 1);
      feedSpeed = pwmFrequencyTarget * 4.8828125; // = pwmFreqTarget / 4000 rpm * 5000 micron per revolution * 1000 * 0.00125 / 256
      feedRange = 0;
      break;
    case 1:
      digitalWrite(speedSel0, 0); digitalWrite(speedSel1, 1); digitalWrite(speedSel2, 1);
      feedSpeed = pwmFrequencyTarget * 9.765625; // ... / 128
      feedRange = 1;
      break;
    case 2:
      digitalWrite(speedSel0, 1); digitalWrite(speedSel1, 0); digitalWrite(speedSel2, 1);
      feedSpeed = pwmFrequencyTarget * 19.53125; // ... / 64
      feedRange = 2;
      break;
    case 3:
      digitalWrite(speedSel0, 0); digitalWrite(speedSel1, 0); digitalWrite(speedSel2, 1);
      feedSpeed = pwmFrequencyTarget * 39.0625; // ... / 32
      feedRange = 3;
      break;
    case 4:
      digitalWrite(speedSel0, 1); digitalWrite(speedSel1, 1); digitalWrite(speedSel2, 0);
      feedSpeed = pwmFrequencyTarget * 78.125; // ... / 16
      feedRange = 4;
      break;
    case 5:
      digitalWrite(speedSel0, 0); digitalWrite(speedSel1, 1); digitalWrite(speedSel2, 0);
      feedSpeed = pwmFrequencyTarget * 156.25; // ... / 8
      feedRange = 5;
       break;
    case 6:
      digitalWrite(speedSel0, 1); digitalWrite(speedSel1, 0); digitalWrite(speedSel2, 0);
      feedSpeed = pwmFrequencyTarget * 312.5; // ... / 4
      feedRange = 6;
      break;
    case 7:
      digitalWrite(speedSel0, 0); digitalWrite(speedSel1, 0); digitalWrite(speedSel2, 0);
      feedSpeed = pwmFrequencyTarget * 625; // ... / 2
      feedRange = 7;
      break;
    }
    feedSpeed = (long)(feedSpeed * 0.00125);
    feedSpeed = feedSpeed/1000.0;
    pwmFrequency = round(pwmFrequencyTarget);
    oldPotPerc = potPerc;
    oldSpeedSel = speedSel;
  }
  
  if (pwmFrequencyRamp < 1.0) {
    pwmFrequencyRamp += 0.01;
  }
  pwmFrequency = pwmFrequency * pwmFrequencyRamp;
  
}

/***************************************************/
/* Read the digital inputs                      */
/***************************************************/
void readInputs() {
  if (digitalRead(buttonSet) == LOW) {
    pwmFrequencyRamp = 0.2;
    encoderPulses = 100000; // Every 4000 pulses = 5 mm or 5000 microns
  }
  if ((digitalRead(buttonOpt) == LOW) && (digitalRead(buttonHome) == HIGH)) {   // Go to Zero position
      encoderPulses = 0;
  }
  if ((digitalRead(buttonOpt) == LOW) && (digitalRead(buttonHome) == LOW)) {   // Set this position as Zero
      encoderPulses = 0;
      pwmInPulses = 0;
      pwmFrequencyRamp = 0.2;
  }
}

/***************************************************/
/* Read the speed potentiometer                    */
/***************************************************/
void readPot() {
     if (adc.available()) {
        SampleBuffer buf = adc.read();
        potPerc = (buf[0] * 0.00152587890625); // 100 / 65536 Pot
        minPot =  (buf[1] * 0.00152587890625); // 100 / 65536 Ground
        maxPot =  (buf[2] * 0.00152587890625); // 100 / 65536 3.3
        buf.release();
     }
     kmV = 100 / (maxPot - minPot);
     potPerc = (potPerc * kmV) - minPot;
     if (potPerc < 0) {
       potPerc = 0;
     } else if (potPerc > 100) {
      potPerc = 100;
     }  
}

/***************************************************/
/* Write constant text on display                  */
/***************************************************/
void writeLabel(char *buf, uint8_t s, int16_t x,  int16_t y, int16_t color, int16_t bckg) {
  display.setCursor(x, y);
  display.setTextSize(s);
  display.setTextColor(color, bckg);
  display.println(buf); 
}

/***************************************************/
/* Write variable text on display                  */
/***************************************************/
void writeValue(float val, char *dec, uint8_t s, int16_t x,  int16_t y, int16_t color, int16_t bckg) {
  char buf[15];
  snprintf (buf, sizeof(buf), dec, val);
  writeLabel(buf, s, x, y, color, bckg);
}

/***************************************************/
/* Refresh values on display                 */
/***************************************************/

static void refreshDisplay() {
  
    writeLabel("Axis X: ", 6, 50, 30, green, black);
    writeValue((encoderPulses*0.00125), "%.3f   ", 6, 400,  30, green, black);
    
    writeLabel("mm/s X: ", 6, 50, 110, green, black);
    writeValue((feedSpeed), "%.3f   ", 6, 400,  110, green, black);
    
    writeLabel("Pos. X: ", 6, 50, 190, green, black);
    writeValue((pwmInPulses*0.00125), "%.3f   ", 6, 400,  190, green, black);
   
    writeLabel("Freq X: ", 6, 50, 270, green, black);
    writeValue(pwmFrequency, "%.0f   ", 6, 400,  270, green, black);
   
    writeLabel("Range : ", 6, 50, 350, green, black);
    writeValue(feedRange, "%.0f   ", 6, 400,  350, green, black);
    
}

/***************************************************/
/* MAIN LOOP                                       */
/***************************************************/
 void loop() {
   readInputs();
   watchdogRun();
   refreshDisplay();
   readPot();
   setSpeedSelection();
   generatePwm();  
 }

The GIGA DISPLAY should display five lines like these:

Axis X: 1234.567
mm/s X: 1.234
Pos. X: 987.654
Freq X: 100000
Range: 5

before the ":" are fixed text, after ":" dynamic text.
It was running perfectly until yesterday night

The SW is under development, not yet finished...some comment may be not correct..sorry for that

Contacted the Arduino official store support for the replacement of the display,

Unfortunately they suggest only tens of basic tests that I have made by my self prior to expose the case.

No real help from the support.
This is not acceptable.

I think I will eliminate this weak display from my project.

My project is completely blocked.
Asked for replacement, but after many days, still waiting from Arduino Support.

Just blocked in an idle loop...

Hi, we have already approved for replacement and requested the return of the board which you have already confirmed to us in the ticket. Further details regarding the replacement will be shared through the ticket.

OK, true, but the timing is unacceptable.

Hi, has Arduino made any progress with this issue. Someone else in the thread offered that since the display unit itself is still relatively nascent, some of these issues may not have had the opportunity to work themselves out just yet.

That creates a challenge for the end user - am I to sit here with a display that should meet my very basic needs, but doesn't, so it collects dust again?

FWIW, I am seeing the same pixelation, which I can occasionally clear, but not reliably. The "Hello World" example cleared it out more recently, but then that text persisted in follow-up sketches.

In this last instance, the code attempted one task only - to fill the screen yellow. The result - random pixelation/artifacts. (I suppose this is a buffer or memory issue?)

What can I do with this display? Are you still taking exchanges? I do not want to be stuck with a boat anchor!