I'm using SPI communication to try to connect my Arduino Mega 2560 as the master with an ADC chip as the slave (Max 1247
) in external clock mode, but I keep receiving the same values (RB1 = 255, RB2 = 255, RB3 = 255)
or all zeros whenever I run my code. There is also a touch screen (which works) connected. Everything works except the ADC chip communication with the Arduino.
I have tried deleting the define header, and varying the clock. Neither change anything (which might be because of other errors).
//Portion of Header
//Defining SPI connections
#define SELPIN 53 //Selection Pin
#define DATAOUT 50 //MIS0
#define DATAIN 51 //MOSI
#define SPICLOCK 52//Clock
#define SSTRB 43 //SSTRB
#include <Adafruit_GFX.h>
#include "MCUFRIEND_kbv.h"
MCUFRIEND_kbv tft(A3, A2, A1, A0, A4);
int sstrb = 0;
byte TB1 = B11101111;
byte RB1;
byte RB2;
byte RB3;
byte RB4;
//SETUP
void setup(){
pinMode(SELPIN, OUTPUT);
pinMode(sstrb, INPUT);
pinMode(DATAOUT, INPUT);
pinMode(DATAIN, OUTPUT);
pinMode(SPICLOCK, OUTPUT);
//disable device to start.
digitalWrite(SELPIN, HIGH);
digitalWrite(SPICLOCK, LOW);
digitalWrite(DATAIN, LOW);
}
void loop(){
//Some other touch screen stuff prefaces this..
else if (currentPage == '3') {
if (tp.z > myTouch.pressureThreshhold) {
x = tp.x;
y = tp.y;
//Back button command
if ((x >= 20) && (x <= 900) && (y >= 0) && (y <= 320)) {
homescreen();
currentPage = '0';
}
else if ((x >= 700) && (x <= 800) && (y >= 350) && (y <= 875)) {
//loop
SPI.beginTransaction(SPISettings(1000000, MSBFIRST, SPI_MODE0));
digitalWrite(SELPIN, LOW);
//The line beneath might take care of transmitting dataout, and receiving datain (vs currently doing seperately)?.
RB1 = SPI.transfer(TB1);
Serial.print("\r\nRB1="); Serial.print(RB1);
digitalRead(sstrb);
if (sstrb == 0){
RB2 = SPI.transfer(0x0);
Serial.print("\r\nRB2="); Serial.print(RB2);
RB3 = SPI.transfer(0x0);
Serial.print("\r\nRB3="); Serial.print(RB3);
digitalWrite(SELPIN, HIGH);
digitalWrite(SELPIN, LOW);
SPI.endTransaction();
tft.fillRoundRect(40, 20, 300, 70, 15, RED);
tft.setCursor(150, 45);
tft.setTextColor(WHITE);
tft.setTextSize(3);
tft.print("3A");
tp = myTouch.getPoint();
pinMode(YP, OUTPUT);
pinMode(XM, OUTPUT);
digitalWrite(YP, HIGH);
digitalWrite(XM, HIGH);
}
else{
Serial.print("SSTRB is high");
}
}
}
}
}
Errors include RB1 = 255; RB2 = 255; RB3 = 255 or all zeroes.
I can't definitely say if this is the root of your problem, but I found the following:
You defined SSTRB to be pin 43
#define SSTRB 43 //SSTRB
but you are actually never using this value. Instead you also defined
int sstrb = 0;
a few lines below, which you are then using to define pin 0 as input
pinMode(sstrb, INPUT);
I assume this should rather be
pinMode(SSTRB, INPUT);
Then, there are these lines in your loop
digitalRead(sstrb);
if (sstrb == 0){
where digitalRead actually does nothing (reads from pin 0 and discards the value), I assume you wanted to write
sstrb = digitalRead(SSTRB);
otherwise, sstrb
never actually changes and is always 0.
Also, since the datasheet (https://datasheets.maximintegrated.com/en/ds/MAX1246-MAX1247.pdf#page=13) states that
In external clock mode, [...]. SSTRB pulses high for one clock period after the last bit of the control byte.
and you are using external clock mode, I assume you rather want to wait for this pulse to finish before you continue. You could do a busy wait like this:
bool wasHigh = false;
do {
sstrb = digitalRead(SSTRB);
if( sstrb == 1 ){
wasHigh = true;
}
}while( !(wasHigh && sstrb == 0) );
Please note that if the pulse occurs before this wait or if it never occurs, you will stay in this loop endlessly. You may wan't to add a break condition or timeout here. You could of course also use an interrupt instead to solve this problem.
Additional note: You are calling endTransaction
in the branch where you check if sstrb
is 0 only. I don't know how the SPI library handles beginning a transaction again without ending the old one first, it's probably working fine, I just wanted to let you know that this may be a potential pitfall.