1

I have run into this issue where my code will upload to my Due but fails to execute. I have verified the code works on a SparkFun Redboard. The only code difference is that the SPI pin assignments have been appropriately changed. My code, for initial testing purposes, can run without any sort of attachments or additional boards. I do use or rather will be using SPI communication when I do wire up all of the instruments. The code currently handles not having anything connected just fine. The expected output as provided by running on the Redboard is below.

screen shot of desired serial monitor as produced by a redboard

Initially I thought that my code was running on the Due and failing to communicate serially, but when I tried to implement a simple blink routine near the beginning of the loop and even some things during setup, it became clear that the code was failing to make it through the "setup" function. I couldn't even get a serial print from the second line of the setup function. It is very clear that the code fully uploads based on both the IDE and the Rx/Tx LEDs on the board. I am using the correct port, and I am using the correct board selection and USB port on the board (the programming port nearest to the barrel plug jack).

I came across a number of posts and they either didn't address my issue or they didn't actually come to a conclusion. I did find some very simple test code post in a different topic (below). This code does run. I have also successfully run the "Blink" example code on the Due.

byte count = 0;

void setup() {
  Serial.begin(115200);
}

void loop() {
  Serial.print ("Count = ");
  Serial.println (count);
  count++;
  delay(500);
}

It was brought to my attention that there may be some libraries that don't play well with the Due, but even when I removed all immediately unnecessary libraries, I was unable to get the code to run on the Due.

The actual code for the project is shown below. There is some commented-out code that I tried to use for debugging. Also, I have split up the code into separate CPP and header files as that was what I was taught to do in college.

Does anyone know what is going on here? Does anyone know of a fix or workaround?

The code is provided in the follow order:

fluidized_bed_test.ino Blower.cpp Blower.h Heater.cpp Heater.h Thermocouple.cpp Thermocouple.h control.cpp control.h fluidized_bed_test.h

fluidized_bed_test.ino

#pragma once
#include "Thermocouple.h"
#include "Heater.h"
#include "Blower.h"
#include "fluidized_bed_test.h"

#define MAX_MESSAGE_LEN 50

Thermocouple therm1(MOSIPin,MISOPin,CLKPin,CHIPSEL1,DRDYPIN1);
Thermocouple therm2(MOSIPin,MISOPin,CLKPin,CHIPSEL2,DRDYPIN2);
Thermocouple therm3(MOSIPin,MISOPin,CLKPin,CHIPSEL3,DRDYPIN3);
Heater heater(HEATERPIN);
Blower blower(BLOWERPIN);

void setup() 
{
  Serial.begin(115200);
//  while (!Serial){}
  Serial.print("Shall we begin");
  SPI.begin();
  pinMode( MISOPin, INPUT );
  pinMode( MOSIPin, OUTPUT );
  pinMode( DRDYPIN1, INPUT );
  pinMode( CHIPSEL1, OUTPUT ); // Thermocouple 1
  pinMode( DRDYPIN2, INPUT );
  pinMode( CHIPSEL2, OUTPUT ); // Thermocouple 2
  pinMode( DRDYPIN3, INPUT );
  pinMode( CHIPSEL3, OUTPUT ); // Thermocouple 3
  pinMode( HEATERPIN, OUTPUT); // Heater
//  pinMode(LED_BUILTIN, OUTPUT);
//  pinMode(13, OUTPUT);
  
  therm1.setFaultMask();
  therm1.setBaseConfig();
  therm1.setColdOffset();
  therm1.setTemperatureFault();

  therm2.setFaultMask();
  therm2.setBaseConfig();
  therm2.setColdOffset();
  therm2.setTemperatureFault();

  therm3.setFaultMask();
  therm3.setBaseConfig();
  therm3.setColdOffset();
  therm3.setTemperatureFault();

  heater.setControl(0);
  blower.setControl(1);
  blower.setBlower(1);
  blower.setPID(255);
//  digitalWrite(LED_BUILTIN, LOW); //added to see if executing at all 
//  delay(5000);
//  digitalWrite(LED_BUILTIN, HIGH); //added to see if executing at all
//  delay(5000);
  delay(200);
}

void loop() 
{
  static float temperature1 = 0;
  static float temperature2 = 0;
  static float temperature3 = 0;
  static int blower_pid = 255;
  static int new_blower_pid = -1;
  static int remaining_char = 0;
  static int i = 0;
  static char inByte = 0;
  static char incoming_message[MAX_MESSAGE_LEN];
  temperature1 = therm1.getTemp();
  temperature2 = therm2.getTemp();
  temperature3 = therm3.getTemp();

  digitalWrite(LED_BUILTIN, LOW); //added to see if executing at all 
//  delay(5000);               

//  static int j = 0;
//  while(j < 10)
//  {
//  digitalWrite(LED_BUILTIN, LOW); //added to see if executing at all 
//  delay(500);
//  digitalWrite(LED_BUILTIN, HIGH); //added to see if executing at all
//  delay(500);
//  j++;
//    }

 // Retrieve Thermocouple 1 temps
  Serial.println("Thermocouple 1 Temperature");
  Serial.println(temperature1);
  Serial.println("Cold Junction 1 Temperature");
  Serial.println(therm1.getColdTemp());

 // Retrieve Thermocouple 2 temps
  Serial.println("Thermocouple 2 Temperature");
  Serial.println(temperature2);
  Serial.println("Cold Junction 2 Temperature");
  Serial.println(therm2.getColdTemp());

// Retrieve Thermocouple 3 temps
  Serial.println("Thermocouple 3 Temperature");
  Serial.println(temperature3);
  Serial.println("Cold Junction 3 Temperature");
  Serial.println(therm3.getColdTemp());

  i = 0;
  
  while ( Serial.available() )
  {
    inByte = Serial.read();

    if ( inByte != '\n' && (i < MAX_MESSAGE_LEN - 1) )
    {
      incoming_message[i] = inByte;
      i++;
    }
    else
    {
      incoming_message[i] = '\0';
    }
  }  
  new_blower_pid = atoi(incoming_message);
  digitalWrite(LED_BUILTIN, HIGH); //added to see if execturing at all
  delay(1000);
}

Blower.cpp

#pragma once
#include "Blower.h"

Blower::Blower(int pin)
{
  pinNum = pin;
  blowerState = 0;
  pidState = 0;
  pidValue = 255;
}

void Blower::setBlower( boolean state )
{
  blowerState = state;  
  updateBlower();
}

void Blower::setControl(boolean state )
{
  pidState = state;
  updateBlower();
}

void Blower::setPID( int pid )
{
  pidValue = pid;
  updateBlower();
}

boolean Blower::isOn()
{
  return blowerState;
}

boolean Blower::getControl()
{
  return pidState;
}

int Blower::getPIDValue()
{
  return pidValue;
}

void Blower::updateBlower()
{
  if(blowerState)
  {
    if(pidState)
    {
      analogWrite(pinNum,pidValue);
    }
    else
    {
      analogWrite(pinNum,255);
    }
  }
  else
  {
    analogWrite(pinNum,255);
  }
}

Blower.h

#pragma once
#if ARDUINO >= 100
  #include "Arduino.h"
#else
  #include "WProgram.h"
#endif

class Blower
{
  public:
    Blower( int pin);
    void setBlower(boolean = false);
    void setControl(boolean = false);
    void setPID(int pid = 255);
    boolean isOn();
    boolean getPidState();
    boolean getControl();
    int getPIDValue();
    

  private:
    void updateBlower();

    
    boolean blowerState;
    boolean pidState;
    int pidValue;
    int pinNum; 
};

Heater.cpp

#pragma once
#include "Heater.h"

Heater::Heater(int pin)
{
  pinNum = pin;
  heaterState = 0;
  pidState = 0;
  pidValue = 255;
}

void Heater::setHeater( boolean state )
{
  heaterState = state;  
  updateHeater();
}

void Heater::setControl(boolean state )
{
  pidState = state;
  updateHeater();
}

void Heater::setPID( int pid )
{
  pidValue = pid;
  updateHeater();
}

boolean Heater::isOn()
{
  return heaterState;
}

boolean Heater::getControl()
{
  return pidState;
}

int Heater::getPIDValue()
{
  return pidValue;
}

void Heater::updateHeater()
{
  if(heaterState)
  {
    if(pidState)
    {
      analogWrite(pinNum,pidValue);
    }
    else
    {
      analogWrite(pinNum,255);
    }
  }
  else
  {
    analogWrite(pinNum,255);
  }
}

Heater.h

#pragma once
#if ARDUINO >= 100
  #include "Arduino.h"
#else
  #include "WProgram.h"
#endif

class Heater
{
  public:
    Heater( int pin);
    void setHeater(boolean = false);
    void setControl(boolean = false);
    void setPID(int pid = 255);
    boolean isOn();
    boolean getPidState();
    boolean getControl();
    int getPIDValue();
    

  private:
    void updateHeater();

    
    boolean heaterState;
    boolean pidState;
    int pidValue;
    int pinNum; 
};

Thermocouple.cpp

#pragma once
#include "Thermocouple.h"

Thermocouple::Thermocouple(int mosiPin,int misoPin,int clkPin, int chslctPin, int drdy)
{
  SPI.begin();
  MOSI = mosiPin;
  MISO = misoPin;
  CLK = clkPin;
  CHSLCT = chslctPin;
  DRDY = drdy;
}

double Thermocouple::getTemp(int unitTemp)
{
  switch(unitTemp)
  {
    case 0:
      return readThermocouple();
      break;
    case 1:
      return readThermocouple() + 273.15;
      break;
    case 2:
      return readThermocouple()*1.8 + 32;
      break;
    case 3:
      return (readThermocouple() + 273.15) * 1.8 - 32;
      break;
  }
}

double Thermocouple::binaryTempConvert( int binaryResult, int byteNumber )
{
  double decimalAns = 0;
  int placeHolder = 0;
  int numbit = 0;
  while (numbit <= 7 )
  {
    placeHolder = 0;
    placeHolder = binaryResult & int(pow(2, numbit)+.5);
    if ( placeHolder != 0 )
    {
      if ( byteNumber == 3 && numbit <= 5 )
      {
      }
      else if ( numbit == 7 && byteNumber == 1 )
      {
        decimalAns = decimalAns*(-1);
      }      
      else
      {
        decimalAns = decimalAns + pow(2,(((8*(4-byteNumber))-1)-(7-numbit)-12));
        
      }

    }
    numbit = numbit+1;
  }
  return decimalAns;
}


/*double Thermocouple::readThermocouple()
{
  double result = 0;
  unsigned int preresult1 = 0;
  unsigned int preresult2 = 0;
  unsigned int preresult3 = 0;

  SPI.beginTransaction(SPISettings(500000,MSBFIRST,SPI_MODE1));
  
  digitalWrite( CHSLCT, LOW );

  SPI.transfer(rLinThermByte2);
  preresult1 = SPI.transfer(0);
  
  SPI.transfer(rLinThermByte1);
  preresult2 = SPI.transfer(0);
  
  SPI.transfer(rLinThermByte0);
  preresult3 = SPI.transfer(0);

  digitalWrite( chipselectPin1, HIGH );
  SPI.endTransaction();

  result = binaryTempConvert( preresult1, 1 );
  result = result + binaryTempConvert( preresult2, 2 );
  result = result + binaryTempConvert( preresult3, 3 );
  
  return result;
  
}*/

double Thermocouple::readThermocouple()
{
  byte dataToSend;
  double result = 0;
  unsigned int preresult1 = 0;
  unsigned int preresult2 = 0;
  unsigned int preresult3 = 0;
  unsigned int preresult[] = {0,0,0};
  int i = 0;

  SPI.beginTransaction(SPISettings(500000,MSBFIRST,SPI_MODE1));
  
  /*digitalWrite( CHSLCT, LOW );

  
  dataToSend = rLinThermByte2;
  SPI.transfer(rLinThermByte2);
  preresult1 = SPI.transfer(0);

  digitalWrite( CHSLCT, HIGH );

  digitalWrite( CHSLCT, LOW );

  
  dataToSend = rLinThermByte1;
  SPI.transfer(rLinThermByte1);
  preresult2 = SPI.transfer(0);

  digitalWrite( CHSLCT, HIGH );

  digitalWrite( CHSLCT, LOW );

  
  dataToSend = rLinThermByte0;
  SPI.transfer(rLinThermByte0);
  preresult3 = SPI.transfer(0);

  digitalWrite( CHSLCT, HIGH );
  SPI.endTransaction();

  result = binaryTempConvert( preresult1, 1 );
  result = result + binaryTempConvert( preresult2, 2 );
  result = result + binaryTempConvert( preresult3, 3 );*/

  for( i; i<3; i++)
  {
    digitalWrite(CHSLCT, LOW);
    SPI.transfer(rLinThermByte2 + byte(i));
    preresult[i] = SPI.transfer(0);
    digitalWrite(CHSLCT,HIGH);
  }
  for( i = 0; i<3; i++)
  {
    result += binaryTempConvert(preresult[i],i+1);
  }
  lastTemp = result;
  return result;
  
}


bool Thermocouple::isReady()
{
  return !digitalRead(DRDY);
}


void Thermocouple::writeRegister( byte thisRegister, byte thisValue )
{
   digitalWrite( CHSLCT, LOW );
  SPI.beginTransaction(SPISettings(1000000,MSBFIRST,SPI_MODE1));

  SPI.transfer(thisRegister);
  SPI.transfer(thisValue);
  
  digitalWrite( CHSLCT, HIGH );
  SPI.endTransaction();
  
}


unsigned int Thermocouple::readRegister( byte thisRegister ) 
{
  
  
  byte inByte = 0;
  unsigned int result = 0;


  digitalWrite( CHSLCT, LOW );  

  byte dataToSend = thisRegister;
  SPI.beginTransaction(SPISettings(1000000,MSBFIRST,SPI_MODE1));
  SPI.transfer(dataToSend);
  result = SPI.transfer(0b10101010);

  SPI.endTransaction();
  digitalWrite( CHSLCT, HIGH );

  
  return result;
}

void Thermocouple::setFaultMask(byte regFault)
{
  writeRegister(wfaultMask,regFault);
}

void Thermocouple::setBaseConfig(byte regOne, byte regTwo )
{
  writeRegister(wCNfig0,regOne);
  writeRegister(wCNfig1,regTwo);
}

void Thermocouple::setTemperatureFault(int lowCold, int highCold, double lowHot, double highHot )
{
  int i = 0;
  int value = 0;
  double placeHold = 0;
  double absTemp = abs(lowHot);
  char binOne = 0;
  char binTwo = 0;
  if( lowHot > -2074.9375 || lowHot < 2074.9375 )
  {
    for( i = -4; i < 11; i++)
    {
      
      if( abs(absTemp - placeHold) > abs(absTemp - placeHold + pow(2,i)) )
      {
        placeHold += pow(2,i);
        value = (value << 1) | 0b00000001;
      }
    }
    if( lowHot < 0 )
      value = value | 0b1000000000000000;
  }
  binOne = char(value >> 8);
  binTwo = char(value & 0b0000000011111111);
  writeRegister(wLinThermLowFaultThreshMSB, binOne);
  writeRegister(wLinThermLowFaultThreshLSB, binTwo);

  value = 0;
  placeHold = 0;
  absTemp = abs(highHot);
  binOne = 0;
  binTwo = 0;

  if( highHot > -2074.9375 || highHot < 2074.9375 )
  {
    for( i = -4; i < 11; i++)
    {
      
      if( abs(absTemp - placeHold) > abs(absTemp - placeHold + pow(2,i)) )
      {
        placeHold += pow(2,i);
        value = (value << 1) | 0b00000001;
      }
    }
    if( highHot < 0 )
      value = value | 0b1000000000000000;
  }
  binOne = char(value >> 8);
  binTwo = char(value & 0b0000000011111111);
  writeRegister(wLinThermHighFaultThreshMSB, binOne);
  writeRegister(wLinThermHighFaultThreshLSB, binTwo);

  binOne = 0;
  binTwo = 0;

  if( lowCold >= 0b11111111 && highCold <= 0b01111111 && highCold > lowCold ) 
  {
    binOne = char(lowCold);
    binTwo = char(highCold);

    writeRegister(wColdLowFaultThresh,binOne);
    writeRegister(wColdHighFaultThresh,binTwo);
  }
  
  
}

void Thermocouple::setColdOffset(double temp)
{
  int i = 0;
  char value = 0;
  double placeHold;
  double absTemp = abs(temp);
  if( temp > -7.9375 || temp < 7.9375 )
  {
    for( i = 2; i > -5; i--)
    {
      if( abs(absTemp - placeHold) > abs(absTemp - placeHold + pow(2,i)) )
      {
        placeHold += pow(2,i);
        value = value | int(pow(2,i+4)+.5);
      }
    }
    if( temp < 0 )
      value = value | 0b10000000;
  }
  writeRegister(wColdOffset, value);
}

double Thermocouple::getColdOffset()
{
  int placeHold = 0;
  int i;
  double result = 0;
  char regVal = readRegister(rColdOffset);
  for( i=0; i<7; i++)
  {
    placeHold = int(pow(2,i)+.5);
    if( regVal & placeHold )
      result += pow(2,i-4);
  }
  if( regVal & 0b10000000 )
    result *= (-1);
  return result;  
}

double Thermocouple::getColdTemp()
{
  int i = 0;
  int tempReading = byte( readRegister(rColdTempMSB) );
  tempReading = tempReading << 8;
  tempReading = tempReading | byte( readRegister(rColdTempLSB) );
  double result = 0;

  for( i=-6;i<7;i++)
  {
    if (  tempReading & int(pow(2,i+8)+.5) )
    {
      result += pow(2,i);
    }
  }
  return result;
}

double Thermocouple::getLatestTemp()
{
  return lastTemp;
}

Thermocouple.h

#pragma once
#if ARDUINO >= 100
  #include "Arduino.h"
#else
  #include "WProgram.h"
#endif
#include <SPI.h>

// memory register WRITE addresses of MAX31856 thermocouple board
#define wCNfig0 0x80
#define wCNfig1 0x81
#define wfaultMask 0x82
#define wColdHighFaultThresh 0x83
#define wColdLowFaultThresh 0x84
#define wLinThermHighFaultThreshMSB 0x85
#define wLinThermHighFaultThreshLSB 0x86
#define wLinThermLowFaultThreshMSB 0x87
#define wLinThermLowFaultThreshLSB 0x88
#define wColdOffset 0x89
#define wColdTempMSB 0x8A
#define wColdTempLSB 0x8B

// memory register READ addresses of MAX31856 thermocouple board
#define rCNfig0 0x00
#define rCNfig1 0x01
#define rfaultMask 0x02
#define rColdHighFaultThresh 0x03
#define rColdLowFaultThresh 0x04
#define rLinThermHighFaultThreshMSB 0x05
#define rLinThermHighFaultThreshLSB 0x06
#define rLinThermLowFaultThreshMSB 0x07
#define rLinThermLowFaultThreshLSB 0x08
#define rColdOffset 0x09
#define rColdTempMSB 0x0A
#define rColdTempLSB 0x0B
#define rLinThermByte2 0x0C
#define rLinThermByte1 0x0D
#define rLinThermByte0 0x0E
#define rFaultStatus 0x0F
#ifndef THERMOCOUPLE_H
#define THERMOCOUPLE_H

class Thermocouple
{
  public:
    Thermocouple(int mosiPin,int misoPin,int clkPin, int chslctPin, int drdy);//{MOSI,MISO,CLK,CHSLCT,DRDY};
    double getTemp(int unitTemp = 0);
    double getLatestTemp();
    void setFaultMask(byte regFault = 0b00110011);
    void setBaseConfig(byte regOne = 0b10000010,byte regTwo = 0b00000011 );
    void setTemperatureFault(int lowCold = 0,int highCold = 50,double lowHot = 0,double highHot = 200);
    void setColdOffset(double temp = 0);
    double getColdOffset();
    double getColdTemp();
    bool isReady();

  private:
    unsigned int readRegister(byte);
    void writeRegister(byte,byte);
    double readThermocouple();
    double binaryTempConvert(int,int);
    double lastTemp;
    int MOSI,MISO,CLK,CHSLCT,DRDY;
  
};
#endif

control.cpp

#pragma once
#include "control.h"
// #include "Thermocouple.h"
// #include "Heater.cpp"
// #include "Blower.h"

void fluid_bed_control( Heater heater, Blower blower, double inlet_temp, double bed_temp)// double MAX_INLET_TEMP, double MAX_BED_TEMP, double MIN_BED_TEMP)
{
  if( inlet_temp > MAX_INLET_TEMP )
  {
    heater.setHeater(0);
    blower.setBlower(1);
  }
  else if( bed_temp > MAX_BED_TEMP )
  {
    heater.setHeater(0);
    blower.setBlower(1);
  }
  else if( bed_temp < MIN_BED_TEMP )
  {
    heater.setHeater(1);
    blower.setBlower(1);
  }


}

control.h

#pragma once
#include "Thermocouple.h"
#include "Heater.h"
#include "Blower.h"
#include "fluidized_bed_test.h"

void fluid_bed_control( Heater heater, Blower blower, double inlet_temp, double bed_temp);//, double max_inlet_temp, double max_bed_temp, double min_bed_temp);

fluidized_bed_test.h

#pragma once
//#include <TimerOne.h>
//#include <Chrono.h>
//#include <LightChrono.h>
#include <SPI.h>
//#include <LiquidCrystal.h>
//#include <Wire.h> // Include the I2C library (required)
//#include <SparkFunSX1509.h> // Include SX1509 library

#define MAX_INLET_TEMP 82.2
#define MIN_INLET_TEMP 68.0
#define MAX_BED_TEMP 72.0
#define MIN_BED_TEMP 68.0

// pinout of redboard

// #define scrnPin1 1
// #define scrnPin2 2
// #define scrnPin3 3
// #define scrnPin4 4
// #define scrnPin5 5
// #define scrnPin6 6
#define DRDYPIN3 5
#define CHIPSEL3 6
#define DRDYPIN2 7
#define CHIPSEL2 8
#define DRDYPIN1 9
#define CHIPSEL1 10
//#define MOSIPin 11
//#define MISOPin 12
//#define CLKPin 13
#define MOSIPin 75
#define MISOPin 74
#define CLKPin 76
// #define SCRNCOM A0
// #define FLOATPIN1 A1
// #define FLOATPIN2 A2
// #define VALVEPIN1 A3
// #define VALVEPIN2 A4
#define HEATERPIN 4
#define BLOWERPIN 3

// pinout of I2C board
// #define MOTORPIN1 20
// #define MOTORPIN2 21
// #define FAULTPIN1 22
// #define FAULTPIN2 23

struct ProcessState
{
  bool safetyFlag;
  bool fillState;
  bool firstTime;
  bool standBy;
  bool warmUp;
  bool pasteurize;
  bool coolDown;
  bool emptyState;
  bool standByEmpty;
};
8
  • What happens on the Due instead?
    – PMF
    Oct 10, 2022 at 9:09
  • SPI on the Due is.... strange. There are multiple "channels" each using the same data / clock pins, but tied to specific chip select pins. Trying to use pins that aren't those specific chip select pins could have unwanted results. I don't know what those results will be, but I personally avoid the Due for anything, and especially anything where SPI is concerned.
    – Majenko
    Oct 10, 2022 at 9:23
  • @pmf Nothing happens on the due. There is no serial communication, even if I put the serial communication initialization and first serial print in the first two lines of the setup function. When I try to get the onboard LED to blink like in the "blink" sketch, nothing happens.
    – Ender
    Oct 12, 2022 at 1:31
  • @Majenko So I have learned. I wish I knew that the Due was so difficult to deal with before I purchased it. Also the whole premise of having an "unrequired" pre-designated chip select (CS) pin is weird. Any other pin that can be switched be high and low can function as a CS pin.
    – Ender
    Oct 12, 2022 at 1:38
  • Try putting a delay (of half a second or so) between Serial.begin() and the first print. Sometimes, the first characters are lost otherwise. I was able to get SPI to run on the Due, but that was some time ago.
    – PMF
    Oct 12, 2022 at 6:10

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Browse other questions tagged or ask your own question.