Communication between the ESP8266 and arduino due

I am encountering problems regarding mesage communication between ESP8266 and arduino due.
The following link contains my codes:

The webpage folder contains the code for esp8266 (webpage.ino and webpage.h)
The stimuli folder contains the code for arduino due (stimuli.ino)

I am trying to create a WiFi-controlled fear conditioning device, which uses sound and shock to test animals. I am using the ESP8266 to control the arduino due by the webpage i created.
I have tested that the esp8266 can send message to the arduino due but the variables that i have put into the esp8266 appears as 0.00 on the arduino due serial monitor and i don't seem to find where the problem is.

The esp8266 code for sending variables to the arduino due looks like this:

/*
 * Núcleo de Neurociências - UFMG/Brazil (Universidade Federal de Minas Gerais)
 * 
 * Custom Conditioning Chamber for Classical Fear Conditioning - ESP Control
 * 
 * 
 * Authors: Paulo Aparecido Amaral Júnior  - amaraljr.paulo@gmail.com
 *          Flávio Afonso Gonçalves Mourão - mourao.fg@gmail.com
 *          Márcio Flávio Dutra Moraes     - mfdm@icb.ufmg.br
 * 
 * ESP8266 libraries: https://github.com/esp8266/Arduino      
 * The code relies on the following library boards: Aug 03, 2018 / version: 2.4.2 -> https://github.com/esp8266/Arduino/releases?page=2
 *          
 * Last code update: August/2022 - Flávio Mourao
 * 
 */
 
/*############################################################################################################
        Includes.
############################################################################################################*/
  
  #include <ESP8266WiFi.h> // 
  #include <ESP8266WebServer.h>
  #include <ESP8266mDNS.h>
  
  #include <SPI.h>
  #include <EEPROM.h>
  
  //#include "user_interface.h"
  #include "Web_Page.h"
  ControleDueSkinner *ArduinoDueSkinner = new ControleDueSkinner(); // Initialize the pointer here

/*############################################################################################################
        Global variables.
############################################################################################################*/
  
  const char *ssid = "ConditioningCage";
  const char *password = "0112358132"; // Fibonacci
  IPAddress myIP;
  ESP8266WebServer server ( 80 );

/*############################################################################################################
        Function declarations.
############################################################################################################*/
  
  void handleRoot();
  void Programar();
  void handleNotFound();

/*############################################################################################################
        Setup.
############################################################################################################*/
  void setup ( void ) 
  {
    // Uncommenting Serial.begin() and all Serial.println() lines may help troubleshooting this sketch.
    // Configure UART communication
	  //Serial.begin ( 115200 );

    pinMode ( ArduinoDueSkinner->pinABORT, OUTPUT );
    digitalWrite ( ArduinoDueSkinner->pinABORT, LOW );
    pinMode ( ArduinoDueSkinner->pinSOUND, OUTPUT );
    digitalWrite ( ArduinoDueSkinner->pinSOUND, LOW );
    //pinMode ( ArduinoDueSkinner->pinSOUNDnot, OUTPUT );
    //digitalWrite ( ArduinoDueSkinner->pinSOUNDnot, HIGH );
    pinMode ( ArduinoDueSkinner->pinSHOCK, OUTPUT );
    digitalWrite ( ArduinoDueSkinner->pinSHOCK, LOW );

    // Waiting 1 second before reset Arduino
    delay(1000);
    pinMode (ArduinoDueSkinner->pinRSTarduino,OUTPUT);
    digitalWrite ( ArduinoDueSkinner->pinRSTarduino, LOW );
    delay(100);
    digitalWrite ( ArduinoDueSkinner->pinRSTarduino, HIGH );
  
    // Configure SPI communication.
    SPI.begin ();
    SPI.setBitOrder(MSBFIRST);
    SPI.setDataMode(SPI_MODE0); 
    SPI.setClockDivider(SPI_CLOCK_DIV16);
    //SPI.setClockDivider(SPI_CLOCK_DIV2); 
                                         /* SPI_CLOCK_DIV2    0x00101001 //8 MHz
                                            SPI_CLOCK_DIV4    0x00241001 //4 MHz
                                            SPI_CLOCK_DIV8    0x004c1001 //2 MHz
                                            SPI_CLOCK_DIV16   0x009c1001 //1 MHz
                                            SPI_CLOCK_DIV32   0x013c1001 //500 KHz
                                            SPI_CLOCK_DIV64   0x027c1001 //250 KHz
                                            SPI_CLOCK_DIV128  0x04fc1001 //125 KHz */
    SPI.setHwCs(true); // setHwCs(true) sets ESP8266 as MASTER. setHwCs(false) sets ESP8266 as SLAVE.

    // Configure WiFI
    WiFi.mode(WIFI_AP);
    WiFi.softAP(ssid, password);
    myIP = WiFi.softAPIP();

    //Domain Name Server. 
    if ( MDNS.begin ( "esp8266" ) ) 
    {
    //  Serial.println ( "MDNS responder started" );
    }
    
    /*
  	Serial.println("Configuring access point...");
    Serial.println();
    Serial.print("Access point name is: ");
    Serial.println(ssid);
    Serial.print("Access Point IP address: ");
    Serial.println(myIP);
  
     // Print the IP address
      Serial.print("Use this URL to connect: ");
      Serial.print("http://");
      Serial.print(myIP);
      Serial.println("/");
  */
  	server.on ( "/", handleRoot );
  	server.on ( "/Programar", Programar );
  	server.on ( "/inline", []() 
  	{
  		server.send ( 200, "text/plain", "this works as well" );
  	} );
  	server.onNotFound ( handleNotFound );
  	server.begin();
  //	Serial.println ( "HTTP server started" );
  }


/*############################################################################################################
        loop.
############################################################################################################*/
  
  void loop ( void ) 
  {
  	server.handleClient();
  }

/*############################################################################################################
        handleRoot.
############################################################################################################*/
  
  void handleRoot() 
  {
    // Publish webpage.
      server.send ( 200, "text/html", ArduinoDueSkinner->PaginaHTML );
  }

/*############################################################################################################
       Experiment code.
############################################################################################################*/
  
  void Programar()
  {
      String argname,argvalue,strResponse;
      uint8_t numofargs = (uint8_t) (server.args());
      Serial.print("numofargs: "); 
      Serial.println(numofargs);
      bool bSenha=false;

      strResponse="";
      
      // For all the arguments...
      for (int i = 0; i < numofargs; i++ )
      {
          // Get argument name, which is a String, and turn it into an array of chars.
          argname = server.argName(i);
          //Serial.print(argname);
          //Serial.print(": ");
          // Get argument value, which is a String, and turn it into an array of chars.
          argvalue = server.arg(i);
          //Serial.println(argvalue);

          // switch structure on the first character of parameter name (indicates the type)
          
          if (argname=="Comando1")
          {
            strResponse+="O comando1 =" + argvalue + "; ";
          }

          if (argname=="Comando2")
          {
            strResponse+="O comando2 =" + argvalue + "; ";
          }

          if (argname=="Comando3")
          {
            strResponse+="O comando3 =" + argvalue + "; ";
          }
          
          if (argname=="Comando4")
          {
            uint16_t uDataIn;
            uDataIn=SPI.transfer16(0xA0A0); //Pode processar
            char *chTemp; chTemp=(char *) &uDataIn;
            strResponse+=String("O comando4 =") + uDataIn + "; ";
          }

          if (argname=="EscrevaBytes")
          {
            
           
            char *c = (char *) ArduinoDueSkinner->BufferFloat;
            c[0]='A';
            c[1]='B';
            c[2]='C';
            c[3]='D';

            uint16_t *varX;
            
            strResponse+="Request sending (" + argvalue + ") bytes on SPI bus; ";

            for (int zxc=0;zxc<argvalue.toInt();zxc+=2) 
              {
                varX=(uint16_t *)(c +zxc);
                while (SPI1CMD & SPIBUSY) {};
                SPI.write16(*varX,true);
              }
            
    
          }      
          if (argname=="Senha")
          {
            if (argvalue=="12345")
              {
                strResponse+="** CORRECT PASSWORD ** \n";
                bSenha=true;
              } else strResponse+="** INCORRECT PASSWORD ** \n";
            
          }

          if (argname=="ProgramarTrials")
          {
            if (i==(numofargs-1)) strResponse+="SOME PARAMETERS ARE MISSING";
              else if ((server.argName(i+1)=="strTrials")&&(bSenha))
                {
                  i++;
                  ArduinoDueSkinner->ProgramaVariaveis(argvalue.toInt(),server.arg(i));
                } else strResponse+="STRING PARAMETERS IS MISSING";
          }

          if ((argname=="START")&&bSenha)
            {
              ArduinoDueSkinner->StartTrials();
              strResponse+="\nSTART COMMAND\n";
            }
            
          if ((argname=="ABORT")&&bSenha)
            {
              ArduinoDueSkinner->Abort();
              strResponse+="\nABORT COMMAND\n";
            }
          
          
     } // end for structure (end sending parameters)
     //Serial.println("end variables");
     server.send ( 200, "application/x-www-form-urlencoded; charset=UTF-8",strResponse);
  }


/*############################################################################################################
        handleNotFound.
############################################################################################################*/

void handleNotFound() 
{
  String message = "File Not Found\n\n";
  message += "URI: ";
  message += server.uri();
  message += "\nMethod: ";
  message += ( server.method() == HTTP_GET ) ? "GET" : "POST";
  message += "\nArguments: ";
  message += server.args();
  message += "\n";

  for ( uint8_t i = 0; i < server.args(); i++ ) 
  {
    message += " " + server.argName ( i ) + ": " + server.arg ( i ) + "\n";
  }

  server.send ( 404, "text/plain", message );
}

// Global functions.
  int parseStringToFloat(String str,char delimiter);
  int parseStringToFloat(String str,char delimiter, float *floatArray);

// Timers and their interrupt service routines.
  os_timer_t trial_timer, sound_timer, shock_timer;

  void isr_trial(void *pArg);
  void isr_sound(void *pArg);
  void isr_shock(void *pArg);

/* Function parseStringToFloat, used in 2 different ways (2 implementations below)
 *  
 *  
 */
   int parseStringToFloat(String str,char delimiter)
   {
      int floatsEscritos=0;
      for (int k=0;k<str.length();k++) if (str[k]==delimiter) floatsEscritos++;
      return (floatsEscritos+1);
   }

int parseStringToFloat(String str,char delimiter, float *floatArray)
{
  int floatsEscritos=0;
  int lastPos=0;
  for (int i=0;i<str.length();i++)
    if (str[i]==delimiter)
      {
        floatArray[floatsEscritos]=str.substring(lastPos,i).toFloat();
        lastPos=i+1;
        floatsEscritos++;
      }
  floatArray[floatsEscritos]=str.substring(lastPos).toFloat();
  return (floatsEscritos+1);
}

    
class ControleDueSkinner
{
  public:
  //Construtor
  ControleDueSkinner();

 //Class functions 
  void StartTrials();
  void Abort();
  bool ProgramaArduinoSPI(int iQualTrial);
  bool ProgramaVariaveis(int QuantosTrials, String strVar);
  bool bReady=0;
  
 //Control GPIOs
  const int pinABORT = 4;       // Pin used to tell Arduino to abort experiment (Abort).
  const int pinSOUND = 0;       // Pin used to tell Arduino that the sound (modulator + carrier) must be played.
  const int pinSOUNDnot = 5;    // PinSOUNDnot = not(pinSOUND)
  const int pinSHOCK = 2;       // Pin used to tell Arduino to shock rat's paw.
  const int pinRSTarduino = 16; // Pin used to reset Arduino.
  
 // Variables related to experiment parameters. Data comes from WEBPAGE.
  float BufferFloat[1800];    // a buffer to hold the values configured by user via webpage. Values are copied from strVar.
  float *silence;             // in seconds.
  float current_trial_length; // in seconds
  float *onset_shock;         // in seconds.
  float *onset_sound;         // in seconds.
  float *sound_duration;      // in seconds.
  float *shock_duration;      // in seconds.
  float *carrier_freq;        // in Hertz.
  float *modulator_freq;      // in Hertz.
  float *pulse_shockHigh;     // in ms. 
  float *pulse_shockLow;      // in ms.
  float *volume_sound;        // in percent (%).

  int iCountTrials=0;
  int iNumberOfTrials=0;
  
/*############################################################################################################ 
// Webpage content. -> Need to convert html to string and then past here below
############################################################################################################*/

 String PaginaHTML =  
"<!DOCTYPE html>\n\
<html>\n\
<body>\n\
\n\
<body style=\"background-color:powderblue;\">\n\
\n\
<center><h2>Conditioning Cage V1.0</h2></center>\n\
<!-- \n\
<button type=\"button\" onclick=\"loadDoc()\">Request data</button></br>\n\
-->\n\
\n\
Cage Control Password: <input id=\"senha\" type=\"password\" value=\"\" />\n\
<button type=\"button\" onclick=\"enviarESP()\">Send Parameters</button>\n\
<button type=\"button\" onclick=\"enviarESPSTART()\">START</button>\n\
<button type=\"button\" onclick=\"enviarESPABORT()\">ABORT</button></br>\n\
<!-- \n\
<button type=\"button\" onclick=\"testeESP()\">TESTANDO COISAS</button></br>\n\
-->\n\
<div id=\"entrada\">\n\
 <p>TRIAL CONFIGURATION</p></br>\n\
  Inter-trial silence or initial silence (seconds)<input id=\"Silence\" type=\"text\" value=\"\" /><br>\n\
  Sound onset (seconds)<input id=\"SoundOnset\" type=\"text\" value=\"\" />  \n\
  Sound duration (seconds)<input id=\"SoundDuration\" type=\"text\" value=\"\" /><br>\n\
  Shock onset (seconds)<input id=\"ShockOnset\" type=\"text\" value=\"\" />  \n\
  Shock duration (seconds)<input id=\"ShockDuration\" type=\"text\" value=\"\" /><br>\n\
  </br>\n\
  Carrier Frequency (Hz)<input id=\"CarrierFreq\" type=\"text\" value=\"\" />  \n\
  Modulator Frequency (Hz)<input id=\"ModFreq\" type=\"text\" value=\"\" /><br>\n\
  ShockPulse High (ms)<input id=\"ShockPulseHigh\" type=\"text\" value=\"\" />  \n\
  ShockPulse Low (ms)<input id=\"ShockPulseLow\" type=\"text\" value=\"\" /><br>\n\
  Sound Volume (%)<input id=\"SoundVolume\" type=\"text\" value=\"\" /><br>\n\
  </br>\n\
  <input id=\"SubmitTrial\" type=\"button\" onclick=\"adicionarTrial()\" value=\"Add Trial\" /><br>\n\
</div>\n\
<hr>\n\
<textarea id=\"expTexto\" rows=\"4\" cols=\"50\"></textarea>\n\
<button type=\"button\" onclick=\"programaExperimento()\">LOAD TRIAL(S)</button></br>\n\
<hr><br>\n\
<div id=\"saidaHTML\">\n\
</div>\n\
\n\
<p id=\"demo\"></p>\n\
 \n\
<script>\n\
//Variáveis Globais\n\
xhr=new XMLHttpRequest();\n\
\n\
var Trials = [];\n\
var varSet = [];\n\
\n\
varSet[0]=\"Silence\";\n\
varSet[1]=\"SoundOnset\";\n\
varSet[2]=\"SoundDuration\";\n\
varSet[3]=\"ShockOnset\";\n\
varSet[4]=\"ShockDuration\";\n\
varSet[5]=\"CarrierFreq\";\n\
varSet[6]=\"ModFreq\";\n\
varSet[7]=\"ShockPulseHigh\";\n\
varSet[8]=\"ShockPulseLow\";\n\
varSet[9]=\"SoundVolume\";\n\
for (var i=0;i<varSet.length;i++) Trials[i]=[];\n\
\n\
function adicionarTrial()\n\
{\n\
var indice=0;\n\
if (typeof Trials[0] != 'undefined') indice=Trials[0].length;\n\
for (var i=0;i<varSet.length;i++) Trials[i][indice]=document.getElementById(varSet[i]).value;\n\
ShowRecordedTrials();\n\
};\n\
\n\
function ShowRecordedTrials()\n\
{\n\
var strTemp=\"<center><p> ALL RECORDED TRIALS </p></center>\";\n\
\n\
for (var i=0;i<Trials[0].length;i++)\n\
  {\n\
  strTemp+=\"<hr>\";\n\
  strTemp+=\"<p>RECORDED TRIAL - \" + i + \" Start at (seg): \" + Trials[0][i] + \"s. \";\n\
  strTemp+=\"<br> To delete this trial click ====> <button id=\\\"reg\" + i + \"\\\" type=\\\"button\\\" onclick=\\\"ClickDeleteReg(this)\\\">Delete</button></p>\";\n\
\n\
  strTemp+=varSet[1] + \" = \" + Trials[1][i] + \" e \";\n\
  strTemp+=varSet[2] + \" = \" + Trials[2][i];\n\
  strTemp+=\"<br>\" + varSet[3] + \" = \" + Trials[3][i] + \" e \";\n\
  strTemp+=varSet[4] + \" = \" + Trials[4][i];\n\
  strTemp+=\"<br>\" + varSet[5] + \" = \" + Trials[5][i] + \" e \";\n\
  strTemp+=varSet[6] + \" = \" + Trials[6][i];\n\
  strTemp+=\"<br>\" + varSet[7] + \" = \" + Trials[7][i] + \" e \";\n\
  strTemp+=varSet[8] + \" = \" + Trials[8][i];\n\
  strTemp+=\"<br>\" + varSet[9] + \" = \" + Trials[9][i]; \n\
  strTemp+=\"<hr>\";\n\
  }\n\
//strTemp+=\"Sort = \" + Trials[0].sort();  ele faz o sort e fode tudo  \n\
document.getElementById(\"saidaHTML\").innerHTML = strTemp;\n\
\n\
strTemp=\"\";\n\
for (var j=0;j<varSet.length;j++)\n\
  {\n\
  //strTemp+=\"|\";\n\
  for (var i=0;i<((Trials[0].length)-1);i++)\n\
    strTemp+=Trials[j][i] + \";\";\n\
  strTemp+=Trials[j][i] + \"|\";\n\
  }\n\
strTemp=strTemp.substring(0, strTemp.length-1); \n\
document.getElementById(\"expTexto\").value=strTemp;\n\
}\n\
\n\
function programaExperimento()\n\
{\n\
//Trials = [];\n\
\n\
var linha=document.getElementById(\"expTexto\").value;\n\
var linha2=linha.split(\"|\");\n\
var linha3;\n\
\n\
for (var i=0; i<linha2.length ;i++)\n\
  {\n\
  linha3=linha2[i].split(\";\");\n\
  for (var j=0; j<linha3.length ;j++)\n\
    Trials[i][j]=linha3[j];\n\
  }\n\
  \n\
ShowRecordedTrials();\n\
}\n\
\n\
\n\
function ClickDeleteReg(ele)\n\
{\n\
  var iQual=ele.id.substring(3);\n\
  \n\
  if (confirm(\"Tem certeza? Voce vai deletar o TRIAL: \" + iQual))\n\
    for (var i=0;i<varSet.length;i++) Trials[i].splice(iQual,1);\n\
    \n\
  \n\
  ShowRecordedTrials();\n\
}\n\
\n\
function trataResposta()\n\
{\n\
if(xhr.readyState == 4 && xhr.status == 200) \n\
  {\n\
      alert(xhr.responseText);\n\
  }\n\
};\n\
\n\
\n\
function enviarESP() \n\
{\n\
//MUITO CUIDADO, FALTA SORT E OUTRAS COISITAS MAS\n\
var strTemp=\"\";\n\
\n\
\n\
strTemp+=\"ProgramarTrials=\" + Trials[0].length + \"&\";\n\
strTemp+=\"strTrials=\";\n\
\n\
for (var j=0;j<varSet.length;j++)\n\
  for (var i=0;i<Trials[0].length;i++)\n\
    strTemp+=Trials[j][i] + \";\";\n\
\n\
strTemp=strTemp.substring(0,strTemp.length-1);\n\
\n\
var strTemp2=\"Senha=\" + document.getElementById(\"senha\").value + \"&\";\n\
\n\
xhr.open(\"POST\", \"http://192.168.4.1/Programar\", true);\n\
xhr.setRequestHeader(\"Content-Type\", \"application/x-www-form-urlencoded; charset=UTF-8\");\n\
xhr.onreadystatechange = trataResposta;\n\
xhr.send(strTemp2+strTemp);\n\
\n\
};\n\
\n\
function enviarESPSTART() \n\
{\n\
//MUITO CUIDADO, FALTA SORT E OUTRAS COISITAS MAS\n\
//var strTemp=\"EscrevaBytes=32\";\n\
var strTemp=\"Senha=\" + document.getElementById(\"senha\").value + \"&START=1\";\n\
xhr.open(\"POST\", \"http://192.168.4.1/Programar\", true);\n\
xhr.setRequestHeader(\"Content-Type\", \"application/x-www-form-urlencoded; charset=UTF-8\");\n\
xhr.onreadystatechange = trataResposta;\n\
xhr.send(strTemp);\n\
};\n\
\n\
function enviarESPABORT() \n\
{\n\
//MUITO CUIDADO, FALTA SORT E OUTRAS COISITAS MAS\n\
//var strTemp=\"EscrevaBytes=32\";\n\
var strTemp=\"Senha=\" + document.getElementById(\"senha\").value + \"&ABORT=1\";\n\
xhr.open(\"POST\", \"http://192.168.4.1/Programar\", true);\n\
xhr.setRequestHeader(\"Content-Type\", \"application/x-www-form-urlencoded; charset=UTF-8\");\n\
xhr.onreadystatechange = trataResposta;\n\
xhr.send(strTemp);\n\
};\n\
\n\
function testeESP() \n\
{\n\
//MUITO CUIDADO, FALTA SORT E OUTRAS COISITAS MAS\n\
//var strTemp=\"EscrevaBytes=32\";\n\
var strTemp=\"Comando4=1\";\n\
\n\
\n\
\n\
\n\
xhr.open(\"POST\", \"http://192.168.4.1/Programar\", true);\n\
xhr.setRequestHeader(\"Content-Type\", \"application/x-www-form-urlencoded; charset=UTF-8\");\n\
xhr.onreadystatechange = trataResposta;\n\
xhr.send(strTemp);\n\
\n\
};\n\
function loadDoc() \n\
{\n\
xhr.open(\"POST\", \"http://192.168.4.1/Programar\", true);\n\
xhr.setRequestHeader(\"Content-Type\", \"application/x-www-form-urlencoded; charset=UTF-8\");\n\
xhr.onreadystatechange = trataResposta;\n\
xhr.send(\"Comando4=Este foi o Primeiro&teste1=Depois este&teste2=LIGA ESTA PORRA\");\n\
\n\
//ProgramarTrials=5&strTrials=2.14.314;2342342342;2423423;234234;...\n\
//\n\
};\n\
\n\
</script>\n\
\n\
</body>\n\
</html>";


// End Webpage.


  private:




  protected:



  
};
extern ControleDueSkinner *ArduinoDueSkinner;


/*############################################################################################################
        Funções da CLASSE
############################################################################################################*/

ControleDueSkinner::ControleDueSkinner()
{
  os_timer_setfn(&trial_timer, isr_trial, NULL); // sets callback function for sound_timer.
  os_timer_setfn(&sound_timer, isr_sound, NULL); // sets callback function for sound_timer.
  os_timer_setfn(&shock_timer, isr_shock, NULL); // sets callback function for shock_timer.
}

/*############################################################################################################
    SPI COMUNICATION FROM/TO MASTER: Our protocol.

        0xA0A0 is the command word sent by ESP8266 that indicates SPI data should be processed.
        0x0010 is the command word sent by ESP8266 that indicates control variables should be programmed.
          (values for carrier_freq, modulator_freq, pulse_shockHigh and pulse_shockLow should be sent by ESP8266 after 0x0010 command)
        0x10FF is the command word sent by Arduino indicating that the values for the control variables were all received.
        0x1000 is the command word sent by Arduino indicating that the values for the control variables were not received.
        0x1A00 is the command word sent by ESP8266 indicating to ABORT experiment.
        
############################################################################################################*/

bool ControleDueSkinner::ProgramaArduinoSPI(int iQualTrial)
{
  uint16_t *uTemp;

  SPI.write16(0x0010,true); // Command sent to Arduino indicating that parameters are goind to be sent through SPI.
  
  uTemp=(uint16_t *)(carrier_freq+iQualTrial);
  SPI.write16(*uTemp,true); SPI.write16(*(uTemp+1),true); // sending first float variable (every 2 bytes)

  uTemp=(uint16_t *)(modulator_freq+iQualTrial);
  SPI.write16(*uTemp,true); SPI.write16(*(uTemp+1),true); // sending second float variable (every 2 bytes)

  uTemp=(uint16_t *)(pulse_shockHigh+iQualTrial);
  SPI.write16(*uTemp,true); SPI.write16(*(uTemp+1),true); // sending third float variable (every 2 bytes)

  uTemp=(uint16_t *)(pulse_shockLow+iQualTrial);
  SPI.write16(*uTemp,true); SPI.write16(*(uTemp+1),true); // sending fourth float variable (every 2 bytes)

  uTemp=(uint16_t *)(volume_sound+iQualTrial);
  SPI.write16(*uTemp,true); SPI.write16(*(uTemp+1),true); // sending fifth float variable (every 2 bytes)

  SPI.write16(0xA0A0,true); // Telling Arduino to process data.
  return true;

}

void ControleDueSkinner::Abort()
{
  // Disarm timers and put GPIOs in LOW state (except pinRSTarduino and pinSOUNDnot, which goes HIGH), indicating not to play sound and not to shock anymore.
    os_timer_disarm(&trial_timer);
    os_timer_disarm(&sound_timer);
    os_timer_disarm(&shock_timer);
    
    digitalWrite(pinSOUND, LOW); 
    digitalWrite(pinSOUNDnot, HIGH);
    digitalWrite(pinSHOCK, LOW);

    
    SPI.write16(0x001A,true); //Comando para programar parametros
    SPI.write16(0xA0A0,true); //Pode processar
   // Web page response.
  //  server.send ( 200, "text/html", temp );
}

void ControleDueSkinner::StartTrials()
{
  //Vamos zerar o contador
  if (bReady==0) return;

  //Colocar os pinos de controle em LOW
  digitalWrite ( pinSOUND, LOW );
  digitalWrite ( pinSOUNDnot, HIGH ); 
  digitalWrite ( pinSHOCK, LOW );

  //Vamos desarmar os interrupts:
  os_timer_disarm(&trial_timer);
  os_timer_disarm(&sound_timer);
  os_timer_disarm(&shock_timer);

  void *nada;
  iCountTrials=-1; //Vai acrescentar assim que entrar no interrupt de timer
  if (silence[0]==0) isr_trial(nada); //Começar direto
    else os_timer_arm(&(trial_timer), (uint32_t)(silence[0]*1000), 0);  //Ligar o timer
}



bool ControleDueSkinner::ProgramaVariaveis(int QuantosTrials, String strVar)
{

            //Formato strVar: iNumberOfTrials;todos os silence; todos os onset_sound ...
            
            iNumberOfTrials=QuantosTrials;
            parseStringToFloat(strVar,';',BufferFloat);
            
            silence = BufferFloat;  
            onset_sound = BufferFloat+iNumberOfTrials*1;  
            sound_duration = BufferFloat+iNumberOfTrials*2; 
            onset_shock = BufferFloat+iNumberOfTrials*3; 
            shock_duration = BufferFloat+iNumberOfTrials*4; 
                        
            carrier_freq = BufferFloat+iNumberOfTrials*5;      
            modulator_freq = BufferFloat+iNumberOfTrials*6; 
            pulse_shockHigh = BufferFloat+iNumberOfTrials*7; 
            pulse_shockLow = BufferFloat+iNumberOfTrials*8; 
            volume_sound = BufferFloat+iNumberOfTrials*9; 

            bReady=1; 
            return true;         
}
/*############################################################################################################
        Funções de Timmer Interrupt - FORA DA CLASSE
############################################################################################################*/
  
//extern void ControleDueSkinner::isr_trial(void *pArg)
void isr_trial(void *pArg)
{
  ArduinoDueSkinner->iCountTrials++; //Vamos acrscentar o trial para o Próximo, este já deu início e foi programado.
  
  //Colocar os pinos de controle em LOW
  digitalWrite ( ArduinoDueSkinner->pinSOUND, LOW ); 
  digitalWrite ( ArduinoDueSkinner->pinSOUNDnot, HIGH ); 
  digitalWrite ( ArduinoDueSkinner->pinSHOCK, LOW );

  //Vamos desarmar os interrupts:
  os_timer_disarm(&(sound_timer));
  os_timer_disarm(&(shock_timer));

  ArduinoDueSkinner->ProgramaArduinoSPI(ArduinoDueSkinner->iCountTrials); //Programar o que tiver que ser programado
  delay(10); //Esperar um pouco antes de começar

  //Vamos programar os sons e choques deste trial
  if (ArduinoDueSkinner->onset_shock[ArduinoDueSkinner->iCountTrials]==0) 
  {
    digitalWrite ( ArduinoDueSkinner->pinSHOCK, HIGH );
    os_timer_arm(&(shock_timer), (uint32_t)(ArduinoDueSkinner->shock_duration[ArduinoDueSkinner->iCountTrials]*1000), 0);
  }    else if (ArduinoDueSkinner->onset_shock[ArduinoDueSkinner->iCountTrials]>0) os_timer_arm(&(shock_timer), (uint32_t)(ArduinoDueSkinner->onset_shock[ArduinoDueSkinner->iCountTrials]*1000), 0);
  
  if (ArduinoDueSkinner->onset_sound[ArduinoDueSkinner->iCountTrials]==0) 
  {
    digitalWrite ( ArduinoDueSkinner->pinSOUND, HIGH );
    digitalWrite ( ArduinoDueSkinner->pinSOUNDnot, LOW );
    os_timer_arm(&(sound_timer), (uint32_t)(ArduinoDueSkinner->sound_duration[ArduinoDueSkinner->iCountTrials]*1000), 0);
  }    else if (ArduinoDueSkinner->onset_sound[ArduinoDueSkinner->iCountTrials]>0) os_timer_arm(&(sound_timer), (uint32_t)(ArduinoDueSkinner->onset_sound[ArduinoDueSkinner->iCountTrials]*1000), 0);


  /* Let's program next trial (if there is one). Note that the trial_timer is programmed for the next trial
   * just after starting the current trial (programming SOUND and SHOCK timers for the current timer).
   * First, we have to calculate the current trial length in order to program the next trial.
   */
  if ( (ArduinoDueSkinner->onset_sound[ArduinoDueSkinner->iCountTrials] + ArduinoDueSkinner->sound_duration[ArduinoDueSkinner->iCountTrials])
        >=
       (ArduinoDueSkinner->onset_shock[ArduinoDueSkinner->iCountTrials] + ArduinoDueSkinner->shock_duration[ArduinoDueSkinner->iCountTrials]) )
          ArduinoDueSkinner->current_trial_length = ArduinoDueSkinner->onset_sound[ArduinoDueSkinner->iCountTrials] + ArduinoDueSkinner->sound_duration[ArduinoDueSkinner->iCountTrials];
  else
          ArduinoDueSkinner->current_trial_length = ArduinoDueSkinner->onset_shock[ArduinoDueSkinner->iCountTrials] + ArduinoDueSkinner->shock_duration[ArduinoDueSkinner->iCountTrials];
          
  if ( ArduinoDueSkinner->iCountTrials<(ArduinoDueSkinner->iNumberOfTrials-1) ) // Checking if there are more trials to program.
    os_timer_arm( &(trial_timer), (uint32_t)((ArduinoDueSkinner->silence[ArduinoDueSkinner->iCountTrials+1] + ArduinoDueSkinner->current_trial_length) * 1000), 0 ); //Ligar o timer
  else os_timer_disarm(&(trial_timer));    //Na verdade não precisaria desta linha, mas, em todo caso ....                                                    
  
  
}

//extern void ControleDueSkinner::isr_sound(void *pArg)
void isr_sound(void *pArg)
{

if (digitalRead (ArduinoDueSkinner->pinSOUND)) 
  {
    digitalWrite ( ArduinoDueSkinner->pinSOUND, LOW );
    digitalWrite ( ArduinoDueSkinner->pinSOUNDnot, HIGH );
  }
  else 
  {
    digitalWrite ( ArduinoDueSkinner->pinSOUND, HIGH );
    digitalWrite ( ArduinoDueSkinner->pinSOUNDnot, LOW );
    os_timer_arm(&(sound_timer), (uint32_t)(ArduinoDueSkinner->sound_duration[ArduinoDueSkinner->iCountTrials]*1000), 0);
  }

}

//extern void ControleDueSkinner::isr_shock(void *pArg)
void isr_shock(void *pArg)
{

if (digitalRead (ArduinoDueSkinner->pinSHOCK)) digitalWrite ( ArduinoDueSkinner->pinSHOCK, LOW );
  else 
  {
    digitalWrite ( ArduinoDueSkinner->pinSHOCK, HIGH );
    os_timer_arm(&(shock_timer), (uint32_t)(ArduinoDueSkinner->shock_duration[ArduinoDueSkinner->iCountTrials]*1000), 0);
  }

}

And the arduino code to receive messages from the esp8266 looks like this:

/*
 * Núcleo de Neurociências - UFMG/Brazil (Universidade Federal de Minas Gerais)
 * 
 * Custom Conditioning Chamber for Classical Fear Conditioning
 * 
 * Sketch for Arduino Due (slave SPI). It receives parameters from ESP8266 (master SPI) and generates configurable sound and shock stimuli patterns.
 * Timer4 and Timer5 are used to control sound and shock temporal patterns.
 * Sound signal is produced by DAC1.
 * Shock signals are produced in 8 digital pins (configurable via code).
 * 
 * Authors: Paulo Aparecido Amaral Júnior  - amaraljr.paulo@gmail.com
 *          Flávio Afonso Gonçalves Mourão - mourao.fg@gmail.com
 *          Márcio Flávio Dutra Moraes     - mfdm@icb.ufmg.br
 *          
 *          2019
 */
 
/*############################################################################################################
        includes.
############################################################################################################*/

#include "Waveforms.h"
#include "DueTimer.h"
#include <SPI.h>
#include <avr/interrupt.h>

/*############################################################################################################
        Defines.
############################################################################################################*/

static BitOrder bitOrder = MSBFIRST;
static int pinSS = 10;    // Slave Select pin for Arduino.
static int pinABORT = 48; // Pin used to Abort experiment (Abort).
static int pinSOUND = 50; // Input pin by which ESP8266 controls SOUND.
static int pinSHOCK = 52; // Input pin by which ESP8266 controls SHOCK.
static int pinTrigger = 53; // Output pin used to generate a reference signal (a square wave) that represents sound modulator.


bool bpinSOUND = false;  // variable used to determine if it's a rising or a falling edge on pinSOUND.
bool bpinSHOCK = false;  // variable used to determine if it's a rising or a falling edge on pinSHOCK.
bool bBarStatus = false; // variable used to track the status of SHOCK (if shock is on or if it's off).

/*  ATENTION!!
    freqModulating must be less than (clock freqModulating)/maxSampleNumModulating
*/
/*############################################################################################################
        Global variables.
############################################################################################################*/
// Variables that ESP8266 will send to ArduinoDue via SPI bus.
/*  ATENTION!!
  carrier_freq must be less than (clock carrier_freq)/maxSampleNumCarrier
  REMEMBER! : maximum feasible frequency is given by the conversor limit: 125kHz
  */
float carrier_freq   = 1000;   // defauilt value for carrier frequency (in Hertz). This variable can be programmed by ESP8266 via webpage -> SPI.
float modulator_freq = 53.71; // default value for modulator frequency (in Hertz). This variable can be programmed by ESP8266 via webpage -> SPI.
float volume_sound   = 100;     // default value for volume sound (in percent). This variable can be programmed by ESP8266 via webpage -> SPI.
int iC = 0;   // Carrier wave counter.
int iM = 0;   // Modulating wave counter
uint32_t DACbuffer[maxSamplesNumCarrier * maxSamplesNumModulating]; // Template of the signal with modulator already calculated.

// SHOCK variables.
float pulse_shockHigh = 0; // default value for the time the bar is tied to GND (in ms). This variable can be programmed by ESP8266 via webpage -> SPI.
float pulse_shockLow  = 0;  // default value for the time that should be waited until reach next bar (in ms). This variable can be programmed by ESP8266 via webpage -> SPI.
float fDeltaT;
int ipulse_shockHigh; // in ms.
int ipulse_shockLow; // in ms.
int iDeltaT;

int iBarPin = 22;
static int iInitialBarPin = 23; // Initial pin for the first bar.
static int MaxNumBarPin   = 8;    // Number of bars.
static int iBarPinStep    = 2;     // Step for bar pins (so we can choose only odd or even pins, for example).
int iCountShockIntervals;

bool bSPIprocessdataOUT = false;
bool bSPIprocessdataIn  = false;
int iSPIdataCountIN  = 0;
int iSPIdataCountOUT = 0;
int iSPIdataMaxOUT   = 0;
byte byteBufferDataIN[500];
byte byteBufferDataOUT[500];
uint32_t uData; // A variable where we copy the content of the SPI Receive Data Register when we have an SPI interrupt.
uint32_t *pointerData;

String strTEMP;

/*############################################################################################################
        Function declarations.
############################################################################################################*/

void slaveBegin(uint8_t _pin);
void FUNCAO_INTERRUPT();
void ProcessIncomingData();
void bars(bool bStatusiBarPin);
void carrier();
void modulating();
void pinSOUND_rising();
void pinSOUND_falling();
void pinSHOCK_rising();
void pinSHOCK_falling();
void ProgramSound();
void ProgramShock();
void Abort();

/*############################################################################################################
        Setup
############################################################################################################*/

void setup()
{
  // Configure SPI communication.
  slaveBegin(pinSS);

  pinMode(pinABORT, INPUT);
  pinMode(pinSOUND, INPUT);
  pinMode(pinSHOCK, INPUT);
  pinMode(pinTrigger, OUTPUT);
  digitalWrite(pinTrigger, LOW);
  
  // Programming pins that control bars potentials
  for (int i = 0; i < MaxNumBarPin; i++)
  {
    pinMode((iInitialBarPin + i * iBarPinStep), OUTPUT);
    digitalWrite((iInitialBarPin + i * iBarPinStep), LOW);
  }

  // Timer4 produces carrier signal and timer5 modulates carrier signal
  Timer4.attachInterrupt(carrier);
  Timer5.attachInterrupt(modulating);

  analogWriteResolution(12);
  analogWrite(DAC1, 0); // Configure DAC communication with analogWrite's built-in parameters

  ProgramSound(); //Program template signal for SOUND.
}

/*############################################################################################################
        Loop
############################################################################################################*/

void loop()
{
  if (bpinSOUND != digitalRead(pinSOUND)) // check if pinSOUND has changed state.
  {
    if (bpinSOUND) pinSOUND_falling(); // check if it was a falling edge.
    else pinSOUND_rising();            

    bpinSOUND = !bpinSOUND; // toggle bpinsSOUND, since pinSOUND changed state.
  }

  if (bpinSHOCK != digitalRead(pinSHOCK)) // check if pinSHOCK has changed state.
  {
    if (bpinSHOCK) pinSHOCK_falling();    // check if it was a falling edge.
      else pinSHOCK_rising();             
    if (ipulse_shockHigh > 0) bpinSHOCK = !bpinSHOCK; // we check if pulse_shockHigh > 0 before writing TRUE/FALSE to bpinSHOCK. Else, bpinSHOCK will always be false.
  }

  if (bpinSHOCK) bars(bBarStatus); // if bpinSHOCK is TRUE, shock must be turned on (this is made in bars() function).

  //SerialComandCheck();
  if (bSPIprocessdataIn) ProcessIncomingData();

}

/*############################################################################################################
        slaveBegin. Programm Arduino Due as a slave SPI.
############################################################################################################*/

void slaveBegin(uint8_t _pin)
{
  SPI.begin(_pin);
  REG_SPI0_CR = SPI_CR_SWRST;      // reset SPI
  REG_SPI0_CR = SPI_CR_SPIEN;      // enable SPI
  REG_SPI0_MR = SPI_MR_MODFDIS;    // slave and no modefault
  REG_SPI0_CSR = SPI_MODE0|(0x80); // DLYBCT=0, DLYBS=0, SCBR=0, 16 bit transfer

  //REG_SPI0_IER=SPI_IER_RDRF; // Setting Interrupt Enable Flag Register to 1???

  delay(1000);
  
  // Configures interruption whenever master SPI sends a message.
  int intNum = digitalPinToInterrupt(_pin); // _pin (SPI slave select) is used to generate interrupts.
  if (intNum != NOT_AN_INTERRUPT) 
  {
    SPI.usingInterrupt(intNum); // uses slave select pin to trigger an interrupt service routine (FUNCAO_INTERRUPT).
    attachInterrupt(intNum, FUNCAO_INTERRUPT, RISING); // Slave select rising indicates that SPI transaction in done and data can be processed.
  }
}

/*############################################################################################################
    SPI Transmission/reception complete ISR
    
    SPI COMUNICATION FROM/TO MASTER: Our protocol.

        0xA0A0 is the command word sent by ESP8266 that indicates SPI data should be processed.
        0x0010 is the command word sent by ESP8266 that indicates control variables should be programmed.
          (values for carrier_freq, modulator_freq, pulse_shockHigh and pulse_shockLow should be sent by ESP8266 after 0x0010 command)
        0x10FF is the command word sent by Arduino indicating that the values for the control variables were all received.
        0x1000 is the command word sent by Arduino indicating that the values for the control variables were not received.
        0x1A00 is the command word sent by ESP8266 indicating to ABORT experiment.

    SPI Registers and Commands:
        REG_SPI0_SR - SPI Status Register
        REG_SPI0_RDR - SPI Receive Data Register
        SPI_SR_RDRF - Receive Data Register Full
        SPI_SR_TDRE - Transmit Data Register Empty
        
############################################################################################################*/

void FUNCAO_INTERRUPT()
{
    while ((REG_SPI0_SR & SPI_SR_RDRF) != 0) // wait for SPI data is available
      {
      uData = REG_SPI0_RDR; // The registry is a uint32_t 32bit word
        if (bitOrder == LSBFIRST) uData = __REV(__RBIT(uData));
      byteBufferDataIN[iSPIdataCountIN]= (uData & 0xFF);        // copy the first byte received to byteBufferDataIN.
      byteBufferDataIN[iSPIdataCountIN+1]= (uData & 0xFF00)>>8; // copy the second byte received to byteBufferDataIN.
      iSPIdataCountIN+=2;

      if (uData==0xA0A0) bSPIprocessdataIn=true; // status of bSPIprocessdataIn variable is checked in main loop. Fim de comando.

      if (((REG_SPI0_SR & SPI_SR_TDRE) != 0) && bSPIprocessdataOUT) // checking if we have to send data
        {
          pointerData= (uint32_t *) (byteBufferDataOUT +iSPIdataCountOUT);
          REG_SPI0_TDR = *pointerData;
          iSPIdataCountOUT+=2;
          if (iSPIdataCountOUT>=iSPIdataMaxOUT) // If at the end, finished reading.
              {
                iSPIdataCountOUT=0;
                bSPIprocessdataOUT=false;
                iSPIdataMaxOUT=0;
              }
        }
      }
}

void ProcessIncomingData()
{
  //Serial.println(iSPIdataCountIN);
  if ((byteBufferDataIN[0]==0x10)&&((byteBufferDataIN[1]==0x00))) // Command 0x0010
      // This is the command that tells Arduino to program experiment control variables.
    {
      float *fTemp= (float *)(byteBufferDataIN+2);
      carrier_freq=fTemp[0];    //+ 4bytes = 6
      modulator_freq=fTemp[1];  //+ 4bytes = 10
      pulse_shockHigh=fTemp[2]; //+ 4bytes = 14
      pulse_shockLow=fTemp[3];  //+ 4bytes = 18
      volume_sound=fTemp[4];    //+ 4bytes = 22
                                //+ 2bytes = 24. This is the process command: 0xA0A0;
      
      if (iSPIdataCountIN==24) // Succeeded in SPI communication (received expected number of bytes). Don't forget 0xA0A0 in order to process SPI data.
        {          
          byteBufferDataOUT[iSPIdataCountOUT]=0x10; // 0x10FF indicates success in receiving data.
          byteBufferDataOUT[iSPIdataCountOUT+1]=0xFF; // 0x10FF indicates success in receiving data.
          ProgramSound();
          //ProgramShock();
          //Serial.println(carrier_freq);
          //Serial.println(modulator_freq);
          //Serial.println(pulse_shockHigh);
          //Serial.println(pulse_shockLow);
          //Serial.println(volume_sound);
        } else 
          {
          byteBufferDataOUT[iSPIdataCountOUT]=0x10; // 0x1000 indicates fail in receiving data.
          byteBufferDataOUT[iSPIdataCountOUT+1]=0x00; // 0x1000 indicates fail in receiving data.
          }
      // Anyway,
      iSPIdataMaxOUT+=2;
      bSPIprocessdataOUT=true; 
      //Serial.println(String("Mandando Sinal de Volta: ") + iSPIdataMaxOUT);
    }

  if ((byteBufferDataIN[0]==0x1A)&&((byteBufferDataIN[1]==0x00))) // ABORT Command 0x1A00.
    {
        Abort();
    }
    
  //Independent of what was processed, erase and restart.
  iSPIdataCountIN=0;
  bSPIprocessdataIn=false;
}

/*############################################################################################################
        Functions for PIN control
############################################################################################################*/

  void pinSOUND_rising() // pinSOUND rises when ESP8266 indicates Arduino Due should start producing SOUND.
  {
    iC = 0; iM = 0;
  }
  
  void pinSOUND_falling() // pinSOUND falls when ESP8266 indicates Arduino Due should stop producing SOUND.
  {
    analogWrite(DAC1, 0);
    iC = 0; iM = 0;
    PIO_SetOutput( g_APinDescription[pinTrigger].pPort, g_APinDescription[pinTrigger].ulPin, LOW, 0, PIO_DEFAULT );
  }
  
  void pinSHOCK_rising() // pinSHOCK rises when ESP8266 indicates Arduino Due should start producing shock patterns (control signals).
  {
    iBarPin = iInitialBarPin;
    iCountShockIntervals = 0;
  }
  
  void pinSHOCK_falling() // pinSHOCK rises when ESP8266 indicates Arduino Due should stop producing shock patterns (control signals).
  {
    PIO_SetOutput(g_APinDescription[iBarPin].pPort, g_APinDescription[iBarPin].ulPin, LOW, 0, PIO_DEFAULT) ;
    iBarPin = iInitialBarPin;
    bBarStatus = false;
    iCountShockIntervals = 0;
  }

/*############################################################################################################
        Function: bars
############################################################################################################*/

  void bars(bool bStatusiBarPin) //When the interrupt is called those sequence of commands are executed
  {
  // This function will execute when the processor is idle ... within the loop ... the priority FOR TIMING is with the wave generation.
    // If Count is between zero and ipulse_shockHigh, SHOCK is suposed to be on.
    // If Count is between ipulse_shockHigh and ipulse_shockLow, SHOCK is suposed to be off.
    // If Count is greater than ipulse_shockHigh + ipulse_shockLow, should SHOCK next bar.
    if (bStatusiBarPin) // SHOCK is on => let's see if we have to turn it off.
    {
      if (iCountShockIntervals >= ipulse_shockHigh)
      {
        PIO_SetOutput( g_APinDescription[iBarPin].pPort, g_APinDescription[iBarPin].ulPin, LOW, 0, PIO_DEFAULT );
        bBarStatus = false;
      }
  
    } else // SHOCK is off => let's see if we have to turn it on.
    {
      if ((iCountShockIntervals >= 0) && (iCountShockIntervals<ipulse_shockHigh))
      {
        PIO_SetOutput( g_APinDescription[iBarPin].pPort, g_APinDescription[iBarPin].ulPin, HIGH, 0, PIO_DEFAULT );
        bBarStatus = true;
      }
      
      // SHOCK is off => let's see if we have to change to next bar.
      if (iCountShockIntervals >= (ipulse_shockHigh + ipulse_shockLow))
          {
            iCountShockIntervals = 0;
            iBarPin += iBarPinStep;
            // If we were in the last bar, return to the first one.
              if (iBarPin == (iInitialBarPin + MaxNumBarPin * iBarPinStep)) iBarPin = iInitialBarPin; 
          }
    }
  }

/*############################################################################################################
        Function: carrier
############################################################################################################*/

void carrier()
{
  // note that the DACbuffer was already calculated in ProgramSound(). Here, we only check which value we have to write on DAC.
  if (bpinSOUND) dacc_write_conversion_data(DACC_INTERFACE, DACbuffer[iC + iM * maxSamplesNumCarrier]); // writes data directly on the pin (analogWrite is too slow); with analogWrite() the maximum frequency achieved was 28kHz, whereas that implementation can reach up to 125kHz
  iC++;
  // check if carrier completed one period.
    if (iC == maxSamplesNumCarrier) iC = 0;
  // 
  if (bpinSHOCK) iCountShockIntervals += iDeltaT; // We are using the same clock to count shock and sound intervals.

  //IFs must be only bools or INTs ... working with floats delays things
}

/*############################################################################################################
        Function: modulating
############################################################################################################*/

void modulating()
{
  // The next 2 if's below are used to generate a trigger sinal that will be used as a reference for the modulation phase.
    if ((iM == 0) && (bpinSOUND)) PIO_SetOutput( g_APinDescription[pinTrigger].pPort, g_APinDescription[pinTrigger].ulPin, LOW, 0, PIO_DEFAULT );
    if ((iM == (maxSamplesNumModulating/2)) && (bpinSOUND)) PIO_SetOutput( g_APinDescription[pinTrigger].pPort, g_APinDescription[pinTrigger].ulPin, HIGH, 0, PIO_DEFAULT );
  iM++;
  if (iM == maxSamplesNumModulating) iM = 0;// Modulator completes one period
}

/*############################################################################################################
        Function: ProgramSound

        This is where we program a sound buffer that will be played during experiment.

        Timer4 is used to control the carrier wave and the shock.
        Timer5 is used to control trigger wave.
        
############################################################################################################*/

void ProgramSound()
{
  //Stop Everything
  Timer4.stop();
  Timer5.stop();
  bpinSOUND = false;

  // First program sound buffer with new parameters.
  for (int i = 0; i < maxSamplesNumModulating; i++)
    for (int j = 0; j < maxSamplesNumCarrier; j++)
      // check if sound is modulated of if it's a pure tune.
      if (modulator_freq > 0) DACbuffer[j + (i * maxSamplesNumCarrier)] = ((1 + waveformsTableCarrier[j] * waveformsTableModulating[i]) * 4095 * volume_sound/100) / 2;
      else DACbuffer[j + (i * maxSamplesNumCarrier)] = ((1 + waveformsTableCarrier[j]) * 4095 * volume_sound/100) / 2;

  iC = 0;
  iM = 0;
  fDeltaT = (1 / (carrier_freq * maxSamplesNumCarrier)) * 1000; // Pacote de cada Delta T do interrupt de SOM ... Em millisegundos.

  float fTemp;
  fTemp = fDeltaT * 1000; // In multiples of 10 microsseconds;
  iDeltaT = floor(fTemp);
  iCountShockIntervals = 0;

  fTemp = pulse_shockHigh * 1000; // In multiples of 10 microsseconds;
  ipulse_shockHigh = floor(fTemp);

  fTemp = pulse_shockLow * 1000; // In multiples of 10 microsseconds;
  ipulse_shockLow = floor(fTemp);

  // The line below can be a problem if carrier_freq is zero. Shock will have no clock to control its temporal patterns.
  Timer4.setFrequency(carrier_freq * maxSamplesNumCarrier);
  if (modulator_freq > 0)
  {
    Timer5.setFrequency(modulator_freq * maxSamplesNumModulating);
    Timer5.start();
  }
  Timer4.start();
}

/*############################################################################################################
        Function: Abort
############################################################################################################*/

void Abort()
{
  // Disable all timers.
}

Any thoughts will be helpful, thank you!

Your Due code has all the Serial.println lines commented out. What line of code is generating the "0.00" on the Due serial monitor?

How long are the SPI wires between the two devices?

Draw a circuit diagram showing all the connections.

That sounds very much like cruelty to animals

Topic closed