using 2 spi devices together - tft display + shift registers

Hello,
I am pretty new to all of the SPI communication stuff and I am having a trouble.
That is my first time trying to use 2 different spi devices at once, which are the 1.44inch tft display with adafruit_gfx and TFT_ili9163c, and also 595 shift register with shiftPWM library.
I connected togrther the SCK and SDA/MOSI to the arduino pins. then, I connected the A0 of the display, CS of the display, and latch of the shift register to their own 3 pins. when I tried running each code on his own it worked, but together, the spi has a problem. also, when running the code for the display few outputs of the shift registers light up randomly. Is there a solution fot my problem?

Thank you for ANY help,
Arad.

Hi,
Can you please post your codes and a copy of your circuit, in CAD or a picture of a hand drawn circuit in jpg, png?

Thanks.. Tom.. :slight_smile:

TomGeorge:
Can you please post your codes and a copy of your circuit, in CAD or a picture of a hand drawn circuit in jpg, png?

Hi Tom,
Here is my code (Ignore the shiftIn stuff):

int inLatchPin = 3;
int inDataPin = 4;
int inClockPin = 2;

int colorData[8][3] = {
  {0, 0, 255},
  {0, 255, 0},
  {255, 0, 0},
  {255, 0, 255},
  {255, 255, 0},
  {0, 255, 255},
  {155, 155, 155},
  {255, 255, 255}
};

byte switchVar1 = 72;

//ShiftPWM Library Stuff
const int ShiftPWM_latchPin = 5;
//#define SHIFTPWM_NOSPI
//const int ShiftPWM_dataPin = 8;
//const int ShiftPWM_clockPin = 13;
const bool ShiftPWM_invertOutputs = true;
const bool ShiftPWM_balanceLoad = false;
#include <ShiftPWM.h>
unsigned char maxBrightness = 255;
unsigned char pwmFrequency = 75;
int numRegisters = 3;
int numRGBleds = numRegisters*8/3;

//Main Display Stuff
#include <SPI.h>
#include <Adafruit_GFX.h>
#include <TFT_ILI9163C.h>
#define white 0xFFFF
#define displayCS 8
#define displayDC 10
TFT_ILI9163C mainDisplay = TFT_ILI9163C(displayCS, 9, displayDC);

void setup() {
  Serial.begin(9600);
  
  ShiftPWM.SetAmountOfRegisters(numRegisters);
  ShiftPWM.SetPinGrouping(1);
  ShiftPWM.Start(pwmFrequency,maxBrightness);

  pinMode(inLatchPin, OUTPUT);
  pinMode(inClockPin, OUTPUT); 
  pinMode(inDataPin, INPUT);

  mainDisplay.begin();
  mainDisplay.fillScreen();
}

void loop() {
  //shift in
  
  digitalWrite(inLatchPin, HIGH);
  digitalWrite(inLatchPin, LOW);

  switchVar1 = shiftIn(inDataPin, inClockPin);
  Serial.println(switchVar1, BIN);
  Serial.println("-------------------");
  
  //LED control
  for(int i = 0; i < numRGBleds; i++){
    ShiftPWM.SetRGB(i, colorData[i][0], colorData[i][1], colorData[i][2]);
  }

  //Display Drawing
  testText();
  delay(500);
}

byte shiftIn(int myDataPin, int myClockPin) { 
  int i;
  int temp = 0;
  int pinState;
  byte myDataIn = 0;

  pinMode(myClockPin, OUTPUT);
  pinMode(myDataPin, INPUT);

  for (i=7; i>=0; i--) {
    digitalWrite(myClockPin, 0);
    temp = digitalRead(myDataPin);
    if (temp) {
      pinState = 1;
      myDataIn = myDataIn | (1 << i);
    }
    else {
      pinState = 0;
    }

    digitalWrite(myClockPin, 1);

  }
  return myDataIn;
}

unsigned long testText() {
  mainDisplay.setCursor(29, 63);
  mainDisplay.setTextColor(white);  
  mainDisplay.setTextSize(1);
  mainDisplay.println("Hello World!");
}

I also attached the schematic of my circuit as a png file, but if you need for some reason, I have it on my easyEDA account too.

Hi,
Thanks for the schematic;
e99272c3b74f3e79d4ed5be9b58c92fa075a0db2.png

How are you powering all this, have you measured the 5V and checked that it is not being overloaded.
If you are using the 5V from the UNO it does have limited current capability, even when the UNO is being powered by 5V USB.

Thanks… Tom… :slight_smile:

TomGeorge:
If you are using the 5V from the UNO it does have limited current capability, even when the UNO is being powered by 5V USB.

Hello,
I don't think the current is a problem, because all the leds light up, and the smae happens with the display. it just don't light up in the right colors. also the display really says "Hello world!" but with a lot of noise pixels all over the screen.

Your schematic has no decoupling capacitors on those shift register chips.
Each chip needs a 0.1uF ceramic capacitor between power and ground. The capacitors need to be fitted as close to the chip as possible and with as short a lead length as possible.

Grumpy_Mike:
Your schematic has no decoupling capacitors on those shift register chips.
Each chip needs a 0.1uF ceramic capacitor between power and ground. The capacitors need to be fitted as close to the chip as possible and with as short a lead length as possible.

That won't help for my problem, I know that a capacitor will help, but it's not THAT neccesary.

I know that a capacitor will help, but it’s not THAT neccesary.

Yes they are that necessary, thy are compulsory.

That won’t help for my problem,

How on Earth do you come to that conclusion? Stop being so arrogant, you asked a question so take the advice or go away.

Grumpy_Mike:
Yes they are that necessary, thy are compulsory.

How on Earth do you come to that conclusion? Stop being so arrogant, you asked a question so take the advice or go away.

Hello Mike,
I am just saying that I know from past personal usage with these shift registers and online recources I know that capacitors are helpful on flickering on the latch pin, and may damage the IC. It is not required to run the circuit properly at all. I am not arrogant so please don't be offensive. I am saying what I know about the arcticle and you say how you would behave in that situation instead of me. that is how forums works, and I accept your post about the capacitor but do not agree with it. as far as I know my problem is with the data transmitted from the arduino to the SPI data lines on the devices.

I know that capacitors are helpful on flickering on the latch pin,

Really?

and may damage the IC.

Really?

Please show us where you found that information.

groundFungus:
Really?

The official Arduino page about shifting out with the sn74hc595 shift register.

groundFungus:
Really?

Arduino forum.

0.1uF on the latch pin is incorrect. 0.1uF on the chip's power pin is always beneficial.

MorganS:
0.1uF on the latch pin is incorrect. 0.1uF on the chip's power pin is always beneficial.

Yes maybe I will try it in the future, but my issue is with SPI communication because as i already said- my devices are getting good power, but incorrect data.

Hi,
I am no SPI expert, but the protocol has 4 different modes, which are speed and logic polarity different.
As you are using a library to communicate with the TFT, it may switch the SPI to a different possibly faster mode than the expansion ICs.
This may be causing lockups especially if logic polarity is changed.

https://www.arduino.cc/en/Reference/SPISetDataMode

The TFT may use a higher speed due to the amount of data need to be transfered.

Tom... :slight_smile:

TomGeorge:
The TFT may use a higher speed due to the amount of data need to be transfered.

Thank you Tom! It makes sense now because each part of the code works great on his own, but together... neh..

I found SPI_MODE0 in the tft library file, and in the shiftPWM file - nothing.
But when I read the arduino page in the link you sent, I found out it should not be used anymore, and I should use .beginTransaction or something like that... and this line shows up a lot in the tft library file, but again nothing in the shiftPWM. then I discovered that when calling the tft.begin() function the settings are being set to a number that depends on few variables, something that is called MSBFIRST, and SPI_MODE0 as used before like that:

ILI9163C_SPI = SPISettings(num, MSBFIRST, SPI_MODE0);

Although you are not an SPI expert :stuck_out_tongue: looks like you have some knowledge about it, so is there a default SPI mode that is used in the shiftPWM library as a... default (obviously)?

EDIT: I don't even know if it is a problem with the SPI, bacause I tried using the noSPI mode of shiftPWM and it still didn't work. The problem occurs when calling the shift.Start(); and I don't know why it makes problems because it has an if statement for the usage of SPI communication.

after a lot of tries I didn't managed to make it work... let me ask a bit more general question: Did anyone ever use the shiftPWM library with a second SPI device?

Thank you for helping,
Arad.

Example of where adding capacitors solved the problem
http://arduino.cc/forum/index.php/topic,86873.0.html
http://arduino.cc/forum/index.php/topic,88243.0.html
http://arduino.cc/forum/index.php/topic,85247.0.html
http://arduino.cc/forum/index.php/topic,98088.0.html
http://arduino.cc/forum/index.php/topic,94913.15.html

One where using ceramic ones instead of mylar ones made a difference

Grumpy_Mike:
Example of where adding capacitors solved the problem
http://arduino.cc/forum/index.php/topic,86873.0.html
http://arduino.cc/forum/index.php/topic,88243.0.html
http://arduino.cc/forum/index.php/topic,85247.0.html
http://arduino.cc/forum/index.php/topic,98088.0.html
http://arduino.cc/forum/index.php/topic,94913.15.html
http://forum.arduino.cc/index.php?topic=380974.msg2626901;topicseen#new
One where using ceramic ones instead of mylar ones made a difference
http://forum.arduino.cc/index.php?topic=343563.10

Hi Mike,
Thank you very much for your help, but again the shift registers are working and I don't need to change nothing. the problem happens in the communication with the LCD display because the shiftPWM library interrupts the signal somehow. non of the links you sent contains relevant information about the 595 shift registers, the shiftPWM library, and the ili9163c tft display (and by the way all of my project is kind of these three things). I am not using any led driver of any kind and I don't consider using it in the future because I have no problem with the leds nor the shift registers. I have just a software issue / hardware issue with the display only.

Sorry, you did say shiftPWM.h in your first post and I just skimmed past that because I’m not familiar with it.

shiftPWM uses timer interrupts to send out new data to the shift register hundreds of times per second. You can’t do this while you’re in the middle of an SPI transaction with the SD card.

While there is a start() method for shiftPWM, there’s no stop(). Once it’s been given control over those output pins, it will be using those pins continuously, with no way to pause it while accessing the SD card. Yes, you probably could just grab the data from the SD card and then start shiftPWM afterwards, but that’s really not a great solution.

I would use the SHIFTPWM_NOSPI option and put the PWM onto different pins that won’t interfere with the SD card.

MorganS:
Sorry, you did say shiftPWM.h in your first post and I just skimmed past that because I'm not familiar with it.

shiftPWM uses timer interrupts to send out new data to the shift register hundreds of times per second. You can't do this while you're in the middle of an SPI transaction with the SD card.

While there is a start() method for shiftPWM, there's no stop(). Once it's been given control over those output pins, it will be using those pins continuously, with no way to pause it while accessing the SD card. Yes, you probably could just grab the data from the SD card and then start shiftPWM afterwards, but that's really not a great solution.

I would use the SHIFTPWM_NOSPI option and put the PWM onto different pins that won't interfere with the SD card.

Hello morgan!

looks like you misunderstood me hehe,
I am not using an sd card module, but a tft display module (1.44 inch 128x128). but it doesn't really matter because you really helped me! I think the solution might be writing the data to the display just in time when the shiftPWM code finish running, which will result in unfixed fps but I don't really care about it because I am not planning to play complex animations on the display, just some menus. also the leds won't be changed most of the time so I think it will be helpful to write an if statement that updates the leds only when their state is changed in the code. the problem is that I have no idea how to implement all of this in the code and altough I know how SPI works in concept I am not sure how to write code for this, and especially with all of that timing interrupts... I will be happy to get some help from you because it sounds like you are into the topic.

Thanks alot,
Arad. :slight_smile:

EDIT:
If you want to try it yourself you have the schematic that I posted before, and the library can be found here:

but you don't need to build the circuit, I have it ready, just tell me what do you think is important to add to the code to solve this problem.