Spectrum Analyser and TFT drawing issues

Hi all,
I'm build a Spectrum analyser based on the UNO chip and Sparkfun Spectrum shield, the prototype is working fine with a small OLED I2C display, but I I want to use on my final board one of this 1.8" 128x160 SPI TFT display based on ST7735 chipset. I have tested with both the Arduino TFT libs and with Adafruit, the latter seems to work better in this case. I draw bars to visualise the 14 levels (7 Left + 7 right.) My problem is that the redraw of the bars is very sketchy, I'm positive is not resource issues on ATMEGA, is plenty and it works fine with my OLED version. Do you think I'm expecting too much from this display, in the ST7735 Datasheet I don't see major issues.

Thanks,
Ermanno

I attached the code here:

/******************************************************************************
  SparkFun Spectrum Shield Demo
  Bands: 63Hz / 160Hz / 400Hz / 1kHz / 2.5kHz / 6.25kHz / 16kHZ
*********************************************************************************/

// Libraries required 
//#include <Arduino.h>
#include <Adafruit_GFX.h>    // Core graphics library
#include <Adafruit_ST7735.h> // Hardware-specific library for ST7735
#include <SPI.h>

// TFT 1.8" Display 128x160 pins and type
#define TFT_CS        10
#define TFT_RST        9 // Or set to -1 and connect to Arduino RESET pin
#define TFT_DC         8
// PIN 11 (MOSI) and 13(SCK) are used for SPI

Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS, TFT_DC, TFT_RST);

//Declare Spectrum Shield pin connections
#define STROBE 4
#define RESET 5
#define DC_One A0 // Left Channel
#define DC_Two A1 // Right Channel

//Define variables
int freq_amp, i, left, right;
int Frequencies_One[7];
int Frequencies_Two[7];

#define ARRAYSIZE 8
int left_pos[ARRAYSIZE] = { 121 , 113 , 105 , 97 , 89 , 81 , 73 };  // portrait
int right_pos[ARRAYSIZE] = { 48 , 40 , 32 , 24 , 16 , 8 , 0};  // portrait

void setup() {
  
  // TFT initializer for 1.8" TFT screen:
  tft.initR(INITR_BLACKTAB);      // Init ST7735S chip
  
  //Set spectrum Shield pin configurations
  pinMode(STROBE, OUTPUT);
  pinMode(RESET, OUTPUT);
  pinMode(DC_One, INPUT);
  pinMode(DC_Two, INPUT);

  //Initialize Spectrum Analyzers
  digitalWrite(STROBE, LOW);
  digitalWrite(RESET, LOW);
  delay(5);

  //Serial.begin(115200);
  //delay(1000);
  tft.fillScreen(ST77XX_BLACK);
}

void loop() {

  digitalWrite(RESET, HIGH);
  delayMicroseconds(200);
  digitalWrite(RESET, LOW);
  delayMicroseconds(200);

  //Read frequencies for each band
  for (freq_amp = 0; freq_amp < 7; freq_amp++)
  {
    digitalWrite(STROBE, HIGH);
    delayMicroseconds(50);
    digitalWrite(STROBE, LOW);
    delayMicroseconds(50);
  
    Frequencies_Two[freq_amp] = analogRead(DC_Two);  //Right Channel
        right = map(Frequencies_One[freq_amp], 60, 1023, 0, 159);
    Frequencies_One[freq_amp] = analogRead(DC_One);  //Left Channel
        left = map(Frequencies_One[freq_amp], 60, 1023, 0, 159);
         
        tft.fillRect(right_pos[freq_amp], 0, 7, right, ST77XX_GREEN);
        tft.fillRect(left_pos[freq_amp], 0, 7, left, ST77XX_GREEN);              
  }
  delayMicroseconds(400);
  tft.fillScreen(ST77XX_BLACK);  
}

What does that mean?

This looks like a mistake. You are reading Frequencies_Two[freq_amp] but then mapping Frequencies_One[freq_amp]. That means the 'right' value is actually the 'left' value from the previous cycle.

Do you really need to update the screen 2000 times a second? I would think a delay of 10 milliseconds would make more sense than a delay of 400 microseconds.

I would also move the blanking of the display to just before the redrawing (just after the RESET).

Thanks John for spotting the mistake, that what happens when you mess around with the code too much... (at late hours), my original I2C code was correct.

Well, my goal is for the drawing to follow with fidelity the sound so it should, be able to run as fast as possible.
In practice the delay seems to be irrelevant, it's still sketchy (in slo-mo) even with 100ms.

I attached a small clip to show you what I experience
IMG_2010.mov.zip (3.3 MB)
. I have tried your suggestions, no changes.

I will post a bit later the I2C OLED display version that works a charm, just the display size is too tiny for my purpose. Maybe I just need to look for a better display.

John, this works like a charm, and there's no jumping at all. (what you might see in this second video is actually the phone camera, live is perfect)

/******************************************************************************
  SparkFun Spectrum Shield Demo
  Bands: 63Hz / 160Hz / 400Hz / 1kHz / 2.5kHz / 6.25kHz / 16kHZ

*********************************************************************************/

// OLED I2C Display 128x64
#include <U8g2lib.h>
#include <Wire.h>

// Declare display type
U8G2_SSD1306_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE);

//Declare Spectrum Shield pin connections
#define STROBE 4
#define RESET 5
#define DC_One A0 // Left Channel
#define DC_Two A1 // Right Channel

//Define spectrum variables
int freq_amp, i, left, right, pos_r, pos_l;
int Frequencies_One[7];
int Frequencies_Two[7];

#define ARRAYSIZE 8
int right_pos[ARRAYSIZE] = { 48 , 40 , 32 , 24 , 16 , 8 , 0 };
int left_pos[ARRAYSIZE] = { 119 , 111 , 103 , 95 , 87 , 79 , 71 };

void setup() {
  
  // UG82 lib init call  
  u8g2.begin();
  
  //Set spectrum Shield pin configurations
  pinMode(STROBE, OUTPUT);
  pinMode(RESET, OUTPUT);
  pinMode(DC_One, INPUT);
  pinMode(DC_Two, INPUT);

  //Initialize Spectrum Analyzers
  digitalWrite(STROBE, LOW);
  digitalWrite(RESET, LOW);
  delay(5);

  //Serial.begin(115200);
}


void loop() {
  Read_Frequencies();
  Graph_Frequencies();
}


/*******************Pull frquencies from Spectrum Shield********************/
void Read_Frequencies() {
  digitalWrite(RESET, HIGH);
  delayMicroseconds(200);
  digitalWrite(RESET, LOW);
  delayMicroseconds(200);

  //Read frequencies for each band
  for (freq_amp = 0; freq_amp < 7; freq_amp++)
  {
    digitalWrite(STROBE, HIGH);
    delayMicroseconds(50);
    digitalWrite(STROBE, LOW);
    delayMicroseconds(50);

    Frequencies_One[freq_amp] = analogRead(DC_One);  //Left Channel
    Frequencies_Two[freq_amp] = analogRead(DC_Two);  //Right Channel
  }
}

/*****************Print Out Band Values for Serial Plotter*****************/
void Graph_Frequencies() {
   u8g2.clearBuffer();          // clear the internal memory
   u8g2.setFont(u8g2_font_6x10_tf);
   u8g2.setDrawColor(1);
    
  for (i = 0; i < 7; i++)
  {
    left = map(Frequencies_One[i], 60, 1023, 0, 62);
    pos_l = left_pos[i];
        u8g2.drawBox(pos_l,0,7,left);

    right = map(Frequencies_Two[i], 60, 1023, 0, 62);
    pos_r = right_pos[i];
        u8g2.drawBox(pos_r,0,7,right);      
  }
  u8g2.sendBuffer(); 
}

IMG_2013.mov.zip (2.5 MB)

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.