Search code examples
arduinospiadc

Arduino Mega to ADC SPI communication is not working


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.


Solution

  • 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.